fvwm-2.6.7/0000755000175700017570000000000013010103346007513 500000000000000fvwm-2.6.7/po/0000755000175700017570000000000013010103346010131 500000000000000fvwm-2.6.7/po/fvwm.zh_CN.po0000644000175700017570000001722112673746443012424 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR fvwm workers # This file is distributed under the same license as the PACKAGE package. # Funda Wang , 2004. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2004-05-22 16:12+0800\n" "Last-Translator: Funda Wang \n" "Language-Team: zh_CN \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "内建菜单" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "设置表单" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "设置 95 脚本" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "执行 fvwm 命令" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "重新启动 fvwm" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "退出 fvwm" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "桌面" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\t几何" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "桌面:%d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "" #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "根菜单" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "远程登录" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "实用工具" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "Fvwm 模块" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "Fvwm 窗口操作" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "Fvwm 配置操作" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "刷新屏幕" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "重新抓取屏幕" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "退出 Fvwm" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "重置 X 默认值" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "粘性置焦" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "单击置焦" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "焦点跟随鼠标" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "颜色图跟随鼠标" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "颜色图跟随焦点" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "移动(&M)" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "大小(&R)" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "升起(&A)" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "降低(&L)" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "最小化(&I)" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "置顶(&S)" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "最大化(&X)" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "删除(&D)" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "关闭(&C)" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "摧毁" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "窗口操作" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "刷新窗口(&F)" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "打印" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "翻转打印(&V)" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "控制动画" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "桌面" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "停止模块菜单" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "停止 Fvwm 模块" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "停止" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "真的要退出 Fvwm 吗?" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "是的,真的退出" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "重新启动" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "开始" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "只是 Xterm" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "不,不要退出" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "fvwm - 创建配置" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "使用此表单创建您自己的 fvwm2rc 配置文件。" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "创建的文件是 ~/.fvwm/.fvwm2rc 或 $FVWM_USERDIR/.fvwm2rc。" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "创建之后,fvwm2rc 文件就可以用您喜欢的任何" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "文本编辑器进行更改。" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "创建初始的 .fvwm2rc 文件" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "这些文件是可选的。请选择您想要自定义的模块。" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "您当然可以稍后再复制。" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "返回 - 丢弃" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "复制配置文件" fvwm-2.6.7/po/FvwmScript.zh_CN.gmo0000644000175700017570000000470012673746443013713 00000000000000/C  ,: @ NY^ cn t   &)17 ?JR Zh m"{     " *:7r   0HO_ fs     $ 7 J Y i x      # /+ $&*('!-,.% ") Show hidden filesAcceleration:ApplyAutoRepeat OnBackgroundBeepBellBell SetupBlankBrowser...CancelClick Volume (%)Config and DemoCycle(s):DPMSDisableDisable xinit backgroundDuration(ms):EnableFile BrowserKeyboardKeyboard SetupMouse configuration:OKOff(s):Path:PatternPitch(Hz):Pixmap:PointerPointer SetupQuitRepeat Delay:Right-handed user|Left-handed userSaveScreen SetupScreen-saverSelected file:Standby(s):Start Delay: Suspend(s):Threshold (pixels):Timeout(s):Uniform color:Volume:xscreensaverProject-Id-Version: FvwmScript POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2004-05-22 16:16+0800 Last-Translator: Funda Wang Language-Team: zh_CN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 显示隐藏文件加速:应用自动重复开背景响铃相应响铃设置空浏览器...取消点击音量(%)配置并演示循环(秒):DPMS禁用禁用 xinit 背景持续时间(毫秒):启用文件浏览器键盘键盘设置鼠标配置:确定关机(秒):路径:图案频率(Hz):像素图:指针指点设备设置退出重复延迟:右手用户|左手用户保存屏幕设置屏幕保护程序选中的文件:待机(秒):启动延迟:休眠(秒):阀值(像素):计时(秒):单一颜色:音量:xscreensaverfvwm-2.6.7/po/Makefile.am0000644000175700017570000002363313010047777012133 00000000000000 localedir = @LOCALEDIR@ FVWM_POT_FILES = \ ../fvwm/fvwm.c \ ../fvwm/expand.c \ ../fvwm/windowlist.c \ ../fvwm/virtual.c \ ../fvwm/menus.c FVWMRC_POT_FILES = \ ../fvwm/ConfigFvwmSetup \ ../modules/FvwmForm/FvwmForm-Setup.in FVWMSCRIPT_POT_FILES = \ ../modules/FvwmScript/Scripts/FvwmScript-BellSetup \ ../modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup \ ../modules/FvwmScript/Scripts/FvwmScript-PointerSetup \ ../modules/FvwmScript/Scripts/FvwmScript-ScreenSetup \ ../modules/FvwmScript/Scripts/FvwmScript-FileBrowser EXTRA_DIST = \ @POFILES@ @GMOFILES@ fvwm.pot FvwmScript.pot \ remove-potcdate.sed remove-potcdate.sin COPYRIGHT_HOLDER = fvwm workers # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = MSGMERGE_UPDATE = @MSGMERGE@ --update SUFFIXES = .po .gmo .mo .sed .sin .nop .po-update .po.mo: @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ .po.gmo: @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ if test -f $(srcdir)/$${lang}.po; then \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo; \ fi .sin.sed: sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all-local: all-local-@USE_NLS@ # make [all] should do nothing ... #all-local-yes: $(CATALOGS) all-local-yes: all-local-no: catalogs: $(CATALOGS) maintainer-clean-local: rm -f $(GMOFILES) $(FVWM_DOMAIN).pot-update: $(FVWM_POT_FILES) \ $(FVWMRC_POT_FILES) \ remove-potcdate.sed rm -f fvwmrc.pot; \ rcpotfiles='$(FVWMRC_POT_FILES)'; \ rm -f duplicate; \ for file in $$rcpotfiles; do \ perl -ne 's/\[gt\.((\\.|.)+?)\]/ print \ "\#$$ARGV: line $$.\n"."msgid \"$$1\"\n"."msgstr \"\"\n\n"/ge' \ $$file >> duplicate; \ done; \ msguniq duplicate > fvwmrc.pot; rm -f duplicate; \ potfiles='$(FVWM_POT_FILES)'; \ $(XGETTEXT) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) -o $(FVWM_DOMAIN).po \ --copyright-holder='$(COPYRIGHT_HOLDER)' $$potfiles; \ test ! -f $(FVWM_DOMAIN).po || { \ if test -f $(srcdir)/$(FVWM_DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(FVWM_DOMAIN).pot > $(FVWM_DOMAIN).1po && \ sed -f remove-potcdate.sed < $(FVWM_DOMAIN).po > $(FVWM_DOMAIN).2po && \ if cmp $(FVWM_DOMAIN).1po $(FVWM_DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(FVWM_DOMAIN).1po $(FVWM_DOMAIN).2po $(FVWM_DOMAIN).po; \ else \ rm -f $(FVWM_DOMAIN).1po $(FVWM_DOMAIN).2po $(srcdir)/$(FVWM_DOMAIN).pot && \ mv $(FVWM_DOMAIN).po $(srcdir)/$(FVWM_DOMAIN).pot; \ fi; \ else \ mv $(FVWM_DOMAIN).po $(srcdir)/$(FVWM_DOMAIN).pot; \ fi; \ mv $(FVWM_DOMAIN).pot duplicate.pot; \ cat fvwmrc.pot >> duplicate.pot; \ msguniq duplicate.pot > $(FVWM_DOMAIN).pot; \ rm -f duplicate.pot fvwmrc.pot; \ } $(srcdir)/$(FVWM_DOMAIN).pot: $(MAKE) $(FVWM_DOMAIN).pot-update $(FVWMSCRIPT_DOMAIN).pot-update: $(FVWMSCRIPT_POT_FILES) \ remove-potcdate.sed potfiles='$(FVWMSCRIPT_POT_FILES)'; \ rm -f duplicate; \ for file in $$potfiles; do \ perl -ne 's/LocaleTitle\s+\{((\\.|.)+?)\}/ print \ "\#$$ARGV: line $$.\n"."msgid \"$$1\"\n"."msgstr \"\"\n\n"/ge' \ $$file >> duplicate; \ done; \ msguniq duplicate > duplicate.pot; \ cat pot_head_sample > $(FVWMSCRIPT_DOMAIN).pot; \ cat duplicate.pot >> $(FVWMSCRIPT_DOMAIN).pot; \ rm -f duplicate duplicate.pot; $(srcdir)/$(FVWMSCRIPT_DOMAIN).pot: $(MAKE) $(FVWMSCRIPT_DOMAIN).pot-update $(POFILES): $(srcdir)/$(FVWM_DOMAIN).pot \ $(srcdir)/$(FVWMSCRIPT_DOMAIN).pot dlang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ dom=`echo $$dlang | sed -e 's/\..*$$//'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ if test -f $${dlang}.po; then \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${dlang}.po $${dom}.pot"; \ cd $(srcdir) && $(MSGMERGE_UPDATE) $${dlang}.po $${dom}.pot; \ fi # @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ # test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ # echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(FVWM_DOMAIN).pot"; \ # cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(FVWM_DOMAIN).pot install-data-local: install-data-local-@USE_NLS@ install-data-local-no: all install-data-local-yes: all $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ all_domains='$(ALL_DOMAINS)'; \ for dom in $$all_domains; do \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ cat="$$dom.$$cat"; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ if test -r $$cat; \ then realcat=$$cat; \ else realcat=$(srcdir)/$$cat; \ fi; \ if test -f $$realcat; then \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$$dom.mo; \ echo "installing $$realcat as $(DESTDIR)$$dir/$$dom.mo"; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' \ >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc \ $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo; \ ln -s ../LC_MESSAGES/$$dom.mo \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo 2>/dev/null || \ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$dom.mo \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo 2>/dev/null || \ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$dom.mo \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo; \ echo "installing $$realcat link as \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo"; \ fi; \ done; \ fi; \ done; \ done installdirs-data: installdirs-data-local-@USE_NLS@ installdirs-data-local-no: installdirs-data-local-yes: $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ all_domains='$(ALL_DOMAINS)'; \ for dom in $$all_domainss; do \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' \ >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc \ $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ fi; \ done; \ done; \ done uninstall-local: uninstall-local-@USE_NLS@ uninstall-local-no: uninstall-local-yes: catalogs='$(CATALOGS)'; \ all_domains='$(ALL_DOMAINS)'; \ for dom in $$all_domains; do \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo; \ done; \ done; \ done update-po: Makefile $(MAKE) $(FVWM_DOMAIN).pot-update $(MAKE) $(FVWMSCRIPT_DOMAIN).pot-update $(MAKE) $(UPDATEPOFILES) $(MAKE) update-gmo # General rule for updating PO files. .nop.po-update: dlang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po-update$$//'`; \ dom=`echo $$dlang | sed -e 's/\..*$$//'`; \ tmpdir=`pwd`; \ echo "$$dlang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $$dlang.po $$dom.pot -o $$dlang.new.po"; \ cd $(srcdir); \ if $(MSGMERGE) $$dlang.po $$dom.pot -o $$tmpdir/$$dlang.new.po; then \ if cmp $$dlang.po $$tmpdir/$$dlang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$dlang.new.po; \ else \ if mv -f $$tmpdir/$$dlang.new.po $$dlang.po; then \ :; \ else \ echo "msgmerge for $$dlang.po failed: cannot move \ $$tmpdir/$$dlang.new.po to $$dlang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$dlang.po failed!" 1>&2; \ rm -f $$tmpdir/$$dlang.new.po; \ fi $(DUMMYPOFILES): update-gmo: Makefile $(GMOFILES) @: fvwm-2.6.7/po/fvwm.ru.po0000644000175700017570000002137312673746443012054 00000000000000# Russian translation for fvwm package. # Copyright (C) 2013 fvwm workers # This file is distributed under the same license as the fvwm package. # Ivan Gayevskiy (a.k.a. Spoofing) , 2013. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2013-02-12 13:30+0800\n" "Last-Translator: Ivan Gayevskiy \n" "Language-Team: Russian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "Главное меню" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "Мастер настройки" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "Мастер настройки 95" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "Список команд FVWM" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "Перезапустить FVWM" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "Выход из FVWM" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "Стол" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\tПозиция" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "Стол: %d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "Ещё&..." #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "Главное меню" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "Удаленные подключения" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "Утилиты" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "Модули FVWM" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "Действия над окнами" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "Параметры конфигурации" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "Обновить экран (Refresh)" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "Обновить экран (Recapture)" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "Выход из FVWM" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "Сбросить настройки Xorg" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "Не терять фокус" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "Фокус по клику" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "Фокус следует за мышью" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "Colormap следует за мышью" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "Colormap следует за фокусом" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "Вкл. постраничную навигацию" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "Выкл. постраничную навигацию" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "Горизонтальный переход" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "Вертикальный переход" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "Только наполовину" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "Развернуть и оставить рамку" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "&Переместить" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "Изменить &размер" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "В &начало" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "В &конец" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "С&вернуть" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "Прикр&епить" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "Ра&звернуть" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "&Удалить" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "Закр&ыть" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "Уни&чтожить" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "П&араметры окна" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "О&бновить окно" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "Печат&ь" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "Обратная печа&ть" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "Анимация окна" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "столы" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "Выкл. модуль меню" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "Выкл. все модули" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "Стоп" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "На самом деле выйти?" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "Выходи уже давай" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "Перезапустить" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "Поехали" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "Обычный Xterm" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "Ой, я передумал" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "Создание конфигурации" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "Используйте это окно для создания новой конфигурации." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "Будет создан файл ~/.fvwm/.fvwm2rc или $FVWM_USERDIR/.fvwm2rc." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "После создания файл конфигурации может быть изменен простым" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "текстовым редактором." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "Создать файл конфигурации" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "Файлы не обязательны. Выберите модули, которые желаете настроить." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "Вы можете скопировать их позже." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "Enter - Отменить" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "Скопировать файлы" fvwm-2.6.7/po/fvwm.ar.gmo0000644000175700017570000001142612673746443012172 00000000000000B,Y<    =3 BO^u   +: JWg~   *; CP ak { ?D 8F        ' C S ] g q y '   n $P "u  3 1  ". ,Q ~    " 5 %,Ro  7 A'b*5Ig| $IjFa"-Pl: &.-# =8' 13 0 ),& $7+;*/@(:?B"!>65<%A492 Geometry&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximizeAfter creation, the fvwm2rc file can then be changed with anyAll Paging OFFBuiltin MenuClick To FocusColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDeskDesk: %d%sDestroyExit FvwmExit fvwmFocus Follows MouseFull Paging && Edge WrapFull Paging ONFvwm Config OpsFvwm ModulesFvwm Window OpsHorizontal Paging OnlyIssue fvwm commandsJust an XtermNo, Don't QuitPartial PagingPrintPrint Re&verseR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRemote LoginsReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSetup 95 ScriptSetup FormSloppy FocusStartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.Use this form to create your fvwm2rc configuration file.UtilitiesVertical Paging OnlyWindow OpsYes, Really QuitYou can always copy them later.deskseditor to suit your own needs.fvwm - Create ConfigurationProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2002-12-06 08:25+0100 Last-Translator: Nadim Shaikli Language-Team: Arabic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: KBabel 0.9.6 الأبعادأ&غلقاح&ذفا&خفض&حركغ&ير الحجم(عدم) التحويل لأي&قونة(أزل)ت&ثبيت(أزل) الت&كبيربعد الإنشاء، من الممكن تعديل الملف الخيارات fvwm2rc بإستعمال أيتوقيف التصفح الكاملقائمة مبنية داخلياتركيز بالضعطخارطة الألوان تلحق بالتركيزخارطة الألوان تلحق بالفارةتحكم بالحركةإنسخ ملفات التعريفأنشئ الملف المبدئي .fvwm2rc المكتبالمكتب: %d%sتدميرالخروج من Fvwmأخرج من fvwmتركيز بلحاق الفارةتصفح كامل مع القلب عند الحوافتشغيل التصفح الكامل خيارات إعداد Fvwmوحدات Fvwmخيارات نوافذ Fvwmالتصفح الأفقي فقطأصدر أوامر fvwmأظهر Xterm فقطلا، لا تخرجتصفح جزئيأطبعأطبع بالم&قلوبار&فعأعد تنشيط النافذةهل تريد الخروج من Fvwm ؟أعد عرض الشاشةأعد تنشيط الشاشةالدخول عن بعدإسترجاع الإفتراضي لأكسأعد التشغيلأعد تشغيل fvwmرجوع - خروجالقائمة الجذريةملف إعداد 95شاشة الإعدادتركيز بطيئإبدأإيقافإيقاف وحدات Fvemقائمة إيقاف الوحداتالملف المنشأ هو ~/.fvwm/.fvwm2rc أو $FVWM_USERDIR/.fvwm2rcالملفات التالية إختيارية. أختر الوحدات التي تود أن تخصصها.إستعمل هذا النموذج لإنشاء ملف الإعدادات fvwm2rc الخاص بكبرامج الخدماتالتصفح العمودي فقطخيارات النافذةنعم، أريد الخروجتستطيع نسخهم في الوقت الذي تريد.مكاتبمحرر نصوص تريده.إنشاء ملف خيارات ل fvwmfvwm-2.6.7/po/FvwmScript.de.po0000644000175700017570000001506112673746443013140 00000000000000# German translations for fvwm package # Copyright (C) 2003 fvwm workers # This file is distributed under the same license as the fvwm package. # Andrei Mitrofanow , 2003. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2003-04-13 11:35+0200\n" "Last-Translator: Andrei Mitrofanow \n" "Language-Team: German\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "Lautsprecher Konfiguration" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "Akzeptieren" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "Speichern" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "Beenden" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "Piebton" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "Lautstrke:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "Tonhhe(Hz)" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "Dauer(ms):" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "Lautsprecher" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "Konfiguration der Tastatur" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "Lautstrke des Klicks (%)" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "Wiederhohlung Aktiv" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "Startverzgerung:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "Wiederhohlverzgerung:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "Tastatur" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "Maus Einstellungen" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "Rechtshnder|Linkshnder" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "Maus Konfiguration:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "Beschleunigung:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "Schwellwert" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "Zeiger" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "Bildschirm Einstellungen" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "Hintergrund" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "Farben:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "Bilder:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "Betrachter" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "Deaktiviere Hintergrund" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "Bildschirmschoner" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "Leer" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "Timeout(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "Pattern" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "Kreislauf" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "DPMS" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "Aktivieren" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "Deaktivieren" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "Standby(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "Suspend(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "Aus(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "xscreensaver" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "Konfiguration und Demo" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "Dateimanager" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "OK" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "Abbrechen" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "Pfad:" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr "Zeige versteckte Dateien" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "Auswahl:" fvwm-2.6.7/po/fvwm.de.gmo0000644000175700017570000003375312673746443012167 00000000000000    + < ] z     K =NM] 9-DVjI ;-SiT  &:Sbr O5JH_AOP:RFL%VrOWq 83*?T]r { 5I(0?)p5CG)q&  5CIZ bo  'D   ' 3F@?DK:8  2 =GXIx:,**0["zLH3 OA]670 ?L`IP Hg !!!!!"! ""-" 5" ?"L"["k"}"O"8"#O)#y# #8####$)$ H$i$L$ $$$ %%L$%Wq%M% & $&1&B&[& j&x&&&&&N&$'*'D'Z'Xp'['R%(Yx(V(Y))X)\)V9*e** + "+/+A5+=w+++++, , , ,9&,`,Yy,,T,/G-Xw--H-L/.|.E...../ /&/;/R/i// ///// //- 0W80000 0 0M00161;1O1;c1C1Z1>2T2,j222 222 22 3N*3@y3G3 424B42[4T4R465S5We5K5Q 65[66P6M6PH7Q7njiU)/(XG6I1x`p!YRQKm%s<|O\rqyf.:h5 VBb_Z;vw$ ~?L=4 z8@aeEPW2,F[lg }SuCNT7A&9+ c0D#t'{] MJ^*k>o3d-H" Geometry (Default is 24) (Directory for converted icons) (Full path to store output)&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximize/usr/share/icons can used except the hicolor theme because it's the defaultAfter creation, the fvwm2rc file can then be changed with anyAll Paging OFFAlso it is a good idea to check .xsession-errors in the user home for errors.Application Icon: Builtin MenuBut remember, if the menu doesn't exist, nothing happens.Click To FocusColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDefault is 'FvwmMenu'.Defines which type of menu should be found. Possible name types could be:DeskDesk: %d%sDesktop: DestroyDirectory Icon: Enable this checkbox to insert generated menu(s) IN a menu.Enter here the FULL path of the menu to store. Default path is $FVWM_USERDIR/.menu.Enter in this field the name of the menu (its top title) where the generated menu(s)Exit FvwmExit fvwmFocus Follows MouseFull Paging && Edge WrapFull Paging ONFvwm Config OpsFvwm Menu Desktop ConfigFvwm ModulesFvwm Window OpsGeneral OptionsGenerate Menu(s)Generated icons are saved in $HOME/.fvwm/icons or the directory specified here.HelpHorizontal Paging OnlyIcon directory: Icon size: If 'Use Icons' is enabled and for a directory in a menu no icon is foundIf 'Use Icons' is enabled and for an application no icon is foundIf 'Use Icons' is set, by default 24x24 mini-icons are used. If another size isIf no menus appear check why from within a terminal with 'fvwm-menu-desktop -v'.If the specified icon isn't that size it is converted if ImageMagick is installed.If there are too much menus found an error occurs in .xsession-errors:If this option is set menus are generated with titles. Default is no titles.If you want a single menu only deselect all menus above and fill out the fields below.In this section all XDG menus found on the system are shown. All selected menusIn this section you can define a custom-assembled menu 'foo-bar.menu' placed on anotherInsert in menu: Install-Prefix: Issue fvwm commandsJust an XtermList menus with checkboxes found in $HOME/.config/menus/List menus with checkboxes found in /etc/xdg/menus/Menu Top Title: Menu(s) in a Menu? Menus inMenutype: More&...Multiple Multiple MenuNo No menus found! Check why from within a terminal withNo, Don't QuitNote that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/One limitation exists:Only the name of an icon is needed not the path!Option enables mini-icons in the menu(s).Otherwise no icon appears in the menu for that entry.Output path: Overrides the name of the main desktop environment installed on theOverrides the standard locations for XDG menu definitions. The standardPartial PagingPossible names: gnome, kde, lxde, etc.PrintPrint Re&verseQuitR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRegenerate XDG MenuRegenerate XDG Menu(s)Remote LoginsResetReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSave SettingsSet which menu generation will be used.Sets the used icon theme. Default is 'gnome' but all others found inSetup 95 ScriptSetup FormSingleSingle MenuSloppy FocusSpecifies the menu title of the top menu used by Fvwm's Popup command.StartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.This happens because PipeRead used for menu generation has a command lengthUse Icons? Use Titles? Use this form to create your fvwm2rc configuration file.Used Icon theme: Used Menu Type: UtilitiesVertical Paging OnlyWindow OpsYes Yes, Really QuitYou can always copy them later.applications, settings, preferences, etc. Note if the specified menu typeas default icon is used. But if the gnome icon theme isn'tdesired enter the wanted size in this field.desksdoesn't exist the generated menu is empty!editor to suit your own needs.exactly as the icon directory e.g.fallback theme if no icon is found. Note that the theme name must be writtenfollowing the XDG menu specification only shown in $HOME/.config/menus/.fvwm - Create Configurationif available.installed no default icon appears. Another icon can defined here.is typically set. It is ignored if this field is used.limit of 1000 characters. Sorry for that inconvinience.location as defined in the XDG menu definitions.locations are /etc/xdg/menus andshould insert. For more information see the USAGE section in the man page ofsystem. If a system offers multiple desktop environments $XDG_MENU_PREFIXuse the 'Single Menu' section.will integrate in one Fvwm menu. If you want to generate a custom-assembled menuProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2013-10-25 22:45+0200 Last-Translator: Thomas Funk Language-Team: German Language: German MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); Geometrie (Default ist 24) (fr konvertierte Icons) (voller Speicherpfad der Ausgabe)&Schliesse&LscheAb&senken&Verschieben&Grsse ndern(De)&Minimierer(Los)&Festklemmer(De)Ma&ximiererwerden, knnen verwendet werden. Ausgenommen 'hicolor', weil dieser der defaultNach dem Erzeugen, knnen Sie die Datei mit einem EditorSeitenbergang ausAuch ist es eine gute Idee in .xsession-errors nach Fehlermeldungen zu schauen.Applikations-Icon: Internes MenBitte beachten: wenn ein Men leer ist, passiert nichts.Klick fr FokusFarbpalette folgt FokusFarbpalette folgt MausAnimationskontrolleKonfigurationsdateien kopierenErzeuge eine Startdatei .fvwm2rcDefault ist 'FvwmMenu'.Definiert welcher Mentyp gefunden werden soll. Mgliche Typen knnten sein:ArbeitsplatzArbeitsplatz: %d%sDesktop: &ZerstreVerzeichnis-Icon: Aktivieren Sie diese Checkbox, um erstellte Mens IN einem Men einzubinden.Hier den VOLLEN Speicherpfad des Fvwm-Mens eintragen. Default ist $FVWM_USERDIR/.menu.Hier den Namen des Mens (seinen Toptitel) eintragen, wo die erstellten MensFvwm beendenFvwm beendenFokus folgt MausSeitenbergang && EckenSeitenbergangKonfigurationFvwm Menu Desktop KonfigurationModule von FvwmFensterGenerelle OptionenMen(s) erstelleninstalliert ist. Generierte Icons werden unter $HOME/.fvwm/icons oder dem hierHilfeSeitenbergang horizontalIcon-Verzeichnis: Icongre: Wenn 'Icons verwenden' gesetzt ist und fr ein Verzeichnis kein Icon gefunden wird, wirdWenn 'Icons verwenden' gesetzt ist, aber fr eine Applikation kein Icon gefunden wird, wirdWenn 'Icons verwenden' gesetzt ist, werden per default 24x24 Mini-Icons verwendet.Wenn keine Mens erscheinen, von einem Terminal mit 'fvwm-menu-desktop -v' checken warum.Wenn das Icon in der Gre nicht vorhanden ist, wird es konvertiert, falls ImageMagickWenn zuviele Mens gefunden werden, taucht folgende Fehlemeldung in .xsession-errors auf:Wenn diese Option gesetzt ist, werden Mens mit Titeln erstellt. Default ist ohne Titel.Fr ein Einzelmen alle nicht bentigten Mens deselektieren und die Felder unten ausfllen.In diesem Bereich werden alle XDG Mens angezeigt, die auf dem System gefunden werden.In dieser Sektion knnen Sie ein eigenerstelltes Men 'foo-bar.menu', das an einem anderen Ort als inEinfgen in Men: Install-Prefix: Fvwm-KonsoleXTermListet in $HOME/.config/menus/ gefundene Mens mit Checkboxen aufListet in /etc/xdg/menus/ gefundene Mens mit Checkboxen auf.Men Top Titel: Men(s) in dem Men? Mens inMentyp: Mehr&...Mehrfach MehrfachmenNein Keine Mens gefunden! In einem Terminal checken warum mitNein, fvwm nicht beendenAnmerkung: gleiche Mens, die in /etc/xdg/menus UND $HOME/.config/menus/ gefunden werden,Es existiert eine Limitierung:Defaulticon definiert werden. Es muss nur der Name, nicht der Pfad angegeben werden!Option aktiviert Mini-Icons in dem/den Men(s).angegebenen Verzeichnis gespeichert. Sonst taucht kein Icon im Men fr den Eintrag auf.Ausgabepfad: berschreibt den Namen der Haupt-Desktop-Umgebung, welche auf dem Systemberschreibt die Standardorte fr die XDG Mendefinitionen. Die StandardorteSeitenbergang teilweisewenn dieses Feld benutzt wird. Mgliche Namen: gnome, kde, lxde, etc.DruckenDrucken (Rckseite)BeendenAn&hebenFester erneuernFvwm beenden?Bildschirm speichernBildschirm neuzeichnenXDG Menu neu erstellenXDG Menu(s) neu erstellenEntfernt AnmeldenZurcksetzenX Voreinstellungen setzenNeustartFvwm neu startenAnnehmen - SchliessenHaupt MenuSettings speichernSetzt die zu verwendende Mengenerierungsart.Setzt den Icontheme. Default ist 'gnome', aber alle die unter /usr/share/icons gefundenKonfiguration mit Script95Konfiguration mit FormEinzelEinzelmenFokus flssigSpezifiziert den Mentitel des Topmens, das Fvwm's Popup Kommando verwendet.StartStopFvwm-Module stoppenFvwm-Module stoppenDie Datei ist ~/.fvwm/.fvwm2rc oder $FVWM_USERDIR/.fvwm2rc.Diese Dateien sind nicht notwendig. Die Auswahl der Module anpassenDas passiert, weil PipeRead, das zum generieren des Mens verwendet wird, eine LimitierungIcons verwenden? Titel verwenden? Nutze dieses Formular um fvwm2rc zu erzeugenBenutzter Icontheme: Verwendeter Mentyp: WerkzeugeSeitenbergang vertikaleFensterJa Ja, fvwm beendenSie knnen diese spter kopierenapplications, settings, preferences, etc. Achtung, wenn das hier spezifizierteals Defaulticon verwendet. Wenn jedoch der Gnome-Icontheme nichtWenn eine andere Gre verwendet werden soll, in diesem Feld eintragen.ArbeitsplatzMen nicht existiert, ist das erstellte Men leer!an Ihre Wnsche anpassenexakt gleich wie das Verzeichnis geschrieben wird:Fallback Theme ist, wenn kein Icon gefunden wird. Es ist wichtig, dass der Themenamewerden der XDG Menspezifikation folgend nur unter $HOME/.config/menus/ angezeigt.fvwm - Erzeuge Konfiguration(wenn vorhanden).installiert ist, taucht auch kein Icon fr den Eintrag auf. Darum kann hier ein anderesnormalerweise $XDG_MENU_PREFIX gesetzt. Die Variable wird jedoch ignoriert,von 1000 Zeichen fr ein Kommando hat. Entschuldigung fr diese Unannehmlichkeit.den XDG Menspezifikationen definiert ist, erstellen.sind /etc/xdg/menus undeingebunden werden sollen. Fr weitere Informationen siehe die USAGE Sektion voninstalliert ist. Wenn ein System mehrere Desktop-Umgebungen bereitstellt, istzusammengestelltes Menu erstellen wollen, benutzen Sie die 'Einzelmen' Sektion.Alle ausgewhlten Mens werden in einem Fvwm-Men integriert. Wenn Sie ein eigensfvwm-2.6.7/po/FvwmScript.ar.gmo0000644000175700017570000000054712673746443013321 00000000000000$,8-9Project-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2003-04-13 11:35+0200 Last-Translator: NEEDS TRANSLATION Language-Team: Should be Arabic MIME-Version: 1.0 Content-Type: text/plain; charset=ascii Content-Transfer-Encoding: 8bit fvwm-2.6.7/po/Makefile.in0000644000175700017570000006102113010103323012111 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = po DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @LOCALEDIR@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ FVWM_POT_FILES = \ ../fvwm/fvwm.c \ ../fvwm/expand.c \ ../fvwm/windowlist.c \ ../fvwm/virtual.c \ ../fvwm/menus.c FVWMRC_POT_FILES = \ ../fvwm/ConfigFvwmSetup \ ../modules/FvwmForm/FvwmForm-Setup.in FVWMSCRIPT_POT_FILES = \ ../modules/FvwmScript/Scripts/FvwmScript-BellSetup \ ../modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup \ ../modules/FvwmScript/Scripts/FvwmScript-PointerSetup \ ../modules/FvwmScript/Scripts/FvwmScript-ScreenSetup \ ../modules/FvwmScript/Scripts/FvwmScript-FileBrowser EXTRA_DIST = \ @POFILES@ @GMOFILES@ fvwm.pot FvwmScript.pot \ remove-potcdate.sed remove-potcdate.sin COPYRIGHT_HOLDER = fvwm workers # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = MSGMERGE_UPDATE = @MSGMERGE@ --update SUFFIXES = .po .gmo .mo .sed .sin .nop .po-update all: all-am .SUFFIXES: .SUFFIXES: .po .gmo .mo .sed .sin .nop .po-update $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign po/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign po/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ cscopelist-am ctags-am distclean distclean-generic distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic \ maintainer-clean-local mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am uninstall-local .po.mo: @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ .po.gmo: @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ if test -f $(srcdir)/$${lang}.po; then \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo; \ fi .sin.sed: sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all-local: all-local-@USE_NLS@ # make [all] should do nothing ... #all-local-yes: $(CATALOGS) all-local-yes: all-local-no: catalogs: $(CATALOGS) maintainer-clean-local: rm -f $(GMOFILES) $(FVWM_DOMAIN).pot-update: $(FVWM_POT_FILES) \ $(FVWMRC_POT_FILES) \ remove-potcdate.sed rm -f fvwmrc.pot; \ rcpotfiles='$(FVWMRC_POT_FILES)'; \ rm -f duplicate; \ for file in $$rcpotfiles; do \ perl -ne 's/\[gt\.((\\.|.)+?)\]/ print \ "\#$$ARGV: line $$.\n"."msgid \"$$1\"\n"."msgstr \"\"\n\n"/ge' \ $$file >> duplicate; \ done; \ msguniq duplicate > fvwmrc.pot; rm -f duplicate; \ potfiles='$(FVWM_POT_FILES)'; \ $(XGETTEXT) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) -o $(FVWM_DOMAIN).po \ --copyright-holder='$(COPYRIGHT_HOLDER)' $$potfiles; \ test ! -f $(FVWM_DOMAIN).po || { \ if test -f $(srcdir)/$(FVWM_DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(FVWM_DOMAIN).pot > $(FVWM_DOMAIN).1po && \ sed -f remove-potcdate.sed < $(FVWM_DOMAIN).po > $(FVWM_DOMAIN).2po && \ if cmp $(FVWM_DOMAIN).1po $(FVWM_DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(FVWM_DOMAIN).1po $(FVWM_DOMAIN).2po $(FVWM_DOMAIN).po; \ else \ rm -f $(FVWM_DOMAIN).1po $(FVWM_DOMAIN).2po $(srcdir)/$(FVWM_DOMAIN).pot && \ mv $(FVWM_DOMAIN).po $(srcdir)/$(FVWM_DOMAIN).pot; \ fi; \ else \ mv $(FVWM_DOMAIN).po $(srcdir)/$(FVWM_DOMAIN).pot; \ fi; \ mv $(FVWM_DOMAIN).pot duplicate.pot; \ cat fvwmrc.pot >> duplicate.pot; \ msguniq duplicate.pot > $(FVWM_DOMAIN).pot; \ rm -f duplicate.pot fvwmrc.pot; \ } $(srcdir)/$(FVWM_DOMAIN).pot: $(MAKE) $(FVWM_DOMAIN).pot-update $(FVWMSCRIPT_DOMAIN).pot-update: $(FVWMSCRIPT_POT_FILES) \ remove-potcdate.sed potfiles='$(FVWMSCRIPT_POT_FILES)'; \ rm -f duplicate; \ for file in $$potfiles; do \ perl -ne 's/LocaleTitle\s+\{((\\.|.)+?)\}/ print \ "\#$$ARGV: line $$.\n"."msgid \"$$1\"\n"."msgstr \"\"\n\n"/ge' \ $$file >> duplicate; \ done; \ msguniq duplicate > duplicate.pot; \ cat pot_head_sample > $(FVWMSCRIPT_DOMAIN).pot; \ cat duplicate.pot >> $(FVWMSCRIPT_DOMAIN).pot; \ rm -f duplicate duplicate.pot; $(srcdir)/$(FVWMSCRIPT_DOMAIN).pot: $(MAKE) $(FVWMSCRIPT_DOMAIN).pot-update $(POFILES): $(srcdir)/$(FVWM_DOMAIN).pot \ $(srcdir)/$(FVWMSCRIPT_DOMAIN).pot dlang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ dom=`echo $$dlang | sed -e 's/\..*$$//'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ if test -f $${dlang}.po; then \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${dlang}.po $${dom}.pot"; \ cd $(srcdir) && $(MSGMERGE_UPDATE) $${dlang}.po $${dom}.pot; \ fi # @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ # test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ # echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(FVWM_DOMAIN).pot"; \ # cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(FVWM_DOMAIN).pot install-data-local: install-data-local-@USE_NLS@ install-data-local-no: all install-data-local-yes: all $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ all_domains='$(ALL_DOMAINS)'; \ for dom in $$all_domains; do \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ cat="$$dom.$$cat"; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ if test -r $$cat; \ then realcat=$$cat; \ else realcat=$(srcdir)/$$cat; \ fi; \ if test -f $$realcat; then \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$$dom.mo; \ echo "installing $$realcat as $(DESTDIR)$$dir/$$dom.mo"; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' \ >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc \ $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo; \ ln -s ../LC_MESSAGES/$$dom.mo \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo 2>/dev/null || \ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$dom.mo \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo 2>/dev/null || \ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$$dom.mo \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo; \ echo "installing $$realcat link as \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo"; \ fi; \ done; \ fi; \ done; \ done installdirs-data: installdirs-data-local-@USE_NLS@ installdirs-data-local-no: installdirs-data-local-yes: $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ all_domains='$(ALL_DOMAINS)'; \ for dom in $$all_domainss; do \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' \ >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && \ LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc \ $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file \ $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ fi; \ done; \ done; \ done uninstall-local: uninstall-local-@USE_NLS@ uninstall-local-no: uninstall-local-yes: catalogs='$(CATALOGS)'; \ all_domains='$(ALL_DOMAINS)'; \ for dom in $$all_domains; do \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$$dom.mo; \ done; \ done; \ done update-po: Makefile $(MAKE) $(FVWM_DOMAIN).pot-update $(MAKE) $(FVWMSCRIPT_DOMAIN).pot-update $(MAKE) $(UPDATEPOFILES) $(MAKE) update-gmo # General rule for updating PO files. .nop.po-update: dlang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po-update$$//'`; \ dom=`echo $$dlang | sed -e 's/\..*$$//'`; \ tmpdir=`pwd`; \ echo "$$dlang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $$dlang.po $$dom.pot -o $$dlang.new.po"; \ cd $(srcdir); \ if $(MSGMERGE) $$dlang.po $$dom.pot -o $$tmpdir/$$dlang.new.po; then \ if cmp $$dlang.po $$tmpdir/$$dlang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$dlang.new.po; \ else \ if mv -f $$tmpdir/$$dlang.new.po $$dlang.po; then \ :; \ else \ echo "msgmerge for $$dlang.po failed: cannot move \ $$tmpdir/$$dlang.new.po to $$dlang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$dlang.po failed!" 1>&2; \ rm -f $$tmpdir/$$dlang.new.po; \ fi $(DUMMYPOFILES): update-gmo: Makefile $(GMOFILES) @: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/po/FvwmScript.es.po0000644000175700017570000001505412673746443013161 00000000000000# Spanish translations for fvwm package # Copyright (C) 2013 fvwm workers # This file is distributed under the same license as the PACKAGE package. # Adonai Martin , 2013. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2013-03-11 17:20+0200\n" "Last-Translator: Adonai Martin \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "Configuracin de Sonido" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "Aplicar" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "Guardar" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "Cerrar" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "Pitido" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "Volumen:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "Tono(Hz)" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "Duracin(ms)" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "Sonido" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "Configuracin de Teclado" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "Click Volumen (%)" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "AutoRepeticin On" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "Retardo de Inicio: " #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "Retardo de Repeticin:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "Teclado" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "Configuracin de Puntero" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "Usuario diestro| Usuario zurdo" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "Configuracin de Ratn:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "Aceleracin:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "Umbral (pxeles):" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "Puntero" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "Configuracin de Pantalla" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "Tapiz" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "Color uniforme:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "Mapa de pxeles" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "Navegar..." #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "Deshabilitar fondo xinit" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "Protector de Pantalla" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "Vaco" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "Tiempo de espera():" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "Patrn" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "Ciclo(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "DPMS" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "Habilitar" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "Deshabilitar" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "Espera(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "Suspendido(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "Off(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "xscreensaver" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "Configuracin y Demo" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "Navegacin de Archivos" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "OK" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "Cancelar" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "Ruta:" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr " Mostrar archivos ocultos" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "Archivo seleccionado:" fvwm-2.6.7/po/fvwm.sv_SE.gmo0000644000175700017570000001032312673746443012602 00000000000000C4YL    =C R_n   ";J Zgw & 5CT \i z  ?D 8_       B4 w       9  + 8 P g |      & D ^   #     )9> O] m{ 1CB@E !7 L!X z3/.$ >9" 24 1 *-' %8,<+0A);@C#!?76=&B5(:3 Geometry&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximizeAfter creation, the fvwm2rc file can then be changed with anyAll Paging OFFBuiltin MenuClick To FocusColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDeskDesk: %d%sDestroyExit FvwmExit fvwmFocus Follows MouseFull Paging && Edge WrapFull Paging ONFvwm Config OpsFvwm ModulesFvwm Window OpsHorizontal Paging OnlyIssue fvwm commandsJust an XtermMore&...No, Don't QuitPartial PagingPrintPrint Re&verseR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRemote LoginsReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSetup 95 ScriptSetup FormSloppy FocusStartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.Use this form to create your fvwm2rc configuration file.UtilitiesVertical Paging OnlyWindow OpsYes, Really QuitYou can always copy them later.deskseditor to suit your own needs.fvwm - Create ConfigurationProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2003-10-19 15:01+0200 Last-Translator: Johan Svedberg Language-Team: Swedish MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); StorlekSt&ng&Ta bort&Snk&Flytta&ndra storlek(Av)&Minimera(Av)&Stt fast(Av)Ma&ximeraEfter skapande s kan fvwm2rc-filen modifieras med vilkenAll sidfunktionalitet AVInbyggd menyKlicka fr att fokuseraFrgkarta fljer fokusFrgkarta fljer musKontrollera animationKopiera konfigurationsfil(er)Skapa en startande .fvwm2rc-filSkrivbordSkrivbord: %d%sFrstrAvsluta FvwmAvsluta fvwmFokus fljer musFull sidfunktionalitet && KantbrytningFull sidfunktionalitet PFvwm-konfigurationsinstllningarFvwm-modulerFvwm-fnsterinstllningarEndast horisontal sidfunktionalitetUtfr fvwm-kommandonBara en XtermMer&...Nej, avsluta inteDelvis sidfunktionalitetSkriv utSkriv ut omvnd&HjR&ita om fnsterAvsluta Fvwm?Uppdatera skrmRita om skrmFjrrinloggningarNollstll X-standarderStarta omStarta om fvwmtervnd - AvslutaRotmenyStll in 95 skriptInstllningsformulrSlarvigt fokusStartaStannaStanna Fvwm-modulerStanna modulmenyDen skapade filen r ~/.fvwm/.fvwm2rc eller $FVWM_USERDIR/.fvwm2rc.De hr filerna r valfria. Vlj modulerna som du vill stlla in.Anvnd det hr formulret fr att skapa din fvwm2rc-konfigurationsfilVerktygEndast vertikal sidfunktionalitetFnsterinstllningarJa, avslutaDu kan alltid kopiera dem senare.skrivbordredigerare som helst fr att passa dina egna behov.fvwm - Skapa konfigurationfvwm-2.6.7/po/FvwmScript.es.gmo0000644000175700017570000000476312673746443013332 00000000000000/C  ,: @ NY^ cn t   &)17 ?JR Zh m"{     " *7R ly     5 BLck + 3 M c y          # /+ $&*('!-,.% ") Show hidden filesAcceleration:ApplyAutoRepeat OnBackgroundBeepBellBell SetupBlankBrowser...CancelClick Volume (%)Config and DemoCycle(s):DPMSDisableDisable xinit backgroundDuration(ms):EnableFile BrowserKeyboardKeyboard SetupMouse configuration:OKOff(s):Path:PatternPitch(Hz):Pixmap:PointerPointer SetupQuitRepeat Delay:Right-handed user|Left-handed userSaveScreen SetupScreen-saverSelected file:Standby(s):Start Delay: Suspend(s):Threshold (pixels):Timeout(s):Uniform color:Volume:xscreensaverProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2013-03-11 17:20+0200 Last-Translator: Adonai Martin Language-Team: Spanish MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Mostrar archivos ocultosAceleracin:AplicarAutoRepeticin OnTapizPitidoSonidoConfiguracin de SonidoVacoNavegar...CancelarClick Volumen (%)Configuracin y DemoCiclo(s):DPMSDeshabilitarDeshabilitar fondo xinitDuracin(ms)HabilitarNavegacin de ArchivosTecladoConfiguracin de TecladoConfiguracin de Ratn:OKOff(s):Ruta:PatrnTono(Hz)Mapa de pxelesPunteroConfiguracin de PunteroCerrarRetardo de Repeticin:Usuario diestro| Usuario zurdoGuardarConfiguracin de PantallaProtector de PantallaArchivo seleccionado:Espera(s):Retardo de Inicio: Suspendido(s):Umbral (pxeles):Tiempo de espera():Color uniforme:Volumen:xscreensaverfvwm-2.6.7/po/FvwmScript.zh_CN.po0000644000175700017570000001475512673746443013562 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR fvwm workers # This file is distributed under the same license as the PACKAGE package. # Funda Wang , 2004. # msgid "" msgstr "" "Project-Id-Version: FvwmScript\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2004-05-22 16:16+0800\n" "Last-Translator: Funda Wang \n" "Language-Team: zh_CN \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "响铃设置" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "应用" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "保存" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "退出" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "响铃" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "音量:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "频率(Hz):" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "持续时间(毫秒):" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "相应" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "键盘设置" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "点击音量(%)" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "自动重复开" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "启动延迟:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "重复延迟:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "键盘" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "指点设备设置" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "右手用户|左手用户" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "鼠标配置:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "加速:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "阀值(像素):" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "指针" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "屏幕设置" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "背景" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "单一颜色:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "像素图:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "浏览器..." #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "禁用 xinit 背景" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "屏幕保护程序" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "空" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "计时(秒):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "图案" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "循环(秒):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "DPMS" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "启用" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "禁用" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "待机(秒):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "休眠(秒):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "关机(秒):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "xscreensaver" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "配置并演示" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "文件浏览器" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "确定" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "取消" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "路径:" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr " 显示隐藏文件" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "选中的文件:" fvwm-2.6.7/po/FvwmScript.ru.po0000644000175700017570000001566712673746443013212 00000000000000# Russian translation for fvwm package. # Copyright (C) 2013 fvwm workers # This file is distributed under the same license as the fvwm package. # Ivan Gayevskiy (a.k.a. Spoofing) , 2013. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2013-02-12 14:20+0800\n" "Last-Translator: Ivan Gayevskiy \n" "Language-Team: Russian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "Настройка оповещений" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "Применить" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "Сохранить" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "Закрыть" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "Спикер" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "Громкость:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "Частота:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "Продолжительность:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "Оповещение" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "Настройка клавиатуры" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "Выбор громкости" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "Автоповтор Вкл." #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "Ожидать начало:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "Ожидать повтор:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "Клавиатура" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "Настройка курсора" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "Пользователь правша, либо левша" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "Настройка мышки:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "Ускорение:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "Порог ожидания:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "Курсор" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "Настройка экрана" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "Фон" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "Однородный цвет:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "Картинка:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "Обзор..." #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "Отключить фон из xinit" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "Хранитель экрана" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "Пусто" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "Таймаут:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "Шаблон" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "Повтор:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "DPMS" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "Включить" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "Отключить" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "Запасной:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "Отложить:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "Отключить:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "xscreensaver" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "Предпросмотр" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "Файловый менеджер" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "Ок" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "Отмена" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "Путь:" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr " Отображать скрытые файлы" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "Выбранные файлы:" fvwm-2.6.7/po/fvwm.sv_SE.po0000644000175700017570000001775112673746443012452 00000000000000# Swedish translations for fvwm package # Svenska versttningar fr paket fvwm. # Copyright (C) 2003 fvwm workers # This file is distributed under the same license as the fvwm package. # Johan Svedberg , 2003. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2003-10-19 15:01+0200\n" "Last-Translator: Johan Svedberg \n" "Language-Team: Swedish\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "Inbyggd meny" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "Instllningsformulr" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "Stll in 95 skript" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "Utfr fvwm-kommandon" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "Starta om fvwm" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "Avsluta fvwm" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "Skrivbord" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\tStorlek" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "Skrivbord: %d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "Mer&..." #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "Rotmeny" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "Fjrrinloggningar" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "Verktyg" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "Fvwm-moduler" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "Fvwm-fnsterinstllningar" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "Fvwm-konfigurationsinstllningar" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "Rita om skrm" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "Uppdatera skrm" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "Avsluta Fvwm" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "Nollstll X-standarder" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "Slarvigt fokus" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "Klicka fr att fokusera" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "Fokus fljer mus" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "Frgkarta fljer mus" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "Frgkarta fljer fokus" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "Full sidfunktionalitet P" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "All sidfunktionalitet AV" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "Endast horisontal sidfunktionalitet" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "Endast vertikal sidfunktionalitet" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "Delvis sidfunktionalitet" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "Full sidfunktionalitet && Kantbrytning" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "&Flytta" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "&ndra storlek" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "&Hj" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "&Snk" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "(Av)&Minimera" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "(Av)&Stt fast" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "(Av)Ma&ximera" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "&Ta bort" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "St&ng" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "Frstr" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "Fnsterinstllningar" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "R&ita om fnster" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "Skriv ut" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "Skriv ut omvnd" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "Kontrollera animation" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "skrivbord" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "Stanna modulmeny" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "Stanna Fvwm-moduler" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "Stanna" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "Avsluta Fvwm?" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "Ja, avsluta" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "Starta om" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "Starta" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "Bara en Xterm" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "Nej, avsluta inte" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "fvwm - Skapa konfiguration" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "Anvnd det hr formulret fr att skapa din fvwm2rc-konfigurationsfil" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "Den skapade filen r ~/.fvwm/.fvwm2rc eller $FVWM_USERDIR/.fvwm2rc." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "Efter skapande s kan fvwm2rc-filen modifieras med vilken" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "redigerare som helst fr att passa dina egna behov." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "Skapa en startande .fvwm2rc-fil" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "De hr filerna r valfria. Vlj modulerna som du vill stlla in." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "Du kan alltid kopiera dem senare." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "tervnd - Avsluta" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "Kopiera konfigurationsfil(er)" fvwm-2.6.7/po/fvwm.ar.po0000644000175700017570000002102212673746443012017 00000000000000# Arabic translations for fvwm package. # Copyright (C) 2002 fvwm workers # This file is distributed under the same license as the fvwm package. # Nadim Shaikli # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2002-12-06 08:25+0100\n" "Last-Translator: Nadim Shaikli \n" "Language-Team: Arabic\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 0.9.6\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "قائمة مبنية داخليا" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "شاشة الإعداد" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "ملف إعداد 95" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "أصدر أوامر fvwm" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "أعد تشغيل fvwm" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "أخرج من fvwm" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "المكتب" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\tالأبعاد" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "المكتب: %d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "" #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "القائمة الجذرية" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "الدخول عن بعد" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "برامج الخدمات" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "وحدات Fvwm" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "خيارات نوافذ Fvwm" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "خيارات إعداد Fvwm" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "أعد تنشيط الشاشة" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "أعد عرض الشاشة" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "الخروج من Fvwm" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "إسترجاع الإفتراضي لأكس" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "تركيز بطيئ" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "تركيز بالضعط" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "تركيز بلحاق الفارة" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "خارطة الألوان تلحق بالفارة" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "خارطة الألوان تلحق بالتركيز" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "تشغيل التصفح الكامل " #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "توقيف التصفح الكامل" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "التصفح الأفقي فقط" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "التصفح العمودي فقط" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "تصفح جزئي" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "تصفح كامل مع القلب عند الحواف" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "&حرك" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "غ&ير الحجم" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "ار&فع" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "ا&خفض" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "(عدم) التحويل لأي&قونة" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "(أزل)ت&ثبيت" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "(أزل) الت&كبير" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "اح&ذف" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "أ&غلق" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "تدمير" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "خيارات النافذة" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "أعد تنشيط النافذة" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "أطبع" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "أطبع بالم&قلوب" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "تحكم بالحركة" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "مكاتب" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "قائمة إيقاف الوحدات" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "إيقاف وحدات Fvem" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "إيقاف" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "هل تريد الخروج من Fvwm ؟" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "نعم، أريد الخروج" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "أعد التشغيل" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "إبدأ" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "أظهر Xterm فقط" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "لا، لا تخرج" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "إنشاء ملف خيارات ل fvwm" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "إستعمل هذا النموذج لإنشاء ملف الإعدادات fvwm2rc الخاص بك" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "الملف المنشأ هو ~/.fvwm/.fvwm2rc أو $FVWM_USERDIR/.fvwm2rc" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "بعد الإنشاء، من الممكن تعديل الملف الخيارات fvwm2rc بإستعمال أي" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "محرر نصوص تريده." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "أنشئ الملف المبدئي .fvwm2rc " #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "الملفات التالية إختيارية. أختر الوحدات التي تود أن تخصصها." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "تستطيع نسخهم في الوقت الذي تريد." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "رجوع - خروج" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "إنسخ ملفات التعريف" fvwm-2.6.7/po/fvwm.ru.gmo0000644000175700017570000001201212673746443012206 00000000000000C4YL    =C R_n   ";J Zgw & 5CT \i z  ?D 8_       4 K [ k {      o 5o   + ' , !F 0h      ) 33O+$+1 FQ!m $' %5)[("=]zPy!c'6S9r ()/.$ >9" 24 1 *-' %8,<+0A);@C#!?76=&B5(:3 Geometry&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximizeAfter creation, the fvwm2rc file can then be changed with anyAll Paging OFFBuiltin MenuClick To FocusColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDeskDesk: %d%sDestroyExit FvwmExit fvwmFocus Follows MouseFull Paging && Edge WrapFull Paging ONFvwm Config OpsFvwm ModulesFvwm Window OpsHorizontal Paging OnlyIssue fvwm commandsJust an XtermMore&...No, Don't QuitPartial PagingPrintPrint Re&verseR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRemote LoginsReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSetup 95 ScriptSetup FormSloppy FocusStartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.Use this form to create your fvwm2rc configuration file.UtilitiesVertical Paging OnlyWindow OpsYes, Really QuitYou can always copy them later.deskseditor to suit your own needs.fvwm - Create ConfigurationProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2013-02-12 13:30+0800 Last-Translator: Ivan Gayevskiy Language-Team: Russian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ПозицияЗакр&ыть&УдалитьВ &конец&ПереместитьИзменить &размерС&вернутьПрикр&епитьРа&звернутьПосле создания файл конфигурации может быть изменен простымВыкл. постраничную навигациюГлавное менюФокус по кликуColormap следует за фокусомColormap следует за мышьюАнимация окнаСкопировать файлыСоздать файл конфигурацииСтолСтол: %d%sУни&чтожитьВыход из FVWMВыход из FVWMФокус следует за мышьюРазвернуть и оставить рамкуВкл. постраничную навигациюПараметры конфигурацииМодули FVWMДействия над окнамиГоризонтальный переходСписок команд FVWMОбычный XtermЕщё&...Ой, я передумалТолько наполовинуПечат&ьОбратная печа&тьВ &началоО&бновить окноНа самом деле выйти?Обновить экран (Recapture)Обновить экран (Refresh)Удаленные подключенияСбросить настройки XorgПерезапуститьПерезапустить FVWMEnter - ОтменитьГлавное менюМастер настройки 95Мастер настройкиНе терять фокусПоехалиСтопВыкл. все модулиВыкл. модуль менюБудет создан файл ~/.fvwm/.fvwm2rc или $FVWM_USERDIR/.fvwm2rc.Файлы не обязательны. Выберите модули, которые желаете настроить.Используйте это окно для создания новой конфигурации.УтилитыВертикальный переходП&араметры окнаВыходи уже давайВы можете скопировать их позже.столытекстовым редактором.Создание конфигурацииfvwm-2.6.7/po/FvwmScript.de.gmo0000644000175700017570000000476612673746443013316 00000000000000/C  ,: @ NY^ cn t   &)17 ?JR Zh m"{     " *?7w     0 GQ Vc {      % < U _ x       # /+ $&*('!-,.% ") Show hidden filesAcceleration:ApplyAutoRepeat OnBackgroundBeepBellBell SetupBlankBrowser...CancelClick Volume (%)Config and DemoCycle(s):DPMSDisableDisable xinit backgroundDuration(ms):EnableFile BrowserKeyboardKeyboard SetupMouse configuration:OKOff(s):Path:PatternPitch(Hz):Pixmap:PointerPointer SetupQuitRepeat Delay:Right-handed user|Left-handed userSaveScreen SetupScreen-saverSelected file:Standby(s):Start Delay: Suspend(s):Threshold (pixels):Timeout(s):Uniform color:Volume:xscreensaverProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2003-04-13 11:35+0200 Last-Translator: Andrei Mitrofanow Language-Team: German MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); Zeige versteckte DateienBeschleunigung:AkzeptierenWiederhohlung AktivHintergrundPiebtonLautsprecherLautsprecher KonfigurationLeerBetrachterAbbrechenLautstrke des Klicks (%)Konfiguration und DemoKreislaufDPMSDeaktivierenDeaktiviere HintergrundDauer(ms):AktivierenDateimanagerTastaturKonfiguration der TastaturMaus Konfiguration:OKAus(s):Pfad:PatternTonhhe(Hz)Bilder:ZeigerMaus EinstellungenBeendenWiederhohlverzgerung:Rechtshnder|LinkshnderSpeichernBildschirm EinstellungenBildschirmschonerAuswahl:Standby(s):Startverzgerung:Suspend(s):SchwellwertTimeout(s):Farben:Lautstrke:xscreensaverfvwm-2.6.7/po/fvwm.zh_CN.gmo0000644000175700017570000000725312673746443012574 00000000000000<S( )3:BIO W d o=} +K P[ c mw  '8 GUf n{   ?D,8q   41 f n y ;   " 8 N [ n        % 8 ? P [ l        , 3 : M A` B 9  ,9!Oqx3":', !;/7 8.$*#4+01  %-96< )(5&2 Geometry&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximizeAfter creation, the fvwm2rc file can then be changed with anyBuiltin MenuClick To FocusColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDeskDesk: %d%sDestroyExit FvwmExit fvwmFocus Follows MouseFvwm Config OpsFvwm ModulesFvwm Window OpsIssue fvwm commandsJust an XtermNo, Don't QuitPrintPrint Re&verseR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRemote LoginsReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSetup 95 ScriptSetup FormSloppy FocusStartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.Use this form to create your fvwm2rc configuration file.UtilitiesWindow OpsYes, Really QuitYou can always copy them later.deskseditor to suit your own needs.fvwm - Create ConfigurationProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2004-05-22 16:12+0800 Last-Translator: Funda Wang Language-Team: zh_CN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 几何关闭(&C)删除(&D)降低(&L)移动(&M)大小(&R)最小化(&I)置顶(&S)最大化(&X)创建之后,fvwm2rc 文件就可以用您喜欢的任何内建菜单单击置焦颜色图跟随焦点颜色图跟随鼠标控制动画复制配置文件创建初始的 .fvwm2rc 文件桌面桌面:%d%s摧毁退出 Fvwm退出 fvwm焦点跟随鼠标Fvwm 配置操作Fvwm 模块Fvwm 窗口操作执行 fvwm 命令只是 Xterm不,不要退出打印翻转打印(&V)升起(&A)刷新窗口(&F)真的要退出 Fvwm 吗?重新抓取屏幕刷新屏幕远程登录重置 X 默认值重新启动重新启动 fvwm返回 - 丢弃根菜单设置 95 脚本设置表单粘性置焦开始停止停止 Fvwm 模块停止模块菜单创建的文件是 ~/.fvwm/.fvwm2rc 或 $FVWM_USERDIR/.fvwm2rc。这些文件是可选的。请选择您想要自定义的模块。使用此表单创建您自己的 fvwm2rc 配置文件。实用工具窗口操作是的,真的退出您当然可以稍后再复制。桌面文本编辑器进行更改。fvwm - 创建配置fvwm-2.6.7/po/fvwm.fr.gmo0000644000175700017570000003461513010050461012152 00000000000000   # & ; L m      K = ^Mm 9&,CZlI &.;CST ( 2<Pix O/4K`HuAOPPRFL;VOW/ 83 @Ujs  5I>0U)5CG?& 4 KY_p x  'D +6 = IFV?D KP8 )3 H S]nI:,@*Fq"LHI eAs670$ ULvI P, y} !"""*0"%[""" " """ ""U"A=##L## $J$Z$p$w$$$$"$%%M(%v% }%%%%J%Y &[e& & &&(&':'"P's''''['#( ((I(a(Wy(]([/)])])UG*[*a*X[+U+ ,",8, T,O`,J,,- '-2-G- P- Z-h-Bn--T-.A7.9y.V. /O!/Qq//&//00 $0.0G0\0p000000 011 1/19D1]~1112 2 #2H02 y222292@2Q2333B334 '434R4 p4z4"4O4F5HL55<5+536Y:6U6!6 7U7Kq7Q7;8 K8Ol8K819R:9okjV*0)YH7J2yaq"`ZSRLn&t=}P]srzg/;i6!WCc[<wx% @M>5 {9AbfFQX3-G\mh ~TvDOU8B':, d1E$u(|^ NK_+l?p4e.I# Geometry (Default is 24) (Directory for converted icons) (Full path to store output)&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximize/usr/share/icons can used except the hicolor theme because it's the defaultAfter creation, the fvwm2rc file can then be changed with anyAll Paging OFFAlso it is a good idea to check .xsession-errors in the user home for errors.Application Icon: Builtin MenuBut remember, if the menu doesn't exist, nothing happens.Click To FocusCloseColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDefault is 'FvwmMenu'.Defines which type of menu should be found. Possible name types could be:DeskDesk: %d%sDesktop: DestroyDirectory Icon: Enable this checkbox to insert generated menu(s) IN a menu.Enter here the FULL path of the menu to store. Default path is $FVWM_USERDIR/.menu.Enter in this field the name of the menu (its top title) where the generated menu(s)Exit FvwmExit fvwmFocus Follows MouseFull Paging && Edge WrapFull Paging ONFvwm Config OpsFvwm Menu Desktop ConfigFvwm ModulesFvwm Window OpsGeneral OptionsGenerate Menu(s)Generated icons are saved in $HOME/.fvwm/icons or the directory specified here.HelpHorizontal Paging OnlyIcon directory: Icon size: If 'Use Icons' is enabled and for a directory in a menu no icon is foundIf 'Use Icons' is enabled and for an application no icon is foundIf 'Use Icons' is set, by default 24x24 mini-icons are used. If another size isIf no menus appear check why from within a terminal with 'fvwm-menu-desktop -v'.If the specified icon isn't that size it is converted if ImageMagick is installed.If there are too much menus found an error occurs in .xsession-errors:If this option is set menus are generated with titles. Default is no titles.If you want a single menu only deselect all menus above and fill out the fields below.In this section all XDG menus found on the system are shown. All selected menusIn this section you can define a custom-assembled menu 'foo-bar.menu' placed on anotherInsert in menu: Install-Prefix: Issue fvwm commandsJust an XtermList menus with checkboxes found in $HOME/.config/menus/List menus with checkboxes found in /etc/xdg/menus/Menu Top Title: Menu(s) in a Menu? Menus inMenutype: More&...Multiple Multiple MenuNo No menus found! Check why from within a terminal withNo, Don't QuitNote that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/One limitation exists:Only the name of an icon is needed not the path!Option enables mini-icons in the menu(s).Otherwise no icon appears in the menu for that entry.Output path: Overrides the name of the main desktop environment installed on theOverrides the standard locations for XDG menu definitions. The standardPartial PagingPossible names: gnome, kde, lxde, etc.PrintPrint Re&verseQuitR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRegenerate XDG MenuRegenerate XDG Menu(s)Remote LoginsResetReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSave SettingsSet which menu generation will be used.Sets the used icon theme. Default is 'gnome' but all others found inSetup 95 ScriptSetup FormSingleSingle MenuSloppy FocusSpecifies the menu title of the top menu used by Fvwm's Popup command.StartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.This happens because PipeRead used for menu generation has a command lengthUse Icons? Use Titles? Use this form to create your fvwm2rc configuration file.Used Icon theme: Used Menu Type: UtilitiesVertical Paging OnlyWindow OpsYes Yes, Really QuitYou can always copy them later.applications, settings, preferences, etc. Note if the specified menu typeas default icon is used. But if the gnome icon theme isn'tdesired enter the wanted size in this field.desksdoesn't exist the generated menu is empty!editor to suit your own needs.exactly as the icon directory e.g.fallback theme if no icon is found. Note that the theme name must be writtenfollowing the XDG menu specification only shown in $HOME/.config/menus/.fvwm - Create Configurationif available.installed no default icon appears. Another icon can defined here.is typically set. It is ignored if this field is used.limit of 1000 characters. Sorry for that inconvinience.location as defined in the XDG menu definitions.locations are /etc/xdg/menus andshould insert. For more information see the USAGE section in the man page ofsystem. If a system offers multiple desktop environments $XDG_MENU_PREFIXuse the 'Single Menu' section.will integrate in one Fvwm menu. If you want to generate a custom-assembled menuProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2014-02-27 11:40+0100 Last-Translator: Dominique Michel Language-Team: French Language: French MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); X-Generator: Poedit 1.5.5 Géometrie (Par défaut, 24) (Répertoire pour les icônes converties) (Chemin complêt du fichier de menu)&Fermer&QuitterEn &arrière&Déplacer&Redimensionner(Dé)&Minimiser(Dế)&Fixer(Dé)&Maximiserdans /usr/share/icons peut être utilisée sauf le théme hicolor car c'est le thémeAprès création, vous pouvez éditer ce fichier avec un éditeurToute pagination désactivéeC'est aussi une bonne idée de chercher les erreurs dans ~/.xsession-errors.Icône d'applications: Menu Interneci-dessous. Mais rappelez-vous, si le menu n'existe pas, rien ne se passe.Cliquer pour le focusFermezLes couleurs suivent le focusLes couleurs suivent la sourisContrôler l'animationCopier les fichiersCréez un fichier .fvwm2rc initialLa valeur par défaut est 'FvwmMenu'. Définit quel type de menu doit être trouvé. Les noms des types possiblesBureauBureau: %d%sBureau : &BrûlerAnnuaire d'icône: Activez cette case à cocher pour insérer le menu généré dans un menu.Entrez ici le chemin complet du menu pour l'enregistrer. Par default $FVWM_USERDIR/.menu.Entrez dans ce chanp le nom du menu (son titre principal) où le menu généré devra êtreQuitter fvwmQuitter fvwmLe focus suit la sourisPagination complète && Bord électriquePagination complète activéeOpérations de configConfiguration de Fvwm Menu DesktopModules de FvwmOpérations sur les fenêtresOptions généralesGénérez le menuest installé. Les icônes générées sont sauvegardées sous $HOME/.fvwm/icons ou dans leAidePagination horizontale seulementDossier des icônes: Taille d'icône : Si 'Utiliser des icônes' est actif et qu'aucune icône n'est trouvée dans un dossier,Si 'Utiliser des icônes' est actif et que pour une application aucune icnone n'est trouvée,Si 'Utiliser des icônes' est choisi, par defaut des mini-icones de 24x24 seront utilisés.Si le menu n'apparaît pas, vérifiez pourquoi dans un terminal avec 'fvwm-menu-desktop -v'.Si l'icône specifiée n'exsite pas à cette taille, elle peut être convertie si ImageMagickS'il y a trop de menus trouvés, un message d'erreur apparaît dans .xsession-errors:Si cet option est active les menus sont générés avec des titres. Par défaut sans titre.Si vous voulez un menu unique, désélectionner tous les menus ci-dessus et remplissez les champsDans cette section tous les menus XDG trouvés seront affichés sur le systeme. Tous lesDans cette section vous pouvez customiser un menu 'foo-bar.menu' placé dans un autreInsérer dans le menu: Préfixe de menu : Executer des commandes fvwmJuste XTermLa liste des menus avec des cases à cocher se trouve dans $HOME/.config/menus/La liste des menus avec des cases à cocher se trouve dans /etc/xdg/menus/Titre du menu : Menu(s) dans un menu? Menus dansType de menu : Plus&...Multiple Menu multipleNon Pas de menu trouvé ! Depuis un terminal, contrôlez pourquoi avecNon, on ne quitte pasNotez que des menus identiques trouvés dans /etc/xdg/menus et $HOME/.config/menus/,Il existe une limitation :Seul le nom d'une icône est nécessaire, pas le chemin d'accés.Option pour activer les mini icônes dans le/les menu(s).dossier spécifié ici. Sinon aucune icône apparaît dans le menu pour cette entrée.Chemin de sortie: Écrase le nom de l'environnement principal qui est installé sur le systeme. Écrase l'emplacement standard pour la definition du menu XDG. Les emplacementsPagination partiellepossibles sont: gnome, kde, lxde, etc.ImprimerImpression in&verseQuittez&En avantRa&fraîchir la fenêtreOn quitte vraiment ?Recapturer l'écranRafraîchir l'écranRégénérer le menu XDGRégénérer le(s) menu(s) XDGLogin à distanceRemise à zéroRétablir les défauts de XRedémarrerRedémarrer fvwmQuitterMenu PrincipalSauvez les réglagesApplique quel type de génération de menu sera utilisé.Applique le théme d'icônes utilisé. Par défaut 'gnome', mais toute autre icône trouvéeConfiguration avec Script95Configuration avec FormSimpleMenu simpleFocus fluide Specifiez le titre du menu principal utilisé par la commande de Fvwm.DémarrerStopArrêter des ModulesMenu d'arrêt des ModulesCe ficher est ~/.fvwm/.fvwm2rc ou $FVWM_USERDIR/.fvwm2rc.Ces fichiers sont optionnels. Choisissez les modules à éditer.Cela se produit quand PipeRead a utilisé pour la generation du menu une commandeUtiliser des icônes? Utiliser des titres? Utilisez ce formulaire pour créer votre fichier de configuration.Thème d'icônes: Type de menu utilisé :UtilitairesPagination verticale seulementOpérations sur les fenêtresOui Oui, on quitte vraimentVous pourrez les copier plus tard.peuvent être : applications, settings, preferences, etc. Attention: si le typeest utilisé par defaut. Mais si le théme d'icône de gnome n'est pasSi une autre taille est desirée, entrer la taille voulue dans ce champ.bureauxde menu specifié n'existe pas, le menu généré est vide !pour une configuration à votre convenance.même nom que le dossier des icônes, par exemple :de secour par défaut, si aucune icône n'est trouvée. Notez que le théme doit avoir lesuivant la spécification de menu XDG ne sont montrés que dans $HOME/.config/menus/.fvwm - Créer votre configurationsi disponible.installé, aucune icône n'apparaîtera. D'autres icônes peuvent être definies ici.normalement appliqué. Elle est ignorée si le champ est utilisé. Les nomsqui dépasse la limite de 1000 caractéres. Désolé pour la gêne occassionnée.emplacement comme defini dans les définitions du menu XDG.standards sont /etc/xdg/menus etinséré. Pour plus d'information regardez la section USAGE dans la page man deSi le systeme offre plusieurs environneents de bureau, $XDG_MENU_PREFIX estun menu client, utlisez la section 'Menu simple'.menus selectionnés seront intégrés dans un menu Fvwm. Si vous voulez générerfvwm-2.6.7/po/FvwmScript.fr.gmo0000644000175700017570000000504113010050461013266 00000000000000/C  ,: @ NY^ cn t   &)17 ?JR Zh m"{     " *e7  &;QZ _j |   . 6 L ] d }           # /+ $&*('!-,.% ") Show hidden filesAcceleration:ApplyAutoRepeat OnBackgroundBeepBellBell SetupBlankBrowser...CancelClick Volume (%)Config and DemoCycle(s):DPMSDisableDisable xinit backgroundDuration(ms):EnableFile BrowserKeyboardKeyboard SetupMouse configuration:OKOff(s):Path:PatternPitch(Hz):Pixmap:PointerPointer SetupQuitRepeat Delay:Right-handed user|Left-handed userSaveScreen SetupScreen-saverSelected file:Standby(s):Start Delay: Suspend(s):Threshold (pixels):Timeout(s):Uniform color:Volume:xscreensaverProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2014-02-27 12:02+0100 Last-Translator: Dominique Michel Language-Team: French Language: French MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); Montrer les fichiers cachsAcclration :AppliquerRptition ActiveFondBipClocheConfiguration de la ClocheVideParcourirAnnulerVolume d'un clic (%)Configuration et dmoCycle(s)DPMSDsactiverPas de fond xinitDure(ms) :ActiverNavigateur de fichiersClavierConfiguration du ClavierSouris pour un :OKExtinction(s) :Chemin :MotifTon (Hz)Image :SourisConfiguration de la sourisQuitterDlai de Rptition :Droitier|GaucherSauverConfiguration de l'cranconomiseur d'cranFichier slectionn :Interrompre(s) :Dlai de Dpart :Veille(s) :Seuil (pixels) :Dlai(s) :Couleur uniforme :Volume:conomiseur d'cranfvwm-2.6.7/po/FvwmScript.ar.po0000644000175700017570000001367112673746443013157 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR fvwm workers # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2003-04-13 11:35+0200\n" "Last-Translator: NEEDS TRANSLATION \n" "Language-Team: Should be Arabic \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ascii\n" "Content-Transfer-Encoding: 8bit\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "" fvwm-2.6.7/po/FvwmScript.fr.po0000644000175700017570000001517612750322415013147 00000000000000# French translations for fvwm package # Traduction anglaise du package fvwm. # Copyright (C) 2002 fvwm workers # This file is distributed under the same license as the fvwm package. # Olivier Chapuis , 2002. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2014-02-27 12:02+0100\n" "Last-Translator: Dominique Michel \n" "Language-Team: French\n" "Language: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "Configuration de la Cloche" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "Appliquer" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "Sauver" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "Quitter" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "Bip" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "Volume:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "Ton (Hz)" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "Dure(ms) :" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "Cloche" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "Configuration du Clavier" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "Volume d'un clic (%)" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "Rptition Active" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "Dlai de Dpart :" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "Dlai de Rptition :" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "Clavier" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "Configuration de la souris" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "Droitier|Gaucher" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "Souris pour un :" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "Acclration :" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "Seuil (pixels) :" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "Souris" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "Configuration de l'cran" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "Fond" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "Couleur uniforme :" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "Image :" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "Parcourir" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "Pas de fond xinit" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "conomiseur d'cran" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "Vide" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "Dlai(s) :" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "Motif" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "Cycle(s)" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "DPMS" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "Activer" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "Dsactiver" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "Interrompre(s) :" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "Veille(s) :" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "Extinction(s) :" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "conomiseur d'cran" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "Configuration et dmo" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "Navigateur de fichiers" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "OK" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "Annuler" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "Chemin :" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr "Montrer les fichiers cachs" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "Fichier slectionn :" fvwm-2.6.7/po/FvwmScript.sv_SE.po0000644000175700017570000001517412673746443013574 00000000000000# Swedish translations for fvwm package # Svenska versttningar fr paket fvwm. # Copyright (C) 2003 fvwm workers # This file is distributed under the same license as the fvwm package. # Johan Svedberg , 2003. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2003-10-19 13:33+0200\n" "Last-Translator: Johan Svedberg \n" "Language-Team: Swedish\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "Ringklockinstllningar" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "Verkstll" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "Spara" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "Avsluta" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "Tuta" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "Volym:" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "Tonhjd(Hz):" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "Varaktighet(ms):" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "Ringklocka" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "Tangentbordsinstllningar" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "Klickvolym (%)" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "Autorepetition p" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "Startfrdrjning: " #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "Repetitionsfrdrjning:" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "Tangentbord" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "Pekdonsinstllningar" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "Hgerhnt anvndare|Vnsterhnt anvndare" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "Muskonfiguration:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "Acceleration:" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "Nedre grns (bildpunkter):" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "Pekare" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "Skrminstllningar" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "Bakgrund" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "Genomgende frg:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "Punktgrafikbild:" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "Blddrare..." #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "Inaktivera xinit-bakgrund" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "Skrmslckare" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "Tom" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "Timeout(er):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "Mnster" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "Cykel(s)" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "DPMS" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "Aktivera" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "Inaktivera" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "Standby(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "Suspendering(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "Avstngning(s):" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "xscreensaver" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "Konfiguration och demonstration" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "Filhanterare" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "Ok" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "Avbryt" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "Skvg:" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr " Visa dolda filer" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "Vald fil:" fvwm-2.6.7/po/fvwm.es.gmo0000644000175700017570000003371212673746443012201 00000000000000    + < ] z     K =NM] 9-DVjI ;-SiT  &:Sbr O5JH_AOP:RFL%VrOWq 83*?T]r { 5I(0?)p5CG)q&  5CIZ bo  'D   ' 3F@?DK:8  2 =GXIx:,**0["zLH3 OA]670 ?L`IP ,g !!!!#!)!" !"+"3":"I" Z"f"Tv"["'#G9## #E###$8$"M$%p$$U$ %%&%=%F%C]%Y%U% Q& _&k&'&&&& &''.'W>'''''Z'R>(P(X(\;)N)Z)`B*V*h*c+z+++C+>+7,L,c,l,, , ,,C,,X-Z-/l-3-B-.R*.Q}..(. //$/ +/5/I/\/p////// //00&0+<0Th0000 0 1Q1h1o1u11@1N1Z+222C223 &313H3 \3f3$}3S3B3.94 h4t40494V4LP555W54$6Y6x66S6K 7 U7Sv7njiU)/(XG6I1x`p!YRQKm%s<|O\rqyf.:h5 VBb_Z;vw$ ~?L=4 z8@aeEPW2,F[lg }SuCNT7A&9+ c0D#t'{] MJ^*k>o3d-H" Geometry (Default is 24) (Directory for converted icons) (Full path to store output)&Close&Delete&Lower&Move&Resize(De)&Iconify(Un)&Stick(Un)Ma&ximize/usr/share/icons can used except the hicolor theme because it's the defaultAfter creation, the fvwm2rc file can then be changed with anyAll Paging OFFAlso it is a good idea to check .xsession-errors in the user home for errors.Application Icon: Builtin MenuBut remember, if the menu doesn't exist, nothing happens.Click To FocusColormap Follows FocusColormap Follows MouseControl AnimationCopy Config File(s)Create a starting .fvwm2rc fileDefault is 'FvwmMenu'.Defines which type of menu should be found. Possible name types could be:DeskDesk: %d%sDesktop: DestroyDirectory Icon: Enable this checkbox to insert generated menu(s) IN a menu.Enter here the FULL path of the menu to store. Default path is $FVWM_USERDIR/.menu.Enter in this field the name of the menu (its top title) where the generated menu(s)Exit FvwmExit fvwmFocus Follows MouseFull Paging && Edge WrapFull Paging ONFvwm Config OpsFvwm Menu Desktop ConfigFvwm ModulesFvwm Window OpsGeneral OptionsGenerate Menu(s)Generated icons are saved in $HOME/.fvwm/icons or the directory specified here.HelpHorizontal Paging OnlyIcon directory: Icon size: If 'Use Icons' is enabled and for a directory in a menu no icon is foundIf 'Use Icons' is enabled and for an application no icon is foundIf 'Use Icons' is set, by default 24x24 mini-icons are used. If another size isIf no menus appear check why from within a terminal with 'fvwm-menu-desktop -v'.If the specified icon isn't that size it is converted if ImageMagick is installed.If there are too much menus found an error occurs in .xsession-errors:If this option is set menus are generated with titles. Default is no titles.If you want a single menu only deselect all menus above and fill out the fields below.In this section all XDG menus found on the system are shown. All selected menusIn this section you can define a custom-assembled menu 'foo-bar.menu' placed on anotherInsert in menu: Install-Prefix: Issue fvwm commandsJust an XtermList menus with checkboxes found in $HOME/.config/menus/List menus with checkboxes found in /etc/xdg/menus/Menu Top Title: Menu(s) in a Menu? Menus inMenutype: More&...Multiple Multiple MenuNo No menus found! Check why from within a terminal withNo, Don't QuitNote that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/One limitation exists:Only the name of an icon is needed not the path!Option enables mini-icons in the menu(s).Otherwise no icon appears in the menu for that entry.Output path: Overrides the name of the main desktop environment installed on theOverrides the standard locations for XDG menu definitions. The standardPartial PagingPossible names: gnome, kde, lxde, etc.PrintPrint Re&verseQuitR&aiseRe&fresh WindowReally Quit Fvwm?Recapture ScreenRefresh ScreenRegenerate XDG MenuRegenerate XDG Menu(s)Remote LoginsResetReset X defaultsRestartRestart fvwmReturn - DismissRoot MenuSave SettingsSet which menu generation will be used.Sets the used icon theme. Default is 'gnome' but all others found inSetup 95 ScriptSetup FormSingleSingle MenuSloppy FocusSpecifies the menu title of the top menu used by Fvwm's Popup command.StartStopStop Fvwm ModulesStop Module MenuThe file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.These files are optional. Select the modules you want to customize.This happens because PipeRead used for menu generation has a command lengthUse Icons? Use Titles? Use this form to create your fvwm2rc configuration file.Used Icon theme: Used Menu Type: UtilitiesVertical Paging OnlyWindow OpsYes Yes, Really QuitYou can always copy them later.applications, settings, preferences, etc. Note if the specified menu typeas default icon is used. But if the gnome icon theme isn'tdesired enter the wanted size in this field.desksdoesn't exist the generated menu is empty!editor to suit your own needs.exactly as the icon directory e.g.fallback theme if no icon is found. Note that the theme name must be writtenfollowing the XDG menu specification only shown in $HOME/.config/menus/.fvwm - Create Configurationif available.installed no default icon appears. Another icon can defined here.is typically set. It is ignored if this field is used.limit of 1000 characters. Sorry for that inconvinience.location as defined in the XDG menu definitions.locations are /etc/xdg/menus andshould insert. For more information see the USAGE section in the man page ofsystem. If a system offers multiple desktop environments $XDG_MENU_PREFIXuse the 'Single Menu' section.will integrate in one Fvwm menu. If you want to generate a custom-assembled menuProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2013-10-25 22:45+0200 Last-Translator: Adonai Martin Language-Team: Spanish Language: Spanish MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit Geometra (Estndar es 24) (Directorio de iconos convertidos) (Ruta completa para almacenar la salida)&Cerrar&EliminarReducir&Mover&Redimensionar(Des)&Iconificar(Des)&Pegar(Des)Ma&ximizar/usr/share/icons pueden ser usados. Exceptuando tema 'hicolor' porque es el tema porDespus de la creacin, el archivo .fvwm2rc puede ser cambiado posteriormente con cualquierTodo paginado OFFUna buena idea, es comprobar los mensajes de error en .xsession-errors.Icono Aplicacin: Men Internocampos siguientes. Pero recuerde: si el men no existe, no pasa nada.Foco al hacer clicMapa de colores por enfoqueMapa de colores siguiendo ratnControl de AnimacinCopiar Archivo(s) de ConfiguracinCrear un archivo de comienzo .fvwm2rcPredeterminado es 'FvwmMenu'.Define qu tipo de men debe ser encontrado. Posibles tipos pueden ser: applications,EscritorioEscritorio: %d%sEscritorio: DestruirIcono de carpeta: Habilitar este checkbox para insertar menu(s) generados EN un men.Escriba aqu la ruta COMPLETA en el men para guardarla. Estndar es $FVWM_USERDIR/.menu.Escriba en el campo de nombre de men (encima del ttulo) donde los men(s) generadosSalir de FvwmCerrar fvwmFoco siguiendo al ratnPaginado Completo && Redondeo de BordesPaginado completo ONOpciones de configuracinFvwm Menu Desktop ConfiguracinModulos FvwmOpciones de ventanaOpciones generalesGenerar Men(s)Los iconos generados se guardan en $HOME/.fvwm/icons o el directorio especificado aqu.AyudaSlo Paginado HorizontalDirectorio de iconos: Tamao de icono: Si 'Usar Iconos' est activado y para un directorio en un men ningn icono es encontrado,Si 'Usar Iconos' est habilitado y para una aplicacin ningn icono es encontrado,Si 'Usar Iconos' est seleccionado, iconos de 24x24 sern usados por defecto. SiSi ningun men aparece, compruebe la causa desde un terminal con 'fvwm-menu-desktop -v'.Si el icono especificado no es de ese tamao, ser convertido, si ImageMagic est instalado.Si se encuentran muchos mens, aparece el siguiente error en .xsession-errors:Si esta opcin est activada, los mens son generados con ttulos. Estndar es sin ttulo.Si desea tan solo un nico men, anule la seleccin de todos los mens anteriores y complete losEn esta seccin todos los mens XDG encontrados en el sistema son mostrados. Todos losEn esta seccin usted puede crear un men 'foo-bar.menu', que fue definido en otro lugar diferente a lasInsertar en el men: Prefijo instalacin:Invocar comandos fvwmSlo una XtermLista los mens encontrados en $HOME/.config/menus/ con checkboxes.Lista los mens encontrados en /etc/xdg/menus/ con checkboxes.Ttulo sobre men: Men(s) en el men? Mens enTipo de men: Ms&...Mltiple Men mltipleNo No se han encontrado mens! Compruebe por qu desde un terminal conNo, no deseo cerrarNota: mens iguales encontrados en /etc/xdg/menus UND $HOME/.config/menus/, siguiendo laExiste un lmite:el nombre de un icono es necesario, no la ruta!Opcin para activar mini-iconos en el(los) men(s).De otra manera ningn icono aparecer en el men para esa entrada.Ruta de salida: Sobreescribir el nombre del escritorio principal, que fue instalado en el sistema.Sobreescribir la ubicacin estndar para las definiciones de men XDG. Los sitiosPaginado ParcialPosibles nombres: gnome, kde, lxde, etc.ImprimirImprimir Re&versoCerrar&AumentarAc&tualizar VentanaDesea cerrar Fvwm?Recapturar PantallaActualizar PantallaRegenerar Men XDGRegenerar Men(s) XDGInicio de sesin remotoResetearRestaurar valores por defectoReiniciarReiniciar fvwmVolver - TerminarMen principalGuardar ConfiguracinEstablecer el men de generacin utilizado.Establecer el icono de tema usado. Por defecto es 'gnome', pero otros encontrados enGuin de configuracin FVWM95Formulario de configuracinnicoMen nicoFoco relajadoEspecifica el ttulo del men principal que es usado por el popup comando Fvwm's.InicioPararParar Mdulos FvwmMen Parar MdulosEl archivo creado es ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc.Estos archivos son opcionales. Seleccione los mdulos que quiera personalizar.Esto sucede, porque PipeRead usada para generar el men tiene un lmite de 100 caracteres.Usar Iconos? Utilizar ttulos? Use este formulario para crear el archivo de configuracin .fvwm2rcIcono de tema usado: Tipo de men usado: UtilidadesSlo Paginado VerticalOpciones de VentanaS S, confirmo el cierrePuede siempre copiarlos ms adelantesettings, preferences, etc. Atencin, si el tipo de men especificado no existe, elser usado por defecto. Pero si el icono del tema de gnome no estdesea otro tamao, establzcalo en este campo.escritoriosmen generado est vaco!editor para adaptarse a sus propias necesidades.ser escrito exactamente como el directorio de los iconos:defecto de reserva si ningn icono es encontrado. Atencin al nombre del tema, debe deespecificacin de men XDG, son solamente mostrados en $HOME/.config/menus/.fvwm - Crear Configuracinsi est disponible.instalado, ningn icono aparecer por defecto. Otro icono puede ser definido aqu. Sloseleccionado, pero se ignora si este campo es usado.Perdn por este inconveniente.especificaciones del men XDG.estndar son /etc/xdg/menus ydeberan insertarse. Para ms informacin vea la seccin de USO en la pgina man deSi un sistema ofrece mltiples escritorios, $XDG_MENU_PREFIX es tpicamenteutilice la seccin 'Men nico'.mens seleccionados, son integrados en un men Fvwm. Si desea crear su men propio,fvwm-2.6.7/po/fvwm.de.po0000644000175700017570000005363612673746443012025 00000000000000# German translations for fvwm package # Copyright (C) 2013 fvwm workers # This file is distributed under the same license as the fvwm package. # Andrei Mitrofanow , 2003. # Thomas Funk , 2013 # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2013-10-25 22:45+0200\n" "Last-Translator: Thomas Funk \n" "Language-Team: German\n" "Language: German\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "Internes Men" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "Konfiguration mit Form" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "Konfiguration mit Script95" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "Fvwm-Konsole" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "Fvwm neu starten" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "Fvwm beenden" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "Arbeitsplatz" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\tGeometrie" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "Arbeitsplatz: %d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "Mehr&..." #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "Haupt Menu" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "Entfernt Anmelden" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "Werkzeuge" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "Module von Fvwm" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "Fenster" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "Konfiguration" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "Bildschirm neuzeichnen" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "Bildschirm speichern" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "Fvwm beenden" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "X Voreinstellungen setzen" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "Fokus flssig" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "Klick fr Fokus" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "Fokus folgt Maus" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "Farbpalette folgt Maus" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "Farbpalette folgt Fokus" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "Seitenbergang" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "Seitenbergang aus" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "Seitenbergang horizontal" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "Seitenbergang vertikale" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "Seitenbergang teilweise" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "Seitenbergang && Ecken" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "&Verschieben" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "&Grsse ndern" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "An&heben" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "Ab&senken" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "(De)&Minimierer" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "(Los)&Festklemmer" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "(De)Ma&ximierer" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "&Lsche" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "&Schliesse" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "&Zerstre" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "Fenster" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "Fester erneuern" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "Drucken" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "Drucken (Rckseite)" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "Animationskontrolle" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "Arbeitsplatz" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "Fvwm-Module stoppen" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "Fvwm-Module stoppen" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "Stop" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "Fvwm beenden?" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "Ja, fvwm beenden" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "Neustart" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "Start" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "XTerm" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "Nein, fvwm nicht beenden" # FvwmForm #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "fvwm - Erzeuge Konfiguration" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "Nutze dieses Formular um fvwm2rc zu erzeugen" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "Die Datei ist ~/.fvwm/.fvwm2rc oder $FVWM_USERDIR/.fvwm2rc." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "Nach dem Erzeugen, knnen Sie die Datei mit einem Editor" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "an Ihre Wnsche anpassen" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "Erzeuge eine Startdatei .fvwm2rc" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "Diese Dateien sind nicht notwendig. Die Auswahl der Module anpassen" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "Sie knnen diese spter kopieren" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "Annehmen - Schliessen" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "Konfigurationsdateien kopieren" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 51 msgid "Fvwm Menu Desktop Config" msgstr "Fvwm Menu Desktop Konfiguration" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 58 msgid "Multiple Menu" msgstr "Mehrfachmen" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 66 msgid "Menus in" msgstr "Mens in" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 95 msgid "No menus found! Check why from within a terminal with" msgstr "Keine Mens gefunden! In einem Terminal checken warum mit" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 109 msgid "Single Menu" msgstr "Einzelmen" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 114 msgid "If you want a single menu only deselect all menus above and fill out the fields below." msgstr "Fr ein Einzelmen alle nicht bentigten Mens deselektieren und die Felder unten ausfllen." #. ./bin/fvwm-menu-desktop-config.fpl.in: line 116 msgid "But remember, if the menu doesn't exist, nothing happens." msgstr "Bitte beachten: wenn ein Men leer ist, passiert nichts." #. ./bin/fvwm-menu-desktop-config.fpl.in: line 120 msgid "Menu Top Title: " msgstr "Men Top Titel: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 123 msgid " " msgstr " " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 124 msgid "Install-Prefix: " msgstr "Install-Prefix: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 128 msgid "Desktop: " msgstr "Desktop: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 132 msgid "Menutype: " msgstr "Mentyp: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 141 msgid "General Options" msgstr "Generelle Optionen" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 146 msgid "Used Menu Type: " msgstr "Verwendeter Mentyp: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 149 msgid "Multiple " msgstr "Mehrfach " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 150 msgid "Single" msgstr "Einzel" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 153 msgid "Use Icons? " msgstr "Icons verwenden? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 155 msgid "Yes " msgstr "Ja " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 156 msgid "No " msgstr "Nein " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 159 msgid "Icon size: " msgstr "Icongre: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 161 msgid " (Default is 24)" msgstr "(Default ist 24)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 164 msgid "Use Titles? " msgstr "Titel verwenden? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 170 msgid "Used Icon theme: " msgstr "Benutzter Icontheme: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 174 msgid "Menu(s) in a Menu? " msgstr "Men(s) in dem Men? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 180 msgid "Insert in menu: " msgstr "Einfgen in Men: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 184 msgid "Directory Icon: " msgstr "Verzeichnis-Icon: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 188 msgid "Application Icon: " msgstr "Applikations-Icon: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 192 msgid "Icon directory: " msgstr "Icon-Verzeichnis: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 194 msgid " (Directory for converted icons)" msgstr " (fr konvertierte Icons)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 197 msgid "Output path: " msgstr "Ausgabepfad: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 199 msgid " (Full path to store output)" msgstr " (voller Speicherpfad der Ausgabe)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 209 msgid "Generate Menu(s)" msgstr "Men(s) erstellen" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 235 msgid "Save Settings" msgstr "Settings speichern" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 262 msgid "Reset" msgstr "Zurcksetzen" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 264 msgid "Help" msgstr "Hilfe" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 266 msgid "Quit" msgstr "Beenden" #. ./bin/fvwm-menu-desktop.in: line 472 msgid "Regenerate XDG Menu(s)" msgstr "XDG Menu(s) neu erstellen" #. ./bin/fvwm-menu-desktop.in: line 515 msgid "Regenerate XDG Menu" msgstr "XDG Menu neu erstellen" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 17 msgid "In this section you can define a custom-assembled menu 'foo-bar.menu' placed on another" msgstr "In dieser Sektion knnen Sie ein eigenerstelltes Men 'foo-bar.menu', das an einem anderen Ort als in" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 19 msgid "location as defined in the XDG menu definitions." msgstr "den XDG Menspezifikationen definiert ist, erstellen." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 24 msgid "Specifies the menu title of the top menu used by Fvwm's Popup command." msgstr "Spezifiziert den Mentitel des Topmens, das Fvwm's Popup Kommando verwendet." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 26 msgid " " msgstr " " #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 27 msgid "Default is 'FvwmMenu'." msgstr "Default ist 'FvwmMenu'." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 32 msgid "Overrides the standard locations for XDG menu definitions. The standard" msgstr "berschreibt die Standardorte fr die XDG Mendefinitionen. Die Standardorte" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "locations are /etc/xdg/menus and" msgstr "sind /etc/xdg/menus und" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "if available." msgstr "(wenn vorhanden)." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 40 msgid "Overrides the name of the main desktop environment installed on the" msgstr "berschreibt den Namen der Haupt-Desktop-Umgebung, welche auf dem System" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 43 msgid "system. If a system offers multiple desktop environments $XDG_MENU_PREFIX" msgstr "installiert ist. Wenn ein System mehrere Desktop-Umgebungen bereitstellt, ist" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 46 msgid "is typically set. It is ignored if this field is used." msgstr "normalerweise $XDG_MENU_PREFIX gesetzt. Die Variable wird jedoch ignoriert," #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 49 msgid "Possible names: gnome, kde, lxde, etc." msgstr "wenn dieses Feld benutzt wird. Mgliche Namen: gnome, kde, lxde, etc." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 54 msgid "Defines which type of menu should be found. Possible name types could be:" msgstr "Definiert welcher Mentyp gefunden werden soll. Mgliche Typen knnten sein:" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 57 msgid "applications, settings, preferences, etc. Note if the specified menu type" msgstr "applications, settings, preferences, etc. Achtung, wenn das hier spezifizierte" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 60 msgid "doesn't exist the generated menu is empty!" msgstr "Men nicht existiert, ist das erstellte Men leer!" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 17 msgid "In this section all XDG menus found on the system are shown. All selected menus" msgstr "In diesem Bereich werden alle XDG Mens angezeigt, die auf dem System gefunden werden." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 19 msgid "will integrate in one Fvwm menu. If you want to generate a custom-assembled menu" msgstr "Alle ausgewhlten Mens werden in einem Fvwm-Men integriert. Wenn Sie ein eigens" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 21 msgid "use the 'Single Menu' section." msgstr "zusammengestelltes Menu erstellen wollen, benutzen Sie die 'Einzelmen' Sektion." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 28 msgid "List menus with checkboxes found in /etc/xdg/menus/" msgstr "Listet in /etc/xdg/menus/ gefundene Mens mit Checkboxen auf." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 36 msgid "List menus with checkboxes found in $HOME/.config/menus/" msgstr "Listet in $HOME/.config/menus/ gefundene Mens mit Checkboxen auf" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 42 msgid "Note that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/" msgstr "Anmerkung: gleiche Mens, die in /etc/xdg/menus UND $HOME/.config/menus/ gefunden werden," #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 44 msgid "following the XDG menu specification only shown in $HOME/.config/menus/." msgstr "werden der XDG Menspezifikation folgend nur unter $HOME/.config/menus/ angezeigt." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 48 msgid "If no menus appear check why from within a terminal with 'fvwm-menu-desktop -v'." msgstr "Wenn keine Mens erscheinen, von einem Terminal mit 'fvwm-menu-desktop -v' checken warum." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 50 msgid "Also it is a good idea to check .xsession-errors in the user home for errors." msgstr "Auch ist es eine gute Idee in .xsession-errors nach Fehlermeldungen zu schauen." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 54 msgid "One limitation exists:" msgstr "Es existiert eine Limitierung:" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 56 msgid "If there are too much menus found an error occurs in .xsession-errors:" msgstr "Wenn zuviele Mens gefunden werden, taucht folgende Fehlemeldung in .xsession-errors auf:" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 62 msgid "This happens because PipeRead used for menu generation has a command length" msgstr "Das passiert, weil PipeRead, das zum generieren des Mens verwendet wird, eine Limitierung" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 64 msgid "limit of 1000 characters. Sorry for that inconvinience." msgstr "von 1000 Zeichen fr ein Kommando hat. Entschuldigung fr diese Unannehmlichkeit." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 18 msgid "Set which menu generation will be used." msgstr "Setzt die zu verwendende Mengenerierungsart." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 23 msgid "Option enables mini-icons in the menu(s)." msgstr "Option aktiviert Mini-Icons in dem/den Men(s)." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 28 msgid "If 'Use Icons' is set, by default 24x24 mini-icons are used. If another size is" msgstr "Wenn 'Icons verwenden' gesetzt ist, werden per default 24x24 Mini-Icons verwendet." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 31 msgid "desired enter the wanted size in this field." msgstr "Wenn eine andere Gre verwendet werden soll, in diesem Feld eintragen." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 36 msgid "If the specified icon isn't that size it is converted if ImageMagick is installed." msgstr "Wenn das Icon in der Gre nicht vorhanden ist, wird es konvertiert, falls ImageMagick" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 39 msgid "Generated icons are saved in $HOME/.fvwm/icons or the directory specified here." msgstr "installiert ist. Generierte Icons werden unter $HOME/.fvwm/icons oder dem hier" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 42 msgid "Otherwise no icon appears in the menu for that entry." msgstr "angegebenen Verzeichnis gespeichert. Sonst taucht kein Icon im Men fr den Eintrag auf." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 47 msgid "Sets the used icon theme. Default is 'gnome' but all others found in" msgstr "Setzt den Icontheme. Default ist 'gnome', aber alle die unter /usr/share/icons gefunden" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 50 msgid "/usr/share/icons can used except the hicolor theme because it's the default" msgstr "werden, knnen verwendet werden. Ausgenommen 'hicolor', weil dieser der default" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 53 msgid "fallback theme if no icon is found. Note that the theme name must be written" msgstr "Fallback Theme ist, wenn kein Icon gefunden wird. Es ist wichtig, dass der Themename" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 56 msgid "exactly as the icon directory e.g." msgstr "exakt gleich wie das Verzeichnis geschrieben wird:" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 61 msgid "If 'Use Icons' is enabled and for a directory in a menu no icon is found" msgstr "Wenn 'Icons verwenden' gesetzt ist und fr ein Verzeichnis kein Icon gefunden wird, wird" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 64 msgid "as default icon is used. But if the gnome icon theme isn't" msgstr "als Defaulticon verwendet. Wenn jedoch der Gnome-Icontheme nicht" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 67 msgid "installed no default icon appears. Another icon can defined here." msgstr "installiert ist, taucht auch kein Icon fr den Eintrag auf. Darum kann hier ein anderes" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 70 msgid "Only the name of an icon is needed not the path!" msgstr "Defaulticon definiert werden. Es muss nur der Name, nicht der Pfad angegeben werden!" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 75 msgid "If 'Use Icons' is enabled and for an application no icon is found" msgstr "Wenn 'Icons verwenden' gesetzt ist, aber fr eine Applikation kein Icon gefunden wird, wird" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 89 msgid "Enable this checkbox to insert generated menu(s) IN a menu." msgstr "Aktivieren Sie diese Checkbox, um erstellte Mens IN einem Men einzubinden." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 94 msgid "Enter in this field the name of the menu (its top title) where the generated menu(s)" msgstr "Hier den Namen des Mens (seinen Toptitel) eintragen, wo die erstellten Mens" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 97 msgid "should insert. For more information see the USAGE section in the man page of" msgstr "eingebunden werden sollen. Fr weitere Informationen siehe die USAGE Sektion von" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 105 msgid "If this option is set menus are generated with titles. Default is no titles." msgstr "Wenn diese Option gesetzt ist, werden Mens mit Titeln erstellt. Default ist ohne Titel." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 110 msgid "Enter here the FULL path of the menu to store. Default path is $FVWM_USERDIR/.menu." msgstr "Hier den VOLLEN Speicherpfad des Fvwm-Mens eintragen. Default ist $FVWM_USERDIR/.menu." fvwm-2.6.7/po/FvwmScript.pot0000644000175700017570000001364612673746443012744 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR fvwm workers # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 2 msgid "Bell Setup" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 44 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 43 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 47 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 132 msgid "Apply" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 62 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 66 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 170 msgid "Save" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 80 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 89 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 94 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 235 msgid "Quit" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 95 msgid "Beep" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 130 msgid "Volume:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 156 msgid "Pitch(Hz):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 182 msgid "Duration(ms):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-BellSetup: line 207 msgid "Bell" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 2 msgid "Keyboard Setup" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 120 msgid "Click Volume (%)" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 133 msgid "AutoRepeat On" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 159 msgid "Start Delay: " msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 185 msgid "Repeat Delay:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-KeyboardSetup: line 210 msgid "Keyboard" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 2 msgid "Pointer Setup" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 108 msgid "Right-handed user|Left-handed user" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 122 msgid "Mouse configuration:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 150 msgid "Acceleration:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 177 msgid "Threshold (pixels):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-PointerSetup: line 202 msgid "Pointer" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 2 msgid "Screen Setup" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 264 msgid "Background" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 279 msgid "Uniform color:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 394 msgid "Pixmap:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 425 msgid "Browser..." msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 468 msgid "Disable xinit background" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 500 msgid "Screen-saver" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 514 msgid "Blank" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 528 msgid "Timeout(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 554 msgid "Pattern" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 569 msgid "Cycle(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 614 msgid "DPMS" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 628 #. #-#-#-#-# duplicate #-#-#-#-# #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 768 msgid "Enable" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 643 msgid "Disable" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 657 msgid "Standby(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 684 msgid "Suspend(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 711 msgid "Off(s):" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 754 msgid "xscreensaver" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-ScreenSetup: line 794 msgid "Config and Demo" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 2 msgid "File Browser" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 42 msgid "OK" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 58 msgid "Cancel" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 86 msgid "Path:" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 181 msgid " Show hidden files" msgstr "" #. ./modules/FvwmScript/Scripts/FvwmScript-FileBrowser: line 246 msgid "Selected file:" msgstr "" fvwm-2.6.7/po/remove-potcdate.sin0000644000175700017570000000066012673746443013715 00000000000000# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } fvwm-2.6.7/po/FvwmScript.sv_SE.gmo0000644000175700017570000000502512673746443013732 00000000000000/C  ,: @ NY^ cn t   &)17 ?JR Zh m"{     " *B7z     -6 ;F`q z     $ )< f l           # /+ $&*('!-,.% ") Show hidden filesAcceleration:ApplyAutoRepeat OnBackgroundBeepBellBell SetupBlankBrowser...CancelClick Volume (%)Config and DemoCycle(s):DPMSDisableDisable xinit backgroundDuration(ms):EnableFile BrowserKeyboardKeyboard SetupMouse configuration:OKOff(s):Path:PatternPitch(Hz):Pixmap:PointerPointer SetupQuitRepeat Delay:Right-handed user|Left-handed userSaveScreen SetupScreen-saverSelected file:Standby(s):Start Delay: Suspend(s):Threshold (pixels):Timeout(s):Uniform color:Volume:xscreensaverProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2003-10-19 13:33+0200 Last-Translator: Johan Svedberg Language-Team: Swedish MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); Visa dolda filerAcceleration:VerkstllAutorepetition pBakgrundTutaRingklockaRingklockinstllningarTomBlddrare...AvbrytKlickvolym (%)Konfiguration och demonstrationCykel(s)DPMSInaktiveraInaktivera xinit-bakgrundVaraktighet(ms):AktiveraFilhanterareTangentbordTangentbordsinstllningarMuskonfiguration:OkAvstngning(s):Skvg:MnsterTonhjd(Hz):Punktgrafikbild:PekarePekdonsinstllningarAvslutaRepetitionsfrdrjning:Hgerhnt anvndare|Vnsterhnt anvndareSparaSkrminstllningarSkrmslckareVald fil:Standby(s):Startfrdrjning: Suspendering(s):Nedre grns (bildpunkter):Timeout(er):Genomgende frg:Volym:xscreensaverfvwm-2.6.7/po/FvwmScript.ru.gmo0000644000175700017570000000556612673746443013353 00000000000000/C  ,: @ NY^ cn t   &)17 ?JR Zh m"{     " *7/N~ '   ,9W p~$#! '' O n s   !   : V i       & 6 U i    # /+ $&*('!-,.% ") Show hidden filesAcceleration:ApplyAutoRepeat OnBackgroundBeepBellBell SetupBlankBrowser...CancelClick Volume (%)Config and DemoCycle(s):DPMSDisableDisable xinit backgroundDuration(ms):EnableFile BrowserKeyboardKeyboard SetupMouse configuration:OKOff(s):Path:PatternPitch(Hz):Pixmap:PointerPointer SetupQuitRepeat Delay:Right-handed user|Left-handed userSaveScreen SetupScreen-saverSelected file:Standby(s):Start Delay: Suspend(s):Threshold (pixels):Timeout(s):Uniform color:Volume:xscreensaverProject-Id-Version: fvwm POT-Creation-Date: 2002-11-28 14:23+0100 PO-Revision-Date: 2013-02-12 14:20+0800 Last-Translator: Ivan Gayevskiy Language-Team: Russian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Отображать скрытые файлыУскорение:ПрименитьАвтоповтор Вкл.ФонСпикерОповещениеНастройка оповещенийПустоОбзор...ОтменаВыбор громкостиПредпросмотрПовтор:DPMSОтключитьОтключить фон из xinitПродолжительность:ВключитьФайловый менеджерКлавиатураНастройка клавиатурыНастройка мышки:ОкОтключить:Путь:ШаблонЧастота:Картинка:КурсорНастройка курсораЗакрытьОжидать повтор:Пользователь правша, либо левшаСохранитьНастройка экранаХранитель экранаВыбранные файлы:Запасной:Ожидать начало:Отложить:Порог ожидания:Таймаут:Однородный цвет:Громкость:xscreensaverfvwm-2.6.7/po/fvwm.fr.po0000644000175700017570000005523112750322415012016 00000000000000# French translations for fvwm package # Traduction anglaise du package fvwm. # Copyright (C) 2002 fvwm workers # This file is distributed under the same license as the fvwm package. # Olivier Chapuis , 2002. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2014-02-27 11:40+0100\n" "Last-Translator: Dominique Michel \n" "Language-Team: French\n" "Language: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Poedit 1.5.5\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "Menu Interne" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "Configuration avec Form" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "Configuration avec Script95" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "Executer des commandes fvwm" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "Redémarrer fvwm" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "Quitter fvwm" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "Bureau" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\tGéometrie" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "Bureau: %d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "Plus&..." #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "Menu Principal" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "Login à distance" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "Utilitaires" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "Modules de Fvwm" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "Opérations sur les fenêtres" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "Opérations de config" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "Rafraîchir l'écran" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "Recapturer l'écran" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "Quitter fvwm" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "Rétablir les défauts de X" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "Focus fluide" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "Cliquer pour le focus" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "Le focus suit la souris" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "Les couleurs suivent la souris" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "Les couleurs suivent le focus" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "Pagination complète activée" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "Toute pagination désactivée" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "Pagination horizontale seulement" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "Pagination verticale seulement" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "Pagination partielle" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "Pagination complète && Bord électrique" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "&Déplacer" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "&Redimensionner" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "&En avant" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "En &arrière" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "(Dé)&Minimiser" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "(Dế)&Fixer" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "(Dé)&Maximiser" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "&Quitter" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "&Fermer" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "&Brûler" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "Opérations sur les fenêtres" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "Ra&fraîchir la fenêtre" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "Imprimer" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "Impression in&verse" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "Contrôler l'animation" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "bureaux" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "Menu d'arrêt des Modules" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "Arrêter des Modules" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "Stop" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "On quitte vraiment ?" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "Oui, on quitte vraiment" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "Redémarrer" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "Démarrer" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "Juste XTerm" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "Non, on ne quitte pas" # FvwmForm #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "fvwm - Créer votre configuration" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "Utilisez ce formulaire pour créer votre fichier de configuration." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "Ce ficher est ~/.fvwm/.fvwm2rc ou $FVWM_USERDIR/.fvwm2rc." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "Après création, vous pouvez éditer ce fichier avec un éditeur" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "pour une configuration à votre convenance." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "Créez un fichier .fvwm2rc initial" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "Ces fichiers sont optionnels. Choisissez les modules à éditer." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "Vous pourrez les copier plus tard." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "Quitter" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "Copier les fichiers" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 51 msgid "Fvwm Menu Desktop Config" msgstr "Configuration de Fvwm Menu Desktop" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 58 msgid "Multiple Menu" msgstr "Menu multiple" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 66 msgid "Menus in" msgstr "Menus dans" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 95 msgid "No menus found! Check why from within a terminal with" msgstr "Pas de menu trouvé ! Depuis un terminal, contrôlez pourquoi avec" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 109 msgid "Single Menu" msgstr "Menu simple" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 114 msgid "" "If you want a single menu only deselect all menus above and fill out the " "fields below." msgstr "" "Si vous voulez un menu unique, désélectionner tous les menus ci-dessus et " "remplissez les champs" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 116 msgid "But remember, if the menu doesn't exist, nothing happens." msgstr "" "ci-dessous. Mais rappelez-vous, si le menu n'existe pas, rien ne se passe." #. ./bin/fvwm-menu-desktop-config.fpl.in: line 120 msgid "Menu Top Title: " msgstr "Titre du menu : " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 123 msgid " " msgstr " " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 124 msgid "Install-Prefix: " msgstr "Préfixe de menu : " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 128 msgid "Desktop: " msgstr "Bureau : " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 132 msgid "Menutype: " msgstr "Type de menu : " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 141 msgid "General Options" msgstr "Options générales" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 146 msgid "Used Menu Type: " msgstr "Type de menu utilisé :" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 149 msgid "Multiple " msgstr "Multiple " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 150 msgid "Single" msgstr "Simple" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 153 msgid "Use Icons? " msgstr "Utiliser des icônes? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 155 msgid "Yes " msgstr "Oui " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 156 msgid "No " msgstr "Non " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 159 msgid "Icon size: " msgstr "Taille d'icône : " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 161 msgid " (Default is 24)" msgstr " (Par défaut, 24)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 164 msgid "Use Titles? " msgstr "Utiliser des titres? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 170 msgid "Used Icon theme: " msgstr "Thème d'icônes: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 174 msgid "Menu(s) in a Menu? " msgstr "Menu(s) dans un menu? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 180 msgid "Insert in menu: " msgstr "Insérer dans le menu: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 184 msgid "Directory Icon: " msgstr "Annuaire d'icône: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 188 msgid "Application Icon: " msgstr "Icône d'applications: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 192 msgid "Icon directory: " msgstr "Dossier des icônes: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 194 msgid " (Directory for converted icons)" msgstr " (Répertoire pour les icônes converties)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 197 msgid "Output path: " msgstr "Chemin de sortie: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 199 msgid " (Full path to store output)" msgstr " (Chemin complêt du fichier de menu)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 209 msgid "Generate Menu(s)" msgstr "Générez le menu" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 235 msgid "Save Settings" msgstr "Sauvez les réglages" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 262 msgid "Reset" msgstr "Remise à zéro" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 264 msgid "Help" msgstr "Aide" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 266 msgid "Quit" msgstr "Quittez" #. ./bin/fvwm-menu-desktop.in: line 472 msgid "Regenerate XDG Menu(s)" msgstr "Régénérer le(s) menu(s) XDG" #. ./bin/fvwm-menu-desktop.in: line 515 msgid "Regenerate XDG Menu" msgstr "Régénérer le menu XDG" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 17 msgid "" "In this section you can define a custom-assembled menu 'foo-bar.menu' placed " "on another" msgstr "" "Dans cette section vous pouvez customiser un menu 'foo-bar.menu' placé dans " "un autre" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 19 msgid "location as defined in the XDG menu definitions." msgstr "emplacement comme defini dans les définitions du menu XDG." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 24 msgid "Specifies the menu title of the top menu used by Fvwm's Popup command." msgstr "" " Specifiez le titre du menu principal utilisé par la commande de Fvwm." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 26 msgid " " msgstr " " #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 27 msgid "Default is 'FvwmMenu'." msgstr "La valeur par défaut est 'FvwmMenu'." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 32 msgid "Overrides the standard locations for XDG menu definitions. The standard" msgstr "" " Écrase l'emplacement standard pour la definition du menu XDG. Les " "emplacements" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "locations are /etc/xdg/menus and" msgstr "standards sont /etc/xdg/menus et" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "if available." msgstr "si disponible." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 40 msgid "Overrides the name of the main desktop environment installed on the" msgstr "" " Écrase le nom de l'environnement principal qui est installé sur le systeme." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 43 msgid "" "system. If a system offers multiple desktop environments $XDG_MENU_PREFIX" msgstr "" "Si le systeme offre plusieurs environneents de bureau, $XDG_MENU_PREFIX est" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 46 msgid "is typically set. It is ignored if this field is used." msgstr "" "normalement appliqué. Elle est ignorée si le champ est utilisé. Les noms" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 49 msgid "Possible names: gnome, kde, lxde, etc." msgstr "possibles sont: gnome, kde, lxde, etc." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 54 msgid "" "Defines which type of menu should be found. Possible name types could be:" msgstr "" " Définit quel type de menu doit être trouvé. Les noms des types possibles" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 57 msgid "" "applications, settings, preferences, etc. Note if the specified menu type" msgstr "" "peuvent être : applications, settings, preferences, etc. Attention: si le " "type" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 60 msgid "doesn't exist the generated menu is empty!" msgstr "de menu specifié n'existe pas, le menu généré est vide !" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 17 msgid "" "In this section all XDG menus found on the system are shown. All selected " "menus" msgstr "" "Dans cette section tous les menus XDG trouvés seront affichés sur le " "systeme. Tous les" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 19 msgid "" "will integrate in one Fvwm menu. If you want to generate a custom-assembled " "menu" msgstr "" "menus selectionnés seront intégrés dans un menu Fvwm. Si vous voulez générer" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 21 msgid "use the 'Single Menu' section." msgstr "un menu client, utlisez la section 'Menu simple'." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 28 msgid "List menus with checkboxes found in /etc/xdg/menus/" msgstr "" "La liste des menus avec des cases à cocher se trouve dans /etc/xdg/menus/" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 36 msgid "List menus with checkboxes found in $HOME/.config/menus/" msgstr "" "La liste des menus avec des cases à cocher se trouve dans $HOME/.config/" "menus/" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 42 msgid "" "Note that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/" msgstr "" "Notez que des menus identiques trouvés dans /etc/xdg/menus et $HOME/.config/" "menus/," #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 44 msgid "" "following the XDG menu specification only shown in $HOME/.config/menus/." msgstr "" "suivant la spécification de menu XDG ne sont montrés que dans $HOME/.config/" "menus/." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 48 msgid "" "If no menus appear check why from within a terminal with 'fvwm-menu-desktop -" "v'." msgstr "" "Si le menu n'apparaît pas, vérifiez pourquoi dans un terminal avec 'fvwm-" "menu-desktop -v'." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 50 msgid "" "Also it is a good idea to check .xsession-errors in the user home for errors." msgstr "" "C'est aussi une bonne idée de chercher les erreurs dans ~/.xsession-errors." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 54 msgid "One limitation exists:" msgstr "Il existe une limitation :" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 56 msgid "If there are too much menus found an error occurs in .xsession-errors:" msgstr "" "S'il y a trop de menus trouvés, un message d'erreur apparaît dans .xsession-" "errors:" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 62 msgid "" "This happens because PipeRead used for menu generation has a command length" msgstr "" "Cela se produit quand PipeRead a utilisé pour la generation du menu une " "commande" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 64 msgid "limit of 1000 characters. Sorry for that inconvinience." msgstr "" "qui dépasse la limite de 1000 caractéres. Désolé pour la gêne occassionnée." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 74 msgid "Close" msgstr "Fermez" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 18 msgid "Set which menu generation will be used." msgstr "Applique quel type de génération de menu sera utilisé." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 23 msgid "Option enables mini-icons in the menu(s)." msgstr "Option pour activer les mini icônes dans le/les menu(s)." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 28 msgid "" "If 'Use Icons' is set, by default 24x24 mini-icons are used. If another size " "is" msgstr "" "Si 'Utiliser des icônes' est choisi, par defaut des mini-icones de 24x24 " "seront utilisés." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 31 msgid "desired enter the wanted size in this field." msgstr "" "Si une autre taille est desirée, entrer la taille voulue dans ce champ." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 36 msgid "" "If the specified icon isn't that size it is converted if ImageMagick is " "installed." msgstr "" "Si l'icône specifiée n'exsite pas à cette taille, elle peut être convertie " "si ImageMagick" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 39 msgid "" "Generated icons are saved in $HOME/.fvwm/icons or the directory specified " "here." msgstr "" "est installé. Les icônes générées sont sauvegardées sous $HOME/.fvwm/icons " "ou dans le" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 42 msgid "Otherwise no icon appears in the menu for that entry." msgstr "" "dossier spécifié ici. Sinon aucune icône apparaît dans le menu pour cette " "entrée." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 47 msgid "Sets the used icon theme. Default is 'gnome' but all others found in" msgstr "" "Applique le théme d'icônes utilisé. Par défaut 'gnome', mais toute autre " "icône trouvée" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 50 msgid "" "/usr/share/icons can used except the hicolor theme because it's the default" msgstr "" "dans /usr/share/icons peut être utilisée sauf le théme hicolor car c'est le " "théme" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 53 msgid "" "fallback theme if no icon is found. Note that the theme name must be written" msgstr "" "de secour par défaut, si aucune icône n'est trouvée. Notez que le théme doit " "avoir le" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 56 msgid "exactly as the icon directory e.g." msgstr "même nom que le dossier des icônes, par exemple :" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 61 msgid "" "If 'Use Icons' is enabled and for a directory in a menu no icon is found" msgstr "" "Si 'Utiliser des icônes' est actif et qu'aucune icône n'est trouvée dans un " "dossier," #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 64 msgid "as default icon is used. But if the gnome icon theme isn't" msgstr "est utilisé par defaut. Mais si le théme d'icône de gnome n'est pas" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 67 msgid "installed no default icon appears. Another icon can defined here." msgstr "" "installé, aucune icône n'apparaîtera. D'autres icônes peuvent être definies " "ici." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 70 msgid "Only the name of an icon is needed not the path!" msgstr "Seul le nom d'une icône est nécessaire, pas le chemin d'accés." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 75 msgid "If 'Use Icons' is enabled and for an application no icon is found" msgstr "" "Si 'Utiliser des icônes' est actif et que pour une application aucune icnone " "n'est trouvée," #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 89 msgid "Enable this checkbox to insert generated menu(s) IN a menu." msgstr "Activez cette case à cocher pour insérer le menu généré dans un menu." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 94 msgid "" "Enter in this field the name of the menu (its top title) where the generated " "menu(s)" msgstr "" "Entrez dans ce chanp le nom du menu (son titre principal) où le menu généré " "devra être" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 97 msgid "" "should insert. For more information see the USAGE section in the man page of" msgstr "" "inséré. Pour plus d'information regardez la section USAGE dans la page man de" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 105 msgid "" "If this option is set menus are generated with titles. Default is no titles." msgstr "" "Si cet option est active les menus sont générés avec des titres. Par défaut " "sans titre." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 110 msgid "" "Enter here the FULL path of the menu to store. Default path is " "$FVWM_USERDIR/.menu." msgstr "" "Entrez ici le chemin complet du menu pour l'enregistrer. Par default " "$FVWM_USERDIR/.menu." fvwm-2.6.7/po/fvwm.pot0000644000175700017570000004065312673746443011615 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR fvwm workers # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: LANGUAGE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "" #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 51 msgid "Fvwm Menu Desktop Config" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 58 msgid "Multiple Menu" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 66 msgid "Menus in" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 95 msgid "No menus found! Check why from within a terminal with" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 109 msgid "Single Menu" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 114 msgid "If you want a single menu only deselect all menus above and fill out the fields below." msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 116 msgid "But remember, if the menu doesn't exist, nothing happens." msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 120 msgid "Menu Top Title: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 123 msgid " " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 124 msgid "Install-Prefix: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 128 msgid "Desktop: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 132 msgid "Menutype: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 141 msgid "General Options" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 146 msgid "Used Menu Type: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 149 msgid "Multiple " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 150 msgid "Single" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 153 msgid "Use Icons? " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 155 msgid "Yes " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 156 msgid "No " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 159 msgid "Icon size: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 161 msgid " (Default is 24)" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 164 msgid "Use Titles? " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 170 msgid "Used Icon theme: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 174 msgid "Menu(s) in a Menu? " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 180 msgid "Insert in menu: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 184 msgid "Directory Icon: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 188 msgid "Application Icon: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 192 msgid "Icon directory: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 194 msgid " (Directory for converted icons)" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 197 msgid "Output path: " msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 199 msgid " (Full path to store output)" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 209 msgid "Generate Menu(s)" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 235 msgid "Save Settings" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 262 msgid "Reset" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 264 msgid "Help" msgstr "" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 266 msgid "Quit" msgstr "" #. ./bin/fvwm-menu-desktop.in: line 472 msgid "Regenerate XDG Menu(s)" msgstr "" #. ./bin/fvwm-menu-desktop.in: line 515 msgid "Regenerate XDG Menu" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 17 msgid "In this section you can define a custom-assembled menu 'foo-bar.menu' placed on another" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 19 msgid "location as defined in the XDG menu definitions." msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 24 msgid "Specifies the menu title of the top menu used by Fvwm's Popup command." msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 26 msgid " " msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 27 msgid "Default is 'FvwmMenu'." msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 32 msgid "Overrides the standard locations for XDG menu definitions. The standard" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "locations are /etc/xdg/menus and" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "if available." msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 40 msgid "Overrides the name of the main desktop environment installed on the" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 43 msgid "system. If a system offers multiple desktop environments $XDG_MENU_PREFIX" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 46 msgid "is typically set. It is ignored if this field is used." msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 49 msgid "Possible names: gnome, kde, lxde, etc." msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 54 msgid "Defines which type of menu should be found. Possible name types could be:" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 57 msgid "applications, settings, preferences, etc. Note if the specified menu type" msgstr "" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 60 msgid "doesn't exist the generated menu is empty!" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 17 msgid "In this section all XDG menus found on the system are shown. All selected menus" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 19 msgid "will integrate in one Fvwm menu. If you want to generate a custom-assembled menu" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 21 msgid "use the 'Single Menu' section." msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 28 msgid "List menus with checkboxes found in /etc/xdg/menus/" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 36 msgid "List menus with checkboxes found in $HOME/.config/menus/" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 42 msgid "Note that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 44 msgid "following the XDG menu specification only shown in $HOME/.config/menus/." msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 48 msgid "If no menus appear check why from within a terminal with 'fvwm-menu-desktop -v'." msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 50 msgid "Also it is a good idea to check .xsession-errors in the user home for errors." msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 54 msgid "One limitation exists:" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 56 msgid "If there are too much menus found an error occurs in .xsession-errors:" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 62 msgid "This happens because PipeRead used for menu generation has a command length" msgstr "" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 64 msgid "limit of 1000 characters. Sorry for that inconvinience." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 18 msgid "Set which menu generation will be used." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 23 msgid "Option enables mini-icons in the menu(s)." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 28 msgid "If 'Use Icons' is set, by default 24x24 mini-icons are used. If another size is" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 31 msgid "desired enter the wanted size in this field." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 36 msgid "If the specified icon isn't that size it is converted if ImageMagick is installed." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 39 msgid "Generated icons are saved in $HOME/.fvwm/icons or the directory specified here." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 42 msgid "Otherwise no icon appears in the menu for that entry." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 47 msgid "Sets the used icon theme. Default is 'gnome' but all others found in" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 50 msgid "/usr/share/icons can used except the hicolor theme because it's the default" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 53 msgid "fallback theme if no icon is found. Note that the theme name must be written" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 56 msgid "exactly as the icon directory e.g." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 61 msgid "If 'Use Icons' is enabled and for a directory in a menu no icon is found" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 64 msgid "as default icon is used. But if the gnome icon theme isn't" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 67 msgid "installed no default icon appears. Another icon can defined here." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 70 msgid "Only the name of an icon is needed not the path!" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 75 msgid "If 'Use Icons' is enabled and for an application no icon is found" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 89 msgid "Enable this checkbox to insert generated menu(s) IN a menu." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 94 msgid "Enter in this field the name of the menu (its top title) where the generated menu(s)" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 97 msgid "should insert. For more information see the USAGE section in the man page of" msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 105 msgid "If this option is set menus are generated with titles. Default is no titles." msgstr "" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 110 msgid "Enter here the FULL path of the menu to store. Default path is $FVWM_USERDIR/.menu." msgstr "" fvwm-2.6.7/po/remove-potcdate.sed0000644000175700017570000000007212673746443013674 00000000000000/^"POT-Creation-Date: .*"$/{ x s/P/P/ ta g d bb :a x :b } fvwm-2.6.7/po/fvwm.es.po0000644000175700017570000005352212673746443012036 00000000000000# Spanish translations for fvwm package # Copyright (C) 2013 fvwm workers # This file is distributed under the same license as the PACKAGE package. # Adonai Martin , 2013. # msgid "" msgstr "" "Project-Id-Version: fvwm\n" "POT-Creation-Date: 2002-11-28 14:23+0100\n" "PO-Revision-Date: 2013-10-25 22:45+0200\n" "Last-Translator: Adonai Martin \n" "Language-Team: Spanish\n" "Language: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" #: ../fvwm/fvwm.c:1362 msgid "Builtin Menu" msgstr "Men Interno" #: ../fvwm/fvwm.c:1365 msgid "Setup Form" msgstr "Formulario de configuracin" #: ../fvwm/fvwm.c:1368 msgid "Setup 95 Script" msgstr "Guin de configuracin FVWM95" #: ../fvwm/fvwm.c:1371 msgid "Issue fvwm commands" msgstr "Invocar comandos fvwm" #: ../fvwm/fvwm.c:1374 ../modules/FvwmForm/FvwmForm-Setup.in: line 66 msgid "Restart fvwm" msgstr "Reiniciar fvwm" #: ../fvwm/fvwm.c:1375 msgid "Exit fvwm" msgstr "Cerrar fvwm" #: ../fvwm/expand.c:255 ../fvwm/virtual.c:2042 msgid "Desk" msgstr "Escritorio" #: ../fvwm/windowlist.c:94 ../fvwm/windowlist.c:100 ../fvwm/windowlist.c:107 msgid "\tGeometry" msgstr "\tGeometra" #: ../fvwm/windowlist.c:105 #, c-format msgid "Desk: %d%s" msgstr "Escritorio: %d%s" #: ../fvwm/menus.c:1674 msgid "More&..." msgstr "Ms&..." #. ./fvwm/ConfigFvwmSetup: line 91 msgid "Root Menu" msgstr "Men principal" #. ./fvwm/ConfigFvwmSetup: line 95 msgid "Remote Logins" msgstr "Inicio de sesin remoto" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 97 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 109 msgid "Utilities" msgstr "Utilidades" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 99 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 194 msgid "Fvwm Modules" msgstr "Modulos Fvwm" #. ./fvwm/ConfigFvwmSetup: line 100 msgid "Fvwm Window Ops" msgstr "Opciones de ventana" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 101 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 124 msgid "Fvwm Config Ops" msgstr "Opciones de configuracin" #. ./fvwm/ConfigFvwmSetup: line 103 msgid "Refresh Screen" msgstr "Actualizar Pantalla" #. ./fvwm/ConfigFvwmSetup: line 104 msgid "Recapture Screen" msgstr "Recapturar Pantalla" #. ./fvwm/ConfigFvwmSetup: line 106 msgid "Exit Fvwm" msgstr "Salir de Fvwm" #. ./fvwm/ConfigFvwmSetup: line 121 msgid "Reset X defaults" msgstr "Restaurar valores por defecto" #. ./fvwm/ConfigFvwmSetup: line 125 msgid "Sloppy Focus" msgstr "Foco relajado" #. ./fvwm/ConfigFvwmSetup: line 126 msgid "Click To Focus" msgstr "Foco al hacer clic" #. ./fvwm/ConfigFvwmSetup: line 127 msgid "Focus Follows Mouse" msgstr "Foco siguiendo al ratn" #. ./fvwm/ConfigFvwmSetup: line 129 msgid "Colormap Follows Mouse" msgstr "Mapa de colores siguiendo ratn" #. ./fvwm/ConfigFvwmSetup: line 130 msgid "Colormap Follows Focus" msgstr "Mapa de colores por enfoque" #. ./fvwm/ConfigFvwmSetup: line 132 msgid "Full Paging ON" msgstr "Paginado completo ON" #. ./fvwm/ConfigFvwmSetup: line 133 msgid "All Paging OFF" msgstr "Todo paginado OFF" #. ./fvwm/ConfigFvwmSetup: line 134 msgid "Horizontal Paging Only" msgstr "Slo Paginado Horizontal" #. ./fvwm/ConfigFvwmSetup: line 135 msgid "Vertical Paging Only" msgstr "Slo Paginado Vertical" #. ./fvwm/ConfigFvwmSetup: line 136 msgid "Partial Paging" msgstr "Paginado Parcial" #. ./fvwm/ConfigFvwmSetup: line 137 msgid "Full Paging && Edge Wrap" msgstr "Paginado Completo && Redondeo de Bordes" #. ./fvwm/ConfigFvwmSetup: line 144 msgid "&Move" msgstr "&Mover" #. ./fvwm/ConfigFvwmSetup: line 145 msgid "&Resize" msgstr "&Redimensionar" #. ./fvwm/ConfigFvwmSetup: line 146 msgid "R&aise" msgstr "&Aumentar" #. ./fvwm/ConfigFvwmSetup: line 147 msgid "&Lower" msgstr "Reducir" #. ./fvwm/ConfigFvwmSetup: line 148 msgid "(De)&Iconify" msgstr "(Des)&Iconificar" #. ./fvwm/ConfigFvwmSetup: line 149 msgid "(Un)&Stick" msgstr "(Des)&Pegar" #. ./fvwm/ConfigFvwmSetup: line 150 msgid "(Un)Ma&ximize" msgstr "(Des)Ma&ximizar" #. ./fvwm/ConfigFvwmSetup: line 152 msgid "&Delete" msgstr "&Eliminar" #. ./fvwm/ConfigFvwmSetup: line 153 msgid "&Close" msgstr "&Cerrar" #. ./fvwm/ConfigFvwmSetup: line 154 msgid "Destroy" msgstr "Destruir" #. ./fvwm/ConfigFvwmSetup: line 161 msgid "Window Ops" msgstr "Opciones de Ventana" #. ./fvwm/ConfigFvwmSetup: line 163 msgid "Re&fresh Window" msgstr "Ac&tualizar Ventana" #. ./fvwm/ConfigFvwmSetup: line 172 msgid "Print" msgstr "Imprimir" #. ./fvwm/ConfigFvwmSetup: line 173 msgid "Print Re&verse" msgstr "Imprimir Re&verso" #. ./fvwm/ConfigFvwmSetup: line 195 msgid "Control Animation" msgstr "Control de Animacin" #. ./fvwm/ConfigFvwmSetup: line 204 msgid "desks" msgstr "escritorios" #. ./fvwm/ConfigFvwmSetup: line 210 msgid "Stop Module Menu" msgstr "Men Parar Mdulos" #. ./fvwm/ConfigFvwmSetup: line 213 msgid "Stop Fvwm Modules" msgstr "Parar Mdulos Fvwm" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 214 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 215 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 216 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 217 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 218 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 219 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 220 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 221 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 222 msgid "Stop" msgstr "Parar" #. ./fvwm/ConfigFvwmSetup: line 241 msgid "Really Quit Fvwm?" msgstr "Desea cerrar Fvwm?" #. ./fvwm/ConfigFvwmSetup: line 242 msgid "Yes, Really Quit" msgstr "S, confirmo el cierre" #. ./fvwm/ConfigFvwmSetup: line 244 msgid "Restart" msgstr "Reiniciar" #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 246 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 247 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 248 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 249 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 250 #. #-#-#-#-# duplicate #-#-#-#-# #. ./fvwm/ConfigFvwmSetup: line 251 msgid "Start" msgstr "Inicio" #. ./fvwm/ConfigFvwmSetup: line 253 msgid "Just an Xterm" msgstr "Slo una Xterm" #. ./fvwm/ConfigFvwmSetup: line 255 msgid "No, Don't Quit" msgstr "No, no deseo cerrar" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 8 msgid "fvwm - Create Configuration" msgstr "fvwm - Crear Configuracin" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 13 msgid "Use this form to create your fvwm2rc configuration file." msgstr "Use este formulario para crear el archivo de configuracin .fvwm2rc" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 15 msgid "The file created is ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." msgstr "El archivo creado es ~/.fvwm/.fvwm2rc or $FVWM_USERDIR/.fvwm2rc." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 19 msgid "After creation, the fvwm2rc file can then be changed with any" msgstr "Despus de la creacin, el archivo .fvwm2rc puede ser cambiado posteriormente con cualquier" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 21 msgid "editor to suit your own needs." msgstr "editor para adaptarse a sus propias necesidades." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 26 msgid "Create a starting .fvwm2rc file" msgstr "Crear un archivo de comienzo .fvwm2rc" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 30 msgid "These files are optional. Select the modules you want to customize." msgstr "Estos archivos son opcionales. Seleccione los mdulos que quiera personalizar." #. ./modules/FvwmForm/FvwmForm-Setup.in: line 32 msgid "You can always copy them later." msgstr "Puede siempre copiarlos ms adelante" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 53 msgid "Return - Dismiss" msgstr "Volver - Terminar" #. ./modules/FvwmForm/FvwmForm-Setup.in: line 55 msgid "Copy Config File(s)" msgstr "Copiar Archivo(s) de Configuracin" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 51 msgid "Fvwm Menu Desktop Config" msgstr "Fvwm Menu Desktop Configuracin" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 58 msgid "Multiple Menu" msgstr "Men mltiple" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 66 msgid "Menus in" msgstr "Mens en" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 95 msgid "No menus found! Check why from within a terminal with" msgstr "No se han encontrado mens! Compruebe por qu desde un terminal con" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 109 msgid "Single Menu" msgstr "Men nico" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 114 msgid "If you want a single menu only deselect all menus above and fill out the fields below." msgstr "Si desea tan solo un nico men, anule la seleccin de todos los mens anteriores y complete los" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 116 msgid "But remember, if the menu doesn't exist, nothing happens." msgstr "campos siguientes. Pero recuerde: si el men no existe, no pasa nada." #. ./bin/fvwm-menu-desktop-config.fpl.in: line 120 msgid "Menu Top Title: " msgstr "Ttulo sobre men: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 123 msgid " " msgstr " " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 124 msgid "Install-Prefix: " msgstr "Prefijo instalacin:" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 128 msgid "Desktop: " msgstr "Escritorio: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 132 msgid "Menutype: " msgstr "Tipo de men: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 141 msgid "General Options" msgstr "Opciones generales" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 146 msgid "Used Menu Type: " msgstr "Tipo de men usado: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 149 msgid "Multiple " msgstr "Mltiple " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 150 msgid "Single" msgstr "nico" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 153 msgid "Use Icons? " msgstr "Usar Iconos? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 155 msgid "Yes " msgstr "S " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 156 msgid "No " msgstr "No " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 159 msgid "Icon size: " msgstr "Tamao de icono: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 161 msgid " (Default is 24)" msgstr " (Estndar es 24)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 164 msgid "Use Titles? " msgstr "Utilizar ttulos? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 170 msgid "Used Icon theme: " msgstr "Icono de tema usado: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 174 msgid "Menu(s) in a Menu? " msgstr "Men(s) en el men? " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 180 msgid "Insert in menu: " msgstr "Insertar en el men: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 184 msgid "Directory Icon: " msgstr "Icono de carpeta: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 188 msgid "Application Icon: " msgstr "Icono Aplicacin: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 192 msgid "Icon directory: " msgstr "Directorio de iconos: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 194 msgid " (Directory for converted icons)" msgstr " (Directorio de iconos convertidos)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 197 msgid "Output path: " msgstr "Ruta de salida: " #. ./bin/fvwm-menu-desktop-config.fpl.in: line 199 msgid " (Full path to store output)" msgstr " (Ruta completa para almacenar la salida)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 209 msgid "Generate Menu(s)" msgstr "Generar Men(s)" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 235 msgid "Save Settings" msgstr "Guardar Configuracin" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 262 msgid "Reset" msgstr "Resetear" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 264 msgid "Help" msgstr "Ayuda" #. ./bin/fvwm-menu-desktop-config.fpl.in: line 266 msgid "Quit" msgstr "Cerrar" #. ./bin/fvwm-menu-desktop.in: line 472 msgid "Regenerate XDG Menu(s)" msgstr "Regenerar Men(s) XDG" #. ./bin/fvwm-menu-desktop.in: line 515 msgid "Regenerate XDG Menu" msgstr "Regenerar Men XDG" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 17 msgid "In this section you can define a custom-assembled menu 'foo-bar.menu' placed on another" msgstr "En esta seccin usted puede crear un men 'foo-bar.menu', que fue definido en otro lugar diferente a las" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 19 msgid "location as defined in the XDG menu definitions." msgstr "especificaciones del men XDG." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 24 msgid "Specifies the menu title of the top menu used by Fvwm's Popup command." msgstr "Especifica el ttulo del men principal que es usado por el popup comando Fvwm's." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 26 msgid " " msgstr " " #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 27 msgid "Default is 'FvwmMenu'." msgstr "Predeterminado es 'FvwmMenu'." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 32 msgid "Overrides the standard locations for XDG menu definitions. The standard" msgstr "Sobreescribir la ubicacin estndar para las definiciones de men XDG. Los sitios" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "locations are /etc/xdg/menus and" msgstr "estndar son /etc/xdg/menus y" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 35 msgid "if available." msgstr "si est disponible." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 40 msgid "Overrides the name of the main desktop environment installed on the" msgstr "Sobreescribir el nombre del escritorio principal, que fue instalado en el sistema." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 43 msgid "system. If a system offers multiple desktop environments $XDG_MENU_PREFIX" msgstr "Si un sistema ofrece mltiples escritorios, $XDG_MENU_PREFIX es tpicamente" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 46 msgid "is typically set. It is ignored if this field is used." msgstr "seleccionado, pero se ignora si este campo es usado." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 49 msgid "Possible names: gnome, kde, lxde, etc." msgstr "Posibles nombres: gnome, kde, lxde, etc." #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 54 msgid "Defines which type of menu should be found. Possible name types could be:" msgstr "Define qu tipo de men debe ser encontrado. Posibles tipos pueden ser: applications," #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 57 msgid "applications, settings, preferences, etc. Note if the specified menu type" msgstr "settings, preferences, etc. Atencin, si el tipo de men especificado no existe, el" #. ./modules/FvwmForm/FvwmForm-SingleMenuHelp: line 60 msgid "doesn't exist the generated menu is empty!" msgstr "men generado est vaco!" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 17 msgid "In this section all XDG menus found on the system are shown. All selected menus" msgstr "En esta seccin todos los mens XDG encontrados en el sistema son mostrados. Todos los" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 19 msgid "will integrate in one Fvwm menu. If you want to generate a custom-assembled menu" msgstr "mens seleccionados, son integrados en un men Fvwm. Si desea crear su men propio," #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 21 msgid "use the 'Single Menu' section." msgstr "utilice la seccin 'Men nico'." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 28 msgid "List menus with checkboxes found in /etc/xdg/menus/" msgstr "Lista los mens encontrados en /etc/xdg/menus/ con checkboxes." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 36 msgid "List menus with checkboxes found in $HOME/.config/menus/" msgstr "Lista los mens encontrados en $HOME/.config/menus/ con checkboxes." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 42 msgid "Note that equal menus found under /etc/xdg/menus AND $HOME/.config/menus/" msgstr "Nota: mens iguales encontrados en /etc/xdg/menus UND $HOME/.config/menus/, siguiendo la" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 44 msgid "following the XDG menu specification only shown in $HOME/.config/menus/." msgstr "especificacin de men XDG, son solamente mostrados en $HOME/.config/menus/." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 48 msgid "If no menus appear check why from within a terminal with 'fvwm-menu-desktop -v'." msgstr "Si ningun men aparece, compruebe la causa desde un terminal con 'fvwm-menu-desktop -v'." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 50 msgid "Also it is a good idea to check .xsession-errors in the user home for errors." msgstr "Una buena idea, es comprobar los mensajes de error en .xsession-errors." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 54 msgid "One limitation exists:" msgstr "Existe un lmite:" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 56 msgid "If there are too much menus found an error occurs in .xsession-errors:" msgstr "Si se encuentran muchos mens, aparece el siguiente error en .xsession-errors:" #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 62 msgid "This happens because PipeRead used for menu generation has a command length" msgstr "Esto sucede, porque PipeRead usada para generar el men tiene un lmite de 100 caracteres." #. ./modules/FvwmForm/FvwmForm-MultiMenuHelp: line 64 msgid "limit of 1000 characters. Sorry for that inconvinience." msgstr "Perdn por este inconveniente." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 18 msgid "Set which menu generation will be used." msgstr "Establecer el men de generacin utilizado." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 23 msgid "Option enables mini-icons in the menu(s)." msgstr "Opcin para activar mini-iconos en el(los) men(s)." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 28 msgid "If 'Use Icons' is set, by default 24x24 mini-icons are used. If another size is" msgstr "Si 'Usar Iconos' est seleccionado, iconos de 24x24 sern usados por defecto. Si" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 31 msgid "desired enter the wanted size in this field." msgstr "desea otro tamao, establzcalo en este campo." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 36 msgid "If the specified icon isn't that size it is converted if ImageMagick is installed." msgstr "Si el icono especificado no es de ese tamao, ser convertido, si ImageMagic est instalado." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 39 msgid "Generated icons are saved in $HOME/.fvwm/icons or the directory specified here." msgstr "Los iconos generados se guardan en $HOME/.fvwm/icons o el directorio especificado aqu." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 42 msgid "Otherwise no icon appears in the menu for that entry." msgstr "De otra manera ningn icono aparecer en el men para esa entrada." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 47 msgid "Sets the used icon theme. Default is 'gnome' but all others found in" msgstr "Establecer el icono de tema usado. Por defecto es 'gnome', pero otros encontrados en" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 50 msgid "/usr/share/icons can used except the hicolor theme because it's the default" msgstr "/usr/share/icons pueden ser usados. Exceptuando tema 'hicolor' porque es el tema por" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 53 msgid "fallback theme if no icon is found. Note that the theme name must be written" msgstr "defecto de reserva si ningn icono es encontrado. Atencin al nombre del tema, debe de" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 56 msgid "exactly as the icon directory e.g." msgstr "ser escrito exactamente como el directorio de los iconos:" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 61 msgid "If 'Use Icons' is enabled and for a directory in a menu no icon is found" msgstr "Si 'Usar Iconos' est activado y para un directorio en un men ningn icono es encontrado," #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 64 msgid "as default icon is used. But if the gnome icon theme isn't" msgstr "ser usado por defecto. Pero si el icono del tema de gnome no est" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 67 msgid "installed no default icon appears. Another icon can defined here." msgstr "instalado, ningn icono aparecer por defecto. Otro icono puede ser definido aqu. Slo" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 70 msgid "Only the name of an icon is needed not the path!" msgstr "el nombre de un icono es necesario, no la ruta!" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 75 msgid "If 'Use Icons' is enabled and for an application no icon is found" msgstr "Si 'Usar Iconos' est habilitado y para una aplicacin ningn icono es encontrado," #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 89 msgid "Enable this checkbox to insert generated menu(s) IN a menu." msgstr "Habilitar este checkbox para insertar menu(s) generados EN un men." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 94 msgid "Enter in this field the name of the menu (its top title) where the generated menu(s)" msgstr "Escriba en el campo de nombre de men (encima del ttulo) donde los men(s) generados" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 97 msgid "should insert. For more information see the USAGE section in the man page of" msgstr "deberan insertarse. Para ms informacin vea la seccin de USO en la pgina man de" #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 105 msgid "If this option is set menus are generated with titles. Default is no titles." msgstr "Si esta opcin est activada, los mens son generados con ttulos. Estndar es sin ttulo." #. ./modules/FvwmForm/FvwmForm-GenOptionHelp: line 110 msgid "Enter here the FULL path of the menu to store. Default path is $FVWM_USERDIR/.menu." msgstr "Escriba aqu la ruta COMPLETA en el men para guardarla. Estndar es $FVWM_USERDIR/.menu." fvwm-2.6.7/po/README0000644000175700017570000000523212673746443010764 00000000000000* Requirement for Translators and developers: gettext-0.11.5 http://www.gnu.org/software/gettext/ Read the doc. However, the logic used is a bit different than the gettext logic * For translators: Contact fvwm-workers@fvwm.org * For programmers: To be written * For creating a new catalogs, say LL_CC (e.g., fr, zh_CN): - Edit configure.in and add LL_CC to ALL_LINGUAS - run autoconf and ./configure (with your usual options) and check that the new "lang" appear in the list of "lang" Locale msg: prefix/share/locale ... LL_CC ... - cd to po/ - create a domain.LL_CC.po file for all files domain.pot: msginit -i fvwm.pot -l LL_CC -o fvwm.LL_CC.po msginit -i FvwmTaskBar.pot -l LL_CC -o FvwmTaskBar.LL_CC.po ... The --no-translator option can be useful under certain situation (e.g., you do not use the LL_CC locale). In this case you should edit the files you have created and in particular set the appropriate CHARSET. - Then, you can start the translation of fvwm.LL_CC.po, FvwmTaskBar.LL_CC.po ...etc NOTE: You should "make domain.LL_CC.gmo" before make install and test your translation visually! * make: - make [all] should do nothing (but, maybe, recreating the Makefile). "make install" install! But see the previous NOTE. - The following (re)build everything (safe): make po-update - If some messages have changed in some source files in "domain": make domain.pot-update update domain.pot. Then you can make domain.LL_CC.po to get the new messages for translation. After translation: make domain.LL_CC.gmo # create a binary mo file from the po one make install restart fvwm for visual testing. - Other targets: make update-gmo # build all the binary gmo files * Creation of a new domain: ask the fvwm-workers@fvwm.org. Basically: - Update ALL_DOMAINS in configure.in - Add NEW_DOMAIN in configure.in - Create po/$NEW_DOMAIN.pot (xgettext) and add it to EXTRA_DIST (todo: remove this step) - Set the files which contains msg NEW_DOMAIN = file1 file2 ... in the beginning of po/Makefile.am - Add $(srcdir)/$(NEW_DOMAIN).pot: and $(NEW_DOMAIN).pot-update: in po/Makfile.am - Update $(POFILES): and update-po: in po/Makfile.am (todo: remove this step) * New instructions, Feb 19, 2013 (Dan Espen): - Got .po files from contributor. - Change configure.ac to add X to ALL_LINGUAS. - Generate .gmo files by doing: make fvwm.X.gmo FvwmScript.X.gmo FvwmTaskBar.X.gmo where X is the language. fvwm-2.6.7/perllib/0000755000175700017570000000000013010103345011143 500000000000000fvwm-2.6.7/perllib/FVWM/0000755000175700017570000000000013010103345011722 500000000000000fvwm-2.6.7/perllib/FVWM/Makefile.am0000644000175700017570000000117512773470550013726 00000000000000## Process this file with automake to create Makefile.in SUBDIRS = Module Tracker configdir = @FVWM_PERLLIBDIR@/FVWM ORIGINAL_PMS = \ Commands.pm Constants.pm EventNames.pm Event.pm Tracker.pm config_DATA = $(ORIGINAL_PMS) Module.pm EXTRA_DIST = $(ORIGINAL_PMS) create-commands create-constants _Constants.pm: Makefile.am $(top_srcdir)/libs/Module.h cd $(top_builddir)/perllib/FVWM && \ (fvwm_libdir=$(top_builddir)/libs ./create-constants) _Commands.pm: Makefile $(top_srcdir)/fvwm/functable.c cd $(top_builddir)/perllib/FVWM && \ (fvwm_libdir=$(top_builddir)/libs ./create-commands) regenerate: _Constants.pm _Commands.pm fvwm-2.6.7/perllib/FVWM/Module.pm.in0000644000175700017570000010554212750325036014056 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Module; use 5.004; use strict; use IO::File; BEGIN { use vars qw($prefix $datarootdir $datadir); $prefix = "@prefix@"; $datarootdir = "@datarootdir@"; $datadir = "@datadir@"; } use lib "@FVWM_PERLLIBDIR@"; use vars qw($VERSION @ISA @EXPORT $AUTOLOAD); use FVWM::Constants; use FVWM::Event; use Exporter; @EXPORT = @FVWM::Constants::EXPORT; @ISA = qw(Exporter); # The major version part indicates major API changes $VERSION = '2.0'; # Set the fvwm search directories (used for non fully qualified file names) $General::FileSystem::SAVE_FILE_DIR = $General::FileSystem::SAVE_FILE_DIR || __PACKAGE__->user_data_dir(); $General::FileSystem::LOAD_FILE_DIRS = $General::FileSystem::LOAD_FILE_DIRS || [ __PACKAGE__->search_dirs() ]; sub internal_die ($$) { my $self = shift; my $msg = shift; $msg =~ s/([^\.!?])$/$1./; die $self->name . ": $msg Exiting.\n"; } sub show_error ($$) { my $self = shift; my $msg = shift; print STDERR $self->name . ": $msg\n"; } sub show_message ($$) { my $self = shift; my $msg = shift; print STDERR "[" . $self->name . "]: $msg\n"; } sub show_debug ($$) { my $self = shift; my $msg = shift; print STDERR "[" . $self->name . "]: $msg\n"; } sub debug ($$;$) { my $self = shift; my $msg = shift; my $level = shift; $level = 1 unless defined $level; my $debug_level = $self->{debug}; $debug_level = $ENV{FVWM_MODULE_DEBUG} if exists $ENV{FVWM_MODULE_DEBUG}; return if $debug_level < $level; $msg =~ s/\n$//s; $self->show_debug($msg); } sub is_event_extended ($$) { my $self = shift; my $type = shift; return $type & M_EXTENDED_MSG ? 1 : 0; } sub new ($@) { my $class = shift; my %params = @_; my $self = {}; my $name = $0; $name =~ s|.*/||; $name = $params{'Name'} || $name; my $mask = $params{'Mask'}; my $xmask = $params{'XMask'}; my $sync_mask = $params{'SyncMask'}; my $sync_xmask = $params{'SyncXMask'}; # initialize module from argv my ($out_fd, $in_fd, $rc_file, $win_id, $context); if (@ARGV >= 5 && $ARGV[0] =~ /^\d+$/ && $ARGV[1] =~ /^\d+$/) { $self->{is_dummy} = 0; ($out_fd, $in_fd, $rc_file, $win_id, $context) = splice(@ARGV, 0, 5); } else { warn "$name should be spawned by fvwm normally.\n"; warn "Activating a dummy command line mode for 30 minutes (no events).\n"; warn "----------------------------------------------------------------\n"; open(DUMMYOUT, '| cat >/dev/null'); open(DUMMYIN, 'sleep 1800 |'); $self->{is_dummy} = 1; ($out_fd, $in_fd) = (fileno(DUMMYOUT), fileno(DUMMYIN)); ($rc_file, $win_id, $context) = ("none", 0, 0); } if (@ARGV && $params{'EnableAlias'} && $ARGV[0] =~ /^\w[\w\d\.\/-]*/) { $name = shift @ARGV; } if (@ARGV && ref($params{'EnableOptions'}) eq 'HASH') { # save time by lazy loading Getopt::Long only if needed eval "use Getopt::Long;"; die "$name: $@" if $@; GetOptions(%{$params{'EnableOptions'}}) or die "$name: Incorrect options given.\n"; } my @argv = @ARGV; $self->{rc_file} = $rc_file; $self->{win_id} = hex $win_id; $self->{context} = $context; $self->{argv} = [@argv]; # a module may need this autoflush STDOUT; autoflush STDERR; $self->{ostream} = new IO::File ">&$out_fd" or die "$name: Can't write to file descriptor (&$out_fd)\n"; $self->{istream} = new IO::File "<&$in_fd" or die "$name: Can't read from file descriptor (&$in_fd)\n"; $self->{ostream}->autoflush(1); $self->{istream}->autoflush(1); $self->{disconnected} = 0; $self->{debug} = $params{'Debug'} || 0; $self->{debug} = ${$self->{debug}} if ref($self->{debug}) eq 'SCALAR'; $self->{last_packet} = []; $self->{handlers} = {}; $self->{should_send_unlock} = 0; $self->{should_send_ready} = 1; $self->{add_mask} = 0; $self->{add_xmask} = 0; $self->{mask_was_set} = defined $mask; $self->{xmask_was_set} = defined $xmask; $self->{held_command_args} = []; $self->{synthetic_events} = []; $self->{used_tracker_classes} = {}; $self->{trackers} = {}; # bless here, so die above does not run DESTROY bless $self, $class; $self->name($name); $self->mask($mask || 0, $self->{mask_was_set}); $self->xmask($xmask, $self->{xmask_was_set}) if $xmask; $self->sync_mask($sync_mask || 0); $self->sync_xmask($sync_xmask) if $sync_xmask; $self->reset_handlers; return $self; } sub disconnect ($) { my $self = shift; # do nonrecoverable things, but do them only once return if $self->{disconnected}; $self->{disconnected} = 1; $self->invoke_handler(new FVWM::Event(ON_EXIT)); if (defined $self->{ostream} && $self->{ostream}->opened) { # TODO: should wait until fvwm actually gets it $self->send("Nop", 0, 0); close $self->{ostream}; } if (defined $self->{istream} && $self->{istream}->opened) { close $self->{istream}; } } sub DESTROY ($) { my $self = shift; $self->disconnect; } sub is_dummy ($) { my $self = shift; return $self->{is_dummy}; } sub name ($;$) { my $self = shift; my $name = shift; $self->{name} = $name if defined $name; return $self->{name}; } sub mask ($;$$) { my $self = shift; my $mask = shift; my $explicit = shift; $explicit = 1 unless defined $explicit; if (defined $mask) { $self->internal_die("mask() can't get extended mask, use xmask()") if $self->is_event_extended($mask); my $old_mask = $self->{mask}; $self->send_mask($mask, $self->{add_mask}) unless defined $old_mask && $old_mask == $mask; $self->{mask} = $mask; $self->{mask_was_set} = $explicit; return $old_mask; } return $self->{mask} || 0; } sub xmask ($;$$) { my $self = shift; my $mask = shift; my $explicit = shift; $explicit = 1 unless defined $explicit; if (defined $mask) { $mask &= ~M_EXTENDED_MSG; my $old_mask = $self->{xmask}; $self->send_mask($mask | M_EXTENDED_MSG, $self->{add_xmask}) unless defined $old_mask && $old_mask == $mask; $self->{xmask} = $mask; $self->{xmask_was_set} = $explicit; return $old_mask; } return $self->{xmask} || 0; } sub is_in_mask ($$) { my $self = shift; my $type = shift; my $mask = ($type & M_EXTENDED_MSG) ? $self->{xmask} : $self->{mask}; return $type & ($mask || 0); } sub sync_mask ($;$) { my $self = shift; my $mask = shift; if (defined $mask) { $self->internal_die("sync_mask() can't get extended mask, use sync_xmask()") if $self->is_event_extended($mask); my $old_mask = $self->{sync_mask}; $self->send("SET_SYNC_MASK $mask") unless defined $old_mask && $old_mask == $mask; $self->{sync_mask} = $mask; return $old_mask; } return $self->{sync_mask} || 0; } sub sync_xmask ($;$) { my $self = shift; my $mask = shift; if (defined $mask) { $mask &= ~M_EXTENDED_MSG; my $old_mask = $self->{sync_xmask}; $self->send("SET_SYNC_MASK " . ($mask | M_EXTENDED_MSG)) unless defined $old_mask && $old_mask == $mask; $self->{sync_xmask} = $mask; return $old_mask; } return $self->{sync_xmask} || 0; } sub is_in_sync_mask ($$) { my $self = shift; my $type = shift; my $mask = ($type & M_EXTENDED_MSG) ? $self->{sync_xmask} : $self->{sync_mask}; return $type & ($mask || 0); } # by default the version of a module is the fvwm version sub version ($) { my $self = shift; return "@VERSION@"; } sub version_info ($) { my $self = shift; return "@VERSIONINFO@"; } sub argv ($) { my $self = shift; return @{$self->{argv}}; } sub reset_handlers ($) { my $self = shift; $self->{handlers}->{regular} = {}; $self->{handlers}->{extended} = {}; $self->{handlers}->{special} = {}; } sub get_handler_category ($$) { my $self = shift; my $type = shift; return "special" if $type =~ /e/i; return "extended" if $self->is_event_extended($type); return "regular"; } sub postpone_send ($@) { my $self = shift; push @{$self->{held_command_args}}, [ @_ ]; } # params: text, [win_id], [continue=0/1] sub send ($$;$$) { my $self = shift; my $text = shift; my $win_id = shift || 0; my $continue = shift; $continue = 1 unless defined $continue; $self->internal_die("send requires at least text param") unless defined $text; my @lines = split(/\n/s, $text); my $last_line = ""; for my $line (@lines) { # support continuation lines $line = "$last_line$line" if $last_line ne ""; if ($line =~ /^(.*)\\$/) { $last_line = $1; next; } else { $last_line = ""; } next if $line =~ /^\s*$/; unless ($self->{ostream}->opened) { $self->debug("Closed send [$line]\n", 1); next; } $self->debug("sent [$line]" . (!$continue && " FINISH"), 2); my $len = length $line; local $SIG{PIPE} = sub { $self->debug("Failed send [$line]\n", 1); }; $self->{ostream}->print( pack("l!l!a${len}l!", $win_id, $len, $line, $continue) ); } return $self; } sub send_ready ($) { my $self = shift; $self->send(RESPONSE_READY) if $self->{should_send_ready}; $self->{should_send_ready} = 0; return $self; } sub send_unlock ($) { my $self = shift; $self->send(RESPONSE_UNLOCK) if $self->{should_send_unlock}; $self->{should_send_unlock} = 0; return $self; } sub send_mask ($$;$) { my $self = shift; my $mask = shift; my $add_mask = shift || 0; $self->send("SET_MASK " . ($mask | $add_mask)); } sub request_reply ($$) { my $self = shift; my $text = shift; my $win_id = shift; $self->send("Send_Reply $text", $win_id); } sub terminate ($;$) { my $self = shift; my $continue = shift || 0; die "!quit" if !$continue; die "!next"; } sub wait_packet ($) { } sub read_packet ($) { my $self = shift; goto RETURN_PACKET if @{$self->{synthetic_events}}; $self->{last_packet} = []; my $header = ""; my $packet = ""; $self->wait_packet; # read a packet's header first, sizeof(int) * HEADER_SIZE bytes long my $got; # With perl-5.8.0+, $SIG{ALRM} causes sysread to exit with "Illegal seek", # so loop around sysread. I am not sure this is safe. do { $got = sysread($self->{istream}, $header, INTSIZE * HEADER_SIZE); } until (defined $got); if ($got != (INTSIZE * HEADER_SIZE)) { # module killed or other read error $self->debug($got ? "read packet error" : "connection closed", 3); return undef; } my ($magic, $type, $len, $timestamp) = unpack(sprintf("L!%d", HEADER_SIZE), $header); $self->internal_die("Bad magic number $magic in packet") unless $magic == START_FLAG; # $type should not be anything other than a 32-bit number # however, extended messages are padded with set bits on 64-bit systems $type &= 0xffffffff; # $len is number of words in packet, including header; # we need this as number of bytes. $len -= HEADER_SIZE; $len *= INTSIZE; if ($len > 0) { my $off = 0; while ($off < $len) { $got = sysread($self->{istream}, $packet, $len, $off); if (!defined $got) { $self->internal_die("sysread error: $!"); } $off += $got; } $self->internal_die("Got packet len $off while expecting $len") if $off != $len; } RETURN_PACKET: ($type, $packet) = @{shift @{$self->{synthetic_events}}} if @{$self->{synthetic_events}}; $self->{last_packet} = [$type, $packet]; return ($type, $packet); } sub invoke_handler ($$) { my $self = shift; my $event = shift; my $type = $event->type; my $category = $self->get_handler_category($type); my @masks = sort { $a <=> $b } keys %{$self->{handlers}->{$category}}; foreach my $mask (@masks) { if ($type eq $mask || $type & $mask) { foreach my $handler (@{$self->{handlers}->{$category}->{$mask}}) { last unless $event->propagation_allowed; next unless defined $handler; # skip deleted ones eval { &$handler($self, $event); }; if ($@) { return 0 if $@ =~ /^!quit/i; return 1 if $@ =~ /^!next/i; die $@; } } } } return 1; } sub process_packet ($;$$) { my $self = shift; my ($type, $packet) = @_; ($type, $packet) = @{$self->{last_packet}} unless defined $packet; return undef unless defined $packet; my $event = eval { new FVWM::Event($type, $packet); }; $self->internal_die($@ || "Internal error") unless defined $event; if ($self->{debug}) { my $msg = "got " . $event->name; $msg .= " [" . $event->arg_values->[-1] . "]" if @{$event->arg_types} && $event->arg_types->[-1] == FVWM::EventNames::string(); $self->debug($msg, 2); } $self->{should_send_unlock} = 1 if $self->is_in_sync_mask($type); my $continue = $self->invoke_handler($event); $self->send_unlock if $self->{should_send_unlock}; return $continue; } sub emulate_event ($$$) { my $self = shift; my ($type, $packet) = @_; if ($self->{is_in_event_loop}) { $self->invoke_handler(new FVWM::Event($type, $packet)); return; } push @{$self->{synthetic_events}}, [$type, $packet]; } sub event_loop_prepared ($@) { my $self = shift; my $tracking = shift() ? 1 : 0; if (!$self->{is_in_event_loop}) { $self->send_ready unless $tracking; $self->debug("entered event loop", 3 + $tracking); $self->{is_in_event_loop} = 1; } # update module masks to handle trackers if needed my $add_mask = 0; my $add_xmask = 0; foreach (values %{$self->{trackers}}) { my ($mask, $xmask) = $_->masks; $add_mask |= $mask; $add_xmask |= $xmask; } $self->send_mask($self->mask, $self->{add_mask} = $add_mask) if $add_mask != $self->{add_mask}; $self->send_mask($self->xmask | M_EXTENDED_MSG, $self->{add_xmask} = $add_xmask) if $add_xmask != $self->{add_xmask}; # execute postponed commands if any $self->send(@{shift @{$self->{held_command_args}}}) while @{$self->{held_command_args}}; # fire emulated events if any $self->process_packet(@{shift @{$self->{synthetic_events}}}) while !$tracking && @{$self->{synthetic_events}}; } sub event_loop_finished ($@) { my $self = shift; my $tracking = shift() ? 1 : 0; $self->debug("exited event loop", 3 + $tracking); unless ($tracking) { foreach my $tracker (values %{$self->{trackers}}) { $tracker->to_be_disconnected; } $self->disconnect; } $self->{is_in_event_loop} = 0; } sub event_loop ($@) { my $self = shift; while (1) { $self->event_loop_prepared(@_); # catch exceptions during read, for example from alarm() handler, # but don't catch errors (or die) in event handlers $self->process_packet(eval { $self->read_packet }) || last; } $self->event_loop_finished(@_); } sub track ($$;$@) { my $self = shift; my $params = ref($_[0]) eq 'HASH' ? shift() : {}; my $tracker_type = shift; my $tracker_class = $tracker_type =~ /::/ ? $tracker_type : "FVWM::Tracker::$tracker_type"; # load a tracker class if not yet unless (defined $self->{used_tracker_classes}->{$tracker_class}) { eval "use $tracker_class;"; die $@ if $@; $self->{used_tracker_classes}->{$tracker_class} = 1; } my $tracker = !$params->{NoReuse} && $self->{trackers}->{$tracker_type} || $tracker_class->new($self, @_); if ($params->{NoReuse}) { $tracker_type .= "+" while exists $self->{trackers}->{$tracker_type}; } $self->{trackers}->{$tracker_type} = $tracker; $tracker->start unless $params->{NoStart}; return $tracker; } sub add_handler ($$$;$) { my $self = shift; my $type = shift; my $handler = shift; my $is_tracking = shift || 0; $self->internal_die("add_handler: no handler type") unless defined $type; $self->internal_die("add_handler: no handler code") unless ref($handler) eq 'CODE'; my $category = $self->get_handler_category($type); $self->{handlers}->{$category}->{$type} = [] unless exists $self->{handlers}->{$category}->{$type}; push @{$self->{handlers}->{$category}->{$type}}, $handler; my $index = @{$self->{handlers}->{$category}->{$type}} - 1; unless ($is_tracking) { $self->mask($self->mask | $type, 0) if !$self->{mask_was_set} && $category eq "regular"; $self->xmask($self->xmask | $type, 0) if !$self->{xmask_was_set} && $category eq "extended"; } return [$type, $index]; } sub delete_handler ($$) { my $self = shift; my $id = shift; return 0 unless ref($id) eq 'ARRAY' && @$id == 2; my ($type, $index) = @$id; my $category = $self->get_handler_category($type); return 0 unless defined $self->{handlers}->{$category}->{$type}->[$index]; $self->{handlers}->{$category}->{$type}->[$index] = undef; return 1; } sub add_default_error_handler ($) { my $self = shift; $self->add_handler(M_ERROR, sub { my ($self, $type, @args) = @_; my $error = $args[3]; print STDERR "[", $self->name, "]: got fvwm error: $error\n"; #$self->terminate; }); } sub user_data_dir ($) { return $ENV{FVWM_USERDIR} || (($ENV{HOME} || "") . "/.fvwm"); } sub site_data_dir ($) { return "@FVWM_DATADIR@"; } sub search_dirs ($) { my $this = shift; return ($this->user_data_dir, $this->site_data_dir); } # support old API, like addHandler, dispatch to add_handler sub AUTOLOAD ($;@) { my $self = shift; my @params = @_; my $autoload_method = $AUTOLOAD; my $method = $autoload_method; # remove the package name $method =~ s/.*://g; $method =~ s/XMask/Xmask/; $method =~ s/([a-z])([A-Z])/${1}_\L$2/g; die "No method $method in $self as guessed from $autoload_method" unless $self->can($method); $self->$method(@params); } 1; __END__ =head1 NAME FVWM::Module - the base class representing fvwm module =head1 SYNOPSIS use lib `fvwm-perllib dir`; use FVWM::Module; my $module = new FVWM::Module; $module->send("Beep"); # auto-raise all windows sub auto_raise { $_[0]->send("Raise", $_[1]->_win_id) }; $module->add_handler(M_FOCUS_CHANGE, \&auto_raise); # terminate itself after 5 minutes my $scheduler = $module->track('Scheduler'); $scheduler->schedule(5 * 60, sub { $module->terminate; }); # print the current desk number ($page_tracker is auto updated) my $page_tracker = $module->track("PageInfo"); $module->show_message("Desk: " . $page_tracker->data->{desk_n}); $module->event_loop; =head1 DESCRIPTION An fvwm module is a separate program that communicates with the main I process, receives a module configuration and events and sends commands back. This class B makes it easy to create fvwm modules in Perl. If you are interested in all module protocol details that this class tries to make invisible, visit the web page I. You will need an information about packet arguments anyway to be able to write complex modules. This is however not obligatory for simple modules that only send commands back when something happens. A typical fvwm module has an initialization part including setting event handlers using B methods and entering an event loop using B method. Most of the work is done in the event handlers although a module may define other execution ways, for example using C<$SIG{ALRM}>. An fvwm module receives 3 values from I: I - the file this module was called from or "none" if the module is called as a command from another module or from a binding/function (this value is not really useful), I - the window context of this module if it is called from window decoration bindings or window menu (the value is integer, 0 if there is no window context), and finally I that indicates the place this module was called from, like menu or window title (see the fvwm documentation). All these values may be accessed as properties of the module object, like C<$module-E{win_id}>. =head1 METHODS The following methods are available: B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B. The following methods are called from other methods above, but may be useful in other situations as well: B, B, B, B, B, B, B, B, B, B, B, B, B, B. These methods deal with a received packet (event): B These methods deal with configuration directories: B, B, B =over 4 =item B I Creates a module object. Only one module instance may be created in the program, since this object gets exclusive rights on communication with I. The following parameters may be given in the constractor: Name - used in module configuration and debugging Mask - events a module is interested to receive XMask - the same for extended events SyncMask - events to lock on SyncXMask - the same for extended events EnableAlias - whether a module accepts an alias in command line EnableOptions - options that a module accepts in command line Debug - 0 means no debug, 1 - user debug, 2,3,4 - perllib Example: my $module = new FVWM::Module( Name => "FvwmPerlBasedWindowRearranger", Mask => M_CONFIGURE_WINDOW | M_END_WINDOWLIST, EnableOptions => { "animate" => \$a, "cascade" => \$c }, Debug => 2, ); Event types needed for the 4 mask parameters are defined in B. Set I to 2 to nicely dump all communication with fvwm (sent commands and received events). Setting it to 3 makes it even more verbose. Some options cause an automatically parsing of the module command line args. See L for the format of the hash ref accepted by I parameter. If boolean I parameter is given, then the alias argument may be specified anywhere on the command line, for example before or after long/short options or even in between, as long as there are no conflicts with some non-mandatory option arguments. In which case "--" may be used to indicate the end of the options. All non-parsed command line arguments are available to the program using B method. =item B Returns fvwm version string I. =item B Returns fvwm version info string, like " (from cvs)" or " (snap-YYYYMMDD)". This string is usually empty for the final version. =item B Returns remaining module arguments (array ref) passed in the command line. Arguments that are used for I-to-module communication are not included. Arguments that are automatically parsed using I and/or I specified in the constructor are not included. =item B I [I] [I] Sends I back for execution. If the I is specified this command will be executed in this window context. I of 0 signals that this is the last sent command from the module, the default for this flag is 1. =item B [I] [I] [I] Creates a module tracker object (see L) specified by a I. I may include parameters: NoStart - true value means the created tracker is not auto-started NoReuse - true value means not to reuse any existing named tracker I is specific to the tracker named I. Every tracker class (a subclass of B) has its own manual page, contact it for the tracker details and usage. =item B The main event loop. A module should define some event handlers using B before entering the event loop. When the event happens all event handlers registered on this event are called, then a module returns to the event loop awaiting for new events forever. This method may be finished when one of the following happens. 1) Explicit B is called in one of the event handlers. 2) Signal handler (system signals are independent from this event loop) decides to I. This is usually catched and a proper shutdown is done. 3) An event handler Id, in this case the module aborts, this is done on purpose to encourage programmers to fix bugs. 4) Communication with I closed, for example B called or the main I process exited. In all these cases (except for the third one) I event handlers are called if defined and then B is called. So no communication is available after this method is finished. If you need a communication before the module exits, define an I event handler. =item B This is automatically called (if needed) when a module enters B, but sometimes you may want to tell I that the module is fully ready earlier. This only makes sence if the module was run using B command, in this case I gets locked until the module sends the "ready" notification. =item B When an event was configured to be sent to a module synchronously using I and I, I gets locked until the module sends the "unlock" notification. This is automatically sent (if needed) when a handler is finished, but sometimes a handler should release I earlier. =item B I [I] A module may request I to send the same text (but possibly interpolated) back to it using MX_REPLY event. This method sends special command I. =item B I [I] [I] The same like B, but the actual command sending is postponed until before the module enters the reading-from-fvwm phase in B. =item B [I] This method is used for 2 purposed, usually in event handlers. To terminate the entire event loop and to terminate only an execution of the current handler if I is set. =item B This deletes all event handlers without exception. =item B I Defines a handler (that is a I subroutine) for the given I event (or several events). Usually the event type is one of the fvwm I or I constants (see B), but it may also be I, this special event is called just before the event loop is terminated. The I may include several events in the same category (the event types are or-ed). In this case the handler will be called for every matching event. Currently there are 3 categories: regular events (M_*), extended events (MX_*) and special events (ON_EXIT). These 3 categories of events can't be mixed, primary because of technical reasons. The handler subroutine is called with these parameters: ($self, $event) where C<$self> is a module object, C<$event> is B object. If the I includes more than one event type, use C<$event-Etype> to dispatch event types if needed. The handler may call C<$self-Eterminate> to terminate the event loop completely or C<$self-Eterminate("continue")> to terminate the current event handler only. The second form is useful when the handler subroutine calls other subroutines that need to terminate the primary one. If several event handlers are added for the same event type, they are executed in the added order. To forbid the further propagation of the same event, an event handler may call C<$event-Epropagation_allowed(0)>. The return value from B is an identifier the only purpose of which is to be passed to B in case the newly defined handler should be deleted at some point. =item B I Removes the handler specified by I. The return value is 1 if the handler is found and deleted, 0 otherwise. =item B This adds the default handler for I event. This class simply prints an error message to the standard error stream, but subclasses may define another default handler by overwriting this method. =item B I [I] Prints I to the standard error stream if I is greater or equal to the module debug level defined using I in the constructor. The default I for this method is 1 that makes it possible to add user debugging output without specifying a level. The default module level is 0, so no debugging output of positive levels is shown. This module uses B internally (with I 2) to dump all incoming and outgoing communication data in B and B. Apparently this output is only seen if I is set to 2 or greater. =item B I Writes I to the error stream (stderr). It is supposed that the argument has no traling end of line. May be used to signal non fatal error. Subclasses may overwrite this method and, for example, show all error messages in separate windows or in the common error window. =item B I Writes I to the message stream (stderr). It is supposed that the argument has no traling end of line. May be used to show a named output. Subclasses may overwrite this method and, for example, show all messages in separate windows or in the common message window. =item B I Unconditionally writes I to the debug stream (stderr). It is supposed that the argument has no traling end of line. Used in B to actually show the message when the level is matched. Subclasses may overwrite this method and, for example, show all debugging messages in separate windows or in the common debug window. =item B Usually a module should be executed by I only. But to help creating GUI applications, the dummy mode is supported when the module is started from the command line. No events are received in this case, but with some effort they may be emulated: $module->emulate_event(M_NEW_DESK, [ 2 ]) if $module->is_dummy; =item B I This may be used to end the module with the corresponding I. For a clean module exit use B and B instead. =item B [I] Sets or returns the module name. Called automatically from the constructor. =item B [I] [I] =item B [I] [I] Sets or returns the module mask. Called automatically from the constructor. Regular and extended event types should never be mixed, this is why there are 2 variants of this method, the first is for regular and the second is for extended event types. Without a parameter, the module mask is returned, the integer parameter indicates a mask to set and the old mask is returned. The module only receives the packets matching these 2 module masks (regular and extended). This class is smart to update the minimal module masks automatically if you never set them explicitly (either in constructor or using these methods). The I parameter should not be usually used, it defaults to 1. If you set it to 0 then the module is informed to continue to automatically update masks on the following B calls even after the current mask setting. =item B I Returns true if the module mask matches the given I. Good for both regular and extended event types as long as they are queried separately. =item B [I] =item B [I] The same as B and B, but sets/returns the synchronization mask of the module. The module is synchronized with I on all packets matching these 2 module synchronization masks (regular and extended). =item B I Returns true if the module synchronization mask matches the given I. Good for both regular and extended event types as long as they are queried separately. =item B This method invokes I handlers if any and closes communication. It is called automatically from B before finishing. It is safe to call this method more than once. This method may be called from signal handlers before Iing for the proper shutdown. =item B I Returns one of 3 string ids depending on the event handler I that has the same meaning as the corresponding packet type ("regular" or "extended") with an addition of "special" category for I handlers. =item B This is a blocking method that waits until there is a packet on the communication end from I. Then it returns a list of 2 values, packet type and packet data (unpacked array of arguments). =item B I Dispatches the apropos event handlers with the event data. This method is called automatically, so you usually should not worry about it. =item B [I] This method constructs the event object from the packet data and calls B with it. Prints debug info if requested. Finally calls B if needed. You should not really worry about this method, it is called automatically from the event loop. =item B I This method emulates the event as returned by B. The given event is processed immediately if in the event loop, or just before the real B otherwise. The parameters are the same as in B and the same as in L constructor. =item B Called from B every time before reading the packet for new data. Subclasses should pass this method the same arguments that B received for a possible future use. =item B Called from B just before the return. Subclasses should pass this method the same arguments that B received for a possible future use. =item B I For technical reasons there are 2 categories of fvwm events, regular and extended. This is done to enable more events. With introdution of the extended event types (with the highest bit set) it is now possible to have 31+31=62 different event types rather than 32. This is a good point, the bad point is that only event types of the same category may be masked (or-ed) together. This method returns 1 or 0 depending on whether the event I is extended or not. =item B Returns the user data directory, usually ~/.fvwm or set by $FVWM_USERDIR. =item B Returns the system-wide data directory, the one configured when fvwm is installed. It is also returned by `fvwm-config --fvwm-datadir`. =item B It is a good practice for a module to search for the given configuration in one of 2 data directories, the user one and the system-wide. This method returns a list of both directories in that order. =back =head1 BUGS Awaiting for your reporting. =head1 CAVEATS In keeping with the UNIX philosophy, B does not keep you from doing stupid things, as that would also keep you from doing clever things. What this means is that there are several areas with which you can hang your module or even royally confuse your running I process. This is due to flexibility, not bugs. =head1 AUTHOR Mikhael Goikhman . =head1 THANKS TO Randy J. Ray . =head1 SEE ALSO For more information, see L and L, L. =cut fvwm-2.6.7/perllib/FVWM/Makefile.in0000644000175700017570000005715013010103323013713 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = perllib/FVWM DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/Module.pm.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = Module.pm CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(configdir)" DATA = $(config_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ SUBDIRS = Module Tracker configdir = @FVWM_PERLLIBDIR@/FVWM ORIGINAL_PMS = \ Commands.pm Constants.pm EventNames.pm Event.pm Tracker.pm config_DATA = $(ORIGINAL_PMS) Module.pm EXTRA_DIST = $(ORIGINAL_PMS) create-commands create-constants all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign perllib/FVWM/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign perllib/FVWM/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): Module.pm: $(top_builddir)/config.status $(srcdir)/Module.pm.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-configDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-configDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am \ install-configDATA install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ tags-am uninstall uninstall-am uninstall-configDATA _Constants.pm: Makefile.am $(top_srcdir)/libs/Module.h cd $(top_builddir)/perllib/FVWM && \ (fvwm_libdir=$(top_builddir)/libs ./create-constants) _Commands.pm: Makefile $(top_srcdir)/fvwm/functable.c cd $(top_builddir)/perllib/FVWM && \ (fvwm_libdir=$(top_builddir)/libs ./create-commands) regenerate: _Constants.pm _Commands.pm # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/perllib/FVWM/create-commands0000755000175700017570000000740612673746443014673 00000000000000#!/usr/bin/perl -w use FindBin; use lib "$FindBin::Bin/.."; use General::FileSystem; use POSIX; chdir($FindBin::Bin) || die "Can't chmod $FindBin::Bin: $!\n"; my $functable_src = "../../fvwm/functable.c"; my $content_ref = load_file($functable_src); die "No commands found, so Commands.pm is not generated.\n" unless $content_ref; my $command_entries_code = ""; foreach my $entry ($$content_ref =~ m{(?:/\* )?CMD_ENT\(\s*(?:"|PRE_).*?\),(?: \*/)?.*?/\* .*?- .*? \*/}sg) { my ($name, $flags, $cursor, $name2, $descr) = $entry =~ m{ , .*? CMD_(\w+) , .*? , .*? ([\w\s|]+?) , .*? (?:CRS_)?(\w+) .*? \) , .*? /\*\s (?:(.+)\s)? -\s (.*?) \s\*/ }xs; $name = $name2 if $name2; my $window = $flags =~ FUNC_NEEDS_WINDOW? 1: 0; $cursor = "" if $cursor eq "0"; $command_entries_code .= "\t{\n\t\tname => '$name',\n\t\tcursor => '$cursor',\n" . "\t\twindow => $window,\n\t\tdescr => q{$descr},\n\t},\n"; } my $version = `egrep '^VERSION = |^VERSIONINFO = ' Makefile | cut -d"=" -f2 \\ | perl -pe 's/^ //;s/\\n//'`; my $time = time; my $output = <{name}, \$command->{descr}; } =head1 PUBLIC CONSTANTS =over 4 =item \$VERS The fvwm version number at the generation time like "2.6.0" plus the info that may indicate that this is not a final version, but a cvs snapshot. =item \$TIME The unix time of the command list generation. Example: print "The fvwm command list found on your system was generated " . (time() - \$FVWM::Commands::TIME) / 86400 . " days ago\\n"; =item \@LIST The command list that is an array of hashes with keys I, I, I (string) and I (boolean). I may be special, like "+", "#" and "*". Other names usually contain only isalpha characters, like B, B. I may be either empty or the cursor context used in B (like "SELECT" or "MOVE"), associated with the command. I is a short one line description of the command. I is true for commands that need a window. Example: # get command names only \@command_names = map { \$_->{name} } \@FVWM::Commands::LIST; =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information about the commands themselves, see fvwm(1). =cut ENDOUTPUT # --------------------------------- print "Creating Commands.pm\n"; save_file("Commands.pm", \$output); # --------------------------------- print "Testing Commands.pm\n"; eval qq{ use lib '$FindBin::Bin/..'; use FVWM::Commands; }; die $@ if $@; $FVWM::Commands::TIME ||= 0; # avoid "used once" warning my $date = strftime("%d-%b-%Y", gmtime($FVWM::Commands::TIME)); my $cmds = "The recognized commands for fvwm $version as of $date:\n\n"; foreach my $command (@FVWM::Commands::LIST = @FVWM::Commands::LIST) { $cmds .= sprintf " %-21s - %s\n", $command->{name}, $command->{descr}; } # --------------------------------- print "Creating ../../docs/COMMANDS\n"; save_file("../../docs/COMMANDS", \$cmds); fvwm-2.6.7/perllib/FVWM/Constants.pm0000644000175700017570000001002012673746443014177 00000000000000# Autogenerated from the fvwm sources. package FVWM::Constants; use Exporter; use Config; @ISA = qw(Exporter); use constant M_NEW_PAGE => (1); use constant M_NEW_DESK => (1<<1); use constant M_OLD_ADD_WINDOW => (1<<2); use constant M_RAISE_WINDOW => (1<<3); use constant M_LOWER_WINDOW => (1<<4); use constant M_OLD_CONFIGURE_WINDOW => (1<<5); use constant M_FOCUS_CHANGE => (1<<6); use constant M_DESTROY_WINDOW => (1<<7); use constant M_ICONIFY => (1<<8); use constant M_DEICONIFY => (1<<9); use constant M_WINDOW_NAME => (1<<10); use constant M_ICON_NAME => (1<<11); use constant M_RES_CLASS => (1<<12); use constant M_RES_NAME => (1<<13); use constant M_END_WINDOWLIST => (1<<14); use constant M_ICON_LOCATION => (1<<15); use constant M_MAP => (1<<16); use constant M_ERROR => (1<<17); use constant M_CONFIG_INFO => (1<<18); use constant M_END_CONFIG_INFO => (1<<19); use constant M_ICON_FILE => (1<<20); use constant M_DEFAULTICON => (1<<21); use constant M_STRING => (1<<22); use constant M_MINI_ICON => (1<<23); use constant M_WINDOWSHADE => (1<<24); use constant M_DEWINDOWSHADE => (1<<25); use constant M_VISIBLE_NAME => (1<<26); use constant M_SENDCONFIG => (1<<27); use constant M_RESTACK => (1<<28); use constant M_ADD_WINDOW => (1<<29); use constant M_CONFIGURE_WINDOW => (1<<30); use constant M_EXTENDED_MSG => (1<<31); use constant MX_VISIBLE_ICON_NAME => ((1<<0)|M_EXTENDED_MSG); use constant MX_ENTER_WINDOW => ((1<<1)|M_EXTENDED_MSG); use constant MX_LEAVE_WINDOW => ((1<<2)|M_EXTENDED_MSG); use constant MX_PROPERTY_CHANGE => ((1<<3)|M_EXTENDED_MSG); use constant MX_REPLY => ((1<<4)|M_EXTENDED_MSG); use constant MX_PROPERTY_CHANGE_NONE => 0; use constant MX_PROPERTY_CHANGE_BACKGROUND => 1; use constant MX_PROPERTY_CHANGE_SWALLOW => 2; use constant MAX_MSG_MASK => 0x7fffffff; use constant MAX_XMSG_MASK => 0x0000001f; use constant HEADER_SIZE => 4; use constant START_FLAG => 0xffffffff; use constant RESPONSE_READY => "NOP FINISHED STARTUP"; use constant RESPONSE_UNLOCK => "NOP UNLOCK"; use constant ON_EXIT => '1e20'; use constant INTSIZE => $Config{longsize}; @EXPORT = qw( M_NEW_PAGE M_NEW_DESK M_OLD_ADD_WINDOW M_RAISE_WINDOW M_LOWER_WINDOW M_OLD_CONFIGURE_WINDOW M_FOCUS_CHANGE M_DESTROY_WINDOW M_ICONIFY M_DEICONIFY M_WINDOW_NAME M_ICON_NAME M_RES_CLASS M_RES_NAME M_END_WINDOWLIST M_ICON_LOCATION M_MAP M_ERROR M_CONFIG_INFO M_END_CONFIG_INFO M_ICON_FILE M_DEFAULTICON M_STRING M_MINI_ICON M_WINDOWSHADE M_DEWINDOWSHADE M_VISIBLE_NAME M_SENDCONFIG M_RESTACK M_ADD_WINDOW M_CONFIGURE_WINDOW M_EXTENDED_MSG MX_VISIBLE_ICON_NAME MX_ENTER_WINDOW MX_LEAVE_WINDOW MX_PROPERTY_CHANGE MX_REPLY MX_PROPERTY_CHANGE_NONE MX_PROPERTY_CHANGE_BACKGROUND MX_PROPERTY_CHANGE_SWALLOW MAX_MSG_MASK MAX_XMSG_MASK HEADER_SIZE START_FLAG RESPONSE_READY RESPONSE_UNLOCK ON_EXIT INTSIZE ); 1; __END__ =head1 NAME FVWM::Constants - exports fvwm specific constants =head1 DESCRIPTION This class is used to load fvwm constants into your perl script or class. Note, if you use I the constants are automatically exported. So you usually do not need to include this class. =head1 USAGE use FVWM::Constants; =head1 SEE ALSO For more information, see L. =head1 EXPORTED CONSTANTS M_NEW_PAGE M_NEW_DESK M_OLD_ADD_WINDOW M_RAISE_WINDOW M_LOWER_WINDOW M_OLD_CONFIGURE_WINDOW M_FOCUS_CHANGE M_DESTROY_WINDOW M_ICONIFY M_DEICONIFY M_WINDOW_NAME M_ICON_NAME M_RES_CLASS M_RES_NAME M_END_WINDOWLIST M_ICON_LOCATION M_MAP M_ERROR M_CONFIG_INFO M_END_CONFIG_INFO M_ICON_FILE M_DEFAULTICON M_STRING M_MINI_ICON M_WINDOWSHADE M_DEWINDOWSHADE M_VISIBLE_NAME M_SENDCONFIG M_RESTACK M_ADD_WINDOW M_CONFIGURE_WINDOW M_EXTENDED_MSG MX_VISIBLE_ICON_NAME MX_ENTER_WINDOW MX_LEAVE_WINDOW MX_PROPERTY_CHANGE MX_REPLY MX_PROPERTY_CHANGE_NONE MX_PROPERTY_CHANGE_BACKGROUND MX_PROPERTY_CHANGE_SWALLOW MAX_MSG_MASK MAX_XMSG_MASK HEADER_SIZE START_FLAG RESPONSE_READY RESPONSE_UNLOCK ON_EXIT INTSIZE fvwm-2.6.7/perllib/FVWM/Event.pm0000644000175700017570000001775012673746443013325 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Event; use strict; use FVWM::EventNames; sub new ($$$) { my $class = shift; my $type = shift; my $arg_values = shift; my $is_special = defined $arg_values ? 0 : 1; my $is_extended = $type & M_EXTENDED_MSG ? 1 : 0; $arg_values ||= []; $arg_values = event_arg_values($is_special ? "faked" : $type, $arg_values) unless ref($arg_values); my $self = { type => $type, args => undef, # lazy hash of event arguments arg_values => $arg_values, propagation_allowed => 1, is_special => $is_special, is_extended => $is_extended, }; bless $self, $class; return $self; } sub type ($) { my $self = shift; return $self->{'type'}; } sub arg_values ($) { my $self = shift; return $self->{'arg_values'}; } sub arg_names ($) { my $self = shift; return event_arg_names($self->type, $self->arg_values); } sub arg_types ($) { my $self = shift; return event_arg_types($self->type, $self->arg_values); } sub loop_arg_names ($) { my $self = shift; return event_loop_arg_names($self->type, $self->arg_values); } sub loop_arg_types ($) { my $self = shift; return event_loop_arg_types($self->type, $self->arg_values); } sub args ($) { my $self = shift; $self->{'args'} ||= event_args($self->type, $self->arg_values); return $self->{'args'}; } sub is_extended ($) { my $self = shift; return $self->{'is_extended'}; } sub name ($) { my $self = shift; return event_name($self->type); } sub propagation_allowed ($;$) { my $self = shift; my $value = shift; $self->{'propagation_allowed'} = $value if defined $value; return $self->{'propagation_allowed'}; } sub dump ($) { my $self = shift; my $args = $self->args; my $string = $self->name . "\n"; my @arg_names = @{$self->arg_names}; my @arg_types = @{$self->arg_types}; my @arg_values = @{$self->arg_values}; while (@arg_names) { my $name = shift @arg_names; my $type = shift @arg_types; my $value = shift @arg_values; my $text; if ($type == FVWM::EventNames::number) { $text = $value; $text = "*undefined*" unless defined $value; } elsif ($type == FVWM::EventNames::bool) { $text = $value? "True": "False"; } elsif ($type == FVWM::EventNames::window) { $text = sprintf("0x%07lx", $value); } elsif ($type == FVWM::EventNames::pixel) { $text = "rgb:" . join('/', sprintf("%06lx", $value) =~ /(..)(..)(..)/); } elsif ($type == FVWM::EventNames::string) { $value =~ s/"/\\"/g; $text = qq("$value"); } elsif ($type == FVWM::EventNames::looped) { my $loop_arg_names = $self->loop_arg_names; my $loop_arg_types = $self->loop_arg_types; my $j = 0; while ($j < @$value) { my $k = 0; foreach (@$loop_arg_names) { my $i = int($j / @$loop_arg_names) + 1; push @arg_names, "[$i] $_"; push @arg_types, $loop_arg_types->[$k]; push @arg_values, $value->[$j]; $j++; $k++; } } $text = sprintf("(%d)", @$value / @$loop_arg_names); } elsif ($type == FVWM::EventNames::wflags) { $text = qq([window flags are not supported yet]); } else { $text = qq([unsupported arg type $type] "$value"); } my $name_len = 12; $name_len = int((length($name) + 5) / 6) * 6 if length($name) > $name_len; $string .= sprintf "\t%-${name_len}s %s\n", $name, $text; } return $string; } sub AUTOLOAD ($;@) { my $self = shift; my @params = @_; my $method = $FVWM::Event::AUTOLOAD; # remove the package name $method =~ s/.*://g; # DESTROY messages should never be propagated return if $method eq 'DESTROY'; if ($method =~ s/^_//) { my $arg_value = $self->args->{$method}; return $arg_value if defined $arg_value; my $alias = event_arg_aliases($self->type)->{$method} || '*none*'; $arg_value = $self->args->{$alias}; return $arg_value if defined $arg_value; die "Unknown argument $method for event " . $self->name . "\n"; } die "Unknown method $method on $self called\n"; } # ---------------------------------------------------------------------------- =head1 NAME FVWM::Event - the fvwm event object passed to event handlers =head1 SYNOPSIS use lib `fvwm-perllib dir`; use FVWM::Module; my $module = new FVWM::Module(Mask => M_FOCUS_CHANGE); # auto-raise all windows sub auto_raise ($$) { my ($module, $event) = @_; $module->debug("Got " . $event->name . "\n"); $module->debug("\t$_: " . $event->args->{$_} . "\n") foreach sort keys %{$event->args}; $module->send("Raise", $event->_win_id); } $module->add_handler(M_FOCUS_CHANGE, \&auto_raise); $module->event_loop; =head1 DESCRIPTION To be written. =head1 METHODS =over 4 =item B I I Constructs event object of the given I. I is either an array ref of event's arguments (every event type has its own argument list, see L) or a packed string of these arguments as received from the I pipe. =item B Returns event's type (usually long integer). =item B Returns an array ref of the event argument names. print "$_ " foreach @{$event->arg_names}); Note that this array of names is statical for any given event type. =item B Returns an array ref of the event argument types. print "$_ " foreach @{$event->arg_types}); Note that this array of types is statical for any given event type. =item B Returns an array ref of the looped argument names of the event (or undef). =item B Returns an array ref of the looped argument types of the event (or undef). =item B Returns an array ref of the event argument values. In the previous versions of the library, all argument values were passed to event handlers, now only one event object is passed. Calling this method is the way to emulate the old behaviour. Note that you should know the order of arguments, so the suggested way is to use C instead, although it is a bit slower. =item B Returns hash ref of the named event argument values. print "[Debug] Got event ", $event->type, " with args:\n"; while (($name, $value) = each %{$event->args}) { print "\t$name: $value\n"; } =item B For technical reasons there are 2 categories of fvwm events, regular and extended. This was done to enable more events. With introdution of the extended event types (with the highest bit set) it is now possible to have 31+31=62 different event types rather than 32. This is a good point, the bad point is that only event types of the same category may be masked (or-ed) together. This method returns 1 or 0 depending on whether the event is extended or not. =item B Returns a string representing the event name (like "M_ADD_WINDOW"), it is the same as the corresponding C/Perl constant. May be (and in fact is) used for debugging. =item B [I] Sets or returns a boolean value that indicates enabling or disabling of this event propagation. =item B Returns a string representation of the event object, basically the event name and all argument name=value lines. =item B<_>I This is a shortcut for $event->args->{'I'}. Returns the named event argument. See L for names of all event argument names. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L, L, L and L. =cut 1; fvwm-2.6.7/perllib/FVWM/Tracker.pm0000644000175700017570000002660612673746443013637 00000000000000# Copyright (c) 2003-2009, Mikhael Goikhman # # 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 package FVWM::Tracker; use 5.004; use strict; use FVWM::Constants; sub import ($@) { my $class = shift; my $caller = caller; while (@_) { my $name = shift; if ($name eq 'base') { next if UNIVERSAL::isa($caller, __PACKAGE__); eval " package $caller; use vars qw(\@ISA); use FVWM::Constants; \@ISA = qw(FVWM::Tracker); "; if ($@) { die "Internal error:\n$@"; } } } } sub new ($$) { my $class = shift; my $module = shift; die "$class: no FVWM::Module object given in constructor\n" unless UNIVERSAL::isa($module, "FVWM::Module"); my $self = { module => $module, data => undef, active => 0, handler_types => {}, handler_ids => {}, observers => {}, }; bless $self, $class; return $self; } sub masks ($) { my $self = shift; my $mask = 0; my $xmask = 0; while (my ($id, $type) = each %{$self->{handler_types}}) { (($type & M_EXTENDED_MSG) ? $xmask : $mask) |= $type; } $self->internal_die("Inactive mask is not zero") unless $self->{active} || !$mask && !$xmask; my @list = ($mask, $xmask); return wantarray ? @list : \@list; } sub add_handler ($$$) { my $self = shift; my $type = shift; my $handler = shift; my $handler_id = $self->{module}->add_handler($type, $handler, 1); $self->{handler_types}->{$handler_id} = $type; $self->{handler_ids}->{$handler_id} = $handler_id; return $handler_id; } sub delete_handlers ($;$) { my $self = shift; my $handler_ids = ref($_[0]) eq 'ARRAY' ? shift() : [ keys %{$self->{handler_ids}} ]; foreach (@$handler_ids) { next unless defined delete $self->{handler_types}->{$_}; my $handler_id = delete $self->{handler_ids}->{$_} or die "Internal #1"; if ($self->{module}) { $self->{module}->delete_handler($handler_id) or die "Internal #2"; } } } sub observe ($$;$) { my $self = shift; my $observable = ref($_[0]) eq "" ? shift : "main"; my $callback = shift; my $observables = $self->observables; $observable = $observables->[0] if $observable eq "main"; $self->{module}->debug(qq(observe "$observable"), 3); # TODO: check observable existence $self->{observers}->{$observable} ||= []; push @{$self->{observers}->{$observable}}, $callback; return [ $observable, @{$self->{observers}->{$observable}} - 1 ]; } sub unobserve ($;$$) { my $self = shift; my $observable = ref($_) eq "" ? shift : "*"; my $observer_id = shift || "*"; ### TODO #$self->{observers}->{$observable} = []; } sub notify ($$@) { my $self = shift; my $observable = shift; my $observables = $self->observables; $observable = $observables->[0] if $observable eq "main"; $self->{module}->debug(qq(notify "$observable"), 3); # TODO: check observable existence my @callbacks = (); push @callbacks, @{$self->{observers}->{$observable}} if exists $self->{observers}->{$observable}; push @callbacks, @{$self->{observers}->{'all'}} if exists $self->{observers}->{'all'} && $observable ne 'all'; foreach (@callbacks) { $_->($self->{module}, $self, $self->data, @_); } } sub start ($) { my $self = shift; return if $self->{active}; $self->{active} = 1; $self->{module}->FVWM::Module::event_loop(1) if %{$self->{handler_ids}}; return $self->data; } sub stop ($) { my $self = shift; return unless $self->{active}; $self->delete_handlers; $self->{active} = 0; } sub restart ($) { my $self = shift; $self->stop; $self->start; } sub to_be_disconnected ($) { } sub data ($) { my $self = shift; return $self->{data}; } sub dump ($) { my $self = shift; return ""; } sub request_windowlist_events ($) { my $self = shift; my $module = $self->{module}; warn "request_windowlist_events() called after start()" if $self->{active}; $self->add_handler(M_END_WINDOWLIST, sub { $_[0]->terminate; }); $module->emulate_event(M_END_WINDOWLIST, []) if $module->is_dummy; $module->postpone_send("Send_WindowList"); } sub request_configinfo_events ($;$) { my $self = shift; my $name = shift; my $module = $self->{module}; warn "request_configinfo_events() called after start()" if $self->{active}; $self->add_handler(M_END_CONFIG_INFO, sub { $_[0]->terminate; }); $module->emulate_event(M_END_CONFIG_INFO, []) if $module->is_dummy; $module->postpone_send("Send_ConfigInfo" . ($name ? " *$name" : "")); } sub internal_die ($$) { my $self = shift; my $msg = shift; my $class = ref($self); $self->{module}->internal_die("$class: $msg") } sub DESTROY ($) { my $self = shift; $self->stop; } # class method, should be overwritten sub observables ($) { return []; } use vars qw($AUTOLOAD); # support old API, like addHandler, dispatch to add_handler sub AUTOLOAD ($;@) { my $self = shift; my @params = @_; my $autoload_method = $AUTOLOAD; my $method = $autoload_method; # remove the package name $method =~ s/.*://g; $method =~ s/XMask/Xmask/; $method =~ s/([a-z])([A-Z])/${1}_\L$2/g; die "No method $method in $self as guessed from $autoload_method" unless $self->can($method); $self->$method(@params); } 1; __END__ =head1 DESCRIPTION Tracker is an object that automatically listens to certain fvwm events and gathers an information in the background. When a tracker is created it may enter its own event loop to gather an initial data, so the returned tracker object already has the initial data. It also continues to update the data automatically until it is stopped. This package is a superclass for the concrete tracker implementations. It defines the common Tracker API, including a way to access the tracked data and to define high level events for the tracker caller to observe. =head1 SYNOPSYS Using B $module object: my $tracker = $module->track("TrackerName", @params); my $initial_data = $tracker->data; $tracker->observe("observable1", sub { shift->data }); $tracker->observe("observable2", sub { shift->stop }); In the future this syntax will probably work too: my $tracker = new FVWM::Tracker::TrackerName($module, @params); my $initial_data = $tracker->start; $tracker->observe("observable1", sub { shift->data }); $tracker->observe("observable2", sub { shift->stop }); =head1 PUBLIC METHODS =over 4 =item B Makes the tracker actually work, i.e. listen to I events, gather data and forms high level events, so called observables. This method is usually automatically called when the tracker is created unless specifically asked not to. =item B Stops the tracker activity. The corresponding I events are not listened, data is not updated and no observers called. To return the tracker to the normal activity, call B method. =item B This is a shortcut method to B and then B the tracker. The following scenatio is possible. You start the tracker, read its data and immediately stop it (to reduce event tracker to the module). At some point you may want to read the updated data, so you restart the tracker and optionally stop it again. Note that no observers are removed during B, so the tracker theoretically may be restarted without any side effect even if some observers are defined. =item B [I] I Defines an observer that will be called every time the tracker I happens. The I is a CODE reference that gets the following parameters: $module (B object), $tracker (this object), $data (the same as returned by B method) and optional observable parameters that are specific to this I. A special I value "main" means the first observable defined in the tracker, it is the default value when no I is given. =item B [I [I]] Stops an observing using the I that is returned by B method. A special I value "main" means the first observable defined in the tracker. A special I value "*" means all defined observables. =item B Returns the whole data collected by the tracker. Usually subclasses add an optional parameter I that limits the whole data to the given key. =item B Returns the string representing the whole tracker data in the human readable form, useful for debugging. Usually subclasses add an optional parameter I that limits the whole data to the given key. =back =head1 METHODS FOR SUBCLASSES =over 4 =item B A subclass should define a list of observables that a caller may listen to using B method. It is the subclass responsiblity to actually signal every observable listed using B method. Returns a reference to a string array. =item B I I This superclass method should be called by subclasses. Please do not use this class method in programs, use the first syntax shown in the I section instead. I is an B instance. I is specific to the concrete Tracker class. =item B I I A wrapper to B::B, has the same syntax, but stores all handlers so they may be deleted at once using B. =item B [I] Deletes all handlers defined using add_handler or the ones specified using an optional I array ref. =item B I [I] Notifies all listeners that were defined using B, by calling their observer function with the following parameters: $module, $tracker, $data, I. =item B Subclasses that work using I events sent in responce to B command should call this shortcut method. Automatically sends the needed command (after the tracker event mask is counted) and defines a handler that terminates the initial tracker event loop in response to I event. =item B Subclasses that work using I events sent in responce to B command should call this shortcut method. Automatically sends the needed command (after a tracker event mask is counted) and defines a handler that terminates the initial tracker event loop in response to I event. =item B Subclasses may call this method when something wrong happens. This is a wrapper to B::B. =item B Does nothing by default. Subclasses may implement this method if something should be sent to I just before the module disconnects itself. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L and the concrete tracker implementations: L, L, L, L, L, L. =cut fvwm-2.6.7/perllib/FVWM/Tracker/0000755000175700017570000000000013010103345013315 500000000000000fvwm-2.6.7/perllib/FVWM/Tracker/Makefile.am0000644000175700017570000000035312773470550015316 00000000000000## Process this file with automake to create Makefile.in configdir = @FVWM_PERLLIBDIR@/FVWM/Tracker config_DATA = \ Colorsets.pm GlobalConfig.pm ModuleConfig.pm PageInfo.pm \ Scheduler.pm WindowList.pm EXTRA_DIST = $(config_DATA) fvwm-2.6.7/perllib/FVWM/Tracker/Colorsets.pm0000644000175700017570000001147612673746443015613 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Tracker::Colorsets; use strict; use FVWM::Tracker qw(base); use General::Parse qw(get_tokens); use constant CS_FIELDS => qw( fg bg hilite shadow fgsh tint icon_tint pixmap shape_mask fg_alpha_percent width height pixmap_type shape_width shape_height shape_type tint_percent do_dither_icon icon_tint_percent icon_alpha_percent ); use constant PIXMAP_TYPES => qw( PIXMAP_TILED PIXMAP_STRETCH_X PIXMAP_STRETCH_Y PIXMAP_STRETCH PIXMAP_STRETCH_ASPECT PIXMAP_ROOT_PIXMAP_PURE PIXMAP_ROOT_PIXMAP_TRAN ); sub observables ($) { return [ "colorset changed", ]; } sub start ($) { my $self = shift; # just an extra debug service for developers $self->{module}->emulate_event(M_CONFIG_INFO, [ 0, 0, 0, "Colorset 0 0 00c0c0 00e0e0 00a0a0 007070 0 0 0 0 64 0 0 0 0 0 0 0 0 0 64" ]) if $self->{module}->is_dummy; $self->{data} = {}; $self->add_handler(M_CONFIG_INFO, sub { my $event = $_[1]; $self->calculate_internals($event->args); }); $self->request_configinfo_events; my $result = $self->SUPER::start; $self->delete_handlers; $self->add_handler(M_CONFIG_INFO, sub { my $event = $_[1]; my ($num, $old_hash) = $self->calculate_internals($event->args); return unless defined $num; $self->notify("colorset changed", $num, $old_hash); }); return $result; } sub calculate_internals ($$) { my $self = shift; my $args = shift; my $data = $self->{data}; my $text = $args->{text}; $self->internal_die("No 'text' arg in M_CONFIG_INFO") unless defined $text; return undef if $text !~ /^colorset ([\da-f]+) ([\da-f ]+)$/i; my $num = hex($1); my @numbers = get_tokens($2); return undef if @numbers != CS_FIELDS; # memory used for keys may be optimized later my $new_hash = {}; my $i = 0; foreach (CS_FIELDS) { $new_hash->{$_} = hex($numbers[$i++]); } my $old_hash = $data->{$num}; $data->{$num} = $new_hash; return wantarray? ($num, $old_hash): $num; } sub data ($;$) { my $self = shift; my $num = shift; my $data = $self->{data}; return $data unless defined $num; return $data->{$num}; } sub dump ($;$) { my $self = shift; my $num = shift; my $data = $self->{data}; return "Colorset $num is unknown\n" if defined $num && !$data->{$num}; my @nums = defined $num? ($num): sort { "$a$b" =~ /^\d+$/? $a <=> $b: $a cmp $b } keys %$data; my $string = ""; foreach (@nums) { my $cs_hash = $data->{$_}; $string .= "Colorset $_"; my $i = 0; foreach (CS_FIELDS) { my $value = $cs_hash->{$_}; $i++; next if $i > 5 && ($value == 0 || /alpha_percent$/ && $value == 100); $value = sprintf("#%06lx", $value) if $i <= 7; $value = sprintf("0x%07lx", $value) if /pixmap$/; $string .= " $_=$value"; } $string .= "\n"; } return $string; } 1; __END__ =head1 DESCRIPTION This is a subclass of B that enables to read the colorset definitions. This tracker defines the following observable: "colorset changed" that is notified using 2 additional parameters: colorset number and old colorset data hash ref. =head1 SYNOPSYS Using B $module object: my $cs_tracker = $module->track("Colorsets"); my $cs_hash = $cs_tracker->data; my $cs2_fg = $cs_hash->{2}->{fg} || 'black'; my $cs5_bg = $cs_tracker->data(5)->{bg} || 'gray'; $cs_tracker->observe(sub { my ($module, $tracker, $data, $num, $old_hash) = @_; my $new_hash = $data->{$num}; if ($old_hash->{pixmap} == 0 && $new_hash->{pixmap}) { my $pixmap_type = $new_hash->{pixmap_type}; my $pixmap_name = ($tracker->PIXMAP_TYPES)[$pixmap_type]; $module->debug("Colorset: $num, Pixmap type: $pixmap_name"); } }; =head1 OVERRIDDEN METHODS =over 4 =item B [I] Returns either array ref of colorset hash refs, or one hash ref if I is given. The hash keys are listed in CS_FIELDS, the constant of this class. =item B [I] Works similarly to B, but returns debug line(s) for one or all colorsets. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L and L. =cut fvwm-2.6.7/perllib/FVWM/Tracker/PageInfo.pm0000644000175700017570000000705612673746443015325 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Tracker::PageInfo; use strict; use FVWM::Tracker qw(base); sub observables ($) { return [ "desk/page changed", "desk only changed", "page only changed", ]; } sub start ($) { my $self = shift; $self->{data} = {}; $self->add_handler(M_NEW_PAGE, sub { my $event = $_[1]; $self->calculate_internals($event->args); }); $self->request_windowlist_events; my $result = $self->SUPER::start; $self->delete_handlers; $self->add_handler(M_NEW_PAGE | M_NEW_DESK, sub { my $event = $_[1]; if ($event->type == M_NEW_DESK) { my $old_desk_n = $self->{data}->{desk_n}; my $new_desk_n = $event->args->{desk_n}; $self->{data}->{desk_n} = $new_desk_n; my $really_changed = $old_desk_n != $new_desk_n; $self->notify("desk only changed", $really_changed); return unless $really_changed; } else { $self->calculate_internals($event->args); $self->notify("page only changed"); } $self->notify("desk/page changed"); }); return $result; } sub calculate_internals ($$) { my $self = shift; my $args = shift; my $data = $self->{data}; @$data{keys %$args} = values %$args; $data->{page_nx} = int($data->{vp_x} / $data->{vp_width}); $data->{page_ny} = int($data->{vp_y} / $data->{vp_height}); } sub dump ($) { my $self = shift; my $data = $self->{data}; my $string = join(', ', map { "$_=$data->{$_}" } sort keys %$data) . "\n"; $string =~ s/^(.*?)(, d.*?)(, p.*?), (v.*)$/$1$3$2\n$4/s; return $string; } 1; __END__ =head1 DESCRIPTION This B subclass provides an information about the current fvwm page and desk and screen dimensions. Like with all trackers, this information is automatically brought up to the date for the entire tracker object life and may be retrieved by its C method. This tracker defines the following observables that enable additional way of work: "desk/page changed", "desk only changed", "page only changed", =head1 SYNOPSYS Using B $module object: my $page_tracker = $module->track("PageInfo"); my $page_hash = $page_tracker->data; my $curr_desk = $page_hash->{'desk_n'}; =head1 OVERRIDDEN METHODS =over 4 =item B Returns hash ref representing the current page/desk, with the following keys (the fvwm variable equivalents are shown on the right): desk_n $[desk.n] page_nx $[page.nx] page_ny $[page.ny] desk_pages_x $[desk.pagesx] desk_pages_y $[desk.pagesy] vp_width $[vp.width] vp_height $[vp.height] vp_x $[vp.x] vp_y $[vp.y] =item B Returns 2 debug lines representing the current page data (as described in C) in the human readable format. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L and L. =cut fvwm-2.6.7/perllib/FVWM/Tracker/Makefile.in0000644000175700017570000004154213010103323015304 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = perllib/FVWM/Tracker DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(configdir)" DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ configdir = @FVWM_PERLLIBDIR@/FVWM/Tracker config_DATA = \ Colorsets.pm GlobalConfig.pm ModuleConfig.pm PageInfo.pm \ Scheduler.pm WindowList.pm EXTRA_DIST = $(config_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign perllib/FVWM/Tracker/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign perllib/FVWM/Tracker/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-configDATA \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-configDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/perllib/FVWM/Tracker/ModuleConfig.pm0000644000175700017570000001244012673746443016201 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Tracker::ModuleConfig; use strict; use FVWM::Tracker qw(base); sub observables ($) { return [ "config line added", ]; } sub new ($$%) { my $class = shift; my $module = shift; my %params = @_; my $self = $class->FVWM::Tracker::new($module); $self->{is_hash} = 1; $self->{module_name} = $self->{module}->name; $self->{filter} = 'spacefree'; $self->{default_config} = {}; return $self->init(%params); } sub init ($%) { my $self = shift; my %params = @_; if ($params{ConfigType}) { $self->{is_hash} = $params{ConfigType} eq 'hash'; $self->{default_config} = $self->{is_hash} ? {} : []; } $self->{module_name} = $params{ModuleName} if $params{ModuleName}; $self->{filter} = $params{LineFilter} if $params{LineFilter}; $self->{default_config} = $params{DefaultConfig} if ref($self->{default_config}) eq ref($params{DefaultConfig}); return $self; } sub start ($) { my $self = shift; my $default = $self->{default_config}; $self->{data} = $self->{is_hash} ? { %$default } : [ @$default ]; $self->add_handler(M_CONFIG_INFO, sub { my $event = $_[1]; $self->calculate_internals($event->args); }); $self->request_configinfo_events($self->{module_name}); my $result = $self->SUPER::start; $self->delete_handlers; $self->add_handler(M_CONFIG_INFO | M_SENDCONFIG, sub { my $event = $_[1]; return unless $event->type == M_CONFIG_INFO; my $info = $self->calculate_internals($event->args); return unless defined $info; $self->notify("config line added", $info); }); return $result; } sub calculate_internals ($$) { my $self = shift; my $args = shift; my $data = $self->{data}; my $text = $args->{text}; $self->internal_die("No 'text' arg in M_CONFIG_INFO") unless defined $text; return undef unless $text =~ /^\*$self->{module_name}(\s*[^\s].*)$/i; my $line = $1; $line =~ s/^\s+// unless $self->{filter} eq 'asis'; $line =~ s/\s+$// unless $self->{filter} eq 'asis'; if ($self->{is_hash}) { my ($key, $value) = $line =~ /([^\s]+)\s*(.*)/; $key = lc($key) if $self->{filter} eq 'lowerkeys'; $key = uc($key) if $self->{filter} eq 'upperkeys'; $self->{data}->{$key} = $value; return $key; } else { push @{$self->{data}}, $line; return @{$self->{data}} - 1; } } sub data ($;$) { my $self = shift; my $info = shift; my $data = $self->{data}; return $data unless defined $info; return $data->{$info} if $self->{is_hash}; return $data->[$info]; } sub dump ($;$) { my $self = shift; my $info = shift; my $data = $self->{data}; my @infos = defined $info? ($info): $self->{is_hash} ? sort keys %$data : (0 .. @$data - 1); my $string = ""; foreach (@infos) { my $line_data = $self->{is_hash} ? "$_ $data->{$_}" : $data->[$_]; $string .= "\*$self->{module_name}: $line_data\n"; } return $string; } 1; __END__ =head1 DESCRIPTION This is a subclass of B that enables to read the module configuration. The module configuration is usually represented using a hash, but it may be represented as array of lines too. This tracker defines the following observables: "config line added" =head1 SYNOPSYS Using B $module object: my $config_tracker = $module->track("ModuleConfig"); my $config_hash = $config_tracker->data; my $font = $config_hash->{Font} || 'fixed'; or: my $config_tracker = $module->track( "ModuleConfig", DefaultConfig => { Font => 'fixed' } ); my $font = $config_tracker->data('Font'); =head1 NEW METHODS =over 4 =item B I Makes it possible to change the parameters of this tracker on the fly. Use with caution. See B method for the description of the I hash. =back =head1 OVERRIDDEN METHODS =over 4 =item B I I It is possible to specify additional parameters that this tracker understands. ConfigType - string "hash" (default) or "array" ModuleName - module to query, the default is $module->name LineFilter - "asis", "spacefree" (default), "lowerkeys", "upperkeys" DefaultConfig - the config hash/array of config to initially use =item B [I] Returns either array ref of configuration hash refs, or one hash ref if I is given. Returns I if the configuration line for I is not defined. =item B [I] Works similarly to B, but returns one or many debug lines. Returns an empty string if no module configuration is defined. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L and L. =cut fvwm-2.6.7/perllib/FVWM/Tracker/Scheduler.pm0000644000175700017570000001613312673746443015547 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Tracker::Scheduler; use strict; use FVWM::Tracker qw(base); sub observables ($) { return [ "scheduled alarm", ]; } sub new ($$%) { my $class = shift; my $module = shift; my %params = @_; my $self = $class->FVWM::Tracker::new($module); $self->{random_base_number} = 8000000 + int(rand(900000)); $self->{sent_string_prefix} = "FVWM::Tracker::Scheduler alarm "; $self->{module_name} = $params{ModuleName} || $self->{module}->name; $self->{use_alarm} = (exists $params{UseAlarm} ? $params{UseAlarm} : $module->is_dummy) ? 1 : 0; return $self; } sub start ($) { my $self = shift; $self->{data} = {}; my $result = $self->SUPER::start; $self->{internal_observer_id} ||= $self->observe(sub { my $schedule_id = $_[3]; my $schedule_data = $self->data($schedule_id); $self->{rescheduled_seconds} = -1; &{$schedule_data->{callback}}($schedule_data, @{$schedule_data->{params}}); my $new_seconds = $self->{rescheduled_seconds}; if ($new_seconds >= 0) { $schedule_data->{seconds} = $new_seconds if $new_seconds; $self->send_schedule($schedule_id); } else { $self->deschedule($schedule_id); } }); $self->add_handler(M_STRING, sub { my $event = $_[1]; my $text = $event->_text; return unless $text =~ /^$self->{sent_string_prefix}(\d+)/; $self->notify("main", $1); }); return $result; } sub stop ($) { my $self = shift; $self->SUPER::stop; $self->deschedule_all; } sub send_schedule ($$) { my $self = shift; my $schedule_id = shift; my $sd = $self->{data}->{$schedule_id}; my $string = "$self->{sent_string_prefix}$schedule_id"; if ($self->{use_alarm}) { $SIG{ALRM} = sub { $self->{module}->emulate_event(M_STRING, [ 0, 0, 0, $string ]); }; alarm($sd->{seconds}); } else { my $mseconds = $sd->{seconds} * 1000; $self->{module}->send("Schedule $mseconds $sd->{fvwm_id} " . "SendToModule $self->{module_name} $string"); } $sd->{time_sent} = time(); } sub schedule ($$$;$) { my $self = shift; my $seconds = shift || $self->internal_die("schedule: no seconds"); my $callback = shift || $self->internal_die("schedule: no callback"); my $schedule_id = ++$self->{last_schedule_num}; my $fvwm_id = $self->{random_base_number} + $schedule_id; my $schedule_data = { time_sent => 0, seconds => $seconds, fvwm_id => $fvwm_id, callback => $callback, params => [ @_ ], }; $self->{data}->{$schedule_id} = $schedule_data; $self->send_schedule($schedule_id); return $schedule_id; } sub deschedule ($$) { my $self = shift; my $schedule_id = shift; my $data = $self->{data}; next unless exists $data->{$schedule_id}; my $fvwm_id = $data->{$schedule_id}->{fvwm_id}; $self->{module}->send("Deschedule $fvwm_id") if defined $self->{module}; # ready for DESTROY delete $data->{$schedule_id}; } sub reschedule ($;$) { my $self = shift; my $seconds = shift || 0; $self->{rescheduled_seconds} = $seconds; } sub deschedule_all ($) { my $self = shift; my $data = $self->{data}; foreach (keys %$data) { $self->deschedule($_); } } sub to_be_disconnected ($) { my $self = shift; $self->deschedule_all(); } sub data ($;$) { my $self = shift; my $schedule_id = shift; my $data = $self->{data}; return $data unless defined $schedule_id; return $data->{$schedule_id}; } sub dump ($;$) { my $self = shift; my $schedule_id = shift; my $data = $self->{data}; my @ids = $schedule_id ? $schedule_id : sort { $a <=> $b } keys %$data; my $string = ""; foreach (@ids) { my $sd = $data->{$_}; my $time_str = localtime($sd->{time_sent}); $time_str = "$5-$2-$3 $4" if $time_str =~ /^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)$/; $string .= "Schedule $_: $time_str + $sd->{seconds} sec, use 'Deschedule $sd->{fvwm_id}'\n"; } return $string; } 1; __END__ =head1 DESCRIPTION This is a subclass of B that enables to define alarm callback, several at the same time. This tracker defines the following observables: "scheduled alarm" But it is suggested not to use the usual tracker B/B API, but to use the B/B/B API instead. This tracker uses the I command B to get a notification. It is possible to use the perl I. This is the default if the module is run in the dummy mode. To set it explicitly, pass I boolean value when the tracker is created. Note that alarm signals are not relable in some perl versions, on some systems and with some kind of applications, don't expect the alarm method to work at all. =head1 SYNOPSYS Using B $module object: # beep every 40 seconds; exit in 100 seconds my $scheduler = $module->track("Scheduler"); $scheduler->schedule(40, sub { $module->send("Beep"); $scheduler->reschedule; }); $scheduler->schedule(100, sub { $module->terminate; }); =head1 PUBLIC METHODS =over 4 =item B I I [I] Sets the alarm I that is called in about I seconds. The I parameters are: hash as returned using B when called with the I parameter, and optional I. Returns I that may be used in B or B. =item B I Removes the scheduled callback identified by I. =item B [I] When the scheduled callback is called, it is possible to reinitialize the same callback using the same or different number of I. This may be useful when defining a periodical callback that should be, say, called every 10 minutes (600 seconds). =item deschedule_all Removes all previously scheduled callbacks. =back =head1 OVERRIDDEN METHODS =over 4 =item to_be_disconnected Calls B. =item B [I] Returns either array ref of hash refs, or one hash ref if I is given. The hash keys are: time_sent - unix time (seconds since 1970) seconds - requested alarm seconds fvwm_id - internal I's Schedule id callback - alarm callback, CODE ref params - ARRAY ref of optional callback parameters =item B [I] Works similarly to B, but returns one or many debug lines (one line per scheduled alarm). If no scheduled callbacks are active, the empty string is returned as expected. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L and L. =cut fvwm-2.6.7/perllib/FVWM/Tracker/GlobalConfig.pm0000644000175700017570000000612112673746443016153 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Tracker::GlobalConfig; use strict; use FVWM::Tracker qw(base); sub observables ($) { return [ "value updated", ]; } sub start ($) { my $self = shift; $self->{data} = {}; $self->add_handler(M_CONFIG_INFO, sub { my $event = $_[1]; $self->calculate_internals($event->args); }); $self->request_configinfo_events; my $result = $self->SUPER::start; $self->delete_handlers; $self->add_handler(M_CONFIG_INFO, sub { my $event = $_[1]; my $name = $self->calculate_internals($event->args); return unless defined $name; $self->notify("value changed", $name); }); return $result; } sub calculate_internals ($$) { my $self = shift; my $args = shift; my $data = $self->{data}; my $text = $args->{text}; $self->internal_die("No 'text' arg in M_CONFIG_INFO") unless defined $text; return undef if $text =~ /^(?:desktopsize|colorset|\*)/i; return undef unless $text =~ /^(desktopname \d+|[^\s]+) (.*)$/i; my $name = $1; my $value = $2; $self->{data}->{$name} = $value; return $name; } sub data ($;$) { my $self = shift; my $name = shift; my $data = $self->{data}; return $data unless defined $name; return $data->{$name}; } sub dump ($;$) { my $self = shift; my $name = shift; my $data = $self->{data}; my @names = defined $name? ($name): sort keys %$data; my $string = ""; foreach (@names) { my $value = $data->{$_}; $string .= "$_ $value\n"; } return $string; } 1; __END__ =head1 DESCRIPTION This is a subclass of B that enables to read the global FVWM configuration. "value changed" =head1 SYNOPSYS Using B $module object: my $config_tracker = $module->track("GlobalConfig"); my $config_hash = $config_tracker->data; my $image_path = $config_hash->{'ImagePath'}; or: my $config_tracker = $module->track("GlobalConfig"); my $xinerama_info = $config_tracker->data('XineramaConfig'); my $desktop2_name = $config_tracker->data('DesktopName 2'); =head1 OVERRIDDEN METHODS =over 4 =item B [I] Returns either hash ref of all global configuration values, or one value if I is given. =item B [I] Works similarly to B, but returns debug lines for one or all global configuration values. =back =head1 AUTHOR Mikhael Goikhman . =head1 SEE ALSO For more information, see L and L. =cut fvwm-2.6.7/perllib/FVWM/Tracker/WindowList.pm0000644000175700017570000002351012673746443015731 00000000000000# Copyright (c) 2004-2009 Mikhael Goikhman, Scott Smedley # # 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 package FVWM::Tracker::WindowList; use strict; use FVWM::Tracker qw(base); my $window_events = M_ADD_WINDOW | M_CONFIGURE_WINDOW | M_DESTROY_WINDOW | M_ICONIFY | M_DEICONIFY; my $name_events = M_RES_NAME | M_RES_CLASS | M_WINDOW_NAME | M_VISIBLE_NAME | M_ICON_NAME; my $name_xevents = MX_VISIBLE_ICON_NAME; my $stack_events = M_RESTACK | M_RAISE_WINDOW | M_LOWER_WINDOW; my $icon_events = M_ICON_LOCATION | M_ICON_FILE | M_DEFAULTICON | M_MINI_ICON; sub observables ($) { return [ "window added", "window deleted", "window properties updated", "window moved", "window resized", "window iconified", "window deiconified", "window name updated", "window stack updated", "window icon updated", ]; } sub new ($$;$) { my $class = shift; my $module = shift; my @options = split(/ /, shift || ""); my $self = $class->FVWM::Tracker::new($module); $self->{options} = [ @options ]; return $self; } sub add_requested_info_handlers ($$) { my $self = shift; my $handler = shift; my $use_winfo = 1; my $use_names = 1; my $use_stack = 0; my $use_icons = 0; foreach (@{$self->{options}}) { /^(\!?)winfo$/ and $use_winfo = $1 ne '!'; /^(\!?)names$/ and $use_names = $1 ne '!'; /^(\!?)stack$/ and $use_stack = $1 ne '!'; /^(\!?)icons$/ and $use_icons = $1 ne '!'; } my $mask = 0; $mask |= $window_events if $use_winfo; $mask |= $name_events if $use_names; $mask |= $stack_events if $use_stack; $mask |= $icon_events if $use_icons; my $xmask = 0; $xmask |= $name_xevents if $use_names; $self->add_handler($mask, $handler) if $mask; $self->add_handler($xmask, $handler) if $xmask; $self->add_handler(M_NEW_PAGE | M_NEW_DESK, sub { $self->handler_page_info($_[1]); }) if $use_winfo; } sub start ($) { my $self = shift; $self->{data} = {}; $self->add_requested_info_handlers(sub { my $event = $_[1]; $self->calculate_internals($event); }); $self->request_windowlist_events; my $result = $self->SUPER::start; $self->delete_handlers; $self->add_requested_info_handlers(sub { my $event = $_[1]; my ($win_id, $old_hash) = $self->calculate_internals($event); return unless defined $win_id; my $type = $event->type(); my $observable = undef; if ($self->{module}->is_event_extended($type)) { if ($type & $name_xevents) { $observable = "window name updated"; } } elsif ($type & M_ADD_WINDOW) { $observable = "window added"; } elsif ($type & M_CONFIGURE_WINDOW) { $observable = "window properties updated"; # this observable is too broad, try to narrow if ($old_hash) { my $win = $self->{data}->{$win_id}; $self->notify("window resized", $win_id, $old_hash) if $win->{width} != $old_hash->{width} || $win->{height} != $old_hash->{height}; $self->notify("window moved", $win_id, $old_hash) if $win->{desk} != $old_hash->{desk} || $win->{x} != $old_hash->{x} || $win->{y} != $old_hash->{y}; } } elsif ($type & M_DESTROY_WINDOW) { $observable = "window deleted"; } elsif ($type & M_ICONIFY) { $observable = "window iconified"; } elsif ($type & M_DEICONIFY) { $observable = "window deiconified"; } elsif ($type & $name_events) { $observable = "window name updated"; } elsif ($type & $stack_events) { $observable = "window stack updated"; } elsif ($type & $icon_events) { $observable = "window icon updated"; } $self->notify($observable, $win_id, $old_hash) if $observable; }); return $result; } sub calculate_internals ($$) { my $self = shift; my $event = shift; my $args = $event->args; my $data = $self->{data}; my $win_id = $args->{win_id}; my $old_hash = undef; $old_hash = { %{$data->{$win_id}} } if defined $data->{$win_id}; my $window = $data->{$win_id} ||= bless { id => $win_id, iconified => 0, _tracker => $self }, "FVWM::Window"; # There are some fields that are not unique to all events. To ensure # we don't clobber them, we rename some fields. For example, the 'name' # field of M_MINI_ICON events is renamed to 'mini_icon_name'. foreach ('name', 'x', 'y', 'width', 'height') { if (defined $args->{$_}) { (my $name = lc($event->name())) =~ s/^.*?_//; $name .= "_$_" if ($name !~ /$_$/); $args->{$name} = $args->{$_}; delete $args->{$_}; } } #print $event->dump; $args->{name} = delete $args->{window_name} if exists $args->{window_name}; @$window{keys %$args} = values %$args; if (defined $args->{frame_x}) { # frame_x & frame_y are _relative_ coords of the window to the # current page - calculate the _absolute_ coords - x & y. $window->{x} = delete $window->{frame_x}; $window->{y} = delete $window->{frame_y}; $window->{width} = delete $window->{frame_width}; $window->{height} = delete $window->{frame_height}; my $page = $self->{page_info}; if (defined $page) { $window->{X} = $page->{vp_x} + $window->{x}; $window->{Y} = $page->{vp_y} + $window->{y}; $window->{page_nx} = int($window->{X} / $page->{vp_width}); $window->{page_ny} = int($window->{Y} / $page->{vp_height}); } } my $type = $event->type(); if (!$self->{module}->is_event_extended($type)) { if ($type & M_DEICONIFY) { $window->{iconified} = 0; } elsif ($type & M_ICONIFY) { $window->{iconified} = 1; } elsif ($type & M_DESTROY_WINDOW) { delete $data->{$win_id}; } } return wantarray ? ($win_id, $old_hash) : $win_id; } sub handler_page_info ($$) { my $self = shift; my $event = shift; my $args = $event->args; my $data = $self->{page_info} ||= {}; @$data{keys %$args} = values %$args; if ($event->type & M_NEW_PAGE) { $data->{page_nx} = int($data->{vp_x} / $data->{vp_width}); $data->{page_ny} = int($data->{vp_y} / $data->{vp_height}); } } sub page_info ($;$) { my $self = shift; my $id = shift; my $data = $self->{page_info}; return $data unless defined $id; return $data->{$id}; } sub data ($;$) { my $self = shift; my $id = shift; my $data = $self->{data}; return $data unless defined $id; return $data->{$id}; } sub dump ($;$) { my $self = shift; my $id = shift; my $data = $self->{data}; my @ids = defined $id? ($id): sort { $a <=> $b } keys %$data; my $string = ""; foreach (@ids) { my $window = $data->{$_}; $string .= $window->dump; } return $string; } sub windows ($) { my $self = shift; my @windows = values %{$self->data}; return wantarray? @windows: \@windows; } # ---------------------------------------------------------------------------- package FVWM::Window; sub match ($$) { my $self = shift; my $condition = shift; my @conditions = split(/[,\s]+/, $condition); my $match = 1; foreach (@conditions) { my $opposite = s/^!//; if (/^iconified$/i) { return 0 unless $opposite ^ $self->{iconified}; } elsif (/^current(page|desk)$/i) { my $page = $self->{_tracker}->page_info; return 0 unless $opposite ^ ($self->{desk} == $page->{desk_n}); next if lc($1) eq "desk"; return 0 unless $opposite ^ ( $self->{x} + $self->{width} > $page->{vp_x} && $self->{x} < $page->{vp_x} + $page->{vp_width} && $self->{y} + $self->{height} > $page->{vp_y} && $self->{y} < $page->{vp_y} + $page->{vp_height} ); } } return $match; } sub dump ($) { my $self = shift; my $id = $self->{win_id}; my $string = "Window $id\n"; foreach my $prop (sort keys %$self) { next if $prop =~ /^_/; $string .= "\t$prop:\t[$self->{$prop}]\n"; } return $string; } # ---------------------------------------------------------------------------- 1; __END__ =head1 DESCRIPTION This is a subclass of B that enables to read the window information. This tracker defines the following observables: "window added", "window deleted", "window properties updated", "window moved", "window resized", "window iconified", "window deiconified", "window name updated", "window stack updated", "window icon updated", =head1 SYNOPSYS Using B $module object: my $tracker = $module->track("WindowList"); my @windows = $tracker->windows; foreach my $window ($tracker->windows) { print "+$window->{x}+$window->{y}, $window->{name}\n"; } or: my $tracker = $module->track("WindowList", "winfo"); my $x = $tracker->data("0x230002a")->{x}; or: my $tracker = $module->track("WindowList", $options); my $data = $tracker->data; while (my ($win_id, $window) = each %$data) { next unless $window->match("CurrentPage, Iconified"); $module->send("Iconify off", $win_id); } Default $options string is: "!stack !icons names winfo" =head1 OVERRIDDEN METHODS =over 4 =item B I I It is possible the kind of window list. To be written. =item B [I] Returns hash ref of window hash refs. or one window hash ref if I is given. =item B [I] Works similarly to B, but returns debug lines for one or all windows. =back =head1 METHODS =over 4 =item B [I] Returns hash ref of page/desk info, or actual hash value using B as a key (if specified). =back =head1 AUTHORS =over 4 =item Mikhael Goikhman =item Scott Smedley =back =head1 SEE ALSO For more information, see L and L. =cut fvwm-2.6.7/perllib/FVWM/create-constants0000755000175700017570000000330712673746443015102 00000000000000#!/bin/sh : ${fvwm_libdir=../../libs} infile=${fvwm_libdir}/Module.h outfile=`dirname $0`/Constants.pm ( \ echo "# Autogenerated from the fvwm sources."; \ echo ""; \ echo "package FVWM::Constants;"; \ echo "use Exporter;"; \ echo "use Config;"; \ echo "@ISA = qw(Exporter);"; \ echo ""; \ ) \ >$outfile ( \ grep "#define M_" $infile; \ grep "#define MX_" $infile | sed 's/ | /|/'; \ grep "#define MAX_MSG_MASK " $infile; \ grep "#define MAX_XMSG_MASK " $infile; \ grep "#define FvwmPacketHeaderSize " $infile | sed 's/FvwmPacketHeaderSize/HEADER_SIZE/'; \ grep "#define START_FLAG " $infile; \ grep "#define ModuleFinishedStartupResponse " $infile | tr ' ' : | sed 's/:ModuleFinishedStartupResponse:\+/ RESPONSE_READY /'; \ grep "#define ModuleUnlockResponse " $infile | tr ' ' : | sed 's/:ModuleUnlockResponse:\+/ RESPONSE_UNLOCK /'; \ ) \ | awk '{ print "use constant " $2 " => " $3 ";" }' \ | tr : ' ' \ >>$outfile ( \ echo "use constant ON_EXIT => '1e20';"; \ echo "use constant INTSIZE => \$Config{longsize};" \ ) \ >>$outfile ( \ grep constant $outfile | cut -d" " -f3 | awk '{ print " " $1 }'; \ ) \ >"$outfile.tmp" ( \ echo '@EXPORT = qw('; \ cat "$outfile.tmp"; \ echo ');' \ ) \ >>$outfile ( \ echo " 1; __END__ =head1 NAME FVWM::Constants - exports fvwm specific constants =head1 DESCRIPTION This class is used to load fvwm constants into your perl script or class. Note, if you use I the constants are automatically exported. So you usually do not need to include this class. =head1 USAGE use FVWM::Constants; =head1 SEE ALSO For more information, see L. =head1 EXPORTED CONSTANTS "; \ cat "$outfile.tmp"; \ ) \ >>$outfile rm "$outfile.tmp" fvwm-2.6.7/perllib/FVWM/Module/0000755000175700017570000000000013010103345013147 500000000000000fvwm-2.6.7/perllib/FVWM/Module/Makefile.am0000644000175700017570000000025512773470550015151 00000000000000## Process this file with automake to create Makefile.in configdir = @FVWM_PERLLIBDIR@/FVWM/Module config_DATA = Toolkit.pm Terminal.pm Tk.pm EXTRA_DIST = $(config_DATA) fvwm-2.6.7/perllib/FVWM/Module/Makefile.in0000644000175700017570000004144013010103323015133 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = perllib/FVWM/Module DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(configdir)" DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ configdir = @FVWM_PERLLIBDIR@/FVWM/Module config_DATA = Toolkit.pm Terminal.pm Tk.pm EXTRA_DIST = $(config_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign perllib/FVWM/Module/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign perllib/FVWM/Module/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-configDATA \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-configDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/perllib/FVWM/Module/Tk.pm0000644000175700017570000002025712673746443014043 00000000000000# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Module::Tk; use 5.004; use strict; use FVWM::Module::Toolkit qw(base Tk Tk::Dialog Tk::ROText); sub new ($@) { my $class = shift; # support the old API with the first top-level argument my $top = shift if @_ && UNIVERSAL::isa($_[0], "Tk::Toplevel"); my %params = @_; $top = delete $params{TopWindow} if exists $params{TopWindow}; my $self = $class->SUPER::new(%params); $self->internal_die("TopWindow given in constructor is not Tk::Toplevel") unless $top || UNIVERSAL::isa($top, "Tk::Toplevel"); unless ($top) { $top = MainWindow->new; $top->withdraw; } $self->{top_window} = $top; return $self; } sub event_loop ($) { my $self = shift; my @params = @_; $self->event_loop_prepared(@params); my $top = $self->{top_window}; $top->fileevent($self->{istream}, readable => sub { unless ($self->process_packet($self->read_packet)) { if ($self->{disconnected}) { # Seems like something does not want to exit - force it. # For example, a new Tk window is launched on ON_EXIT. $top->destroy if defined $top && defined $top->{Configure}; $self->debug("Forced to exit to escape event_loop, fix the module", 0); exit 1; } $self->event_loop_finished(@params); $top->destroy; } else { $self->event_loop_prepared(@params); } } ); MainLoop; } sub show_error ($$;$) { my $self = shift; my $error = shift; my $title = shift || ($self->name . " Error"); my $top = $self->{top_window}; my $dialog = $top->Dialog( -title => $title, -bitmap => 'error', -default_button => 'Close', -text => $error, -buttons => ['Close', 'Close All Errors', 'Exit Module'], ); my $btn = $dialog->Show; $self->terminate if $btn eq 'Exit Module'; $self->send("All ('$title') Close") if $btn eq 'Close All Errors'; } sub show_message ($$;$) { my $self = shift; my $msg = shift; my $title = shift || ($self->name . " Message"); $self->{top_window}->messageBox( -icon => 'info', -type => 'ok', -title => $title, -message => $msg, ); } sub show_debug ($$;$) { my $self = shift; my $msg = shift; my $title = shift || ($self->name . " Debug"); my $dialog = $self->{tk_debug_dialog}; my $top = $self->{top_window}; unless (defined $top && defined $top->{Configure}) { # in the constructor (too early) or in destructor (too late) $self->FVWM::Module::Toolkit::show_debug($msg, $title); return; } if (!$dialog) { # Tk's Dialog widgets are too damn inflexible. # It's less hassle to build one from scratch. $dialog = $top->Toplevel(-title => $title); my $scroll = $dialog->Frame()->pack(-expand => 1, -fill => 'both'); my $bottom = $dialog->Frame()->pack(-expand => 0, -fill => 'x'); my $text = $scroll->Scrolled('ROText', -bg => 'white', -wrap => 'word', -scrollbars => 'oe', )->pack(-expand => 1, -fill => 'both'); $dialog->protocol('WM_DELETE_WINDOW', sub { $dialog->withdraw(); }); my @pack_opts = (-side => 'left', -expand => 1, -fill => 'both'); $bottom->Button( -text => 'Close', -command => sub { $dialog->withdraw(); }, )->pack(@pack_opts); $bottom->Button( -text => 'Clear', -command => sub { $text->delete('0.0', 'end'); }, )->pack(@pack_opts); $bottom->Button( -text => 'Save', -command => sub { my $file = $dialog->getSaveFile(-title => "Save $title"); return unless defined $file; if (!open(OUT, ">$file")) { $self->show_error("Couldn't save $file: $!", 'Save Error'); return; } print OUT $text->get('0.0', 'end'); close(OUT); }, )->pack(@pack_opts); $self->{tk_debug_dialog} = $dialog; $self->{tk_debug_text_wg} = $text; } else { $dialog->deiconify() if $dialog->state() eq 'withdrawn'; } my $text = $self->{tk_debug_text_wg}; $text->insert('end', "$msg\n"); $text->see('end'); } sub top_window ($) { return shift->{top_window}; } 1; __END__ =head1 NAME FVWM::Module::Tk - FVWM::Module with the Tk widget library attached =head1 SYNOPSIS Name this module TestModuleTk, make it executable and place in ModulePath: #!/usr/bin/perl -w use lib `fvwm-perllib dir`; use FVWM::Module::Tk; use Tk; # preferably in this order my $top = new MainWindow(-name => "Simple Test"); my $id = $top->wrapper->[0]; my $module = new FVWM::Module::Tk( TopWindow => $top, Mask => M_ICONIFY | M_ERROR, # Mask may be omitted Debug => 2, ); $top->Button( -text => "Close", -command => sub { $top->destroy; } )->pack; $module->add_default_error_handler; $module->add_handler(M_ICONIFY, sub { my $id0 = $_[1]->_win_id; $module->send("Iconify off", $id) if $id0 == $id; }); $module->track('Scheduler')->schedule(60, sub { $module->show_message("You run this module for 1 minute") }); $module->send('Style "*imple Test" Sticky'); $module->event_loop; =head1 DESCRIPTION The B class is a sub-class of B that overloads the methods B, B, B, B and B to manage Tk objects as well. It also adds new method B. This manual page details only those differences. For details on the API itself, see L. =head1 METHODS Only overloaded or new methods are covered here: =over 8 =item B I $module = new B I => $top, %params Create and return an object of the B class. This B method is identical to the (grand-)parent class method, with the exception that a Tk top-level of some sort (MainWindow, TopLevel, Frame, etc.) may be passed in the hash of options using the I named value. Other options in I are the same as described in L. If no top-level window is specified in the constructor, such dummy window is created and immediately withdrawn. This top-level window is needed to create Tk dialogs. =item B From outward appearances, this methods operates just as the parent B does. It is worth mentioning, however, that this version enters into the Tk B subroutine, ostensibly not to return. =item B I [I] This method creates a dialog box using the Tk widgets. The dialog has three buttons labeled "Close", "Close All Errors" and "Exit Module". Selecting the "Close" button closes the dialog. "Close All Errors" closes all error dialogs that may be open on the screen at that time. "Exit Module" terminates your entire module. Good for diagnostics of a Tk based module. =item B<show_message> I<msg> [I<title>] Creates a message window with one "Ok" button. Useful for notices by a Tk based module. =item B<show_debug> I<msg> [I<title>] Creates a debug window with 3 buttons "Close", "Clear" and "Save". All debug messages are added to the debug window. "Close" withdraws the window until the next debug message arrives. "Clear" erases the current contents of the debug window. "Save" dumps the current contents of the debug window to the selected file. Useful for debugging a Tk based module. =item B<top_window> Returns the Tk toplevel that this object was created with. =back =head1 BUGS Would not surprise me in the least. =head1 AUTHOR Mikhael Goikhman <migo@homemail.com>. =head1 THANKS TO Randy J. Ray <randy@byz.org>, author of the old classes B<X11::Fvwm> and B<X11::Fvwm::Tk>. Scott Smedley <ss@aao.gov.au>. Nick Ing-Simmons <Nick.Ing-Simmons@tiuk.ti.com> for Tk Perl extension. =head1 SEE ALSO For more information, see L<fvwm>, L<FVWM::Module> and L<Tk>. =cut �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/FVWM/Module/Terminal.pm����������������������������������������������������������0000644�0001757�0001757�00000013467�12673746443�015245� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 BEGIN { if ($ENV{FVWM_MODULE_TERMINAL_CLIENT}) { my ($out_fd, $in_fd, $name, $prompt, $ornaments) = @ARGV; $name ||= "FVWM::Module::Terminal"; $prompt ||= ""; $ornaments ||= 0; $name .= " Client"; eval "use IO::File; use Term::ReadLine;"; $SIG{__DIE__} = sub { my $msg = shift; $msg =~ /(.*?)^BEGIN failed/sm and die $1; print "$name: $msg"; sleep(2); die "$name: Exiting due to errors\n"; }; die "$name: $@" if $@; my $ostream = new IO::File ">&$out_fd" or die "Can't write to file descriptor (&$out_fd)\n"; my $istream = new IO::File "<&$in_fd" or die "Can't read from file descriptor (&$in_fd)\n"; $ostream->autoflush(1); $istream->autoflush(1); # DEBUG $ostream->print("Abra ka Dabra\n"); print "($ostream) ($istream)\n"; my $term = Term::ReadLine->new($name); $term->ornaments($ornaments); my $line; while (defined($line = $term->readline($prompt))) { $ostream->print("$line\n"); } print "Closed\n"; sleep(1); exit(0); } } package FVWM::Module::Terminal; use 5.004; use strict; use FVWM::Module::Toolkit qw(base IO::Select); use General::Parse; sub new ($@) { my $class = shift; my %params = @_; my $xterm = delete $params{XTerm} || "xterm -name FvwmPerlTerminal -e"; my $prompt = delete $params{Prompt} || ""; my $ornaments = delete $params{Ornaments} || 0; my $self = $class->SUPER::new(%params); pipe(PARENT_IN, CHILD_OUT) || $self->internal_die("Can't pipe"); pipe(CHILD_IN, PARENT_OUT) || $self->internal_die("Can't pipe"); CHILD_OUT->autoflush; PARENT_OUT->autoflush; my $pid = fork; $self->internal_die("Can't fork: $!") unless defined $pid; if ($pid == 0) { close PARENT_IN; close PARENT_OUT; my $co = fileno(CHILD_OUT); my $ci = fileno(CHILD_IN); my $q = sub { local $_ = shift; s/'/\\'/g; $_ }; $ENV{FVWM_MODULE_TERMINAL_CLIENT} = 1; my @cmd = ($^X, "-w", __FILE__, $co, $ci, $self->name, $prompt, $ornaments); unshift @cmd, get_tokens($xterm); # DEBUG my $ostream = new IO::File ">&$co" or die "Can't write to file descriptor (&$co)\n"; $ostream->print("Asta la Vista\n"); print join(", ", @cmd), "\n"; { exec {$cmd[0]} @cmd } $self->internal_die("Can't fork $cmd[0]"); close CHILD_IN; close CHILD_OUT; exit 0; } close CHILD_IN; close CHILD_OUT; $self->{term_select} = new IO::Select($self->{istream}, \*PARENT_IN); $self->{term_output} = \*PARENT_OUT; return $self; } sub wait_packet ($) { my $self = shift; while (1) { my @handles = $self->{term_select}->can_read(); my ($core_input, $term_input); foreach (@handles) { ($_ == $self->{istream}? $core_input: $term_input) = $_; } if ($term_input) { my $line = $term_input->getline; unless (defined $line) { $self->debug("EOF from terminal client, terminating", 3); $self->terminate; } chomp($line); $self->debug("Got [$line] from terminal client", 4); $self->process_term_line($line); } last if $core_input; } } sub process_term_line ($$) { my $self = shift; my $line = shift; $self->show_message("I got $line!"); } 1; __END__ =head1 NAME FVWM::Module::Terminal - FVWM::Module with X terminal based solutions =head1 SYNOPSIS NOTE: This class is not functional yet. Name this module TestModuleTerminal, make it executable and place in ModulePath: #!/usr/bin/perl -w use lib `fvwm-perllib dir`; use FVWM::Module::Terminal; my $module = new FVWM::Module::Terminal( XTerm => 'rxvt', Debug => 2, Name => "TestModuleTerminal", ); my $id = undef; $module->send('Next (TestModuleTerminal) SendToModule myid $[w.id]'); $module->add_default_error_handler; $module->add_handler(M_STRING, sub { $[1]->_text =~ /^myid (.*)$/ && $id = eval $1; }; $module->add_handler(M_ICONIFY, sub { return unless defined $id; my $id0 = $_[1]->_win_id; $module->send("WindowId $id Iconify off") if $id0 == $id; }); $module->track('Scheduler')->schedule(60, sub { $module->show_message("You run this module for 1 minute") }); $module->event_loop; =head1 DESCRIPTION NOTE: This class is not functional yet. The B<FVWM::Module::Terminal> class is a sub-class of B<FVWM::Module::Toolkit> that overloads the methods B<wait_packet>, B<show_error>, B<show_message> and B<show_debug> to manage terminal functionality. This manual page details only those differences. For details on the API itself, see L<FVWM::Module>. =head1 METHODS Only overloaded or new methods are covered here: =over 8 =item B<wait_packet> Listen to the terminal read-line while waiting for the packet from fvwm. =item B<show_error> I<msg> [I<title>] Shows the error message in terminal. Useful for diagnostics of a Terminal based module. =item B<show_message> I<msg> [I<title>] Shows the message in terminal. Useful for notices by a Terminal based module. =item B<show_debug> I<msg> [I<title>] Shows the debug info in terminal. Useful for debugging a Terminal based module. =back =head1 BUGS Awaiting for your reporting. =head1 AUTHOR Mikhael Goikhman <migo@homemail.com>. =head1 SEE ALSO For more information, see L<fvwm>, L<FVWM::Module> and L<Term::ReadLine>. =cut ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/FVWM/Module/Toolkit.pm�����������������������������������������������������������0000644�0001757�0001757�00000017622�12750325036�015077� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2003-2009 Mikhael Goikhman # # 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 package FVWM::Module::Toolkit; use 5.004; use strict; use vars qw($VERSION @ISA $_dialog_tool); use FVWM::Module; BEGIN { $VERSION = $FVWM::Module::VERSION; @ISA = qw(FVWM::Module); } sub import ($@) { my $class = shift; my $caller = caller; my $error = 0; my $name = "*undefined*"; while (@_) { $name = shift; if ($name eq 'base') { next if UNIVERSAL::isa($caller, __PACKAGE__); my $caller2 = (caller(1))[0]; eval " package $caller2; use FVWM::Constants; package $caller; use vars qw(\$VERSION \@ISA); use FVWM::Constants; \$VERSION = \$FVWM::Module::Toolkit::VERSION; \@ISA = qw(FVWM::Module::Toolkit); "; if ($@) { die "Internal error:\n$@"; } } else { my ($name0, $args) = split(/>?=/, $name, 2); my $mod = $args? "$name0 split(/,/, q{$args})": $name; eval " package $caller; use $mod; "; if ($@) { $error = 1; last; } } } if ($error) { my $script_name = $0; $script_name =~ s|.*/||; my $error_title = 'FVWM Perl library error'; my $error_msg = "$script_name requires Perl package $name to be installed.\n\n"; $error_msg .= "You may either find it as a binary package for your distribution\n"; $error_msg .= "or download it from CPAN, http://cpan.org/modules/by-module/ .\n"; $class->show_message($error_msg, $error_title, 1); print STDERR "[$error_title]: $error_msg\n$@"; exit(1); } } sub show_error ($$;$) { my $self = shift; my $msg = shift; my $title = shift || ($self->name . " Error"); $self->show_message($msg, $title, 1); print STDERR "[$title]: $msg\n"; } sub show_message ($$;$) { my $self = shift; my $msg = shift; my $title = shift || ($self->name . " Message"); my $no_stderr = shift || 0; # for private usage only unless ($_dialog_tool) { my @dirs = split(':', $ENV{PATH}); # kdialog is last because at least v0.9 ignores --title TOOL_CANDIDATE: foreach (qw(gdialog Xdialog zenity message kdialog)) { foreach my $dir (@dirs) { my $file = "$dir/$_"; if (-x $file) { $_dialog_tool = $_; last TOOL_CANDIDATE; } } } } my $tool = $_dialog_tool || "xterm"; $msg =~ s/'/'"'"'/sg; $title =~ s/'/'"'"'/sg; if ($tool eq "gdialog" || $tool eq "Xdialog" || $tool eq "kdialog") { system("$tool --title '$title' --msgbox '$msg' 500 100 &"); } elsif ($tool eq "zenity") { system("zenity --title '$title' --info --text '$msg' --no-wrap &"); } elsif ($tool eq "xmessage") { system("xmessage -name '$title' '$msg' &"); } else { $msg =~ s/"/\\"/sg; $msg =~ s/\n/\\n/sg; system("xterm -g 70x10 -T '$title' -e \"echo '$msg'; sleep 600000\" &"); } print STDERR "[$title]: $msg\n" if $! && !$no_stderr; } sub show_debug ($$;$) { my $self = shift; my $msg = shift; my $title = shift || ($self->name . " Debug"); print STDERR "[$title]: $msg\n"; } sub add_default_error_handler ($) { my $self = shift; $self->add_handler(M_ERROR, sub { my ($self, $event) = @_; $self->show_error($event->_text, "fvwm error"); }); } 1; __END__ =head1 NAME FVWM::Module::Toolkit - FVWM::Module with abstract widget toolkit attached =head1 SYNOPSIS 1) May be used anywhere to require external Perl classes and report error in the nice dialog if absent: use FVWM::Module::Toolkit qw(Tk X11::Protocol Tk::Balloon); use FVWM::Module::Toolkit qw(Tk=804.024,catch X11::Protocol>=0.52); There is the same syntactic sugar as in "perl -M", with an addition of ">=" being fully equivalent to "=". The ">=" form may look better for the user in the error message. If the required Perl class is absent, FVWM::Module::Toolkit->show_message() is used to show the dialog and the application dies. 2) This class should be uses to implement concrete toolkit subclasses. A new toolkit subclass implementation may look like this: package FVWM::Module::SomeToolkit; # this automatically sets the base class and tries "use SomeToolkit;" use FVWM::Module::Toolkit qw(base SomeToolkit); sub show_error ($$;$) { my ($self, $error, $title) = @_; $title ||= $self->name . " Error"; # create a dialog box using SomeToolkit widgets SomeToolkit->Dialog( -title => $title, -text => $error, -buttons => ['Close'], ); } sub event_loop ($$) { my $self = shift; my @params = @_; # enter the SomeToolkit event loop with hooking $self->{istream} $self->event_loop_prepared(@params); fileevent($self->{istream}, read => sub { unless ($self->process_packet($self->read_packet)) { $self->disconnect; $top->destroy; } $self->event_loop_prepared(@params); } ); SomeToolkit->MainLoop; $self->event_loop_finished(@params); } =head1 DESCRIPTION The B<FVWM::Module::Toolkit> package is a sub-class of B<FVWM::Module> that is intended to be uses as the base of sub-classes that attach widget toolkit library, like Perl/Tk. It does some common work to load widget toolkit libraries and to show an error in the external window like xmessage if the required libraries are not available. This class overloads one method B<add_default_error_handler> and expects sub-classes to overload the methods B<show_error>, B<show_message> and B<show_debug> to use native widgets. These 3 methods are implemented in this class, they extend the superclass versions by adding a title parameter and using an external dialog tool to show error/message. This manual page details only those differences. For details on the API itself, see L<FVWM::Module>. =head1 METHODS Only overloaded or new methods are covered here: =over 8 =item B<show_error> I<msg> [I<title>] This method is intended to be overridden in subclasses to create a dialog box using the corresponding widgets. The default fall back implementation is similar to B<show_message>, but the error message (with title) is also always printed to STDERR. May be good for module diagnostics or any other purpose. =item B<show_message> I<msg> [I<title>] This method is intended to be overridden in subclasses to create a dialog box using the corresponding widgets. The default fall back implementation is to find a system message application to show the message. The potentially used applications are I<gdialog>, I<Xdialog>, I<zenity>, I<xmessage>, I<kdialog>, or I<xterm> as the last resort. If not given, I<title> is based on the module name. May be good for module debugging or any other purpose. =item B<show_debug> I<msg> [I<title>] This method is intended to be overridden in subclasses to create a dialog box using the corresponding widgets. The default fall back implementation is to print a message (with a title that is the module name by default) to STDERR. May be good for module debugging or any other purpose. =item B<add_default_error_handler> This methods adds a M_ERROR handler to automatically notify you that an error has been reported by fvwm. The M_ERROR handler then calls C<show_error()> with the received error text as a parameter to show it in a window. =back =head1 AUTHOR Mikhael Goikhman <migo@homemail.com>. =head1 SEE ALSO For more information, see L<fvwm>, L<FVWM::Module>, L<FVWM::Module::Tk>. =cut ��������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/FVWM/Commands.pm�����������������������������������������������������������������0000644�0001757�0001757�00000057604�12750322651�013772� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Autogenerated from the fvwm sources. package FVWM::Commands; use vars qw($VERS $TIME @LIST); $VERS = '2.6.6 (from cvs)'; $TIME = 1410306754; @LIST = ( { name => '#', cursor => '', window => 0, descr => q{Comment line (ignored)}, }, { name => '*', cursor => '', window => 0, descr => q{Module configuration line (no space after asterisk)}, }, { name => '+', cursor => '', window => 0, descr => q{Continue the last AddToFunc, AddToMenu or AddToDecor}, }, { name => 'AddButtonStyle', cursor => '', window => 0, descr => q{Add to a button style (see ButtonStyle)}, }, { name => 'AddTitleStyle', cursor => '', window => 0, descr => q{Add to a title style (see TitleStyle)}, }, { name => 'AddToDecor', cursor => '', window => 0, descr => q{Add a decor definition (will be obsolete)}, }, { name => 'AddToFunc', cursor => '', window => 0, descr => q{Add a function definition}, }, { name => 'AddToMenu', cursor => '', window => 0, descr => q{Add a menu definition}, }, { name => 'All', cursor => '', window => 0, descr => q{Operate on all windows matching the given condition}, }, { name => 'AnimatedMove', cursor => 'MOVE', window => 1, descr => q{Like Move, but uses animation to move windows}, }, { name => 'Any', cursor => '', window => 0, descr => q{Operate if there is any window matching the condition}, }, { name => 'Beep', cursor => '', window => 0, descr => q{Produce a bell}, }, { name => 'BorderStyle', cursor => '', window => 0, descr => q{Define a window border look (will be reworked)}, }, { name => 'Break', cursor => '', window => 0, descr => q{Stop executing the current (but not parent) function}, }, { name => 'BugOpts', cursor => '', window => 0, descr => q{Set some application bug workarounds}, }, { name => 'BusyCursor', cursor => '', window => 0, descr => q{Show/don't show the wait cursor in certain operations}, }, { name => 'ButtonState', cursor => '', window => 0, descr => q{Disable some titlebar button states (not recommended)}, }, { name => 'ButtonStyle', cursor => '', window => 0, descr => q{Define a window button look (will be reworked)}, }, { name => 'ChangeDecor', cursor => 'SELECT', window => 1, descr => q{Attach decor to a window (will be obsolete)}, }, { name => 'ChangeMenuStyle', cursor => '', window => 0, descr => q{Attach menu style to a menu (see MenuStyle)}, }, { name => 'CleanupColorsets', cursor => '', window => 0, descr => q{Reset all used colorsets with the default gray colors}, }, { name => 'ClickTime', cursor => '', window => 0, descr => q{Set a time in milliseconds for click and double click}, }, { name => 'Close', cursor => 'DESTROY', window => 1, descr => q{Try to Delete a window, if this fails, Destroy it}, }, { name => 'ColorLimit', cursor => '', window => 0, descr => q{Set limit on colors used (obsolete)}, }, { name => 'ColormapFocus', cursor => '', window => 0, descr => q{Change the colormap behaviour for low-depth X servers}, }, { name => 'Colorset', cursor => '', window => 0, descr => q{Manage colors used like fg, bg, image bg, gradient bg}, }, { name => 'CopyMenuStyle', cursor => '', window => 0, descr => q{Copy the existing menu style to new or existing one}, }, { name => 'Current', cursor => '', window => 0, descr => q{Operate on the currently focused window}, }, { name => 'CursorMove', cursor => '', window => 0, descr => q{Move the cursor pointer non interactively}, }, { name => 'CursorStyle', cursor => '', window => 0, descr => q{Define different cursor pointer shapes and colors}, }, { name => 'DefaultColors', cursor => '', window => 0, descr => q{Set colors for the feedback window (will be obsolete)}, }, { name => 'DefaultColorset', cursor => '', window => 0, descr => q{Set colors for the Move/Resize feedback window}, }, { name => 'DefaultFont', cursor => '', window => 0, descr => q{The default font to use (mainly for feedback window)}, }, { name => 'DefaultIcon', cursor => '', window => 0, descr => q{The default icon to use for iconified windows}, }, { name => 'DefaultLayers', cursor => '', window => 0, descr => q{Set StaysOnBottom, StaysPut, StaysOnTop layer numbers}, }, { name => 'Delete', cursor => 'DESTROY', window => 1, descr => q{Try to delete a window using the X delete protocol}, }, { name => 'Deschedule', cursor => '', window => 0, descr => q{Remove commands sheduled earlier using Schedule}, }, { name => 'Desk', cursor => '', window => 0, descr => q{(obsolete, use GotoDesk instead)}, }, { name => 'DesktopName', cursor => '', window => 0, descr => q{Define the desktop names used in WindowList, modules}, }, { name => 'DesktopSize', cursor => '', window => 0, descr => q{Set virtual desktop size in units of physical pages}, }, { name => 'Destroy', cursor => 'DESTROY', window => 1, descr => q{Kill a window without any warning to an application}, }, { name => 'DestroyDecor', cursor => '', window => 0, descr => q{Delete decor defined by AddToDecor (will be obsolete)}, }, { name => 'DestroyFunc', cursor => '', window => 0, descr => q{Delete function defined using AddToFunc}, }, { name => 'DestroyMenu', cursor => '', window => 0, descr => q{Delete menu defined using AddToMenu}, }, { name => 'DestroyMenuStyle', cursor => '', window => 0, descr => q{Delete menu style defined using MenuStyle}, }, { name => 'DestroyModuleConfig', cursor => '', window => 0, descr => q{Delete matching module config lines defined using "*"}, }, { name => 'DestroyStyle', cursor => '', window => 0, descr => q{Delete style defined using Style}, }, { name => 'DestroyWindowStyle', cursor => 'SELECT', window => 1, descr => q{Delete style defined using WindowStyle}, }, { name => 'Direction', cursor => '', window => 0, descr => q{Operate on the next window in the specified direction}, }, { name => 'Echo', cursor => '', window => 0, descr => q{Print message to stderr, mainly for debugging}, }, { name => 'EchoFuncDefinition', cursor => '', window => 0, descr => q{Print the definion of a function}, }, { name => 'EdgeCommand', cursor => '', window => 0, descr => q{Bind one or another screen edge to an fvwm action}, }, { name => 'EdgeLeaveCommand', cursor => '', window => 0, descr => q{Bind one or another screen edge to an fvwm action}, }, { name => 'EdgeResistance', cursor => '', window => 0, descr => q{Control viewport scrolling and window move over edge}, }, { name => 'EdgeScroll', cursor => '', window => 0, descr => q{Control how much of the viewport is scrolled if any}, }, { name => 'EdgeThickness', cursor => '', window => 0, descr => q{Control how closely to edge to run command/scrolling}, }, { name => 'Emulate', cursor => '', window => 0, descr => q{Only used to position the position/size window}, }, { name => 'EscapeFunc', cursor => '', window => 0, descr => q{Abort a wait or ModuleSynchonous command}, }, { name => 'EwmhBaseStruts', cursor => '', window => 0, descr => q{Define restricted areas of the screen}, }, { name => 'EwmhNumberOfDesktops', cursor => '', window => 0, descr => q{For ewmh pager, define number of desktops}, }, { name => 'Exec', cursor => '', window => 0, descr => q{Execute an external command}, }, { name => 'ExecUseShell', cursor => '', window => 0, descr => q{The shell to use to execute an external command}, }, { name => 'FakeClick', cursor => '', window => 0, descr => q{Generate a mouse click}, }, { name => 'FakeKeypress', cursor => '', window => 0, descr => q{Send a keyboard event to a window}, }, { name => 'FlipFocus', cursor => 'SELECT', window => 1, descr => q{Focus a window without rotating windowlist order}, }, { name => 'Focus', cursor => 'SELECT', window => 1, descr => q{Give focus to a window}, }, { name => 'FocusStyle', cursor => '', window => 0, descr => q{Configure focus and raise policy for windows}, }, { name => 'Function', cursor => '', window => 0, descr => q{Execute a user defined function, see AddToFunc}, }, { name => 'GlobalOpts', cursor => '', window => 0, descr => q{(obsolete, use corresponding Style * instead)}, }, { name => 'GnomeButton', cursor => '', window => 0, descr => q{Pass mouse button presses on root to GNOME program}, }, { name => 'GnomeShowDesks', cursor => '', window => 0, descr => q{Limit GNOME pager to the number of desks}, }, { name => 'GotoDesk', cursor => '', window => 0, descr => q{Switch viewport to another desk same page}, }, { name => 'GotoDeskAndPage', cursor => '', window => 0, descr => q{Switch viewport to another desk and page}, }, { name => 'GotoPage', cursor => '', window => 0, descr => q{Switch viewport to another page same desk}, }, { name => 'HideGeometryWindow', cursor => '', window => 0, descr => q{Hide/show the position/size window}, }, { name => 'HilightColor', cursor => '', window => 0, descr => q{(obsolete, use Style * HighlightFore/Back)}, }, { name => 'HilightColorset', cursor => '', window => 0, descr => q{(obsolete, use Style * HighlightColorset)}, }, { name => 'IconFont', cursor => '', window => 0, descr => q{(obsolete, use Style * IconFont)}, }, { name => 'Iconify', cursor => 'SELECT', window => 1, descr => q{Change iconification status of a window (minimize)}, }, { name => 'IconPath', cursor => '', window => 0, descr => q{(obsolete, use ImagePath instead)}, }, { name => 'IgnoreModifiers', cursor => '', window => 0, descr => q{Modifiers to ignore on mouse and key bindings}, }, { name => 'ImagePath', cursor => '', window => 0, descr => q{Directories to search for images}, }, { name => 'InfoStoreAdd', cursor => '', window => 0, descr => q{Adds an entry (key/value pairs) to the infostore}, }, { name => 'InfoStoreRemove', cursor => '', window => 0, descr => q{Removes an entry from the infostore}, }, { name => '- KeepRc', cursor => '', window => 0, descr => q{Do not modify the previous command return code}, }, { name => 'Key', cursor => '', window => 0, descr => q{Bind or unbind a key to an fvwm action}, }, { name => 'KillModule', cursor => '', window => 0, descr => q{Stops an fvwm module}, }, { name => 'Layer', cursor => 'SELECT', window => 1, descr => q{Change the layer of a window}, }, { name => 'LocalePath', cursor => '', window => 0, descr => q{Directories/domains to search for locale data}, }, { name => 'Lower', cursor => 'SELECT', window => 1, descr => q{Lower a window within a layer}, }, { name => 'Maximize', cursor => 'SELECT', window => 1, descr => q{Toggle maximal-size status of a window}, }, { name => 'Menu', cursor => '', window => 0, descr => q{Display (post) a menu}, }, { name => 'MenuStyle', cursor => '', window => 0, descr => q{Control appearance and behavior of a menu}, }, { name => 'Module', cursor => '', window => 0, descr => q{Invoke an fvwm module}, }, { name => 'ModuleListenOnly', cursor => '', window => 0, descr => q{Invoke an fvwm module}, }, { name => 'ModulePath', cursor => '', window => 0, descr => q{Modify the directories to search for an fvwm module}, }, { name => 'ModuleSynchronous', cursor => '', window => 0, descr => q{Invoke an fvwm module synchronously}, }, { name => 'ModuleTimeout', cursor => '', window => 0, descr => q{Set timeout value for response from module}, }, { name => 'Mouse', cursor => '', window => 0, descr => q{Bind or unbind a mouse button press to an fvwm action}, }, { name => 'Move', cursor => 'MOVE', window => 1, descr => q{Move a window}, }, { name => 'MoveThreshold', cursor => '', window => 0, descr => q{Set number of pixels in a click and a hold vs. a drag}, }, { name => 'MoveToDesk', cursor => 'SELECT', window => 1, descr => q{Move a window to another desk same page}, }, { name => 'MoveToPage', cursor => 'SELECT', window => 1, descr => q{Move a window to another page same desk}, }, { name => 'MoveToScreen', cursor => 'SELECT', window => 1, descr => q{Move a window to another Xinerama screen}, }, { name => 'Next', cursor => '', window => 0, descr => q{Operate on the next window matching conditions}, }, { name => 'None', cursor => '', window => 0, descr => q{Perform command if no window matches conditions}, }, { name => 'Nop', cursor => '', window => 0, descr => q{Do nothing (used internally)}, }, { name => 'NoWindow', cursor => '', window => 0, descr => q{Prefix that runs a command without a window context}, }, { name => 'OpaqueMoveSize', cursor => '', window => 0, descr => q{Set maximum size window fvwm should move opaquely}, }, { name => 'Pick', cursor => 'SELECT', window => 1, descr => q{Prefix to force a window context, prompted if needed}, }, { name => 'PipeRead', cursor => '', window => 0, descr => q{Exec system command interpret output as fvwm commands}, }, { name => 'PixmapPath', cursor => '', window => 0, descr => q{(obsolete, use ImagePath instead)}, }, { name => 'PlaceAgain', cursor => 'SELECT', window => 1, descr => q{Replace a window using initial window placement logic}, }, { name => 'PointerKey', cursor => '', window => 0, descr => q{Bind an action to a key based on pointer not focus}, }, { name => 'PointerWindow', cursor => '', window => 0, descr => q{Operate on window under pointer if it meets conditions}, }, { name => 'Popup', cursor => '', window => 0, descr => q{Display (pop-up) a menu, see also Menu}, }, { name => 'Prev', cursor => '', window => 0, descr => q{Operate on the precious window matching conditions}, }, { name => 'PrintInfo', cursor => '', window => 0, descr => q{Print information about the state of fvwm}, }, { name => 'PropertyChange', cursor => '', window => 0, descr => q{Internal, used for inter-module communication}, }, { name => 'Quit', cursor => '', window => 0, descr => q{Exit fvwm}, }, { name => 'QuitScreen', cursor => '', window => 0, descr => q{Stop managing the specified screen}, }, { name => 'QuitSession', cursor => '', window => 0, descr => q{Ask session manager to shut down itself and fvwm}, }, { name => 'Raise', cursor => 'SELECT', window => 1, descr => q{Raise a window in a layer}, }, { name => 'RaiseLower', cursor => 'SELECT', window => 1, descr => q{Alternately raise or lower a window in a layer}, }, { name => 'Read', cursor => '', window => 0, descr => q{Read fvwm commands from a file}, }, { name => 'ReadWriteColors', cursor => '', window => 0, descr => q{Used for colorset speed hacks (will be removed?)}, }, { name => 'Recapture', cursor => '', window => 0, descr => q{Reapply styles to all windows (will be obsolete)}, }, { name => 'RecaptureWindow', cursor => 'SELECT', window => 1, descr => q{Reapply styles to one window (will be obsolete)}, }, { name => 'Refresh', cursor => '', window => 0, descr => q{Cause all windows to redraw themselves}, }, { name => 'RefreshWindow', cursor => 'SELECT', window => 1, descr => q{Cause one window to redraw itself}, }, { name => 'Repeat', cursor => '', window => 0, descr => q{Repeat (very unreliably) the last command, don't use}, }, { name => 'Resize', cursor => 'RESIZE', window => 1, descr => q{Cause a window to be resized}, }, { name => 'ResizeMaximize', cursor => 'RESIZE', window => 1, descr => q{Resize a window and mark window as maximized}, }, { name => 'ResizeMove', cursor => 'RESIZE', window => 1, descr => q{Resize and move in one operation}, }, { name => 'ResizeMoveMaximize', cursor => 'RESIZE', window => 1, descr => q{Resize and move in one operation and mark maximized}, }, { name => 'RestackTransients', cursor => 'SELECT', window => 1, descr => q{Regroup the window transients in the stack}, }, { name => 'Restart', cursor => '', window => 0, descr => q{Restart itself or replace with another window manager}, }, { name => 'SaveQuitSession', cursor => '', window => 0, descr => q{Cause session manager to save and shutdown fvwm}, }, { name => 'SaveSession', cursor => '', window => 0, descr => q{Cause session manager to save the session}, }, { name => 'ScanForWindow', cursor => '', window => 0, descr => q{Operate on the matching window in the given direction}, }, { name => 'Schedule', cursor => '', window => 0, descr => q{Run an fvwm command after a delay}, }, { name => 'Scroll', cursor => '', window => 0, descr => q{Scroll the desktop viewport}, }, { name => 'Send_ConfigInfo', cursor => '', window => 0, descr => q{Internal, used for module communication}, }, { name => 'Send_Reply', cursor => '', window => 0, descr => q{Internal, used for module communication}, }, { name => 'Send_WindowList', cursor => '', window => 0, descr => q{Internal, used for module communication}, }, { name => 'SendToModule', cursor => '', window => 0, descr => q{Send a string (action) to a module}, }, { name => 'set_mask', cursor => '', window => 0, descr => q{Internal, used for module communication}, }, { name => 'set_nograb_mask', cursor => '', window => 0, descr => q{Internal, used for module communication}, }, { name => 'set_sync_mask', cursor => '', window => 0, descr => q{Internal, used for module communication}, }, { name => 'SetAnimation', cursor => '', window => 0, descr => q{Control animated moves and menus}, }, { name => 'SetEnv', cursor => '', window => 0, descr => q{Set an environment variable}, }, { name => 'Silent', cursor => '', window => 0, descr => q{Suppress errors on command, avoid window selection}, }, { name => 'SnapAttraction', cursor => '', window => 0, descr => q{Control attraction of windows during move}, }, { name => 'SnapGrid', cursor => '', window => 0, descr => q{Control grid used with SnapAttraction}, }, { name => 'State', cursor => 'SELECT', window => 1, descr => q{Control user defined window states}, }, { name => 'Stick', cursor => 'SELECT', window => 1, descr => q{Change window stickyness}, }, { name => 'StickAcrossDesks', cursor => 'SELECT', window => 1, descr => q{Change window stickyness on a desk basis}, }, { name => 'StickAcrossPages', cursor => 'SELECT', window => 1, descr => q{Change window stickyness on a page basis}, }, { name => 'Stroke', cursor => '', window => 0, descr => q{Bind a stroke to an fvwm action}, }, { name => 'StrokeFunc', cursor => '', window => 0, descr => q{Record stroke and execute corresponding stroke action}, }, { name => 'Style', cursor => '', window => 0, descr => q{Set attributes of windows that match a pattern}, }, { name => 'TearMenuOff', cursor => '', window => 0, descr => q{Convert a menu to a window, for use in menu items}, }, { name => 'Test', cursor => '', window => 0, descr => q{Execute command if conditions are met}, }, { name => 'TestRc', cursor => '', window => 0, descr => q{Conditional switch (may be changed)}, }, { name => 'ThisWindow', cursor => '', window => 0, descr => q{Operate on the context window if it meets conditions}, }, { name => 'Title', cursor => '', window => 0, descr => q{Insert title into a menu}, }, { name => 'TitleStyle', cursor => '', window => 0, descr => q{Control window title}, }, { name => 'UnsetEnv', cursor => '', window => 0, descr => q{Remove an environment variable}, }, { name => 'UpdateDecor', cursor => '', window => 0, descr => q{Update window decor (obsolete and not needed anymore)}, }, { name => 'UpdateStyles', cursor => '', window => 0, descr => q{Cause styles to update while still in a function}, }, { name => 'Wait', cursor => '', window => 0, descr => q{Pause until a matching window appears}, }, { name => 'WarpToWindow', cursor => 'SELECT', window => 1, descr => q{Warp the pointer to a window}, }, { name => 'WindowFont', cursor => '', window => 0, descr => q{(obsolete, use Style * Font)}, }, { name => 'WindowId', cursor => '', window => 0, descr => q{Execute command for window matching the windowid}, }, { name => 'WindowList', cursor => '', window => 0, descr => q{Display the window list as a menu to select a window}, }, { name => 'WindowShade', cursor => 'SELECT', window => 1, descr => q{Shade/unshade a window}, }, { name => 'WindowShadeAnimate', cursor => '', window => 0, descr => q{(obsolete, use Style * WindowShadeSteps)}, }, { name => 'WindowStyle', cursor => 'SELECT', window => 1, descr => q{Set styles on the selected window}, }, { name => 'Xinerama', cursor => '', window => 0, descr => q{Control Xinerama support}, }, { name => 'XineramaPrimaryScreen', cursor => '', window => 0, descr => q{Identify Xinerama primary screen}, }, { name => 'XineramaSls', cursor => '', window => 0, descr => q{Control single logical screen support}, }, { name => 'XineramaSlsScreens', cursor => '', window => 0, descr => q{Configure layout for single logical screen}, }, { name => 'XineramaSlsSize', cursor => '', window => 0, descr => q{Configure layout for single logical screen sizes}, }, { name => 'XorPixmap', cursor => '', window => 0, descr => q{Use a pixmap for move/resize rubber-band}, }, { name => 'XorValue', cursor => '', window => 0, descr => q{Change bits used for move/resize rubber-band}, }, { name => 'XSync', cursor => '', window => 0, descr => q{For debugging, send all pending requests to X server}, }, { name => 'XSynchronize', cursor => '', window => 0, descr => q{For debugging, cause all X requests to be synchronous}, }, ); 1; __END__ =head1 NAME FVWM::Commands - lists all available fvwm commands =head1 DESCRIPTION This class is autogenerated from the fvwm sources. It may be used to get a list of all available fvwm commands including the command name, its short description and some other command properties. =head1 USAGE use lib `fvwm-perllib dir`; use FVWM::Commands; use POSIX; my $date = strftime("%d-%b-%Y", gmtime($FVWM::Commands::TIME)); my $version = $FVWM::Commands::VERS; print "The recognized commands for fvwm $version as of $date:\n\n"; foreach my $command (@FVWM::Commands::LIST) { printf " %-21s - %s\n", $command->{name}, $command->{descr}; } =head1 PUBLIC CONSTANTS =over 4 =item $VERS The fvwm version number at the generation time like "2.6.0" plus the info that may indicate that this is not a final version, but a cvs snapshot. =item $TIME The unix time of the command list generation. Example: print "The fvwm command list found on your system was generated " . (time() - $FVWM::Commands::TIME) / 86400 . " days ago\n"; =item @LIST The command list that is an array of hashes with keys I<name>, I<cursor>, I<descr> (string) and I<window> (boolean). I<name> may be special, like "+", "#" and "*". Other names usually contain only isalpha characters, like B<Move>, B<SendToModule>. I<cursor> may be either empty or the cursor context used in B<CursorStyle> (like "SELECT" or "MOVE"), associated with the command. I<descr> is a short one line description of the command. I<window> is true for commands that need a window. Example: # get command names only @command_names = map { $_->{name} } @FVWM::Commands::LIST; =back =head1 AUTHOR Mikhael Goikhman <migo@homemail.com>. =head1 SEE ALSO For more information about the commands themselves, see fvwm(1). =cut ����������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/FVWM/EventNames.pm���������������������������������������������������������������0000644�0001757�0001757�00000043672�12673746443�014313� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2003-2009, Mikhael Goikhman # # 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 package FVWM::EventNames; use strict; use FVWM::Constants; use constant number => 0; use constant bool => 1; use constant window => 2; use constant pixel => 3; use constant string => 4; use constant wflags => 5; use constant looped => 6; use vars qw($EVENTS_INFO); # ---------------------------------------------------------------------------- # start of the would-be-generated part $EVENTS_INFO = { &M_NEW_PAGE => { format => "l!3L!4", fields => [ vp_x => number, vp_y => number, desk_n => number, vp_width => number, vp_height => number, desk_pages_x => number, desk_pages_y => number, ], aliases => { desk => 'desk_n', }, }, &M_NEW_DESK => { format => "l!", fields => [ desk_n => number, ], aliases => { desk => 'desk_n', }, }, # &M_OLD_ADD_WINDOW => { # }, &M_RAISE_WINDOW => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &M_LOWER_WINDOW => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, # &M_OLD_CONFIGURE_WINDOW => { # }, &M_FOCUS_CHANGE => { format => "L!5", fields => [ win_id => window, frame_id => window, flip => bool, focus_fg => pixel, focus_bg => pixel, ], }, &M_DESTROY_WINDOW => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &M_ICONIFY => { format => "L!3l!8", fields => [ win_id => window, frame_id => window, ptr => number, icon_x => number, icon_y => number, icon_width => number, icon_height => number, frame_x => number, frame_y => number, frame_width => number, frame_height => number, ], }, &M_DEICONIFY => { format => "L!3l!8", fields => [ win_id => window, frame_id => window, ptr => number, icon_x => number, icon_y => number, icon_width => number, icon_height => number, frame_x => number, frame_y => number, frame_width => number, frame_height => number, ], }, &M_WINDOW_NAME => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &M_ICON_NAME => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &M_RES_CLASS => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &M_RES_NAME => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &M_END_WINDOWLIST => { format => "", fields => [ ], }, &M_ICON_LOCATION => { format => "L!3l!4", fields => [ win_id => window, frame_id => window, ptr => number, x => number, y => number, width => number, height => number, ], }, &M_MAP => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &M_ERROR => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, text => string, ], }, &M_CONFIG_INFO => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, text => string, ], }, &M_END_CONFIG_INFO => { format => "", fields => [ ], }, &M_ICON_FILE => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &M_DEFAULTICON => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &M_STRING => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, text => string, ], }, &M_MINI_ICON => { format => "L!9a*", fields => [ win_id => window, frame_id => window, ptr => number, width => number, height => number, depth => number, icon_id => window, mask => number, alpha => number, name => string, ], }, &M_WINDOWSHADE => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &M_DEWINDOWSHADE => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &M_VISIBLE_NAME => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, # &M_SENDCONFIG => { # }, &M_RESTACK => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, low_windows => looped, ], loop_format => "L!3a*", loop_fields => [ win_id => window, frame_id => window, ptr => number, ], }, &M_ADD_WINDOW => { format => "L!3l!6l!8L!2l!L!2l!3S4a*", fields => [ win_id => window, frame_id => window, ptr => number, frame_x => number, frame_y => number, frame_width => number, frame_height => number, desk => number, layer => number, win_width => number, win_height => number, resize_width_inc => number, resize_height_inc => number, minimum_width => number, minimum_height => number, maximum_width => number, maximum_height => number, icon_title_id => window, icon_image_id => window, gravity => number, fore_color => pixel, back_color => pixel, ewmh_layer => number, ewmh_desktop => number, ewmh_window_type => number, title_height => number, border_width => number, dummy_zero_1 => number, dummy_zero_2 => number, window_flags => wflags, ], }, &M_CONFIGURE_WINDOW => { format => "L!3l!6l!8L!2l!L!2l!3S4a*", fields => [ win_id => window, frame_id => window, ptr => number, frame_x => number, frame_y => number, frame_width => number, frame_height => number, desk => number, layer => number, win_width => number, win_height => number, resize_width_inc => number, resize_height_inc => number, minimum_width => number, minimum_height => number, maximum_width => number, maximum_height => number, icon_title_id => window, icon_image_id => window, gravity => number, fore_color => pixel, back_color => pixel, ewmh_layer => number, ewmh_desktop => number, ewmh_window_type => number, title_height => number, border_width => number, dummy_zero_1 => number, dummy_zero_2 => number, window_flags => wflags, ], }, # &M_EXTENDED_MSG => { # }, &MX_VISIBLE_ICON_NAME => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, name => string, ], }, &MX_ENTER_WINDOW => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &MX_LEAVE_WINDOW => { format => "L!3", fields => [ win_id => window, frame_id => window, ptr => number, ], }, &MX_PROPERTY_CHANGE => { format => "L!3a*", fields => [ type => number, value => number, win_id => window, text => string, ], info => { type_names => [ qw(NONE BACKGROUND SWALLOW) ], }, }, &MX_REPLY => { format => "L!3a*", fields => [ win_id => window, frame_id => window, ptr => number, text => string, ], }, "faked" => { format => "", fields => [ ], }, }; # end of the would-be-generated part # ---------------------------------------------------------------------------- use Exporter; use vars qw(@EXPORT @ISA $EVENT_TYPES $EVENT_NAMES $EVENT_TYPE_NAMES); @EXPORT = ( @FVWM::Constants::EXPORT, qw(event_name event_arg_names event_arg_types event_arg_values event_args), qw(event_loop_arg_names event_loop_arg_types), qw(event_arg_aliases all_event_names all_event_types) ); @ISA = qw(Exporter); sub all_event_type_names () { if (!defined $EVENT_TYPE_NAMES) { $EVENT_TYPES = []; $EVENT_NAMES = []; $EVENT_TYPE_NAMES = {}; my ($type, $name); foreach $name (@FVWM::Constants::EXPORT) { next unless $name =~ /^MX?_/; next if $name eq 'M_EXTENDED_MSG'; no strict 'refs'; $type = &$name(); next if $name =~ /^MX_/ && !($type & M_EXTENDED_MSG); push @$EVENT_TYPES, $type; push @$EVENT_NAMES, $name; $EVENT_TYPE_NAMES->{$type} = $name; } } return $EVENT_TYPE_NAMES; } sub all_event_names () { all_event_type_names(); return wantarray? @$EVENT_NAMES: $EVENT_NAMES; } sub all_event_types () { all_event_type_names(); return wantarray? @$EVENT_TYPES: $EVENT_TYPES; } sub event_name ($) { my $type = shift; return all_event_type_names()->{$type}; } sub event_type_to_binary ($) { my $type = shift || "no-event-type"; return $type unless $type =~ /^\d+$/; return sprintf("%b", $type); } sub event_info ($) { my $type = shift; unless (defined $EVENTS_INFO->{$type}) { die "FVWM::EventNames: Unknown event type (" . event_type_to_binary($type) . ")\n"; } return $EVENTS_INFO->{$type}; } sub calculate_internals ($) { my $type = shift; my $event_info = event_info($type); $event_info->{names} = []; $event_info->{types} = []; my $i = 0; foreach (@{$event_info->{fields}}) { push @{$event_info->{names}}, $_ if ($i % 2) == 0; push @{$event_info->{types}}, $_ if ($i % 2) == 1; $i++; } # handle loop args if any return unless exists $event_info->{loop_fields}; $event_info->{loop_names} = []; $event_info->{loop_types} = []; $i = 0; foreach (@{$event_info->{loop_fields}}) { push @{$event_info->{loop_names}}, $_ if ($i % 2) == 0; push @{$event_info->{loop_types}}, $_ if ($i % 2) == 1; $i++; } } sub event_arg_names ($$) { my $type = shift; my $arg_values = shift; my $event_info = event_info($type); my $arg_names = $event_info->{names}; return $arg_names if defined $arg_names; calculate_internals($type); return $event_info->{names}; } sub event_arg_types ($$) { my $type = shift; my $arg_values = shift; my $event_info = event_info($type); my $arg_types = $event_info->{types}; return $arg_types if defined $arg_types; calculate_internals($type); return $event_info->{types}; } sub event_arg_values ($$) { my $type = shift; my $packed_str = shift; my $event_info = event_info($type); my @arg_values = unpack($event_info->{format}, $packed_str); my $arg_fields = $event_info->{fields}; push @arg_values, (undef) x ((@$arg_fields / 2) - @arg_values); # process looped args if (@$arg_fields && $arg_fields->[@$arg_fields - 1] == looped) { my @loop_arg_values = (); my $rest_str = pop @arg_values; while ($rest_str ne "") { my @new_arg_values = unpack($event_info->{loop_format}, $rest_str); die "Internal error, no loop args unpacked ($type)\n" unless @new_arg_values > 1; $rest_str = pop @new_arg_values; push @loop_arg_values, @new_arg_values; } push @arg_values, \@loop_arg_values; } # strip everything past the first null (or newline) if needed if (@$arg_fields && $arg_fields->[-1] == string) { $arg_values[-1] =~ s/\n*\0.*//s; } return \@arg_values; } sub event_loop_arg_names ($$) { my $type = shift; my $arg_values = shift; my $event_info = event_info($type); my $arg_names = $event_info->{loop_names}; return $arg_names if defined $arg_names; calculate_internals($type); return $event_info->{loop_names}; } sub event_loop_arg_types ($$) { my $type = shift; my $arg_values = shift; my $event_info = event_info($type); my $arg_types = $event_info->{loop_types}; return $arg_types if defined $arg_types; calculate_internals($type); return $event_info->{loop_types}; } sub event_args ($$) { my $type = shift; my $arg_values = shift; my $arg_names = event_arg_names($type, $arg_values); die sprintf "Internal error, event type %s (%d names, %d values)\n", event_type_to_binary($type), scalar @$arg_names, scalar @$arg_values if @$arg_names != @$arg_values; my $loop_arg_names = event_loop_arg_names($type, $arg_values); die sprintf "Internal error, event type %s (%d loop names, non array)\n", event_type_to_binary($type), scalar @$loop_arg_names if $loop_arg_names && ref($loop_arg_names) ne 'ARRAY' && !@$loop_arg_names && ref($arg_values->[-1]) ne 'ARRAY'; my $i = 0; my %args = map { my $value = $_; $arg_names->[$i++], ref($value) ne 'ARRAY'? $value: do { my $loop_value = []; my $j = 0; while ($j < @$value) { my %loop_hash = map { $_, $value->[$j++] } @$loop_arg_names; push @$loop_value, \%loop_hash; } $loop_value } } @$arg_values; return \%args; } sub event_arg_aliases ($) { my $type = shift; return event_info($type)->{aliases} || {}; } # ---------------------------------------------------------------------------- =head1 NAME FVWM::EventNames - names and types of all fvwm event arguments =head1 SYNOPSIS use FVWM::EventNames; print "All event names: ", join(", ", @{all_event_names()}), "\n"; print "All event types: ", join(", ", @{all_event_types()}), "\n"; my $name = event_name (M_ICON_LOCATION); my $arg_values = event_arg_values(M_ICON_LOCATION, $packed_str); my $arg_names = event_arg_names (M_ICON_LOCATION, $arg_values); my $arg_types = event_arg_types (M_ICON_LOCATION, $arg_values); my $args = event_args (M_ICON_LOCATION, $arg_values); =head1 DESCRIPTION Every event send by I<fvwm> consist of arguments. The argument names and types vary from one event type to another. For example, event of the type B<M_NEW_DESK> consists of only one argument I<desk> of type I<number>. B<M_NEW_PAGE> consists of 5 numeric arguments, B<M_MINI_ICON> consists of 10 arguments of different types. This class provides information about all fvwm events. It provides such services as listing all supported event types and their names, converting event type to event name, listing the event argument names/types, constructing event argument values from the plain packet data. Usually you do not need to work with this class directly, but, instead, with B<FVWM::Event> objects. Hovewer, you may need this class source as a reference for the names of the event arguments and their types. =head1 PUBLIC FUNCTIONS =over 4 =item B<event_name> I<type> Returns the string representation of the numeric event I<type> constant, like I<M_RAISE_WINDOW> or I<MX_ENTER_WINDOW>. =item B<event_arg_values> I<type> I<packed_str> Constructs array ref of argument values for the event I<type> from the I<packed_str> (as received from I<fvwm>). If the last argument type of the event is string, for convenience, everything past the first null (or newline) is automatically stripped from the last argument value. =item B<event_arg_names> I<type> I<arg_values> Returns array ref of argument names of the event type. I<arg_values> is either the real array ref of values (as returned by B<event_arg_values>) or a number of actual values. The returned array has the same number of elements. =item B<event_arg_types> I<type> I<arg_values> Returns array ref of argument types of the event type. I<arg_values> is either the real array ref of values (as returned by B<event_arg_values>) or a number of actual values. The returned array has the same number of elements. =item B<event_loop_arg_names> I<type> I<arg_values> Returns array ref of looped argument names of the event type (or undef). =item B<event_loop_arg_types> I<type> I<arg_values> Returns array ref of looped argument types of the event type (or undef). =item B<event_args> I<type> I<arg_values> Constructs hash ref of the named arguments for the event I<type> from the I<arg_values> array ref (as returned by B<event_arg_values>). =item B<event_arg_aliases> I<type> This method is provided for backward compatibility when argument names are changed. For example, in the past the argument name of I<M_NEW_DESK> was B<desk>, but now it is B<desk_n>. Using this method it is possible to make both names supported. Returns hash ref (old-name => new-name). =item B<all_event_names> Returns array ref of all known event names (strings). In the list context returns list of these names. =item B<all_event_types> Returns array ref of all known event types (numbers). In the list context returns list of these types. =item B<all_event_type_names> Returns hash ref of all known event names and types (type => name). =back =head1 SEE ALSO L<FVWM::Event>. =cut 1; ����������������������������������������������������������������������fvwm-2.6.7/perllib/Makefile.am����������������������������������������������������������������������0000644�0001757�0001757�00000000201�13006057357�013130� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Process this file with automake to create Makefile.in SUBDIRS = FVWM General uninstall-hook: rm -fr @FVWM_DATADIR@/perllib �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/Makefile.in����������������������������������������������������������������������0000644�0001757�0001757�00000051552�13010103323�013134� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = perllib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ SUBDIRS = FVWM General all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign perllib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign perllib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: $(am__recursive_targets) install-am install-strip uninstall-am .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-hook uninstall-hook: rm -fr @FVWM_DATADIR@/perllib # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/General/�������������������������������������������������������������������������0000755�0001757�0001757�00000000000�13010103345�012520� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/General/Makefile.am��������������������������������������������������������������0000644�0001757�0001757�00000000243�12773470550�014517� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Process this file with automake to create Makefile.in configdir = @FVWM_PERLLIBDIR@/General config_DATA = FileSystem.pm Parse.pm EXTRA_DIST = $(config_DATA) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/General/Makefile.in��������������������������������������������������������������0000644�0001757�0001757�00000041412�13010103323�014503� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = perllib/General DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(configdir)" DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ configdir = @FVWM_PERLLIBDIR@/General config_DATA = FileSystem.pm Parse.pm EXTRA_DIST = $(config_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign perllib/General/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign perllib/General/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-configDATA \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-configDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/General/FileSystem.pm������������������������������������������������������������0000644�0001757�0001757�00000057570�12750325036�015115� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 1998-2009, Mikhael Goikhman # # 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 package General::FileSystem; require 5.004; use strict; use vars qw(@ISA @EXPORT); require Exporter; @ISA = qw(Exporter); @EXPORT = qw( load_file save_file append_file remove_file copy_file move_file make_dir make_path clean_dir remove_dir copy_dir move_dir list_filenames find_file find_executable default_dir_perm preserve_stat parse_path get_cwd ); use vars qw($CACHE_FILE_NUM $cache_counter @prev_filenames @prev_file_content_refs); use vars qw($ENABLE_CACHE %NEVER_COPY_FILES %NEVER_REMOVE_FILES); use vars qw($DEFAULT_DIR_PERM $PRESERVED_STAT); use vars qw($DEBUG_ENABLED $ERROR_HANDLER $LOAD_FILE_DIRS $SAVE_FILE_DIR); BEGIN { $ENABLE_CACHE = 0; # this is risky for dynamical files %NEVER_COPY_FILES = ( 'CVS' => 1, 'core' => 1 ); %NEVER_REMOVE_FILES = ( 'CVS' => 1 ); $DEFAULT_DIR_PERM = 0775; $PRESERVED_STAT = 0; # allow these constants to be set directly from outside $ERROR_HANDLER ||= "warn"; # may be "die", "warn", "quiet" or CODE $DEBUG_ENABLED ||= 0; $LOAD_FILE_DIRS ||= [ "." ]; # for non fully qualified files only $SAVE_FILE_DIR ||= "."; # for non fully qualified files only } # ---------------------------------------------------------------------------- =head1 NAME General::FileSystem - file system specific functions =head1 SYNOPSIS use General::FileSystem "-die", "-debug"; # die on errors eval { make_path("/tmp/my-own/dir"); my $file_content_ref = load_file("/etc/issue"); save_file("/tmp/my-own/dir/issue", $file_content_ref); # This is equivalent to the previous two lines, but optimized copy_file("/etc/issue", "/tmp/my-own/dir/issue"); make_dir("/tmp/my-own/dir2", 0711); copy_file("/etc/issue", "/tmp/my-own/dir2/issue"); move_file("/tmp/my-own/dir2/issue", "/tmp/my-own/dir2/issue2"); remove_file("/tmp/my-own/dir2/issue2"); clean_dir("/tmp/my-own/dir2"); # no effect, it's empty already remove_dir("/tmp/my-own"); }; if ($@) { print "File System Error: $@"; }; or just: use General::FileSystem; copy_file("origin.txt", "backup.txt"); =head1 DESCRIPTION This package contains common file operation functions: B<load_file>, B<save_file>, B<append_file>, B<remove_file>, B<copy_file>, B<move_file>, B<make_dir>, B<make_path>, B<clean_dir>, B<remove_dir>, B<copy_dir>, B<move_dir>, B<list_filenames>, B<find_file>, B<find_executable>, B<default_dir_perm>, B<preserve_stat>, B<parse_path>, B<get_cwd>. On fatal file system errors all functions call the error handler, that may throw exception (die), issue a warning or quietly return undef. You may control this by passing one of the arguments I<-die>, I<-warn> or I<-quiet> in B<use> or by setting C<$ERROR_HANDLER> to one of these values (don't specify a dash in this case). =head1 REQUIREMENTS L<Cwd>, L<File::Basename>, L<File::Copy>. =head1 FUNCTIONS =cut # ============================================================================ use Cwd; use File::Basename; use File::Copy; sub import ($;$) { my $package = shift; while (@_ && $_[0] =~ /^-/) { local $_ = shift; $ERROR_HANDLER = $1 if /^-(die|warn|quiet)$/i; $DEBUG_ENABLED = $1 if /^-(debug)$/i; } $package->export_to_level(1, @_); } # private function sub call_error_handler ($) { my $msg = shift; die "$msg: [$!]\n" if $ERROR_HANDLER eq "die"; warn "$msg: [$!]\n" if $ERROR_HANDLER eq "warn"; return undef if $ERROR_HANDLER eq "quiet"; &$ERROR_HANDLER($msg) if ref($ERROR_HANDLER) eq "CODE"; return undef; } # private function sub print_log ($) { my $msg = shift; return unless $DEBUG_ENABLED; print STDERR "FileSystem: $msg\n"; } # ---------------------------------------------------------------------------- =head2 load_file =over 4 =item usage $content_ref = load_file($filename) =item description Loads file with given file-name from local filesystem. =item parameters * filename - name of the file to be loaded. =item returns Reference to file content string on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ BEGIN { $CACHE_FILE_NUM = 6; $cache_counter = -1; @prev_filenames = ("", "", "", "", "", ""); @prev_file_content_refs = \("", "", "", "", "", ""); } sub load_file ($) { my $filename = shift; foreach (@$LOAD_FILE_DIRS) { if (-f "$_/$filename") { $filename = "$_/$filename"; last; } } print_log("Loading file $filename") if $DEBUG_ENABLED; if ($ENABLE_CACHE) { for (0 .. $CACHE_FILE_NUM-1) { if ($filename eq $prev_filenames[$_] && -r $filename) { print_log("getting from file cache") if $DEBUG_ENABLED; return $prev_file_content_refs[$_]; } } } open(FILE, "<$filename") || return call_error_handler("Can't open $filename"); my $content = join("", <FILE>); close(FILE) || return call_error_handler("Can't close $filename"); if ($ENABLE_CACHE) { $cache_counter = ($cache_counter+1) % $CACHE_FILE_NUM; $prev_filenames[$cache_counter] = $filename; $prev_file_content_refs[$cache_counter] = \$content; } return \$content; } # ---------------------------------------------------------------------------- =head2 save_file =over 4 =item description Saves file-content to local filesystem with given file-name. =item usage save_file($filename, \$content); =item parameters * filename - name of the file to be saved into * content_ref - reference to file content string * create_subdirs - optional flag (default is 0 - don't create subdirs) =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub save_file ($$;$) { my ($filename, $content_ref, $create_dirs) = @_; if ($filename !~ m=^[/\\]|\w:\\=) { $filename = "$SAVE_FILE_DIR/$filename"; } print_log("Saving file $filename") if $DEBUG_ENABLED; die("save_file: No SCALAR ref parameter\n") unless ref($content_ref) eq 'SCALAR'; if ($ENABLE_CACHE) { for (0 .. $CACHE_FILE_NUM-1) { $prev_file_content_refs[$_] = $content_ref if $filename eq $prev_filenames[$_]; } } if ($create_dirs) { my $dirname = dirname($filename); make_path($dirname) unless -d $dirname; } open(FILE, ">$filename") || return call_error_handler("Can't open $filename"); print FILE $$content_ref; close(FILE) || return call_error_handler("Can't close $filename"); return 1; } # ---------------------------------------------------------------------------- =head2 append_file =over 4 =item description Appends file-content to local filesystem with given file-name. =item usage append_file($filename, \$appended_content); =item parameters * filename - name of the file to be saved into * appended_content_ref - reference to appended-content string =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub append_file ($$) { my ($filename, $appended_content_ref) = @_; print_log("Append>>file $filename") if $DEBUG_ENABLED; if ($ENABLE_CACHE) { for (0 .. $CACHE_FILE_NUM-1 && -r $filename) { ${$prev_file_content_refs[$_]} .= $$appended_content_ref if $filename eq $prev_filenames[$_]; } } open(FILE, ">>$filename") || return call_error_handler("Can't append to $filename"); print FILE $$appended_content_ref; close(FILE) || return call_error_handler("Can't close $filename"); return 1; } # ---------------------------------------------------------------------------- =head2 remove_file =over 4 =item description Removes all files from given directory. =item usage remove_file($filename); =item parameters * filename - name of the file to be deleted =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub remove_file ($;$) { my $filename = shift; print_log("Removin file $filename") if $DEBUG_ENABLED; unlink($filename) || return call_error_handler("Can't unlink $filename"); return 1; } # ---------------------------------------------------------------------------- =head2 make_dir =over 4 =item description Removes all files from given directory. =item usage make_dir($PREVIEW_DIR); =item parameters * directory to make * optional creating dir permissions (default is $DEFAULT_DIR_PERM) =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub make_dir ($;$) { my $dirname = shift; my $perm = shift || $DEFAULT_DIR_PERM; print_log("Creating dir $dirname, " . sprintf("%o", $perm)) if $DEBUG_ENABLED; mkdir($dirname, $perm) || return call_error_handler("Can't mkdir $dirname"); return 1; } # ---------------------------------------------------------------------------- =head2 make_path =over 4 =item description Removes all files from given directory. =item usage make_path($PUBLISH_DIR); =item parameters * path to make * optional creating dir permissions (default is $DEFAULT_DIR_PERM) =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub make_path ($;$) { my $dirname = shift; my $perm = shift || $DEFAULT_DIR_PERM; print_log("Making path $dirname, " . sprintf("%o", $perm)) if $DEBUG_ENABLED; return 1 if -d $dirname; my $parent_dir = dirname($dirname); local $DEBUG_ENABLED = 0; &make_path($parent_dir, $perm) unless -d $parent_dir; make_dir($dirname, $perm); return 1; } # ---------------------------------------------------------------------------- =head2 copy_file =over 4 =item description Copies a file to another location. =item usage copy_file($from, $to); =item parameters * file name to copy from * file name to copy to =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub copy_file ($$) { my ($src_filename, $dst_filename) = @_; print_log("Copying file $src_filename to $dst_filename") if $DEBUG_ENABLED; # Must manage symbolic links somehow # return if -l $src_filename; copy($src_filename, $dst_filename) or return call_error_handler("Can't copy $src_filename $dst_filename"); if ($PRESERVED_STAT) { my ($device, $inode, $mode) = stat($src_filename); chmod($mode, $dst_filename); } return 1; } # ---------------------------------------------------------------------------- =head2 move_file =over 4 =item description Moves (or renames) a file to another location. =item usage move_file($from, $to); =item parameters * file name to move from * file name to move to =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub move_file ($$) { my ($src_filename, $dst_filename) = @_; print_log("Moving file $src_filename to $dst_filename") if $DEBUG_ENABLED; move($src_filename, $dst_filename) or return call_error_handler("Can't move $src_filename $dst_filename"); return 1; } # ---------------------------------------------------------------------------- =head2 clean_dir =over 4 =item description Removes all files from given directory. =item usage clean_dir($PREVIEW_DIR); =item parameters * directory to clean * optional flag: 0 - don't go recursively, unlink files in first level only 1 - recursively clean subdirs (default) 2 - unlink subdirs 3 - unlink given directory =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub clean_dir ($;$) { my $dirname = shift; my $recursive = shift || 1; die("clean_dir: Unsupported flag $recursive\n") if $recursive > 3 || $recursive < 0; print_log(($recursive != 3 ? "Cleaning" : "Removing") . " dir $dirname " . ["files only", "recursively files only", "recursively", "completely"]->[$recursive]) if $DEBUG_ENABLED; local $DEBUG_ENABLED = 0; my @subdirs = (); my $filenames = list_filenames($dirname); # process files foreach (@$filenames) { next if $NEVER_REMOVE_FILES{$_}; my $filename = "$dirname/$_"; if (-d $filename) { push @subdirs, $filename; } else { unlink("$filename") || return call_error_handler("Can't unlink $filename"); } } # process subdirs map { clean_dir($_, $recursive); rmdir($_) || return call_error_handler("Can't unlink $_") if $recursive == 2; } @subdirs if $recursive; rmdir($dirname) || return call_error_handler("Can't unlink $dirname") if $recursive == 3; return 1; } # ---------------------------------------------------------------------------- =head2 remove_dir =over 4 =item description Entirely removes given directory and its content (if any). This is an alias to C<clean_dir(3)>. =item usage remove_dir($TMP_DIR); =item parameters * directory to clean =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub remove_dir ($) { my $dirname = shift; return clean_dir($dirname, 3); } # ---------------------------------------------------------------------------- =head2 copy_dir =over 4 =item description Recursively copies all files and subdirectories inside given directory to new location. Destination directory must not exist. Use: C<trap { remove_dir($dest); };> to remove it before copying. =item usage copy_dir($dir_from, $dir_to); =item parameters * source directory to copy * destination directory to copy to (may not exist) * optional creating dir permissions (default is $DEFAULT_DIR_PERM) =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub copy_dir ($$) { my ($src_dirname, $dst_dirname, $perm) = @_; return call_error_handler("Directory $src_dirname does not exist") unless -d $src_dirname; make_dir($dst_dirname, $perm) unless -d $dst_dirname; print_log("Copying dir $src_dirname to $dst_dirname recursively") if $DEBUG_ENABLED;; local $DEBUG_ENABLED = 0; my $error = 0; my @subdirs = (); my $filenames = list_filenames($src_dirname); # process files foreach (@$filenames) { next if $NEVER_COPY_FILES{$_}; my $src_filename = "$src_dirname/$_"; my $dst_filename = "$dst_dirname/$_"; if (-d $src_filename) { push @subdirs, $_; } elsif (-l $src_filename) { next if "# We ignore links for now! TO FIX!" } else { copy_file($src_filename, $dst_filename) or $error = 1; } } # process subdirs foreach (@subdirs) { my $src_subdirname = "$src_dirname/$_"; my $dst_subdirname = "$dst_dirname/$_"; ©_dir($src_subdirname, $dst_subdirname) or $error = 1; } return call_error_handler("Errors while copying some files/subdirs in $src_dirname to $dst_dirname") if $error; return 1; } # ---------------------------------------------------------------------------- =head2 move_dir =over 4 =item description Moves (or actually renames) a directory to another location. Destination directory must not exist. Use: C<trap { remove_dir($dest); };> to remove it before copying. =item usage move_dir($dir_from, $dir_to); =item parameters * source directory to move from * destination directory to move to (must not exist) =item returns C<1> on success, otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub move_dir ($$) { my ($src_dirname, $dst_dirname) = @_; print_log("Moving dir $src_dirname to $dst_dirname") if $DEBUG_ENABLED; rename($src_dirname, $dst_dirname) or return call_error_handler("Can't rename $src_dirname $dst_dirname"); return 1; } # ---------------------------------------------------------------------------- =head2 list_filenames =over 4 =item description Returns the file names in the given directory including all types of files (regular, directory, link, other), not including '.' and '..' entries. =item usage # mini file lister $dir = '/home/ftp'; foreach my $file (@{list_filenames($dir)}) { print "File $file\n" if -f "$dir/$file"; print "Dir $file\n" if -d "$dir/$file"; } =item parameters * directory to list (or array ref of directories) * optional flag, 1 means work recursively, the default is 0 =item returns Array ref of scalars (file names) on success. Otherwise either dies or warns and returns undef as configured. =back =cut # ============================================================================ sub list_filenames ($;$) { my $dirname = shift; my $recursive = shift || 0; if (ref($dirname) eq "ARRAY") { my @files = (); foreach (@$dirname) { push @files, &list_filenames($_); } return \@files; } print_log("Listing dir $dirname") if $DEBUG_ENABLED; opendir(DIR, $dirname) || return call_error_handler("Can't opendir $dirname"); my @files = grep { $_ ne '.' && $_ ne '..' } readdir(DIR); closedir(DIR) || return call_error_handler("Can't closedir $dirname"); if ($recursive) { my $i = 0; for (; $i < @files; ) { my $subdir = $files[$i]; if (-d "$dirname/$subdir") { splice(@files, $i, 1, map { "$subdir/$_" } @{&list_filenames("$dirname/$subdir")}); } else { $i++; } } } return \@files; } # ---------------------------------------------------------------------------- =head2 find_file =over 4 =item description Searches for the given file in the given directories. Returns the fully qualified file name. =item parameters * file name to search for * array ref of directories to search in =item returns File name with full path if found, or undef if not found. =back =cut # ============================================================================ sub find_file ($$) { my $filename = shift; my $dirs = shift(); die "find_file: no dirs given\n" unless ref($dirs) eq "ARRAY"; foreach (@$dirs) { my $file_path = "$_/$filename"; return $file_path if -f $file_path; } return undef; } # ---------------------------------------------------------------------------- =head2 find_executable =over 4 =item description Searches for the given executable file in the directories that are in the environmebt variable $PATH or in the additional parameter. Returns the fully qualified file name. =item usage my $gzip_exe = find_executable("gzip", ["/usr/gnu/bin", "/gnu/bin"]); =item parameters * file name to search for (only executables are tested) * optional array ref of extra directories to search in =item returns File name with full path if found, or undef if not found. =back =cut # ============================================================================ sub find_executable ($;$) { my $filename = shift; my $extra_dirs = shift; my @dirs = split(":", $ENV{"PATH"} || ""); if (ref($extra_dirs) eq "ARRAY") { push @dirs, @$extra_dirs; } foreach (@dirs) { my $file_path = "$_/$filename"; return $file_path if -x $file_path; } return undef; } # ---------------------------------------------------------------------------- =head2 default_dir_perm =over 4 =item description This functions changes default directory permissions, used in C<make_dir>, C<make_path>, C<copy_dir> and C<move_dir> functions. The default of this package is 0775. If no parameters specified, the current value is returned. =item usage default_dir_perm(0700); =item parameters * optional default directory permission (integer) =item returns Previous value. =back =cut # ============================================================================ sub default_dir_perm (;$) { return if $^O =~ /Win|DOS/; my $new_value = shift; my $old_value = $DEFAULT_DIR_PERM; if (defined $new_value) { print_log("default_dir_perm = $new_value") if $DEBUG_ENABLED; $DEFAULT_DIR_PERM = $new_value; } return $old_value; } # ---------------------------------------------------------------------------- =head2 preserve_stat =over 4 =item description This functions changes behavior of C<copy_file> and C<copy_dir> functions. If 0 is given as a parameter stats will not be preserved. TODO: specify values for diferent preserves: 0 nothing 1 mode file mode (type and permissions) 2 uid numeric user ID of file's owner 4 gid numeric group ID of file's owner 8 atime last access time since the epoch 16 mtime last modify time since the epoch 32 ctime inode change time (NOT creation time!) since the epo The default of this package is 0. If no parameters specified, nothing is set (only current value is returned). =item usage preserve_stat(1); =item parameters * optional flag (currently 0 or 1) =item returns Previous value. =back =cut # ============================================================================ sub preserve_stat (;$) { return if $^O =~ /Win|DOS/; my $new_value = shift; my $old_value = $PRESERVED_STAT; if (defined $new_value) { print_log("preserve_stat = $new_value") if $DEBUG_ENABLED; $PRESERVED_STAT = $new_value; } return $old_value; } # ---------------------------------------------------------------------------- =head2 parse_path =over 4 =item usage my ($dirname, $basename) = parse_path($filename); =item examples # in: "/data/projects/magazine" out: ("/data/projects", "magazine") # in: "/magazine" out: ("", "magazine") # in: "dir/" out: (dir", "") # in: "magazine" out: (".", "magazine") # in: "c:\projects\magazine" out: ("c:\projects", "magazine") # in: "c:\magazine" out: ("c:", "magazine") # in: "c:magazine" out: ("c:.", "magazine") =item description Returns a list of 2 scalars: directory name and base name. All unix and dos file names supported. Note, the rule is this: you can join both scalars using a directory delimiter (slash or backslash) and you will always get the the original (logical) file name. =back =cut # ============================================================================ sub parse_path ($) { my $path = shift; if ($path =~ m=^(.*)[/\\]+([^/\\]*)$=) { return ($1, $2); } else { # support even funny dos form c:file return $path =~ m=^(\w:)(.*)$= ? ($1 . ".", $2) : (".", $path); } } # ---------------------------------------------------------------------------- =head2 get_cwd =over 4 =item usage my $cwd = get_cwd(); =item description Returns the current working directory. =back =cut # ============================================================================ sub get_cwd () { $^O eq "MSWin32" ? Win32::GetCwd() : require "getcwd.pl" && getcwd(); } # ---------------------------------------------------------------------------- =head1 BUGS All global functions and constants in this package should probably be instantiated into a class object. As usual there are pros and cons. =head1 AUTHOR Mikhael Goikhman <migo@homemail.com> =cut # ============================================================================ 1; ����������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/perllib/General/Parse.pm�����������������������������������������������������������������0000644�0001757�0001757�00000012366�12673746443�014112� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2002-2009, Mikhael Goikhman # # 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 package General::Parse; use strict; use vars qw(@ISA @EXPORT); require Exporter; @ISA = qw(Exporter); @EXPORT = qw( get_token cut_token get_tokens cut_tokens eqi nei ); # currently backslashes are ignored and this is a bit buggy sub get_token ($) { my $line = shift; my $token; $line =~ s/^\s+//; my $quote = '\s'; $quote = substr($line, 0, 1) if $line =~ /^["'`]/; $line =~ s/^$quote//; if ($line =~ /^(.*?)$quote\s*(.*)$/) { $token = $1; $line = $2; } elsif ($line eq "") { $token = undef; $line = ""; } else { $token = $line; $line = ""; } return wantarray ? ($token, $line) : $token; } # returns the next quoted token, modifies the parameter (ref to line) sub cut_token ($) { my $line_ref = shift; my ($token, $rest) = get_token($$line_ref); $$line_ref = $rest; return $token; } sub cut_tokens ($$) { my $line_ref = shift; my $limit = shift; my @tokens = (); $$line_ref =~ s/^\s+//; while ($$line_ref ne "" && $limit-- > 0) { push @tokens, cut_token($line_ref); } return wantarray ? @tokens : \@tokens; } sub get_tokens ($;$) { my $line = shift; my $limit = shift || 1000; return cut_tokens(\$line, $limit); } sub eqi ($$) { my ($a, $b) = @_; return lc($a) eq lc($b); } sub nei ($$) { my ($a, $b) = @_; return lc($a) ne lc($b); } # ---------------------------------------------------------------------------- =head1 NAME General::Parse - parsing functions =head1 SYNOPSIS use General::Parse; my $string = q{Some "not very long" string of 6 tokens.}; my $token1 = cut_token(\$string); # $token1 = "Some"; my ($token2, $token3) = cut_tokens(\$string, 2); my @subtokens = get_tokens($token2); # ("not", "very", "long") my $subtoken1 = get_token($token2); # the same as $subtokens[0] my $ending_array_ref = get_tokens($string); # ["of", "6", "tokens."] =head1 DESCRIPTION This package may be used for parsing a string into tokens (quoted words). =head1 FUNCTIONS =head2 get_token =over 4 =item description Returns the first token of the given string without changing the string itself. If the string is empty or consists of only spaces the returned token is undef. If the caller expects a scalar - the token is returned. If it expects an array - 2 values returned, the token and the rest of the string. =item parameters String (scalar) to be parsed. =item returns Token (scalar). Or, in array context, array of 2 scalars: token and the rest of string. =back =head2 cut_token =over 4 =item description Returns the first token of the given string, the input string is cut to contain tokens starting from the second one. If the string is empty or consists of only spaces the returned token is undef and the string is changed to an empty string. =item parameters String (scalar) to be parsed. =item returns Token (scalar). =back =head2 get_tokens =over 4 =item description Returns all or the requested number of tokens of the given string without changing the string itself. The returned array may contain less tokens than requested if the string is too short. Particularly, the returned array is empty if the string is empty or consists of only spaces. If the caller expects a scalar - a reference to the token array is returned. If it expects an array - the token array is returned. =item parameters String (scalar) to be parsed, and optional limit (integer) for number of returned tokens. =item returns Tokens (array of scalars or array ref of scalars depending on context). =back =head2 cut_tokens =over 4 =item description Returns the requested number of tokens of the given string, the string is cut to contain the tokens starting from the first non returned token. The returned array may contain less tokens than requested if the string is too short. Particularly, the returned array is empty if the string is empty or consists of only spaces. If the caller expects a scalar - a reference to the token array is returned. If it expects an array - the token array is returned. =item parameters String (scalar) to be parsed, and limit (integer) for number of returned tokens. =item returns Tokens (array of scalars or array ref of scalars depending on context). =back =head2 eqi =over 4 =item description Similar to B<eq>, but case-insensitive, gets 2 strings, returns boolean. =back =head2 nei =over 4 =item description Similar to B<ne>, but case-insensitive, gets 2 strings, returns boolean. =back =head1 AUTHOR Mikhael Goikhman <migo@homemail.com> =cut # ============================================================================ 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/Makefile.am������������������������������������������������������������������������������0000644�0001757�0001757�00000001707�13010047777�011513� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## -*- Makefile -*- mode ## Process this file with automake to create Makefile.in ## Make sure we have a current version of automake AUTOMAKE_OPTIONS = 1.4 SUBDIRS = \ default-config \ libs \ fvwm \ modules \ bin \ utils \ $(FVWM_PERLLIB) \ doc \ docs \ $(POSUB) \ tests ## --------------------------------------------------------------------------- ## Manage bzip2 archive together with gzip archive # Usage: # make dist2 # instead of make dist # make distcheck2 # instead of make distcheck # make distclean2 # instead of make distclean DISTCHECK_CONFIGURE_FLAGS = --enable-htmldoc distcheck2: distcheck @banner="$(distdir).tar.gz - ready for distribution"; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo "$$banner"; \ echo "$$dashes" @if test "x$(ISRELEASED)" != xyes; then \ echo 'Warning: ISRELEASED is not set to "yes".'; \ echo ' So these can not be the official tarballs.'; \ exit 1; \ fi distclean2: distclean ���������������������������������������������������������fvwm-2.6.7/doc/�������������������������������������������������������������������������������������0000755�0001757�0001757�00000000000�13010103346�010260� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/header.html��������������������������������������������������������������������������0000644�0001757�0001757�00000001510�12753310630�012324� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<htmlcode> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td align="left" valign="top"><a href="http://www.fvwm.org"><img src="../images/m.logo.png" align="left" border="0"/></a></td> <td class="postheader" valign="top"> <a href="../index.html"><font class="header">Home</font></a> ⋅ <a href="../allCommands.html"><font class="header">All Commands</font></a> ⋅ <a href="../groupedCommands.html"><font class="header">Grouped Commands</font></a> ⋅ <a href="../modules.html"><font class="header">Modules</font></a> ⋅ <a href="http://www.fvwm.org/documentation/faq.html"><font class="header">FAQ</font></a> </td> <td align="right" valign="top"><a href="http://www.fvwm.org/"><img src="../images/fvwm.logo2.png" align="right" border="0"/></a></td> </tr> </tbody> </table> </htmlcode> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/�������������������������������������������������������������������������0000755�0001757�0001757�00000000000�13010103345�012475� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/docbookx.dtd�������������������������������������������������������������0000644�0001757�0001757�00000013157�12753310630�014743� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook XML DTD V4.5 ................................................. --> <!-- File docbookx.dtd .................................................... --> <!-- Copyright 1992-2006 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). See also http://docbook.org/specs/ $Id$ Permission to use, copy, modify and distribute the DocBook XML DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This is the driver file for V4.5 of the DocBook DTD. Please use the following formal public identifier to identify it: "-//OASIS//DTD DocBook XML V4.5//EN" For example, if your document's top-level element is Book, and you are using DocBook directly, use the FPI in the DOCTYPE declaration: <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [...]> Or, if you have a higher-level driver file that customizes DocBook, use the FPI in the parameter entity declaration: <!ENTITY % DocBookDTD PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> %DocBookDTD; See the documentation for detailed information on the parameter entity and module scheme used in DocBook, customizing DocBook and planning for interchange, and changes made since the last release of DocBook. --> <!-- ...................................................................... --> <!-- Enable SGML features ................................................. --> <!ENTITY % sgml.features "IGNORE"> <![%sgml.features;[ <!ENTITY % xml.features "IGNORE"> ]]> <!ENTITY % xml.features "INCLUDE"> <![%sgml.features;[ <![%xml.features;[ <!-- ERROR: Exactly one of xml.features and sgml.features must be turned on! --> <!ENTITY % dbnotn SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt"> <!ENTITY % dbcent SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt"> <!ENTITY % dbpool SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt"> <!ENTITY % dbhier SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt"> <!ENTITY % dbgenent SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt"> ]]> ]]> <![%sgml.features;[ <!ENTITY % ho "- O"> <!ENTITY % hh "- -"> ]]> <![%xml.features;[ <!ENTITY % ho ""> <!ENTITY % hh ""> ]]> <!-- ...................................................................... --> <!-- Notation declarations ................................................ --> <!ENTITY % dbnotn.module "INCLUDE"> <![%dbnotn.module;[ <!ENTITY % dbnotn PUBLIC "-//OASIS//ENTITIES DocBook Notations V4.5//EN" "dbnotnx.mod"> %dbnotn; ]]> <!-- ...................................................................... --> <!-- ISO character entity sets ............................................ --> <!ENTITY % dbcent.module "INCLUDE"> <![%dbcent.module;[ <!ENTITY % dbcent.euro "INCLUDE"> <![%dbcent.euro;[ <![%sgml.features;[ <!ENTITY euro SDATA "[euro ]"><!-- euro sign --> ]]> <![%xml.features;[ <!ENTITY euro "€"><!-- euro sign, U+20AC NEW --> ]]> ]]> <!ENTITY % dbcent PUBLIC "-//OASIS//ENTITIES DocBook Character Entities V4.5//EN" "dbcentx.mod"> %dbcent; ]]> <!-- ...................................................................... --> <!-- DTD modules .......................................................... --> <!-- Information pool .............. --> <!ENTITY % dbpool.module "INCLUDE"> <![ %dbpool.module; [ <!ENTITY % dbpool PUBLIC "-//OASIS//ELEMENTS DocBook Information Pool V4.5//EN" "dbpoolx.mod"> %dbpool; ]]> <!-- Redeclaration placeholder ..... --> <!ENTITY % intermod.redecl.module "IGNORE"> <![%intermod.redecl.module;[ <!-- Defining rdbmods here makes some buggy XML parsers happy. --> <!ENTITY % rdbmods ""> %rdbmods; <!--end of intermod.redecl.module-->]]> <!-- Document hierarchy ............ --> <!ENTITY % dbhier.module "INCLUDE"> <![ %dbhier.module; [ <!ENTITY % dbhier PUBLIC "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN" "dbhierx.mod"> %dbhier; ]]> <!-- ...................................................................... --> <!-- Other general entities ............................................... --> <!ENTITY % dbgenent.module "INCLUDE"> <![ %dbgenent.module; [ <!ENTITY % dbgenent PUBLIC "-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN" "dbgenent.mod"> %dbgenent; ]]> <!-- End of DocBook XML DTD V4.5 .......................................... --> <!-- ...................................................................... --> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/Makefile.am��������������������������������������������������������������0000644�0001757�0001757�00000000320�13010047777�014464� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = ent EXTRA_DIST = \ README \ calstblx.dtd \ catalog.xml \ dbcentx.mod \ dbgenent.mod \ dbhierx.mod \ dbnotnx.mod \ dbpoolx.mod \ docbook.cat \ docbookx.dtd \ htmltblx.mod \ soextblx.dtd ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/Makefile.in��������������������������������������������������������������0000644�0001757�0001757�00000051670�13010103322�014466� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/docbook-xml DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ SUBDIRS = ent EXTRA_DIST = \ README \ calstblx.dtd \ catalog.xml \ dbcentx.mod \ dbgenent.mod \ dbhierx.mod \ dbnotnx.mod \ dbpoolx.mod \ docbook.cat \ docbookx.dtd \ htmltblx.mod \ soextblx.dtd all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/docbook-xml/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/docbook-xml/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/soextblx.dtd�������������������������������������������������������������0000644�0001757�0001757�00000031536�12753310630�015004� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- XML EXCHANGE TABLE MODEL DECLARATION MODULE --> <!-- This set of declarations defines the XML version of the Exchange Table Model as of the date shown in the Formal Public Identifier (FPI) for this entity. This set of declarations may be referred to using a public external entity declaration and reference as shown in the following three lines: <!ENTITY % calstblx PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN"> %calstblx; If various parameter entities used within this set of declarations are to be given non-default values, the appropriate declarations should be given before calling in this package (i.e., before the "%calstblx;" reference). --> <!-- The motivation for this XML version of the Exchange Table Model is simply to create an XML version of the SGML Exchange Table Model. By design, no effort has been made to "improve" the model. This XML version incorporates the logical bare minimum changes necessary to make the Exchange Table Model a valid XML DTD. It has been modified slightly for use in the combined HTML/CALS models supported by DocBook V4.3 and later. --> <!-- The XML version of the Exchange Table Model differs from the SGML version in the following ways: The following parameter entities have been removed: - tbl.table.excep, tbl.hdft.excep, tbl.row.excep, tbl.entry.excep There are no exceptions in XML. The following normative statement is made in lieu of exceptions: the exchange table model explicitly forbids a table from occurring within another table. If the content model of an entry includes a table element, then this cannot be enforced by the DTD, but it is a deviation from the exchange table model to include a table within a table. - tbl.hdft.name, tbl.hdft.mdl, tbl.hdft.excep, tbl.hdft.att The motivation for these elements was to change the table header/footer elements. Since XML does not allow element declarations to contain name groups, and the exchange table model does not allow a table to contain footers, the continued presence of these attributes seems unnecessary. The following parameter entity has been added: - tbl.thead.att This entity parameterizes the attributes on thead. It replaces the tbl.hdft.att parameter entity. Other miscellaneous changes: - Tag ommission indicators have been removed - Comments have been removed from declarations - NUMBER attributes have been changed to NMTOKEN - NUTOKEN attributes have been to changed to NMTOKEN - Removed the grouping characters around the content model parameter entry for the 'entry' element. This is necessary so that an entry can contain #PCDATA and be defined as an optional, repeatable OR group beginning with #PCDATA. --> <!-- This entity includes a set of element and attribute declarations that partially defines the Exchange table model. However, the model is not well-defined without the accompanying natural language description of the semantics (meanings) of these various elements, attributes, and attribute values. The semantic writeup, also available from SGML Open, should be used in conjunction with this entity. --> <!-- In order to use the Exchange table model, various parameter entity declarations are required. A brief description is as follows: ENTITY NAME WHERE USED WHAT IT IS %yesorno In ATTLIST of: An attribute declared value almost all elements for a "boolean" attribute %paracon In content model of: The "text" (logical content) <entry> of the model group for <entry> %titles In content model of: The "title" part of the model table element group for the table element %tbl.table.name In declaration of: The name of the "table" table element element %tbl.table-titles.mdl In content model of: The model group for the title table elements part of the content model for table element %tbl.table.mdl In content model of: The model group for the content table elements model for table element, often (and by default) defined in terms of %tbl.table-titles.mdl and tgroup %tbl.table.att In ATTLIST of: Additional attributes on the table element table element %bodyatt In ATTLIST of: Additional attributes on the table element table element (for backward compatibility with the SGML model) %tbl.tgroup.mdl In content model of: The model group for the content <tgroup> model for <tgroup> %tbl.tgroup.att In ATTLIST of: Additional attributes on the <tgroup> <tgroup> element %tbl.thead.att In ATTLIST of: Additional attributes on the <thead> <thead> element %tbl.tbody.att In ATTLIST of: Additional attributes on the <tbody> <tbody> element %tbl.colspec.att In ATTLIST of: Additional attributes on the <colspec> <colspec> element %tbl.row.mdl In content model of: The model group for the content <row> model for <row> %tbl.row.att In ATTLIST of: Additional attributes on the <row> <row> element %tbl.entry.mdl In content model of: The model group for the content <entry> model for <entry> %tbl.entry.att In ATTLIST of: Additional attributes on the <entry> <entry> element This set of declarations will use the default definitions shown below for any of these parameter entities that are not declared before this set of declarations is referenced. --> <!-- These definitions are not directly related to the table model, but are used in the default CALS table model and may be defined elsewhere (and prior to the inclusion of this table module) in the referencing DTD. --> <!ENTITY % yesorno 'NMTOKEN'> <!-- no if zero(s), yes if any other value --> <!ENTITY % titles 'title?'> <!ENTITY % pcd "#PCDATA"> <!ENTITY % paracon '%pcd;'> <!-- default for use in entry content --> <!-- The parameter entities as defined below change and simplify the CALS table model as published (as part of the Example DTD) in MIL-HDBK-28001. The resulting simplified DTD has support from the SGML Open vendors and is therefore more interoperable among different systems. These following declarations provide the Exchange default definitions for these entities. However, these entities can be redefined (by giving the appropriate parameter entity declaration(s) prior to the reference to this Table Model declaration set entity) to fit the needs of the current application. Note, however, that changes may have significant effect on the ability to interchange table information. These changes may manifest themselves in useability, presentation, and possible structure information degradation. --> <!ENTITY % tbl.table.name "table"> <!ENTITY % tbl.table-titles.mdl "%titles;,"> <!ENTITY % tbl.table-main.mdl "tgroup+"> <!ENTITY % tbl.table.mdl "%tbl.table-titles.mdl; %tbl.table-main.mdl;"> <!ENTITY % tbl.table.att " pgwide %yesorno; #IMPLIED "> <!ENTITY % bodyatt ""> <!ENTITY % tbl.tgroup.mdl "colspec*,thead?,tbody"> <!ENTITY % tbl.tgroup.att ""> <!ENTITY % tbl.thead.att ""> <!ENTITY % tbl.tbody.att ""> <!ENTITY % tbl.colspec.att ""> <!ENTITY % tbl.row.mdl "entry+"> <!ENTITY % tbl.row.att ""> <!ENTITY % tbl.entry.mdl "(%paracon;)*"> <!ENTITY % tbl.entry.att ""> <!ENTITY % tbl.frame.attval "top|bottom|topbot|all|sides|none"> <!ENTITY % tbl.tbody.mdl "row+"> <!-- ===== Element and attribute declarations follow. ===== --> <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % tbl.table.name "table" ENTITY % tbl.table-titles.mdl "%titles;," ENTITY % tbl.table.mdl "%tbl.table-titles; tgroup+" ENTITY % tbl.table.att " pgwide %yesorno; #IMPLIED " --> <!--doc:???--> <!ELEMENT %tbl.table.name; (%tbl.table.mdl;)> <!ATTLIST %tbl.table.name; frame (%tbl.frame.attval;) #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED %tbl.table.att; %bodyatt; > <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % tbl.tgroup.mdl "colspec*,thead?,tbody" ENTITY % tbl.tgroup.att "" --> <!--doc:A wrapper for the main content of a table, or part of a table.--> <!ELEMENT tgroup (%tbl.tgroup.mdl;) > <!ATTLIST tgroup cols NMTOKEN #REQUIRED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED %tbl.tgroup.att; > <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % tbl.colspec.att "" --> <!--doc:Specifications for a column in a table.--> <!ELEMENT colspec EMPTY > <!ATTLIST colspec colnum NMTOKEN #IMPLIED colname NMTOKEN #IMPLIED colwidth CDATA #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff NMTOKEN #IMPLIED %tbl.colspec.att; > <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % tbl.thead.att "" --> <!--doc:A table header consisting of one or more rows.--> <!ELEMENT thead (row+)> <!ATTLIST thead valign (top|middle|bottom) #IMPLIED %tbl.thead.att; > <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % tbl.tbody.att "" --> <!--doc:A wrapper for the rows of a table or informal table.--> <!ELEMENT tbody (%tbl.tbody.mdl;)> <!ATTLIST tbody valign (top|middle|bottom) #IMPLIED %tbl.tbody.att; > <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % tbl.row.mdl "entry+" ENTITY % tbl.row.att "" --> <!--doc:A row in a table.--> <!ELEMENT row (%tbl.row.mdl;)> <!ATTLIST row rowsep %yesorno; #IMPLIED valign (top|middle|bottom) #IMPLIED %tbl.row.att; > <!-- Default declarations previously defined in this entity and referenced below include: ENTITY % paracon "#PCDATA" ENTITY % tbl.entry.mdl "(%paracon;)*" ENTITY % tbl.entry.att "" --> <!--doc:A cell in a table.--> <!ELEMENT entry (%tbl.entry.mdl;)*> <!ATTLIST entry colname NMTOKEN #IMPLIED namest NMTOKEN #IMPLIED nameend NMTOKEN #IMPLIED morerows NMTOKEN #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff NMTOKEN #IMPLIED valign (top|middle|bottom) #IMPLIED %tbl.entry.att; > ������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/dbgenent.mod�������������������������������������������������������������0000644�0001757�0001757�00000003035�12753310630�014717� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook additional general entities V4.5 ............................. --> <!-- Copyright 1992-2004 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). In DTD driver files referring to this module, please use an entity declaration that uses the public identifier shown below: <!ENTITY % dbgenent PUBLIC "-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN" "dbgenent.mod"> %dbgenent; --> <!-- File dbgenent.mod .................................................... --> <!-- You can edit this file to add the following: o General entity declarations of any kind. For example: <!ENTITY productname "WinWidget"> (small boilerplate) <!ENTITY legal-notice SYSTEM "notice.sgm"> (large boilerplate) o Notation declarations. For example: <!NOTATION chicken-scratch SYSTEM> o Declarations for and references to external parameter entities containing collections of any of the above. For example: <!ENTITY % all-titles PUBLIC "-//DocTools//ELEMENTS Book Titles//EN" "booktitles.ent"> %all-titles; --> <!-- End of DocBook additional general entities V4.5 ...................... --> <!-- ...................................................................... --> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/calstblx.dtd�������������������������������������������������������������0000644�0001757�0001757�00000021646�12753310630�014751� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook CALS Table Model V4.5 ........................................ --> <!-- File calstblx.mod .................................................... --> <!-- Copyright 1992-2002 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). This DTD is based on the CALS Table Model PUBLIC "-//USA-DOD//DTD Table Model 951010//EN" $Id$ Permission to use, copy, modify and distribute the DocBook DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This module contains the definitions for the CALS Table Model converted to XML. It has been modified slightly for use in the combined HTML/CALS models supported by DocBook V4.5. --> <!-- These definitions are not directly related to the table model, but are used in the default CALS table model and are usually defined elsewhere (and prior to the inclusion of this table module) in a CALS DTD. --> <!ENTITY % bodyatt ""> <!ENTITY % secur ""> <!-- no if zero(s), yes if any other digits value --> <!ENTITY % yesorno 'CDATA'> <!ENTITY % titles 'title?'> <!-- default for use in entry content --> <!ENTITY % paracon '#PCDATA'> <!-- The parameter entities as defined below provide the CALS table model as published (as part of the Example DTD) in MIL-HDBK-28001. These following declarations provide the CALS-compliant default definitions for these entities. However, these entities can and should be redefined (by giving the appropriate parameter entity declaration(s) prior to the reference to this Table Model declaration set entity) to fit the needs of the current application. --> <!ENTITY % tbl.table.name "(table|chart)"> <!ENTITY % tbl.table-titles.mdl "%titles;,"> <!ENTITY % tbl.table-main.mdl "(tgroup+|graphic+)"> <!ENTITY % tbl.table.mdl "%tbl.table-titles.mdl; %tbl.table-main.mdl;"> <!ENTITY % tbl.table.att ' tabstyle CDATA #IMPLIED tocentry %yesorno; #IMPLIED shortentry %yesorno; #IMPLIED orient (port|land) #IMPLIED pgwide %yesorno; #IMPLIED '> <!ENTITY % tbl.tgroup.mdl "colspec*,spanspec*,thead?,tfoot?,tbody"> <!ENTITY % tbl.tgroup.att ' tgroupstyle CDATA #IMPLIED '> <!ENTITY % tbl.hdft.mdl "colspec*,row+"> <!ENTITY % tbl.row.mdl "(entry|entrytbl)+"> <!ENTITY % tbl.entrytbl.mdl "colspec*,spanspec*,thead?,tbody"> <!ENTITY % tbl.entry.mdl "(para|warning|caution|note|legend|%paracon;)*"> <!ENTITY % tbl.frame.attval "top|bottom|topbot|all|sides|none"> <!ENTITY % tbl.tbody.mdl "row+"> <!-- ===== Element and attribute declarations follow. ===== --> <!--doc:A formal table in a document.--> <!ELEMENT table %ho; (%tbl.table.mdl;)> <!ATTLIST table frame (%tbl.frame.attval;) #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED %tbl.table.att; %bodyatt; %secur; > <!--doc:A wrapper for the main content of a table, or part of a table.--> <!ELEMENT tgroup %ho; (%tbl.tgroup.mdl;) > <!ATTLIST tgroup cols CDATA #REQUIRED %tbl.tgroup.att; colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff CDATA #IMPLIED %secur; > <!--doc:Specifications for a column in a table.--> <!ELEMENT colspec %ho; EMPTY > <!ATTLIST colspec colnum CDATA #IMPLIED colname CDATA #IMPLIED colwidth CDATA #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff CDATA #IMPLIED > <!--doc:Formatting information for a spanned column in a table.--> <!ELEMENT spanspec %ho; EMPTY > <!ATTLIST spanspec namest CDATA #REQUIRED nameend CDATA #REQUIRED spanname CDATA #REQUIRED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff CDATA #IMPLIED > <!--doc:A table header consisting of one or more rows.--> <!ELEMENT thead %ho; (%tbl.hdft.mdl;)> <!ATTLIST thead valign (top|middle|bottom) #IMPLIED %secur; > <!--doc:A table footer consisting of one or more rows.--> <!ELEMENT tfoot %ho; (%tbl.hdft.mdl;)> <!ATTLIST tfoot valign (top|middle|bottom) #IMPLIED %secur; > <!--doc:A wrapper for the rows of a table or informal table.--> <!ELEMENT tbody %ho; (%tbl.tbody.mdl;)> <!ATTLIST tbody valign (top|middle|bottom) #IMPLIED %secur; > <!--doc:A row in a table.--> <!ELEMENT row %ho; (%tbl.row.mdl;)> <!ATTLIST row rowsep %yesorno; #IMPLIED valign (top|middle|bottom) #IMPLIED %secur; > <!--doc:A subtable appearing in place of an Entry in a table.--> <!ELEMENT entrytbl %ho; (%tbl.entrytbl.mdl;)> <!ATTLIST entrytbl cols CDATA #REQUIRED %tbl.tgroup.att; colname CDATA #IMPLIED spanname CDATA #IMPLIED namest CDATA #IMPLIED nameend CDATA #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff CDATA #IMPLIED %secur; > <!--doc:A cell in a table.--> <!ELEMENT entry %ho; (%tbl.entry.mdl;)*> <!ATTLIST entry colname CDATA #IMPLIED namest CDATA #IMPLIED nameend CDATA #IMPLIED spanname CDATA #IMPLIED morerows CDATA #IMPLIED colsep %yesorno; #IMPLIED rowsep %yesorno; #IMPLIED align (left|right|center|justify|char) #IMPLIED char CDATA #IMPLIED charoff CDATA #IMPLIED rotate %yesorno; #IMPLIED valign (top|middle|bottom) #IMPLIED %secur; > <!-- End of DocBook CALS Table Model V4.5 ................................. --> <!-- ...................................................................... --> ������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/dbhierx.mod��������������������������������������������������������������0000644�0001757�0001757�00000174227�12753310630�014572� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook document hierarchy module V4.5 ............................... --> <!-- File dbhierx.mod ..................................................... --> <!-- Copyright 1992-2004 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). $Id$ Permission to use, copy, modify and distribute the DocBook DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This module contains the definitions for the overall document hierarchies of DocBook documents. It covers computer documentation manuals and manual fragments, as well as reference entries (such as man pages) and technical journals or anthologies containing articles. This module depends on the DocBook information pool module. All elements and entities referenced but not defined here are assumed to be defined in the information pool module. In DTD driver files referring to this module, please use an entity declaration that uses the public identifier shown below: <!ENTITY % dbhier PUBLIC "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN" "dbhierx.mod"> %dbhier; See the documentation for detailed information on the parameter entity and module scheme used in DocBook, customizing DocBook and planning for interchange, and changes made since the last release of DocBook. --> <!-- ...................................................................... --> <!-- Entities for module inclusions ....................................... --> <!ENTITY % dbhier.redecl.module "IGNORE"> <!ENTITY % dbhier.redecl2.module "IGNORE"> <!-- ...................................................................... --> <!-- Entities for element classes ......................................... --> <!ENTITY % local.appendix.class ""> <!ENTITY % appendix.class "appendix %local.appendix.class;"> <!ENTITY % local.article.class ""> <!ENTITY % article.class "article %local.article.class;"> <!ENTITY % local.book.class ""> <!ENTITY % book.class "book %local.book.class;"> <!ENTITY % local.chapter.class ""> <!ENTITY % chapter.class "chapter %local.chapter.class;"> <!ENTITY % local.index.class ""> <!ENTITY % index.class "index|setindex %local.index.class;"> <!ENTITY % local.refentry.class ""> <!ENTITY % refentry.class "refentry %local.refentry.class;"> <!ENTITY % local.section.class ""> <!ENTITY % section.class "section %local.section.class;"> <!ENTITY % local.nav.class ""> <!ENTITY % nav.class "toc|lot|index|glossary|bibliography %local.nav.class;"> <!-- Redeclaration placeholder ............................................ --> <!-- For redeclaring entities that are declared after this point while retaining their references to the entities that are declared before this point --> <![%dbhier.redecl.module;[ <!-- Defining rdbhier here makes some buggy XML parsers happy. --> <!ENTITY % rdbhier ""> %rdbhier; <!--end of dbhier.redecl.module-->]]> <!-- ...................................................................... --> <!-- Entities for element mixtures ........................................ --> <!ENTITY % local.divcomponent.mix ""> <!ENTITY % divcomponent.mix "%list.class; |%admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |%compound.class; |%genobj.class; |%descobj.class; |%ndxterm.class; |beginpage %forms.hook; %local.divcomponent.mix;"> <!ENTITY % local.refcomponent.mix ""> <!ENTITY % refcomponent.mix "%list.class; |%admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |%compound.class; |%genobj.class; |%descobj.class; |%ndxterm.class; |beginpage %forms.hook; %local.refcomponent.mix;"> <!ENTITY % local.indexdivcomponent.mix ""> <!ENTITY % indexdivcomponent.mix "itemizedlist|orderedlist|variablelist|simplelist |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |anchor|remark |%link.char.class; |beginpage %local.indexdivcomponent.mix;"> <!ENTITY % local.refname.char.mix ""> <!ENTITY % refname.char.mix "#PCDATA |%tech.char.class; %local.refname.char.mix;"> <!ENTITY % local.partcontent.mix ""> <!ENTITY % partcontent.mix "%appendix.class;|%chapter.class;|%nav.class;|%article.class; |preface|%refentry.class;|reference %local.partcontent.mix;"> <!ENTITY % local.refinline.char.mix ""> <!ENTITY % refinline.char.mix "#PCDATA |%xref.char.class; |%gen.char.class; |%link.char.class; |%tech.char.class; |%base.char.class; |%docinfo.char.class; |%other.char.class; |%ndxterm.class; |beginpage %local.refinline.char.mix;"> <!ENTITY % local.refclass.char.mix ""> <!ENTITY % refclass.char.mix "#PCDATA |application %local.refclass.char.mix;"> <!-- Redeclaration placeholder 2 .......................................... --> <!-- For redeclaring entities that are declared after this point while retaining their references to the entities that are declared before this point --> <![%dbhier.redecl2.module;[ <!-- Defining rdbhier2 here makes some buggy XML parsers happy. --> <!ENTITY % rdbhier2 ""> %rdbhier2; <!--end of dbhier.redecl2.module-->]]> <!-- ...................................................................... --> <!-- Entities for content models .......................................... --> <!ENTITY % div.title.content "title, subtitle?, titleabbrev?"> <!ENTITY % bookcomponent.title.content "title, subtitle?, titleabbrev?"> <!ENTITY % sect.title.content "title, subtitle?, titleabbrev?"> <!ENTITY % refsect.title.content "title, subtitle?, titleabbrev?"> <!ENTITY % bookcomponent.content "((%divcomponent.mix;)+, (sect1*|(%refentry.class;)*|simplesect*|(%section.class;)*)) | (sect1+|(%refentry.class;)+|simplesect+|(%section.class;)+)"> <!-- ...................................................................... --> <!-- Set and SetInfo ...................................................... --> <!ENTITY % set.content.module "INCLUDE"> <![%set.content.module;[ <!ENTITY % set.module "INCLUDE"> <![%set.module;[ <!ENTITY % local.set.attrib ""> <!ENTITY % set.role.attrib "%role.attrib;"> <!ENTITY % set.element "INCLUDE"> <![%set.element;[ <!--doc:A collection of books.--> <!ELEMENT set %ho; ((%div.title.content;)?, setinfo?, toc?, (set|%book.class;)+, setindex?) %ubiq.inclusion;> <!--end of set.element-->]]> <!-- FPI: SGML formal public identifier --> <!ENTITY % set.attlist "INCLUDE"> <![%set.attlist;[ <!ATTLIST set fpi CDATA #IMPLIED %status.attrib; %common.attrib; %set.role.attrib; %local.set.attrib; > <!--end of set.attlist-->]]> <!--end of set.module-->]]> <!ENTITY % setinfo.module "INCLUDE"> <![%setinfo.module;[ <!ENTITY % local.setinfo.attrib ""> <!ENTITY % setinfo.role.attrib "%role.attrib;"> <!ENTITY % setinfo.element "INCLUDE"> <![%setinfo.element;[ <!--doc:Meta-information for a Set.--> <!ELEMENT setinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of setinfo.element-->]]> <!-- Contents: IDs of the ToC, Books, and SetIndex that comprise the set, in the order of their appearance --> <!ENTITY % setinfo.attlist "INCLUDE"> <![%setinfo.attlist;[ <!ATTLIST setinfo contents IDREFS #IMPLIED %common.attrib; %setinfo.role.attrib; %local.setinfo.attrib; > <!--end of setinfo.attlist-->]]> <!--end of setinfo.module-->]]> <!--end of set.content.module-->]]> <!-- ...................................................................... --> <!-- Book and BookInfo .................................................... --> <!ENTITY % book.content.module "INCLUDE"> <![%book.content.module;[ <!ENTITY % book.module "INCLUDE"> <![%book.module;[ <!ENTITY % local.book.attrib ""> <!ENTITY % book.role.attrib "%role.attrib;"> <!ENTITY % book.element "INCLUDE"> <![%book.element;[ <!--doc:A book.--> <!ELEMENT book %ho; ((%div.title.content;)?, bookinfo?, (dedication | toc | lot | glossary | bibliography | preface | %chapter.class; | reference | part | %article.class; | %appendix.class; | %index.class; | colophon)*) %ubiq.inclusion;> <!--end of book.element-->]]> <!-- FPI: SGML formal public identifier --> <!ENTITY % book.attlist "INCLUDE"> <![%book.attlist;[ <!ATTLIST book fpi CDATA #IMPLIED %label.attrib; %status.attrib; %common.attrib; %book.role.attrib; %local.book.attrib; > <!--end of book.attlist-->]]> <!--end of book.module-->]]> <!ENTITY % bookinfo.module "INCLUDE"> <![%bookinfo.module;[ <!ENTITY % local.bookinfo.attrib ""> <!ENTITY % bookinfo.role.attrib "%role.attrib;"> <!ENTITY % bookinfo.element "INCLUDE"> <![%bookinfo.element;[ <!--doc:Meta-information for a Book.--> <!ELEMENT bookinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of bookinfo.element-->]]> <!-- Contents: IDs of the ToC, LoTs, Prefaces, Parts, Chapters, Appendixes, References, GLossary, Bibliography, and indexes comprising the Book, in the order of their appearance --> <!ENTITY % bookinfo.attlist "INCLUDE"> <![%bookinfo.attlist;[ <!ATTLIST bookinfo contents IDREFS #IMPLIED %common.attrib; %bookinfo.role.attrib; %local.bookinfo.attrib; > <!--end of bookinfo.attlist-->]]> <!--end of bookinfo.module-->]]> <!--end of book.content.module-->]]> <!-- ...................................................................... --> <!-- Dedication, ToC, and LoT ............................................. --> <!ENTITY % dedication.module "INCLUDE"> <![%dedication.module;[ <!ENTITY % local.dedication.attrib ""> <!ENTITY % dedication.role.attrib "%role.attrib;"> <!ENTITY % dedication.element "INCLUDE"> <![%dedication.element;[ <!--doc:A wrapper for the dedication section of a book.--> <!ELEMENT dedication %ho; ((%sect.title.content;)?, (%legalnotice.mix;)+)> <!--end of dedication.element-->]]> <!ENTITY % dedication.attlist "INCLUDE"> <![%dedication.attlist;[ <!ATTLIST dedication %status.attrib; %common.attrib; %dedication.role.attrib; %local.dedication.attrib; > <!--end of dedication.attlist-->]]> <!--end of dedication.module-->]]> <!ENTITY % colophon.module "INCLUDE"> <![ %colophon.module; [ <!ENTITY % local.colophon.attrib ""> <!ENTITY % colophon.role.attrib "%role.attrib;"> <!ENTITY % colophon.element "INCLUDE"> <![ %colophon.element; [ <!--doc:Text at the back of a book describing facts about its production.--> <!ELEMENT colophon %ho; ((%sect.title.content;)?, (%textobject.mix;)+)> <!--end of colophon.element-->]]> <!ENTITY % colophon.attlist "INCLUDE"> <![ %colophon.attlist; [ <!ATTLIST colophon %status.attrib; %common.attrib; %colophon.role.attrib; %local.colophon.attrib;> <!--end of colophon.attlist-->]]> <!--end of colophon.module-->]]> <!ENTITY % toc.content.module "INCLUDE"> <![%toc.content.module;[ <!ENTITY % toc.module "INCLUDE"> <![%toc.module;[ <!ENTITY % local.toc.attrib ""> <!ENTITY % toc.role.attrib "%role.attrib;"> <!ENTITY % toc.element "INCLUDE"> <![%toc.element;[ <!--doc:A table of contents.--> <!ELEMENT toc %ho; (beginpage?, (%bookcomponent.title.content;)?, tocfront*, (tocpart | tocchap)*, tocback*)> <!--end of toc.element-->]]> <!ENTITY % toc.attlist "INCLUDE"> <![%toc.attlist;[ <!ATTLIST toc %pagenum.attrib; %common.attrib; %toc.role.attrib; %local.toc.attrib; > <!--end of toc.attlist-->]]> <!--end of toc.module-->]]> <!ENTITY % tocfront.module "INCLUDE"> <![%tocfront.module;[ <!ENTITY % local.tocfront.attrib ""> <!ENTITY % tocfront.role.attrib "%role.attrib;"> <!ENTITY % tocfront.element "INCLUDE"> <![%tocfront.element;[ <!--doc:An entry in a table of contents for a front matter component.--> <!ELEMENT tocfront %ho; (%para.char.mix;)*> <!--end of tocfront.element-->]]> <!-- to element that this entry represents --> <!ENTITY % tocfront.attlist "INCLUDE"> <![%tocfront.attlist;[ <!ATTLIST tocfront %label.attrib; %linkend.attrib; %pagenum.attrib; %common.attrib; %tocfront.role.attrib; %local.tocfront.attrib; > <!--end of tocfront.attlist-->]]> <!--end of tocfront.module-->]]> <!ENTITY % tocentry.module "INCLUDE"> <![%tocentry.module;[ <!ENTITY % local.tocentry.attrib ""> <!ENTITY % tocentry.role.attrib "%role.attrib;"> <!ENTITY % tocentry.element "INCLUDE"> <![%tocentry.element;[ <!--doc:A component title in a table of contents.--> <!ELEMENT tocentry %ho; (%para.char.mix;)*> <!--end of tocentry.element-->]]> <!-- to element that this entry represents --> <!ENTITY % tocentry.attlist "INCLUDE"> <![%tocentry.attlist;[ <!ATTLIST tocentry %linkend.attrib; %pagenum.attrib; %common.attrib; %tocentry.role.attrib; %local.tocentry.attrib; > <!--end of tocentry.attlist-->]]> <!--end of tocentry.module-->]]> <!ENTITY % tocpart.module "INCLUDE"> <![%tocpart.module;[ <!ENTITY % local.tocpart.attrib ""> <!ENTITY % tocpart.role.attrib "%role.attrib;"> <!ENTITY % tocpart.element "INCLUDE"> <![%tocpart.element;[ <!--doc:An entry in a table of contents for a part of a book.--> <!ELEMENT tocpart %ho; (tocentry+, tocchap*)> <!--end of tocpart.element-->]]> <!ENTITY % tocpart.attlist "INCLUDE"> <![%tocpart.attlist;[ <!ATTLIST tocpart %common.attrib; %tocpart.role.attrib; %local.tocpart.attrib; > <!--end of tocpart.attlist-->]]> <!--end of tocpart.module-->]]> <!ENTITY % tocchap.module "INCLUDE"> <![%tocchap.module;[ <!ENTITY % local.tocchap.attrib ""> <!ENTITY % tocchap.role.attrib "%role.attrib;"> <!ENTITY % tocchap.element "INCLUDE"> <![%tocchap.element;[ <!--doc:An entry in a table of contents for a component in the body of a document.--> <!ELEMENT tocchap %ho; (tocentry+, toclevel1*)> <!--end of tocchap.element-->]]> <!ENTITY % tocchap.attlist "INCLUDE"> <![%tocchap.attlist;[ <!ATTLIST tocchap %label.attrib; %common.attrib; %tocchap.role.attrib; %local.tocchap.attrib; > <!--end of tocchap.attlist-->]]> <!--end of tocchap.module-->]]> <!ENTITY % toclevel1.module "INCLUDE"> <![%toclevel1.module;[ <!ENTITY % local.toclevel1.attrib ""> <!ENTITY % toclevel1.role.attrib "%role.attrib;"> <!ENTITY % toclevel1.element "INCLUDE"> <![%toclevel1.element;[ <!--doc:A top-level entry within a table of contents entry for a chapter-like component.--> <!ELEMENT toclevel1 %ho; (tocentry+, toclevel2*)> <!--end of toclevel1.element-->]]> <!ENTITY % toclevel1.attlist "INCLUDE"> <![%toclevel1.attlist;[ <!ATTLIST toclevel1 %common.attrib; %toclevel1.role.attrib; %local.toclevel1.attrib; > <!--end of toclevel1.attlist-->]]> <!--end of toclevel1.module-->]]> <!ENTITY % toclevel2.module "INCLUDE"> <![%toclevel2.module;[ <!ENTITY % local.toclevel2.attrib ""> <!ENTITY % toclevel2.role.attrib "%role.attrib;"> <!ENTITY % toclevel2.element "INCLUDE"> <![%toclevel2.element;[ <!--doc:A second-level entry within a table of contents entry for a chapter-like component.--> <!ELEMENT toclevel2 %ho; (tocentry+, toclevel3*)> <!--end of toclevel2.element-->]]> <!ENTITY % toclevel2.attlist "INCLUDE"> <![%toclevel2.attlist;[ <!ATTLIST toclevel2 %common.attrib; %toclevel2.role.attrib; %local.toclevel2.attrib; > <!--end of toclevel2.attlist-->]]> <!--end of toclevel2.module-->]]> <!ENTITY % toclevel3.module "INCLUDE"> <![%toclevel3.module;[ <!ENTITY % local.toclevel3.attrib ""> <!ENTITY % toclevel3.role.attrib "%role.attrib;"> <!ENTITY % toclevel3.element "INCLUDE"> <![%toclevel3.element;[ <!--doc:A third-level entry within a table of contents entry for a chapter-like component.--> <!ELEMENT toclevel3 %ho; (tocentry+, toclevel4*)> <!--end of toclevel3.element-->]]> <!ENTITY % toclevel3.attlist "INCLUDE"> <![%toclevel3.attlist;[ <!ATTLIST toclevel3 %common.attrib; %toclevel3.role.attrib; %local.toclevel3.attrib; > <!--end of toclevel3.attlist-->]]> <!--end of toclevel3.module-->]]> <!ENTITY % toclevel4.module "INCLUDE"> <![%toclevel4.module;[ <!ENTITY % local.toclevel4.attrib ""> <!ENTITY % toclevel4.role.attrib "%role.attrib;"> <!ENTITY % toclevel4.element "INCLUDE"> <![%toclevel4.element;[ <!--doc:A fourth-level entry within a table of contents entry for a chapter-like component.--> <!ELEMENT toclevel4 %ho; (tocentry+, toclevel5*)> <!--end of toclevel4.element-->]]> <!ENTITY % toclevel4.attlist "INCLUDE"> <![%toclevel4.attlist;[ <!ATTLIST toclevel4 %common.attrib; %toclevel4.role.attrib; %local.toclevel4.attrib; > <!--end of toclevel4.attlist-->]]> <!--end of toclevel4.module-->]]> <!ENTITY % toclevel5.module "INCLUDE"> <![%toclevel5.module;[ <!ENTITY % local.toclevel5.attrib ""> <!ENTITY % toclevel5.role.attrib "%role.attrib;"> <!ENTITY % toclevel5.element "INCLUDE"> <![%toclevel5.element;[ <!--doc:A fifth-level entry within a table of contents entry for a chapter-like component.--> <!ELEMENT toclevel5 %ho; (tocentry+)> <!--end of toclevel5.element-->]]> <!ENTITY % toclevel5.attlist "INCLUDE"> <![%toclevel5.attlist;[ <!ATTLIST toclevel5 %common.attrib; %toclevel5.role.attrib; %local.toclevel5.attrib; > <!--end of toclevel5.attlist-->]]> <!--end of toclevel5.module-->]]> <!ENTITY % tocback.module "INCLUDE"> <![%tocback.module;[ <!ENTITY % local.tocback.attrib ""> <!ENTITY % tocback.role.attrib "%role.attrib;"> <!ENTITY % tocback.element "INCLUDE"> <![%tocback.element;[ <!--doc:An entry in a table of contents for a back matter component.--> <!ELEMENT tocback %ho; (%para.char.mix;)*> <!--end of tocback.element-->]]> <!-- to element that this entry represents --> <!ENTITY % tocback.attlist "INCLUDE"> <![%tocback.attlist;[ <!ATTLIST tocback %label.attrib; %linkend.attrib; %pagenum.attrib; %common.attrib; %tocback.role.attrib; %local.tocback.attrib; > <!--end of tocback.attlist-->]]> <!--end of tocback.module-->]]> <!--end of toc.content.module-->]]> <!ENTITY % lot.content.module "INCLUDE"> <![%lot.content.module;[ <!ENTITY % lot.module "INCLUDE"> <![%lot.module;[ <!ENTITY % local.lot.attrib ""> <!ENTITY % lot.role.attrib "%role.attrib;"> <!ENTITY % lot.element "INCLUDE"> <![%lot.element;[ <!--doc:A list of the titles of formal objects (as tables or figures) in a document.--> <!ELEMENT lot %ho; (beginpage?, (%bookcomponent.title.content;)?, lotentry*)> <!--end of lot.element-->]]> <!ENTITY % lot.attlist "INCLUDE"> <![%lot.attlist;[ <!ATTLIST lot %label.attrib; %common.attrib; %lot.role.attrib; %local.lot.attrib; > <!--end of lot.attlist-->]]> <!--end of lot.module-->]]> <!ENTITY % lotentry.module "INCLUDE"> <![%lotentry.module;[ <!ENTITY % local.lotentry.attrib ""> <!ENTITY % lotentry.role.attrib "%role.attrib;"> <!ENTITY % lotentry.element "INCLUDE"> <![%lotentry.element;[ <!--doc:An entry in a list of titles.--> <!ELEMENT lotentry %ho; (%para.char.mix;)*> <!--end of lotentry.element-->]]> <!-- SrcCredit: Information about the source of the entry, as for a list of illustrations --> <!-- linkend: to element that this entry represents--> <!ENTITY % lotentry.attlist "INCLUDE"> <![%lotentry.attlist;[ <!ATTLIST lotentry %linkend.attrib; %pagenum.attrib; srccredit CDATA #IMPLIED %common.attrib; %lotentry.role.attrib; %local.lotentry.attrib; > <!--end of lotentry.attlist-->]]> <!--end of lotentry.module-->]]> <!--end of lot.content.module-->]]> <!-- ...................................................................... --> <!-- Appendix, Chapter, Part, Preface, Reference, PartIntro ............... --> <!ENTITY % appendix.module "INCLUDE"> <![%appendix.module;[ <!ENTITY % local.appendix.attrib ""> <!ENTITY % appendix.role.attrib "%role.attrib;"> <!ENTITY % appendix.element "INCLUDE"> <![%appendix.element;[ <!--doc:An appendix in a Book or Article.--> <!ELEMENT appendix %ho; (beginpage?, appendixinfo?, (%bookcomponent.title.content;), (%nav.class;)*, tocchap?, (%bookcomponent.content;), (%nav.class;)*) %ubiq.inclusion;> <!--end of appendix.element-->]]> <!ENTITY % appendix.attlist "INCLUDE"> <![%appendix.attlist;[ <!ATTLIST appendix %label.attrib; %status.attrib; %common.attrib; %appendix.role.attrib; %local.appendix.attrib; > <!--end of appendix.attlist-->]]> <!--end of appendix.module-->]]> <!ENTITY % chapter.module "INCLUDE"> <![%chapter.module;[ <!ENTITY % local.chapter.attrib ""> <!ENTITY % chapter.role.attrib "%role.attrib;"> <!ENTITY % chapter.element "INCLUDE"> <![%chapter.element;[ <!--doc:A chapter, as of a book.--> <!ELEMENT chapter %ho; (beginpage?, chapterinfo?, (%bookcomponent.title.content;), (%nav.class;)*, tocchap?, (%bookcomponent.content;), (%nav.class;)*) %ubiq.inclusion;> <!--end of chapter.element-->]]> <!ENTITY % chapter.attlist "INCLUDE"> <![%chapter.attlist;[ <!ATTLIST chapter %label.attrib; %status.attrib; %common.attrib; %chapter.role.attrib; %local.chapter.attrib; > <!--end of chapter.attlist-->]]> <!--end of chapter.module-->]]> <!ENTITY % part.module "INCLUDE"> <![%part.module;[ <!-- Note that Part was to have its content model reduced in V4.5. This change will not be made after all. --> <!ENTITY % local.part.attrib ""> <!ENTITY % part.role.attrib "%role.attrib;"> <!ENTITY % part.element "INCLUDE"> <![%part.element;[ <!--doc:A division in a book.--> <!ELEMENT part %ho; (beginpage?, partinfo?, (%bookcomponent.title.content;), partintro?, (%partcontent.mix;)+) %ubiq.inclusion;> <!--end of part.element-->]]> <!ENTITY % part.attlist "INCLUDE"> <![%part.attlist;[ <!ATTLIST part %label.attrib; %status.attrib; %common.attrib; %part.role.attrib; %local.part.attrib; > <!--end of part.attlist-->]]> <!--ELEMENT PartIntro (defined below)--> <!--end of part.module-->]]> <!ENTITY % preface.module "INCLUDE"> <![%preface.module;[ <!ENTITY % local.preface.attrib ""> <!ENTITY % preface.role.attrib "%role.attrib;"> <!ENTITY % preface.element "INCLUDE"> <![%preface.element;[ <!--doc:Introductory matter preceding the first chapter of a book.--> <!ELEMENT preface %ho; (beginpage?, prefaceinfo?, (%bookcomponent.title.content;), (%nav.class;)*, tocchap?, (%bookcomponent.content;), (%nav.class;)*) %ubiq.inclusion;> <!--end of preface.element-->]]> <!ENTITY % preface.attlist "INCLUDE"> <![%preface.attlist;[ <!ATTLIST preface %status.attrib; %common.attrib; %preface.role.attrib; %local.preface.attrib; > <!--end of preface.attlist-->]]> <!--end of preface.module-->]]> <!ENTITY % reference.module "INCLUDE"> <![%reference.module;[ <!ENTITY % local.reference.attrib ""> <!ENTITY % reference.role.attrib "%role.attrib;"> <!ENTITY % reference.element "INCLUDE"> <![%reference.element;[ <!--doc:A collection of reference entries.--> <!ELEMENT reference %ho; (beginpage?, referenceinfo?, (%bookcomponent.title.content;), partintro?, (%refentry.class;)+) %ubiq.inclusion;> <!--end of reference.element-->]]> <!ENTITY % reference.attlist "INCLUDE"> <![%reference.attlist;[ <!ATTLIST reference %label.attrib; %status.attrib; %common.attrib; %reference.role.attrib; %local.reference.attrib; > <!--end of reference.attlist-->]]> <!--ELEMENT PartIntro (defined below)--> <!--end of reference.module-->]]> <!ENTITY % partintro.module "INCLUDE"> <![%partintro.module;[ <!ENTITY % local.partintro.attrib ""> <!ENTITY % partintro.role.attrib "%role.attrib;"> <!ENTITY % partintro.element "INCLUDE"> <![%partintro.element;[ <!--doc:An introduction to the contents of a part.--> <!ELEMENT partintro %ho; ((%div.title.content;)?, (%bookcomponent.content;)) %ubiq.inclusion;> <!--end of partintro.element-->]]> <!ENTITY % partintro.attlist "INCLUDE"> <![%partintro.attlist;[ <!ATTLIST partintro %label.attrib; %common.attrib; %partintro.role.attrib; %local.partintro.attrib; > <!--end of partintro.attlist-->]]> <!--end of partintro.module-->]]> <!-- ...................................................................... --> <!-- Other Info elements .................................................. --> <!ENTITY % appendixinfo.module "INCLUDE"> <![ %appendixinfo.module; [ <!ENTITY % local.appendixinfo.attrib ""> <!ENTITY % appendixinfo.role.attrib "%role.attrib;"> <!ENTITY % appendixinfo.element "INCLUDE"> <![ %appendixinfo.element; [ <!--doc:Meta-information for an Appendix.--> <!ELEMENT appendixinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of appendixinfo.element-->]]> <!ENTITY % appendixinfo.attlist "INCLUDE"> <![ %appendixinfo.attlist; [ <!ATTLIST appendixinfo %common.attrib; %appendixinfo.role.attrib; %local.appendixinfo.attrib; > <!--end of appendixinfo.attlist-->]]> <!--end of appendixinfo.module-->]]> <!ENTITY % bibliographyinfo.module "INCLUDE"> <![ %bibliographyinfo.module; [ <!ENTITY % local.bibliographyinfo.attrib ""> <!ENTITY % bibliographyinfo.role.attrib "%role.attrib;"> <!ENTITY % bibliographyinfo.element "INCLUDE"> <![ %bibliographyinfo.element; [ <!--doc:Meta-information for a Bibliography.--> <!ELEMENT bibliographyinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of bibliographyinfo.element-->]]> <!ENTITY % bibliographyinfo.attlist "INCLUDE"> <![ %bibliographyinfo.attlist; [ <!ATTLIST bibliographyinfo %common.attrib; %bibliographyinfo.role.attrib; %local.bibliographyinfo.attrib; > <!--end of bibliographyinfo.attlist-->]]> <!--end of bibliographyinfo.module-->]]> <!ENTITY % chapterinfo.module "INCLUDE"> <![ %chapterinfo.module; [ <!ENTITY % local.chapterinfo.attrib ""> <!ENTITY % chapterinfo.role.attrib "%role.attrib;"> <!ENTITY % chapterinfo.element "INCLUDE"> <![ %chapterinfo.element; [ <!--doc:Meta-information for a Chapter.--> <!ELEMENT chapterinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of chapterinfo.element-->]]> <!ENTITY % chapterinfo.attlist "INCLUDE"> <![ %chapterinfo.attlist; [ <!ATTLIST chapterinfo %common.attrib; %chapterinfo.role.attrib; %local.chapterinfo.attrib; > <!--end of chapterinfo.attlist-->]]> <!--end of chapterinfo.module-->]]> <!ENTITY % glossaryinfo.module "INCLUDE"> <![ %glossaryinfo.module; [ <!ENTITY % local.glossaryinfo.attrib ""> <!ENTITY % glossaryinfo.role.attrib "%role.attrib;"> <!ENTITY % glossaryinfo.element "INCLUDE"> <![ %glossaryinfo.element; [ <!--doc:Meta-information for a Glossary.--> <!ELEMENT glossaryinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of glossaryinfo.element-->]]> <!ENTITY % glossaryinfo.attlist "INCLUDE"> <![ %glossaryinfo.attlist; [ <!ATTLIST glossaryinfo %common.attrib; %glossaryinfo.role.attrib; %local.glossaryinfo.attrib; > <!--end of glossaryinfo.attlist-->]]> <!--end of glossaryinfo.module-->]]> <!ENTITY % indexinfo.module "INCLUDE"> <![ %indexinfo.module; [ <!ENTITY % local.indexinfo.attrib ""> <!ENTITY % indexinfo.role.attrib "%role.attrib;"> <!ENTITY % indexinfo.element "INCLUDE"> <![ %indexinfo.element; [ <!--doc:Meta-information for an Index.--> <!ELEMENT indexinfo %ho; ((%info.class;)+)> <!--end of indexinfo.element-->]]> <!ENTITY % indexinfo.attlist "INCLUDE"> <![ %indexinfo.attlist; [ <!ATTLIST indexinfo %common.attrib; %indexinfo.role.attrib; %local.indexinfo.attrib; > <!--end of indexinfo.attlist-->]]> <!--end of indexinfo.module-->]]> <!ENTITY % setindexinfo.module "INCLUDE"> <![ %setindexinfo.module; [ <!ENTITY % local.setindexinfo.attrib ""> <!ENTITY % setindexinfo.role.attrib "%role.attrib;"> <!ENTITY % setindexinfo.element "INCLUDE"> <![ %setindexinfo.element; [ <!--doc:Meta-information for a SetIndex.--> <!ELEMENT setindexinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of setindexinfo.element-->]]> <!ENTITY % setindexinfo.attlist "INCLUDE"> <![ %setindexinfo.attlist; [ <!ATTLIST setindexinfo %common.attrib; %setindexinfo.role.attrib; %local.setindexinfo.attrib; > <!--end of setindexinfo.attlist-->]]> <!--end of setindexinfo.module-->]]> <!ENTITY % partinfo.module "INCLUDE"> <![ %partinfo.module; [ <!ENTITY % local.partinfo.attrib ""> <!ENTITY % partinfo.role.attrib "%role.attrib;"> <!ENTITY % partinfo.element "INCLUDE"> <![ %partinfo.element; [ <!--doc:Meta-information for a Part.--> <!ELEMENT partinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of partinfo.element-->]]> <!ENTITY % partinfo.attlist "INCLUDE"> <![ %partinfo.attlist; [ <!ATTLIST partinfo %common.attrib; %partinfo.role.attrib; %local.partinfo.attrib; > <!--end of partinfo.attlist-->]]> <!--end of partinfo.module-->]]> <!ENTITY % prefaceinfo.module "INCLUDE"> <![ %prefaceinfo.module; [ <!ENTITY % local.prefaceinfo.attrib ""> <!ENTITY % prefaceinfo.role.attrib "%role.attrib;"> <!ENTITY % prefaceinfo.element "INCLUDE"> <![ %prefaceinfo.element; [ <!--doc:Meta-information for a Preface.--> <!ELEMENT prefaceinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of prefaceinfo.element-->]]> <!ENTITY % prefaceinfo.attlist "INCLUDE"> <![ %prefaceinfo.attlist; [ <!ATTLIST prefaceinfo %common.attrib; %prefaceinfo.role.attrib; %local.prefaceinfo.attrib; > <!--end of prefaceinfo.attlist-->]]> <!--end of prefaceinfo.module-->]]> <!ENTITY % refentryinfo.module "INCLUDE"> <![ %refentryinfo.module; [ <!ENTITY % local.refentryinfo.attrib ""> <!ENTITY % refentryinfo.role.attrib "%role.attrib;"> <!ENTITY % refentryinfo.element "INCLUDE"> <![ %refentryinfo.element; [ <!--doc:Meta-information for a Refentry.--> <!ELEMENT refentryinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of refentryinfo.element-->]]> <!ENTITY % refentryinfo.attlist "INCLUDE"> <![ %refentryinfo.attlist; [ <!ATTLIST refentryinfo %common.attrib; %refentryinfo.role.attrib; %local.refentryinfo.attrib; > <!--end of refentryinfo.attlist-->]]> <!--end of refentryinfo.module-->]]> <!ENTITY % refsectioninfo.module "INCLUDE"> <![ %refsectioninfo.module; [ <!ENTITY % local.refsectioninfo.attrib ""> <!ENTITY % refsectioninfo.role.attrib "%role.attrib;"> <!ENTITY % refsectioninfo.element "INCLUDE"> <![ %refsectioninfo.element; [ <!--doc:Meta-information for a refsection.--> <!ELEMENT refsectioninfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of refsectioninfo.element-->]]> <!ENTITY % refsectioninfo.attlist "INCLUDE"> <![ %refsectioninfo.attlist; [ <!ATTLIST refsectioninfo %common.attrib; %refsectioninfo.role.attrib; %local.refsectioninfo.attrib; > <!--end of refsectioninfo.attlist-->]]> <!--end of refsectioninfo.module-->]]> <!ENTITY % refsect1info.module "INCLUDE"> <![ %refsect1info.module; [ <!ENTITY % local.refsect1info.attrib ""> <!ENTITY % refsect1info.role.attrib "%role.attrib;"> <!ENTITY % refsect1info.element "INCLUDE"> <![ %refsect1info.element; [ <!--doc:Meta-information for a RefSect1.--> <!ELEMENT refsect1info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of refsect1info.element-->]]> <!ENTITY % refsect1info.attlist "INCLUDE"> <![ %refsect1info.attlist; [ <!ATTLIST refsect1info %common.attrib; %refsect1info.role.attrib; %local.refsect1info.attrib; > <!--end of refsect1info.attlist-->]]> <!--end of refsect1info.module-->]]> <!ENTITY % refsect2info.module "INCLUDE"> <![ %refsect2info.module; [ <!ENTITY % local.refsect2info.attrib ""> <!ENTITY % refsect2info.role.attrib "%role.attrib;"> <!ENTITY % refsect2info.element "INCLUDE"> <![ %refsect2info.element; [ <!--doc:Meta-information for a RefSect2.--> <!ELEMENT refsect2info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of refsect2info.element-->]]> <!ENTITY % refsect2info.attlist "INCLUDE"> <![ %refsect2info.attlist; [ <!ATTLIST refsect2info %common.attrib; %refsect2info.role.attrib; %local.refsect2info.attrib; > <!--end of refsect2info.attlist-->]]> <!--end of refsect2info.module-->]]> <!ENTITY % refsect3info.module "INCLUDE"> <![ %refsect3info.module; [ <!ENTITY % local.refsect3info.attrib ""> <!ENTITY % refsect3info.role.attrib "%role.attrib;"> <!ENTITY % refsect3info.element "INCLUDE"> <![ %refsect3info.element; [ <!--doc:Meta-information for a RefSect3.--> <!ELEMENT refsect3info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of refsect3info.element-->]]> <!ENTITY % refsect3info.attlist "INCLUDE"> <![ %refsect3info.attlist; [ <!ATTLIST refsect3info %common.attrib; %refsect3info.role.attrib; %local.refsect3info.attrib; > <!--end of refsect3info.attlist-->]]> <!--end of refsect3info.module-->]]> <!ENTITY % refsynopsisdivinfo.module "INCLUDE"> <![ %refsynopsisdivinfo.module; [ <!ENTITY % local.refsynopsisdivinfo.attrib ""> <!ENTITY % refsynopsisdivinfo.role.attrib "%role.attrib;"> <!ENTITY % refsynopsisdivinfo.element "INCLUDE"> <![ %refsynopsisdivinfo.element; [ <!--doc:Meta-information for a RefSynopsisDiv.--> <!ELEMENT refsynopsisdivinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of refsynopsisdivinfo.element-->]]> <!ENTITY % refsynopsisdivinfo.attlist "INCLUDE"> <![ %refsynopsisdivinfo.attlist; [ <!ATTLIST refsynopsisdivinfo %common.attrib; %refsynopsisdivinfo.role.attrib; %local.refsynopsisdivinfo.attrib; > <!--end of refsynopsisdivinfo.attlist-->]]> <!--end of refsynopsisdivinfo.module-->]]> <!ENTITY % referenceinfo.module "INCLUDE"> <![ %referenceinfo.module; [ <!ENTITY % local.referenceinfo.attrib ""> <!ENTITY % referenceinfo.role.attrib "%role.attrib;"> <!ENTITY % referenceinfo.element "INCLUDE"> <![ %referenceinfo.element; [ <!--doc:Meta-information for a Reference.--> <!ELEMENT referenceinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of referenceinfo.element-->]]> <!ENTITY % referenceinfo.attlist "INCLUDE"> <![ %referenceinfo.attlist; [ <!ATTLIST referenceinfo %common.attrib; %referenceinfo.role.attrib; %local.referenceinfo.attrib; > <!--end of referenceinfo.attlist-->]]> <!--end of referenceinfo.module-->]]> <!ENTITY % local.sect1info.attrib ""> <!ENTITY % sect1info.role.attrib "%role.attrib;"> <!ENTITY % sect1info.element "INCLUDE"> <![%sect1info.element;[ <!--doc:Meta-information for a Sect1.--> <!ELEMENT sect1info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sect1info.element-->]]> <!ENTITY % sect1info.attlist "INCLUDE"> <![%sect1info.attlist;[ <!ATTLIST sect1info %common.attrib; %sect1info.role.attrib; %local.sect1info.attrib; > <!--end of sect1info.attlist-->]]> <!ENTITY % local.sect2info.attrib ""> <!ENTITY % sect2info.role.attrib "%role.attrib;"> <!ENTITY % sect2info.element "INCLUDE"> <![%sect2info.element;[ <!--doc:Meta-information for a Sect2.--> <!ELEMENT sect2info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sect2info.element-->]]> <!ENTITY % sect2info.attlist "INCLUDE"> <![%sect2info.attlist;[ <!ATTLIST sect2info %common.attrib; %sect2info.role.attrib; %local.sect2info.attrib; > <!--end of sect2info.attlist-->]]> <!ENTITY % local.sect3info.attrib ""> <!ENTITY % sect3info.role.attrib "%role.attrib;"> <!ENTITY % sect3info.element "INCLUDE"> <![%sect3info.element;[ <!--doc:Meta-information for a Sect3.--> <!ELEMENT sect3info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sect3info.element-->]]> <!ENTITY % sect3info.attlist "INCLUDE"> <![%sect3info.attlist;[ <!ATTLIST sect3info %common.attrib; %sect3info.role.attrib; %local.sect3info.attrib; > <!--end of sect3info.attlist-->]]> <!ENTITY % local.sect4info.attrib ""> <!ENTITY % sect4info.role.attrib "%role.attrib;"> <!ENTITY % sect4info.element "INCLUDE"> <![%sect4info.element;[ <!--doc:Meta-information for a Sect4.--> <!ELEMENT sect4info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sect4info.element-->]]> <!ENTITY % sect4info.attlist "INCLUDE"> <![%sect4info.attlist;[ <!ATTLIST sect4info %common.attrib; %sect4info.role.attrib; %local.sect4info.attrib; > <!--end of sect4info.attlist-->]]> <!ENTITY % local.sect5info.attrib ""> <!ENTITY % sect5info.role.attrib "%role.attrib;"> <!ENTITY % sect5info.element "INCLUDE"> <![%sect5info.element;[ <!--doc:Meta-information for a Sect5.--> <!ELEMENT sect5info %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sect5info.element-->]]> <!ENTITY % sect5info.attlist "INCLUDE"> <![%sect5info.attlist;[ <!ATTLIST sect5info %common.attrib; %sect5info.role.attrib; %local.sect5info.attrib; > <!--end of sect5info.attlist-->]]> <!-- ...................................................................... --> <!-- Section (parallel to Sect*) ......................................... --> <!ENTITY % section.content.module "INCLUDE"> <![ %section.content.module; [ <!ENTITY % section.module "INCLUDE"> <![ %section.module; [ <!ENTITY % local.section.attrib ""> <!ENTITY % section.role.attrib "%role.attrib;"> <!ENTITY % section.element "INCLUDE"> <![ %section.element; [ <!--doc:A recursive section.--> <!ELEMENT section %ho; (sectioninfo?, (%sect.title.content;), (%nav.class;)*, (((%divcomponent.mix;)+, ((%refentry.class;)*|(%section.class;)*|simplesect*)) | (%refentry.class;)+|(%section.class;)+|simplesect+), (%nav.class;)*) %ubiq.inclusion;> <!--end of section.element-->]]> <!ENTITY % section.attlist "INCLUDE"> <![ %section.attlist; [ <!ATTLIST section %label.attrib; %status.attrib; %common.attrib; %section.role.attrib; %local.section.attrib; > <!--end of section.attlist-->]]> <!--end of section.module-->]]> <!ENTITY % sectioninfo.module "INCLUDE"> <![ %sectioninfo.module; [ <!ENTITY % sectioninfo.role.attrib "%role.attrib;"> <!ENTITY % local.sectioninfo.attrib ""> <!ENTITY % sectioninfo.element "INCLUDE"> <![ %sectioninfo.element; [ <!--doc:Meta-information for a recursive section.--> <!ELEMENT sectioninfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sectioninfo.element-->]]> <!ENTITY % sectioninfo.attlist "INCLUDE"> <![ %sectioninfo.attlist; [ <!ATTLIST sectioninfo %common.attrib; %sectioninfo.role.attrib; %local.sectioninfo.attrib; > <!--end of sectioninfo.attlist-->]]> <!--end of sectioninfo.module-->]]> <!--end of section.content.module-->]]> <!-- ...................................................................... --> <!-- Sect1, Sect2, Sect3, Sect4, Sect5 .................................... --> <!ENTITY % sect1.module "INCLUDE"> <![%sect1.module;[ <!ENTITY % local.sect1.attrib ""> <!ENTITY % sect1.role.attrib "%role.attrib;"> <!ENTITY % sect1.element "INCLUDE"> <![%sect1.element;[ <!--doc:A top-level section of document.--> <!ELEMENT sect1 %ho; (sect1info?, (%sect.title.content;), (%nav.class;)*, (((%divcomponent.mix;)+, ((%refentry.class;)* | sect2* | simplesect*)) | (%refentry.class;)+ | sect2+ | simplesect+), (%nav.class;)*) %ubiq.inclusion;> <!--end of sect1.element-->]]> <!-- Renderas: Indicates the format in which the heading should appear --> <!ENTITY % sect1.attlist "INCLUDE"> <![%sect1.attlist;[ <!ATTLIST sect1 renderas (sect2 |sect3 |sect4 |sect5) #IMPLIED %label.attrib; %status.attrib; %common.attrib; %sect1.role.attrib; %local.sect1.attrib; > <!--end of sect1.attlist-->]]> <!--end of sect1.module-->]]> <!ENTITY % sect2.module "INCLUDE"> <![%sect2.module;[ <!ENTITY % local.sect2.attrib ""> <!ENTITY % sect2.role.attrib "%role.attrib;"> <!ENTITY % sect2.element "INCLUDE"> <![%sect2.element;[ <!--doc:A subsection within a Sect1.--> <!ELEMENT sect2 %ho; (sect2info?, (%sect.title.content;), (%nav.class;)*, (((%divcomponent.mix;)+, ((%refentry.class;)* | sect3* | simplesect*)) | (%refentry.class;)+ | sect3+ | simplesect+), (%nav.class;)*)> <!--end of sect2.element-->]]> <!-- Renderas: Indicates the format in which the heading should appear --> <!ENTITY % sect2.attlist "INCLUDE"> <![%sect2.attlist;[ <!ATTLIST sect2 renderas (sect1 |sect3 |sect4 |sect5) #IMPLIED %label.attrib; %status.attrib; %common.attrib; %sect2.role.attrib; %local.sect2.attrib; > <!--end of sect2.attlist-->]]> <!--end of sect2.module-->]]> <!ENTITY % sect3.module "INCLUDE"> <![%sect3.module;[ <!ENTITY % local.sect3.attrib ""> <!ENTITY % sect3.role.attrib "%role.attrib;"> <!ENTITY % sect3.element "INCLUDE"> <![%sect3.element;[ <!--doc:A subsection within a Sect2.--> <!ELEMENT sect3 %ho; (sect3info?, (%sect.title.content;), (%nav.class;)*, (((%divcomponent.mix;)+, ((%refentry.class;)* | sect4* | simplesect*)) | (%refentry.class;)+ | sect4+ | simplesect+), (%nav.class;)*)> <!--end of sect3.element-->]]> <!-- Renderas: Indicates the format in which the heading should appear --> <!ENTITY % sect3.attlist "INCLUDE"> <![%sect3.attlist;[ <!ATTLIST sect3 renderas (sect1 |sect2 |sect4 |sect5) #IMPLIED %label.attrib; %status.attrib; %common.attrib; %sect3.role.attrib; %local.sect3.attrib; > <!--end of sect3.attlist-->]]> <!--end of sect3.module-->]]> <!ENTITY % sect4.module "INCLUDE"> <![%sect4.module;[ <!ENTITY % local.sect4.attrib ""> <!ENTITY % sect4.role.attrib "%role.attrib;"> <!ENTITY % sect4.element "INCLUDE"> <![%sect4.element;[ <!--doc:A subsection within a Sect3.--> <!ELEMENT sect4 %ho; (sect4info?, (%sect.title.content;), (%nav.class;)*, (((%divcomponent.mix;)+, ((%refentry.class;)* | sect5* | simplesect*)) | (%refentry.class;)+ | sect5+ | simplesect+), (%nav.class;)*)> <!--end of sect4.element-->]]> <!-- Renderas: Indicates the format in which the heading should appear --> <!ENTITY % sect4.attlist "INCLUDE"> <![%sect4.attlist;[ <!ATTLIST sect4 renderas (sect1 |sect2 |sect3 |sect5) #IMPLIED %label.attrib; %status.attrib; %common.attrib; %sect4.role.attrib; %local.sect4.attrib; > <!--end of sect4.attlist-->]]> <!--end of sect4.module-->]]> <!ENTITY % sect5.module "INCLUDE"> <![%sect5.module;[ <!ENTITY % local.sect5.attrib ""> <!ENTITY % sect5.role.attrib "%role.attrib;"> <!ENTITY % sect5.element "INCLUDE"> <![%sect5.element;[ <!--doc:A subsection within a Sect4.--> <!ELEMENT sect5 %ho; (sect5info?, (%sect.title.content;), (%nav.class;)*, (((%divcomponent.mix;)+, ((%refentry.class;)* | simplesect*)) | (%refentry.class;)+ | simplesect+), (%nav.class;)*)> <!--end of sect5.element-->]]> <!-- Renderas: Indicates the format in which the heading should appear --> <!ENTITY % sect5.attlist "INCLUDE"> <![%sect5.attlist;[ <!ATTLIST sect5 renderas (sect1 |sect2 |sect3 |sect4) #IMPLIED %label.attrib; %status.attrib; %common.attrib; %sect5.role.attrib; %local.sect5.attrib; > <!--end of sect5.attlist-->]]> <!--end of sect5.module-->]]> <!ENTITY % simplesect.module "INCLUDE"> <![%simplesect.module;[ <!ENTITY % local.simplesect.attrib ""> <!ENTITY % simplesect.role.attrib "%role.attrib;"> <!ENTITY % simplesect.element "INCLUDE"> <![%simplesect.element;[ <!--doc:A section of a document with no subdivisions.--> <!ELEMENT simplesect %ho; ((%sect.title.content;), (%divcomponent.mix;)+) %ubiq.inclusion;> <!--end of simplesect.element-->]]> <!ENTITY % simplesect.attlist "INCLUDE"> <![%simplesect.attlist;[ <!ATTLIST simplesect %common.attrib; %simplesect.role.attrib; %local.simplesect.attrib; > <!--end of simplesect.attlist-->]]> <!--end of simplesect.module-->]]> <!-- ...................................................................... --> <!-- Bibliography ......................................................... --> <!ENTITY % bibliography.content.module "INCLUDE"> <![%bibliography.content.module;[ <!ENTITY % bibliography.module "INCLUDE"> <![%bibliography.module;[ <!ENTITY % local.bibliography.attrib ""> <!ENTITY % bibliography.role.attrib "%role.attrib;"> <!ENTITY % bibliography.element "INCLUDE"> <![%bibliography.element;[ <!--doc:A bibliography.--> <!ELEMENT bibliography %ho; (bibliographyinfo?, (%bookcomponent.title.content;)?, (%component.mix;)*, (bibliodiv+ | (biblioentry|bibliomixed)+))> <!--end of bibliography.element-->]]> <!ENTITY % bibliography.attlist "INCLUDE"> <![%bibliography.attlist;[ <!ATTLIST bibliography %status.attrib; %common.attrib; %bibliography.role.attrib; %local.bibliography.attrib; > <!--end of bibliography.attlist-->]]> <!--end of bibliography.module-->]]> <!ENTITY % bibliodiv.module "INCLUDE"> <![%bibliodiv.module;[ <!ENTITY % local.bibliodiv.attrib ""> <!ENTITY % bibliodiv.role.attrib "%role.attrib;"> <!ENTITY % bibliodiv.element "INCLUDE"> <![%bibliodiv.element;[ <!--doc:A section of a Bibliography.--> <!ELEMENT bibliodiv %ho; ((%sect.title.content;)?, (%component.mix;)*, (biblioentry|bibliomixed)+)> <!--end of bibliodiv.element-->]]> <!ENTITY % bibliodiv.attlist "INCLUDE"> <![%bibliodiv.attlist;[ <!ATTLIST bibliodiv %status.attrib; %common.attrib; %bibliodiv.role.attrib; %local.bibliodiv.attrib; > <!--end of bibliodiv.attlist-->]]> <!--end of bibliodiv.module-->]]> <!--end of bibliography.content.module-->]]> <!-- ...................................................................... --> <!-- Glossary ............................................................. --> <!ENTITY % glossary.content.module "INCLUDE"> <![%glossary.content.module;[ <!ENTITY % glossary.module "INCLUDE"> <![%glossary.module;[ <!ENTITY % local.glossary.attrib ""> <!ENTITY % glossary.role.attrib "%role.attrib;"> <!ENTITY % glossary.element "INCLUDE"> <![%glossary.element;[ <!--doc:A glossary.--> <!ELEMENT glossary %ho; (glossaryinfo?, (%bookcomponent.title.content;)?, (%component.mix;)*, (glossdiv+ | glossentry+), bibliography?)> <!--end of glossary.element-->]]> <!ENTITY % glossary.attlist "INCLUDE"> <![%glossary.attlist;[ <!ATTLIST glossary %status.attrib; %common.attrib; %glossary.role.attrib; %local.glossary.attrib; > <!--end of glossary.attlist-->]]> <!--end of glossary.module-->]]> <!ENTITY % glossdiv.module "INCLUDE"> <![%glossdiv.module;[ <!ENTITY % local.glossdiv.attrib ""> <!ENTITY % glossdiv.role.attrib "%role.attrib;"> <!ENTITY % glossdiv.element "INCLUDE"> <![%glossdiv.element;[ <!--doc:A division in a Glossary.--> <!ELEMENT glossdiv %ho; ((%sect.title.content;), (%component.mix;)*, glossentry+)> <!--end of glossdiv.element-->]]> <!ENTITY % glossdiv.attlist "INCLUDE"> <![%glossdiv.attlist;[ <!ATTLIST glossdiv %status.attrib; %common.attrib; %glossdiv.role.attrib; %local.glossdiv.attrib; > <!--end of glossdiv.attlist-->]]> <!--end of glossdiv.module-->]]> <!--end of glossary.content.module-->]]> <!-- ...................................................................... --> <!-- Index and SetIndex ................................................... --> <!ENTITY % index.content.module "INCLUDE"> <![%index.content.module;[ <!ENTITY % indexes.module "INCLUDE"> <![%indexes.module;[ <!ENTITY % local.indexes.attrib ""> <!ENTITY % indexes.role.attrib "%role.attrib;"> <!ENTITY % index.element "INCLUDE"> <![%index.element;[ <!--doc:An index.--> <!ELEMENT index %ho; (indexinfo?, (%bookcomponent.title.content;)?, (%component.mix;)*, (indexdiv* | indexentry*)) %ndxterm.exclusion;> <!--end of index.element-->]]> <!ENTITY % index.attlist "INCLUDE"> <![%index.attlist;[ <!ATTLIST index type CDATA #IMPLIED %common.attrib; %indexes.role.attrib; %local.indexes.attrib; > <!--end of index.attlist-->]]> <!ENTITY % setindex.element "INCLUDE"> <![%setindex.element;[ <!--doc:An index to a set of books.--> <!ELEMENT setindex %ho; (setindexinfo?, (%bookcomponent.title.content;)?, (%component.mix;)*, (indexdiv* | indexentry*)) %ndxterm.exclusion;> <!--end of setindex.element-->]]> <!ENTITY % setindex.attlist "INCLUDE"> <![%setindex.attlist;[ <!ATTLIST setindex %common.attrib; %indexes.role.attrib; %local.indexes.attrib; > <!--end of setindex.attlist-->]]> <!--end of indexes.module-->]]> <!ENTITY % indexdiv.module "INCLUDE"> <![%indexdiv.module;[ <!-- SegmentedList in this content is useful for marking up permuted indices. --> <!ENTITY % local.indexdiv.attrib ""> <!ENTITY % indexdiv.role.attrib "%role.attrib;"> <!ENTITY % indexdiv.element "INCLUDE"> <![%indexdiv.element;[ <!--doc:A division in an index.--> <!ELEMENT indexdiv %ho; ((%sect.title.content;)?, ((%indexdivcomponent.mix;)*, (indexentry+ | segmentedlist)))> <!--end of indexdiv.element-->]]> <!ENTITY % indexdiv.attlist "INCLUDE"> <![%indexdiv.attlist;[ <!ATTLIST indexdiv %common.attrib; %indexdiv.role.attrib; %local.indexdiv.attrib; > <!--end of indexdiv.attlist-->]]> <!--end of indexdiv.module-->]]> <!ENTITY % indexentry.module "INCLUDE"> <![%indexentry.module;[ <!-- Index entries appear in the index, not the text. --> <!ENTITY % local.indexentry.attrib ""> <!ENTITY % indexentry.role.attrib "%role.attrib;"> <!ENTITY % indexentry.element "INCLUDE"> <![%indexentry.element;[ <!--doc:An entry in an index.--> <!ELEMENT indexentry %ho; (primaryie, (seeie|seealsoie)*, (secondaryie, (seeie|seealsoie|tertiaryie)*)*)> <!--end of indexentry.element-->]]> <!ENTITY % indexentry.attlist "INCLUDE"> <![%indexentry.attlist;[ <!ATTLIST indexentry %common.attrib; %indexentry.role.attrib; %local.indexentry.attrib; > <!--end of indexentry.attlist-->]]> <!--end of indexentry.module-->]]> <!ENTITY % primsecterie.module "INCLUDE"> <![%primsecterie.module;[ <!ENTITY % local.primsecterie.attrib ""> <!ENTITY % primsecterie.role.attrib "%role.attrib;"> <!ENTITY % primaryie.element "INCLUDE"> <![%primaryie.element;[ <!--doc:A primary term in an index entry, not in the text.--> <!ELEMENT primaryie %ho; (%ndxterm.char.mix;)*> <!--end of primaryie.element-->]]> <!-- to IndexTerms that these entries represent --> <!ENTITY % primaryie.attlist "INCLUDE"> <![%primaryie.attlist;[ <!ATTLIST primaryie %linkends.attrib; %common.attrib; %primsecterie.role.attrib; %local.primsecterie.attrib; > <!--end of primaryie.attlist-->]]> <!ENTITY % secondaryie.element "INCLUDE"> <![%secondaryie.element;[ <!--doc:A secondary term in an index entry, rather than in the text.--> <!ELEMENT secondaryie %ho; (%ndxterm.char.mix;)*> <!--end of secondaryie.element-->]]> <!-- to IndexTerms that these entries represent --> <!ENTITY % secondaryie.attlist "INCLUDE"> <![%secondaryie.attlist;[ <!ATTLIST secondaryie %linkends.attrib; %common.attrib; %primsecterie.role.attrib; %local.primsecterie.attrib; > <!--end of secondaryie.attlist-->]]> <!ENTITY % tertiaryie.element "INCLUDE"> <![%tertiaryie.element;[ <!--doc:A tertiary term in an index entry, rather than in the text.--> <!ELEMENT tertiaryie %ho; (%ndxterm.char.mix;)*> <!--end of tertiaryie.element-->]]> <!-- to IndexTerms that these entries represent --> <!ENTITY % tertiaryie.attlist "INCLUDE"> <![%tertiaryie.attlist;[ <!ATTLIST tertiaryie %linkends.attrib; %common.attrib; %primsecterie.role.attrib; %local.primsecterie.attrib; > <!--end of tertiaryie.attlist-->]]> <!--end of primsecterie.module-->]]> <!ENTITY % seeie.module "INCLUDE"> <![%seeie.module;[ <!ENTITY % local.seeie.attrib ""> <!ENTITY % seeie.role.attrib "%role.attrib;"> <!ENTITY % seeie.element "INCLUDE"> <![%seeie.element;[ <!--doc:A See entry in an index, rather than in the text.--> <!ELEMENT seeie %ho; (%ndxterm.char.mix;)*> <!--end of seeie.element-->]]> <!-- to IndexEntry to look up --> <!ENTITY % seeie.attlist "INCLUDE"> <![%seeie.attlist;[ <!ATTLIST seeie %linkend.attrib; %common.attrib; %seeie.role.attrib; %local.seeie.attrib; > <!--end of seeie.attlist-->]]> <!--end of seeie.module-->]]> <!ENTITY % seealsoie.module "INCLUDE"> <![%seealsoie.module;[ <!ENTITY % local.seealsoie.attrib ""> <!ENTITY % seealsoie.role.attrib "%role.attrib;"> <!ENTITY % seealsoie.element "INCLUDE"> <![%seealsoie.element;[ <!--doc:A See also entry in an index, rather than in the text.--> <!ELEMENT seealsoie %ho; (%ndxterm.char.mix;)*> <!--end of seealsoie.element-->]]> <!-- to related IndexEntries --> <!ENTITY % seealsoie.attlist "INCLUDE"> <![%seealsoie.attlist;[ <!ATTLIST seealsoie %linkends.attrib; %common.attrib; %seealsoie.role.attrib; %local.seealsoie.attrib; > <!--end of seealsoie.attlist-->]]> <!--end of seealsoie.module-->]]> <!--end of index.content.module-->]]> <!-- ...................................................................... --> <!-- RefEntry ............................................................. --> <!ENTITY % refentry.content.module "INCLUDE"> <![%refentry.content.module;[ <!ENTITY % refentry.module "INCLUDE"> <![%refentry.module;[ <!ENTITY % local.refentry.attrib ""> <!ENTITY % refentry.role.attrib "%role.attrib;"> <!ENTITY % refentry.element "INCLUDE"> <![%refentry.element;[ <!--doc:A reference page (originally a UNIX man-style reference page).--> <!ELEMENT refentry %ho; (beginpage?, (%ndxterm.class;)*, refentryinfo?, refmeta?, (remark|%link.char.class;)*, refnamediv+, refsynopsisdiv?, (refsect1+|refsection+)) %ubiq.inclusion;> <!--end of refentry.element-->]]> <!ENTITY % refentry.attlist "INCLUDE"> <![%refentry.attlist;[ <!ATTLIST refentry %status.attrib; %common.attrib; %refentry.role.attrib; %local.refentry.attrib; > <!--end of refentry.attlist-->]]> <!--end of refentry.module-->]]> <!ENTITY % refmeta.module "INCLUDE"> <![%refmeta.module;[ <!ENTITY % local.refmeta.attrib ""> <!ENTITY % refmeta.role.attrib "%role.attrib;"> <!ENTITY % refmeta.element "INCLUDE"> <![%refmeta.element;[ <!--doc:Meta-information for a reference entry.--> <!ELEMENT refmeta %ho; ((%ndxterm.class;)*, refentrytitle, manvolnum?, refmiscinfo*, (%ndxterm.class;)*) %beginpage.exclusion;> <!--end of refmeta.element-->]]> <!ENTITY % refmeta.attlist "INCLUDE"> <![%refmeta.attlist;[ <!ATTLIST refmeta %common.attrib; %refmeta.role.attrib; %local.refmeta.attrib; > <!--end of refmeta.attlist-->]]> <!--end of refmeta.module-->]]> <!ENTITY % refmiscinfo.module "INCLUDE"> <![%refmiscinfo.module;[ <!ENTITY % local.refmiscinfo.attrib ""> <!ENTITY % refmiscinfo.role.attrib "%role.attrib;"> <!ENTITY % refmiscinfo.element "INCLUDE"> <![%refmiscinfo.element;[ <!--doc:Meta-information for a reference entry other than the title and volume number.--> <!ELEMENT refmiscinfo %ho; (%docinfo.char.mix;)*> <!--end of refmiscinfo.element-->]]> <!-- Class: Freely assignable parameter; no default --> <!ENTITY % refmiscinfo.attlist "INCLUDE"> <![%refmiscinfo.attlist;[ <!ATTLIST refmiscinfo class CDATA #IMPLIED %common.attrib; %refmiscinfo.role.attrib; %local.refmiscinfo.attrib; > <!--end of refmiscinfo.attlist-->]]> <!--end of refmiscinfo.module-->]]> <!ENTITY % refnamediv.module "INCLUDE"> <![%refnamediv.module;[ <!ENTITY % local.refnamediv.attrib ""> <!ENTITY % refnamediv.role.attrib "%role.attrib;"> <!ENTITY % refnamediv.element "INCLUDE"> <![%refnamediv.element;[ <!--doc:The name, purpose, and classification of a reference page.--> <!ELEMENT refnamediv %ho; (refdescriptor?, refname+, refpurpose, refclass*, (remark|%link.char.class;)*)> <!--end of refnamediv.element-->]]> <!ENTITY % refnamediv.attlist "INCLUDE"> <![%refnamediv.attlist;[ <!ATTLIST refnamediv %common.attrib; %refnamediv.role.attrib; %local.refnamediv.attrib; > <!--end of refnamediv.attlist-->]]> <!--end of refnamediv.module-->]]> <!ENTITY % refdescriptor.module "INCLUDE"> <![%refdescriptor.module;[ <!ENTITY % local.refdescriptor.attrib ""> <!ENTITY % refdescriptor.role.attrib "%role.attrib;"> <!ENTITY % refdescriptor.element "INCLUDE"> <![%refdescriptor.element;[ <!--doc:A description of the topic of a reference page.--> <!ELEMENT refdescriptor %ho; (%refname.char.mix;)*> <!--end of refdescriptor.element-->]]> <!ENTITY % refdescriptor.attlist "INCLUDE"> <![%refdescriptor.attlist;[ <!ATTLIST refdescriptor %common.attrib; %refdescriptor.role.attrib; %local.refdescriptor.attrib; > <!--end of refdescriptor.attlist-->]]> <!--end of refdescriptor.module-->]]> <!ENTITY % refname.module "INCLUDE"> <![%refname.module;[ <!ENTITY % local.refname.attrib ""> <!ENTITY % refname.role.attrib "%role.attrib;"> <!ENTITY % refname.element "INCLUDE"> <![%refname.element;[ <!--doc:The name of (one of) the subject(s) of a reference page.--> <!ELEMENT refname %ho; (%refname.char.mix;)*> <!--end of refname.element-->]]> <!ENTITY % refname.attlist "INCLUDE"> <![%refname.attlist;[ <!ATTLIST refname %common.attrib; %refname.role.attrib; %local.refname.attrib; > <!--end of refname.attlist-->]]> <!--end of refname.module-->]]> <!ENTITY % refpurpose.module "INCLUDE"> <![%refpurpose.module;[ <!ENTITY % local.refpurpose.attrib ""> <!ENTITY % refpurpose.role.attrib "%role.attrib;"> <!ENTITY % refpurpose.element "INCLUDE"> <![%refpurpose.element;[ <!--doc:A short (one sentence) synopsis of the topic of a reference page.--> <!ELEMENT refpurpose %ho; (%refinline.char.mix;)*> <!--end of refpurpose.element-->]]> <!ENTITY % refpurpose.attlist "INCLUDE"> <![%refpurpose.attlist;[ <!ATTLIST refpurpose %common.attrib; %refpurpose.role.attrib; %local.refpurpose.attrib; > <!--end of refpurpose.attlist-->]]> <!--end of refpurpose.module-->]]> <!ENTITY % refclass.module "INCLUDE"> <![%refclass.module;[ <!ENTITY % local.refclass.attrib ""> <!ENTITY % refclass.role.attrib "%role.attrib;"> <!ENTITY % refclass.element "INCLUDE"> <![%refclass.element;[ <!--doc:The scope or other indication of applicability of a reference entry.--> <!ELEMENT refclass %ho; (%refclass.char.mix;)*> <!--end of refclass.element-->]]> <!ENTITY % refclass.attlist "INCLUDE"> <![%refclass.attlist;[ <!ATTLIST refclass %common.attrib; %refclass.role.attrib; %local.refclass.attrib; > <!--end of refclass.attlist-->]]> <!--end of refclass.module-->]]> <!ENTITY % refsynopsisdiv.module "INCLUDE"> <![%refsynopsisdiv.module;[ <!ENTITY % local.refsynopsisdiv.attrib ""> <!ENTITY % refsynopsisdiv.role.attrib "%role.attrib;"> <!ENTITY % refsynopsisdiv.element "INCLUDE"> <![%refsynopsisdiv.element;[ <!--doc:A syntactic synopsis of the subject of the reference page.--> <!ELEMENT refsynopsisdiv %ho; (refsynopsisdivinfo?, (%refsect.title.content;)?, (((%refcomponent.mix;)+, refsect2*) | (refsect2+)))> <!--end of refsynopsisdiv.element-->]]> <!ENTITY % refsynopsisdiv.attlist "INCLUDE"> <![%refsynopsisdiv.attlist;[ <!ATTLIST refsynopsisdiv %common.attrib; %refsynopsisdiv.role.attrib; %local.refsynopsisdiv.attrib; > <!--end of refsynopsisdiv.attlist-->]]> <!--end of refsynopsisdiv.module-->]]> <!ENTITY % refsection.module "INCLUDE"> <![%refsection.module;[ <!ENTITY % local.refsection.attrib ""> <!ENTITY % refsection.role.attrib "%role.attrib;"> <!ENTITY % refsection.element "INCLUDE"> <![%refsection.element;[ <!--doc:A recursive section in a refentry.--> <!ELEMENT refsection %ho; (refsectioninfo?, (%refsect.title.content;), (((%refcomponent.mix;)+, refsection*) | refsection+))> <!--end of refsection.element-->]]> <!ENTITY % refsection.attlist "INCLUDE"> <![%refsection.attlist;[ <!ATTLIST refsection %status.attrib; %common.attrib; %refsection.role.attrib; %local.refsection.attrib; > <!--end of refsection.attlist-->]]> <!--end of refsection.module-->]]> <!ENTITY % refsect1.module "INCLUDE"> <![%refsect1.module;[ <!ENTITY % local.refsect1.attrib ""> <!ENTITY % refsect1.role.attrib "%role.attrib;"> <!ENTITY % refsect1.element "INCLUDE"> <![%refsect1.element;[ <!--doc:A major subsection of a reference entry.--> <!ELEMENT refsect1 %ho; (refsect1info?, (%refsect.title.content;), (((%refcomponent.mix;)+, refsect2*) | refsect2+))> <!--end of refsect1.element-->]]> <!ENTITY % refsect1.attlist "INCLUDE"> <![%refsect1.attlist;[ <!ATTLIST refsect1 %status.attrib; %common.attrib; %refsect1.role.attrib; %local.refsect1.attrib; > <!--end of refsect1.attlist-->]]> <!--end of refsect1.module-->]]> <!ENTITY % refsect2.module "INCLUDE"> <![%refsect2.module;[ <!ENTITY % local.refsect2.attrib ""> <!ENTITY % refsect2.role.attrib "%role.attrib;"> <!ENTITY % refsect2.element "INCLUDE"> <![%refsect2.element;[ <!--doc:A subsection of a RefSect1.--> <!ELEMENT refsect2 %ho; (refsect2info?, (%refsect.title.content;), (((%refcomponent.mix;)+, refsect3*) | refsect3+))> <!--end of refsect2.element-->]]> <!ENTITY % refsect2.attlist "INCLUDE"> <![%refsect2.attlist;[ <!ATTLIST refsect2 %status.attrib; %common.attrib; %refsect2.role.attrib; %local.refsect2.attrib; > <!--end of refsect2.attlist-->]]> <!--end of refsect2.module-->]]> <!ENTITY % refsect3.module "INCLUDE"> <![%refsect3.module;[ <!ENTITY % local.refsect3.attrib ""> <!ENTITY % refsect3.role.attrib "%role.attrib;"> <!ENTITY % refsect3.element "INCLUDE"> <![%refsect3.element;[ <!--doc:A subsection of a RefSect2.--> <!ELEMENT refsect3 %ho; (refsect3info?, (%refsect.title.content;), (%refcomponent.mix;)+)> <!--end of refsect3.element-->]]> <!ENTITY % refsect3.attlist "INCLUDE"> <![%refsect3.attlist;[ <!ATTLIST refsect3 %status.attrib; %common.attrib; %refsect3.role.attrib; %local.refsect3.attrib; > <!--end of refsect3.attlist-->]]> <!--end of refsect3.module-->]]> <!--end of refentry.content.module-->]]> <!-- ...................................................................... --> <!-- Article .............................................................. --> <!ENTITY % article.module "INCLUDE"> <![%article.module;[ <!-- An Article is a chapter-level, stand-alone document that is often, but need not be, collected into a Book. --> <!ENTITY % local.article.attrib ""> <!ENTITY % article.role.attrib "%role.attrib;"> <!ENTITY % article.element "INCLUDE"> <![%article.element;[ <!--doc:An article.--> <!ELEMENT article %ho; ((%div.title.content;)?, articleinfo?, tocchap?, lot*, (%bookcomponent.content;), (%nav.class;|%appendix.class;|colophon|ackno)*) %ubiq.inclusion;> <!--end of article.element-->]]> <!-- Class: Indicates the type of a particular article; all articles have the same structure and general purpose. No default. --> <!-- ParentBook: ID of the enclosing Book --> <!ENTITY % article.attlist "INCLUDE"> <![%article.attlist;[ <!ATTLIST article class (journalarticle |productsheet |whitepaper |techreport |specification |faq) #IMPLIED parentbook IDREF #IMPLIED %status.attrib; %common.attrib; %article.role.attrib; %local.article.attrib; > <!--end of article.attlist-->]]> <!--end of article.module-->]]> <!-- End of DocBook document hierarchy module V4.5 ........................ --> <!-- ...................................................................... --> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/dbnotnx.mod��������������������������������������������������������������0000644�0001757�0001757�00000010572�12753310630�014611� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook notations module V4.5 ........................................ --> <!-- File dbnotnx.mod ..................................................... --> <!-- Copyright 1992-2004 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). $Id$ Permission to use, copy, modify and distribute the DocBook DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This module contains the notation declarations used by DocBook. In DTD driver files referring to this module, please use an entity declaration that uses the public identifier shown below: <!ENTITY % dbnotn PUBLIC "-//OASIS//ENTITIES DocBook Notations V4.5//EN" "dbnotnx.mod"> %dbnotn; See the documentation for detailed information on the parameter entity and module scheme used in DocBook, customizing DocBook and planning for interchange, and changes made since the last release of DocBook. --> <!ENTITY % local.notation.class ""> <!ENTITY % notation.class "BMP| CGM-CHAR | CGM-BINARY | CGM-CLEAR | DITROFF | DVI | EPS | EQN | FAX | GIF | GIF87a | GIF89a | JPG | JPEG | IGES | PCX | PIC | PNG | PS | SGML | TBL | TEX | TIFF | WMF | WPG | SVG | PDF | SWF | linespecific %local.notation.class;"> <!NOTATION BMP PUBLIC "+//ISBN 0-7923-94.2-1::Graphic Notation//NOTATION Microsoft Windows bitmap//EN"> <!NOTATION CGM-CHAR PUBLIC "ISO 8632/2//NOTATION Character encoding//EN"> <!NOTATION CGM-BINARY PUBLIC "ISO 8632/3//NOTATION Binary encoding//EN"> <!NOTATION CGM-CLEAR PUBLIC "ISO 8632/4//NOTATION Clear text encoding//EN"> <!NOTATION DITROFF SYSTEM "DITROFF"> <!NOTATION DVI SYSTEM "DVI"> <!NOTATION EPS PUBLIC "+//ISBN 0-201-18127-4::Adobe//NOTATION PostScript Language Ref. Manual//EN"> <!NOTATION EQN SYSTEM "EQN"> <!NOTATION FAX PUBLIC "-//USA-DOD//NOTATION CCITT Group 4 Facsimile Type 1 Untiled Raster//EN"> <!NOTATION GIF SYSTEM "GIF"> <!NOTATION GIF87a PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 87a//EN"> <!NOTATION GIF89a PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN"> <!NOTATION JPG SYSTEM "JPG"> <!NOTATION JPEG SYSTEM "JPG"> <!NOTATION IGES PUBLIC "-//USA-DOD//NOTATION (ASME/ANSI Y14.26M-1987) Initial Graphics Exchange Specification//EN"> <!NOTATION PCX PUBLIC "+//ISBN 0-7923-94.2-1::Graphic Notation//NOTATION ZSoft PCX bitmap//EN"> <!NOTATION PIC SYSTEM "PIC"> <!NOTATION PNG SYSTEM "http://www.w3.org/TR/REC-png"> <!NOTATION PS SYSTEM "PS"> <!NOTATION SGML PUBLIC "ISO 8879:1986//NOTATION Standard Generalized Markup Language//EN"> <!NOTATION TBL SYSTEM "TBL"> <!NOTATION TEX PUBLIC "+//ISBN 0-201-13448-9::Knuth//NOTATION The TeXbook//EN"> <!NOTATION TIFF SYSTEM "TIFF"> <!NOTATION WMF PUBLIC "+//ISBN 0-7923-94.2-1::Graphic Notation//NOTATION Microsoft Windows Metafile//EN"> <!NOTATION WPG SYSTEM "WPG"> <!--WordPerfect Graphic format--> <!NOTATION SVG SYSTEM "http://www.w3.org/TR/SVG/"> <!NOTATION PDF SYSTEM "http://www.adobe.com/products/acrobat/adobepdf.html"> <!NOTATION SWF SYSTEM "http://www.macromedia.com/software/flash"> <!NOTATION linespecific SYSTEM "linespecific"> <!-- End of DocBook notations module V4.5 ................................. --> <!-- ...................................................................... --> ��������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/dbpoolx.mod��������������������������������������������������������������0000644�0001757�0001757�00000742341�12753310630�014612� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook XML information pool module V4.5 ............................. --> <!-- File dbpoolx.mod ..................................................... --> <!-- Copyright 1992-2004 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). $Id$ Permission to use, copy, modify and distribute the DocBook XML DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook XML DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This module contains the definitions for the objects, inline elements, and so on that are available to be used as the main content of DocBook documents. Some elements are useful for general publishing, and others are useful specifically for computer documentation. This module has the following dependencies on other modules: o It assumes that a %notation.class; entity is defined by the driver file or other high-level module. This entity is referenced in the NOTATION attributes for the graphic-related and ModeSpec elements. o It assumes that an appropriately parameterized table module is available for use with the table-related elements. In DTD driver files referring to this module, please use an entity declaration that uses the public identifier shown below: <!ENTITY % dbpool PUBLIC "-//OASIS//ELEMENTS DocBook XML Information Pool V4.5//EN" "dbpoolx.mod"> %dbpool; See the documentation for detailed information on the parameter entity and module scheme used in DocBook, customizing DocBook and planning for interchange, and changes made since the last release of DocBook. --> <!-- ...................................................................... --> <!-- Forms entities ....................................................... --> <!-- These PEs provide the hook by which the forms module can be inserted --> <!-- into the DTD. --> <!ENTITY % forminlines.hook ""> <!ENTITY % forms.hook ""> <!-- ...................................................................... --> <!-- General-purpose semantics entities ................................... --> <!ENTITY % yesorno.attvals "CDATA"> <!-- ...................................................................... --> <!-- Entities for module inclusions ....................................... --> <!ENTITY % dbpool.redecl.module "IGNORE"> <!-- ...................................................................... --> <!-- Entities for element classes and mixtures ............................ --> <!-- "Ubiquitous" classes: ndxterm.class and beginpage --> <!ENTITY % local.ndxterm.class ""> <!ENTITY % ndxterm.class "indexterm %local.ndxterm.class;"> <!-- Object-level classes ................................................. --> <!ENTITY % local.list.class ""> <!ENTITY % list.class "calloutlist|glosslist|bibliolist|itemizedlist|orderedlist|segmentedlist |simplelist|variablelist %local.list.class;"> <!ENTITY % local.admon.class ""> <!ENTITY % admon.class "caution|important|note|tip|warning %local.admon.class;"> <!ENTITY % local.linespecific.class ""> <!ENTITY % linespecific.class "literallayout|programlisting|programlistingco|screen |screenco|screenshot %local.linespecific.class;"> <!ENTITY % local.method.synop.class ""> <!ENTITY % method.synop.class "constructorsynopsis |destructorsynopsis |methodsynopsis %local.method.synop.class;"> <!ENTITY % local.synop.class ""> <!ENTITY % synop.class "synopsis|cmdsynopsis|funcsynopsis |classsynopsis|fieldsynopsis |%method.synop.class; %local.synop.class;"> <!ENTITY % local.para.class ""> <!ENTITY % para.class "formalpara|para|simpara %local.para.class;"> <!ENTITY % local.informal.class ""> <!ENTITY % informal.class "address|blockquote |graphic|graphicco|mediaobject|mediaobjectco |informalequation |informalexample |informalfigure |informaltable %local.informal.class;"> <!ENTITY % local.formal.class ""> <!ENTITY % formal.class "equation|example|figure|table %local.formal.class;"> <!-- The DocBook TC may produce an official EBNF module for DocBook. --> <!-- This PE provides the hook by which it can be inserted into the DTD. --> <!ENTITY % ebnf.block.hook ""> <!ENTITY % local.compound.class ""> <!ENTITY % compound.class "msgset|procedure|sidebar|qandaset|task %ebnf.block.hook; %local.compound.class;"> <!ENTITY % local.genobj.class ""> <!ENTITY % genobj.class "anchor|bridgehead|remark|highlights %local.genobj.class;"> <!ENTITY % local.descobj.class ""> <!ENTITY % descobj.class "abstract|authorblurb|epigraph %local.descobj.class;"> <!-- Character-level classes .............................................. --> <!ENTITY % local.xref.char.class ""> <!ENTITY % xref.char.class "footnoteref|xref|biblioref %local.xref.char.class;"> <!ENTITY % local.gen.char.class ""> <!ENTITY % gen.char.class "abbrev|acronym|citation|citerefentry|citetitle|citebiblioid|emphasis |firstterm|foreignphrase|glossterm|termdef|footnote|phrase |orgname|quote|trademark|wordasword |personname %local.gen.char.class;"> <!ENTITY % local.link.char.class ""> <!ENTITY % link.char.class "link|olink|ulink %local.link.char.class;"> <!-- The DocBook TC may produce an official EBNF module for DocBook. --> <!-- This PE provides the hook by which it can be inserted into the DTD. --> <!ENTITY % ebnf.inline.hook ""> <!ENTITY % local.tech.char.class ""> <!ENTITY % tech.char.class "action|application |classname|methodname|interfacename|exceptionname |ooclass|oointerface|ooexception |package |command|computeroutput |database|email|envar|errorcode|errorname|errortype|errortext|filename |function|guibutton|guiicon|guilabel|guimenu|guimenuitem |guisubmenu|hardware|interface|keycap |keycode|keycombo|keysym|literal|code|constant|markup|medialabel |menuchoice|mousebutton|option|optional|parameter |prompt|property|replaceable|returnvalue|sgmltag|structfield |structname|symbol|systemitem|uri|token|type|userinput|varname %ebnf.inline.hook; %local.tech.char.class;"> <!ENTITY % local.base.char.class ""> <!ENTITY % base.char.class "anchor %local.base.char.class;"> <!ENTITY % local.docinfo.char.class ""> <!ENTITY % docinfo.char.class "author|authorinitials|corpauthor|corpcredit|modespec|othercredit |productname|productnumber|revhistory %local.docinfo.char.class;"> <!ENTITY % local.other.char.class ""> <!ENTITY % other.char.class "remark|subscript|superscript %local.other.char.class;"> <!ENTITY % local.inlineobj.char.class ""> <!ENTITY % inlineobj.char.class "inlinegraphic|inlinemediaobject|inlineequation %local.inlineobj.char.class;"> <!-- ...................................................................... --> <!-- Entities for content models .......................................... --> <!ENTITY % formalobject.title.content "title, titleabbrev?"> <!-- Redeclaration placeholder ............................................ --> <!-- For redeclaring entities that are declared after this point while retaining their references to the entities that are declared before this point --> <![%dbpool.redecl.module;[ <!-- Defining rdbpool here makes some buggy XML parsers happy. --> <!ENTITY % rdbpool ""> %rdbpool; <!--end of dbpool.redecl.module-->]]> <!-- Object-level mixtures ................................................ --> <!-- list admn line synp para infm form cmpd gen desc Component mixture X X X X X X X X X X Sidebar mixture X X X X X X X a X Footnote mixture X X X X X Example mixture X X X X X Highlights mixture X X X Paragraph mixture X X X X Admonition mixture X X X X X X b c Figure mixture X X X Table entry mixture X X X X d Glossary def mixture X X X X X e Legal notice mixture X X X X f a. Just Procedure; not Sidebar itself or MsgSet. b. No MsgSet. c. No Highlights. d. Just Graphic; no other informal objects. e. No Anchor, BridgeHead, or Highlights. f. Just BlockQuote; no other informal objects. --> <!ENTITY % local.component.mix ""> <!ENTITY % component.mix "%list.class; |%admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |%compound.class; |%genobj.class; |%descobj.class; |%ndxterm.class; |beginpage %forms.hook; %local.component.mix;"> <!ENTITY % local.sidebar.mix ""> <!ENTITY % sidebar.mix "%list.class; |%admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |procedure |%genobj.class; |%ndxterm.class; |beginpage %forms.hook; %local.sidebar.mix;"> <!ENTITY % local.qandaset.mix ""> <!ENTITY % qandaset.mix "%list.class; |%admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |procedure |%genobj.class; |%ndxterm.class; %forms.hook; %local.qandaset.mix;"> <!ENTITY % local.revdescription.mix ""> <!ENTITY % revdescription.mix "%list.class; |%admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |procedure |%genobj.class; |%ndxterm.class; %local.revdescription.mix;"> <!ENTITY % local.footnote.mix ""> <!ENTITY % footnote.mix "%list.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; %local.footnote.mix;"> <!ENTITY % local.example.mix ""> <!ENTITY % example.mix "%list.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%ndxterm.class; |beginpage |procedure %forms.hook; %local.example.mix;"> <!ENTITY % local.highlights.mix ""> <!ENTITY % highlights.mix "%list.class; |%admon.class; |%para.class; |%ndxterm.class; %local.highlights.mix;"> <!-- %formal.class; is explicitly excluded from many contexts in which paragraphs are used --> <!ENTITY % local.para.mix ""> <!ENTITY % para.mix "%list.class; |%admon.class; |%linespecific.class; |%informal.class; |%formal.class; %local.para.mix;"> <!ENTITY % local.admon.mix ""> <!ENTITY % admon.mix "%list.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |procedure|sidebar |anchor|bridgehead|remark |%ndxterm.class; |beginpage %forms.hook; %local.admon.mix;"> <!ENTITY % local.figure.mix ""> <!ENTITY % figure.mix "%linespecific.class; |%synop.class; |%informal.class; |%ndxterm.class; |beginpage %forms.hook; %local.figure.mix;"> <!ENTITY % local.tabentry.mix ""> <!ENTITY % tabentry.mix "%list.class; |%admon.class; |%linespecific.class; |%para.class; |graphic|mediaobject %forms.hook; %local.tabentry.mix;"> <!ENTITY % local.glossdef.mix ""> <!ENTITY % glossdef.mix "%list.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%formal.class; |remark |%ndxterm.class; |beginpage %local.glossdef.mix;"> <!ENTITY % local.legalnotice.mix ""> <!ENTITY % legalnotice.mix "%list.class; |%admon.class; |%linespecific.class; |%para.class; |blockquote |%ndxterm.class; |beginpage %local.legalnotice.mix;"> <!ENTITY % local.textobject.mix ""> <!ENTITY % textobject.mix "%list.class; |%admon.class; |%linespecific.class; |%para.class; |blockquote %local.textobject.mix;"> <!ENTITY % local.mediaobject.mix ""> <!ENTITY % mediaobject.mix "videoobject|audioobject|imageobject|imageobjectco|textobject %local.mediaobject.mix;"> <!ENTITY % local.listpreamble.mix ""> <!ENTITY % listpreamble.mix " %admon.class; |%linespecific.class; |%synop.class; |%para.class; |%informal.class; |%genobj.class; |%descobj.class; |%ndxterm.class; |beginpage %forms.hook; %local.listpreamble.mix;"> <!-- Character-level mixtures ............................................. --> <![%sgml.features;[ <!ENTITY % local.ubiq.mix ""> <!ENTITY % ubiq.mix "%ndxterm.class;|beginpage %local.ubiq.mix;"> <!ENTITY % ubiq.exclusion "-(%ubiq.mix)"> <!ENTITY % ubiq.inclusion "+(%ubiq.mix)"> <!ENTITY % footnote.exclusion "-(footnote|%formal.class;)"> <!ENTITY % highlights.exclusion "-(%ubiq.mix;|%formal.class;)"> <!ENTITY % admon.exclusion "-(%admon.class;)"> <!ENTITY % formal.exclusion "-(%formal.class;)"> <!ENTITY % acronym.exclusion "-(acronym)"> <!ENTITY % beginpage.exclusion "-(beginpage)"> <!ENTITY % ndxterm.exclusion "-(%ndxterm.class;)"> <!ENTITY % blockquote.exclusion "-(epigraph)"> <!ENTITY % remark.exclusion "-(remark|%ubiq.mix;)"> <!ENTITY % glossterm.exclusion "-(glossterm)"> <!ENTITY % links.exclusion "-(link|olink|ulink|xref|biblioref)"> ]]><!-- sgml.features --> <!-- not [sgml.features[ --> <!ENTITY % local.ubiq.mix ""> <!ENTITY % ubiq.mix ""> <!ENTITY % ubiq.exclusion ""> <!ENTITY % ubiq.inclusion ""> <!ENTITY % footnote.exclusion ""> <!ENTITY % highlights.exclusion ""> <!ENTITY % admon.exclusion ""> <!ENTITY % formal.exclusion ""> <!ENTITY % acronym.exclusion ""> <!ENTITY % beginpage.exclusion ""> <!ENTITY % ndxterm.exclusion ""> <!ENTITY % blockquote.exclusion ""> <!ENTITY % remark.exclusion ""> <!ENTITY % glossterm.exclusion ""> <!ENTITY % links.exclusion ""> <!-- ]] not sgml.features --> <!-- #PCD xref word link cptr base dnfo othr inob (synop) para.char.mix X X X X X X X X X title.char.mix X X X X X X X X X ndxterm.char.mix X X X X X X X X a cptr.char.mix X X X X X a smallcptr.char.mix X b a word.char.mix X c X X X a docinfo.char.mix X d X b X a a. Just InlineGraphic; no InlineEquation. b. Just Replaceable; no other computer terms. c. Just Emphasis and Trademark; no other word elements. d. Just Acronym, Emphasis, and Trademark; no other word elements. --> <!ENTITY % local.para.char.mix ""> <!ENTITY % para.char.mix "#PCDATA |%xref.char.class; |%gen.char.class; |%link.char.class; |%tech.char.class; |%base.char.class; |%docinfo.char.class; |%other.char.class; |%inlineobj.char.class; |%synop.class; |%ndxterm.class; |beginpage %forminlines.hook; %local.para.char.mix;"> <!ENTITY % local.title.char.mix ""> <!ENTITY % title.char.mix "#PCDATA |%xref.char.class; |%gen.char.class; |%link.char.class; |%tech.char.class; |%base.char.class; |%docinfo.char.class; |%other.char.class; |%inlineobj.char.class; |%ndxterm.class; %local.title.char.mix;"> <!ENTITY % local.ndxterm.char.mix ""> <!ENTITY % ndxterm.char.mix "#PCDATA |%xref.char.class; |%gen.char.class; |%link.char.class; |%tech.char.class; |%base.char.class; |%docinfo.char.class; |%other.char.class; |inlinegraphic|inlinemediaobject %local.ndxterm.char.mix;"> <!ENTITY % local.cptr.char.mix ""> <!ENTITY % cptr.char.mix "#PCDATA |%link.char.class; |%tech.char.class; |%base.char.class; |%other.char.class; |inlinegraphic|inlinemediaobject |%ndxterm.class; |beginpage %local.cptr.char.mix;"> <!ENTITY % local.smallcptr.char.mix ""> <!ENTITY % smallcptr.char.mix "#PCDATA |replaceable |inlinegraphic|inlinemediaobject |%ndxterm.class; |beginpage %local.smallcptr.char.mix;"> <!ENTITY % local.word.char.mix ""> <!ENTITY % word.char.mix "#PCDATA |acronym|emphasis|trademark |%link.char.class; |%base.char.class; |%other.char.class; |inlinegraphic|inlinemediaobject |%ndxterm.class; |beginpage %local.word.char.mix;"> <!ENTITY % local.docinfo.char.mix ""> <!ENTITY % docinfo.char.mix "#PCDATA |%link.char.class; |emphasis|trademark |replaceable |%other.char.class; |inlinegraphic|inlinemediaobject |%ndxterm.class; %local.docinfo.char.mix;"> <!--ENTITY % bibliocomponent.mix (see Bibliographic section, below)--> <!--ENTITY % person.ident.mix (see Bibliographic section, below)--> <!-- ...................................................................... --> <!-- Entities for attributes and attribute components ..................... --> <!-- Effectivity attributes ............................................... --> <!-- Arch: Computer or chip architecture to which element applies; no default --> <!ENTITY % arch.attrib "arch CDATA #IMPLIED"> <!-- Condition: General-purpose effectivity attribute --> <!ENTITY % condition.attrib "condition CDATA #IMPLIED"> <!-- Conformance: Standards conformance characteristics --> <!ENTITY % conformance.attrib "conformance NMTOKENS #IMPLIED"> <!-- OS: Operating system to which element applies; no default --> <!ENTITY % os.attrib "os CDATA #IMPLIED"> <!-- Revision: Editorial revision to which element belongs; no default --> <!ENTITY % revision.attrib "revision CDATA #IMPLIED"> <!-- Security: Security classification; no default --> <!ENTITY % security.attrib "security CDATA #IMPLIED"> <!-- UserLevel: Level of user experience to which element applies; no default --> <!ENTITY % userlevel.attrib "userlevel CDATA #IMPLIED"> <!-- Vendor: Computer vendor to which element applies; no default --> <!ENTITY % vendor.attrib "vendor CDATA #IMPLIED"> <!-- Wordsize: Computer word size (32 bit, 64 bit, etc.); no default --> <!ENTITY % wordsize.attrib "wordsize CDATA #IMPLIED"> <!ENTITY % local.effectivity.attrib ""> <!ENTITY % effectivity.attrib "%arch.attrib; %condition.attrib; %conformance.attrib; %os.attrib; %revision.attrib; %security.attrib; %userlevel.attrib; %vendor.attrib; %wordsize.attrib; %local.effectivity.attrib;" > <!-- Common attributes .................................................... --> <!-- Id: Unique identifier of element; no default --> <!ENTITY % id.attrib "id ID #IMPLIED"> <!-- Id: Unique identifier of element; a value must be supplied; no default --> <!ENTITY % idreq.attrib "id ID #REQUIRED"> <!-- Lang: Indicator of language in which element is written, for translation, character set management, etc.; no default --> <!ENTITY % lang.attrib "lang CDATA #IMPLIED"> <!-- Remap: Previous role of element before conversion; no default --> <!ENTITY % remap.attrib "remap CDATA #IMPLIED"> <!-- Role: New role of element in local environment; no default --> <!ENTITY % role.attrib "role CDATA #IMPLIED"> <!-- XRefLabel: Alternate labeling string for XRef text generation; default is usually title or other appropriate label text already contained in element --> <!ENTITY % xreflabel.attrib "xreflabel CDATA #IMPLIED"> <!-- RevisionFlag: Revision status of element; default is that element wasn't revised --> <!ENTITY % revisionflag.attrib "revisionflag (changed |added |deleted |off) #IMPLIED"> <!ENTITY % local.common.attrib ""> <!-- dir: Bidirectional override --> <!ENTITY % dir.attrib "dir (ltr |rtl |lro |rlo) #IMPLIED"> <!-- xml:base: base URI --> <![%sgml.features;[ <!ENTITY % xml-base.attrib ""> ]]> <!ENTITY % xml-base.attrib "xml:base CDATA #IMPLIED"> <!-- Role is included explicitly on each element --> <!ENTITY % common.attrib "%id.attrib; %lang.attrib; %remap.attrib; %xreflabel.attrib; %revisionflag.attrib; %effectivity.attrib; %dir.attrib; %xml-base.attrib; %local.common.attrib;" > <!-- Role is included explicitly on each element --> <!ENTITY % idreq.common.attrib "%idreq.attrib; %lang.attrib; %remap.attrib; %xreflabel.attrib; %revisionflag.attrib; %effectivity.attrib; %dir.attrib; %xml-base.attrib; %local.common.attrib;" > <!-- Semi-common attributes and other attribute entities .................. --> <!ENTITY % local.graphics.attrib ""> <!-- EntityRef: Name of an external entity containing the content of the graphic --> <!-- FileRef: Filename, qualified by a pathname if desired, designating the file containing the content of the graphic --> <!-- Format: Notation of the element content, if any --> <!-- SrcCredit: Information about the source of the Graphic --> <!-- Width: Same as CALS reprowid (desired width) --> <!-- Depth: Same as CALS reprodep (desired depth) --> <!-- Align: Same as CALS hplace with 'none' removed; #IMPLIED means application-specific --> <!-- Scale: Conflation of CALS hscale and vscale --> <!-- Scalefit: Same as CALS scalefit --> <!ENTITY % graphics.attrib " entityref ENTITY #IMPLIED fileref CDATA #IMPLIED format (%notation.class;) #IMPLIED srccredit CDATA #IMPLIED width CDATA #IMPLIED contentwidth CDATA #IMPLIED depth CDATA #IMPLIED contentdepth CDATA #IMPLIED align (left |right |center) #IMPLIED valign (top |middle |bottom) #IMPLIED scale CDATA #IMPLIED scalefit %yesorno.attvals; #IMPLIED %local.graphics.attrib;" > <!ENTITY % local.keyaction.attrib ""> <!-- Action: Key combination type; default is unspecified if one child element, Simul if there is more than one; if value is Other, the OtherAction attribute must have a nonempty value --> <!-- OtherAction: User-defined key combination type --> <!ENTITY % keyaction.attrib " action (click |double-click |press |seq |simul |other) #IMPLIED otheraction CDATA #IMPLIED %local.keyaction.attrib;" > <!-- Label: Identifying number or string; default is usually the appropriate number or string autogenerated by a formatter --> <!ENTITY % label.attrib "label CDATA #IMPLIED"> <!-- xml:space: whitespace treatment --> <![%sgml.features;[ <!ENTITY % xml-space.attrib ""> ]]> <!ENTITY % xml-space.attrib "xml:space (preserve) #IMPLIED"> <!-- Format: whether element is assumed to contain significant white space --> <!ENTITY % linespecific.attrib "format NOTATION (linespecific) 'linespecific' %xml-space.attrib; linenumbering (numbered|unnumbered) #IMPLIED continuation (continues|restarts) #IMPLIED startinglinenumber CDATA #IMPLIED language CDATA #IMPLIED"> <!-- Linkend: link to related information; no default --> <!ENTITY % linkend.attrib "linkend IDREF #IMPLIED"> <!-- Linkend: required link to related information --> <!ENTITY % linkendreq.attrib "linkend IDREF #REQUIRED"> <!-- Linkends: link to one or more sets of related information; no default --> <!ENTITY % linkends.attrib "linkends IDREFS #IMPLIED"> <!ENTITY % local.mark.attrib ""> <!ENTITY % mark.attrib "mark CDATA #IMPLIED %local.mark.attrib;" > <!-- MoreInfo: whether element's content has an associated RefEntry --> <!ENTITY % moreinfo.attrib "moreinfo (refentry|none) 'none'"> <!-- Pagenum: number of page on which element appears; no default --> <!ENTITY % pagenum.attrib "pagenum CDATA #IMPLIED"> <!ENTITY % local.status.attrib ""> <!-- Status: Editorial or publication status of the element it applies to, such as "in review" or "approved for distribution" --> <!ENTITY % status.attrib "status CDATA #IMPLIED %local.status.attrib;" > <!-- Width: width of the longest line in the element to which it pertains, in number of characters --> <!ENTITY % width.attrib "width CDATA #IMPLIED"> <!-- ...................................................................... --> <!-- Title elements ....................................................... --> <!ENTITY % title.module "INCLUDE"> <![%title.module;[ <!ENTITY % local.title.attrib ""> <!ENTITY % title.role.attrib "%role.attrib;"> <!ENTITY % title.element "INCLUDE"> <![%title.element;[ <!--doc:The text of the title of a section of a document or of a formal block-level element.--> <!ELEMENT title %ho; (%title.char.mix;)*> <!--end of title.element-->]]> <!ENTITY % title.attlist "INCLUDE"> <![%title.attlist;[ <!ATTLIST title %pagenum.attrib; %common.attrib; %title.role.attrib; %local.title.attrib; > <!--end of title.attlist-->]]> <!--end of title.module-->]]> <!ENTITY % titleabbrev.module "INCLUDE"> <![%titleabbrev.module;[ <!ENTITY % local.titleabbrev.attrib ""> <!ENTITY % titleabbrev.role.attrib "%role.attrib;"> <!ENTITY % titleabbrev.element "INCLUDE"> <![%titleabbrev.element;[ <!--doc:The abbreviation of a Title.--> <!ELEMENT titleabbrev %ho; (%title.char.mix;)*> <!--end of titleabbrev.element-->]]> <!ENTITY % titleabbrev.attlist "INCLUDE"> <![%titleabbrev.attlist;[ <!ATTLIST titleabbrev %common.attrib; %titleabbrev.role.attrib; %local.titleabbrev.attrib; > <!--end of titleabbrev.attlist-->]]> <!--end of titleabbrev.module-->]]> <!ENTITY % subtitle.module "INCLUDE"> <![%subtitle.module;[ <!ENTITY % local.subtitle.attrib ""> <!ENTITY % subtitle.role.attrib "%role.attrib;"> <!ENTITY % subtitle.element "INCLUDE"> <![%subtitle.element;[ <!--doc:The subtitle of a document.--> <!ELEMENT subtitle %ho; (%title.char.mix;)*> <!--end of subtitle.element-->]]> <!ENTITY % subtitle.attlist "INCLUDE"> <![%subtitle.attlist;[ <!ATTLIST subtitle %common.attrib; %subtitle.role.attrib; %local.subtitle.attrib; > <!--end of subtitle.attlist-->]]> <!--end of subtitle.module-->]]> <!-- ...................................................................... --> <!-- Bibliographic entities and elements .................................. --> <!-- The bibliographic elements are typically used in the document hierarchy. They do not appear in content models of information pool elements. See also the document information elements, below. --> <!ENTITY % local.person.ident.mix ""> <!ENTITY % person.ident.mix "honorific|firstname|surname|lineage|othername|affiliation |authorblurb|contrib %local.person.ident.mix;"> <!ENTITY % local.bibliocomponent.mix ""> <!ENTITY % bibliocomponent.mix "abbrev|abstract|address|artpagenums|author |authorgroup|authorinitials|bibliomisc|biblioset |collab|confgroup|contractnum|contractsponsor |copyright|corpauthor|corpname|corpcredit|date|edition |editor|invpartnumber|isbn|issn|issuenum|orgname |biblioid|citebiblioid|bibliosource|bibliorelation|bibliocoverage |othercredit|pagenums|printhistory|productname |productnumber|pubdate|publisher|publishername |pubsnumber|releaseinfo|revhistory|seriesvolnums |subtitle|title|titleabbrev|volumenum|citetitle |personname|%person.ident.mix; |%ndxterm.class; %local.bibliocomponent.mix;"> <!-- I don't think this is well placed, but it needs to be here because of --> <!-- the reference to bibliocomponent.mix --> <!ENTITY % local.info.class ""> <!ENTITY % info.class "graphic | mediaobject | legalnotice | modespec | subjectset | keywordset | itermset | %bibliocomponent.mix; %local.info.class;"> <!-- BiblioList ........................ --> <!ENTITY % bibliolist.module "INCLUDE"> <![%bibliolist.module;[ <!ENTITY % local.bibliolist.attrib ""> <!ENTITY % bibliolist.role.attrib "%role.attrib;"> <!ENTITY % bibliolist.element "INCLUDE"> <![%bibliolist.element;[ <!--doc:A wrapper for a set of bibliography entries.--> <!ELEMENT bibliolist %ho; (blockinfo?, (%formalobject.title.content;)?, (biblioentry|bibliomixed)+)> <!--end of bibliolist.element-->]]> <!ENTITY % bibliolist.attlist "INCLUDE"> <![%bibliolist.attlist;[ <!ATTLIST bibliolist %common.attrib; %bibliolist.role.attrib; %local.bibliolist.attrib; > <!--end of bibliolist.attlist-->]]> <!--end of bibliolist.module-->]]> <!ENTITY % biblioentry.module "INCLUDE"> <![%biblioentry.module;[ <!ENTITY % local.biblioentry.attrib ""> <!ENTITY % biblioentry.role.attrib "%role.attrib;"> <!ENTITY % biblioentry.element "INCLUDE"> <![%biblioentry.element;[ <!--doc:An entry in a Bibliography.--> <!ELEMENT biblioentry %ho; ((articleinfo | (%bibliocomponent.mix;))+) %ubiq.exclusion;> <!--end of biblioentry.element-->]]> <!ENTITY % biblioentry.attlist "INCLUDE"> <![%biblioentry.attlist;[ <!ATTLIST biblioentry %common.attrib; %biblioentry.role.attrib; %local.biblioentry.attrib; > <!--end of biblioentry.attlist-->]]> <!--end of biblioentry.module-->]]> <!ENTITY % bibliomixed.module "INCLUDE"> <![%bibliomixed.module;[ <!ENTITY % local.bibliomixed.attrib ""> <!ENTITY % bibliomixed.role.attrib "%role.attrib;"> <!ENTITY % bibliomixed.element "INCLUDE"> <![%bibliomixed.element;[ <!--doc:An entry in a Bibliography.--> <!ELEMENT bibliomixed %ho; (#PCDATA | %bibliocomponent.mix; | bibliomset)* %ubiq.exclusion;> <!--end of bibliomixed.element-->]]> <!ENTITY % bibliomixed.attlist "INCLUDE"> <![%bibliomixed.attlist;[ <!ATTLIST bibliomixed %common.attrib; %bibliomixed.role.attrib; %local.bibliomixed.attrib; > <!--end of bibliomixed.attlist-->]]> <!--end of bibliomixed.module-->]]> <!ENTITY % articleinfo.module "INCLUDE"> <![%articleinfo.module;[ <!ENTITY % local.articleinfo.attrib ""> <!ENTITY % articleinfo.role.attrib "%role.attrib;"> <!ENTITY % articleinfo.element "INCLUDE"> <![%articleinfo.element;[ <!--doc:Meta-information for an Article.--> <!ELEMENT articleinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of articleinfo.element-->]]> <!ENTITY % articleinfo.attlist "INCLUDE"> <![%articleinfo.attlist;[ <!ATTLIST articleinfo %common.attrib; %articleinfo.role.attrib; %local.articleinfo.attrib; > <!--end of articleinfo.attlist-->]]> <!--end of articleinfo.module-->]]> <!ENTITY % biblioset.module "INCLUDE"> <![%biblioset.module;[ <!ENTITY % local.biblioset.attrib ""> <!ENTITY % biblioset.role.attrib "%role.attrib;"> <!ENTITY % biblioset.element "INCLUDE"> <![%biblioset.element;[ <!--doc:A "raw" container for related bibliographic information.--> <!ELEMENT biblioset %ho; ((%bibliocomponent.mix;)+) %ubiq.exclusion;> <!--end of biblioset.element-->]]> <!-- Relation: Relationship of elements contained within BiblioSet --> <!ENTITY % biblioset.attlist "INCLUDE"> <![%biblioset.attlist;[ <!ATTLIST biblioset relation CDATA #IMPLIED %common.attrib; %biblioset.role.attrib; %local.biblioset.attrib; > <!--end of biblioset.attlist-->]]> <!--end of biblioset.module-->]]> <!ENTITY % bibliomset.module "INCLUDE"> <![%bibliomset.module;[ <!ENTITY % bibliomset.role.attrib "%role.attrib;"> <!ENTITY % local.bibliomset.attrib ""> <!ENTITY % bibliomset.element "INCLUDE"> <![%bibliomset.element;[ <!--doc:A "cooked" container for related bibliographic information.--> <!ELEMENT bibliomset %ho; (#PCDATA | %bibliocomponent.mix; | bibliomset)* %ubiq.exclusion;> <!--end of bibliomset.element-->]]> <!-- Relation: Relationship of elements contained within BiblioMSet --> <!ENTITY % bibliomset.attlist "INCLUDE"> <![%bibliomset.attlist;[ <!ATTLIST bibliomset relation CDATA #IMPLIED %common.attrib; %bibliomset.role.attrib; %local.bibliomset.attrib; > <!--end of bibliomset.attlist-->]]> <!--end of bibliomset.module-->]]> <!ENTITY % bibliomisc.module "INCLUDE"> <![%bibliomisc.module;[ <!ENTITY % local.bibliomisc.attrib ""> <!ENTITY % bibliomisc.role.attrib "%role.attrib;"> <!ENTITY % bibliomisc.element "INCLUDE"> <![%bibliomisc.element;[ <!--doc:Untyped bibliographic information.--> <!ELEMENT bibliomisc %ho; (%para.char.mix;)*> <!--end of bibliomisc.element-->]]> <!ENTITY % bibliomisc.attlist "INCLUDE"> <![%bibliomisc.attlist;[ <!ATTLIST bibliomisc %common.attrib; %bibliomisc.role.attrib; %local.bibliomisc.attrib; > <!--end of bibliomisc.attlist-->]]> <!--end of bibliomisc.module-->]]> <!-- ...................................................................... --> <!-- Subject, Keyword, and ITermSet elements .............................. --> <!ENTITY % subjectset.content.module "INCLUDE"> <![%subjectset.content.module;[ <!ENTITY % subjectset.module "INCLUDE"> <![%subjectset.module;[ <!ENTITY % local.subjectset.attrib ""> <!ENTITY % subjectset.role.attrib "%role.attrib;"> <!ENTITY % subjectset.element "INCLUDE"> <![%subjectset.element;[ <!--doc:A set of terms describing the subject matter of a document.--> <!ELEMENT subjectset %ho; (subject+)> <!--end of subjectset.element-->]]> <!-- Scheme: Controlled vocabulary employed in SubjectTerms --> <!ENTITY % subjectset.attlist "INCLUDE"> <![%subjectset.attlist;[ <!ATTLIST subjectset scheme NMTOKEN #IMPLIED %common.attrib; %subjectset.role.attrib; %local.subjectset.attrib; > <!--end of subjectset.attlist-->]]> <!--end of subjectset.module-->]]> <!ENTITY % subject.module "INCLUDE"> <![%subject.module;[ <!ENTITY % local.subject.attrib ""> <!ENTITY % subject.role.attrib "%role.attrib;"> <!ENTITY % subject.element "INCLUDE"> <![%subject.element;[ <!--doc:One of a group of terms describing the subject matter of a document.--> <!ELEMENT subject %ho; (subjectterm+)> <!--end of subject.element-->]]> <!-- Weight: Ranking of this group of SubjectTerms relative to others, 0 is low, no highest value specified --> <!ENTITY % subject.attlist "INCLUDE"> <![%subject.attlist;[ <!ATTLIST subject weight CDATA #IMPLIED %common.attrib; %subject.role.attrib; %local.subject.attrib; > <!--end of subject.attlist-->]]> <!--end of subject.module-->]]> <!ENTITY % subjectterm.module "INCLUDE"> <![%subjectterm.module;[ <!ENTITY % local.subjectterm.attrib ""> <!ENTITY % subjectterm.role.attrib "%role.attrib;"> <!ENTITY % subjectterm.element "INCLUDE"> <![%subjectterm.element;[ <!--doc:A term in a group of terms describing the subject matter of a document.--> <!ELEMENT subjectterm %ho; (#PCDATA)> <!--end of subjectterm.element-->]]> <!ENTITY % subjectterm.attlist "INCLUDE"> <![%subjectterm.attlist;[ <!ATTLIST subjectterm %common.attrib; %subjectterm.role.attrib; %local.subjectterm.attrib; > <!--end of subjectterm.attlist-->]]> <!--end of subjectterm.module-->]]> <!--end of subjectset.content.module-->]]> <!ENTITY % keywordset.content.module "INCLUDE"> <![%keywordset.content.module;[ <!ENTITY % keywordset.module "INCLUDE"> <![%keywordset.module;[ <!ENTITY % local.keywordset.attrib ""> <!ENTITY % keywordset.role.attrib "%role.attrib;"> <!ENTITY % keywordset.element "INCLUDE"> <![%keywordset.element;[ <!--doc:A set of keywords describing the content of a document.--> <!ELEMENT keywordset %ho; (keyword+)> <!--end of keywordset.element-->]]> <!ENTITY % keywordset.attlist "INCLUDE"> <![%keywordset.attlist;[ <!ATTLIST keywordset %common.attrib; %keywordset.role.attrib; %local.keywordset.attrib; > <!--end of keywordset.attlist-->]]> <!--end of keywordset.module-->]]> <!ENTITY % keyword.module "INCLUDE"> <![%keyword.module;[ <!ENTITY % local.keyword.attrib ""> <!ENTITY % keyword.role.attrib "%role.attrib;"> <!ENTITY % keyword.element "INCLUDE"> <![%keyword.element;[ <!--doc:One of a set of keywords describing the content of a document.--> <!ELEMENT keyword %ho; (#PCDATA)> <!--end of keyword.element-->]]> <!ENTITY % keyword.attlist "INCLUDE"> <![%keyword.attlist;[ <!ATTLIST keyword %common.attrib; %keyword.role.attrib; %local.keyword.attrib; > <!--end of keyword.attlist-->]]> <!--end of keyword.module-->]]> <!--end of keywordset.content.module-->]]> <!ENTITY % itermset.module "INCLUDE"> <![%itermset.module;[ <!ENTITY % local.itermset.attrib ""> <!ENTITY % itermset.role.attrib "%role.attrib;"> <!ENTITY % itermset.element "INCLUDE"> <![%itermset.element;[ <!--doc:A set of index terms in the meta-information of a document.--> <!ELEMENT itermset %ho; (indexterm+)> <!--end of itermset.element-->]]> <!ENTITY % itermset.attlist "INCLUDE"> <![%itermset.attlist;[ <!ATTLIST itermset %common.attrib; %itermset.role.attrib; %local.itermset.attrib; > <!--end of itermset.attlist-->]]> <!--end of itermset.module-->]]> <!-- Bibliographic info for "blocks" --> <!ENTITY % blockinfo.module "INCLUDE"> <![ %blockinfo.module; [ <!ENTITY % local.blockinfo.attrib ""> <!ENTITY % blockinfo.role.attrib "%role.attrib;"> <!ENTITY % blockinfo.element "INCLUDE"> <![ %blockinfo.element; [ <!--doc:Meta-information for a block element.--> <!ELEMENT blockinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of blockinfo.element-->]]> <!ENTITY % blockinfo.attlist "INCLUDE"> <![ %blockinfo.attlist; [ <!ATTLIST blockinfo %common.attrib; %blockinfo.role.attrib; %local.blockinfo.attrib; > <!--end of blockinfo.attlist-->]]> <!--end of blockinfo.module-->]]> <!-- ...................................................................... --> <!-- Compound (section-ish) elements ...................................... --> <!-- Message set ...................... --> <!ENTITY % msgset.content.module "INCLUDE"> <![%msgset.content.module;[ <!ENTITY % msgset.module "INCLUDE"> <![%msgset.module;[ <!ENTITY % local.msgset.attrib ""> <!ENTITY % msgset.role.attrib "%role.attrib;"> <!ENTITY % msgset.element "INCLUDE"> <![%msgset.element;[ <!--doc:A detailed set of messages, usually error messages.--> <!ELEMENT msgset %ho; (blockinfo?, (%formalobject.title.content;)?, (msgentry+|simplemsgentry+))> <!--end of msgset.element-->]]> <!ENTITY % msgset.attlist "INCLUDE"> <![%msgset.attlist;[ <!ATTLIST msgset %common.attrib; %msgset.role.attrib; %local.msgset.attrib; > <!--end of msgset.attlist-->]]> <!--end of msgset.module-->]]> <!ENTITY % msgentry.module "INCLUDE"> <![%msgentry.module;[ <!ENTITY % local.msgentry.attrib ""> <!ENTITY % msgentry.role.attrib "%role.attrib;"> <!ENTITY % msgentry.element "INCLUDE"> <![%msgentry.element;[ <!--doc:A wrapper for an entry in a message set.--> <!ELEMENT msgentry %ho; (msg+, msginfo?, msgexplan*)> <!--end of msgentry.element-->]]> <!ENTITY % msgentry.attlist "INCLUDE"> <![%msgentry.attlist;[ <!ATTLIST msgentry %common.attrib; %msgentry.role.attrib; %local.msgentry.attrib; > <!--end of msgentry.attlist-->]]> <!--end of msgentry.module-->]]> <!ENTITY % simplemsgentry.module "INCLUDE"> <![ %simplemsgentry.module; [ <!ENTITY % local.simplemsgentry.attrib ""> <!ENTITY % simplemsgentry.role.attrib "%role.attrib;"> <!ENTITY % simplemsgentry.element "INCLUDE"> <![ %simplemsgentry.element; [ <!--doc:A wrapper for a simpler entry in a message set.--> <!ELEMENT simplemsgentry %ho; (msgtext, msgexplan+)> <!--end of simplemsgentry.element-->]]> <!ENTITY % simplemsgentry.attlist "INCLUDE"> <![ %simplemsgentry.attlist; [ <!ATTLIST simplemsgentry audience CDATA #IMPLIED level CDATA #IMPLIED origin CDATA #IMPLIED %common.attrib; %simplemsgentry.role.attrib; %local.simplemsgentry.attrib; > <!--end of simplemsgentry.attlist-->]]> <!--end of simplemsgentry.module-->]]> <!ENTITY % msg.module "INCLUDE"> <![%msg.module;[ <!ENTITY % local.msg.attrib ""> <!ENTITY % msg.role.attrib "%role.attrib;"> <!ENTITY % msg.element "INCLUDE"> <![%msg.element;[ <!--doc:A message in a message set.--> <!ELEMENT msg %ho; (title?, msgmain, (msgsub | msgrel)*)> <!--end of msg.element-->]]> <!ENTITY % msg.attlist "INCLUDE"> <![%msg.attlist;[ <!ATTLIST msg %common.attrib; %msg.role.attrib; %local.msg.attrib; > <!--end of msg.attlist-->]]> <!--end of msg.module-->]]> <!ENTITY % msgmain.module "INCLUDE"> <![%msgmain.module;[ <!ENTITY % local.msgmain.attrib ""> <!ENTITY % msgmain.role.attrib "%role.attrib;"> <!ENTITY % msgmain.element "INCLUDE"> <![%msgmain.element;[ <!--doc:The primary component of a message in a message set.--> <!ELEMENT msgmain %ho; (title?, msgtext)> <!--end of msgmain.element-->]]> <!ENTITY % msgmain.attlist "INCLUDE"> <![%msgmain.attlist;[ <!ATTLIST msgmain %common.attrib; %msgmain.role.attrib; %local.msgmain.attrib; > <!--end of msgmain.attlist-->]]> <!--end of msgmain.module-->]]> <!ENTITY % msgsub.module "INCLUDE"> <![%msgsub.module;[ <!ENTITY % local.msgsub.attrib ""> <!ENTITY % msgsub.role.attrib "%role.attrib;"> <!ENTITY % msgsub.element "INCLUDE"> <![%msgsub.element;[ <!--doc:A subcomponent of a message in a message set.--> <!ELEMENT msgsub %ho; (title?, msgtext)> <!--end of msgsub.element-->]]> <!ENTITY % msgsub.attlist "INCLUDE"> <![%msgsub.attlist;[ <!ATTLIST msgsub %common.attrib; %msgsub.role.attrib; %local.msgsub.attrib; > <!--end of msgsub.attlist-->]]> <!--end of msgsub.module-->]]> <!ENTITY % msgrel.module "INCLUDE"> <![%msgrel.module;[ <!ENTITY % local.msgrel.attrib ""> <!ENTITY % msgrel.role.attrib "%role.attrib;"> <!ENTITY % msgrel.element "INCLUDE"> <![%msgrel.element;[ <!--doc:A related component of a message in a message set.--> <!ELEMENT msgrel %ho; (title?, msgtext)> <!--end of msgrel.element-->]]> <!ENTITY % msgrel.attlist "INCLUDE"> <![%msgrel.attlist;[ <!ATTLIST msgrel %common.attrib; %msgrel.role.attrib; %local.msgrel.attrib; > <!--end of msgrel.attlist-->]]> <!--end of msgrel.module-->]]> <!-- MsgText (defined in the Inlines section, below)--> <!ENTITY % msginfo.module "INCLUDE"> <![%msginfo.module;[ <!ENTITY % local.msginfo.attrib ""> <!ENTITY % msginfo.role.attrib "%role.attrib;"> <!ENTITY % msginfo.element "INCLUDE"> <![%msginfo.element;[ <!--doc:Information about a message in a message set.--> <!ELEMENT msginfo %ho; ((msglevel | msgorig | msgaud)*)> <!--end of msginfo.element-->]]> <!ENTITY % msginfo.attlist "INCLUDE"> <![%msginfo.attlist;[ <!ATTLIST msginfo %common.attrib; %msginfo.role.attrib; %local.msginfo.attrib; > <!--end of msginfo.attlist-->]]> <!--end of msginfo.module-->]]> <!ENTITY % msglevel.module "INCLUDE"> <![%msglevel.module;[ <!ENTITY % local.msglevel.attrib ""> <!ENTITY % msglevel.role.attrib "%role.attrib;"> <!ENTITY % msglevel.element "INCLUDE"> <![%msglevel.element;[ <!--doc:The level of importance or severity of a message in a message set.--> <!ELEMENT msglevel %ho; (%smallcptr.char.mix;)*> <!--end of msglevel.element-->]]> <!ENTITY % msglevel.attlist "INCLUDE"> <![%msglevel.attlist;[ <!ATTLIST msglevel %common.attrib; %msglevel.role.attrib; %local.msglevel.attrib; > <!--end of msglevel.attlist-->]]> <!--end of msglevel.module-->]]> <!ENTITY % msgorig.module "INCLUDE"> <![%msgorig.module;[ <!ENTITY % local.msgorig.attrib ""> <!ENTITY % msgorig.role.attrib "%role.attrib;"> <!ENTITY % msgorig.element "INCLUDE"> <![%msgorig.element;[ <!--doc:The origin of a message in a message set.--> <!ELEMENT msgorig %ho; (%smallcptr.char.mix;)*> <!--end of msgorig.element-->]]> <!ENTITY % msgorig.attlist "INCLUDE"> <![%msgorig.attlist;[ <!ATTLIST msgorig %common.attrib; %msgorig.role.attrib; %local.msgorig.attrib; > <!--end of msgorig.attlist-->]]> <!--end of msgorig.module-->]]> <!ENTITY % msgaud.module "INCLUDE"> <![%msgaud.module;[ <!ENTITY % local.msgaud.attrib ""> <!ENTITY % msgaud.role.attrib "%role.attrib;"> <!ENTITY % msgaud.element "INCLUDE"> <![%msgaud.element;[ <!--doc:The audience to which a message in a message set is relevant.--> <!ELEMENT msgaud %ho; (%para.char.mix;)*> <!--end of msgaud.element-->]]> <!ENTITY % msgaud.attlist "INCLUDE"> <![%msgaud.attlist;[ <!ATTLIST msgaud %common.attrib; %msgaud.role.attrib; %local.msgaud.attrib; > <!--end of msgaud.attlist-->]]> <!--end of msgaud.module-->]]> <!ENTITY % msgexplan.module "INCLUDE"> <![%msgexplan.module;[ <!ENTITY % local.msgexplan.attrib ""> <!ENTITY % msgexplan.role.attrib "%role.attrib;"> <!ENTITY % msgexplan.element "INCLUDE"> <![%msgexplan.element;[ <!--doc:Explanatory material relating to a message in a message set.--> <!ELEMENT msgexplan %ho; (title?, (%component.mix;)+)> <!--end of msgexplan.element-->]]> <!ENTITY % msgexplan.attlist "INCLUDE"> <![%msgexplan.attlist;[ <!ATTLIST msgexplan %common.attrib; %msgexplan.role.attrib; %local.msgexplan.attrib; > <!--end of msgexplan.attlist-->]]> <!--end of msgexplan.module-->]]> <!--end of msgset.content.module-->]]> <!ENTITY % task.content.module "INCLUDE"> <![%task.content.module;[ <!ENTITY % task.module "INCLUDE"> <![%task.module;[ <!ENTITY % local.task.attrib ""> <!ENTITY % task.role.attrib "%role.attrib;"> <!ENTITY % task.element "INCLUDE"> <![%task.element;[ <!--doc:A task to be completed.--> <!ELEMENT task %ho; (blockinfo?,(%ndxterm.class;)*, (%formalobject.title.content;), tasksummary?, taskprerequisites?, procedure, example*, taskrelated?)> <!--end of task.element-->]]> <!ENTITY % task.attlist "INCLUDE"> <![%task.attlist;[ <!ATTLIST task %common.attrib; %task.role.attrib; %local.task.attrib; > <!--end of task.attlist-->]]> <!--end of task.module-->]]> <!ENTITY % tasksummary.module "INCLUDE"> <![%tasksummary.module;[ <!ENTITY % local.tasksummary.attrib ""> <!ENTITY % tasksummary.role.attrib "%role.attrib;"> <!ENTITY % tasksummary.element "INCLUDE"> <![%tasksummary.element;[ <!--doc:A summary of a task.--> <!ELEMENT tasksummary %ho; (blockinfo?, (%formalobject.title.content;)?, (%component.mix;)+)> <!--end of tasksummary.element-->]]> <!ENTITY % tasksummary.attlist "INCLUDE"> <![%tasksummary.attlist;[ <!ATTLIST tasksummary %common.attrib; %tasksummary.role.attrib; %local.tasksummary.attrib; > <!--end of tasksummary.attlist-->]]> <!--end of tasksummary.module-->]]> <!ENTITY % taskprerequisites.module "INCLUDE"> <![%taskprerequisites.module;[ <!ENTITY % local.taskprerequisites.attrib ""> <!ENTITY % taskprerequisites.role.attrib "%role.attrib;"> <!ENTITY % taskprerequisites.element "INCLUDE"> <![%taskprerequisites.element;[ <!--doc:The prerequisites for a task.--> <!ELEMENT taskprerequisites %ho; (blockinfo?, (%formalobject.title.content;)?, (%component.mix;)+)> <!--end of taskprerequisites.element-->]]> <!ENTITY % taskprerequisites.attlist "INCLUDE"> <![%taskprerequisites.attlist;[ <!ATTLIST taskprerequisites %common.attrib; %taskprerequisites.role.attrib; %local.taskprerequisites.attrib; > <!--end of taskprerequisites.attlist-->]]> <!--end of taskprerequisites.module-->]]> <!ENTITY % taskrelated.module "INCLUDE"> <![%taskrelated.module;[ <!ENTITY % local.taskrelated.attrib ""> <!ENTITY % taskrelated.role.attrib "%role.attrib;"> <!ENTITY % taskrelated.element "INCLUDE"> <![%taskrelated.element;[ <!--doc:Information related to a task.--> <!ELEMENT taskrelated %ho; (blockinfo?, (%formalobject.title.content;)?, (%component.mix;)+)> <!--end of taskrelated.element-->]]> <!ENTITY % taskrelated.attlist "INCLUDE"> <![%taskrelated.attlist;[ <!ATTLIST taskrelated %common.attrib; %taskrelated.role.attrib; %local.taskrelated.attrib; > <!--end of taskrelated.attlist-->]]> <!--end of taskrelated.module-->]]> <!--end of task.content.module-->]]> <!-- QandASet ........................ --> <!ENTITY % qandaset.content.module "INCLUDE"> <![ %qandaset.content.module; [ <!ENTITY % qandaset.module "INCLUDE"> <![ %qandaset.module; [ <!ENTITY % local.qandaset.attrib ""> <!ENTITY % qandaset.role.attrib "%role.attrib;"> <!ENTITY % qandaset.element "INCLUDE"> <![ %qandaset.element; [ <!--doc:A question-and-answer set.--> <!ELEMENT qandaset %ho; (blockinfo?, (%formalobject.title.content;)?, (%qandaset.mix;)*, (qandadiv+|qandaentry+))> <!--end of qandaset.element-->]]> <!ENTITY % qandaset.attlist "INCLUDE"> <![ %qandaset.attlist; [ <!ATTLIST qandaset defaultlabel (qanda|number|none) #IMPLIED %common.attrib; %qandaset.role.attrib; %local.qandaset.attrib;> <!--end of qandaset.attlist-->]]> <!--end of qandaset.module-->]]> <!ENTITY % qandadiv.module "INCLUDE"> <![ %qandadiv.module; [ <!ENTITY % local.qandadiv.attrib ""> <!ENTITY % qandadiv.role.attrib "%role.attrib;"> <!ENTITY % qandadiv.element "INCLUDE"> <![ %qandadiv.element; [ <!--doc:A titled division in a QandASet.--> <!ELEMENT qandadiv %ho; (blockinfo?, (%formalobject.title.content;)?, (%qandaset.mix;)*, (qandadiv+|qandaentry+))> <!--end of qandadiv.element-->]]> <!ENTITY % qandadiv.attlist "INCLUDE"> <![ %qandadiv.attlist; [ <!ATTLIST qandadiv %common.attrib; %qandadiv.role.attrib; %local.qandadiv.attrib;> <!--end of qandadiv.attlist-->]]> <!--end of qandadiv.module-->]]> <!ENTITY % qandaentry.module "INCLUDE"> <![ %qandaentry.module; [ <!ENTITY % local.qandaentry.attrib ""> <!ENTITY % qandaentry.role.attrib "%role.attrib;"> <!ENTITY % qandaentry.element "INCLUDE"> <![ %qandaentry.element; [ <!--doc:A question/answer set within a QandASet.--> <!ELEMENT qandaentry %ho; (blockinfo?, revhistory?, question, answer*)> <!--end of qandaentry.element-->]]> <!ENTITY % qandaentry.attlist "INCLUDE"> <![ %qandaentry.attlist; [ <!ATTLIST qandaentry %common.attrib; %qandaentry.role.attrib; %local.qandaentry.attrib;> <!--end of qandaentry.attlist-->]]> <!--end of qandaentry.module-->]]> <!ENTITY % question.module "INCLUDE"> <![ %question.module; [ <!ENTITY % local.question.attrib ""> <!ENTITY % question.role.attrib "%role.attrib;"> <!ENTITY % question.element "INCLUDE"> <![ %question.element; [ <!--doc:A question in a QandASet.--> <!ELEMENT question %ho; (label?, (%qandaset.mix;)+)> <!--end of question.element-->]]> <!ENTITY % question.attlist "INCLUDE"> <![ %question.attlist; [ <!ATTLIST question %common.attrib; %question.role.attrib; %local.question.attrib; > <!--end of question.attlist-->]]> <!--end of question.module-->]]> <!ENTITY % answer.module "INCLUDE"> <![ %answer.module; [ <!ENTITY % local.answer.attrib ""> <!ENTITY % answer.role.attrib "%role.attrib;"> <!ENTITY % answer.element "INCLUDE"> <![ %answer.element; [ <!--doc:An answer to a question posed in a QandASet.--> <!ELEMENT answer %ho; (label?, (%qandaset.mix;)*, qandaentry*)> <!--end of answer.element-->]]> <!ENTITY % answer.attlist "INCLUDE"> <![ %answer.attlist; [ <!ATTLIST answer %common.attrib; %answer.role.attrib; %local.answer.attrib; > <!--end of answer.attlist-->]]> <!--end of answer.module-->]]> <!ENTITY % label.module "INCLUDE"> <![ %label.module; [ <!ENTITY % local.label.attrib ""> <!ENTITY % label.role.attrib "%role.attrib;"> <!ENTITY % label.element "INCLUDE"> <![ %label.element; [ <!--doc:A label on a Question or Answer.--> <!ELEMENT label %ho; (%word.char.mix;)*> <!--end of label.element-->]]> <!ENTITY % label.attlist "INCLUDE"> <![ %label.attlist; [ <!ATTLIST label %common.attrib; %label.role.attrib; %local.label.attrib; > <!--end of label.attlist-->]]> <!--end of label.module-->]]> <!--end of qandaset.content.module-->]]> <!-- Procedure ........................ --> <!ENTITY % procedure.content.module "INCLUDE"> <![%procedure.content.module;[ <!ENTITY % procedure.module "INCLUDE"> <![%procedure.module;[ <!ENTITY % local.procedure.attrib ""> <!ENTITY % procedure.role.attrib "%role.attrib;"> <!ENTITY % procedure.element "INCLUDE"> <![%procedure.element;[ <!--doc:A list of operations to be performed in a well-defined sequence.--> <!ELEMENT procedure %ho; (blockinfo?, (%formalobject.title.content;)?, (%component.mix;)*, step+)> <!--end of procedure.element-->]]> <!ENTITY % procedure.attlist "INCLUDE"> <![%procedure.attlist;[ <!ATTLIST procedure %common.attrib; %procedure.role.attrib; %local.procedure.attrib; > <!--end of procedure.attlist-->]]> <!--end of procedure.module-->]]> <!ENTITY % step.module "INCLUDE"> <![%step.module;[ <!ENTITY % local.step.attrib ""> <!ENTITY % step.role.attrib "%role.attrib;"> <!ENTITY % step.element "INCLUDE"> <![%step.element;[ <!--doc:A unit of action in a procedure.--> <!ELEMENT step %ho; (title?, (((%component.mix;)+, ((substeps|stepalternatives), (%component.mix;)*)?) | ((substeps|stepalternatives), (%component.mix;)*)))> <!--end of step.element-->]]> <!-- Performance: Whether the Step must be performed --> <!-- not #REQUIRED! --> <!ENTITY % step.attlist "INCLUDE"> <![%step.attlist;[ <!ATTLIST step performance (optional |required) "required" %common.attrib; %step.role.attrib; %local.step.attrib; > <!--end of step.attlist-->]]> <!--end of step.module-->]]> <!ENTITY % substeps.module "INCLUDE"> <![%substeps.module;[ <!ENTITY % local.substeps.attrib ""> <!ENTITY % substeps.role.attrib "%role.attrib;"> <!ENTITY % substeps.element "INCLUDE"> <![%substeps.element;[ <!--doc:A wrapper for steps that occur within steps in a procedure.--> <!ELEMENT substeps %ho; (step+)> <!--end of substeps.element-->]]> <!-- Performance: whether entire set of substeps must be performed --> <!-- not #REQUIRED! --> <!ENTITY % substeps.attlist "INCLUDE"> <![%substeps.attlist;[ <!ATTLIST substeps performance (optional |required) "required" %common.attrib; %substeps.role.attrib; %local.substeps.attrib; > <!--end of substeps.attlist-->]]> <!--end of substeps.module-->]]> <!ENTITY % stepalternatives.module "INCLUDE"> <![%stepalternatives.module;[ <!ENTITY % local.stepalternatives.attrib ""> <!ENTITY % stepalternatives.role.attrib "%role.attrib;"> <!ENTITY % stepalternatives.element "INCLUDE"> <![%stepalternatives.element;[ <!--doc:Alternative steps in a procedure.--> <!ELEMENT stepalternatives %ho; (step+)> <!--end of stepalternatives.element-->]]> <!-- Performance: Whether (one of) the alternatives must be performed --> <!-- not #REQUIRED! --> <!ENTITY % stepalternatives.attlist "INCLUDE"> <![%stepalternatives.attlist;[ <!ATTLIST stepalternatives performance (optional |required) "required" %common.attrib; %stepalternatives.role.attrib; %local.stepalternatives.attrib; > <!--end of stepalternatives.attlist-->]]> <!--end of stepalternatives.module-->]]> <!--end of procedure.content.module-->]]> <!-- Sidebar .......................... --> <!ENTITY % sidebar.content.model "INCLUDE"> <![ %sidebar.content.model; [ <!ENTITY % sidebarinfo.module "INCLUDE"> <![ %sidebarinfo.module; [ <!ENTITY % local.sidebarinfo.attrib ""> <!ENTITY % sidebarinfo.role.attrib "%role.attrib;"> <!ENTITY % sidebarinfo.element "INCLUDE"> <![ %sidebarinfo.element; [ <!--doc:Meta-information for a Sidebar.--> <!ELEMENT sidebarinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of sidebarinfo.element-->]]> <!ENTITY % sidebarinfo.attlist "INCLUDE"> <![ %sidebarinfo.attlist; [ <!ATTLIST sidebarinfo %common.attrib; %sidebarinfo.role.attrib; %local.sidebarinfo.attrib; > <!--end of sidebarinfo.attlist-->]]> <!--end of sidebarinfo.module-->]]> <!ENTITY % sidebar.module "INCLUDE"> <![%sidebar.module;[ <!ENTITY % local.sidebar.attrib ""> <!ENTITY % sidebar.role.attrib "%role.attrib;"> <!ENTITY % sidebar.element "INCLUDE"> <![%sidebar.element;[ <!--doc:A portion of a document that is isolated from the main narrative flow.--> <!ELEMENT sidebar %ho; (sidebarinfo?, (%formalobject.title.content;)?, (%sidebar.mix;)+)> <!--end of sidebar.element-->]]> <!ENTITY % sidebar.attlist "INCLUDE"> <![%sidebar.attlist;[ <!ATTLIST sidebar %common.attrib; %sidebar.role.attrib; %local.sidebar.attrib; > <!--end of sidebar.attlist-->]]> <!--end of sidebar.module-->]]> <!--end of sidebar.content.model-->]]> <!-- ...................................................................... --> <!-- Paragraph-related elements ........................................... --> <!ENTITY % abstract.module "INCLUDE"> <![%abstract.module;[ <!ENTITY % local.abstract.attrib ""> <!ENTITY % abstract.role.attrib "%role.attrib;"> <!ENTITY % abstract.element "INCLUDE"> <![%abstract.element;[ <!--doc:A summary.--> <!ELEMENT abstract %ho; (title?, (%para.class;)+)> <!--end of abstract.element-->]]> <!ENTITY % abstract.attlist "INCLUDE"> <![%abstract.attlist;[ <!ATTLIST abstract %common.attrib; %abstract.role.attrib; %local.abstract.attrib; > <!--end of abstract.attlist-->]]> <!--end of abstract.module-->]]> <!ENTITY % authorblurb.module "INCLUDE"> <![%authorblurb.module;[ <!ENTITY % local.authorblurb.attrib ""> <!ENTITY % authorblurb.role.attrib "%role.attrib;"> <!ENTITY % authorblurb.element "INCLUDE"> <![%authorblurb.element;[ <!--doc:A short description or note about an author.--> <!ELEMENT authorblurb %ho; (title?, (%para.class;)+)> <!--end of authorblurb.element-->]]> <!ENTITY % authorblurb.attlist "INCLUDE"> <![%authorblurb.attlist;[ <!ATTLIST authorblurb %common.attrib; %authorblurb.role.attrib; %local.authorblurb.attrib; > <!--end of authorblurb.attlist-->]]> <!--end of authorblurb.module-->]]> <!ENTITY % personblurb.module "INCLUDE"> <![%personblurb.module;[ <!ENTITY % local.personblurb.attrib ""> <!ENTITY % personblurb.role.attrib "%role.attrib;"> <!ENTITY % personblurb.element "INCLUDE"> <![%personblurb.element;[ <!--doc:A short description or note about a person.--> <!ELEMENT personblurb %ho; (title?, (%para.class;)+)> <!--end of personblurb.element-->]]> <!ENTITY % personblurb.attlist "INCLUDE"> <![%personblurb.attlist;[ <!ATTLIST personblurb %common.attrib; %personblurb.role.attrib; %local.personblurb.attrib; > <!--end of personblurb.attlist-->]]> <!--end of personblurb.module-->]]> <!ENTITY % blockquote.module "INCLUDE"> <![%blockquote.module;[ <!ENTITY % local.blockquote.attrib ""> <!ENTITY % blockquote.role.attrib "%role.attrib;"> <!ENTITY % blockquote.element "INCLUDE"> <![%blockquote.element;[ <!--doc:A quotation set off from the main text.--> <!ELEMENT blockquote %ho; (blockinfo?, title?, attribution?, (%component.mix;)+) %blockquote.exclusion;> <!--end of blockquote.element-->]]> <!ENTITY % blockquote.attlist "INCLUDE"> <![%blockquote.attlist;[ <!ATTLIST blockquote %common.attrib; %blockquote.role.attrib; %local.blockquote.attrib; > <!--end of blockquote.attlist-->]]> <!--end of blockquote.module-->]]> <!ENTITY % attribution.module "INCLUDE"> <![%attribution.module;[ <!ENTITY % local.attribution.attrib ""> <!ENTITY % attribution.role.attrib "%role.attrib;"> <!ENTITY % attribution.element "INCLUDE"> <![%attribution.element;[ <!--doc:The source of a block quote or epigraph.--> <!ELEMENT attribution %ho; (%para.char.mix;)*> <!--end of attribution.element-->]]> <!ENTITY % attribution.attlist "INCLUDE"> <![%attribution.attlist;[ <!ATTLIST attribution %common.attrib; %attribution.role.attrib; %local.attribution.attrib; > <!--end of attribution.attlist-->]]> <!--end of attribution.module-->]]> <!ENTITY % bridgehead.module "INCLUDE"> <![%bridgehead.module;[ <!ENTITY % local.bridgehead.attrib ""> <!ENTITY % bridgehead.role.attrib "%role.attrib;"> <!ENTITY % bridgehead.element "INCLUDE"> <![%bridgehead.element;[ <!--doc:A free-floating heading.--> <!ELEMENT bridgehead %ho; (%title.char.mix;)*> <!--end of bridgehead.element-->]]> <!-- Renderas: Indicates the format in which the BridgeHead should appear --> <!ENTITY % bridgehead.attlist "INCLUDE"> <![%bridgehead.attlist;[ <!ATTLIST bridgehead renderas (other |sect1 |sect2 |sect3 |sect4 |sect5) #IMPLIED %common.attrib; %bridgehead.role.attrib; %local.bridgehead.attrib; > <!--end of bridgehead.attlist-->]]> <!--end of bridgehead.module-->]]> <!ENTITY % remark.module "INCLUDE"> <![%remark.module;[ <!ENTITY % local.remark.attrib ""> <!ENTITY % remark.role.attrib "%role.attrib;"> <!ENTITY % remark.element "INCLUDE"> <![%remark.element;[ <!--doc:A remark (or comment) intended for presentation in a draft manuscript.--> <!ELEMENT remark %ho; (%para.char.mix;)* %remark.exclusion;> <!--end of remark.element-->]]> <!ENTITY % remark.attlist "INCLUDE"> <![%remark.attlist;[ <!ATTLIST remark %common.attrib; %remark.role.attrib; %local.remark.attrib; > <!--end of remark.attlist-->]]> <!--end of remark.module-->]]> <!ENTITY % epigraph.module "INCLUDE"> <![%epigraph.module;[ <!ENTITY % local.epigraph.attrib ""> <!ENTITY % epigraph.role.attrib "%role.attrib;"> <!ENTITY % epigraph.element "INCLUDE"> <![%epigraph.element;[ <!--doc:A short inscription at the beginning of a document or component.--> <!ELEMENT epigraph %ho; (attribution?, ((%para.class;)|literallayout)+)> <!--end of epigraph.element-->]]> <!ENTITY % epigraph.attlist "INCLUDE"> <![%epigraph.attlist;[ <!ATTLIST epigraph %common.attrib; %epigraph.role.attrib; %local.epigraph.attrib; > <!--end of epigraph.attlist-->]]> <!-- Attribution (defined above)--> <!--end of epigraph.module-->]]> <!ENTITY % footnote.module "INCLUDE"> <![%footnote.module;[ <!ENTITY % local.footnote.attrib ""> <!ENTITY % footnote.role.attrib "%role.attrib;"> <!ENTITY % footnote.element "INCLUDE"> <![%footnote.element;[ <!--doc:A footnote.--> <!ELEMENT footnote %ho; ((%footnote.mix;)+) %footnote.exclusion;> <!--end of footnote.element-->]]> <!ENTITY % footnote.attlist "INCLUDE"> <![%footnote.attlist;[ <!ATTLIST footnote %label.attrib; %common.attrib; %footnote.role.attrib; %local.footnote.attrib; > <!--end of footnote.attlist-->]]> <!--end of footnote.module-->]]> <!ENTITY % highlights.module "INCLUDE"> <![%highlights.module;[ <!ENTITY % local.highlights.attrib ""> <!ENTITY % highlights.role.attrib "%role.attrib;"> <!ENTITY % highlights.element "INCLUDE"> <![%highlights.element;[ <!--doc:A summary of the main points of the discussed component.--> <!ELEMENT highlights %ho; ((%highlights.mix;)+) %highlights.exclusion;> <!--end of highlights.element-->]]> <!ENTITY % highlights.attlist "INCLUDE"> <![%highlights.attlist;[ <!ATTLIST highlights %common.attrib; %highlights.role.attrib; %local.highlights.attrib; > <!--end of highlights.attlist-->]]> <!--end of highlights.module-->]]> <!ENTITY % formalpara.module "INCLUDE"> <![%formalpara.module;[ <!ENTITY % local.formalpara.attrib ""> <!ENTITY % formalpara.role.attrib "%role.attrib;"> <!ENTITY % formalpara.element "INCLUDE"> <![%formalpara.element;[ <!--doc:A paragraph with a title.--> <!ELEMENT formalpara %ho; (title, (%ndxterm.class;)*, para)> <!--end of formalpara.element-->]]> <!ENTITY % formalpara.attlist "INCLUDE"> <![%formalpara.attlist;[ <!ATTLIST formalpara %common.attrib; %formalpara.role.attrib; %local.formalpara.attrib; > <!--end of formalpara.attlist-->]]> <!--end of formalpara.module-->]]> <!ENTITY % para.module "INCLUDE"> <![%para.module;[ <!ENTITY % local.para.attrib ""> <!ENTITY % para.role.attrib "%role.attrib;"> <!ENTITY % para.element "INCLUDE"> <![%para.element;[ <!--doc:A paragraph.--> <!ELEMENT para %ho; (%para.char.mix; | %para.mix;)*> <!--end of para.element-->]]> <!ENTITY % para.attlist "INCLUDE"> <![%para.attlist;[ <!ATTLIST para %common.attrib; %para.role.attrib; %local.para.attrib; > <!--end of para.attlist-->]]> <!--end of para.module-->]]> <!ENTITY % simpara.module "INCLUDE"> <![%simpara.module;[ <!ENTITY % local.simpara.attrib ""> <!ENTITY % simpara.role.attrib "%role.attrib;"> <!ENTITY % simpara.element "INCLUDE"> <![%simpara.element;[ <!--doc:A paragraph that contains only text and inline markup, no block elements.--> <!ELEMENT simpara %ho; (%para.char.mix;)*> <!--end of simpara.element-->]]> <!ENTITY % simpara.attlist "INCLUDE"> <![%simpara.attlist;[ <!ATTLIST simpara %common.attrib; %simpara.role.attrib; %local.simpara.attrib; > <!--end of simpara.attlist-->]]> <!--end of simpara.module-->]]> <!ENTITY % admon.module "INCLUDE"> <![%admon.module;[ <!ENTITY % local.admon.attrib ""> <!ENTITY % admon.role.attrib "%role.attrib;"> <!ENTITY % caution.element "INCLUDE"> <![%caution.element;[ <!--doc:A note of caution.--> <!ELEMENT caution %ho; (title?, (%admon.mix;)+) %admon.exclusion;> <!--end of caution.element-->]]> <!ENTITY % caution.attlist "INCLUDE"> <![%caution.attlist;[ <!ATTLIST caution %common.attrib; %admon.role.attrib; %local.admon.attrib; > <!--end of caution.attlist-->]]> <!ENTITY % important.element "INCLUDE"> <![%important.element;[ <!--doc:An admonition set off from the text.--> <!ELEMENT important %ho; (title?, (%admon.mix;)+) %admon.exclusion;> <!--end of important.element-->]]> <!ENTITY % important.attlist "INCLUDE"> <![%important.attlist;[ <!ATTLIST important %common.attrib; %admon.role.attrib; %local.admon.attrib; > <!--end of important.attlist-->]]> <!ENTITY % note.element "INCLUDE"> <![%note.element;[ <!--doc:A message set off from the text.--> <!ELEMENT note %ho; (title?, (%admon.mix;)+) %admon.exclusion;> <!--end of note.element-->]]> <!ENTITY % note.attlist "INCLUDE"> <![%note.attlist;[ <!ATTLIST note %common.attrib; %admon.role.attrib; %local.admon.attrib; > <!--end of note.attlist-->]]> <!ENTITY % tip.element "INCLUDE"> <![%tip.element;[ <!--doc:A suggestion to the user, set off from the text.--> <!ELEMENT tip %ho; (title?, (%admon.mix;)+) %admon.exclusion;> <!--end of tip.element-->]]> <!ENTITY % tip.attlist "INCLUDE"> <![%tip.attlist;[ <!ATTLIST tip %common.attrib; %admon.role.attrib; %local.admon.attrib; > <!--end of tip.attlist-->]]> <!ENTITY % warning.element "INCLUDE"> <![%warning.element;[ <!--doc:An admonition set off from the text.--> <!ELEMENT warning %ho; (title?, (%admon.mix;)+) %admon.exclusion;> <!--end of warning.element-->]]> <!ENTITY % warning.attlist "INCLUDE"> <![%warning.attlist;[ <!ATTLIST warning %common.attrib; %admon.role.attrib; %local.admon.attrib; > <!--end of warning.attlist-->]]> <!--end of admon.module-->]]> <!-- ...................................................................... --> <!-- Lists ................................................................ --> <!-- GlossList ........................ --> <!ENTITY % glosslist.module "INCLUDE"> <![%glosslist.module;[ <!ENTITY % local.glosslist.attrib ""> <!ENTITY % glosslist.role.attrib "%role.attrib;"> <!ENTITY % glosslist.element "INCLUDE"> <![%glosslist.element;[ <!--doc:A wrapper for a set of GlossEntrys.--> <!ELEMENT glosslist %ho; (blockinfo?, (%formalobject.title.content;)?, glossentry+)> <!--end of glosslist.element-->]]> <!ENTITY % glosslist.attlist "INCLUDE"> <![%glosslist.attlist;[ <!ATTLIST glosslist %common.attrib; %glosslist.role.attrib; %local.glosslist.attrib; > <!--end of glosslist.attlist-->]]> <!--end of glosslist.module-->]]> <!ENTITY % glossentry.content.module "INCLUDE"> <![%glossentry.content.module;[ <!ENTITY % glossentry.module "INCLUDE"> <![%glossentry.module;[ <!ENTITY % local.glossentry.attrib ""> <!ENTITY % glossentry.role.attrib "%role.attrib;"> <!ENTITY % glossentry.element "INCLUDE"> <![%glossentry.element;[ <!--doc:An entry in a Glossary or GlossList.--> <!ELEMENT glossentry %ho; (glossterm, acronym?, abbrev?, (%ndxterm.class;)*, revhistory?, (glosssee|glossdef+))> <!--end of glossentry.element-->]]> <!-- SortAs: String by which the GlossEntry is to be sorted (alphabetized) in lieu of its proper content --> <!ENTITY % glossentry.attlist "INCLUDE"> <![%glossentry.attlist;[ <!ATTLIST glossentry sortas CDATA #IMPLIED %common.attrib; %glossentry.role.attrib; %local.glossentry.attrib; > <!--end of glossentry.attlist-->]]> <!--end of glossentry.module-->]]> <!-- GlossTerm (defined in the Inlines section, below)--> <!ENTITY % glossdef.module "INCLUDE"> <![%glossdef.module;[ <!ENTITY % local.glossdef.attrib ""> <!ENTITY % glossdef.role.attrib "%role.attrib;"> <!ENTITY % glossdef.element "INCLUDE"> <![%glossdef.element;[ <!--doc:A definition in a GlossEntry.--> <!ELEMENT glossdef %ho; ((%glossdef.mix;)+, glossseealso*)> <!--end of glossdef.element-->]]> <!-- Subject: List of subjects; keywords for the definition --> <!ENTITY % glossdef.attlist "INCLUDE"> <![%glossdef.attlist;[ <!ATTLIST glossdef subject CDATA #IMPLIED %common.attrib; %glossdef.role.attrib; %local.glossdef.attrib; > <!--end of glossdef.attlist-->]]> <!--end of glossdef.module-->]]> <!ENTITY % glosssee.module "INCLUDE"> <![%glosssee.module;[ <!ENTITY % local.glosssee.attrib ""> <!ENTITY % glosssee.role.attrib "%role.attrib;"> <!ENTITY % glosssee.element "INCLUDE"> <![%glosssee.element;[ <!--doc:A cross-reference from one GlossEntry to another.--> <!ELEMENT glosssee %ho; (%para.char.mix;)*> <!--end of glosssee.element-->]]> <!-- OtherTerm: Reference to the GlossEntry whose GlossTerm should be displayed at the point of the GlossSee --> <!ENTITY % glosssee.attlist "INCLUDE"> <![%glosssee.attlist;[ <!ATTLIST glosssee otherterm IDREF #IMPLIED %common.attrib; %glosssee.role.attrib; %local.glosssee.attrib; > <!--end of glosssee.attlist-->]]> <!--end of glosssee.module-->]]> <!ENTITY % glossseealso.module "INCLUDE"> <![%glossseealso.module;[ <!ENTITY % local.glossseealso.attrib ""> <!ENTITY % glossseealso.role.attrib "%role.attrib;"> <!ENTITY % glossseealso.element "INCLUDE"> <![%glossseealso.element;[ <!--doc:A cross-reference from one GlossEntry to another.--> <!ELEMENT glossseealso %ho; (%para.char.mix;)*> <!--end of glossseealso.element-->]]> <!-- OtherTerm: Reference to the GlossEntry whose GlossTerm should be displayed at the point of the GlossSeeAlso --> <!ENTITY % glossseealso.attlist "INCLUDE"> <![%glossseealso.attlist;[ <!ATTLIST glossseealso otherterm IDREF #IMPLIED %common.attrib; %glossseealso.role.attrib; %local.glossseealso.attrib; > <!--end of glossseealso.attlist-->]]> <!--end of glossseealso.module-->]]> <!--end of glossentry.content.module-->]]> <!-- ItemizedList and OrderedList ..... --> <!ENTITY % itemizedlist.module "INCLUDE"> <![%itemizedlist.module;[ <!ENTITY % local.itemizedlist.attrib ""> <!ENTITY % itemizedlist.role.attrib "%role.attrib;"> <!ENTITY % itemizedlist.element "INCLUDE"> <![%itemizedlist.element;[ <!--doc:A list in which each entry is marked with a bullet or other dingbat.--> <!ELEMENT itemizedlist %ho; (blockinfo?, (%formalobject.title.content;)?, (%listpreamble.mix;)*, listitem+)> <!--end of itemizedlist.element-->]]> <!-- Spacing: Whether the vertical space in the list should be compressed --> <!-- Mark: Keyword, e.g., bullet, dash, checkbox, none; list of keywords and defaults are implementation specific --> <!ENTITY % itemizedlist.attlist "INCLUDE"> <![%itemizedlist.attlist;[ <!ATTLIST itemizedlist spacing (normal |compact) #IMPLIED %mark.attrib; %common.attrib; %itemizedlist.role.attrib; %local.itemizedlist.attrib; > <!--end of itemizedlist.attlist-->]]> <!--end of itemizedlist.module-->]]> <!ENTITY % orderedlist.module "INCLUDE"> <![%orderedlist.module;[ <!ENTITY % local.orderedlist.attrib ""> <!ENTITY % orderedlist.role.attrib "%role.attrib;"> <!ENTITY % orderedlist.element "INCLUDE"> <![%orderedlist.element;[ <!--doc:A list in which each entry is marked with a sequentially incremented label.--> <!ELEMENT orderedlist %ho; (blockinfo?, (%formalobject.title.content;)?, (%listpreamble.mix;)*, listitem+)> <!--end of orderedlist.element-->]]> <!-- Numeration: Style of ListItem numbered; default is expected to be Arabic --> <!-- InheritNum: Specifies for a nested list that the numbering of ListItems should include the number of the item within which they are nested (e.g., 1a and 1b within 1, rather than a and b) --> <!-- Continuation: Where list numbering begins afresh (Restarts, the default) or continues that of the immediately preceding list (Continues) --> <!-- Spacing: Whether the vertical space in the list should be compressed --> <!ENTITY % orderedlist.attlist "INCLUDE"> <![%orderedlist.attlist;[ <!ATTLIST orderedlist numeration (arabic |upperalpha |loweralpha |upperroman |lowerroman) #IMPLIED inheritnum (inherit |ignore) "ignore" continuation (continues |restarts) "restarts" spacing (normal |compact) #IMPLIED %common.attrib; %orderedlist.role.attrib; %local.orderedlist.attrib; > <!--end of orderedlist.attlist-->]]> <!--end of orderedlist.module-->]]> <!ENTITY % listitem.module "INCLUDE"> <![%listitem.module;[ <!ENTITY % local.listitem.attrib ""> <!ENTITY % listitem.role.attrib "%role.attrib;"> <!ENTITY % listitem.element "INCLUDE"> <![%listitem.element;[ <!--doc:A wrapper for the elements of a list item.--> <!ELEMENT listitem %ho; ((%component.mix;)+)> <!--end of listitem.element-->]]> <!-- Override: Indicates the mark to be used for this ListItem instead of the default mark or the mark specified by the Mark attribute on the enclosing ItemizedList --> <!ENTITY % listitem.attlist "INCLUDE"> <![%listitem.attlist;[ <!ATTLIST listitem override CDATA #IMPLIED %common.attrib; %listitem.role.attrib; %local.listitem.attrib; > <!--end of listitem.attlist-->]]> <!--end of listitem.module-->]]> <!-- SegmentedList .................... --> <!ENTITY % segmentedlist.content.module "INCLUDE"> <![%segmentedlist.content.module;[ <!ENTITY % segmentedlist.module "INCLUDE"> <![%segmentedlist.module;[ <!ENTITY % local.segmentedlist.attrib ""> <!ENTITY % segmentedlist.role.attrib "%role.attrib;"> <!ENTITY % segmentedlist.element "INCLUDE"> <![%segmentedlist.element;[ <!--doc:A segmented list, a list of sets of elements.--> <!ELEMENT segmentedlist %ho; ((%formalobject.title.content;)?, segtitle+, seglistitem+)> <!--end of segmentedlist.element-->]]> <!ENTITY % segmentedlist.attlist "INCLUDE"> <![%segmentedlist.attlist;[ <!ATTLIST segmentedlist %common.attrib; %segmentedlist.role.attrib; %local.segmentedlist.attrib; > <!--end of segmentedlist.attlist-->]]> <!--end of segmentedlist.module-->]]> <!ENTITY % segtitle.module "INCLUDE"> <![%segtitle.module;[ <!ENTITY % local.segtitle.attrib ""> <!ENTITY % segtitle.role.attrib "%role.attrib;"> <!ENTITY % segtitle.element "INCLUDE"> <![%segtitle.element;[ <!--doc:The title of an element of a list item in a segmented list.--> <!ELEMENT segtitle %ho; (%title.char.mix;)*> <!--end of segtitle.element-->]]> <!ENTITY % segtitle.attlist "INCLUDE"> <![%segtitle.attlist;[ <!ATTLIST segtitle %common.attrib; %segtitle.role.attrib; %local.segtitle.attrib; > <!--end of segtitle.attlist-->]]> <!--end of segtitle.module-->]]> <!ENTITY % seglistitem.module "INCLUDE"> <![%seglistitem.module;[ <!ENTITY % local.seglistitem.attrib ""> <!ENTITY % seglistitem.role.attrib "%role.attrib;"> <!ENTITY % seglistitem.element "INCLUDE"> <![%seglistitem.element;[ <!--doc:A list item in a segmented list.--> <!ELEMENT seglistitem %ho; (seg+)> <!--end of seglistitem.element-->]]> <!ENTITY % seglistitem.attlist "INCLUDE"> <![%seglistitem.attlist;[ <!ATTLIST seglistitem %common.attrib; %seglistitem.role.attrib; %local.seglistitem.attrib; > <!--end of seglistitem.attlist-->]]> <!--end of seglistitem.module-->]]> <!ENTITY % seg.module "INCLUDE"> <![%seg.module;[ <!ENTITY % local.seg.attrib ""> <!ENTITY % seg.role.attrib "%role.attrib;"> <!ENTITY % seg.element "INCLUDE"> <![%seg.element;[ <!--doc:An element of a list item in a segmented list.--> <!ELEMENT seg %ho; (%para.char.mix;)*> <!--end of seg.element-->]]> <!ENTITY % seg.attlist "INCLUDE"> <![%seg.attlist;[ <!ATTLIST seg %common.attrib; %seg.role.attrib; %local.seg.attrib; > <!--end of seg.attlist-->]]> <!--end of seg.module-->]]> <!--end of segmentedlist.content.module-->]]> <!-- SimpleList ....................... --> <!ENTITY % simplelist.content.module "INCLUDE"> <![%simplelist.content.module;[ <!ENTITY % simplelist.module "INCLUDE"> <![%simplelist.module;[ <!ENTITY % local.simplelist.attrib ""> <!ENTITY % simplelist.role.attrib "%role.attrib;"> <!ENTITY % simplelist.element "INCLUDE"> <![%simplelist.element;[ <!--doc:An undecorated list of single words or short phrases.--> <!ELEMENT simplelist %ho; (member+)> <!--end of simplelist.element-->]]> <!-- Columns: The number of columns the array should contain --> <!-- Type: How the Members of the SimpleList should be formatted: Inline (members separated with commas etc. inline), Vert (top to bottom in n Columns), or Horiz (in the direction of text flow) in n Columns. If Column is 1 or implied, Type=Vert and Type=Horiz give the same results. --> <!ENTITY % simplelist.attlist "INCLUDE"> <![%simplelist.attlist;[ <!ATTLIST simplelist columns CDATA #IMPLIED type (inline |vert |horiz) "vert" %common.attrib; %simplelist.role.attrib; %local.simplelist.attrib; > <!--end of simplelist.attlist-->]]> <!--end of simplelist.module-->]]> <!ENTITY % member.module "INCLUDE"> <![%member.module;[ <!ENTITY % local.member.attrib ""> <!ENTITY % member.role.attrib "%role.attrib;"> <!ENTITY % member.element "INCLUDE"> <![%member.element;[ <!--doc:An element of a simple list.--> <!ELEMENT member %ho; (%para.char.mix;)*> <!--end of member.element-->]]> <!ENTITY % member.attlist "INCLUDE"> <![%member.attlist;[ <!ATTLIST member %common.attrib; %member.role.attrib; %local.member.attrib; > <!--end of member.attlist-->]]> <!--end of member.module-->]]> <!--end of simplelist.content.module-->]]> <!-- VariableList ..................... --> <!ENTITY % variablelist.content.module "INCLUDE"> <![%variablelist.content.module;[ <!ENTITY % variablelist.module "INCLUDE"> <![%variablelist.module;[ <!ENTITY % local.variablelist.attrib ""> <!ENTITY % variablelist.role.attrib "%role.attrib;"> <!ENTITY % variablelist.element "INCLUDE"> <![%variablelist.element;[ <!--doc:A list in which each entry is composed of a set of one or more terms and an associated description.--> <!ELEMENT variablelist %ho; (blockinfo?, (%formalobject.title.content;)?, (%listpreamble.mix;)*, varlistentry+)> <!--end of variablelist.element-->]]> <!-- TermLength: Length beyond which the presentation engine may consider the Term too long and select an alternate presentation of the Term and, or, its associated ListItem. --> <!ENTITY % variablelist.attlist "INCLUDE"> <![%variablelist.attlist;[ <!ATTLIST variablelist termlength CDATA #IMPLIED spacing (normal |compact) #IMPLIED %common.attrib; %variablelist.role.attrib; %local.variablelist.attrib; > <!--end of variablelist.attlist-->]]> <!--end of variablelist.module-->]]> <!ENTITY % varlistentry.module "INCLUDE"> <![%varlistentry.module;[ <!ENTITY % local.varlistentry.attrib ""> <!ENTITY % varlistentry.role.attrib "%role.attrib;"> <!ENTITY % varlistentry.element "INCLUDE"> <![%varlistentry.element;[ <!--doc:A wrapper for a set of terms and the associated description in a variable list.--> <!ELEMENT varlistentry %ho; (term+, listitem)> <!--end of varlistentry.element-->]]> <!ENTITY % varlistentry.attlist "INCLUDE"> <![%varlistentry.attlist;[ <!ATTLIST varlistentry %common.attrib; %varlistentry.role.attrib; %local.varlistentry.attrib; > <!--end of varlistentry.attlist-->]]> <!--end of varlistentry.module-->]]> <!ENTITY % term.module "INCLUDE"> <![%term.module;[ <!ENTITY % local.term.attrib ""> <!ENTITY % term.role.attrib "%role.attrib;"> <!ENTITY % term.element "INCLUDE"> <![%term.element;[ <!--doc:The word or phrase being defined or described in a variable list.--> <!ELEMENT term %ho; (%para.char.mix;)*> <!--end of term.element-->]]> <!ENTITY % term.attlist "INCLUDE"> <![%term.attlist;[ <!ATTLIST term %common.attrib; %term.role.attrib; %local.term.attrib; > <!--end of term.attlist-->]]> <!--end of term.module-->]]> <!-- ListItem (defined above)--> <!--end of variablelist.content.module-->]]> <!-- CalloutList ...................... --> <!ENTITY % calloutlist.content.module "INCLUDE"> <![%calloutlist.content.module;[ <!ENTITY % calloutlist.module "INCLUDE"> <![%calloutlist.module;[ <!ENTITY % local.calloutlist.attrib ""> <!ENTITY % calloutlist.role.attrib "%role.attrib;"> <!ENTITY % calloutlist.element "INCLUDE"> <![%calloutlist.element;[ <!--doc:A list of Callouts.--> <!ELEMENT calloutlist %ho; ((%formalobject.title.content;)?, callout+)> <!--end of calloutlist.element-->]]> <!ENTITY % calloutlist.attlist "INCLUDE"> <![%calloutlist.attlist;[ <!ATTLIST calloutlist %common.attrib; %calloutlist.role.attrib; %local.calloutlist.attrib; > <!--end of calloutlist.attlist-->]]> <!--end of calloutlist.module-->]]> <!ENTITY % callout.module "INCLUDE"> <![%callout.module;[ <!ENTITY % local.callout.attrib ""> <!ENTITY % callout.role.attrib "%role.attrib;"> <!ENTITY % callout.element "INCLUDE"> <![%callout.element;[ <!--doc:A “called out” description of a marked Area.--> <!ELEMENT callout %ho; ((%component.mix;)+)> <!--end of callout.element-->]]> <!-- AreaRefs: IDs of one or more Areas or AreaSets described by this Callout --> <!ENTITY % callout.attlist "INCLUDE"> <![%callout.attlist;[ <!ATTLIST callout arearefs IDREFS #REQUIRED %common.attrib; %callout.role.attrib; %local.callout.attrib; > <!--end of callout.attlist-->]]> <!--end of callout.module-->]]> <!--end of calloutlist.content.module-->]]> <!-- ...................................................................... --> <!-- Objects .............................................................. --> <!-- Examples etc. .................... --> <!ENTITY % example.module "INCLUDE"> <![%example.module;[ <!ENTITY % local.example.attrib ""> <!ENTITY % example.role.attrib "%role.attrib;"> <!ENTITY % example.element "INCLUDE"> <![%example.element;[ <!--doc:A formal example, with a title.--> <!ELEMENT example %ho; (blockinfo?, (%formalobject.title.content;), (%example.mix;)+) %formal.exclusion;> <!--end of example.element-->]]> <!ENTITY % example.attlist "INCLUDE"> <![%example.attlist;[ <!ATTLIST example floatstyle CDATA #IMPLIED %label.attrib; %width.attrib; %common.attrib; %example.role.attrib; %local.example.attrib; > <!--end of example.attlist-->]]> <!--end of example.module-->]]> <!ENTITY % informalexample.module "INCLUDE"> <![%informalexample.module;[ <!ENTITY % local.informalexample.attrib ""> <!ENTITY % informalexample.role.attrib "%role.attrib;"> <!ENTITY % informalexample.element "INCLUDE"> <![%informalexample.element;[ <!--doc:A displayed example without a title.--> <!ELEMENT informalexample %ho; (blockinfo?, (%example.mix;)+)> <!--end of informalexample.element-->]]> <!ENTITY % informalexample.attlist "INCLUDE"> <![%informalexample.attlist;[ <!ATTLIST informalexample floatstyle CDATA #IMPLIED %width.attrib; %common.attrib; %informalexample.role.attrib; %local.informalexample.attrib; > <!--end of informalexample.attlist-->]]> <!--end of informalexample.module-->]]> <!ENTITY % programlistingco.module "INCLUDE"> <![%programlistingco.module;[ <!ENTITY % local.programlistingco.attrib ""> <!ENTITY % programlistingco.role.attrib "%role.attrib;"> <!ENTITY % programlistingco.element "INCLUDE"> <![%programlistingco.element;[ <!--doc:A program listing with associated areas used in callouts.--> <!ELEMENT programlistingco %ho; (areaspec, programlisting, calloutlist*)> <!--end of programlistingco.element-->]]> <!ENTITY % programlistingco.attlist "INCLUDE"> <![%programlistingco.attlist;[ <!ATTLIST programlistingco %common.attrib; %programlistingco.role.attrib; %local.programlistingco.attrib; > <!--end of programlistingco.attlist-->]]> <!-- CalloutList (defined above in Lists)--> <!--end of informalexample.module-->]]> <!ENTITY % areaspec.content.module "INCLUDE"> <![%areaspec.content.module;[ <!ENTITY % areaspec.module "INCLUDE"> <![%areaspec.module;[ <!ENTITY % local.areaspec.attrib ""> <!ENTITY % areaspec.role.attrib "%role.attrib;"> <!ENTITY % areaspec.element "INCLUDE"> <![%areaspec.element;[ <!--doc:A collection of regions in a graphic or code example.--> <!ELEMENT areaspec %ho; ((area|areaset)+)> <!--end of areaspec.element-->]]> <!-- Units: global unit of measure in which coordinates in this spec are expressed: - CALSPair "x1,y1 x2,y2": lower-left and upper-right coordinates in a rectangle describing repro area in which graphic is placed, where X and Y dimensions are each some number 0..10000 (taken from CALS graphic attributes) - LineColumn "line column": line number and column number at which to start callout text in "linespecific" content - LineRange "startline endline": whole lines from startline to endline in "linespecific" content - LineColumnPair "line1 col1 line2 col2": starting and ending points of area in "linespecific" content that starts at first position and ends at second position (including the beginnings of any intervening lines) - Other: directive to look at value of OtherUnits attribute to get implementation-specific keyword The default is implementation-specific; usually dependent on the parent element (GraphicCO gets CALSPair, ProgramListingCO and ScreenCO get LineColumn) --> <!-- OtherUnits: User-defined units --> <!ENTITY % areaspec.attlist "INCLUDE"> <![%areaspec.attlist;[ <!ATTLIST areaspec units (calspair |linecolumn |linerange |linecolumnpair |other) #IMPLIED otherunits NMTOKEN #IMPLIED %common.attrib; %areaspec.role.attrib; %local.areaspec.attrib; > <!--end of areaspec.attlist-->]]> <!--end of areaspec.module-->]]> <!ENTITY % area.module "INCLUDE"> <![%area.module;[ <!ENTITY % local.area.attrib ""> <!ENTITY % area.role.attrib "%role.attrib;"> <!ENTITY % area.element "INCLUDE"> <![%area.element;[ <!--doc:A region defined for a Callout in a graphic or code example.--> <!ELEMENT area %ho; EMPTY> <!--end of area.element-->]]> <!-- bug number/symbol override or initialization --> <!-- to any related information --> <!-- Units: unit of measure in which coordinates in this area are expressed; inherits from AreaSet and AreaSpec --> <!-- OtherUnits: User-defined units --> <!ENTITY % area.attlist "INCLUDE"> <![%area.attlist;[ <!ATTLIST area %label.attrib; %linkends.attrib; units (calspair |linecolumn |linerange |linecolumnpair |other) #IMPLIED otherunits NMTOKEN #IMPLIED coords CDATA #REQUIRED %idreq.common.attrib; %area.role.attrib; %local.area.attrib; > <!--end of area.attlist-->]]> <!--end of area.module-->]]> <!ENTITY % areaset.module "INCLUDE"> <![%areaset.module;[ <!ENTITY % local.areaset.attrib ""> <!ENTITY % areaset.role.attrib "%role.attrib;"> <!ENTITY % areaset.element "INCLUDE"> <![%areaset.element;[ <!--doc:A set of related areas in a graphic or code example.--> <!ELEMENT areaset %ho; (area+)> <!--end of areaset.element-->]]> <!-- bug number/symbol override or initialization --> <!-- Units: unit of measure in which coordinates in this area are expressed; inherits from AreaSpec --> <!ENTITY % areaset.attlist "INCLUDE"> <![%areaset.attlist;[ <!ATTLIST areaset %label.attrib; units (calspair |linecolumn |linerange |linecolumnpair |other) #IMPLIED otherunits NMTOKEN #IMPLIED coords CDATA #REQUIRED %idreq.common.attrib; %areaset.role.attrib; %local.areaset.attrib; > <!--end of areaset.attlist-->]]> <!--end of areaset.module-->]]> <!--end of areaspec.content.module-->]]> <!ENTITY % programlisting.module "INCLUDE"> <![%programlisting.module;[ <!ENTITY % local.programlisting.attrib ""> <!ENTITY % programlisting.role.attrib "%role.attrib;"> <!ENTITY % programlisting.element "INCLUDE"> <![%programlisting.element;[ <!--doc:A literal listing of all or part of a program.--> <!ELEMENT programlisting %ho; (%para.char.mix;|co|coref|lineannotation|textobject)*> <!--end of programlisting.element-->]]> <!ENTITY % programlisting.attlist "INCLUDE"> <![%programlisting.attlist;[ <!ATTLIST programlisting %width.attrib; %linespecific.attrib; %common.attrib; %programlisting.role.attrib; %local.programlisting.attrib; > <!--end of programlisting.attlist-->]]> <!--end of programlisting.module-->]]> <!ENTITY % literallayout.module "INCLUDE"> <![%literallayout.module;[ <!ENTITY % local.literallayout.attrib ""> <!ENTITY % literallayout.role.attrib "%role.attrib;"> <!ENTITY % literallayout.element "INCLUDE"> <![%literallayout.element;[ <!--doc:A block of text in which line breaks and white space are to be reproduced faithfully.--> <!ELEMENT literallayout %ho; (%para.char.mix;|co|coref|textobject|lineannotation)*> <!--end of literallayout.element-->]]> <!ENTITY % literallayout.attlist "INCLUDE"> <![%literallayout.attlist;[ <!ATTLIST literallayout %width.attrib; %linespecific.attrib; class (monospaced|normal) "normal" %common.attrib; %literallayout.role.attrib; %local.literallayout.attrib; > <!--end of literallayout.attlist-->]]> <!-- LineAnnotation (defined in the Inlines section, below)--> <!--end of literallayout.module-->]]> <!ENTITY % screenco.module "INCLUDE"> <![%screenco.module;[ <!ENTITY % local.screenco.attrib ""> <!ENTITY % screenco.role.attrib "%role.attrib;"> <!ENTITY % screenco.element "INCLUDE"> <![%screenco.element;[ <!--doc:A screen with associated areas used in callouts.--> <!ELEMENT screenco %ho; (areaspec, screen, calloutlist*)> <!--end of screenco.element-->]]> <!ENTITY % screenco.attlist "INCLUDE"> <![%screenco.attlist;[ <!ATTLIST screenco %common.attrib; %screenco.role.attrib; %local.screenco.attrib; > <!--end of screenco.attlist-->]]> <!-- AreaSpec (defined above)--> <!-- CalloutList (defined above in Lists)--> <!--end of screenco.module-->]]> <!ENTITY % screen.module "INCLUDE"> <![%screen.module;[ <!ENTITY % local.screen.attrib ""> <!ENTITY % screen.role.attrib "%role.attrib;"> <!ENTITY % screen.element "INCLUDE"> <![%screen.element;[ <!--doc:Text that a user sees or might see on a computer screen.--> <!ELEMENT screen %ho; (%para.char.mix;|co|coref|textobject|lineannotation)*> <!--end of screen.element-->]]> <!ENTITY % screen.attlist "INCLUDE"> <![%screen.attlist;[ <!ATTLIST screen %width.attrib; %linespecific.attrib; %common.attrib; %screen.role.attrib; %local.screen.attrib; > <!--end of screen.attlist-->]]> <!--end of screen.module-->]]> <!ENTITY % screenshot.content.module "INCLUDE"> <![%screenshot.content.module;[ <!ENTITY % screenshot.module "INCLUDE"> <![%screenshot.module;[ <!ENTITY % local.screenshot.attrib ""> <!ENTITY % screenshot.role.attrib "%role.attrib;"> <!ENTITY % screenshot.element "INCLUDE"> <![%screenshot.element;[ <!--doc:A representation of what the user sees or might see on a computer screen.--> <!ELEMENT screenshot %ho; (screeninfo?, (graphic|graphicco |mediaobject|mediaobjectco))> <!--end of screenshot.element-->]]> <!ENTITY % screenshot.attlist "INCLUDE"> <![%screenshot.attlist;[ <!ATTLIST screenshot %common.attrib; %screenshot.role.attrib; %local.screenshot.attrib; > <!--end of screenshot.attlist-->]]> <!--end of screenshot.module-->]]> <!ENTITY % screeninfo.module "INCLUDE"> <![%screeninfo.module;[ <!ENTITY % local.screeninfo.attrib ""> <!ENTITY % screeninfo.role.attrib "%role.attrib;"> <!ENTITY % screeninfo.element "INCLUDE"> <![%screeninfo.element;[ <!--doc:Information about how a screen shot was produced.--> <!ELEMENT screeninfo %ho; (%para.char.mix;)* %ubiq.exclusion;> <!--end of screeninfo.element-->]]> <!ENTITY % screeninfo.attlist "INCLUDE"> <![%screeninfo.attlist;[ <!ATTLIST screeninfo %common.attrib; %screeninfo.role.attrib; %local.screeninfo.attrib; > <!--end of screeninfo.attlist-->]]> <!--end of screeninfo.module-->]]> <!--end of screenshot.content.module-->]]> <!-- Figures etc. ..................... --> <!ENTITY % figure.module "INCLUDE"> <![%figure.module;[ <!ENTITY % local.figure.attrib ""> <!ENTITY % figure.role.attrib "%role.attrib;"> <!ENTITY % figure.element "INCLUDE"> <![%figure.element;[ <!--doc:A formal figure, generally an illustration, with a title.--> <!ELEMENT figure %ho; (blockinfo?, (%formalobject.title.content;), (%figure.mix; | %link.char.class;)+)> <!--end of figure.element-->]]> <!-- Float: Whether the Figure is supposed to be rendered where convenient (yes (1) value) or at the place it occurs in the text (no (0) value, the default) --> <!ENTITY % figure.attlist "INCLUDE"> <![%figure.attlist;[ <!ATTLIST figure float %yesorno.attvals; '0' floatstyle CDATA #IMPLIED pgwide %yesorno.attvals; #IMPLIED %label.attrib; %common.attrib; %figure.role.attrib; %local.figure.attrib; > <!--end of figure.attlist-->]]> <!--end of figure.module-->]]> <!ENTITY % informalfigure.module "INCLUDE"> <![ %informalfigure.module; [ <!ENTITY % local.informalfigure.attrib ""> <!ENTITY % informalfigure.role.attrib "%role.attrib;"> <!ENTITY % informalfigure.element "INCLUDE"> <![ %informalfigure.element; [ <!--doc:A untitled figure.--> <!ELEMENT informalfigure %ho; (blockinfo?, (%figure.mix; | %link.char.class;)+)> <!--end of informalfigure.element-->]]> <!ENTITY % informalfigure.attlist "INCLUDE"> <![ %informalfigure.attlist; [ <!-- Float: Whether the Figure is supposed to be rendered where convenient (yes (1) value) or at the place it occurs in the text (no (0) value, the default) --> <!ATTLIST informalfigure float %yesorno.attvals; "0" floatstyle CDATA #IMPLIED pgwide %yesorno.attvals; #IMPLIED %label.attrib; %common.attrib; %informalfigure.role.attrib; %local.informalfigure.attrib; > <!--end of informalfigure.attlist-->]]> <!--end of informalfigure.module-->]]> <!ENTITY % graphicco.module "INCLUDE"> <![%graphicco.module;[ <!ENTITY % local.graphicco.attrib ""> <!ENTITY % graphicco.role.attrib "%role.attrib;"> <!ENTITY % graphicco.element "INCLUDE"> <![%graphicco.element;[ <!--doc:A graphic that contains callout areas.--> <!ELEMENT graphicco %ho; (areaspec, graphic, calloutlist*)> <!--end of graphicco.element-->]]> <!ENTITY % graphicco.attlist "INCLUDE"> <![%graphicco.attlist;[ <!ATTLIST graphicco %common.attrib; %graphicco.role.attrib; %local.graphicco.attrib; > <!--end of graphicco.attlist-->]]> <!-- AreaSpec (defined above in Examples)--> <!-- CalloutList (defined above in Lists)--> <!--end of graphicco.module-->]]> <!-- Graphical data can be the content of Graphic, or you can reference an external file either as an entity (Entitref) or a filename (Fileref). --> <!ENTITY % graphic.module "INCLUDE"> <![%graphic.module;[ <!ENTITY % local.graphic.attrib ""> <!ENTITY % graphic.role.attrib "%role.attrib;"> <!ENTITY % graphic.element "INCLUDE"> <![%graphic.element;[ <!--doc:A displayed graphical object (not an inline).--> <!ELEMENT graphic %ho; EMPTY> <!--end of graphic.element-->]]> <!ENTITY % graphic.attlist "INCLUDE"> <![%graphic.attlist;[ <!ATTLIST graphic %graphics.attrib; %common.attrib; %graphic.role.attrib; %local.graphic.attrib; > <!--end of graphic.attlist-->]]> <!--end of graphic.module-->]]> <!ENTITY % inlinegraphic.module "INCLUDE"> <![%inlinegraphic.module;[ <!ENTITY % local.inlinegraphic.attrib ""> <!ENTITY % inlinegraphic.role.attrib "%role.attrib;"> <!ENTITY % inlinegraphic.element "INCLUDE"> <![%inlinegraphic.element;[ <!--doc:An object containing or pointing to graphical data that will be rendered inline.--> <!ELEMENT inlinegraphic %ho; EMPTY> <!--end of inlinegraphic.element-->]]> <!ENTITY % inlinegraphic.attlist "INCLUDE"> <![%inlinegraphic.attlist;[ <!ATTLIST inlinegraphic %graphics.attrib; %common.attrib; %inlinegraphic.role.attrib; %local.inlinegraphic.attrib; > <!--end of inlinegraphic.attlist-->]]> <!--end of inlinegraphic.module-->]]> <!ENTITY % mediaobject.content.module "INCLUDE"> <![ %mediaobject.content.module; [ <!ENTITY % mediaobject.module "INCLUDE"> <![ %mediaobject.module; [ <!ENTITY % local.mediaobject.attrib ""> <!ENTITY % mediaobject.role.attrib "%role.attrib;"> <!ENTITY % mediaobject.element "INCLUDE"> <![ %mediaobject.element; [ <!--doc:A displayed media object (video, audio, image, etc.).--> <!ELEMENT mediaobject %ho; (objectinfo?, (%mediaobject.mix;)+, caption?)> <!--end of mediaobject.element-->]]> <!ENTITY % mediaobject.attlist "INCLUDE"> <![ %mediaobject.attlist; [ <!ATTLIST mediaobject %common.attrib; %mediaobject.role.attrib; %local.mediaobject.attrib; > <!--end of mediaobject.attlist-->]]> <!--end of mediaobject.module-->]]> <!ENTITY % inlinemediaobject.module "INCLUDE"> <![ %inlinemediaobject.module; [ <!ENTITY % local.inlinemediaobject.attrib ""> <!ENTITY % inlinemediaobject.role.attrib "%role.attrib;"> <!ENTITY % inlinemediaobject.element "INCLUDE"> <![ %inlinemediaobject.element; [ <!--doc:An inline media object (video, audio, image, and so on).--> <!ELEMENT inlinemediaobject %ho; (objectinfo?, (%mediaobject.mix;)+)> <!--end of inlinemediaobject.element-->]]> <!ENTITY % inlinemediaobject.attlist "INCLUDE"> <![ %inlinemediaobject.attlist; [ <!ATTLIST inlinemediaobject %common.attrib; %inlinemediaobject.role.attrib; %local.inlinemediaobject.attrib; > <!--end of inlinemediaobject.attlist-->]]> <!--end of inlinemediaobject.module-->]]> <!ENTITY % videoobject.module "INCLUDE"> <![ %videoobject.module; [ <!ENTITY % local.videoobject.attrib ""> <!ENTITY % videoobject.role.attrib "%role.attrib;"> <!ENTITY % videoobject.element "INCLUDE"> <![ %videoobject.element; [ <!--doc:A wrapper for video data and its associated meta-information.--> <!ELEMENT videoobject %ho; (objectinfo?, videodata)> <!--end of videoobject.element-->]]> <!ENTITY % videoobject.attlist "INCLUDE"> <![ %videoobject.attlist; [ <!ATTLIST videoobject %common.attrib; %videoobject.role.attrib; %local.videoobject.attrib; > <!--end of videoobject.attlist-->]]> <!--end of videoobject.module-->]]> <!ENTITY % audioobject.module "INCLUDE"> <![ %audioobject.module; [ <!ENTITY % local.audioobject.attrib ""> <!ENTITY % audioobject.role.attrib "%role.attrib;"> <!ENTITY % audioobject.element "INCLUDE"> <![ %audioobject.element; [ <!--doc:A wrapper for audio data and its associated meta-information.--> <!ELEMENT audioobject %ho; (objectinfo?, audiodata)> <!--end of audioobject.element-->]]> <!ENTITY % audioobject.attlist "INCLUDE"> <![ %audioobject.attlist; [ <!ATTLIST audioobject %common.attrib; %audioobject.role.attrib; %local.audioobject.attrib; > <!--end of audioobject.attlist-->]]> <!--end of audioobject.module-->]]> <!ENTITY % imageobject.module "INCLUDE"> <![ %imageobject.module; [ <!ENTITY % local.imageobject.attrib ""> <!ENTITY % imageobject.role.attrib "%role.attrib;"> <!ENTITY % imageobject.element "INCLUDE"> <![ %imageobject.element; [ <!--doc:A wrapper for image data and its associated meta-information.--> <!ELEMENT imageobject %ho; (objectinfo?, imagedata)> <!--end of imageobject.element-->]]> <!ENTITY % imageobject.attlist "INCLUDE"> <![ %imageobject.attlist; [ <!ATTLIST imageobject %common.attrib; %imageobject.role.attrib; %local.imageobject.attrib; > <!--end of imageobject.attlist-->]]> <!--end of imageobject.module-->]]> <!ENTITY % textobject.module "INCLUDE"> <![ %textobject.module; [ <!ENTITY % local.textobject.attrib ""> <!ENTITY % textobject.role.attrib "%role.attrib;"> <!ENTITY % textobject.element "INCLUDE"> <![ %textobject.element; [ <!--doc:A wrapper for a text description of an object and its associated meta-information.--> <!ELEMENT textobject %ho; (objectinfo?, (phrase|textdata|(%textobject.mix;)+))> <!--end of textobject.element-->]]> <!ENTITY % textobject.attlist "INCLUDE"> <![ %textobject.attlist; [ <!ATTLIST textobject %common.attrib; %textobject.role.attrib; %local.textobject.attrib; > <!--end of textobject.attlist-->]]> <!--end of textobject.module-->]]> <!ENTITY % objectinfo.module "INCLUDE"> <![ %objectinfo.module; [ <!ENTITY % local.objectinfo.attrib ""> <!ENTITY % objectinfo.role.attrib "%role.attrib;"> <!ENTITY % objectinfo.element "INCLUDE"> <![ %objectinfo.element; [ <!--doc:Meta-information for an object.--> <!ELEMENT objectinfo %ho; ((%info.class;)+) %beginpage.exclusion;> <!--end of objectinfo.element-->]]> <!ENTITY % objectinfo.attlist "INCLUDE"> <![ %objectinfo.attlist; [ <!ATTLIST objectinfo %common.attrib; %objectinfo.role.attrib; %local.objectinfo.attrib; > <!--end of objectinfo.attlist-->]]> <!--end of objectinfo.module-->]]> <!--EntityRef: Name of an external entity containing the content of the object data--> <!--FileRef: Filename, qualified by a pathname if desired, designating the file containing the content of the object data--> <!--Format: Notation of the element content, if any--> <!--SrcCredit: Information about the source of the image--> <!ENTITY % local.objectdata.attrib ""> <!ENTITY % objectdata.attrib " entityref ENTITY #IMPLIED fileref CDATA #IMPLIED format (%notation.class;) #IMPLIED srccredit CDATA #IMPLIED %local.objectdata.attrib;" > <!ENTITY % videodata.module "INCLUDE"> <![ %videodata.module; [ <!ENTITY % local.videodata.attrib ""> <!ENTITY % videodata.role.attrib "%role.attrib;"> <!ENTITY % videodata.element "INCLUDE"> <![ %videodata.element; [ <!--doc:Pointer to external video data.--> <!ELEMENT videodata %ho; EMPTY> <!--end of videodata.element-->]]> <!ENTITY % videodata.attlist "INCLUDE"> <![ %videodata.attlist; [ <!--Width: Same as CALS reprowid (desired width)--> <!--Depth: Same as CALS reprodep (desired depth)--> <!--Align: Same as CALS hplace with 'none' removed; #IMPLIED means application-specific--> <!--Scale: Conflation of CALS hscale and vscale--> <!--Scalefit: Same as CALS scalefit--> <!ATTLIST videodata width CDATA #IMPLIED contentwidth CDATA #IMPLIED depth CDATA #IMPLIED contentdepth CDATA #IMPLIED align (left |right |center) #IMPLIED valign (top |middle |bottom) #IMPLIED scale CDATA #IMPLIED scalefit %yesorno.attvals; #IMPLIED %objectdata.attrib; %common.attrib; %videodata.role.attrib; %local.videodata.attrib; > <!--end of videodata.attlist-->]]> <!--end of videodata.module-->]]> <!ENTITY % audiodata.module "INCLUDE"> <![ %audiodata.module; [ <!ENTITY % local.audiodata.attrib ""> <!ENTITY % audiodata.role.attrib "%role.attrib;"> <!ENTITY % audiodata.element "INCLUDE"> <![ %audiodata.element; [ <!--doc:Pointer to external audio data.--> <!ELEMENT audiodata %ho; EMPTY> <!--end of audiodata.element-->]]> <!ENTITY % audiodata.attlist "INCLUDE"> <![ %audiodata.attlist; [ <!ATTLIST audiodata %objectdata.attrib; %common.attrib; %audiodata.role.attrib; %local.audiodata.attrib; > <!--end of audiodata.attlist-->]]> <!--end of audiodata.module-->]]> <!ENTITY % imagedata.module "INCLUDE"> <![ %imagedata.module; [ <!ENTITY % local.imagedata.attrib ""> <!ENTITY % imagedata.role.attrib "%role.attrib;"> <!ENTITY % imagedata.element "INCLUDE"> <![ %imagedata.element; [ <!--doc:Pointer to external image data.--> <!ELEMENT imagedata %ho; EMPTY> <!--end of imagedata.element-->]]> <!ENTITY % imagedata.attlist "INCLUDE"> <![ %imagedata.attlist; [ <!--Width: Same as CALS reprowid (desired width)--> <!--Depth: Same as CALS reprodep (desired depth)--> <!--Align: Same as CALS hplace with 'none' removed; #IMPLIED means application-specific--> <!--Scale: Conflation of CALS hscale and vscale--> <!--Scalefit: Same as CALS scalefit--> <!ATTLIST imagedata width CDATA #IMPLIED contentwidth CDATA #IMPLIED depth CDATA #IMPLIED contentdepth CDATA #IMPLIED align (left |right |center) #IMPLIED valign (top |middle |bottom) #IMPLIED scale CDATA #IMPLIED scalefit %yesorno.attvals; #IMPLIED %objectdata.attrib; %common.attrib; %imagedata.role.attrib; %local.imagedata.attrib; > <!--end of imagedata.attlist-->]]> <!--end of imagedata.module-->]]> <!ENTITY % textdata.module "INCLUDE"> <![ %textdata.module; [ <!ENTITY % local.textdata.attrib ""> <!ENTITY % textdata.role.attrib "%role.attrib;"> <!ENTITY % textdata.element "INCLUDE"> <![ %textdata.element; [ <!--doc:Pointer to external text data.--> <!ELEMENT textdata %ho; EMPTY> <!--end of textdata.element-->]]> <!ENTITY % textdata.attlist "INCLUDE"> <![ %textdata.attlist; [ <!ATTLIST textdata encoding CDATA #IMPLIED %objectdata.attrib; %common.attrib; %textdata.role.attrib; %local.textdata.attrib; > <!--end of textdata.attlist-->]]> <!--end of textdata.module-->]]> <!ENTITY % mediaobjectco.module "INCLUDE"> <![ %mediaobjectco.module; [ <!ENTITY % local.mediaobjectco.attrib ""> <!ENTITY % mediaobjectco.role.attrib "%role.attrib;"> <!ENTITY % mediaobjectco.element "INCLUDE"> <![ %mediaobjectco.element; [ <!--doc:A media object that contains callouts.--> <!ELEMENT mediaobjectco %ho; (objectinfo?, imageobjectco, (imageobjectco|textobject)*)> <!--end of mediaobjectco.element-->]]> <!ENTITY % mediaobjectco.attlist "INCLUDE"> <![ %mediaobjectco.attlist; [ <!ATTLIST mediaobjectco %common.attrib; %mediaobjectco.role.attrib; %local.mediaobjectco.attrib; > <!--end of mediaobjectco.attlist-->]]> <!--end of mediaobjectco.module-->]]> <!ENTITY % imageobjectco.module "INCLUDE"> <![ %imageobjectco.module; [ <!ENTITY % local.imageobjectco.attrib ""> <!ENTITY % imageobjectco.role.attrib "%role.attrib;"> <!ENTITY % imageobjectco.element "INCLUDE"> <![ %imageobjectco.element; [ <!--doc:A wrapper for an image object with callouts.--> <!ELEMENT imageobjectco %ho; (areaspec, imageobject, calloutlist*)> <!--end of imageobjectco.element-->]]> <!ENTITY % imageobjectco.attlist "INCLUDE"> <![ %imageobjectco.attlist; [ <!ATTLIST imageobjectco %common.attrib; %imageobjectco.role.attrib; %local.imageobjectco.attrib; > <!--end of imageobjectco.attlist-->]]> <!--end of imageobjectco.module-->]]> <!--end of mediaobject.content.module-->]]> <!-- Equations ........................ --> <!-- This PE provides a mechanism for replacing equation content, --> <!-- perhaps adding a new or different model (e.g., MathML) --> <!ENTITY % equation.content "(alt?, (graphic+|mediaobject+|mathphrase+))"> <!ENTITY % inlineequation.content "(alt?, (graphic+|inlinemediaobject+|mathphrase+))"> <!ENTITY % equation.module "INCLUDE"> <![%equation.module;[ <!ENTITY % local.equation.attrib ""> <!ENTITY % equation.role.attrib "%role.attrib;"> <!ENTITY % equation.element "INCLUDE"> <![%equation.element;[ <!--doc:A displayed mathematical equation.--> <!ELEMENT equation %ho; (blockinfo?, (%formalobject.title.content;)?, (informalequation | %equation.content;))> <!--end of equation.element-->]]> <!ENTITY % equation.attlist "INCLUDE"> <![%equation.attlist;[ <!ATTLIST equation floatstyle CDATA #IMPLIED %label.attrib; %common.attrib; %equation.role.attrib; %local.equation.attrib; > <!--end of equation.attlist-->]]> <!--end of equation.module-->]]> <!ENTITY % informalequation.module "INCLUDE"> <![%informalequation.module;[ <!ENTITY % local.informalequation.attrib ""> <!ENTITY % informalequation.role.attrib "%role.attrib;"> <!ENTITY % informalequation.element "INCLUDE"> <![%informalequation.element;[ <!--doc:A displayed mathematical equation without a title.--> <!ELEMENT informalequation %ho; (blockinfo?, %equation.content;) > <!--end of informalequation.element-->]]> <!ENTITY % informalequation.attlist "INCLUDE"> <![%informalequation.attlist;[ <!ATTLIST informalequation floatstyle CDATA #IMPLIED %common.attrib; %informalequation.role.attrib; %local.informalequation.attrib; > <!--end of informalequation.attlist-->]]> <!--end of informalequation.module-->]]> <!ENTITY % inlineequation.module "INCLUDE"> <![%inlineequation.module;[ <!ENTITY % local.inlineequation.attrib ""> <!ENTITY % inlineequation.role.attrib "%role.attrib;"> <!ENTITY % inlineequation.element "INCLUDE"> <![%inlineequation.element;[ <!--doc:A mathematical equation or expression occurring inline.--> <!ELEMENT inlineequation %ho; (%inlineequation.content;)> <!--end of inlineequation.element-->]]> <!ENTITY % inlineequation.attlist "INCLUDE"> <![%inlineequation.attlist;[ <!ATTLIST inlineequation %common.attrib; %inlineequation.role.attrib; %local.inlineequation.attrib; > <!--end of inlineequation.attlist-->]]> <!--end of inlineequation.module-->]]> <!ENTITY % alt.module "INCLUDE"> <![%alt.module;[ <!ENTITY % local.alt.attrib ""> <!ENTITY % alt.role.attrib "%role.attrib;"> <!ENTITY % alt.element "INCLUDE"> <![%alt.element;[ <!--doc:Text representation for a graphical element.--> <!ELEMENT alt %ho; (#PCDATA)> <!--end of alt.element-->]]> <!ENTITY % alt.attlist "INCLUDE"> <![%alt.attlist;[ <!ATTLIST alt %common.attrib; %alt.role.attrib; %local.alt.attrib; > <!--end of alt.attlist-->]]> <!--end of alt.module-->]]> <!ENTITY % mathphrase.module "INCLUDE"> <![%mathphrase.module;[ <!ENTITY % local.mathphrase.attrib ""> <!ENTITY % mathphrase.role.attrib "%role.attrib;"> <!ENTITY % mathphrase.element "INCLUDE"> <![%mathphrase.element;[ <!--doc:A mathematical phrase, an expression that can be represented with ordinary text and a small amount of markup.--> <!ELEMENT mathphrase %ho; (#PCDATA|subscript|superscript|emphasis)*> <!--end of mathphrase.element-->]]> <!ENTITY % mathphrase.attlist "INCLUDE"> <![%mathphrase.attlist;[ <!ATTLIST mathphrase %common.attrib; %mathphrase.role.attrib; %local.mathphrase.attrib; > <!--end of mathphrase.attlist-->]]> <!--end of mathphrase.module-->]]> <!-- Tables ........................... --> <!ENTITY % table.module "INCLUDE"> <![%table.module;[ <!-- Choose a table model. CALS or OASIS XML Exchange --> <!ENTITY % cals.table.module "INCLUDE"> <![%cals.table.module;[ <!ENTITY % exchange.table.module "IGNORE"> ]]> <!ENTITY % exchange.table.module "INCLUDE"> <!-- Do we allow the HTML table model as well? --> <!ENTITY % allow.html.tables "INCLUDE"> <![%allow.html.tables;[ <!-- ====================================================== --> <!-- xhtmltbl.mod defines HTML tables and sets parameter entities so that, when the CALS table module is read, we end up allowing any table to be CALS or HTML. i.e. This include must come first! --> <!-- ====================================================== --> <!ENTITY % htmltbl PUBLIC "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN" "htmltblx.mod"> %htmltbl; <!--end of allow.html.tables-->]]> <!ENTITY % tables.role.attrib "%role.attrib;"> <![%cals.table.module;[ <!-- Add label and role attributes to table and informaltable --> <!ENTITY % bodyatt " floatstyle CDATA #IMPLIED rowheader (firstcol|norowheader) #IMPLIED %label.attrib;" > <!-- Add common attributes to Table, TGroup, TBody, THead, TFoot, Row, EntryTbl, and Entry (and InformalTable element). --> <!ENTITY % secur "%common.attrib; %tables.role.attrib;"> <!ENTITY % common.table.attribs "%bodyatt; %secur;"> <!-- Content model for Table. --> <!ENTITY % tbl.table.mdl "(blockinfo?, (%formalobject.title.content;), (%ndxterm.class;)*, textobject*, (graphic+|mediaobject+|tgroup+))"> <!-- Allow either objects or inlines; beware of REs between elements. --> <!ENTITY % tbl.entry.mdl "%para.char.mix; | %tabentry.mix;"> <!-- Reference CALS Table Model --> <!ENTITY % tablemodel PUBLIC "-//OASIS//DTD DocBook CALS Table Model V4.5//EN" "calstblx.dtd"> ]]> <![%exchange.table.module;[ <!-- Add common attributes and the Label attribute to Table and --> <!-- InformalTable. --> <!ENTITY % bodyatt "%common.attrib; rowheader (firstcol|norowheader) #IMPLIED %label.attrib; %tables.role.attrib;"> <!ENTITY % common.table.attribs "%bodyatt;"> <!-- Add common attributes to TGroup, ColSpec, TBody, THead, Row, Entry --> <!ENTITY % tbl.tgroup.att "%common.attrib;"> <!ENTITY % tbl.colspec.att "%common.attrib;"> <!ENTITY % tbl.tbody.att "%common.attrib;"> <!ENTITY % tbl.thead.att "%common.attrib;"> <!ENTITY % tbl.row.att "%common.attrib;"> <!ENTITY % tbl.entry.att "%common.attrib;"> <!-- Content model for Table. --> <!ENTITY % tbl.table.mdl "(blockinfo?, (%formalobject.title.content;), (%ndxterm.class;)*, textobject*, (graphic+|mediaobject+|tgroup+))"> <!-- Allow either objects or inlines; beware of REs between elements. --> <!ENTITY % tbl.entry.mdl "(%para.char.mix; | %tabentry.mix;)*"> <!-- Reference OASIS Exchange Table Model --> <!ENTITY % tablemodel PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN" "soextblx.dtd"> ]]> %tablemodel; <!--end of table.module-->]]> <!ENTITY % informaltable.module "INCLUDE"> <![%informaltable.module;[ <!-- Note that InformalTable is dependent on some of the entity declarations that customize Table. --> <!ENTITY % local.informaltable.attrib ""> <!-- the following entity may have been declared by the XHTML table module --> <!ENTITY % informal.tbl.table.mdl "textobject*, (graphic+|mediaobject+|tgroup+)"> <!ENTITY % informaltable.element "INCLUDE"> <![%informaltable.element;[ <!--doc:A table without a title.--> <!ELEMENT informaltable %ho; (blockinfo?, (%informal.tbl.table.mdl;))> <!--end of informaltable.element-->]]> <!-- Frame, Colsep, and Rowsep must be repeated because they are not in entities in the table module. --> <!-- includes TabStyle, ToCentry, ShortEntry, Orient, PgWide --> <!-- includes Label --> <!-- includes common attributes --> <!ENTITY % informaltable.attlist "INCLUDE"> <![%informaltable.attlist;[ <!ATTLIST informaltable frame (%tbl.frame.attval;) #IMPLIED colsep %yesorno.attvals; #IMPLIED rowsep %yesorno.attvals; #IMPLIED %common.table.attribs; %tbl.table.att; %local.informaltable.attrib; > <!--end of informaltable.attlist-->]]> <!--end of informaltable.module-->]]> <!ENTITY % caption.module "INCLUDE"> <![ %caption.module; [ <!ENTITY % local.caption.attrib ""> <!ENTITY % caption.role.attrib "%role.attrib;"> <!ENTITY % caption.element "INCLUDE"> <![ %caption.element; [ <!--doc:A caption.--> <!ELEMENT caption %ho; (#PCDATA | %textobject.mix;)*> <!--end of caption.element-->]]> <!ENTITY % caption.attlist "INCLUDE"> <![ %caption.attlist; [ <!-- attrs comes from HTML tables ... --> <![ %allow.html.tables; [ <!-- common.attrib, but without ID because ID is in attrs --> <!ENTITY % caption.attlist.content " %caption.role.attrib; %attrs; align (top|bottom|left|right) #IMPLIED %local.caption.attrib; "> ]]> <!ENTITY % caption.attlist.content " %common.attrib; %caption.role.attrib; %local.caption.attrib; "> <!ATTLIST caption %caption.attlist.content;> <!--end of caption.attlist-->]]> <!--end of caption.module-->]]> <!-- ...................................................................... --> <!-- Synopses ............................................................. --> <!-- Synopsis ......................... --> <!ENTITY % synopsis.module "INCLUDE"> <![%synopsis.module;[ <!ENTITY % local.synopsis.attrib ""> <!ENTITY % synopsis.role.attrib "%role.attrib;"> <!ENTITY % synopsis.element "INCLUDE"> <![%synopsis.element;[ <!--doc:A general-purpose element for representing the syntax of commands or functions.--> <!ELEMENT synopsis %ho; (%para.char.mix;|graphic|mediaobject|co|coref|textobject|lineannotation)*> <!--end of synopsis.element-->]]> <!ENTITY % synopsis.attlist "INCLUDE"> <![%synopsis.attlist;[ <!ATTLIST synopsis %label.attrib; %linespecific.attrib; %common.attrib; %synopsis.role.attrib; %local.synopsis.attrib; > <!--end of synopsis.attlist-->]]> <!-- LineAnnotation (defined in the Inlines section, below)--> <!--end of synopsis.module-->]]> <!-- CmdSynopsis ...................... --> <!ENTITY % cmdsynopsis.content.module "INCLUDE"> <![%cmdsynopsis.content.module;[ <!ENTITY % cmdsynopsis.module "INCLUDE"> <![%cmdsynopsis.module;[ <!ENTITY % local.cmdsynopsis.attrib ""> <!ENTITY % cmdsynopsis.role.attrib "%role.attrib;"> <!ENTITY % cmdsynopsis.element "INCLUDE"> <![%cmdsynopsis.element;[ <!--doc:A syntax summary for a software command.--> <!ELEMENT cmdsynopsis %ho; ((command | arg | group | sbr)+, synopfragment*)> <!--end of cmdsynopsis.element-->]]> <!-- Sepchar: Character that should separate command and all top-level arguments; alternate value might be e.g., Δ --> <!ENTITY % cmdsynopsis.attlist "INCLUDE"> <![%cmdsynopsis.attlist;[ <!ATTLIST cmdsynopsis %label.attrib; sepchar CDATA " " cmdlength CDATA #IMPLIED %common.attrib; %cmdsynopsis.role.attrib; %local.cmdsynopsis.attrib; > <!--end of cmdsynopsis.attlist-->]]> <!--end of cmdsynopsis.module-->]]> <!ENTITY % arg.module "INCLUDE"> <![%arg.module;[ <!ENTITY % local.arg.attrib ""> <!ENTITY % arg.role.attrib "%role.attrib;"> <!ENTITY % arg.element "INCLUDE"> <![%arg.element;[ <!--doc:An argument in a CmdSynopsis.--> <!ELEMENT arg %ho; (#PCDATA | arg | group | option | synopfragmentref | replaceable | sbr)*> <!--end of arg.element-->]]> <!-- Choice: Whether Arg must be supplied: Opt (optional to supply, e.g. [arg]; the default), Req (required to supply, e.g. {arg}), or Plain (required to supply, e.g. arg) --> <!-- Rep: whether Arg is repeatable: Norepeat (e.g. arg without ellipsis; the default), or Repeat (e.g. arg...) --> <!ENTITY % arg.attlist "INCLUDE"> <![%arg.attlist;[ <!ATTLIST arg choice (opt |req |plain) 'opt' rep (norepeat |repeat) 'norepeat' %common.attrib; %arg.role.attrib; %local.arg.attrib; > <!--end of arg.attlist-->]]> <!--end of arg.module-->]]> <!ENTITY % group.module "INCLUDE"> <![%group.module;[ <!ENTITY % local.group.attrib ""> <!ENTITY % group.role.attrib "%role.attrib;"> <!ENTITY % group.element "INCLUDE"> <![%group.element;[ <!--doc:A group of elements in a CmdSynopsis.--> <!ELEMENT group %ho; ((arg | group | option | synopfragmentref | replaceable | sbr)+)> <!--end of group.element-->]]> <!-- Choice: Whether Group must be supplied: Opt (optional to supply, e.g. [g1|g2|g3]; the default), Req (required to supply, e.g. {g1|g2|g3}), Plain (required to supply, e.g. g1|g2|g3), OptMult (can supply zero or more, e.g. [[g1|g2|g3]]), or ReqMult (must supply one or more, e.g. {{g1|g2|g3}}) --> <!-- Rep: whether Group is repeatable: Norepeat (e.g. group without ellipsis; the default), or Repeat (e.g. group...) --> <!ENTITY % group.attlist "INCLUDE"> <![%group.attlist;[ <!ATTLIST group choice (opt |req |plain) 'opt' rep (norepeat |repeat) 'norepeat' %common.attrib; %group.role.attrib; %local.group.attrib; > <!--end of group.attlist-->]]> <!--end of group.module-->]]> <!ENTITY % sbr.module "INCLUDE"> <![%sbr.module;[ <!ENTITY % local.sbr.attrib ""> <!-- Synopsis break --> <!ENTITY % sbr.role.attrib "%role.attrib;"> <!ENTITY % sbr.element "INCLUDE"> <![%sbr.element;[ <!--doc:An explicit line break in a command synopsis.--> <!ELEMENT sbr %ho; EMPTY> <!--end of sbr.element-->]]> <!ENTITY % sbr.attlist "INCLUDE"> <![%sbr.attlist;[ <!ATTLIST sbr %common.attrib; %sbr.role.attrib; %local.sbr.attrib; > <!--end of sbr.attlist-->]]> <!--end of sbr.module-->]]> <!ENTITY % synopfragmentref.module "INCLUDE"> <![%synopfragmentref.module;[ <!ENTITY % local.synopfragmentref.attrib ""> <!ENTITY % synopfragmentref.role.attrib "%role.attrib;"> <!ENTITY % synopfragmentref.element "INCLUDE"> <![%synopfragmentref.element;[ <!--doc:A reference to a fragment of a command synopsis.--> <!ELEMENT synopfragmentref %ho; (#PCDATA)> <!--end of synopfragmentref.element-->]]> <!-- to SynopFragment of complex synopsis material for separate referencing --> <!ENTITY % synopfragmentref.attlist "INCLUDE"> <![%synopfragmentref.attlist;[ <!ATTLIST synopfragmentref %linkendreq.attrib; %common.attrib; %synopfragmentref.role.attrib; %local.synopfragmentref.attrib; > <!--end of synopfragmentref.attlist-->]]> <!--end of synopfragmentref.module-->]]> <!ENTITY % synopfragment.module "INCLUDE"> <![%synopfragment.module;[ <!ENTITY % local.synopfragment.attrib ""> <!ENTITY % synopfragment.role.attrib "%role.attrib;"> <!ENTITY % synopfragment.element "INCLUDE"> <![%synopfragment.element;[ <!--doc:A portion of a CmdSynopsis broken out from the main body of the synopsis.--> <!ELEMENT synopfragment %ho; ((arg | group)+)> <!--end of synopfragment.element-->]]> <!ENTITY % synopfragment.attlist "INCLUDE"> <![%synopfragment.attlist;[ <!ATTLIST synopfragment %idreq.common.attrib; %synopfragment.role.attrib; %local.synopfragment.attrib; > <!--end of synopfragment.attlist-->]]> <!--end of synopfragment.module-->]]> <!-- Command (defined in the Inlines section, below)--> <!-- Option (defined in the Inlines section, below)--> <!-- Replaceable (defined in the Inlines section, below)--> <!--end of cmdsynopsis.content.module-->]]> <!-- FuncSynopsis ..................... --> <!ENTITY % funcsynopsis.content.module "INCLUDE"> <![%funcsynopsis.content.module;[ <!ENTITY % funcsynopsis.module "INCLUDE"> <![%funcsynopsis.module;[ <!ENTITY % local.funcsynopsis.attrib ""> <!ENTITY % funcsynopsis.role.attrib "%role.attrib;"> <!ENTITY % funcsynopsis.element "INCLUDE"> <![%funcsynopsis.element;[ <!--doc:The syntax summary for a function definition.--> <!ELEMENT funcsynopsis %ho; ((funcsynopsisinfo | funcprototype)+)> <!--end of funcsynopsis.element-->]]> <!ENTITY % funcsynopsis.attlist "INCLUDE"> <![%funcsynopsis.attlist;[ <!ATTLIST funcsynopsis %label.attrib; %common.attrib; %funcsynopsis.role.attrib; %local.funcsynopsis.attrib; > <!--end of funcsynopsis.attlist-->]]> <!--end of funcsynopsis.module-->]]> <!ENTITY % funcsynopsisinfo.module "INCLUDE"> <![%funcsynopsisinfo.module;[ <!ENTITY % local.funcsynopsisinfo.attrib ""> <!ENTITY % funcsynopsisinfo.role.attrib "%role.attrib;"> <!ENTITY % funcsynopsisinfo.element "INCLUDE"> <![%funcsynopsisinfo.element;[ <!--doc:Information supplementing the FuncDefs of a FuncSynopsis.--> <!ELEMENT funcsynopsisinfo %ho; (%cptr.char.mix;|textobject|lineannotation)*> <!--end of funcsynopsisinfo.element-->]]> <!ENTITY % funcsynopsisinfo.attlist "INCLUDE"> <![%funcsynopsisinfo.attlist;[ <!ATTLIST funcsynopsisinfo %linespecific.attrib; %common.attrib; %funcsynopsisinfo.role.attrib; %local.funcsynopsisinfo.attrib; > <!--end of funcsynopsisinfo.attlist-->]]> <!--end of funcsynopsisinfo.module-->]]> <!ENTITY % funcprototype.module "INCLUDE"> <![%funcprototype.module;[ <!ENTITY % local.funcprototype.attrib ""> <!ENTITY % funcprototype.role.attrib "%role.attrib;"> <!ENTITY % funcprototype.element "INCLUDE"> <![%funcprototype.element;[ <!--doc:The prototype of a function.--> <!ELEMENT funcprototype %ho; (modifier*, funcdef, (void|varargs|(paramdef+, varargs?)), modifier*)> <!--end of funcprototype.element-->]]> <!ENTITY % funcprototype.attlist "INCLUDE"> <![%funcprototype.attlist;[ <!ATTLIST funcprototype %common.attrib; %funcprototype.role.attrib; %local.funcprototype.attrib; > <!--end of funcprototype.attlist-->]]> <!--end of funcprototype.module-->]]> <!ENTITY % funcdef.module "INCLUDE"> <![%funcdef.module;[ <!ENTITY % local.funcdef.attrib ""> <!ENTITY % funcdef.role.attrib "%role.attrib;"> <!ENTITY % funcdef.element "INCLUDE"> <![%funcdef.element;[ <!--doc:A function (subroutine) name and its return type.--> <!ELEMENT funcdef %ho; (#PCDATA | type | replaceable | function)*> <!--end of funcdef.element-->]]> <!ENTITY % funcdef.attlist "INCLUDE"> <![%funcdef.attlist;[ <!ATTLIST funcdef %common.attrib; %funcdef.role.attrib; %local.funcdef.attrib; > <!--end of funcdef.attlist-->]]> <!--end of funcdef.module-->]]> <!ENTITY % void.module "INCLUDE"> <![%void.module;[ <!ENTITY % local.void.attrib ""> <!ENTITY % void.role.attrib "%role.attrib;"> <!ENTITY % void.element "INCLUDE"> <![%void.element;[ <!--doc:An empty element in a function synopsis indicating that the function in question takes no arguments.--> <!ELEMENT void %ho; EMPTY> <!--end of void.element-->]]> <!ENTITY % void.attlist "INCLUDE"> <![%void.attlist;[ <!ATTLIST void %common.attrib; %void.role.attrib; %local.void.attrib; > <!--end of void.attlist-->]]> <!--end of void.module-->]]> <!ENTITY % varargs.module "INCLUDE"> <![%varargs.module;[ <!ENTITY % local.varargs.attrib ""> <!ENTITY % varargs.role.attrib "%role.attrib;"> <!ENTITY % varargs.element "INCLUDE"> <![%varargs.element;[ <!--doc:An empty element in a function synopsis indicating a variable number of arguments.--> <!ELEMENT varargs %ho; EMPTY> <!--end of varargs.element-->]]> <!ENTITY % varargs.attlist "INCLUDE"> <![%varargs.attlist;[ <!ATTLIST varargs %common.attrib; %varargs.role.attrib; %local.varargs.attrib; > <!--end of varargs.attlist-->]]> <!--end of varargs.module-->]]> <!-- Processing assumes that only one Parameter will appear in a ParamDef, and that FuncParams will be used at most once, for providing information on the "inner parameters" for parameters that are pointers to functions. --> <!ENTITY % paramdef.module "INCLUDE"> <![%paramdef.module;[ <!ENTITY % local.paramdef.attrib ""> <!ENTITY % paramdef.role.attrib "%role.attrib;"> <!ENTITY % paramdef.element "INCLUDE"> <![%paramdef.element;[ <!--doc:Information about a function parameter in a programming language.--> <!ELEMENT paramdef %ho; (#PCDATA | initializer | type | replaceable | parameter | funcparams)*> <!--end of paramdef.element-->]]> <!ENTITY % paramdef.attlist "INCLUDE"> <![%paramdef.attlist;[ <!ATTLIST paramdef choice (opt |req) #IMPLIED %common.attrib; %paramdef.role.attrib; %local.paramdef.attrib; > <!--end of paramdef.attlist-->]]> <!--end of paramdef.module-->]]> <!ENTITY % funcparams.module "INCLUDE"> <![%funcparams.module;[ <!ENTITY % local.funcparams.attrib ""> <!ENTITY % funcparams.role.attrib "%role.attrib;"> <!ENTITY % funcparams.element "INCLUDE"> <![%funcparams.element;[ <!--doc:Parameters for a function referenced through a function pointer in a synopsis.--> <!ELEMENT funcparams %ho; (%cptr.char.mix;)*> <!--end of funcparams.element-->]]> <!ENTITY % funcparams.attlist "INCLUDE"> <![%funcparams.attlist;[ <!ATTLIST funcparams %common.attrib; %funcparams.role.attrib; %local.funcparams.attrib; > <!--end of funcparams.attlist-->]]> <!--end of funcparams.module-->]]> <!-- LineAnnotation (defined in the Inlines section, below)--> <!-- Replaceable (defined in the Inlines section, below)--> <!-- Function (defined in the Inlines section, below)--> <!-- Parameter (defined in the Inlines section, below)--> <!--end of funcsynopsis.content.module-->]]> <!-- ClassSynopsis ..................... --> <!ENTITY % classsynopsis.content.module "INCLUDE"> <![%classsynopsis.content.module;[ <!ENTITY % classsynopsis.module "INCLUDE"> <![%classsynopsis.module;[ <!ENTITY % local.classsynopsis.attrib ""> <!ENTITY % classsynopsis.role.attrib "%role.attrib;"> <!ENTITY % classsynopsis.element "INCLUDE"> <![%classsynopsis.element;[ <!--doc:The syntax summary for a class definition.--> <!ELEMENT classsynopsis %ho; ((ooclass|oointerface|ooexception)+, (classsynopsisinfo |fieldsynopsis|%method.synop.class;)*)> <!--end of classsynopsis.element-->]]> <!ENTITY % classsynopsis.attlist "INCLUDE"> <![%classsynopsis.attlist;[ <!ATTLIST classsynopsis language CDATA #IMPLIED class (class|interface) "class" %common.attrib; %classsynopsis.role.attrib; %local.classsynopsis.attrib; > <!--end of classsynopsis.attlist-->]]> <!--end of classsynopsis.module-->]]> <!ENTITY % classsynopsisinfo.module "INCLUDE"> <![ %classsynopsisinfo.module; [ <!ENTITY % local.classsynopsisinfo.attrib ""> <!ENTITY % classsynopsisinfo.role.attrib "%role.attrib;"> <!ENTITY % classsynopsisinfo.element "INCLUDE"> <![ %classsynopsisinfo.element; [ <!--doc:Information supplementing the contents of a ClassSynopsis.--> <!ELEMENT classsynopsisinfo %ho; (%cptr.char.mix;|textobject|lineannotation)*> <!--end of classsynopsisinfo.element-->]]> <!ENTITY % classsynopsisinfo.attlist "INCLUDE"> <![ %classsynopsisinfo.attlist; [ <!ATTLIST classsynopsisinfo %linespecific.attrib; %common.attrib; %classsynopsisinfo.role.attrib; %local.classsynopsisinfo.attrib; > <!--end of classsynopsisinfo.attlist-->]]> <!--end of classsynopsisinfo.module-->]]> <!ENTITY % ooclass.module "INCLUDE"> <![%ooclass.module;[ <!ENTITY % local.ooclass.attrib ""> <!ENTITY % ooclass.role.attrib "%role.attrib;"> <!ENTITY % ooclass.element "INCLUDE"> <![%ooclass.element;[ <!--doc:A class in an object-oriented programming language.--> <!ELEMENT ooclass %ho; ((modifier|package)*, classname)> <!--end of ooclass.element-->]]> <!ENTITY % ooclass.attlist "INCLUDE"> <![%ooclass.attlist;[ <!ATTLIST ooclass %common.attrib; %ooclass.role.attrib; %local.ooclass.attrib; > <!--end of ooclass.attlist-->]]> <!--end of ooclass.module-->]]> <!ENTITY % oointerface.module "INCLUDE"> <![%oointerface.module;[ <!ENTITY % local.oointerface.attrib ""> <!ENTITY % oointerface.role.attrib "%role.attrib;"> <!ENTITY % oointerface.element "INCLUDE"> <![%oointerface.element;[ <!--doc:An interface in an object-oriented programming language.--> <!ELEMENT oointerface %ho; ((modifier|package)*, interfacename)> <!--end of oointerface.element-->]]> <!ENTITY % oointerface.attlist "INCLUDE"> <![%oointerface.attlist;[ <!ATTLIST oointerface %common.attrib; %oointerface.role.attrib; %local.oointerface.attrib; > <!--end of oointerface.attlist-->]]> <!--end of oointerface.module-->]]> <!ENTITY % ooexception.module "INCLUDE"> <![%ooexception.module;[ <!ENTITY % local.ooexception.attrib ""> <!ENTITY % ooexception.role.attrib "%role.attrib;"> <!ENTITY % ooexception.element "INCLUDE"> <![%ooexception.element;[ <!--doc:An exception in an object-oriented programming language.--> <!ELEMENT ooexception %ho; ((modifier|package)*, exceptionname)> <!--end of ooexception.element-->]]> <!ENTITY % ooexception.attlist "INCLUDE"> <![%ooexception.attlist;[ <!ATTLIST ooexception %common.attrib; %ooexception.role.attrib; %local.ooexception.attrib; > <!--end of ooexception.attlist-->]]> <!--end of ooexception.module-->]]> <!ENTITY % modifier.module "INCLUDE"> <![%modifier.module;[ <!ENTITY % local.modifier.attrib ""> <!ENTITY % modifier.role.attrib "%role.attrib;"> <!ENTITY % modifier.element "INCLUDE"> <![%modifier.element;[ <!--doc:Modifiers in a synopsis.--> <!ELEMENT modifier %ho; (%smallcptr.char.mix;)*> <!--end of modifier.element-->]]> <!ENTITY % modifier.attlist "INCLUDE"> <![%modifier.attlist;[ <!ATTLIST modifier %common.attrib; %modifier.role.attrib; %local.modifier.attrib; > <!--end of modifier.attlist-->]]> <!--end of modifier.module-->]]> <!ENTITY % interfacename.module "INCLUDE"> <![%interfacename.module;[ <!ENTITY % local.interfacename.attrib ""> <!ENTITY % interfacename.role.attrib "%role.attrib;"> <!ENTITY % interfacename.element "INCLUDE"> <![%interfacename.element;[ <!--doc:The name of an interface.--> <!ELEMENT interfacename %ho; (%cptr.char.mix;)*> <!--end of interfacename.element-->]]> <!ENTITY % interfacename.attlist "INCLUDE"> <![%interfacename.attlist;[ <!ATTLIST interfacename %common.attrib; %interfacename.role.attrib; %local.interfacename.attrib; > <!--end of interfacename.attlist-->]]> <!--end of interfacename.module-->]]> <!ENTITY % exceptionname.module "INCLUDE"> <![%exceptionname.module;[ <!ENTITY % local.exceptionname.attrib ""> <!ENTITY % exceptionname.role.attrib "%role.attrib;"> <!ENTITY % exceptionname.element "INCLUDE"> <![%exceptionname.element;[ <!--doc:The name of an exception.--> <!ELEMENT exceptionname %ho; (%smallcptr.char.mix;)*> <!--end of exceptionname.element-->]]> <!ENTITY % exceptionname.attlist "INCLUDE"> <![%exceptionname.attlist;[ <!ATTLIST exceptionname %common.attrib; %exceptionname.role.attrib; %local.exceptionname.attrib; > <!--end of exceptionname.attlist-->]]> <!--end of exceptionname.module-->]]> <!ENTITY % fieldsynopsis.module "INCLUDE"> <![%fieldsynopsis.module;[ <!ENTITY % local.fieldsynopsis.attrib ""> <!ENTITY % fieldsynopsis.role.attrib "%role.attrib;"> <!ENTITY % fieldsynopsis.element "INCLUDE"> <![%fieldsynopsis.element;[ <!--doc:The name of a field in a class definition.--> <!ELEMENT fieldsynopsis %ho; (modifier*, type?, varname, initializer?)> <!--end of fieldsynopsis.element-->]]> <!ENTITY % fieldsynopsis.attlist "INCLUDE"> <![%fieldsynopsis.attlist;[ <!ATTLIST fieldsynopsis language CDATA #IMPLIED %common.attrib; %fieldsynopsis.role.attrib; %local.fieldsynopsis.attrib; > <!--end of fieldsynopsis.attlist-->]]> <!--end of fieldsynopsis.module-->]]> <!ENTITY % initializer.module "INCLUDE"> <![%initializer.module;[ <!ENTITY % local.initializer.attrib ""> <!ENTITY % initializer.role.attrib "%role.attrib;"> <!ENTITY % initializer.element "INCLUDE"> <![%initializer.element;[ <!--doc:The initializer for a FieldSynopsis.--> <!ELEMENT initializer %ho; (%smallcptr.char.mix;)*> <!--end of initializer.element-->]]> <!ENTITY % initializer.attlist "INCLUDE"> <![%initializer.attlist;[ <!ATTLIST initializer %common.attrib; %initializer.role.attrib; %local.initializer.attrib; > <!--end of initializer.attlist-->]]> <!--end of initializer.module-->]]> <!ENTITY % constructorsynopsis.module "INCLUDE"> <![%constructorsynopsis.module;[ <!ENTITY % local.constructorsynopsis.attrib ""> <!ENTITY % constructorsynopsis.role.attrib "%role.attrib;"> <!ENTITY % constructorsynopsis.element "INCLUDE"> <![%constructorsynopsis.element;[ <!--doc:A syntax summary for a constructor.--> <!ELEMENT constructorsynopsis %ho; (modifier*, methodname?, (methodparam+|void?), exceptionname*)> <!--end of constructorsynopsis.element-->]]> <!ENTITY % constructorsynopsis.attlist "INCLUDE"> <![%constructorsynopsis.attlist;[ <!ATTLIST constructorsynopsis language CDATA #IMPLIED %common.attrib; %constructorsynopsis.role.attrib; %local.constructorsynopsis.attrib; > <!--end of constructorsynopsis.attlist-->]]> <!--end of constructorsynopsis.module-->]]> <!ENTITY % destructorsynopsis.module "INCLUDE"> <![%destructorsynopsis.module;[ <!ENTITY % local.destructorsynopsis.attrib ""> <!ENTITY % destructorsynopsis.role.attrib "%role.attrib;"> <!ENTITY % destructorsynopsis.element "INCLUDE"> <![%destructorsynopsis.element;[ <!--doc:A syntax summary for a destructor.--> <!ELEMENT destructorsynopsis %ho; (modifier*, methodname?, (methodparam+|void?), exceptionname*)> <!--end of destructorsynopsis.element-->]]> <!ENTITY % destructorsynopsis.attlist "INCLUDE"> <![%destructorsynopsis.attlist;[ <!ATTLIST destructorsynopsis language CDATA #IMPLIED %common.attrib; %destructorsynopsis.role.attrib; %local.destructorsynopsis.attrib; > <!--end of destructorsynopsis.attlist-->]]> <!--end of destructorsynopsis.module-->]]> <!ENTITY % methodsynopsis.module "INCLUDE"> <![%methodsynopsis.module;[ <!ENTITY % local.methodsynopsis.attrib ""> <!ENTITY % methodsynopsis.role.attrib "%role.attrib;"> <!ENTITY % methodsynopsis.element "INCLUDE"> <![%methodsynopsis.element;[ <!--doc:A syntax summary for a method.--> <!ELEMENT methodsynopsis %ho; (modifier*, (type|void)?, methodname, (methodparam+|void?), exceptionname*, modifier*)> <!--end of methodsynopsis.element-->]]> <!ENTITY % methodsynopsis.attlist "INCLUDE"> <![%methodsynopsis.attlist;[ <!ATTLIST methodsynopsis language CDATA #IMPLIED %common.attrib; %methodsynopsis.role.attrib; %local.methodsynopsis.attrib; > <!--end of methodsynopsis.attlist-->]]> <!--end of methodsynopsis.module-->]]> <!ENTITY % methodname.module "INCLUDE"> <![%methodname.module;[ <!ENTITY % local.methodname.attrib ""> <!ENTITY % methodname.role.attrib "%role.attrib;"> <!ENTITY % methodname.element "INCLUDE"> <![%methodname.element;[ <!--doc:The name of a method.--> <!ELEMENT methodname %ho; (%smallcptr.char.mix;)*> <!--end of methodname.element-->]]> <!ENTITY % methodname.attlist "INCLUDE"> <![%methodname.attlist;[ <!ATTLIST methodname %common.attrib; %methodname.role.attrib; %local.methodname.attrib; > <!--end of methodname.attlist-->]]> <!--end of methodname.module-->]]> <!ENTITY % methodparam.module "INCLUDE"> <![%methodparam.module;[ <!ENTITY % local.methodparam.attrib ""> <!ENTITY % methodparam.role.attrib "%role.attrib;"> <!ENTITY % methodparam.element "INCLUDE"> <![%methodparam.element;[ <!--doc:Parameters to a method.--> <!ELEMENT methodparam %ho; (modifier*, type?, ((parameter,initializer?)|funcparams), modifier*)> <!--end of methodparam.element-->]]> <!ENTITY % methodparam.attlist "INCLUDE"> <![%methodparam.attlist;[ <!ATTLIST methodparam choice (opt |req |plain) "req" rep (norepeat |repeat) "norepeat" %common.attrib; %methodparam.role.attrib; %local.methodparam.attrib; > <!--end of methodparam.attlist-->]]> <!--end of methodparam.module-->]]> <!--end of classsynopsis.content.module-->]]> <!-- ...................................................................... --> <!-- Document information entities and elements ........................... --> <!-- The document information elements include some elements that are currently used only in the document hierarchy module. They are defined here so that they will be available for use in customized document hierarchies. --> <!-- .................................. --> <!ENTITY % docinfo.content.module "INCLUDE"> <![%docinfo.content.module;[ <!-- Ackno ............................ --> <!ENTITY % ackno.module "INCLUDE"> <![%ackno.module;[ <!ENTITY % local.ackno.attrib ""> <!ENTITY % ackno.role.attrib "%role.attrib;"> <!ENTITY % ackno.element "INCLUDE"> <![%ackno.element;[ <!--doc:Acknowledgements in an Article.--> <!ELEMENT ackno %ho; (%docinfo.char.mix;)*> <!--end of ackno.element-->]]> <!ENTITY % ackno.attlist "INCLUDE"> <![%ackno.attlist;[ <!ATTLIST ackno %common.attrib; %ackno.role.attrib; %local.ackno.attrib; > <!--end of ackno.attlist-->]]> <!--end of ackno.module-->]]> <!-- Address .......................... --> <!ENTITY % address.content.module "INCLUDE"> <![%address.content.module;[ <!ENTITY % address.module "INCLUDE"> <![%address.module;[ <!ENTITY % local.address.attrib ""> <!ENTITY % address.role.attrib "%role.attrib;"> <!ENTITY % address.element "INCLUDE"> <![%address.element;[ <!--doc:A real-world address, generally a postal address.--> <!ELEMENT address %ho; (#PCDATA|personname|%person.ident.mix; |street|pob|postcode|city|state|country|phone |fax|email|otheraddr)*> <!--end of address.element-->]]> <!ENTITY % address.attlist "INCLUDE"> <![%address.attlist;[ <!ATTLIST address %linespecific.attrib; %common.attrib; %address.role.attrib; %local.address.attrib; > <!--end of address.attlist-->]]> <!--end of address.module-->]]> <!ENTITY % street.module "INCLUDE"> <![%street.module;[ <!ENTITY % local.street.attrib ""> <!ENTITY % street.role.attrib "%role.attrib;"> <!ENTITY % street.element "INCLUDE"> <![%street.element;[ <!--doc:A street address in an address.--> <!ELEMENT street %ho; (%docinfo.char.mix;)*> <!--end of street.element-->]]> <!ENTITY % street.attlist "INCLUDE"> <![%street.attlist;[ <!ATTLIST street %common.attrib; %street.role.attrib; %local.street.attrib; > <!--end of street.attlist-->]]> <!--end of street.module-->]]> <!ENTITY % pob.module "INCLUDE"> <![%pob.module;[ <!ENTITY % local.pob.attrib ""> <!ENTITY % pob.role.attrib "%role.attrib;"> <!ENTITY % pob.element "INCLUDE"> <![%pob.element;[ <!--doc:A post office box in an address.--> <!ELEMENT pob %ho; (%docinfo.char.mix;)*> <!--end of pob.element-->]]> <!ENTITY % pob.attlist "INCLUDE"> <![%pob.attlist;[ <!ATTLIST pob %common.attrib; %pob.role.attrib; %local.pob.attrib; > <!--end of pob.attlist-->]]> <!--end of pob.module-->]]> <!ENTITY % postcode.module "INCLUDE"> <![%postcode.module;[ <!ENTITY % local.postcode.attrib ""> <!ENTITY % postcode.role.attrib "%role.attrib;"> <!ENTITY % postcode.element "INCLUDE"> <![%postcode.element;[ <!--doc:A postal code in an address.--> <!ELEMENT postcode %ho; (%docinfo.char.mix;)*> <!--end of postcode.element-->]]> <!ENTITY % postcode.attlist "INCLUDE"> <![%postcode.attlist;[ <!ATTLIST postcode %common.attrib; %postcode.role.attrib; %local.postcode.attrib; > <!--end of postcode.attlist-->]]> <!--end of postcode.module-->]]> <!ENTITY % city.module "INCLUDE"> <![%city.module;[ <!ENTITY % local.city.attrib ""> <!ENTITY % city.role.attrib "%role.attrib;"> <!ENTITY % city.element "INCLUDE"> <![%city.element;[ <!--doc:The name of a city in an address.--> <!ELEMENT city %ho; (%docinfo.char.mix;)*> <!--end of city.element-->]]> <!ENTITY % city.attlist "INCLUDE"> <![%city.attlist;[ <!ATTLIST city %common.attrib; %city.role.attrib; %local.city.attrib; > <!--end of city.attlist-->]]> <!--end of city.module-->]]> <!ENTITY % state.module "INCLUDE"> <![%state.module;[ <!ENTITY % local.state.attrib ""> <!ENTITY % state.role.attrib "%role.attrib;"> <!ENTITY % state.element "INCLUDE"> <![%state.element;[ <!--doc:A state or province in an address.--> <!ELEMENT state %ho; (%docinfo.char.mix;)*> <!--end of state.element-->]]> <!ENTITY % state.attlist "INCLUDE"> <![%state.attlist;[ <!ATTLIST state %common.attrib; %state.role.attrib; %local.state.attrib; > <!--end of state.attlist-->]]> <!--end of state.module-->]]> <!ENTITY % country.module "INCLUDE"> <![%country.module;[ <!ENTITY % local.country.attrib ""> <!ENTITY % country.role.attrib "%role.attrib;"> <!ENTITY % country.element "INCLUDE"> <![%country.element;[ <!--doc:The name of a country.--> <!ELEMENT country %ho; (%docinfo.char.mix;)*> <!--end of country.element-->]]> <!ENTITY % country.attlist "INCLUDE"> <![%country.attlist;[ <!ATTLIST country %common.attrib; %country.role.attrib; %local.country.attrib; > <!--end of country.attlist-->]]> <!--end of country.module-->]]> <!ENTITY % phone.module "INCLUDE"> <![%phone.module;[ <!ENTITY % local.phone.attrib ""> <!ENTITY % phone.role.attrib "%role.attrib;"> <!ENTITY % phone.element "INCLUDE"> <![%phone.element;[ <!--doc:A telephone number.--> <!ELEMENT phone %ho; (%docinfo.char.mix;)*> <!--end of phone.element-->]]> <!ENTITY % phone.attlist "INCLUDE"> <![%phone.attlist;[ <!ATTLIST phone %common.attrib; %phone.role.attrib; %local.phone.attrib; > <!--end of phone.attlist-->]]> <!--end of phone.module-->]]> <!ENTITY % fax.module "INCLUDE"> <![%fax.module;[ <!ENTITY % local.fax.attrib ""> <!ENTITY % fax.role.attrib "%role.attrib;"> <!ENTITY % fax.element "INCLUDE"> <![%fax.element;[ <!--doc:A fax number.--> <!ELEMENT fax %ho; (%docinfo.char.mix;)*> <!--end of fax.element-->]]> <!ENTITY % fax.attlist "INCLUDE"> <![%fax.attlist;[ <!ATTLIST fax %common.attrib; %fax.role.attrib; %local.fax.attrib; > <!--end of fax.attlist-->]]> <!--end of fax.module-->]]> <!-- Email (defined in the Inlines section, below)--> <!ENTITY % otheraddr.module "INCLUDE"> <![%otheraddr.module;[ <!ENTITY % local.otheraddr.attrib ""> <!ENTITY % otheraddr.role.attrib "%role.attrib;"> <!ENTITY % otheraddr.element "INCLUDE"> <![%otheraddr.element;[ <!--doc:Uncategorized information in address.--> <!ELEMENT otheraddr %ho; (%docinfo.char.mix;)*> <!--end of otheraddr.element-->]]> <!ENTITY % otheraddr.attlist "INCLUDE"> <![%otheraddr.attlist;[ <!ATTLIST otheraddr %common.attrib; %otheraddr.role.attrib; %local.otheraddr.attrib; > <!--end of otheraddr.attlist-->]]> <!--end of otheraddr.module-->]]> <!--end of address.content.module-->]]> <!-- Affiliation ...................... --> <!ENTITY % affiliation.content.module "INCLUDE"> <![%affiliation.content.module;[ <!ENTITY % affiliation.module "INCLUDE"> <![%affiliation.module;[ <!ENTITY % local.affiliation.attrib ""> <!ENTITY % affiliation.role.attrib "%role.attrib;"> <!ENTITY % affiliation.element "INCLUDE"> <![%affiliation.element;[ <!--doc:The institutional affiliation of an individual.--> <!ELEMENT affiliation %ho; (shortaffil?, jobtitle*, orgname?, orgdiv*, address*)> <!--end of affiliation.element-->]]> <!ENTITY % affiliation.attlist "INCLUDE"> <![%affiliation.attlist;[ <!ATTLIST affiliation %common.attrib; %affiliation.role.attrib; %local.affiliation.attrib; > <!--end of affiliation.attlist-->]]> <!--end of affiliation.module-->]]> <!ENTITY % shortaffil.module "INCLUDE"> <![%shortaffil.module;[ <!ENTITY % local.shortaffil.attrib ""> <!ENTITY % shortaffil.role.attrib "%role.attrib;"> <!ENTITY % shortaffil.element "INCLUDE"> <![%shortaffil.element;[ <!--doc:A brief description of an affiliation.--> <!ELEMENT shortaffil %ho; (%docinfo.char.mix;)*> <!--end of shortaffil.element-->]]> <!ENTITY % shortaffil.attlist "INCLUDE"> <![%shortaffil.attlist;[ <!ATTLIST shortaffil %common.attrib; %shortaffil.role.attrib; %local.shortaffil.attrib; > <!--end of shortaffil.attlist-->]]> <!--end of shortaffil.module-->]]> <!ENTITY % jobtitle.module "INCLUDE"> <![%jobtitle.module;[ <!ENTITY % local.jobtitle.attrib ""> <!ENTITY % jobtitle.role.attrib "%role.attrib;"> <!ENTITY % jobtitle.element "INCLUDE"> <![%jobtitle.element;[ <!--doc:The title of an individual in an organization.--> <!ELEMENT jobtitle %ho; (%docinfo.char.mix;)*> <!--end of jobtitle.element-->]]> <!ENTITY % jobtitle.attlist "INCLUDE"> <![%jobtitle.attlist;[ <!ATTLIST jobtitle %common.attrib; %jobtitle.role.attrib; %local.jobtitle.attrib; > <!--end of jobtitle.attlist-->]]> <!--end of jobtitle.module-->]]> <!-- OrgName (defined elsewhere in this section)--> <!ENTITY % orgdiv.module "INCLUDE"> <![%orgdiv.module;[ <!ENTITY % local.orgdiv.attrib ""> <!ENTITY % orgdiv.role.attrib "%role.attrib;"> <!ENTITY % orgdiv.element "INCLUDE"> <![%orgdiv.element;[ <!--doc:A division of an organization.--> <!ELEMENT orgdiv %ho; (%docinfo.char.mix;)*> <!--end of orgdiv.element-->]]> <!ENTITY % orgdiv.attlist "INCLUDE"> <![%orgdiv.attlist;[ <!ATTLIST orgdiv %common.attrib; %orgdiv.role.attrib; %local.orgdiv.attrib; > <!--end of orgdiv.attlist-->]]> <!--end of orgdiv.module-->]]> <!-- Address (defined elsewhere in this section)--> <!--end of affiliation.content.module-->]]> <!-- ArtPageNums ...................... --> <!ENTITY % artpagenums.module "INCLUDE"> <![%artpagenums.module;[ <!ENTITY % local.artpagenums.attrib ""> <!ENTITY % artpagenums.role.attrib "%role.attrib;"> <!ENTITY % artpagenums.element "INCLUDE"> <![%artpagenums.element;[ <!--doc:The page numbers of an article as published.--> <!ELEMENT artpagenums %ho; (%docinfo.char.mix;)*> <!--end of artpagenums.element-->]]> <!ENTITY % artpagenums.attlist "INCLUDE"> <![%artpagenums.attlist;[ <!ATTLIST artpagenums %common.attrib; %artpagenums.role.attrib; %local.artpagenums.attrib; > <!--end of artpagenums.attlist-->]]> <!--end of artpagenums.module-->]]> <!-- PersonName --> <!ENTITY % personname.module "INCLUDE"> <![%personname.module;[ <!ENTITY % local.personname.attrib ""> <!ENTITY % personname.role.attrib "%role.attrib;"> <!ENTITY % personname.element "INCLUDE"> <![%personname.element;[ <!--doc:The personal name of an individual.--> <!ELEMENT personname %ho; ((honorific|firstname|surname|lineage|othername)+)> <!--end of personname.element-->]]> <!ENTITY % personname.attlist "INCLUDE"> <![%personname.attlist;[ <!ATTLIST personname %common.attrib; %personname.role.attrib; %local.personname.attrib; > <!--end of personname.attlist-->]]> <!--end of personname.module-->]]> <!-- Author ........................... --> <!ENTITY % author.module "INCLUDE"> <![%author.module;[ <!ENTITY % local.author.attrib ""> <!ENTITY % author.role.attrib "%role.attrib;"> <!ENTITY % author.element "INCLUDE"> <![%author.element;[ <!--doc:The name of an individual author.--> <!ELEMENT author %ho; ((personname|(%person.ident.mix;)+),(personblurb|email|address)*)> <!--end of author.element-->]]> <!ENTITY % author.attlist "INCLUDE"> <![%author.attlist;[ <!ATTLIST author %common.attrib; %author.role.attrib; %local.author.attrib; > <!--end of author.attlist-->]]> <!--(see "Personal identity elements" for %person.ident.mix;)--> <!--end of author.module-->]]> <!-- AuthorGroup ...................... --> <!ENTITY % authorgroup.content.module "INCLUDE"> <![%authorgroup.content.module;[ <!ENTITY % authorgroup.module "INCLUDE"> <![%authorgroup.module;[ <!ENTITY % local.authorgroup.attrib ""> <!ENTITY % authorgroup.role.attrib "%role.attrib;"> <!ENTITY % authorgroup.element "INCLUDE"> <![%authorgroup.element;[ <!--doc:Wrapper for author information when a document has multiple authors or collabarators.--> <!ELEMENT authorgroup %ho; ((author|editor|collab|corpauthor|corpcredit|othercredit)+)> <!--end of authorgroup.element-->]]> <!ENTITY % authorgroup.attlist "INCLUDE"> <![%authorgroup.attlist;[ <!ATTLIST authorgroup %common.attrib; %authorgroup.role.attrib; %local.authorgroup.attrib; > <!--end of authorgroup.attlist-->]]> <!--end of authorgroup.module-->]]> <!-- Author (defined elsewhere in this section)--> <!-- Editor (defined elsewhere in this section)--> <!ENTITY % collab.content.module "INCLUDE"> <![%collab.content.module;[ <!ENTITY % collab.module "INCLUDE"> <![%collab.module;[ <!ENTITY % local.collab.attrib ""> <!ENTITY % collab.role.attrib "%role.attrib;"> <!ENTITY % collab.element "INCLUDE"> <![%collab.element;[ <!--doc:Identifies a collaborator.--> <!ELEMENT collab %ho; (collabname, affiliation*)> <!--end of collab.element-->]]> <!ENTITY % collab.attlist "INCLUDE"> <![%collab.attlist;[ <!ATTLIST collab %common.attrib; %collab.role.attrib; %local.collab.attrib; > <!--end of collab.attlist-->]]> <!--end of collab.module-->]]> <!ENTITY % collabname.module "INCLUDE"> <![%collabname.module;[ <!ENTITY % local.collabname.attrib ""> <!ENTITY % collabname.role.attrib "%role.attrib;"> <!ENTITY % collabname.element "INCLUDE"> <![%collabname.element;[ <!--doc:The name of a collaborator.--> <!ELEMENT collabname %ho; (%docinfo.char.mix;)*> <!--end of collabname.element-->]]> <!ENTITY % collabname.attlist "INCLUDE"> <![%collabname.attlist;[ <!ATTLIST collabname %common.attrib; %collabname.role.attrib; %local.collabname.attrib; > <!--end of collabname.attlist-->]]> <!--end of collabname.module-->]]> <!-- Affiliation (defined elsewhere in this section)--> <!--end of collab.content.module-->]]> <!-- CorpAuthor (defined elsewhere in this section)--> <!-- OtherCredit (defined elsewhere in this section)--> <!--end of authorgroup.content.module-->]]> <!-- AuthorInitials ................... --> <!ENTITY % authorinitials.module "INCLUDE"> <![%authorinitials.module;[ <!ENTITY % local.authorinitials.attrib ""> <!ENTITY % authorinitials.role.attrib "%role.attrib;"> <!ENTITY % authorinitials.element "INCLUDE"> <![%authorinitials.element;[ <!--doc:The initials or other short identifier for an author.--> <!ELEMENT authorinitials %ho; (%docinfo.char.mix;)*> <!--end of authorinitials.element-->]]> <!ENTITY % authorinitials.attlist "INCLUDE"> <![%authorinitials.attlist;[ <!ATTLIST authorinitials %common.attrib; %authorinitials.role.attrib; %local.authorinitials.attrib; > <!--end of authorinitials.attlist-->]]> <!--end of authorinitials.module-->]]> <!-- ConfGroup ........................ --> <!ENTITY % confgroup.content.module "INCLUDE"> <![%confgroup.content.module;[ <!ENTITY % confgroup.module "INCLUDE"> <![%confgroup.module;[ <!ENTITY % local.confgroup.attrib ""> <!ENTITY % confgroup.role.attrib "%role.attrib;"> <!ENTITY % confgroup.element "INCLUDE"> <![%confgroup.element;[ <!--doc:A wrapper for document meta-information about a conference.--> <!ELEMENT confgroup %ho; ((confdates|conftitle|confnum|address|confsponsor)*)> <!--end of confgroup.element-->]]> <!ENTITY % confgroup.attlist "INCLUDE"> <![%confgroup.attlist;[ <!ATTLIST confgroup %common.attrib; %confgroup.role.attrib; %local.confgroup.attrib; > <!--end of confgroup.attlist-->]]> <!--end of confgroup.module-->]]> <!ENTITY % confdates.module "INCLUDE"> <![%confdates.module;[ <!ENTITY % local.confdates.attrib ""> <!ENTITY % confdates.role.attrib "%role.attrib;"> <!ENTITY % confdates.element "INCLUDE"> <![%confdates.element;[ <!--doc:The dates of a conference for which a document was written.--> <!ELEMENT confdates %ho; (%docinfo.char.mix;)*> <!--end of confdates.element-->]]> <!ENTITY % confdates.attlist "INCLUDE"> <![%confdates.attlist;[ <!ATTLIST confdates %common.attrib; %confdates.role.attrib; %local.confdates.attrib; > <!--end of confdates.attlist-->]]> <!--end of confdates.module-->]]> <!ENTITY % conftitle.module "INCLUDE"> <![%conftitle.module;[ <!ENTITY % local.conftitle.attrib ""> <!ENTITY % conftitle.role.attrib "%role.attrib;"> <!ENTITY % conftitle.element "INCLUDE"> <![%conftitle.element;[ <!--doc:The title of a conference for which a document was written.--> <!ELEMENT conftitle %ho; (%docinfo.char.mix;)*> <!--end of conftitle.element-->]]> <!ENTITY % conftitle.attlist "INCLUDE"> <![%conftitle.attlist;[ <!ATTLIST conftitle %common.attrib; %conftitle.role.attrib; %local.conftitle.attrib; > <!--end of conftitle.attlist-->]]> <!--end of conftitle.module-->]]> <!ENTITY % confnum.module "INCLUDE"> <![%confnum.module;[ <!ENTITY % local.confnum.attrib ""> <!ENTITY % confnum.role.attrib "%role.attrib;"> <!ENTITY % confnum.element "INCLUDE"> <![%confnum.element;[ <!--doc:An identifier, frequently numerical, associated with a conference for which a document was written.--> <!ELEMENT confnum %ho; (%docinfo.char.mix;)*> <!--end of confnum.element-->]]> <!ENTITY % confnum.attlist "INCLUDE"> <![%confnum.attlist;[ <!ATTLIST confnum %common.attrib; %confnum.role.attrib; %local.confnum.attrib; > <!--end of confnum.attlist-->]]> <!--end of confnum.module-->]]> <!-- Address (defined elsewhere in this section)--> <!ENTITY % confsponsor.module "INCLUDE"> <![%confsponsor.module;[ <!ENTITY % local.confsponsor.attrib ""> <!ENTITY % confsponsor.role.attrib "%role.attrib;"> <!ENTITY % confsponsor.element "INCLUDE"> <![%confsponsor.element;[ <!--doc:The sponsor of a conference for which a document was written.--> <!ELEMENT confsponsor %ho; (%docinfo.char.mix;)*> <!--end of confsponsor.element-->]]> <!ENTITY % confsponsor.attlist "INCLUDE"> <![%confsponsor.attlist;[ <!ATTLIST confsponsor %common.attrib; %confsponsor.role.attrib; %local.confsponsor.attrib; > <!--end of confsponsor.attlist-->]]> <!--end of confsponsor.module-->]]> <!--end of confgroup.content.module-->]]> <!-- ContractNum ...................... --> <!ENTITY % contractnum.module "INCLUDE"> <![%contractnum.module;[ <!ENTITY % local.contractnum.attrib ""> <!ENTITY % contractnum.role.attrib "%role.attrib;"> <!ENTITY % contractnum.element "INCLUDE"> <![%contractnum.element;[ <!--doc:The contract number of a document.--> <!ELEMENT contractnum %ho; (%docinfo.char.mix;)*> <!--end of contractnum.element-->]]> <!ENTITY % contractnum.attlist "INCLUDE"> <![%contractnum.attlist;[ <!ATTLIST contractnum %common.attrib; %contractnum.role.attrib; %local.contractnum.attrib; > <!--end of contractnum.attlist-->]]> <!--end of contractnum.module-->]]> <!-- ContractSponsor .................. --> <!ENTITY % contractsponsor.module "INCLUDE"> <![%contractsponsor.module;[ <!ENTITY % local.contractsponsor.attrib ""> <!ENTITY % contractsponsor.role.attrib "%role.attrib;"> <!ENTITY % contractsponsor.element "INCLUDE"> <![%contractsponsor.element;[ <!--doc:The sponsor of a contract.--> <!ELEMENT contractsponsor %ho; (%docinfo.char.mix;)*> <!--end of contractsponsor.element-->]]> <!ENTITY % contractsponsor.attlist "INCLUDE"> <![%contractsponsor.attlist;[ <!ATTLIST contractsponsor %common.attrib; %contractsponsor.role.attrib; %local.contractsponsor.attrib; > <!--end of contractsponsor.attlist-->]]> <!--end of contractsponsor.module-->]]> <!-- Copyright ........................ --> <!ENTITY % copyright.content.module "INCLUDE"> <![%copyright.content.module;[ <!ENTITY % copyright.module "INCLUDE"> <![%copyright.module;[ <!ENTITY % local.copyright.attrib ""> <!ENTITY % copyright.role.attrib "%role.attrib;"> <!ENTITY % copyright.element "INCLUDE"> <![%copyright.element;[ <!--doc:Copyright information about a document.--> <!ELEMENT copyright %ho; (year+, holder*)> <!--end of copyright.element-->]]> <!ENTITY % copyright.attlist "INCLUDE"> <![%copyright.attlist;[ <!ATTLIST copyright %common.attrib; %copyright.role.attrib; %local.copyright.attrib; > <!--end of copyright.attlist-->]]> <!--end of copyright.module-->]]> <!ENTITY % year.module "INCLUDE"> <![%year.module;[ <!ENTITY % local.year.attrib ""> <!ENTITY % year.role.attrib "%role.attrib;"> <!ENTITY % year.element "INCLUDE"> <![%year.element;[ <!--doc:The year of publication of a document.--> <!ELEMENT year %ho; (%docinfo.char.mix;)*> <!--end of year.element-->]]> <!ENTITY % year.attlist "INCLUDE"> <![%year.attlist;[ <!ATTLIST year %common.attrib; %year.role.attrib; %local.year.attrib; > <!--end of year.attlist-->]]> <!--end of year.module-->]]> <!ENTITY % holder.module "INCLUDE"> <![%holder.module;[ <!ENTITY % local.holder.attrib ""> <!ENTITY % holder.role.attrib "%role.attrib;"> <!ENTITY % holder.element "INCLUDE"> <![%holder.element;[ <!--doc:The name of the individual or organization that holds a copyright.--> <!ELEMENT holder %ho; (%docinfo.char.mix;)*> <!--end of holder.element-->]]> <!ENTITY % holder.attlist "INCLUDE"> <![%holder.attlist;[ <!ATTLIST holder %common.attrib; %holder.role.attrib; %local.holder.attrib; > <!--end of holder.attlist-->]]> <!--end of holder.module-->]]> <!--end of copyright.content.module-->]]> <!-- CorpAuthor ....................... --> <!ENTITY % corpauthor.module "INCLUDE"> <![%corpauthor.module;[ <!ENTITY % local.corpauthor.attrib ""> <!ENTITY % corpauthor.role.attrib "%role.attrib;"> <!ENTITY % corpauthor.element "INCLUDE"> <![%corpauthor.element;[ <!--doc:A corporate author, as opposed to an individual.--> <!ELEMENT corpauthor %ho; (%docinfo.char.mix;)*> <!--end of corpauthor.element-->]]> <!ENTITY % corpauthor.attlist "INCLUDE"> <![%corpauthor.attlist;[ <!ATTLIST corpauthor %common.attrib; %corpauthor.role.attrib; %local.corpauthor.attrib; > <!--end of corpauthor.attlist-->]]> <!--end of corpauthor.module-->]]> <!-- CorpCredit ...................... --> <!ENTITY % corpcredit.module "INCLUDE"> <![%corpcredit.module;[ <!ENTITY % local.corpcredit.attrib ""> <!ENTITY % corpcredit.role.attrib "%role.attrib;"> <!ENTITY % corpcredit.element "INCLUDE"> <![%corpcredit.element;[ <!--doc:A corporation or organization credited in a document.--> <!ELEMENT corpcredit %ho; (%docinfo.char.mix;)*> <!--end of corpcredit.element-->]]> <!ENTITY % corpcredit.attlist "INCLUDE"> <![%corpcredit.attlist;[ <!ATTLIST corpcredit class (graphicdesigner |productioneditor |copyeditor |technicaleditor |translator |other) #IMPLIED %common.attrib; %corpcredit.role.attrib; %local.corpcredit.attrib; > <!--end of corpcredit.attlist-->]]> <!--end of corpcredit.module-->]]> <!-- CorpName ......................... --> <!ENTITY % corpname.module "INCLUDE"> <![%corpname.module;[ <!ENTITY % local.corpname.attrib ""> <!ENTITY % corpname.element "INCLUDE"> <![%corpname.element;[ <!--doc:The name of a corporation.--> <!ELEMENT corpname %ho; (%docinfo.char.mix;)*> <!--end of corpname.element-->]]> <!ENTITY % corpname.role.attrib "%role.attrib;"> <!ENTITY % corpname.attlist "INCLUDE"> <![%corpname.attlist;[ <!ATTLIST corpname %common.attrib; %corpname.role.attrib; %local.corpname.attrib; > <!--end of corpname.attlist-->]]> <!--end of corpname.module-->]]> <!-- Date ............................. --> <!ENTITY % date.module "INCLUDE"> <![%date.module;[ <!ENTITY % local.date.attrib ""> <!ENTITY % date.role.attrib "%role.attrib;"> <!ENTITY % date.element "INCLUDE"> <![%date.element;[ <!--doc:The date of publication or revision of a document.--> <!ELEMENT date %ho; (%docinfo.char.mix;)*> <!--end of date.element-->]]> <!ENTITY % date.attlist "INCLUDE"> <![%date.attlist;[ <!ATTLIST date %common.attrib; %date.role.attrib; %local.date.attrib; > <!--end of date.attlist-->]]> <!--end of date.module-->]]> <!-- Edition .......................... --> <!ENTITY % edition.module "INCLUDE"> <![%edition.module;[ <!ENTITY % local.edition.attrib ""> <!ENTITY % edition.role.attrib "%role.attrib;"> <!ENTITY % edition.element "INCLUDE"> <![%edition.element;[ <!--doc:The name or number of an edition of a document.--> <!ELEMENT edition %ho; (%docinfo.char.mix;)*> <!--end of edition.element-->]]> <!ENTITY % edition.attlist "INCLUDE"> <![%edition.attlist;[ <!ATTLIST edition %common.attrib; %edition.role.attrib; %local.edition.attrib; > <!--end of edition.attlist-->]]> <!--end of edition.module-->]]> <!-- Editor ........................... --> <!ENTITY % editor.module "INCLUDE"> <![%editor.module;[ <!ENTITY % local.editor.attrib ""> <!ENTITY % editor.role.attrib "%role.attrib;"> <!ENTITY % editor.element "INCLUDE"> <![%editor.element;[ <!--doc:The name of the editor of a document.--> <!ELEMENT editor %ho; ((personname|(%person.ident.mix;)+),(personblurb|email|address)*)> <!--end of editor.element-->]]> <!ENTITY % editor.attlist "INCLUDE"> <![%editor.attlist;[ <!ATTLIST editor %common.attrib; %editor.role.attrib; %local.editor.attrib; > <!--end of editor.attlist-->]]> <!--(see "Personal identity elements" for %person.ident.mix;)--> <!--end of editor.module-->]]> <!-- ISBN ............................. --> <!ENTITY % isbn.module "INCLUDE"> <![%isbn.module;[ <!ENTITY % local.isbn.attrib ""> <!ENTITY % isbn.role.attrib "%role.attrib;"> <!ENTITY % isbn.element "INCLUDE"> <![%isbn.element;[ <!--doc:The International Standard Book Number of a document.--> <!ELEMENT isbn %ho; (%docinfo.char.mix;)*> <!--end of isbn.element-->]]> <!ENTITY % isbn.attlist "INCLUDE"> <![%isbn.attlist;[ <!ATTLIST isbn %common.attrib; %isbn.role.attrib; %local.isbn.attrib; > <!--end of isbn.attlist-->]]> <!--end of isbn.module-->]]> <!-- ISSN ............................. --> <!ENTITY % issn.module "INCLUDE"> <![%issn.module;[ <!ENTITY % local.issn.attrib ""> <!ENTITY % issn.role.attrib "%role.attrib;"> <!ENTITY % issn.element "INCLUDE"> <![%issn.element;[ <!--doc:The International Standard Serial Number of a periodical.--> <!ELEMENT issn %ho; (%docinfo.char.mix;)*> <!--end of issn.element-->]]> <!ENTITY % issn.attlist "INCLUDE"> <![%issn.attlist;[ <!ATTLIST issn %common.attrib; %issn.role.attrib; %local.issn.attrib; > <!--end of issn.attlist-->]]> <!--end of issn.module-->]]> <!-- BiblioId ................. --> <!ENTITY % biblio.class.attrib "class (uri |doi |isbn |isrn |issn |libraryofcongress |pubnumber |other) #IMPLIED otherclass CDATA #IMPLIED" > <!ENTITY % biblioid.module "INCLUDE"> <![%biblioid.module;[ <!ENTITY % local.biblioid.attrib ""> <!ENTITY % biblioid.role.attrib "%role.attrib;"> <!ENTITY % biblioid.element "INCLUDE"> <![%biblioid.element;[ <!--doc:An identifier for a document.--> <!ELEMENT biblioid %ho; (%docinfo.char.mix;)*> <!--end of biblioid.element-->]]> <!ENTITY % biblioid.attlist "INCLUDE"> <![%biblioid.attlist;[ <!ATTLIST biblioid %biblio.class.attrib; %common.attrib; %biblioid.role.attrib; %local.biblioid.attrib; > <!--end of biblioid.attlist-->]]> <!--end of biblioid.module-->]]> <!-- CiteBiblioId ................. --> <!ENTITY % citebiblioid.module "INCLUDE"> <![%citebiblioid.module;[ <!ENTITY % local.citebiblioid.attrib ""> <!ENTITY % citebiblioid.role.attrib "%role.attrib;"> <!ENTITY % citebiblioid.element "INCLUDE"> <![%citebiblioid.element;[ <!--doc:A citation of a bibliographic identifier.--> <!ELEMENT citebiblioid %ho; (%docinfo.char.mix;)*> <!--end of citebiblioid.element-->]]> <!ENTITY % citebiblioid.attlist "INCLUDE"> <![%citebiblioid.attlist;[ <!ATTLIST citebiblioid %biblio.class.attrib; %common.attrib; %citebiblioid.role.attrib; %local.citebiblioid.attrib; > <!--end of citebiblioid.attlist-->]]> <!--end of citebiblioid.module-->]]> <!-- BiblioSource ................. --> <!ENTITY % bibliosource.module "INCLUDE"> <![%bibliosource.module;[ <!ENTITY % local.bibliosource.attrib ""> <!ENTITY % bibliosource.role.attrib "%role.attrib;"> <!ENTITY % bibliosource.element "INCLUDE"> <![%bibliosource.element;[ <!--doc:The source of a document.--> <!ELEMENT bibliosource %ho; (%docinfo.char.mix;)*> <!--end of bibliosource.element-->]]> <!ENTITY % bibliosource.attlist "INCLUDE"> <![%bibliosource.attlist;[ <!ATTLIST bibliosource %biblio.class.attrib; %common.attrib; %bibliosource.role.attrib; %local.bibliosource.attrib; > <!--end of bibliosource.attlist-->]]> <!--end of bibliosource.module-->]]> <!-- BiblioRelation ................. --> <!ENTITY % bibliorelation.module "INCLUDE"> <![%bibliorelation.module;[ <!ENTITY % local.bibliorelation.attrib ""> <!ENTITY % local.bibliorelation.types ""> <!ENTITY % bibliorelation.type.attrib "type (isversionof |hasversion |isreplacedby |replaces |isrequiredby |requires |ispartof |haspart |isreferencedby |references |isformatof |hasformat |othertype %local.bibliorelation.types;) #IMPLIED othertype CDATA #IMPLIED "> <!ENTITY % bibliorelation.role.attrib "%role.attrib;"> <!ENTITY % bibliorelation.element "INCLUDE"> <![%bibliorelation.element;[ <!--doc:The relationship of a document to another.--> <!ELEMENT bibliorelation %ho; (%docinfo.char.mix;)*> <!--end of bibliorelation.element-->]]> <!ENTITY % bibliorelation.attlist "INCLUDE"> <![%bibliorelation.attlist;[ <!ATTLIST bibliorelation %biblio.class.attrib; %bibliorelation.type.attrib; %common.attrib; %bibliorelation.role.attrib; %local.bibliorelation.attrib; > <!--end of bibliorelation.attlist-->]]> <!--end of bibliorelation.module-->]]> <!-- BiblioCoverage ................. --> <!ENTITY % bibliocoverage.module "INCLUDE"> <![%bibliocoverage.module;[ <!ENTITY % local.bibliocoverage.attrib ""> <!ENTITY % bibliocoverage.role.attrib "%role.attrib;"> <!ENTITY % bibliocoverage.element "INCLUDE"> <![%bibliocoverage.element;[ <!--doc:The spatial or temporal coverage of a document.--> <!ELEMENT bibliocoverage %ho; (%docinfo.char.mix;)*> <!--end of bibliocoverage.element-->]]> <!ENTITY % bibliocoverage.attlist "INCLUDE"> <![%bibliocoverage.attlist;[ <!ATTLIST bibliocoverage spatial (dcmipoint|iso3166|dcmibox|tgn|otherspatial) #IMPLIED otherspatial CDATA #IMPLIED temporal (dcmiperiod|w3c-dtf|othertemporal) #IMPLIED othertemporal CDATA #IMPLIED %common.attrib; %bibliocoverage.role.attrib; %local.bibliocoverage.attrib; > <!--end of bibliocoverage.attlist-->]]> <!--end of bibliocoverage.module-->]]> <!-- InvPartNumber .................... --> <!ENTITY % invpartnumber.module "INCLUDE"> <![%invpartnumber.module;[ <!ENTITY % local.invpartnumber.attrib ""> <!ENTITY % invpartnumber.role.attrib "%role.attrib;"> <!ENTITY % invpartnumber.element "INCLUDE"> <![%invpartnumber.element;[ <!--doc:An inventory part number.--> <!ELEMENT invpartnumber %ho; (%docinfo.char.mix;)*> <!--end of invpartnumber.element-->]]> <!ENTITY % invpartnumber.attlist "INCLUDE"> <![%invpartnumber.attlist;[ <!ATTLIST invpartnumber %common.attrib; %invpartnumber.role.attrib; %local.invpartnumber.attrib; > <!--end of invpartnumber.attlist-->]]> <!--end of invpartnumber.module-->]]> <!-- IssueNum ......................... --> <!ENTITY % issuenum.module "INCLUDE"> <![%issuenum.module;[ <!ENTITY % local.issuenum.attrib ""> <!ENTITY % issuenum.role.attrib "%role.attrib;"> <!ENTITY % issuenum.element "INCLUDE"> <![%issuenum.element;[ <!--doc:The number of an issue of a journal.--> <!ELEMENT issuenum %ho; (%docinfo.char.mix;)*> <!--end of issuenum.element-->]]> <!ENTITY % issuenum.attlist "INCLUDE"> <![%issuenum.attlist;[ <!ATTLIST issuenum %common.attrib; %issuenum.role.attrib; %local.issuenum.attrib; > <!--end of issuenum.attlist-->]]> <!--end of issuenum.module-->]]> <!-- LegalNotice ...................... --> <!ENTITY % legalnotice.module "INCLUDE"> <![%legalnotice.module;[ <!ENTITY % local.legalnotice.attrib ""> <!ENTITY % legalnotice.role.attrib "%role.attrib;"> <!ENTITY % legalnotice.element "INCLUDE"> <![%legalnotice.element;[ <!--doc:A statement of legal obligations or requirements.--> <!ELEMENT legalnotice %ho; (blockinfo?, title?, (%legalnotice.mix;)+) %formal.exclusion;> <!--end of legalnotice.element-->]]> <!ENTITY % legalnotice.attlist "INCLUDE"> <![%legalnotice.attlist;[ <!ATTLIST legalnotice %common.attrib; %legalnotice.role.attrib; %local.legalnotice.attrib; > <!--end of legalnotice.attlist-->]]> <!--end of legalnotice.module-->]]> <!-- ModeSpec ......................... --> <!ENTITY % modespec.module "INCLUDE"> <![%modespec.module;[ <!ENTITY % local.modespec.attrib ""> <!ENTITY % modespec.role.attrib "%role.attrib;"> <!ENTITY % modespec.element "INCLUDE"> <![%modespec.element;[ <!--doc:Application-specific information necessary for the completion of an OLink.--> <!ELEMENT modespec %ho; (%docinfo.char.mix;)* %ubiq.exclusion;> <!--end of modespec.element-->]]> <!-- Application: Type of action required for completion of the links to which the ModeSpec is relevant (e.g., retrieval query) --> <!ENTITY % modespec.attlist "INCLUDE"> <![%modespec.attlist;[ <!ATTLIST modespec application NOTATION (%notation.class;) #IMPLIED %common.attrib; %modespec.role.attrib; %local.modespec.attrib; > <!--end of modespec.attlist-->]]> <!--end of modespec.module-->]]> <!-- OrgName .......................... --> <!ENTITY % orgname.module "INCLUDE"> <![%orgname.module;[ <!ENTITY % local.orgname.attrib ""> <!ENTITY % orgname.role.attrib "%role.attrib;"> <!ENTITY % orgname.element "INCLUDE"> <![%orgname.element;[ <!--doc:The name of an organization other than a corporation.--> <!ELEMENT orgname %ho; (%docinfo.char.mix;)*> <!--end of orgname.element-->]]> <!ENTITY % orgname.attlist "INCLUDE"> <![%orgname.attlist;[ <!ATTLIST orgname %common.attrib; class (corporation|nonprofit|consortium|informal|other) #IMPLIED otherclass CDATA #IMPLIED %orgname.role.attrib; %local.orgname.attrib; > <!--end of orgname.attlist-->]]> <!--end of orgname.module-->]]> <!-- OtherCredit ...................... --> <!ENTITY % othercredit.module "INCLUDE"> <![%othercredit.module;[ <!ENTITY % local.othercredit.attrib ""> <!ENTITY % othercredit.role.attrib "%role.attrib;"> <!ENTITY % othercredit.element "INCLUDE"> <![%othercredit.element;[ <!--doc:A person or entity, other than an author or editor, credited in a document.--> <!ELEMENT othercredit %ho; ((personname|(%person.ident.mix;)+), (personblurb|email|address)*)> <!--end of othercredit.element-->]]> <!ENTITY % othercredit.attlist "INCLUDE"> <![%othercredit.attlist;[ <!ATTLIST othercredit class (graphicdesigner |productioneditor |copyeditor |technicaleditor |translator |other) #IMPLIED %common.attrib; %othercredit.role.attrib; %local.othercredit.attrib; > <!--end of othercredit.attlist-->]]> <!--(see "Personal identity elements" for %person.ident.mix;)--> <!--end of othercredit.module-->]]> <!-- PageNums ......................... --> <!ENTITY % pagenums.module "INCLUDE"> <![%pagenums.module;[ <!ENTITY % local.pagenums.attrib ""> <!ENTITY % pagenums.role.attrib "%role.attrib;"> <!ENTITY % pagenums.element "INCLUDE"> <![%pagenums.element;[ <!--doc:The numbers of the pages in a book, for use in a bibliographic entry.--> <!ELEMENT pagenums %ho; (%docinfo.char.mix;)*> <!--end of pagenums.element-->]]> <!ENTITY % pagenums.attlist "INCLUDE"> <![%pagenums.attlist;[ <!ATTLIST pagenums %common.attrib; %pagenums.role.attrib; %local.pagenums.attrib; > <!--end of pagenums.attlist-->]]> <!--end of pagenums.module-->]]> <!-- Personal identity elements ....... --> <!-- These elements are used only within Author, Editor, and OtherCredit. --> <!ENTITY % person.ident.module "INCLUDE"> <![%person.ident.module;[ <!ENTITY % contrib.module "INCLUDE"> <![%contrib.module;[ <!ENTITY % local.contrib.attrib ""> <!ENTITY % contrib.role.attrib "%role.attrib;"> <!ENTITY % contrib.element "INCLUDE"> <![%contrib.element;[ <!--doc:A summary of the contributions made to a document by a credited source.--> <!ELEMENT contrib %ho; (%docinfo.char.mix;)*> <!--end of contrib.element-->]]> <!ENTITY % contrib.attlist "INCLUDE"> <![%contrib.attlist;[ <!ATTLIST contrib %common.attrib; %contrib.role.attrib; %local.contrib.attrib; > <!--end of contrib.attlist-->]]> <!--end of contrib.module-->]]> <!ENTITY % firstname.module "INCLUDE"> <![%firstname.module;[ <!ENTITY % local.firstname.attrib ""> <!ENTITY % firstname.role.attrib "%role.attrib;"> <!ENTITY % firstname.element "INCLUDE"> <![%firstname.element;[ <!--doc:The first name of a person.--> <!ELEMENT firstname %ho; (%docinfo.char.mix;)*> <!--end of firstname.element-->]]> <!ENTITY % firstname.attlist "INCLUDE"> <![%firstname.attlist;[ <!ATTLIST firstname %common.attrib; %firstname.role.attrib; %local.firstname.attrib; > <!--end of firstname.attlist-->]]> <!--end of firstname.module-->]]> <!ENTITY % honorific.module "INCLUDE"> <![%honorific.module;[ <!ENTITY % local.honorific.attrib ""> <!ENTITY % honorific.role.attrib "%role.attrib;"> <!ENTITY % honorific.element "INCLUDE"> <![%honorific.element;[ <!--doc:The title of a person.--> <!ELEMENT honorific %ho; (%docinfo.char.mix;)*> <!--end of honorific.element-->]]> <!ENTITY % honorific.attlist "INCLUDE"> <![%honorific.attlist;[ <!ATTLIST honorific %common.attrib; %honorific.role.attrib; %local.honorific.attrib; > <!--end of honorific.attlist-->]]> <!--end of honorific.module-->]]> <!ENTITY % lineage.module "INCLUDE"> <![%lineage.module;[ <!ENTITY % local.lineage.attrib ""> <!ENTITY % lineage.role.attrib "%role.attrib;"> <!ENTITY % lineage.element "INCLUDE"> <![%lineage.element;[ <!--doc:The portion of a person's name indicating a relationship to ancestors.--> <!ELEMENT lineage %ho; (%docinfo.char.mix;)*> <!--end of lineage.element-->]]> <!ENTITY % lineage.attlist "INCLUDE"> <![%lineage.attlist;[ <!ATTLIST lineage %common.attrib; %lineage.role.attrib; %local.lineage.attrib; > <!--end of lineage.attlist-->]]> <!--end of lineage.module-->]]> <!ENTITY % othername.module "INCLUDE"> <![%othername.module;[ <!ENTITY % local.othername.attrib ""> <!ENTITY % othername.role.attrib "%role.attrib;"> <!ENTITY % othername.element "INCLUDE"> <![%othername.element;[ <!--doc:A component of a persons name that is not a first name, surname, or lineage.--> <!ELEMENT othername %ho; (%docinfo.char.mix;)*> <!--end of othername.element-->]]> <!ENTITY % othername.attlist "INCLUDE"> <![%othername.attlist;[ <!ATTLIST othername %common.attrib; %othername.role.attrib; %local.othername.attrib; > <!--end of othername.attlist-->]]> <!--end of othername.module-->]]> <!ENTITY % surname.module "INCLUDE"> <![%surname.module;[ <!ENTITY % local.surname.attrib ""> <!ENTITY % surname.role.attrib "%role.attrib;"> <!ENTITY % surname.element "INCLUDE"> <![%surname.element;[ <!--doc:A family name; in western cultures the last name.--> <!ELEMENT surname %ho; (%docinfo.char.mix;)*> <!--end of surname.element-->]]> <!ENTITY % surname.attlist "INCLUDE"> <![%surname.attlist;[ <!ATTLIST surname %common.attrib; %surname.role.attrib; %local.surname.attrib; > <!--end of surname.attlist-->]]> <!--end of surname.module-->]]> <!--end of person.ident.module-->]]> <!-- PrintHistory ..................... --> <!ENTITY % printhistory.module "INCLUDE"> <![%printhistory.module;[ <!ENTITY % local.printhistory.attrib ""> <!ENTITY % printhistory.role.attrib "%role.attrib;"> <!ENTITY % printhistory.element "INCLUDE"> <![%printhistory.element;[ <!--doc:The printing history of a document.--> <!ELEMENT printhistory %ho; ((%para.class;)+)> <!--end of printhistory.element-->]]> <!ENTITY % printhistory.attlist "INCLUDE"> <![%printhistory.attlist;[ <!ATTLIST printhistory %common.attrib; %printhistory.role.attrib; %local.printhistory.attrib; > <!--end of printhistory.attlist-->]]> <!--end of printhistory.module-->]]> <!-- ProductName ...................... --> <!ENTITY % productname.module "INCLUDE"> <![%productname.module;[ <!ENTITY % local.productname.attrib ""> <!ENTITY % productname.role.attrib "%role.attrib;"> <!ENTITY % productname.element "INCLUDE"> <![%productname.element;[ <!--doc:The formal name of a product.--> <!ELEMENT productname %ho; (%para.char.mix;)*> <!--end of productname.element-->]]> <!-- Class: More precisely identifies the item the element names --> <!ENTITY % productname.attlist "INCLUDE"> <![%productname.attlist;[ <!ATTLIST productname class (service |trade |registered |copyright) 'trade' %common.attrib; %productname.role.attrib; %local.productname.attrib; > <!--end of productname.attlist-->]]> <!--end of productname.module-->]]> <!-- ProductNumber .................... --> <!ENTITY % productnumber.module "INCLUDE"> <![%productnumber.module;[ <!ENTITY % local.productnumber.attrib ""> <!ENTITY % productnumber.role.attrib "%role.attrib;"> <!ENTITY % productnumber.element "INCLUDE"> <![%productnumber.element;[ <!--doc:A number assigned to a product.--> <!ELEMENT productnumber %ho; (%docinfo.char.mix;)*> <!--end of productnumber.element-->]]> <!ENTITY % productnumber.attlist "INCLUDE"> <![%productnumber.attlist;[ <!ATTLIST productnumber %common.attrib; %productnumber.role.attrib; %local.productnumber.attrib; > <!--end of productnumber.attlist-->]]> <!--end of productnumber.module-->]]> <!-- PubDate .......................... --> <!ENTITY % pubdate.module "INCLUDE"> <![%pubdate.module;[ <!ENTITY % local.pubdate.attrib ""> <!ENTITY % pubdate.role.attrib "%role.attrib;"> <!ENTITY % pubdate.element "INCLUDE"> <![%pubdate.element;[ <!--doc:The date of publication of a document.--> <!ELEMENT pubdate %ho; (%docinfo.char.mix;)*> <!--end of pubdate.element-->]]> <!ENTITY % pubdate.attlist "INCLUDE"> <![%pubdate.attlist;[ <!ATTLIST pubdate %common.attrib; %pubdate.role.attrib; %local.pubdate.attrib; > <!--end of pubdate.attlist-->]]> <!--end of pubdate.module-->]]> <!-- Publisher ........................ --> <!ENTITY % publisher.content.module "INCLUDE"> <![%publisher.content.module;[ <!ENTITY % publisher.module "INCLUDE"> <![%publisher.module;[ <!ENTITY % local.publisher.attrib ""> <!ENTITY % publisher.role.attrib "%role.attrib;"> <!ENTITY % publisher.element "INCLUDE"> <![%publisher.element;[ <!--doc:The publisher of a document.--> <!ELEMENT publisher %ho; (publishername, address*)> <!--end of publisher.element-->]]> <!ENTITY % publisher.attlist "INCLUDE"> <![%publisher.attlist;[ <!ATTLIST publisher %common.attrib; %publisher.role.attrib; %local.publisher.attrib; > <!--end of publisher.attlist-->]]> <!--end of publisher.module-->]]> <!ENTITY % publishername.module "INCLUDE"> <![%publishername.module;[ <!ENTITY % local.publishername.attrib ""> <!ENTITY % publishername.role.attrib "%role.attrib;"> <!ENTITY % publishername.element "INCLUDE"> <![%publishername.element;[ <!--doc:The name of the publisher of a document.--> <!ELEMENT publishername %ho; (%docinfo.char.mix;)*> <!--end of publishername.element-->]]> <!ENTITY % publishername.attlist "INCLUDE"> <![%publishername.attlist;[ <!ATTLIST publishername %common.attrib; %publishername.role.attrib; %local.publishername.attrib; > <!--end of publishername.attlist-->]]> <!--end of publishername.module-->]]> <!-- Address (defined elsewhere in this section)--> <!--end of publisher.content.module-->]]> <!-- PubsNumber ....................... --> <!ENTITY % pubsnumber.module "INCLUDE"> <![%pubsnumber.module;[ <!ENTITY % local.pubsnumber.attrib ""> <!ENTITY % pubsnumber.role.attrib "%role.attrib;"> <!ENTITY % pubsnumber.element "INCLUDE"> <![%pubsnumber.element;[ <!--doc:A number assigned to a publication other than an ISBN or ISSN or inventory part number.--> <!ELEMENT pubsnumber %ho; (%docinfo.char.mix;)*> <!--end of pubsnumber.element-->]]> <!ENTITY % pubsnumber.attlist "INCLUDE"> <![%pubsnumber.attlist;[ <!ATTLIST pubsnumber %common.attrib; %pubsnumber.role.attrib; %local.pubsnumber.attrib; > <!--end of pubsnumber.attlist-->]]> <!--end of pubsnumber.module-->]]> <!-- ReleaseInfo ...................... --> <!ENTITY % releaseinfo.module "INCLUDE"> <![%releaseinfo.module;[ <!ENTITY % local.releaseinfo.attrib ""> <!ENTITY % releaseinfo.role.attrib "%role.attrib;"> <!ENTITY % releaseinfo.element "INCLUDE"> <![%releaseinfo.element;[ <!--doc:Information about a particular release of a document.--> <!ELEMENT releaseinfo %ho; (%docinfo.char.mix;)*> <!--end of releaseinfo.element-->]]> <!ENTITY % releaseinfo.attlist "INCLUDE"> <![%releaseinfo.attlist;[ <!ATTLIST releaseinfo %common.attrib; %releaseinfo.role.attrib; %local.releaseinfo.attrib; > <!--end of releaseinfo.attlist-->]]> <!--end of releaseinfo.module-->]]> <!-- RevHistory ....................... --> <!ENTITY % revhistory.content.module "INCLUDE"> <![%revhistory.content.module;[ <!ENTITY % revhistory.module "INCLUDE"> <![%revhistory.module;[ <!ENTITY % local.revhistory.attrib ""> <!ENTITY % revhistory.role.attrib "%role.attrib;"> <!ENTITY % revhistory.element "INCLUDE"> <![%revhistory.element;[ <!--doc:A history of the revisions to a document.--> <!ELEMENT revhistory %ho; (revision+)> <!--end of revhistory.element-->]]> <!ENTITY % revhistory.attlist "INCLUDE"> <![%revhistory.attlist;[ <!ATTLIST revhistory %common.attrib; %revhistory.role.attrib; %local.revhistory.attrib; > <!--end of revhistory.attlist-->]]> <!--end of revhistory.module-->]]> <!ENTITY % revision.module "INCLUDE"> <![%revision.module;[ <!ENTITY % local.revision.attrib ""> <!ENTITY % revision.role.attrib "%role.attrib;"> <!ENTITY % revision.element "INCLUDE"> <![%revision.element;[ <!--doc:An entry describing a single revision in the history of the revisions to a document.--> <!ELEMENT revision %ho; (revnumber?, date, (author|authorinitials)*, (revremark|revdescription)?)> <!--end of revision.element-->]]> <!ENTITY % revision.attlist "INCLUDE"> <![%revision.attlist;[ <!ATTLIST revision %common.attrib; %revision.role.attrib; %local.revision.attrib; > <!--end of revision.attlist-->]]> <!--end of revision.module-->]]> <!ENTITY % revnumber.module "INCLUDE"> <![%revnumber.module;[ <!ENTITY % local.revnumber.attrib ""> <!ENTITY % revnumber.role.attrib "%role.attrib;"> <!ENTITY % revnumber.element "INCLUDE"> <![%revnumber.element;[ <!--doc:A document revision number.--> <!ELEMENT revnumber %ho; (%docinfo.char.mix;)*> <!--end of revnumber.element-->]]> <!ENTITY % revnumber.attlist "INCLUDE"> <![%revnumber.attlist;[ <!ATTLIST revnumber %common.attrib; %revnumber.role.attrib; %local.revnumber.attrib; > <!--end of revnumber.attlist-->]]> <!--end of revnumber.module-->]]> <!-- Date (defined elsewhere in this section)--> <!-- AuthorInitials (defined elsewhere in this section)--> <!ENTITY % revremark.module "INCLUDE"> <![%revremark.module;[ <!ENTITY % local.revremark.attrib ""> <!ENTITY % revremark.role.attrib "%role.attrib;"> <!ENTITY % revremark.element "INCLUDE"> <![%revremark.element;[ <!--doc:A description of a revision to a document.--> <!ELEMENT revremark %ho; (%docinfo.char.mix;)*> <!--end of revremark.element-->]]> <!ENTITY % revremark.attlist "INCLUDE"> <![%revremark.attlist;[ <!ATTLIST revremark %common.attrib; %revremark.role.attrib; %local.revremark.attrib; > <!--end of revremark.attlist-->]]> <!--end of revremark.module-->]]> <!ENTITY % revdescription.module "INCLUDE"> <![ %revdescription.module; [ <!ENTITY % local.revdescription.attrib ""> <!ENTITY % revdescription.role.attrib "%role.attrib;"> <!ENTITY % revdescription.element "INCLUDE"> <![ %revdescription.element; [ <!--doc:A extended description of a revision to a document.--> <!ELEMENT revdescription %ho; ((%revdescription.mix;)+)> <!--end of revdescription.element-->]]> <!ENTITY % revdescription.attlist "INCLUDE"> <![ %revdescription.attlist; [ <!ATTLIST revdescription %common.attrib; %revdescription.role.attrib; %local.revdescription.attrib; > <!--end of revdescription.attlist-->]]> <!--end of revdescription.module-->]]> <!--end of revhistory.content.module-->]]> <!-- SeriesVolNums .................... --> <!ENTITY % seriesvolnums.module "INCLUDE"> <![%seriesvolnums.module;[ <!ENTITY % local.seriesvolnums.attrib ""> <!ENTITY % seriesvolnums.role.attrib "%role.attrib;"> <!ENTITY % seriesvolnums.element "INCLUDE"> <![%seriesvolnums.element;[ <!--doc:Numbers of the volumes in a series of books.--> <!ELEMENT seriesvolnums %ho; (%docinfo.char.mix;)*> <!--end of seriesvolnums.element-->]]> <!ENTITY % seriesvolnums.attlist "INCLUDE"> <![%seriesvolnums.attlist;[ <!ATTLIST seriesvolnums %common.attrib; %seriesvolnums.role.attrib; %local.seriesvolnums.attrib; > <!--end of seriesvolnums.attlist-->]]> <!--end of seriesvolnums.module-->]]> <!-- VolumeNum ........................ --> <!ENTITY % volumenum.module "INCLUDE"> <![%volumenum.module;[ <!ENTITY % local.volumenum.attrib ""> <!ENTITY % volumenum.role.attrib "%role.attrib;"> <!ENTITY % volumenum.element "INCLUDE"> <![%volumenum.element;[ <!--doc:The volume number of a document in a set (as of books in a set or articles in a journal).--> <!ELEMENT volumenum %ho; (%docinfo.char.mix;)*> <!--end of volumenum.element-->]]> <!ENTITY % volumenum.attlist "INCLUDE"> <![%volumenum.attlist;[ <!ATTLIST volumenum %common.attrib; %volumenum.role.attrib; %local.volumenum.attrib; > <!--end of volumenum.attlist-->]]> <!--end of volumenum.module-->]]> <!-- .................................. --> <!--end of docinfo.content.module-->]]> <!-- ...................................................................... --> <!-- Inline, link, and ubiquitous elements ................................ --> <!-- Technical and computer terms ......................................... --> <!ENTITY % accel.module "INCLUDE"> <![%accel.module;[ <!ENTITY % local.accel.attrib ""> <!ENTITY % accel.role.attrib "%role.attrib;"> <!ENTITY % accel.element "INCLUDE"> <![%accel.element;[ <!--doc:A graphical user interface (GUI) keyboard shortcut.--> <!ELEMENT accel %ho; (%smallcptr.char.mix;)*> <!--end of accel.element-->]]> <!ENTITY % accel.attlist "INCLUDE"> <![%accel.attlist;[ <!ATTLIST accel %common.attrib; %accel.role.attrib; %local.accel.attrib; > <!--end of accel.attlist-->]]> <!--end of accel.module-->]]> <!ENTITY % action.module "INCLUDE"> <![%action.module;[ <!ENTITY % local.action.attrib ""> <!ENTITY % action.role.attrib "%role.attrib;"> <!ENTITY % action.element "INCLUDE"> <![%action.element;[ <!--doc:A response to a user event.--> <!ELEMENT action %ho; (%cptr.char.mix;)*> <!--end of action.element-->]]> <!ENTITY % action.attlist "INCLUDE"> <![%action.attlist;[ <!ATTLIST action %moreinfo.attrib; %common.attrib; %action.role.attrib; %local.action.attrib; > <!--end of action.attlist-->]]> <!--end of action.module-->]]> <!ENTITY % application.module "INCLUDE"> <![%application.module;[ <!ENTITY % local.application.attrib ""> <!ENTITY % application.role.attrib "%role.attrib;"> <!ENTITY % application.element "INCLUDE"> <![%application.element;[ <!--doc:The name of a software program.--> <!ELEMENT application %ho; (%para.char.mix;)*> <!--end of application.element-->]]> <!ENTITY % application.attlist "INCLUDE"> <![%application.attlist;[ <!ATTLIST application class (hardware |software) #IMPLIED %moreinfo.attrib; %common.attrib; %application.role.attrib; %local.application.attrib; > <!--end of application.attlist-->]]> <!--end of application.module-->]]> <!ENTITY % classname.module "INCLUDE"> <![%classname.module;[ <!ENTITY % local.classname.attrib ""> <!ENTITY % classname.role.attrib "%role.attrib;"> <!ENTITY % classname.element "INCLUDE"> <![%classname.element;[ <!--doc:The name of a class, in the object-oriented programming sense.--> <!ELEMENT classname %ho; (%smallcptr.char.mix;)*> <!--end of classname.element-->]]> <!ENTITY % classname.attlist "INCLUDE"> <![%classname.attlist;[ <!ATTLIST classname %common.attrib; %classname.role.attrib; %local.classname.attrib; > <!--end of classname.attlist-->]]> <!--end of classname.module-->]]> <!ENTITY % package.module "INCLUDE"> <![%package.module;[ <!ENTITY % local.package.attrib ""> <!ENTITY % package.role.attrib "%role.attrib;"> <!ENTITY % package.element "INCLUDE"> <![%package.element;[ <!--doc:A package.--> <!ELEMENT package %ho; (%smallcptr.char.mix;)*> <!--end of package.element-->]]> <!ENTITY % package.attlist "INCLUDE"> <![%package.attlist;[ <!ATTLIST package %common.attrib; %package.role.attrib; %local.package.attrib; > <!--end of package.attlist-->]]> <!--end of package.module-->]]> <!ENTITY % co.module "INCLUDE"> <![%co.module;[ <!ENTITY % local.co.attrib ""> <!-- CO is a callout area of the LineColumn unit type (a single character position); the position is directly indicated by the location of CO. --> <!ENTITY % co.role.attrib "%role.attrib;"> <!ENTITY % co.element "INCLUDE"> <![%co.element;[ <!--doc:The location of a callout embedded in text.--> <!ELEMENT co %ho; EMPTY> <!--end of co.element-->]]> <!-- bug number/symbol override or initialization --> <!-- to any related information --> <!ENTITY % co.attlist "INCLUDE"> <![%co.attlist;[ <!ATTLIST co %label.attrib; %linkends.attrib; %idreq.common.attrib; %co.role.attrib; %local.co.attrib; > <!--end of co.attlist-->]]> <!--end of co.module-->]]> <!ENTITY % coref.module "INCLUDE"> <![%coref.module;[ <!ENTITY % local.coref.attrib ""> <!-- COREF is a reference to a CO --> <!ENTITY % coref.role.attrib "%role.attrib;"> <!ENTITY % coref.element "INCLUDE"> <![%coref.element;[ <!--doc:A cross reference to a co.--> <!ELEMENT coref %ho; EMPTY> <!--end of coref.element-->]]> <!-- bug number/symbol override or initialization --> <!-- to any related information --> <!ENTITY % coref.attlist "INCLUDE"> <![%coref.attlist;[ <!ATTLIST coref %label.attrib; %linkendreq.attrib; %common.attrib; %coref.role.attrib; %local.coref.attrib; > <!--end of coref.attlist-->]]> <!--end of coref.module-->]]> <!ENTITY % command.module "INCLUDE"> <![%command.module;[ <!ENTITY % local.command.attrib ""> <!ENTITY % command.role.attrib "%role.attrib;"> <!ENTITY % command.element "INCLUDE"> <![%command.element;[ <!--doc:The name of an executable program or other software command.--> <!ELEMENT command %ho; (%cptr.char.mix;)*> <!--end of command.element-->]]> <!ENTITY % command.attlist "INCLUDE"> <![%command.attlist;[ <!ATTLIST command %moreinfo.attrib; %common.attrib; %command.role.attrib; %local.command.attrib; > <!--end of command.attlist-->]]> <!--end of command.module-->]]> <!ENTITY % computeroutput.module "INCLUDE"> <![%computeroutput.module;[ <!ENTITY % local.computeroutput.attrib ""> <!ENTITY % computeroutput.role.attrib "%role.attrib;"> <!ENTITY % computeroutput.element "INCLUDE"> <![%computeroutput.element;[ <!--doc:Data, generally text, displayed or presented by a computer.--> <!ELEMENT computeroutput %ho; (%cptr.char.mix;|co)*> <!--end of computeroutput.element-->]]> <!ENTITY % computeroutput.attlist "INCLUDE"> <![%computeroutput.attlist;[ <!ATTLIST computeroutput %moreinfo.attrib; %common.attrib; %computeroutput.role.attrib; %local.computeroutput.attrib; > <!--end of computeroutput.attlist-->]]> <!--end of computeroutput.module-->]]> <!ENTITY % database.module "INCLUDE"> <![%database.module;[ <!ENTITY % local.database.attrib ""> <!ENTITY % database.role.attrib "%role.attrib;"> <!ENTITY % database.element "INCLUDE"> <![%database.element;[ <!--doc:The name of a database, or part of a database.--> <!ELEMENT database %ho; (%cptr.char.mix;)*> <!--end of database.element-->]]> <!-- Class: Type of database the element names; no default --> <!ENTITY % database.attlist "INCLUDE"> <![%database.attlist;[ <!ATTLIST database class (name |table |field |key1 |key2 |record |index |view |primarykey |secondarykey |foreignkey |altkey |procedure |datatype |constraint |rule |user |group) #IMPLIED %moreinfo.attrib; %common.attrib; %database.role.attrib; %local.database.attrib; > <!--end of database.attlist-->]]> <!--end of database.module-->]]> <!ENTITY % email.module "INCLUDE"> <![%email.module;[ <!ENTITY % local.email.attrib ""> <!ENTITY % email.role.attrib "%role.attrib;"> <!ENTITY % email.element "INCLUDE"> <![%email.element;[ <!--doc:An email address.--> <!ELEMENT email %ho; (%docinfo.char.mix;)*> <!--end of email.element-->]]> <!ENTITY % email.attlist "INCLUDE"> <![%email.attlist;[ <!ATTLIST email %common.attrib; %email.role.attrib; %local.email.attrib; > <!--end of email.attlist-->]]> <!--end of email.module-->]]> <!ENTITY % envar.module "INCLUDE"> <![%envar.module;[ <!ENTITY % local.envar.attrib ""> <!ENTITY % envar.role.attrib "%role.attrib;"> <!ENTITY % envar.element "INCLUDE"> <![%envar.element;[ <!--doc:A software environment variable.--> <!ELEMENT envar %ho; (%smallcptr.char.mix;)*> <!--end of envar.element-->]]> <!ENTITY % envar.attlist "INCLUDE"> <![%envar.attlist;[ <!ATTLIST envar %common.attrib; %envar.role.attrib; %local.envar.attrib; > <!--end of envar.attlist-->]]> <!--end of envar.module-->]]> <!ENTITY % errorcode.module "INCLUDE"> <![%errorcode.module;[ <!ENTITY % local.errorcode.attrib ""> <!ENTITY % errorcode.role.attrib "%role.attrib;"> <!ENTITY % errorcode.element "INCLUDE"> <![%errorcode.element;[ <!--doc:An error code.--> <!ELEMENT errorcode %ho; (%smallcptr.char.mix;)*> <!--end of errorcode.element-->]]> <!ENTITY % errorcode.attlist "INCLUDE"> <![%errorcode.attlist;[ <!ATTLIST errorcode %moreinfo.attrib; %common.attrib; %errorcode.role.attrib; %local.errorcode.attrib; > <!--end of errorcode.attlist-->]]> <!--end of errorcode.module-->]]> <!ENTITY % errorname.module "INCLUDE"> <![%errorname.module;[ <!ENTITY % local.errorname.attrib ""> <!ENTITY % errorname.role.attrib "%role.attrib;"> <!ENTITY % errorname.element "INCLUDE"> <![%errorname.element;[ <!--doc:An error name.--> <!ELEMENT errorname %ho; (%smallcptr.char.mix;)*> <!--end of errorname.element-->]]> <!ENTITY % errorname.attlist "INCLUDE"> <![%errorname.attlist;[ <!ATTLIST errorname %common.attrib; %errorname.role.attrib; %local.errorname.attrib; > <!--end of errorname.attlist-->]]> <!--end of errorname.module-->]]> <!ENTITY % errortext.module "INCLUDE"> <![%errortext.module;[ <!ENTITY % local.errortext.attrib ""> <!ENTITY % errortext.role.attrib "%role.attrib;"> <!ENTITY % errortext.element "INCLUDE"> <![%errortext.element;[ <!--doc:An error message..--> <!ELEMENT errortext %ho; (%smallcptr.char.mix;)*> <!--end of errortext.element-->]]> <!ENTITY % errortext.attlist "INCLUDE"> <![%errortext.attlist;[ <!ATTLIST errortext %common.attrib; %errortext.role.attrib; %local.errortext.attrib; > <!--end of errortext.attlist-->]]> <!--end of errortext.module-->]]> <!ENTITY % errortype.module "INCLUDE"> <![%errortype.module;[ <!ENTITY % local.errortype.attrib ""> <!ENTITY % errortype.role.attrib "%role.attrib;"> <!ENTITY % errortype.element "INCLUDE"> <![%errortype.element;[ <!--doc:The classification of an error message.--> <!ELEMENT errortype %ho; (%smallcptr.char.mix;)*> <!--end of errortype.element-->]]> <!ENTITY % errortype.attlist "INCLUDE"> <![%errortype.attlist;[ <!ATTLIST errortype %common.attrib; %errortype.role.attrib; %local.errortype.attrib; > <!--end of errortype.attlist-->]]> <!--end of errortype.module-->]]> <!ENTITY % filename.module "INCLUDE"> <![%filename.module;[ <!ENTITY % local.filename.attrib ""> <!ENTITY % filename.role.attrib "%role.attrib;"> <!ENTITY % filename.element "INCLUDE"> <![%filename.element;[ <!--doc:The name of a file.--> <!ELEMENT filename %ho; (%cptr.char.mix;)*> <!--end of filename.element-->]]> <!-- Class: Type of filename the element names; no default --> <!-- Path: Search path (possibly system-specific) in which file can be found --> <!ENTITY % filename.attlist "INCLUDE"> <![%filename.attlist;[ <!ATTLIST filename class (headerfile |partition |devicefile |libraryfile |directory |extension |symlink) #IMPLIED path CDATA #IMPLIED %moreinfo.attrib; %common.attrib; %filename.role.attrib; %local.filename.attrib; > <!--end of filename.attlist-->]]> <!--end of filename.module-->]]> <!ENTITY % function.module "INCLUDE"> <![%function.module;[ <!ENTITY % local.function.attrib ""> <!ENTITY % function.role.attrib "%role.attrib;"> <!ENTITY % function.element "INCLUDE"> <![%function.element;[ <!--doc:The name of a function or subroutine, as in a programming language.--> <!ELEMENT function %ho; (%cptr.char.mix;)*> <!--end of function.element-->]]> <!ENTITY % function.attlist "INCLUDE"> <![%function.attlist;[ <!ATTLIST function %moreinfo.attrib; %common.attrib; %function.role.attrib; %local.function.attrib; > <!--end of function.attlist-->]]> <!--end of function.module-->]]> <!ENTITY % guibutton.module "INCLUDE"> <![%guibutton.module;[ <!ENTITY % local.guibutton.attrib ""> <!ENTITY % guibutton.role.attrib "%role.attrib;"> <!ENTITY % guibutton.element "INCLUDE"> <![%guibutton.element;[ <!--doc:The text on a button in a GUI.--> <!ELEMENT guibutton %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*> <!--end of guibutton.element-->]]> <!ENTITY % guibutton.attlist "INCLUDE"> <![%guibutton.attlist;[ <!ATTLIST guibutton %moreinfo.attrib; %common.attrib; %guibutton.role.attrib; %local.guibutton.attrib; > <!--end of guibutton.attlist-->]]> <!--end of guibutton.module-->]]> <!ENTITY % guiicon.module "INCLUDE"> <![%guiicon.module;[ <!ENTITY % local.guiicon.attrib ""> <!ENTITY % guiicon.role.attrib "%role.attrib;"> <!ENTITY % guiicon.element "INCLUDE"> <![%guiicon.element;[ <!--doc:Graphic and/or text appearing as a icon in a GUI.--> <!ELEMENT guiicon %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*> <!--end of guiicon.element-->]]> <!ENTITY % guiicon.attlist "INCLUDE"> <![%guiicon.attlist;[ <!ATTLIST guiicon %moreinfo.attrib; %common.attrib; %guiicon.role.attrib; %local.guiicon.attrib; > <!--end of guiicon.attlist-->]]> <!--end of guiicon.module-->]]> <!ENTITY % guilabel.module "INCLUDE"> <![%guilabel.module;[ <!ENTITY % local.guilabel.attrib ""> <!ENTITY % guilabel.role.attrib "%role.attrib;"> <!ENTITY % guilabel.element "INCLUDE"> <![%guilabel.element;[ <!--doc:The text of a label in a GUI.--> <!ELEMENT guilabel %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*> <!--end of guilabel.element-->]]> <!ENTITY % guilabel.attlist "INCLUDE"> <![%guilabel.attlist;[ <!ATTLIST guilabel %moreinfo.attrib; %common.attrib; %guilabel.role.attrib; %local.guilabel.attrib; > <!--end of guilabel.attlist-->]]> <!--end of guilabel.module-->]]> <!ENTITY % guimenu.module "INCLUDE"> <![%guimenu.module;[ <!ENTITY % local.guimenu.attrib ""> <!ENTITY % guimenu.role.attrib "%role.attrib;"> <!ENTITY % guimenu.element "INCLUDE"> <![%guimenu.element;[ <!--doc:The name of a menu in a GUI.--> <!ELEMENT guimenu %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*> <!--end of guimenu.element-->]]> <!ENTITY % guimenu.attlist "INCLUDE"> <![%guimenu.attlist;[ <!ATTLIST guimenu %moreinfo.attrib; %common.attrib; %guimenu.role.attrib; %local.guimenu.attrib; > <!--end of guimenu.attlist-->]]> <!--end of guimenu.module-->]]> <!ENTITY % guimenuitem.module "INCLUDE"> <![%guimenuitem.module;[ <!ENTITY % local.guimenuitem.attrib ""> <!ENTITY % guimenuitem.role.attrib "%role.attrib;"> <!ENTITY % guimenuitem.element "INCLUDE"> <![%guimenuitem.element;[ <!--doc:The name of a terminal menu item in a GUI.--> <!ELEMENT guimenuitem %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*> <!--end of guimenuitem.element-->]]> <!ENTITY % guimenuitem.attlist "INCLUDE"> <![%guimenuitem.attlist;[ <!ATTLIST guimenuitem %moreinfo.attrib; %common.attrib; %guimenuitem.role.attrib; %local.guimenuitem.attrib; > <!--end of guimenuitem.attlist-->]]> <!--end of guimenuitem.module-->]]> <!ENTITY % guisubmenu.module "INCLUDE"> <![%guisubmenu.module;[ <!ENTITY % local.guisubmenu.attrib ""> <!ENTITY % guisubmenu.role.attrib "%role.attrib;"> <!ENTITY % guisubmenu.element "INCLUDE"> <![%guisubmenu.element;[ <!--doc:The name of a submenu in a GUI.--> <!ELEMENT guisubmenu %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*> <!--end of guisubmenu.element-->]]> <!ENTITY % guisubmenu.attlist "INCLUDE"> <![%guisubmenu.attlist;[ <!ATTLIST guisubmenu %moreinfo.attrib; %common.attrib; %guisubmenu.role.attrib; %local.guisubmenu.attrib; > <!--end of guisubmenu.attlist-->]]> <!--end of guisubmenu.module-->]]> <!ENTITY % hardware.module "INCLUDE"> <![%hardware.module;[ <!ENTITY % local.hardware.attrib ""> <!ENTITY % hardware.role.attrib "%role.attrib;"> <!ENTITY % hardware.element "INCLUDE"> <![%hardware.element;[ <!--doc:A physical part of a computer system.--> <!ELEMENT hardware %ho; (%cptr.char.mix;)*> <!--end of hardware.element-->]]> <!ENTITY % hardware.attlist "INCLUDE"> <![%hardware.attlist;[ <!ATTLIST hardware %moreinfo.attrib; %common.attrib; %hardware.role.attrib; %local.hardware.attrib; > <!--end of hardware.attlist-->]]> <!--end of hardware.module-->]]> <!ENTITY % interface.module "INCLUDE"> <![%interface.module;[ <!ENTITY % local.interface.attrib ""> <!ENTITY % interface.role.attrib "%role.attrib;"> <!ENTITY % interface.element "INCLUDE"> <![%interface.element;[ <!--doc:An element of a GUI.--> <!ELEMENT interface %ho; (%smallcptr.char.mix;|accel)*> <!--end of interface.element-->]]> <!-- Class: Type of the Interface item; no default --> <!ENTITY % interface.attlist "INCLUDE"> <![%interface.attlist;[ <!ATTLIST interface %moreinfo.attrib; %common.attrib; %interface.role.attrib; %local.interface.attrib; > <!--end of interface.attlist-->]]> <!--end of interface.module-->]]> <!ENTITY % keycap.module "INCLUDE"> <![%keycap.module;[ <!ENTITY % local.keycap.attrib ""> <!ENTITY % keycap.role.attrib "%role.attrib;"> <!ENTITY % keycap.element "INCLUDE"> <![%keycap.element;[ <!--doc:The text printed on a key on a keyboard.--> <!ELEMENT keycap %ho; (%cptr.char.mix;)*> <!--end of keycap.element-->]]> <!ENTITY % keycap.attlist "INCLUDE"> <![%keycap.attlist;[ <!ATTLIST keycap function (alt |control |shift |meta |escape |enter |tab |backspace |command |option |space |delete |insert |up |down |left |right |home |end |pageup |pagedown |other) #IMPLIED otherfunction CDATA #IMPLIED %moreinfo.attrib; %common.attrib; %keycap.role.attrib; %local.keycap.attrib; > <!--end of keycap.attlist-->]]> <!--end of keycap.module-->]]> <!ENTITY % keycode.module "INCLUDE"> <![%keycode.module;[ <!ENTITY % local.keycode.attrib ""> <!ENTITY % keycode.role.attrib "%role.attrib;"> <!ENTITY % keycode.element "INCLUDE"> <![%keycode.element;[ <!--doc:The internal, frequently numeric, identifier for a key on a keyboard.--> <!ELEMENT keycode %ho; (%smallcptr.char.mix;)*> <!--end of keycode.element-->]]> <!ENTITY % keycode.attlist "INCLUDE"> <![%keycode.attlist;[ <!ATTLIST keycode %common.attrib; %keycode.role.attrib; %local.keycode.attrib; > <!--end of keycode.attlist-->]]> <!--end of keycode.module-->]]> <!ENTITY % keycombo.module "INCLUDE"> <![%keycombo.module;[ <!ENTITY % local.keycombo.attrib ""> <!ENTITY % keycombo.role.attrib "%role.attrib;"> <!ENTITY % keycombo.element "INCLUDE"> <![%keycombo.element;[ <!--doc:A combination of input actions.--> <!ELEMENT keycombo %ho; ((keycap|keycombo|keysym|mousebutton)+)> <!--end of keycombo.element-->]]> <!ENTITY % keycombo.attlist "INCLUDE"> <![%keycombo.attlist;[ <!ATTLIST keycombo %keyaction.attrib; %moreinfo.attrib; %common.attrib; %keycombo.role.attrib; %local.keycombo.attrib; > <!--end of keycombo.attlist-->]]> <!--end of keycombo.module-->]]> <!ENTITY % keysym.module "INCLUDE"> <![%keysym.module;[ <!ENTITY % local.keysym.attrib ""> <!ENTITY % keysysm.role.attrib "%role.attrib;"> <!ENTITY % keysym.element "INCLUDE"> <![%keysym.element;[ <!--doc:The symbolic name of a key on a keyboard.--> <!ELEMENT keysym %ho; (%smallcptr.char.mix;)*> <!--end of keysym.element-->]]> <!ENTITY % keysym.attlist "INCLUDE"> <![%keysym.attlist;[ <!ATTLIST keysym %common.attrib; %keysysm.role.attrib; %local.keysym.attrib; > <!--end of keysym.attlist-->]]> <!--end of keysym.module-->]]> <!ENTITY % lineannotation.module "INCLUDE"> <![%lineannotation.module;[ <!ENTITY % local.lineannotation.attrib ""> <!ENTITY % lineannotation.role.attrib "%role.attrib;"> <!ENTITY % lineannotation.element "INCLUDE"> <![%lineannotation.element;[ <!--doc:A comment on a line in a verbatim listing.--> <!ELEMENT lineannotation %ho; (%para.char.mix;)*> <!--end of lineannotation.element-->]]> <!ENTITY % lineannotation.attlist "INCLUDE"> <![%lineannotation.attlist;[ <!ATTLIST lineannotation %common.attrib; %lineannotation.role.attrib; %local.lineannotation.attrib; > <!--end of lineannotation.attlist-->]]> <!--end of lineannotation.module-->]]> <!ENTITY % literal.module "INCLUDE"> <![%literal.module;[ <!ENTITY % local.literal.attrib ""> <!ENTITY % literal.role.attrib "%role.attrib;"> <!ENTITY % literal.element "INCLUDE"> <![%literal.element;[ <!--doc:Inline text that is some literal value.--> <!ELEMENT literal %ho; (%cptr.char.mix;)*> <!--end of literal.element-->]]> <!ENTITY % literal.attlist "INCLUDE"> <![%literal.attlist;[ <!ATTLIST literal %moreinfo.attrib; %common.attrib; %literal.role.attrib; %local.literal.attrib; > <!--end of literal.attlist-->]]> <!--end of literal.module-->]]> <!ENTITY % code.module "INCLUDE"> <![%code.module;[ <!ENTITY % local.code.attrib ""> <!ENTITY % code.role.attrib "%role.attrib;"> <!ENTITY % code.element "INCLUDE"> <![%code.element;[ <!--doc:An inline code fragment.--> <!ELEMENT code %ho; (%cptr.char.mix;)*> <!--end of code.element-->]]> <!ENTITY % code.attlist "INCLUDE"> <![%code.attlist;[ <!ATTLIST code language CDATA #IMPLIED %common.attrib; %code.role.attrib; %local.code.attrib; > <!--end of code.attlist-->]]> <!--end of code.module-->]]> <!ENTITY % constant.module "INCLUDE"> <![ %constant.module; [ <!ENTITY % local.constant.attrib ""> <!ENTITY % constant.role.attrib "%role.attrib;"> <!ENTITY % constant.element "INCLUDE"> <![ %constant.element; [ <!--doc:A programming or system constant.--> <!ELEMENT constant %ho; (%smallcptr.char.mix;)*> <!--end of constant.element-->]]> <!ENTITY % constant.attlist "INCLUDE"> <![ %constant.attlist; [ <!ATTLIST constant class (limit) #IMPLIED %common.attrib; %constant.role.attrib; %local.constant.attrib; > <!--end of constant.attlist-->]]> <!--end of constant.module-->]]> <!ENTITY % varname.module "INCLUDE"> <![ %varname.module; [ <!ENTITY % local.varname.attrib ""> <!ENTITY % varname.role.attrib "%role.attrib;"> <!ENTITY % varname.element "INCLUDE"> <![ %varname.element; [ <!--doc:The name of a variable.--> <!ELEMENT varname %ho; (%smallcptr.char.mix;)*> <!--end of varname.element-->]]> <!ENTITY % varname.attlist "INCLUDE"> <![ %varname.attlist; [ <!ATTLIST varname %common.attrib; %varname.role.attrib; %local.varname.attrib; > <!--end of varname.attlist-->]]> <!--end of varname.module-->]]> <!ENTITY % markup.module "INCLUDE"> <![%markup.module;[ <!ENTITY % local.markup.attrib ""> <!ENTITY % markup.role.attrib "%role.attrib;"> <!ENTITY % markup.element "INCLUDE"> <![%markup.element;[ <!--doc:A string of formatting markup in text that is to be represented literally.--> <!ELEMENT markup %ho; (%smallcptr.char.mix;)*> <!--end of markup.element-->]]> <!ENTITY % markup.attlist "INCLUDE"> <![%markup.attlist;[ <!ATTLIST markup %common.attrib; %markup.role.attrib; %local.markup.attrib; > <!--end of markup.attlist-->]]> <!--end of markup.module-->]]> <!ENTITY % medialabel.module "INCLUDE"> <![%medialabel.module;[ <!ENTITY % local.medialabel.attrib ""> <!ENTITY % medialabel.role.attrib "%role.attrib;"> <!ENTITY % medialabel.element "INCLUDE"> <![%medialabel.element;[ <!--doc:A name that identifies the physical medium on which some information resides.--> <!ELEMENT medialabel %ho; (%smallcptr.char.mix;)*> <!--end of medialabel.element-->]]> <!-- Class: Type of medium named by the element; no default --> <!ENTITY % medialabel.attlist "INCLUDE"> <![%medialabel.attlist;[ <!ATTLIST medialabel class (cartridge |cdrom |disk |tape) #IMPLIED %common.attrib; %medialabel.role.attrib; %local.medialabel.attrib; > <!--end of medialabel.attlist-->]]> <!--end of medialabel.module-->]]> <!ENTITY % menuchoice.content.module "INCLUDE"> <![%menuchoice.content.module;[ <!ENTITY % menuchoice.module "INCLUDE"> <![%menuchoice.module;[ <!ENTITY % local.menuchoice.attrib ""> <!ENTITY % menuchoice.role.attrib "%role.attrib;"> <!ENTITY % menuchoice.element "INCLUDE"> <![%menuchoice.element;[ <!--doc:A selection or series of selections from a menu.--> <!ELEMENT menuchoice %ho; (shortcut?, (guibutton|guiicon|guilabel |guimenu|guimenuitem|guisubmenu|interface)+)> <!--end of menuchoice.element-->]]> <!ENTITY % menuchoice.attlist "INCLUDE"> <![%menuchoice.attlist;[ <!ATTLIST menuchoice %moreinfo.attrib; %common.attrib; %menuchoice.role.attrib; %local.menuchoice.attrib; > <!--end of menuchoice.attlist-->]]> <!--end of menuchoice.module-->]]> <!ENTITY % shortcut.module "INCLUDE"> <![%shortcut.module;[ <!-- See also KeyCombo --> <!ENTITY % local.shortcut.attrib ""> <!ENTITY % shortcut.role.attrib "%role.attrib;"> <!ENTITY % shortcut.element "INCLUDE"> <![%shortcut.element;[ <!--doc:A key combination for an action that is also accessible through a menu.--> <!ELEMENT shortcut %ho; ((keycap|keycombo|keysym|mousebutton)+)> <!--end of shortcut.element-->]]> <!ENTITY % shortcut.attlist "INCLUDE"> <![%shortcut.attlist;[ <!ATTLIST shortcut %keyaction.attrib; %moreinfo.attrib; %common.attrib; %shortcut.role.attrib; %local.shortcut.attrib; > <!--end of shortcut.attlist-->]]> <!--end of shortcut.module-->]]> <!--end of menuchoice.content.module-->]]> <!ENTITY % mousebutton.module "INCLUDE"> <![%mousebutton.module;[ <!ENTITY % local.mousebutton.attrib ""> <!ENTITY % mousebutton.role.attrib "%role.attrib;"> <!ENTITY % mousebutton.element "INCLUDE"> <![%mousebutton.element;[ <!--doc:The conventional name of a mouse button.--> <!ELEMENT mousebutton %ho; (%smallcptr.char.mix;)*> <!--end of mousebutton.element-->]]> <!ENTITY % mousebutton.attlist "INCLUDE"> <![%mousebutton.attlist;[ <!ATTLIST mousebutton %moreinfo.attrib; %common.attrib; %mousebutton.role.attrib; %local.mousebutton.attrib; > <!--end of mousebutton.attlist-->]]> <!--end of mousebutton.module-->]]> <!ENTITY % msgtext.module "INCLUDE"> <![%msgtext.module;[ <!ENTITY % local.msgtext.attrib ""> <!ENTITY % msgtext.role.attrib "%role.attrib;"> <!ENTITY % msgtext.element "INCLUDE"> <![%msgtext.element;[ <!--doc:The actual text of a message component in a message set.--> <!ELEMENT msgtext %ho; ((%component.mix;)+)> <!--end of msgtext.element-->]]> <!ENTITY % msgtext.attlist "INCLUDE"> <![%msgtext.attlist;[ <!ATTLIST msgtext %common.attrib; %msgtext.role.attrib; %local.msgtext.attrib; > <!--end of msgtext.attlist-->]]> <!--end of msgtext.module-->]]> <!ENTITY % option.module "INCLUDE"> <![%option.module;[ <!ENTITY % local.option.attrib ""> <!ENTITY % option.role.attrib "%role.attrib;"> <!ENTITY % option.element "INCLUDE"> <![%option.element;[ <!--doc:An option for a software command.--> <!ELEMENT option %ho; (%cptr.char.mix;)*> <!--end of option.element-->]]> <!ENTITY % option.attlist "INCLUDE"> <![%option.attlist;[ <!ATTLIST option %common.attrib; %option.role.attrib; %local.option.attrib; > <!--end of option.attlist-->]]> <!--end of option.module-->]]> <!ENTITY % optional.module "INCLUDE"> <![%optional.module;[ <!ENTITY % local.optional.attrib ""> <!ENTITY % optional.role.attrib "%role.attrib;"> <!ENTITY % optional.element "INCLUDE"> <![%optional.element;[ <!--doc:Optional information.--> <!ELEMENT optional %ho; (%cptr.char.mix;)*> <!--end of optional.element-->]]> <!ENTITY % optional.attlist "INCLUDE"> <![%optional.attlist;[ <!ATTLIST optional %common.attrib; %optional.role.attrib; %local.optional.attrib; > <!--end of optional.attlist-->]]> <!--end of optional.module-->]]> <!ENTITY % parameter.module "INCLUDE"> <![%parameter.module;[ <!ENTITY % local.parameter.attrib ""> <!ENTITY % parameter.role.attrib "%role.attrib;"> <!ENTITY % parameter.element "INCLUDE"> <![%parameter.element;[ <!--doc:A value or a symbolic reference to a value.--> <!ELEMENT parameter %ho; (%cptr.char.mix;)*> <!--end of parameter.element-->]]> <!-- Class: Type of the Parameter; no default --> <!ENTITY % parameter.attlist "INCLUDE"> <![%parameter.attlist;[ <!ATTLIST parameter class (command |function |option) #IMPLIED %moreinfo.attrib; %common.attrib; %parameter.role.attrib; %local.parameter.attrib; > <!--end of parameter.attlist-->]]> <!--end of parameter.module-->]]> <!ENTITY % prompt.module "INCLUDE"> <![%prompt.module;[ <!ENTITY % local.prompt.attrib ""> <!ENTITY % prompt.role.attrib "%role.attrib;"> <!ENTITY % prompt.element "INCLUDE"> <![%prompt.element;[ <!--doc:A character or string indicating the start of an input field in a computer display.--> <!ELEMENT prompt %ho; (%smallcptr.char.mix;|co)*> <!--end of prompt.element-->]]> <!ENTITY % prompt.attlist "INCLUDE"> <![%prompt.attlist;[ <!ATTLIST prompt %moreinfo.attrib; %common.attrib; %prompt.role.attrib; %local.prompt.attrib; > <!--end of prompt.attlist-->]]> <!--end of prompt.module-->]]> <!ENTITY % property.module "INCLUDE"> <![%property.module;[ <!ENTITY % local.property.attrib ""> <!ENTITY % property.role.attrib "%role.attrib;"> <!ENTITY % property.element "INCLUDE"> <![%property.element;[ <!--doc:A unit of data associated with some part of a computer system.--> <!ELEMENT property %ho; (%cptr.char.mix;)*> <!--end of property.element-->]]> <!ENTITY % property.attlist "INCLUDE"> <![%property.attlist;[ <!ATTLIST property %moreinfo.attrib; %common.attrib; %property.role.attrib; %local.property.attrib; > <!--end of property.attlist-->]]> <!--end of property.module-->]]> <!ENTITY % replaceable.module "INCLUDE"> <![%replaceable.module;[ <!ENTITY % local.replaceable.attrib ""> <!ENTITY % replaceable.role.attrib "%role.attrib;"> <!ENTITY % replaceable.element "INCLUDE"> <![%replaceable.element;[ <!--doc:Content that may or must be replaced by the user.--> <!ELEMENT replaceable %ho; (#PCDATA | %link.char.class; | optional | %base.char.class; | %other.char.class; | inlinegraphic | inlinemediaobject | co)*> <!--end of replaceable.element-->]]> <!-- Class: Type of information the element represents; no default --> <!ENTITY % replaceable.attlist "INCLUDE"> <![%replaceable.attlist;[ <!ATTLIST replaceable class (command |function |option |parameter) #IMPLIED %common.attrib; %replaceable.role.attrib; %local.replaceable.attrib; > <!--end of replaceable.attlist-->]]> <!--end of replaceable.module-->]]> <!ENTITY % returnvalue.module "INCLUDE"> <![%returnvalue.module;[ <!ENTITY % local.returnvalue.attrib ""> <!ENTITY % returnvalue.role.attrib "%role.attrib;"> <!ENTITY % returnvalue.element "INCLUDE"> <![%returnvalue.element;[ <!--doc:The value returned by a function.--> <!ELEMENT returnvalue %ho; (%smallcptr.char.mix;)*> <!--end of returnvalue.element-->]]> <!ENTITY % returnvalue.attlist "INCLUDE"> <![%returnvalue.attlist;[ <!ATTLIST returnvalue %common.attrib; %returnvalue.role.attrib; %local.returnvalue.attrib; > <!--end of returnvalue.attlist-->]]> <!--end of returnvalue.module-->]]> <!ENTITY % sgmltag.module "INCLUDE"> <![%sgmltag.module;[ <!ENTITY % local.sgmltag.attrib ""> <!ENTITY % sgmltag.role.attrib "%role.attrib;"> <!ENTITY % sgmltag.element "INCLUDE"> <![%sgmltag.element;[ <!--doc:A component of SGML markup.--> <!ELEMENT sgmltag %ho; (%smallcptr.char.mix;)*> <!--end of sgmltag.element-->]]> <!-- Class: Type of SGML construct the element names; no default --> <!ENTITY % sgmltag.attlist "INCLUDE"> <![%sgmltag.attlist;[ <!ATTLIST sgmltag class (attribute |attvalue |element |endtag |emptytag |genentity |numcharref |paramentity |pi |xmlpi |starttag |sgmlcomment |prefix |namespace |localname) #IMPLIED namespace CDATA #IMPLIED %common.attrib; %sgmltag.role.attrib; %local.sgmltag.attrib; > <!--end of sgmltag.attlist-->]]> <!--end of sgmltag.module-->]]> <!ENTITY % structfield.module "INCLUDE"> <![%structfield.module;[ <!ENTITY % local.structfield.attrib ""> <!ENTITY % structfield.role.attrib "%role.attrib;"> <!ENTITY % structfield.element "INCLUDE"> <![%structfield.element;[ <!--doc:A field in a structure (in the programming language sense).--> <!ELEMENT structfield %ho; (%smallcptr.char.mix;)*> <!--end of structfield.element-->]]> <!ENTITY % structfield.attlist "INCLUDE"> <![%structfield.attlist;[ <!ATTLIST structfield %common.attrib; %structfield.role.attrib; %local.structfield.attrib; > <!--end of structfield.attlist-->]]> <!--end of structfield.module-->]]> <!ENTITY % structname.module "INCLUDE"> <![%structname.module;[ <!ENTITY % local.structname.attrib ""> <!ENTITY % structname.role.attrib "%role.attrib;"> <!ENTITY % structname.element "INCLUDE"> <![%structname.element;[ <!--doc:The name of a structure (in the programming language sense).--> <!ELEMENT structname %ho; (%smallcptr.char.mix;)*> <!--end of structname.element-->]]> <!ENTITY % structname.attlist "INCLUDE"> <![%structname.attlist;[ <!ATTLIST structname %common.attrib; %structname.role.attrib; %local.structname.attrib; > <!--end of structname.attlist-->]]> <!--end of structname.module-->]]> <!ENTITY % symbol.module "INCLUDE"> <![%symbol.module;[ <!ENTITY % local.symbol.attrib ""> <!ENTITY % symbol.role.attrib "%role.attrib;"> <!ENTITY % symbol.element "INCLUDE"> <![%symbol.element;[ <!--doc:A name that is replaced by a value before processing.--> <!ELEMENT symbol %ho; (%smallcptr.char.mix;)*> <!--end of symbol.element-->]]> <!-- Class: Type of symbol; no default --> <!ENTITY % symbol.attlist "INCLUDE"> <![%symbol.attlist;[ <!ATTLIST symbol class (limit) #IMPLIED %common.attrib; %symbol.role.attrib; %local.symbol.attrib; > <!--end of symbol.attlist-->]]> <!--end of symbol.module-->]]> <!ENTITY % systemitem.module "INCLUDE"> <![%systemitem.module;[ <!ENTITY % local.systemitem.attrib ""> <!ENTITY % systemitem.role.attrib "%role.attrib;"> <!ENTITY % systemitem.element "INCLUDE"> <![%systemitem.element;[ <!--doc:A system-related item or term.--> <!ELEMENT systemitem %ho; (%cptr.char.mix; | acronym | co)*> <!--end of systemitem.element-->]]> <!-- Class: Type of system item the element names; no default --> <!ENTITY % systemitem.attlist "INCLUDE"> <![%systemitem.attlist;[ <!ATTLIST systemitem class (constant |daemon |domainname |etheraddress |event |eventhandler |filesystem |fqdomainname |groupname |ipaddress |library |macro |netmask |newsgroup |osname |protocol |resource |systemname |username |process |server |service) #IMPLIED %moreinfo.attrib; %common.attrib; %systemitem.role.attrib; %local.systemitem.attrib; > <!--end of systemitem.attlist-->]]> <!--end of systemitem.module-->]]> <!ENTITY % uri.module "INCLUDE"> <![%uri.module;[ <!ENTITY % local.uri.attrib ""> <!ENTITY % uri.role.attrib "%role.attrib;"> <!ENTITY % uri.element "INCLUDE"> <![%uri.element;[ <!--doc:A Uniform Resource Identifier.--> <!ELEMENT uri %ho; (%smallcptr.char.mix;)*> <!--end of uri.element-->]]> <!-- Type: Type of URI; no default --> <!ENTITY % uri.attlist "INCLUDE"> <![%uri.attlist;[ <!ATTLIST uri type CDATA #IMPLIED %common.attrib; %uri.role.attrib; %local.uri.attrib; > <!--end of uri.attlist-->]]> <!--end of uri.module-->]]> <!ENTITY % token.module "INCLUDE"> <![%token.module;[ <!ENTITY % local.token.attrib ""> <!ENTITY % token.role.attrib "%role.attrib;"> <!ENTITY % token.element "INCLUDE"> <![%token.element;[ <!--doc:A unit of information.--> <!ELEMENT token %ho; (%smallcptr.char.mix;)*> <!--end of token.element-->]]> <!ENTITY % token.attlist "INCLUDE"> <![%token.attlist;[ <!ATTLIST token %common.attrib; %token.role.attrib; %local.token.attrib; > <!--end of token.attlist-->]]> <!--end of token.module-->]]> <!ENTITY % type.module "INCLUDE"> <![%type.module;[ <!ENTITY % local.type.attrib ""> <!ENTITY % type.role.attrib "%role.attrib;"> <!ENTITY % type.element "INCLUDE"> <![%type.element;[ <!--doc:The classification of a value.--> <!ELEMENT type %ho; (%smallcptr.char.mix;)*> <!--end of type.element-->]]> <!ENTITY % type.attlist "INCLUDE"> <![%type.attlist;[ <!ATTLIST type %common.attrib; %type.role.attrib; %local.type.attrib; > <!--end of type.attlist-->]]> <!--end of type.module-->]]> <!ENTITY % userinput.module "INCLUDE"> <![%userinput.module;[ <!ENTITY % local.userinput.attrib ""> <!ENTITY % userinput.role.attrib "%role.attrib;"> <!ENTITY % userinput.element "INCLUDE"> <![%userinput.element;[ <!--doc:Data entered by the user.--> <!ELEMENT userinput %ho; (%cptr.char.mix;|co)*> <!--end of userinput.element-->]]> <!ENTITY % userinput.attlist "INCLUDE"> <![%userinput.attlist;[ <!ATTLIST userinput %moreinfo.attrib; %common.attrib; %userinput.role.attrib; %local.userinput.attrib; > <!--end of userinput.attlist-->]]> <!--end of userinput.module-->]]> <!ENTITY % termdef.module "INCLUDE"> <![%termdef.module;[ <!ENTITY % local.termdef.attrib ""> <!ENTITY % termdef.role.attrib "%role.attrib;"> <!ENTITY % termdef.element "INCLUDE"> <![%termdef.element;[ <!--doc:An inline definition of a term.--> <!ELEMENT termdef %ho; (%para.char.mix;)*> <!--end of termdef.element-->]]> <!ENTITY % termdef.attlist "INCLUDE"> <![%termdef.attlist;[ <!ATTLIST termdef %common.attrib; %termdef.role.attrib; %local.termdef.attrib; > <!--end of termdef.attlist-->]]> <!--end of termdef.module-->]]> <!-- General words and phrases ............................................ --> <!ENTITY % abbrev.module "INCLUDE"> <![%abbrev.module;[ <!ENTITY % local.abbrev.attrib ""> <!ENTITY % abbrev.role.attrib "%role.attrib;"> <!ENTITY % abbrev.element "INCLUDE"> <![%abbrev.element;[ <!--doc:An abbreviation, especially one followed by a period.--> <!ELEMENT abbrev %ho; (%word.char.mix;)*> <!--end of abbrev.element-->]]> <!ENTITY % abbrev.attlist "INCLUDE"> <![%abbrev.attlist;[ <!ATTLIST abbrev %common.attrib; %abbrev.role.attrib; %local.abbrev.attrib; > <!--end of abbrev.attlist-->]]> <!--end of abbrev.module-->]]> <!ENTITY % acronym.module "INCLUDE"> <![%acronym.module;[ <!ENTITY % local.acronym.attrib ""> <!ENTITY % acronym.role.attrib "%role.attrib;"> <!ENTITY % acronym.element "INCLUDE"> <![%acronym.element;[ <!--doc:An often pronounceable word made from the initial (or selected) letters of a name or phrase.--> <!ELEMENT acronym %ho; (%word.char.mix;)* %acronym.exclusion;> <!--end of acronym.element-->]]> <!ENTITY % acronym.attlist "INCLUDE"> <![%acronym.attlist;[ <!ATTLIST acronym %common.attrib; %acronym.role.attrib; %local.acronym.attrib; > <!--end of acronym.attlist-->]]> <!--end of acronym.module-->]]> <!ENTITY % citation.module "INCLUDE"> <![%citation.module;[ <!ENTITY % local.citation.attrib ""> <!ENTITY % citation.role.attrib "%role.attrib;"> <!ENTITY % citation.element "INCLUDE"> <![%citation.element;[ <!--doc:An inline bibliographic reference to another published work.--> <!ELEMENT citation %ho; (%para.char.mix;)*> <!--end of citation.element-->]]> <!ENTITY % citation.attlist "INCLUDE"> <![%citation.attlist;[ <!ATTLIST citation %common.attrib; %citation.role.attrib; %local.citation.attrib; > <!--end of citation.attlist-->]]> <!--end of citation.module-->]]> <!ENTITY % citerefentry.module "INCLUDE"> <![%citerefentry.module;[ <!ENTITY % local.citerefentry.attrib ""> <!ENTITY % citerefentry.role.attrib "%role.attrib;"> <!ENTITY % citerefentry.element "INCLUDE"> <![%citerefentry.element;[ <!--doc:A citation to a reference page.--> <!ELEMENT citerefentry %ho; (refentrytitle, manvolnum?)> <!--end of citerefentry.element-->]]> <!ENTITY % citerefentry.attlist "INCLUDE"> <![%citerefentry.attlist;[ <!ATTLIST citerefentry %common.attrib; %citerefentry.role.attrib; %local.citerefentry.attrib; > <!--end of citerefentry.attlist-->]]> <!--end of citerefentry.module-->]]> <!ENTITY % refentrytitle.module "INCLUDE"> <![%refentrytitle.module;[ <!ENTITY % local.refentrytitle.attrib ""> <!ENTITY % refentrytitle.role.attrib "%role.attrib;"> <!ENTITY % refentrytitle.element "INCLUDE"> <![%refentrytitle.element;[ <!--doc:The title of a reference page.--> <!ELEMENT refentrytitle %ho; (%para.char.mix;)*> <!--end of refentrytitle.element-->]]> <!ENTITY % refentrytitle.attlist "INCLUDE"> <![%refentrytitle.attlist;[ <!ATTLIST refentrytitle %common.attrib; %refentrytitle.role.attrib; %local.refentrytitle.attrib; > <!--end of refentrytitle.attlist-->]]> <!--end of refentrytitle.module-->]]> <!ENTITY % manvolnum.module "INCLUDE"> <![%manvolnum.module;[ <!ENTITY % local.manvolnum.attrib ""> <!ENTITY % namvolnum.role.attrib "%role.attrib;"> <!ENTITY % manvolnum.element "INCLUDE"> <![%manvolnum.element;[ <!--doc:A reference volume number.--> <!ELEMENT manvolnum %ho; (%word.char.mix;)*> <!--end of manvolnum.element-->]]> <!ENTITY % manvolnum.attlist "INCLUDE"> <![%manvolnum.attlist;[ <!ATTLIST manvolnum %common.attrib; %namvolnum.role.attrib; %local.manvolnum.attrib; > <!--end of manvolnum.attlist-->]]> <!--end of manvolnum.module-->]]> <!ENTITY % citetitle.module "INCLUDE"> <![%citetitle.module;[ <!ENTITY % local.citetitle.attrib ""> <!ENTITY % citetitle.role.attrib "%role.attrib;"> <!ENTITY % citetitle.element "INCLUDE"> <![%citetitle.element;[ <!--doc:The title of a cited work.--> <!ELEMENT citetitle %ho; (%para.char.mix;)*> <!--end of citetitle.element-->]]> <!-- Pubwork: Genre of published work cited; no default --> <!ENTITY % citetitle.attlist "INCLUDE"> <![%citetitle.attlist;[ <!ATTLIST citetitle pubwork (article |book |chapter |part |refentry |section |journal |series |set |manuscript |cdrom |dvd |wiki |gopher |bbs |emailmessage |webpage |newsposting) #IMPLIED %common.attrib; %citetitle.role.attrib; %local.citetitle.attrib; > <!--end of citetitle.attlist-->]]> <!--end of citetitle.module-->]]> <!ENTITY % emphasis.module "INCLUDE"> <![%emphasis.module;[ <!ENTITY % local.emphasis.attrib ""> <!ENTITY % emphasis.role.attrib "%role.attrib;"> <!ENTITY % emphasis.element "INCLUDE"> <![%emphasis.element;[ <!--doc:Emphasized text.--> <!ELEMENT emphasis %ho; (%para.char.mix;)*> <!--end of emphasis.element-->]]> <!ENTITY % emphasis.attlist "INCLUDE"> <![%emphasis.attlist;[ <!ATTLIST emphasis %common.attrib; %emphasis.role.attrib; %local.emphasis.attrib; > <!--end of emphasis.attlist-->]]> <!--end of emphasis.module-->]]> <!ENTITY % foreignphrase.module "INCLUDE"> <![%foreignphrase.module;[ <!ENTITY % local.foreignphrase.attrib ""> <!ENTITY % foreignphrase.role.attrib "%role.attrib;"> <!ENTITY % foreignphrase.element "INCLUDE"> <![%foreignphrase.element;[ <!--doc:A word or phrase in a language other than the primary language of the document.--> <!ELEMENT foreignphrase %ho; (%para.char.mix;)*> <!--end of foreignphrase.element-->]]> <!ENTITY % foreignphrase.attlist "INCLUDE"> <![%foreignphrase.attlist;[ <!ATTLIST foreignphrase %common.attrib; %foreignphrase.role.attrib; %local.foreignphrase.attrib; > <!--end of foreignphrase.attlist-->]]> <!--end of foreignphrase.module-->]]> <!ENTITY % glossterm.module "INCLUDE"> <![%glossterm.module;[ <!ENTITY % local.glossterm.attrib ""> <!ENTITY % glossterm.role.attrib "%role.attrib;"> <!ENTITY % glossterm.element "INCLUDE"> <![%glossterm.element;[ <!--doc:A glossary term.--> <!ELEMENT glossterm %ho; (%para.char.mix;)* %glossterm.exclusion;> <!--end of glossterm.element-->]]> <!-- to GlossEntry if Glossterm used in text --> <!-- BaseForm: Provides the form of GlossTerm to be used for indexing --> <!ENTITY % glossterm.attlist "INCLUDE"> <![%glossterm.attlist;[ <!ATTLIST glossterm baseform CDATA #IMPLIED %linkend.attrib; %common.attrib; %glossterm.role.attrib; %local.glossterm.attrib; > <!--end of glossterm.attlist-->]]> <!--end of glossterm.module-->]]> <!ENTITY % firstterm.module "INCLUDE"> <![%firstterm.module;[ <!ENTITY % local.firstterm.attrib ""> <!ENTITY % firstterm.role.attrib "%role.attrib;"> <!ENTITY % firstterm.element "INCLUDE"> <![%firstterm.element;[ <!--doc:The first occurrence of a term.--> <!ELEMENT firstterm %ho; (%para.char.mix;)* %glossterm.exclusion;> <!--end of firstterm.element-->]]> <!-- to GlossEntry or other explanation --> <!ENTITY % firstterm.attlist "INCLUDE"> <![%firstterm.attlist;[ <!ATTLIST firstterm baseform CDATA #IMPLIED %linkend.attrib; %common.attrib; %firstterm.role.attrib; %local.firstterm.attrib; > <!--end of firstterm.attlist-->]]> <!--end of firstterm.module-->]]> <!ENTITY % phrase.module "INCLUDE"> <![%phrase.module;[ <!ENTITY % local.phrase.attrib ""> <!ENTITY % phrase.role.attrib "%role.attrib;"> <!ENTITY % phrase.element "INCLUDE"> <![%phrase.element;[ <!--doc:A span of text.--> <!ELEMENT phrase %ho; (%para.char.mix;)*> <!--end of phrase.element-->]]> <!ENTITY % phrase.attlist "INCLUDE"> <![%phrase.attlist;[ <!ATTLIST phrase %common.attrib; %phrase.role.attrib; %local.phrase.attrib; > <!--end of phrase.attlist-->]]> <!--end of phrase.module-->]]> <!ENTITY % quote.module "INCLUDE"> <![%quote.module;[ <!ENTITY % local.quote.attrib ""> <!ENTITY % quote.role.attrib "%role.attrib;"> <!ENTITY % quote.element "INCLUDE"> <![%quote.element;[ <!--doc:An inline quotation.--> <!ELEMENT quote %ho; (%para.char.mix;)*> <!--end of quote.element-->]]> <!ENTITY % quote.attlist "INCLUDE"> <![%quote.attlist;[ <!ATTLIST quote %common.attrib; %quote.role.attrib; %local.quote.attrib; > <!--end of quote.attlist-->]]> <!--end of quote.module-->]]> <!ENTITY % ssscript.module "INCLUDE"> <![%ssscript.module;[ <!ENTITY % local.ssscript.attrib ""> <!ENTITY % ssscript.role.attrib "%role.attrib;"> <!ENTITY % subscript.element "INCLUDE"> <![%subscript.element;[ <!--doc:A subscript (as in H{^2}O, the molecular formula for water).--> <!ELEMENT subscript %ho; (#PCDATA | %link.char.class; | emphasis | replaceable | symbol | inlinegraphic | inlinemediaobject | %base.char.class; | %other.char.class;)* %ubiq.exclusion;> <!--end of subscript.element-->]]> <!ENTITY % subscript.attlist "INCLUDE"> <![%subscript.attlist;[ <!ATTLIST subscript %common.attrib; %ssscript.role.attrib; %local.ssscript.attrib; > <!--end of subscript.attlist-->]]> <!ENTITY % superscript.element "INCLUDE"> <![%superscript.element;[ <!--doc:A superscript (as in x^2, the mathematical notation for x multiplied by itself).--> <!ELEMENT superscript %ho; (#PCDATA | %link.char.class; | emphasis | replaceable | symbol | inlinegraphic | inlinemediaobject | %base.char.class; | %other.char.class;)* %ubiq.exclusion;> <!--end of superscript.element-->]]> <!ENTITY % superscript.attlist "INCLUDE"> <![%superscript.attlist;[ <!ATTLIST superscript %common.attrib; %ssscript.role.attrib; %local.ssscript.attrib; > <!--end of superscript.attlist-->]]> <!--end of ssscript.module-->]]> <!ENTITY % trademark.module "INCLUDE"> <![%trademark.module;[ <!ENTITY % local.trademark.attrib ""> <!ENTITY % trademark.role.attrib "%role.attrib;"> <!ENTITY % trademark.element "INCLUDE"> <![%trademark.element;[ <!--doc:A trademark.--> <!ELEMENT trademark %ho; (#PCDATA | %link.char.class; | %tech.char.class; | %base.char.class; | %other.char.class; | inlinegraphic | inlinemediaobject | emphasis)*> <!--end of trademark.element-->]]> <!-- Class: More precisely identifies the item the element names --> <!ENTITY % trademark.attlist "INCLUDE"> <![%trademark.attlist;[ <!ATTLIST trademark class (service |trade |registered |copyright) 'trade' %common.attrib; %trademark.role.attrib; %local.trademark.attrib; > <!--end of trademark.attlist-->]]> <!--end of trademark.module-->]]> <!ENTITY % wordasword.module "INCLUDE"> <![%wordasword.module;[ <!ENTITY % local.wordasword.attrib ""> <!ENTITY % wordasword.role.attrib "%role.attrib;"> <!ENTITY % wordasword.element "INCLUDE"> <![%wordasword.element;[ <!--doc:A word meant specifically as a word and not representing anything else.--> <!ELEMENT wordasword %ho; (%word.char.mix;)*> <!--end of wordasword.element-->]]> <!ENTITY % wordasword.attlist "INCLUDE"> <![%wordasword.attlist;[ <!ATTLIST wordasword %common.attrib; %wordasword.role.attrib; %local.wordasword.attrib; > <!--end of wordasword.attlist-->]]> <!--end of wordasword.module-->]]> <!-- Links and cross-references ........................................... --> <!ENTITY % link.module "INCLUDE"> <![%link.module;[ <!ENTITY % local.link.attrib ""> <!ENTITY % link.role.attrib "%role.attrib;"> <!ENTITY % link.element "INCLUDE"> <![%link.element;[ <!--doc:A hypertext link.--> <!ELEMENT link %ho; (%para.char.mix;)* %links.exclusion;> <!--end of link.element-->]]> <!-- Endterm: ID of element containing text that is to be fetched from elsewhere in the document to appear as the content of this element --> <!-- to linked-to object --> <!-- Type: Freely assignable parameter --> <!ENTITY % link.attlist "INCLUDE"> <![%link.attlist;[ <!ATTLIST link endterm IDREF #IMPLIED xrefstyle CDATA #IMPLIED type CDATA #IMPLIED %linkendreq.attrib; %common.attrib; %link.role.attrib; %local.link.attrib; > <!--end of link.attlist-->]]> <!--end of link.module-->]]> <!ENTITY % olink.module "INCLUDE"> <![%olink.module;[ <!ENTITY % local.olink.attrib ""> <!ENTITY % olink.role.attrib "%role.attrib;"> <!ENTITY % olink.element "INCLUDE"> <![%olink.element;[ <!--doc:A link that addresses its target indirectly, through an entity.--> <!ELEMENT olink %ho; (%para.char.mix;)* %links.exclusion;> <!--end of olink.element-->]]> <!-- TargetDocEnt: Name of an entity to be the target of the link --> <!-- LinkMode: ID of a ModeSpec containing instructions for operating on the entity named by TargetDocEnt --> <!-- LocalInfo: Information that may be passed to ModeSpec --> <!-- Type: Freely assignable parameter --> <!ENTITY % olink.attlist "INCLUDE"> <![%olink.attlist;[ <!ATTLIST olink targetdocent ENTITY #IMPLIED linkmode IDREF #IMPLIED localinfo CDATA #IMPLIED type CDATA #IMPLIED targetdoc CDATA #IMPLIED targetptr CDATA #IMPLIED xrefstyle CDATA #IMPLIED %common.attrib; %olink.role.attrib; %local.olink.attrib; > <!--end of olink.attlist-->]]> <!--end of olink.module-->]]> <!ENTITY % ulink.module "INCLUDE"> <![%ulink.module;[ <!ENTITY % local.ulink.attrib ""> <!ENTITY % ulink.role.attrib "%role.attrib;"> <!ENTITY % ulink.element "INCLUDE"> <![%ulink.element;[ <!--doc:A link that addresses its target by means of a URL (Uniform Resource Locator).--> <!ELEMENT ulink %ho; (%para.char.mix;)* %links.exclusion;> <!--end of ulink.element-->]]> <!-- URL: uniform resource locator; the target of the ULink --> <!-- Type: Freely assignable parameter --> <!ENTITY % ulink.attlist "INCLUDE"> <![%ulink.attlist;[ <!ATTLIST ulink url CDATA #REQUIRED type CDATA #IMPLIED xrefstyle CDATA #IMPLIED %common.attrib; %ulink.role.attrib; %local.ulink.attrib; > <!--end of ulink.attlist-->]]> <!--end of ulink.module-->]]> <!ENTITY % footnoteref.module "INCLUDE"> <![%footnoteref.module;[ <!ENTITY % local.footnoteref.attrib ""> <!ENTITY % footnoteref.role.attrib "%role.attrib;"> <!ENTITY % footnoteref.element "INCLUDE"> <![%footnoteref.element;[ <!--doc:A cross reference to a footnote (a footnote mark).--> <!ELEMENT footnoteref %ho; EMPTY> <!--end of footnoteref.element-->]]> <!-- to footnote content supplied elsewhere --> <!ENTITY % footnoteref.attlist "INCLUDE"> <![%footnoteref.attlist;[ <!ATTLIST footnoteref %linkendreq.attrib; %label.attrib; %common.attrib; %footnoteref.role.attrib; %local.footnoteref.attrib; > <!--end of footnoteref.attlist-->]]> <!--end of footnoteref.module-->]]> <!ENTITY % xref.module "INCLUDE"> <![%xref.module;[ <!ENTITY % local.xref.attrib ""> <!ENTITY % xref.role.attrib "%role.attrib;"> <!ENTITY % xref.element "INCLUDE"> <![%xref.element;[ <!--doc:A cross reference to another part of the document.--> <!ELEMENT xref %ho; EMPTY> <!--end of xref.element-->]]> <!-- Endterm: ID of element containing text that is to be fetched from elsewhere in the document to appear as the content of this element --> <!-- to linked-to object --> <!ENTITY % xref.attlist "INCLUDE"> <![%xref.attlist;[ <!ATTLIST xref endterm IDREF #IMPLIED xrefstyle CDATA #IMPLIED %common.attrib; %linkendreq.attrib; %xref.role.attrib; %local.xref.attrib; > <!--end of xref.attlist-->]]> <!--end of xref.module-->]]> <!ENTITY % biblioref.module "INCLUDE"> <![%biblioref.module;[ <!ENTITY % local.biblioref.attrib ""> <!ENTITY % biblioref.role.attrib "%role.attrib;"> <!ENTITY % biblioref.element "INCLUDE"> <![%biblioref.element;[ <!--doc:A cross reference to a bibliographic entry.--> <!ELEMENT biblioref %ho; EMPTY> <!--end of biblioref.element-->]]> <!ENTITY % biblioref.attlist "INCLUDE"> <![%biblioref.attlist;[ <!ATTLIST biblioref endterm IDREF #IMPLIED xrefstyle CDATA #IMPLIED units CDATA #IMPLIED begin CDATA #IMPLIED end CDATA #IMPLIED %common.attrib; %linkendreq.attrib; %biblioref.role.attrib; %local.biblioref.attrib; > <!--end of biblioref.attlist-->]]> <!--end of biblioref.module-->]]> <!-- Ubiquitous elements .................................................. --> <!ENTITY % anchor.module "INCLUDE"> <![%anchor.module;[ <!ENTITY % local.anchor.attrib ""> <!ENTITY % anchor.role.attrib "%role.attrib;"> <!ENTITY % anchor.element "INCLUDE"> <![%anchor.element;[ <!--doc:A spot in the document.--> <!ELEMENT anchor %ho; EMPTY> <!--end of anchor.element-->]]> <!-- required --> <!-- replaces Lang --> <!ENTITY % anchor.attlist "INCLUDE"> <![%anchor.attlist;[ <!ATTLIST anchor %idreq.attrib; %pagenum.attrib; %remap.attrib; %xreflabel.attrib; %revisionflag.attrib; %effectivity.attrib; %anchor.role.attrib; %local.anchor.attrib; > <!--end of anchor.attlist-->]]> <!--end of anchor.module-->]]> <!ENTITY % beginpage.module "INCLUDE"> <![%beginpage.module;[ <!ENTITY % local.beginpage.attrib ""> <!ENTITY % beginpage.role.attrib "%role.attrib;"> <!ENTITY % beginpage.element "INCLUDE"> <![%beginpage.element;[ <!--doc:The location of a page break in a print version of the document.--> <!ELEMENT beginpage %ho; EMPTY> <!--end of beginpage.element-->]]> <!-- PageNum: Number of page that begins at this point --> <!ENTITY % beginpage.attlist "INCLUDE"> <![%beginpage.attlist;[ <!ATTLIST beginpage %pagenum.attrib; %common.attrib; %beginpage.role.attrib; %local.beginpage.attrib; > <!--end of beginpage.attlist-->]]> <!--end of beginpage.module-->]]> <!-- IndexTerms appear in the text flow for generating or linking an index. --> <!ENTITY % indexterm.content.module "INCLUDE"> <![%indexterm.content.module;[ <!ENTITY % indexterm.module "INCLUDE"> <![%indexterm.module;[ <!ENTITY % local.indexterm.attrib ""> <!ENTITY % indexterm.role.attrib "%role.attrib;"> <!ENTITY % indexterm.element "INCLUDE"> <![%indexterm.element;[ <!--doc:A wrapper for terms to be indexed.--> <!ELEMENT indexterm %ho; (primary?, ((secondary, ((tertiary, (see|seealso+)?) | see | seealso+)?) | see | seealso+)?) %ubiq.exclusion;> <!--end of indexterm.element-->]]> <!-- Scope: Indicates which generated indices the IndexTerm should appear in: Global (whole document set), Local (this document only), or All (both) --> <!-- Significance: Whether this IndexTerm is the most pertinent of its series (Preferred) or not (Normal, the default) --> <!-- Class: Indicates type of IndexTerm; default is Singular, or EndOfRange if StartRef is supplied; StartOfRange value must be supplied explicitly on starts of ranges --> <!-- StartRef: ID of the IndexTerm that starts the indexing range ended by this IndexTerm --> <!-- Zone: IDs of the elements to which the IndexTerm applies, and indicates that the IndexTerm applies to those entire elements rather than the point at which the IndexTerm occurs --> <!ENTITY % indexterm.attlist "INCLUDE"> <![%indexterm.attlist;[ <!ATTLIST indexterm %pagenum.attrib; scope (all |global |local) #IMPLIED significance (preferred |normal) "normal" class (singular |startofrange |endofrange) #IMPLIED startref IDREF #IMPLIED zone IDREFS #IMPLIED type CDATA #IMPLIED %common.attrib; %indexterm.role.attrib; %local.indexterm.attrib; > <!--end of indexterm.attlist-->]]> <!--end of indexterm.module-->]]> <!ENTITY % primsecter.module "INCLUDE"> <![%primsecter.module;[ <!ENTITY % local.primsecter.attrib ""> <!ENTITY % primsecter.role.attrib "%role.attrib;"> <!ENTITY % primary.element "INCLUDE"> <![%primary.element;[ <!--doc:The primary word or phrase under which an index term should be sorted.--> <!ELEMENT primary %ho; (%ndxterm.char.mix;)*> <!--end of primary.element-->]]> <!-- SortAs: Alternate sort string for index sorting, e.g., "fourteen" for an element containing "14" --> <!ENTITY % primary.attlist "INCLUDE"> <![%primary.attlist;[ <!ATTLIST primary sortas CDATA #IMPLIED %common.attrib; %primsecter.role.attrib; %local.primsecter.attrib; > <!--end of primary.attlist-->]]> <!ENTITY % secondary.element "INCLUDE"> <![%secondary.element;[ <!--doc:A secondary word or phrase in an index term.--> <!ELEMENT secondary %ho; (%ndxterm.char.mix;)*> <!--end of secondary.element-->]]> <!-- SortAs: Alternate sort string for index sorting, e.g., "fourteen" for an element containing "14" --> <!ENTITY % secondary.attlist "INCLUDE"> <![%secondary.attlist;[ <!ATTLIST secondary sortas CDATA #IMPLIED %common.attrib; %primsecter.role.attrib; %local.primsecter.attrib; > <!--end of secondary.attlist-->]]> <!ENTITY % tertiary.element "INCLUDE"> <![%tertiary.element;[ <!--doc:A tertiary word or phrase in an index term.--> <!ELEMENT tertiary %ho; (%ndxterm.char.mix;)*> <!--end of tertiary.element-->]]> <!-- SortAs: Alternate sort string for index sorting, e.g., "fourteen" for an element containing "14" --> <!ENTITY % tertiary.attlist "INCLUDE"> <![%tertiary.attlist;[ <!ATTLIST tertiary sortas CDATA #IMPLIED %common.attrib; %primsecter.role.attrib; %local.primsecter.attrib; > <!--end of tertiary.attlist-->]]> <!--end of primsecter.module-->]]> <!ENTITY % seeseealso.module "INCLUDE"> <![%seeseealso.module;[ <!ENTITY % local.seeseealso.attrib ""> <!ENTITY % seeseealso.role.attrib "%role.attrib;"> <!ENTITY % see.element "INCLUDE"> <![%see.element;[ <!--doc:Part of an index term directing the reader instead to another entry in the index.--> <!ELEMENT see %ho; (%ndxterm.char.mix;)*> <!--end of see.element-->]]> <!ENTITY % see.attlist "INCLUDE"> <![%see.attlist;[ <!ATTLIST see %common.attrib; %seeseealso.role.attrib; %local.seeseealso.attrib; > <!--end of see.attlist-->]]> <!ENTITY % seealso.element "INCLUDE"> <![%seealso.element;[ <!--doc:Part of an index term directing the reader also to another entry in the index.--> <!ELEMENT seealso %ho; (%ndxterm.char.mix;)*> <!--end of seealso.element-->]]> <!ENTITY % seealso.attlist "INCLUDE"> <![%seealso.attlist;[ <!ATTLIST seealso %common.attrib; %seeseealso.role.attrib; %local.seeseealso.attrib; > <!--end of seealso.attlist-->]]> <!--end of seeseealso.module-->]]> <!--end of indexterm.content.module-->]]> <!-- End of DocBook XML information pool module V4.5 ...................... --> <!-- ...................................................................... --> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/catalog.xml��������������������������������������������������������������0000644�0001757�0001757�00000011305�12753310630�014563� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0'?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <!-- ...................................................................... --> <!-- XML Catalog data for DocBook XML V4.5 ................................ --> <!-- File catalog.xml ..................................................... --> <!-- Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/. --> <!-- This is the catalog data file for DocBook V4.5. It is provided as a convenience in building your own catalog files. You need not use the filenames listed here, and need not use the filename method of identifying storage objects at all. See the documentation for detailed information on the files associated with the DocBook DTD. See XML Catalogs at http://www.oasis-open.org/committees/entity/ for detailed information on supplying and using catalog data. --> <!-- ...................................................................... --> <!-- DocBook driver file .................................................. --> <public publicId="-//OASIS//DTD DocBook XML V4.5//EN" uri="docbookx.dtd"/> <system systemId="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" uri="docbookx.dtd"/> <system systemId="http://docbook.org/xml/4.5/docbookx.dtd" uri="docbookx.dtd"/> <!-- ...................................................................... --> <!-- DocBook modules ...................................................... --> <public publicId="-//OASIS//DTD DocBook CALS Table Model V4.5//EN" uri="calstblx.dtd"/> <public publicId="-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN" uri="htmltblx.mod"/> <public publicId="-//OASIS//DTD XML Exchange Table Model 19990315//EN" uri="soextblx.dtd"/> <public publicId="-//OASIS//ELEMENTS DocBook Information Pool V4.5//EN" uri="dbpoolx.mod"/> <public publicId="-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN" uri="dbhierx.mod"/> <public publicId="-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN" uri="dbgenent.mod"/> <public publicId="-//OASIS//ENTITIES DocBook Notations V4.5//EN" uri="dbnotnx.mod"/> <public publicId="-//OASIS//ENTITIES DocBook Character Entities V4.5//EN" uri="dbcentx.mod"/> <!-- ...................................................................... --> <!-- ISO entity sets ...................................................... --> <public publicId="ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML" uri="ent/isodia.ent"/> <public publicId="ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML" uri="ent/isonum.ent"/> <public publicId="ISO 8879:1986//ENTITIES Publishing//EN//XML" uri="ent/isopub.ent"/> <public publicId="ISO 8879:1986//ENTITIES General Technical//EN//XML" uri="ent/isotech.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" uri="ent/isolat1.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Latin 2//EN//XML" uri="ent/isolat2.ent"/> <public publicId="ISO 8879:1986//ENTITIES Greek Letters//EN//XML" uri="ent/isogrk1.ent"/> <public publicId="ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML" uri="ent/isogrk2.ent"/> <public publicId="ISO 8879:1986//ENTITIES Greek Symbols//EN//XML" uri="ent/isogrk3.ent"/> <public publicId="ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML" uri="ent/isogrk4.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML" uri="ent/isoamsa.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML" uri="ent/isoamsb.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML" uri="ent/isoamsc.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML" uri="ent/isoamsn.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML" uri="ent/isoamso.ent"/> <public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML" uri="ent/isoamsr.ent"/> <public publicId="ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML" uri="ent/isobox.ent"/> <public publicId="ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML" uri="ent/isocyr1.ent"/> <public publicId="ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML" uri="ent/isocyr2.ent"/> <!-- End of catalog data for DocBook XML V4.5 ............................. --> <!-- ...................................................................... --> </catalog> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/dbcentx.mod��������������������������������������������������������������0000644�0001757�0001757�00000023574�12753310630�014572� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook character entities module V4.5 ............................... --> <!-- File dbcentx.mod ..................................................... --> <!-- Copyright 1992-2004 HaL Computer Systems, Inc., O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software Corporation, Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). $Id$ Permission to use, copy, modify and distribute the DocBook DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This module contains the entity declarations for the standard ISO entity sets used by DocBook. In DTD driver files referring to this module, please use an entity declaration that uses the public identifier shown below: <!ENTITY % dbcent PUBLIC "-//OASIS//ENTITIES DocBook Character Entities V4.5//EN" "dbcentx.mod"> %dbcent; See the documentation for detailed information on the parameter entity and module scheme used in DocBook, customizing DocBook and planning for interchange, and changes made since the last release of DocBook. --> <!-- ...................................................................... --> <![%sgml.features;[ <!ENTITY % ISOamsa.module "INCLUDE"> <![ %ISOamsa.module; [ <!ENTITY % ISOamsa PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN"> <!--end of ISOamsa.module-->]]> <!ENTITY % ISOamsb.module "INCLUDE"> <![ %ISOamsb.module; [ <!ENTITY % ISOamsb PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN"> <!--end of ISOamsb.module-->]]> <!ENTITY % ISOamsc.module "INCLUDE"> <![ %ISOamsc.module; [ <!ENTITY % ISOamsc PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN"> <!--end of ISOamsc.module-->]]> <!ENTITY % ISOamsn.module "INCLUDE"> <![ %ISOamsn.module; [ <!ENTITY % ISOamsn PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN"> <!--end of ISOamsn.module-->]]> <!ENTITY % ISOamso.module "INCLUDE"> <![ %ISOamso.module; [ <!ENTITY % ISOamso PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN"> <!--end of ISOamso.module-->]]> <!ENTITY % ISOamsr.module "INCLUDE"> <![ %ISOamsr.module; [ <!ENTITY % ISOamsr PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN"> <!--end of ISOamsr.module-->]]> <!ENTITY % ISObox.module "INCLUDE"> <![ %ISObox.module; [ <!ENTITY % ISObox PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN"> <!--end of ISObox.module-->]]> <!ENTITY % ISOcyr1.module "INCLUDE"> <![ %ISOcyr1.module; [ <!ENTITY % ISOcyr1 PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN"> <!--end of ISOcyr1.module-->]]> <!ENTITY % ISOcyr2.module "INCLUDE"> <![ %ISOcyr2.module; [ <!ENTITY % ISOcyr2 PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN"> <!--end of ISOcyr2.module-->]]> <!ENTITY % ISOdia.module "INCLUDE"> <![ %ISOdia.module; [ <!ENTITY % ISOdia PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN"> <!--end of ISOdia.module-->]]> <!ENTITY % ISOgrk1.module "INCLUDE"> <![ %ISOgrk1.module; [ <!ENTITY % ISOgrk1 PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN"> <!--end of ISOgrk1.module-->]]> <!ENTITY % ISOgrk2.module "INCLUDE"> <![ %ISOgrk2.module; [ <!ENTITY % ISOgrk2 PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN"> <!--end of ISOgrk2.module-->]]> <!ENTITY % ISOgrk3.module "INCLUDE"> <![ %ISOgrk3.module; [ <!ENTITY % ISOgrk3 PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN"> <!--end of ISOgrk3.module-->]]> <!ENTITY % ISOgrk4.module "INCLUDE"> <![ %ISOgrk4.module; [ <!ENTITY % ISOgrk4 PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN"> <!--end of ISOgrk4.module-->]]> <!ENTITY % ISOlat1.module "INCLUDE"> <![ %ISOlat1.module; [ <!ENTITY % ISOlat1 PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN"> <!--end of ISOlat1.module-->]]> <!ENTITY % ISOlat2.module "INCLUDE"> <![ %ISOlat2.module; [ <!ENTITY % ISOlat2 PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN"> <!--end of ISOlat2.module-->]]> <!ENTITY % ISOnum.module "INCLUDE"> <![ %ISOnum.module; [ <!ENTITY % ISOnum PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN"> <!--end of ISOnum.module-->]]> <!ENTITY % ISOpub.module "INCLUDE"> <![ %ISOpub.module; [ <!ENTITY % ISOpub PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN"> <!--end of ISOpub.module-->]]> <!ENTITY % ISOtech.module "INCLUDE"> <![ %ISOtech.module; [ <!ENTITY % ISOtech PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN"> <!--end of ISOtech.module-->]]> <!--end of sgml.features-->]]> <![%xml.features;[ <!ENTITY % ISOamsa.module "INCLUDE"> <![%ISOamsa.module;[ <!ENTITY % ISOamsa PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML" "ent/isoamsa.ent"> <!--end of ISOamsa.module-->]]> <!ENTITY % ISOamsb.module "INCLUDE"> <![%ISOamsb.module;[ <!ENTITY % ISOamsb PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML" "ent/isoamsb.ent"> <!--end of ISOamsb.module-->]]> <!ENTITY % ISOamsc.module "INCLUDE"> <![%ISOamsc.module;[ <!ENTITY % ISOamsc PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML" "ent/isoamsc.ent"> <!--end of ISOamsc.module-->]]> <!ENTITY % ISOamsn.module "INCLUDE"> <![%ISOamsn.module;[ <!ENTITY % ISOamsn PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML" "ent/isoamsn.ent"> <!--end of ISOamsn.module-->]]> <!ENTITY % ISOamso.module "INCLUDE"> <![%ISOamso.module;[ <!ENTITY % ISOamso PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML" "ent/isoamso.ent"> <!--end of ISOamso.module-->]]> <!ENTITY % ISOamsr.module "INCLUDE"> <![%ISOamsr.module;[ <!ENTITY % ISOamsr PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML" "ent/isoamsr.ent"> <!--end of ISOamsr.module-->]]> <!ENTITY % ISObox.module "INCLUDE"> <![%ISObox.module;[ <!ENTITY % ISObox PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML" "ent/isobox.ent"> <!--end of ISObox.module-->]]> <!ENTITY % ISOcyr1.module "INCLUDE"> <![%ISOcyr1.module;[ <!ENTITY % ISOcyr1 PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML" "ent/isocyr1.ent"> <!--end of ISOcyr1.module-->]]> <!ENTITY % ISOcyr2.module "INCLUDE"> <![%ISOcyr2.module;[ <!ENTITY % ISOcyr2 PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML" "ent/isocyr2.ent"> <!--end of ISOcyr2.module-->]]> <!ENTITY % ISOdia.module "INCLUDE"> <![%ISOdia.module;[ <!ENTITY % ISOdia PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML" "ent/isodia.ent"> <!--end of ISOdia.module-->]]> <!ENTITY % ISOgrk1.module "INCLUDE"> <![%ISOgrk1.module;[ <!ENTITY % ISOgrk1 PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN//XML" "ent/isogrk1.ent"> <!--end of ISOgrk1.module-->]]> <!ENTITY % ISOgrk2.module "INCLUDE"> <![%ISOgrk2.module;[ <!ENTITY % ISOgrk2 PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML" "ent/isogrk2.ent"> <!--end of ISOgrk2.module-->]]> <!ENTITY % ISOgrk3.module "INCLUDE"> <![%ISOgrk3.module;[ <!ENTITY % ISOgrk3 PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN//XML" "ent/isogrk3.ent"> <!--end of ISOgrk3.module-->]]> <!ENTITY % ISOgrk4.module "INCLUDE"> <![%ISOgrk4.module;[ <!ENTITY % ISOgrk4 PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML" "ent/isogrk4.ent"> <!--end of ISOgrk4.module-->]]> <!ENTITY % ISOlat1.module "INCLUDE"> <![%ISOlat1.module;[ <!ENTITY % ISOlat1 PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" "ent/isolat1.ent"> <!--end of ISOlat1.module-->]]> <!ENTITY % ISOlat2.module "INCLUDE"> <![%ISOlat2.module;[ <!ENTITY % ISOlat2 PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN//XML" "ent/isolat2.ent"> <!--end of ISOlat2.module-->]]> <!ENTITY % ISOnum.module "INCLUDE"> <![%ISOnum.module;[ <!ENTITY % ISOnum PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML" "ent/isonum.ent"> <!--end of ISOnum.module-->]]> <!ENTITY % ISOpub.module "INCLUDE"> <![%ISOpub.module;[ <!ENTITY % ISOpub PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN//XML" "ent/isopub.ent"> <!--end of ISOpub.module-->]]> <!ENTITY % ISOtech.module "INCLUDE"> <![%ISOtech.module;[ <!ENTITY % ISOtech PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN//XML" "ent/isotech.ent"> <!--end of ISOtech.module-->]]> <!--end of xml.features-->]]> <![ %ISOamsa.module; [ %ISOamsa; ]]> <![ %ISOamsb.module; [ %ISOamsb; ]]> <![ %ISOamsc.module; [ %ISOamsc; ]]> <![ %ISOamsn.module; [ %ISOamsn; ]]> <![ %ISOamso.module; [ %ISOamso; ]]> <![ %ISOamsr.module; [ %ISOamsr; ]]> <![ %ISObox.module; [ %ISObox; ]]> <![ %ISOcyr1.module; [ %ISOcyr1; ]]> <![ %ISOcyr2.module; [ %ISOcyr2; ]]> <![ %ISOdia.module; [ %ISOdia; ]]> <![ %ISOgrk1.module; [ %ISOgrk1; ]]> <![ %ISOgrk2.module; [ %ISOgrk2; ]]> <![ %ISOgrk3.module; [ %ISOgrk3; ]]> <![ %ISOgrk4.module; [ %ISOgrk4; ]]> <![ %ISOlat1.module; [ %ISOlat1; ]]> <![ %ISOlat2.module; [ %ISOlat2; ]]> <![ %ISOnum.module; [ %ISOnum; ]]> <![ %ISOpub.module; [ %ISOpub; ]]> <![ %ISOtech.module; [ %ISOtech; ]]> <!-- End of DocBook character entity sets module V4.5 ..................... --> <!-- ...................................................................... --> ������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/docbook.cat��������������������������������������������������������������0000644�0001757�0001757�00000007652�12753310630�014552� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ -- ...................................................................... -- -- Catalog data for DocBook XML V4.5 .................................... -- -- File docbook.cat ..................................................... -- -- Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/. -- -- This is the catalog data file for DocBook XML V4.5. It is provided as a convenience in building your own catalog files. You need not use the filenames listed here, and need not use the filename method of identifying storage objects at all. See the documentation for detailed information on the files associated with the DocBook DTD. See SGML Open Technical Resolution 9401 for detailed information on supplying and using catalog data. -- -- ...................................................................... -- -- DocBook driver file .................................................. -- PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd" -- ...................................................................... -- -- DocBook modules ...................................................... -- PUBLIC "-//OASIS//DTD DocBook CALS Table Model V4.5//EN" "calstblx.dtd" PUBLIC "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN" "htmltblx.mod" PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN" "soextblx.dtd" PUBLIC "-//OASIS//ELEMENTS DocBook Information Pool V4.5//EN" "dbpoolx.mod" PUBLIC "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN" "dbhierx.mod" PUBLIC "-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN" "dbgenent.mod" PUBLIC "-//OASIS//ENTITIES DocBook Notations V4.5//EN" "dbnotnx.mod" PUBLIC "-//OASIS//ENTITIES DocBook Character Entities V4.5//EN" "dbcentx.mod" -- ...................................................................... -- -- ISO entity sets ...................................................... -- PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML" "ent/isodia.ent" PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML" "ent/isonum.ent" PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN//XML" "ent/isopub.ent" PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN//XML" "ent/isotech.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" "ent/isolat1.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN//XML" "ent/isolat2.ent" PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN//XML" "ent/isogrk1.ent" PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML" "ent/isogrk2.ent" PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN//XML" "ent/isogrk3.ent" PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML" "ent/isogrk4.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML" "ent/isoamsa.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML" "ent/isoamsb.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML" "ent/isoamsc.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML" "ent/isoamsn.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML" "ent/isoamso.ent" PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML" "ent/isoamsr.ent" PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML" "ent/isobox.ent" PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML" "ent/isocyr1.ent" PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML" "ent/isocyr2.ent" -- End of catalog data for DocBook XML V4.5 ............................. -- -- ...................................................................... -- ��������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/���������������������������������������������������������������������0000755�0001757�0001757�00000000000�13010103345�013263� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isoamsr.ent����������������������������������������������������������0000644�0001757�0001757�00000015475�12753310630�015416� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isoamsr.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isoamsr.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isoamsr PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML" "http://www.w3.org/2003/entities/iso8879/isoamsr.ent" > %isoamsr; --> <!ENTITY ape "≊" ><!--ALMOST EQUAL OR EQUAL TO --> <!ENTITY asymp "≈" ><!--ALMOST EQUAL TO --> <!ENTITY bcong "≌" ><!--ALL EQUAL TO --> <!ENTITY bepsi "϶" ><!--GREEK REVERSED LUNATE EPSILON SYMBOL --> <!ENTITY bowtie "⋈" ><!--BOWTIE --> <!ENTITY bsim "∽" ><!--REVERSED TILDE --> <!ENTITY bsime "⋍" ><!--REVERSED TILDE EQUALS --> <!ENTITY bump "≎" ><!--GEOMETRICALLY EQUIVALENT TO --> <!ENTITY bumpe "≏" ><!--DIFFERENCE BETWEEN --> <!ENTITY cire "≗" ><!--RING EQUAL TO --> <!ENTITY colone "≔" ><!--COLON EQUALS --> <!ENTITY cuepr "⋞" ><!--EQUAL TO OR PRECEDES --> <!ENTITY cuesc "⋟" ><!--EQUAL TO OR SUCCEEDS --> <!ENTITY cupre "≼" ><!--PRECEDES OR EQUAL TO --> <!ENTITY dashv "⊣" ><!--LEFT TACK --> <!ENTITY ecir "≖" ><!--RING IN EQUAL TO --> <!ENTITY ecolon "≕" ><!--EQUALS COLON --> <!ENTITY eDot "≑" ><!--GEOMETRICALLY EQUAL TO --> <!ENTITY efDot "≒" ><!--APPROXIMATELY EQUAL TO OR THE IMAGE OF --> <!ENTITY egs "⪖" ><!--SLANTED EQUAL TO OR GREATER-THAN --> <!ENTITY els "⪕" ><!--SLANTED EQUAL TO OR LESS-THAN --> <!ENTITY erDot "≓" ><!--IMAGE OF OR APPROXIMATELY EQUAL TO --> <!ENTITY esdot "≐" ><!--APPROACHES THE LIMIT --> <!ENTITY fork "⋔" ><!--PITCHFORK --> <!ENTITY frown "⌢" ><!--FROWN --> <!ENTITY gap "⪆" ><!--GREATER-THAN OR APPROXIMATE --> <!ENTITY gE "≧" ><!--GREATER-THAN OVER EQUAL TO --> <!ENTITY gEl "⪌" ><!--GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN --> <!ENTITY gel "⋛" ><!--GREATER-THAN EQUAL TO OR LESS-THAN --> <!ENTITY ges "⩾" ><!--GREATER-THAN OR SLANTED EQUAL TO --> <!ENTITY Gg "⋙" ><!--VERY MUCH GREATER-THAN --> <!ENTITY gl "≷" ><!--GREATER-THAN OR LESS-THAN --> <!ENTITY gsdot "⋗" ><!--GREATER-THAN WITH DOT --> <!ENTITY gsim "≳" ><!--GREATER-THAN OR EQUIVALENT TO --> <!ENTITY Gt "≫" ><!--MUCH GREATER-THAN --> <!ENTITY lap "⪅" ><!--LESS-THAN OR APPROXIMATE --> <!ENTITY ldot "⋖" ><!--LESS-THAN WITH DOT --> <!ENTITY lE "≦" ><!--LESS-THAN OVER EQUAL TO --> <!ENTITY lEg "⪋" ><!--LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN --> <!ENTITY leg "⋚" ><!--LESS-THAN EQUAL TO OR GREATER-THAN --> <!ENTITY les "⩽" ><!--LESS-THAN OR SLANTED EQUAL TO --> <!ENTITY lg "≶" ><!--LESS-THAN OR GREATER-THAN --> <!ENTITY Ll "⋘" ><!--VERY MUCH LESS-THAN --> <!ENTITY lsim "≲" ><!--LESS-THAN OR EQUIVALENT TO --> <!ENTITY Lt "≪" ><!--MUCH LESS-THAN --> <!ENTITY ltrie "⊴" ><!--NORMAL SUBGROUP OF OR EQUAL TO --> <!ENTITY mid "∣" ><!--DIVIDES --> <!ENTITY models "⊧" ><!--MODELS --> <!ENTITY pr "≺" ><!--PRECEDES --> <!ENTITY prap "⪷" ><!--PRECEDES ABOVE ALMOST EQUAL TO --> <!ENTITY pre "⪯" ><!--PRECEDES ABOVE SINGLE-LINE EQUALS SIGN --> <!ENTITY prsim "≾" ><!--PRECEDES OR EQUIVALENT TO --> <!ENTITY rtrie "⊵" ><!--CONTAINS AS NORMAL SUBGROUP OR EQUAL TO --> <!ENTITY samalg "∐" ><!--N-ARY COPRODUCT --> <!ENTITY sc "≻" ><!--SUCCEEDS --> <!ENTITY scap "⪸" ><!--SUCCEEDS ABOVE ALMOST EQUAL TO --> <!ENTITY sccue "≽" ><!--SUCCEEDS OR EQUAL TO --> <!ENTITY sce "⪰" ><!--SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN --> <!ENTITY scsim "≿" ><!--SUCCEEDS OR EQUIVALENT TO --> <!ENTITY sfrown "⌢" ><!--FROWN --> <!ENTITY smid "∣" ><!--DIVIDES --> <!ENTITY smile "⌣" ><!--SMILE --> <!ENTITY spar "∥" ><!--PARALLEL TO --> <!ENTITY sqsub "⊏" ><!--SQUARE IMAGE OF --> <!ENTITY sqsube "⊑" ><!--SQUARE IMAGE OF OR EQUAL TO --> <!ENTITY sqsup "⊐" ><!--SQUARE ORIGINAL OF --> <!ENTITY sqsupe "⊒" ><!--SQUARE ORIGINAL OF OR EQUAL TO --> <!ENTITY ssmile "⌣" ><!--SMILE --> <!ENTITY Sub "⋐" ><!--DOUBLE SUBSET --> <!ENTITY subE "⫅" ><!--SUBSET OF ABOVE EQUALS SIGN --> <!ENTITY Sup "⋑" ><!--DOUBLE SUPERSET --> <!ENTITY supE "⫆" ><!--SUPERSET OF ABOVE EQUALS SIGN --> <!ENTITY thkap "≈" ><!--ALMOST EQUAL TO --> <!ENTITY thksim "∼" ><!--TILDE OPERATOR --> <!ENTITY trie "≜" ><!--DELTA EQUAL TO --> <!ENTITY twixt "≬" ><!--BETWEEN --> <!ENTITY Vdash "⊩" ><!--FORCES --> <!ENTITY vDash "⊨" ><!--TRUE --> <!ENTITY vdash "⊢" ><!--RIGHT TACK --> <!ENTITY veebar "⊻" ><!--XOR --> <!ENTITY vltri "⊲" ><!--NORMAL SUBGROUP OF --> <!ENTITY vprop "∝" ><!--PROPORTIONAL TO --> <!ENTITY vrtri "⊳" ><!--CONTAINS AS NORMAL SUBGROUP --> <!ENTITY Vvdash "⊪" ><!--TRIPLE VERTICAL BAR RIGHT TURNSTILE --> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/Makefile.am����������������������������������������������������������0000644�0001757�0001757�00000000460�12773470550�015263� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������EXTRA_DIST = \ README \ isoamsa.ent \ isoamsb.ent \ isoamsc.ent \ isoamsn.ent \ isoamso.ent \ isoamsr.ent \ isobox.ent \ isocyr1.ent \ isocyr2.ent \ isodia.ent \ isogrk1.ent \ isogrk2.ent \ isogrk3.ent \ isogrk4.ent \ isolat1.ent \ isolat2.ent \ isonum.ent \ isopub.ent \ isotech.ent ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isonum.ent�����������������������������������������������������������0000644�0001757�0001757�00000013701�12753310630�015241� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isonum.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isonum.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isonum PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML" "http://www.w3.org/2003/entities/iso8879/isonum.ent" > %isonum; --> <!ENTITY amp "&#38;" ><!--AMPERSAND --> <!ENTITY apos "'" ><!--APOSTROPHE --> <!ENTITY ast "*" ><!--ASTERISK --> <!ENTITY brvbar "¦" ><!--BROKEN BAR --> <!ENTITY bsol "\" ><!--REVERSE SOLIDUS --> <!ENTITY cent "¢" ><!--CENT SIGN --> <!ENTITY colon ":" ><!--COLON --> <!ENTITY comma "," ><!--COMMA --> <!ENTITY commat "@" ><!--COMMERCIAL AT --> <!ENTITY copy "©" ><!--COPYRIGHT SIGN --> <!ENTITY curren "¤" ><!--CURRENCY SIGN --> <!ENTITY darr "↓" ><!--DOWNWARDS ARROW --> <!ENTITY deg "°" ><!--DEGREE SIGN --> <!ENTITY divide "÷" ><!--DIVISION SIGN --> <!ENTITY dollar "$" ><!--DOLLAR SIGN --> <!ENTITY equals "=" ><!--EQUALS SIGN --> <!ENTITY excl "!" ><!--EXCLAMATION MARK --> <!ENTITY frac12 "½" ><!--VULGAR FRACTION ONE HALF --> <!ENTITY frac14 "¼" ><!--VULGAR FRACTION ONE QUARTER --> <!ENTITY frac18 "⅛" ><!--VULGAR FRACTION ONE EIGHTH --> <!ENTITY frac34 "¾" ><!--VULGAR FRACTION THREE QUARTERS --> <!ENTITY frac38 "⅜" ><!--VULGAR FRACTION THREE EIGHTHS --> <!ENTITY frac58 "⅝" ><!--VULGAR FRACTION FIVE EIGHTHS --> <!ENTITY frac78 "⅞" ><!--VULGAR FRACTION SEVEN EIGHTHS --> <!ENTITY gt ">" ><!--GREATER-THAN SIGN --> <!ENTITY half "½" ><!--VULGAR FRACTION ONE HALF --> <!ENTITY horbar "―" ><!--HORIZONTAL BAR --> <!ENTITY hyphen "‐" ><!--HYPHEN --> <!ENTITY iexcl "¡" ><!--INVERTED EXCLAMATION MARK --> <!ENTITY iquest "¿" ><!--INVERTED QUESTION MARK --> <!ENTITY laquo "«" ><!--LEFT-POINTING DOUBLE ANGLE QUOTATION MARK --> <!ENTITY larr "←" ><!--LEFTWARDS ARROW --> <!ENTITY lcub "{" ><!--LEFT CURLY BRACKET --> <!ENTITY ldquo "“" ><!--LEFT DOUBLE QUOTATION MARK --> <!ENTITY lowbar "_" ><!--LOW LINE --> <!ENTITY lpar "(" ><!--LEFT PARENTHESIS --> <!ENTITY lsqb "[" ><!--LEFT SQUARE BRACKET --> <!ENTITY lsquo "‘" ><!--LEFT SINGLE QUOTATION MARK --> <!ENTITY lt "&#60;" ><!--LESS-THAN SIGN --> <!ENTITY micro "µ" ><!--MICRO SIGN --> <!ENTITY middot "·" ><!--MIDDLE DOT --> <!ENTITY nbsp " " ><!--NO-BREAK SPACE --> <!ENTITY not "¬" ><!--NOT SIGN --> <!ENTITY num "#" ><!--NUMBER SIGN --> <!ENTITY ohm "Ω" ><!--OHM SIGN --> <!ENTITY ordf "ª" ><!--FEMININE ORDINAL INDICATOR --> <!ENTITY ordm "º" ><!--MASCULINE ORDINAL INDICATOR --> <!ENTITY para "¶" ><!--PILCROW SIGN --> <!ENTITY percnt "%" ><!--PERCENT SIGN --> <!ENTITY period "." ><!--FULL STOP --> <!ENTITY plus "+" ><!--PLUS SIGN --> <!ENTITY plusmn "±" ><!--PLUS-MINUS SIGN --> <!ENTITY pound "£" ><!--POUND SIGN --> <!ENTITY quest "?" ><!--QUESTION MARK --> <!ENTITY quot """ ><!--QUOTATION MARK --> <!ENTITY raquo "»" ><!--RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK --> <!ENTITY rarr "→" ><!--RIGHTWARDS ARROW --> <!ENTITY rcub "}" ><!--RIGHT CURLY BRACKET --> <!ENTITY rdquo "”" ><!--RIGHT DOUBLE QUOTATION MARK --> <!ENTITY reg "®" ><!--REGISTERED SIGN --> <!ENTITY rpar ")" ><!--RIGHT PARENTHESIS --> <!ENTITY rsqb "]" ><!--RIGHT SQUARE BRACKET --> <!ENTITY rsquo "’" ><!--RIGHT SINGLE QUOTATION MARK --> <!ENTITY sect "§" ><!--SECTION SIGN --> <!ENTITY semi ";" ><!--SEMICOLON --> <!ENTITY shy "­" ><!--SOFT HYPHEN --> <!ENTITY sol "/" ><!--SOLIDUS --> <!ENTITY sung "♪" ><!--EIGHTH NOTE --> <!ENTITY sup1 "¹" ><!--SUPERSCRIPT ONE --> <!ENTITY sup2 "²" ><!--SUPERSCRIPT TWO --> <!ENTITY sup3 "³" ><!--SUPERSCRIPT THREE --> <!ENTITY times "×" ><!--MULTIPLICATION SIGN --> <!ENTITY trade "™" ><!--TRADE MARK SIGN --> <!ENTITY uarr "↑" ><!--UPWARDS ARROW --> <!ENTITY verbar "|" ><!--VERTICAL LINE --> <!ENTITY yen "¥" ><!--YEN SIGN --> ���������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isogrk3.ent����������������������������������������������������������0000644�0001757�0001757�00000010230�12753310630�015302� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isogrk3.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Greek Symbols//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isogrk3.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isogrk3 PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN//XML" "http://www.w3.org/2003/entities/iso8879/isogrk3.ent" > %isogrk3; --> <!ENTITY alpha "α" ><!--GREEK SMALL LETTER ALPHA --> <!ENTITY beta "β" ><!--GREEK SMALL LETTER BETA --> <!ENTITY chi "χ" ><!--GREEK SMALL LETTER CHI --> <!ENTITY Delta "Δ" ><!--GREEK CAPITAL LETTER DELTA --> <!ENTITY delta "δ" ><!--GREEK SMALL LETTER DELTA --> <!ENTITY epsi "ϵ" ><!--GREEK LUNATE EPSILON SYMBOL --> <!ENTITY epsis "ϵ" ><!--GREEK LUNATE EPSILON SYMBOL --> <!ENTITY epsiv "ε" ><!--GREEK SMALL LETTER EPSILON --> <!ENTITY eta "η" ><!--GREEK SMALL LETTER ETA --> <!ENTITY Gamma "Γ" ><!--GREEK CAPITAL LETTER GAMMA --> <!ENTITY gamma "γ" ><!--GREEK SMALL LETTER GAMMA --> <!ENTITY gammad "ϝ" ><!--GREEK SMALL LETTER DIGAMMA --> <!ENTITY iota "ι" ><!--GREEK SMALL LETTER IOTA --> <!ENTITY kappa "κ" ><!--GREEK SMALL LETTER KAPPA --> <!ENTITY kappav "ϰ" ><!--GREEK KAPPA SYMBOL --> <!ENTITY Lambda "Λ" ><!--GREEK CAPITAL LETTER LAMDA --> <!ENTITY lambda "λ" ><!--GREEK SMALL LETTER LAMDA --> <!ENTITY mu "μ" ><!--GREEK SMALL LETTER MU --> <!ENTITY nu "ν" ><!--GREEK SMALL LETTER NU --> <!ENTITY Omega "Ω" ><!--GREEK CAPITAL LETTER OMEGA --> <!ENTITY omega "ω" ><!--GREEK SMALL LETTER OMEGA --> <!ENTITY Phi "Φ" ><!--GREEK CAPITAL LETTER PHI --> <!ENTITY phis "ϕ" ><!--GREEK PHI SYMBOL --> <!ENTITY phiv "φ" ><!--GREEK SMALL LETTER PHI --> <!ENTITY Pi "Π" ><!--GREEK CAPITAL LETTER PI --> <!ENTITY pi "π" ><!--GREEK SMALL LETTER PI --> <!ENTITY piv "ϖ" ><!--GREEK PI SYMBOL --> <!ENTITY Psi "Ψ" ><!--GREEK CAPITAL LETTER PSI --> <!ENTITY psi "ψ" ><!--GREEK SMALL LETTER PSI --> <!ENTITY rho "ρ" ><!--GREEK SMALL LETTER RHO --> <!ENTITY rhov "ϱ" ><!--GREEK RHO SYMBOL --> <!ENTITY Sigma "Σ" ><!--GREEK CAPITAL LETTER SIGMA --> <!ENTITY sigma "σ" ><!--GREEK SMALL LETTER SIGMA --> <!ENTITY sigmav "ς" ><!--GREEK SMALL LETTER FINAL SIGMA --> <!ENTITY tau "τ" ><!--GREEK SMALL LETTER TAU --> <!ENTITY Theta "Θ" ><!--GREEK CAPITAL LETTER THETA --> <!ENTITY thetas "θ" ><!--GREEK SMALL LETTER THETA --> <!ENTITY thetav "ϑ" ><!--GREEK THETA SYMBOL --> <!ENTITY Upsi "ϒ" ><!--GREEK UPSILON WITH HOOK SYMBOL --> <!ENTITY upsi "υ" ><!--GREEK SMALL LETTER UPSILON --> <!ENTITY Xi "Ξ" ><!--GREEK CAPITAL LETTER XI --> <!ENTITY xi "ξ" ><!--GREEK SMALL LETTER XI --> <!ENTITY zeta "ζ" ><!--GREEK SMALL LETTER ZETA --> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isoamsb.ent����������������������������������������������������������0000644�0001757�0001757�00000007532�12753310630�015371� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isoamsb.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isoamsb.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isoamsb PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML" "http://www.w3.org/2003/entities/iso8879/isoamsb.ent" > %isoamsb; --> <!ENTITY amalg "⨿" ><!--AMALGAMATION OR COPRODUCT --> <!ENTITY Barwed "⌆" ><!--PERSPECTIVE --> <!ENTITY barwed "⌅" ><!--PROJECTIVE --> <!ENTITY Cap "⋒" ><!--DOUBLE INTERSECTION --> <!ENTITY coprod "∐" ><!--N-ARY COPRODUCT --> <!ENTITY Cup "⋓" ><!--DOUBLE UNION --> <!ENTITY cuvee "⋎" ><!--CURLY LOGICAL OR --> <!ENTITY cuwed "⋏" ><!--CURLY LOGICAL AND --> <!ENTITY diam "⋄" ><!--DIAMOND OPERATOR --> <!ENTITY divonx "⋇" ><!--DIVISION TIMES --> <!ENTITY intcal "⊺" ><!--INTERCALATE --> <!ENTITY lthree "⋋" ><!--LEFT SEMIDIRECT PRODUCT --> <!ENTITY ltimes "⋉" ><!--LEFT NORMAL FACTOR SEMIDIRECT PRODUCT --> <!ENTITY minusb "⊟" ><!--SQUARED MINUS --> <!ENTITY oast "⊛" ><!--CIRCLED ASTERISK OPERATOR --> <!ENTITY ocir "⊚" ><!--CIRCLED RING OPERATOR --> <!ENTITY odash "⊝" ><!--CIRCLED DASH --> <!ENTITY odot "⊙" ><!--CIRCLED DOT OPERATOR --> <!ENTITY ominus "⊖" ><!--CIRCLED MINUS --> <!ENTITY oplus "⊕" ><!--CIRCLED PLUS --> <!ENTITY osol "⊘" ><!--CIRCLED DIVISION SLASH --> <!ENTITY otimes "⊗" ><!--CIRCLED TIMES --> <!ENTITY plusb "⊞" ><!--SQUARED PLUS --> <!ENTITY plusdo "∔" ><!--DOT PLUS --> <!ENTITY prod "∏" ><!--N-ARY PRODUCT --> <!ENTITY rthree "⋌" ><!--RIGHT SEMIDIRECT PRODUCT --> <!ENTITY rtimes "⋊" ><!--RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT --> <!ENTITY sdot "⋅" ><!--DOT OPERATOR --> <!ENTITY sdotb "⊡" ><!--SQUARED DOT OPERATOR --> <!ENTITY setmn "∖" ><!--SET MINUS --> <!ENTITY sqcap "⊓" ><!--SQUARE CAP --> <!ENTITY sqcup "⊔" ><!--SQUARE CUP --> <!ENTITY ssetmn "∖" ><!--SET MINUS --> <!ENTITY sstarf "⋆" ><!--STAR OPERATOR --> <!ENTITY sum "∑" ><!--N-ARY SUMMATION --> <!ENTITY timesb "⊠" ><!--SQUARED TIMES --> <!ENTITY top "⊤" ><!--DOWN TACK --> <!ENTITY uplus "⊎" ><!--MULTISET UNION --> <!ENTITY wreath "≀" ><!--WREATH PRODUCT --> <!ENTITY xcirc "◯" ><!--LARGE CIRCLE --> <!ENTITY xdtri "▽" ><!--WHITE DOWN-POINTING TRIANGLE --> <!ENTITY xutri "△" ><!--WHITE UP-POINTING TRIANGLE --> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/Makefile.in����������������������������������������������������������0000644�0001757�0001757�00000035470�13010103322�015254� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/docbook-xml/ent DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ EXTRA_DIST = \ README \ isoamsa.ent \ isoamsb.ent \ isoamsc.ent \ isoamsn.ent \ isoamso.ent \ isoamsr.ent \ isobox.ent \ isocyr1.ent \ isocyr2.ent \ isodia.ent \ isogrk1.ent \ isogrk2.ent \ isogrk3.ent \ isogrk4.ent \ isolat1.ent \ isolat2.ent \ isonum.ent \ isopub.ent \ isotech.ent all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/docbook-xml/ent/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/docbook-xml/ent/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isocyr1.ent����������������������������������������������������������0000644�0001757�0001757�00000013741�12753310630�015324� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isocyr1.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isocyr1.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isocyr1 PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML" "http://www.w3.org/2003/entities/iso8879/isocyr1.ent" > %isocyr1; --> <!ENTITY Acy "А" ><!--CYRILLIC CAPITAL LETTER A --> <!ENTITY acy "а" ><!--CYRILLIC SMALL LETTER A --> <!ENTITY Bcy "Б" ><!--CYRILLIC CAPITAL LETTER BE --> <!ENTITY bcy "б" ><!--CYRILLIC SMALL LETTER BE --> <!ENTITY CHcy "Ч" ><!--CYRILLIC CAPITAL LETTER CHE --> <!ENTITY chcy "ч" ><!--CYRILLIC SMALL LETTER CHE --> <!ENTITY Dcy "Д" ><!--CYRILLIC CAPITAL LETTER DE --> <!ENTITY dcy "д" ><!--CYRILLIC SMALL LETTER DE --> <!ENTITY Ecy "Э" ><!--CYRILLIC CAPITAL LETTER E --> <!ENTITY ecy "э" ><!--CYRILLIC SMALL LETTER E --> <!ENTITY Fcy "Ф" ><!--CYRILLIC CAPITAL LETTER EF --> <!ENTITY fcy "ф" ><!--CYRILLIC SMALL LETTER EF --> <!ENTITY Gcy "Г" ><!--CYRILLIC CAPITAL LETTER GHE --> <!ENTITY gcy "г" ><!--CYRILLIC SMALL LETTER GHE --> <!ENTITY HARDcy "Ъ" ><!--CYRILLIC CAPITAL LETTER HARD SIGN --> <!ENTITY hardcy "ъ" ><!--CYRILLIC SMALL LETTER HARD SIGN --> <!ENTITY Icy "И" ><!--CYRILLIC CAPITAL LETTER I --> <!ENTITY icy "и" ><!--CYRILLIC SMALL LETTER I --> <!ENTITY IEcy "Е" ><!--CYRILLIC CAPITAL LETTER IE --> <!ENTITY iecy "е" ><!--CYRILLIC SMALL LETTER IE --> <!ENTITY IOcy "Ё" ><!--CYRILLIC CAPITAL LETTER IO --> <!ENTITY iocy "ё" ><!--CYRILLIC SMALL LETTER IO --> <!ENTITY Jcy "Й" ><!--CYRILLIC CAPITAL LETTER SHORT I --> <!ENTITY jcy "й" ><!--CYRILLIC SMALL LETTER SHORT I --> <!ENTITY Kcy "К" ><!--CYRILLIC CAPITAL LETTER KA --> <!ENTITY kcy "к" ><!--CYRILLIC SMALL LETTER KA --> <!ENTITY KHcy "Х" ><!--CYRILLIC CAPITAL LETTER HA --> <!ENTITY khcy "х" ><!--CYRILLIC SMALL LETTER HA --> <!ENTITY Lcy "Л" ><!--CYRILLIC CAPITAL LETTER EL --> <!ENTITY lcy "л" ><!--CYRILLIC SMALL LETTER EL --> <!ENTITY Mcy "М" ><!--CYRILLIC CAPITAL LETTER EM --> <!ENTITY mcy "м" ><!--CYRILLIC SMALL LETTER EM --> <!ENTITY Ncy "Н" ><!--CYRILLIC CAPITAL LETTER EN --> <!ENTITY ncy "н" ><!--CYRILLIC SMALL LETTER EN --> <!ENTITY numero "№" ><!--NUMERO SIGN --> <!ENTITY Ocy "О" ><!--CYRILLIC CAPITAL LETTER O --> <!ENTITY ocy "о" ><!--CYRILLIC SMALL LETTER O --> <!ENTITY Pcy "П" ><!--CYRILLIC CAPITAL LETTER PE --> <!ENTITY pcy "п" ><!--CYRILLIC SMALL LETTER PE --> <!ENTITY Rcy "Р" ><!--CYRILLIC CAPITAL LETTER ER --> <!ENTITY rcy "р" ><!--CYRILLIC SMALL LETTER ER --> <!ENTITY Scy "С" ><!--CYRILLIC CAPITAL LETTER ES --> <!ENTITY scy "с" ><!--CYRILLIC SMALL LETTER ES --> <!ENTITY SHCHcy "Щ" ><!--CYRILLIC CAPITAL LETTER SHCHA --> <!ENTITY shchcy "щ" ><!--CYRILLIC SMALL LETTER SHCHA --> <!ENTITY SHcy "Ш" ><!--CYRILLIC CAPITAL LETTER SHA --> <!ENTITY shcy "ш" ><!--CYRILLIC SMALL LETTER SHA --> <!ENTITY SOFTcy "Ь" ><!--CYRILLIC CAPITAL LETTER SOFT SIGN --> <!ENTITY softcy "ь" ><!--CYRILLIC SMALL LETTER SOFT SIGN --> <!ENTITY Tcy "Т" ><!--CYRILLIC CAPITAL LETTER TE --> <!ENTITY tcy "т" ><!--CYRILLIC SMALL LETTER TE --> <!ENTITY TScy "Ц" ><!--CYRILLIC CAPITAL LETTER TSE --> <!ENTITY tscy "ц" ><!--CYRILLIC SMALL LETTER TSE --> <!ENTITY Ucy "У" ><!--CYRILLIC CAPITAL LETTER U --> <!ENTITY ucy "у" ><!--CYRILLIC SMALL LETTER U --> <!ENTITY Vcy "В" ><!--CYRILLIC CAPITAL LETTER VE --> <!ENTITY vcy "в" ><!--CYRILLIC SMALL LETTER VE --> <!ENTITY YAcy "Я" ><!--CYRILLIC CAPITAL LETTER YA --> <!ENTITY yacy "я" ><!--CYRILLIC SMALL LETTER YA --> <!ENTITY Ycy "Ы" ><!--CYRILLIC CAPITAL LETTER YERU --> <!ENTITY ycy "ы" ><!--CYRILLIC SMALL LETTER YERU --> <!ENTITY YUcy "Ю" ><!--CYRILLIC CAPITAL LETTER YU --> <!ENTITY yucy "ю" ><!--CYRILLIC SMALL LETTER YU --> <!ENTITY Zcy "З" ><!--CYRILLIC CAPITAL LETTER ZE --> <!ENTITY zcy "з" ><!--CYRILLIC SMALL LETTER ZE --> <!ENTITY ZHcy "Ж" ><!--CYRILLIC CAPITAL LETTER ZHE --> <!ENTITY zhcy "ж" ><!--CYRILLIC SMALL LETTER ZHE --> �������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isotech.ent����������������������������������������������������������0000644�0001757�0001757�00000011734�12753310630�015371� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isotech.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES General Technical//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isotech.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isotech PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN//XML" "http://www.w3.org/2003/entities/iso8879/isotech.ent" > %isotech; --> <!ENTITY aleph "ℵ" ><!--ALEF SYMBOL --> <!ENTITY and "∧" ><!--LOGICAL AND --> <!ENTITY ang90 "∟" ><!--RIGHT ANGLE --> <!ENTITY angsph "∢" ><!--SPHERICAL ANGLE --> <!ENTITY angst "Å" ><!--ANGSTROM SIGN --> <!ENTITY ap "≈" ><!--ALMOST EQUAL TO --> <!ENTITY becaus "∵" ><!--BECAUSE --> <!ENTITY bernou "ℬ" ><!--SCRIPT CAPITAL B --> <!ENTITY bottom "⊥" ><!--UP TACK --> <!ENTITY cap "∩" ><!--INTERSECTION --> <!ENTITY compfn "∘" ><!--RING OPERATOR --> <!ENTITY cong "≅" ><!--APPROXIMATELY EQUAL TO --> <!ENTITY conint "∮" ><!--CONTOUR INTEGRAL --> <!ENTITY cup "∪" ><!--UNION --> <!ENTITY Dot "¨" ><!--DIAERESIS --> <!ENTITY DotDot " ⃜" ><!--COMBINING FOUR DOTS ABOVE --> <!ENTITY equiv "≡" ><!--IDENTICAL TO --> <!ENTITY exist "∃" ><!--THERE EXISTS --> <!ENTITY fnof "ƒ" ><!--LATIN SMALL LETTER F WITH HOOK --> <!ENTITY forall "∀" ><!--FOR ALL --> <!ENTITY ge "≥" ><!--GREATER-THAN OR EQUAL TO --> <!ENTITY hamilt "ℋ" ><!--SCRIPT CAPITAL H --> <!ENTITY iff "⇔" ><!--LEFT RIGHT DOUBLE ARROW --> <!ENTITY infin "∞" ><!--INFINITY --> <!ENTITY int "∫" ><!--INTEGRAL --> <!ENTITY isin "∈" ><!--ELEMENT OF --> <!ENTITY lagran "ℒ" ><!--SCRIPT CAPITAL L --> <!ENTITY lang "〈" ><!--LEFT-POINTING ANGLE BRACKET --> <!ENTITY lArr "⇐" ><!--LEFTWARDS DOUBLE ARROW --> <!ENTITY le "≤" ><!--LESS-THAN OR EQUAL TO --> <!ENTITY lowast "∗" ><!--ASTERISK OPERATOR --> <!ENTITY minus "−" ><!--MINUS SIGN --> <!ENTITY mnplus "∓" ><!--MINUS-OR-PLUS SIGN --> <!ENTITY nabla "∇" ><!--NABLA --> <!ENTITY ne "≠" ><!--NOT EQUAL TO --> <!ENTITY ni "∋" ><!--CONTAINS AS MEMBER --> <!ENTITY notin "∉" ><!--NOT AN ELEMENT OF --> <!ENTITY or "∨" ><!--LOGICAL OR --> <!ENTITY order "ℴ" ><!--SCRIPT SMALL O --> <!ENTITY par "∥" ><!--PARALLEL TO --> <!ENTITY part "∂" ><!--PARTIAL DIFFERENTIAL --> <!ENTITY permil "‰" ><!--PER MILLE SIGN --> <!ENTITY perp "⊥" ><!--UP TACK --> <!ENTITY phmmat "ℳ" ><!--SCRIPT CAPITAL M --> <!ENTITY Prime "″" ><!--DOUBLE PRIME --> <!ENTITY prime "′" ><!--PRIME --> <!ENTITY prop "∝" ><!--PROPORTIONAL TO --> <!ENTITY radic "√" ><!--SQUARE ROOT --> <!ENTITY rang "〉" ><!--RIGHT-POINTING ANGLE BRACKET --> <!ENTITY rArr "⇒" ><!--RIGHTWARDS DOUBLE ARROW --> <!ENTITY sim "∼" ><!--TILDE OPERATOR --> <!ENTITY sime "≃" ><!--ASYMPTOTICALLY EQUAL TO --> <!ENTITY square "□" ><!--WHITE SQUARE --> <!ENTITY sub "⊂" ><!--SUBSET OF --> <!ENTITY sube "⊆" ><!--SUBSET OF OR EQUAL TO --> <!ENTITY sup "⊃" ><!--SUPERSET OF --> <!ENTITY supe "⊇" ><!--SUPERSET OF OR EQUAL TO --> <!ENTITY tdot " ⃛" ><!--COMBINING THREE DOTS ABOVE --> <!ENTITY there4 "∴" ><!--THEREFORE --> <!ENTITY tprime "‴" ><!--TRIPLE PRIME --> <!ENTITY Verbar "‖" ><!--DOUBLE VERTICAL LINE --> <!ENTITY wedgeq "≙" ><!--ESTIMATES --> ������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isogrk4.ent����������������������������������������������������������0000644�0001757�0001757�00000010627�12753310630�015315� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isogrk4.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isogrk4.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isogrk4 PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML" "http://www.w3.org/2003/entities/iso8879/isogrk4.ent" > %isogrk4; --> <!ENTITY b.alpha "𝛂" ><!--MATHEMATICAL BOLD SMALL ALPHA --> <!ENTITY b.beta "𝛃" ><!--MATHEMATICAL BOLD SMALL BETA --> <!ENTITY b.chi "𝛘" ><!--MATHEMATICAL BOLD SMALL CHI --> <!ENTITY b.Delta "𝚫" ><!--MATHEMATICAL BOLD CAPITAL DELTA --> <!ENTITY b.delta "𝛅" ><!--MATHEMATICAL BOLD SMALL DELTA --> <!ENTITY b.epsi "𝛆" ><!--MATHEMATICAL BOLD SMALL EPSILON --> <!ENTITY b.epsiv "𝛜" ><!--MATHEMATICAL BOLD EPSILON SYMBOL --> <!ENTITY b.eta "𝛈" ><!--MATHEMATICAL BOLD SMALL ETA --> <!ENTITY b.Gamma "𝚪" ><!--MATHEMATICAL BOLD CAPITAL GAMMA --> <!ENTITY b.gamma "𝛄" ><!--MATHEMATICAL BOLD SMALL GAMMA --> <!ENTITY b.Gammad "Ϝ" ><!--GREEK LETTER DIGAMMA --> <!ENTITY b.gammad "ϝ" ><!--GREEK SMALL LETTER DIGAMMA --> <!ENTITY b.iota "𝛊" ><!--MATHEMATICAL BOLD SMALL IOTA --> <!ENTITY b.kappa "𝛋" ><!--MATHEMATICAL BOLD SMALL KAPPA --> <!ENTITY b.kappav "𝛞" ><!--MATHEMATICAL BOLD KAPPA SYMBOL --> <!ENTITY b.Lambda "𝚲" ><!--MATHEMATICAL BOLD CAPITAL LAMDA --> <!ENTITY b.lambda "𝛌" ><!--MATHEMATICAL BOLD SMALL LAMDA --> <!ENTITY b.mu "𝛍" ><!--MATHEMATICAL BOLD SMALL MU --> <!ENTITY b.nu "𝛎" ><!--MATHEMATICAL BOLD SMALL NU --> <!ENTITY b.Omega "𝛀" ><!--MATHEMATICAL BOLD CAPITAL OMEGA --> <!ENTITY b.omega "𝛚" ><!--MATHEMATICAL BOLD SMALL OMEGA --> <!ENTITY b.Phi "𝚽" ><!--MATHEMATICAL BOLD CAPITAL PHI --> <!ENTITY b.phi "𝛗" ><!--MATHEMATICAL BOLD SMALL PHI --> <!ENTITY b.phiv "𝛟" ><!--MATHEMATICAL BOLD PHI SYMBOL --> <!ENTITY b.Pi "𝚷" ><!--MATHEMATICAL BOLD CAPITAL PI --> <!ENTITY b.pi "𝛑" ><!--MATHEMATICAL BOLD SMALL PI --> <!ENTITY b.piv "𝛡" ><!--MATHEMATICAL BOLD PI SYMBOL --> <!ENTITY b.Psi "𝚿" ><!--MATHEMATICAL BOLD CAPITAL PSI --> <!ENTITY b.psi "𝛙" ><!--MATHEMATICAL BOLD SMALL PSI --> <!ENTITY b.rho "𝛒" ><!--MATHEMATICAL BOLD SMALL RHO --> <!ENTITY b.rhov "𝛠" ><!--MATHEMATICAL BOLD RHO SYMBOL --> <!ENTITY b.Sigma "𝚺" ><!--MATHEMATICAL BOLD CAPITAL SIGMA --> <!ENTITY b.sigma "𝛔" ><!--MATHEMATICAL BOLD SMALL SIGMA --> <!ENTITY b.sigmav "𝛓" ><!--MATHEMATICAL BOLD SMALL FINAL SIGMA --> <!ENTITY b.tau "𝛕" ><!--MATHEMATICAL BOLD SMALL TAU --> <!ENTITY b.Theta "𝚯" ><!--MATHEMATICAL BOLD CAPITAL THETA --> <!ENTITY b.thetas "𝛉" ><!--MATHEMATICAL BOLD SMALL THETA --> <!ENTITY b.thetav "𝛝" ><!--MATHEMATICAL BOLD THETA SYMBOL --> <!ENTITY b.Upsi "𝚼" ><!--MATHEMATICAL BOLD CAPITAL UPSILON --> <!ENTITY b.upsi "𝛖" ><!--MATHEMATICAL BOLD SMALL UPSILON --> <!ENTITY b.Xi "𝚵" ><!--MATHEMATICAL BOLD CAPITAL XI --> <!ENTITY b.xi "𝛏" ><!--MATHEMATICAL BOLD SMALL XI --> <!ENTITY b.zeta "𝛇" ><!--MATHEMATICAL BOLD SMALL ZETA --> ���������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isolat1.ent����������������������������������������������������������0000644�0001757�0001757�00000014061�12753310630�015303� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isolat1.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Latin 1//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isolat1.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isolat1 PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" "http://www.w3.org/2003/entities/iso8879/isolat1.ent" > %isolat1; --> <!ENTITY Aacute "Á" ><!--LATIN CAPITAL LETTER A WITH ACUTE --> <!ENTITY aacute "á" ><!--LATIN SMALL LETTER A WITH ACUTE --> <!ENTITY Acirc "Â" ><!--LATIN CAPITAL LETTER A WITH CIRCUMFLEX --> <!ENTITY acirc "â" ><!--LATIN SMALL LETTER A WITH CIRCUMFLEX --> <!ENTITY AElig "Æ" ><!--LATIN CAPITAL LETTER AE --> <!ENTITY aelig "æ" ><!--LATIN SMALL LETTER AE --> <!ENTITY Agrave "À" ><!--LATIN CAPITAL LETTER A WITH GRAVE --> <!ENTITY agrave "à" ><!--LATIN SMALL LETTER A WITH GRAVE --> <!ENTITY Aring "Å" ><!--LATIN CAPITAL LETTER A WITH RING ABOVE --> <!ENTITY aring "å" ><!--LATIN SMALL LETTER A WITH RING ABOVE --> <!ENTITY Atilde "Ã" ><!--LATIN CAPITAL LETTER A WITH TILDE --> <!ENTITY atilde "ã" ><!--LATIN SMALL LETTER A WITH TILDE --> <!ENTITY Auml "Ä" ><!--LATIN CAPITAL LETTER A WITH DIAERESIS --> <!ENTITY auml "ä" ><!--LATIN SMALL LETTER A WITH DIAERESIS --> <!ENTITY Ccedil "Ç" ><!--LATIN CAPITAL LETTER C WITH CEDILLA --> <!ENTITY ccedil "ç" ><!--LATIN SMALL LETTER C WITH CEDILLA --> <!ENTITY Eacute "É" ><!--LATIN CAPITAL LETTER E WITH ACUTE --> <!ENTITY eacute "é" ><!--LATIN SMALL LETTER E WITH ACUTE --> <!ENTITY Ecirc "Ê" ><!--LATIN CAPITAL LETTER E WITH CIRCUMFLEX --> <!ENTITY ecirc "ê" ><!--LATIN SMALL LETTER E WITH CIRCUMFLEX --> <!ENTITY Egrave "È" ><!--LATIN CAPITAL LETTER E WITH GRAVE --> <!ENTITY egrave "è" ><!--LATIN SMALL LETTER E WITH GRAVE --> <!ENTITY ETH "Ð" ><!--LATIN CAPITAL LETTER ETH --> <!ENTITY eth "ð" ><!--LATIN SMALL LETTER ETH --> <!ENTITY Euml "Ë" ><!--LATIN CAPITAL LETTER E WITH DIAERESIS --> <!ENTITY euml "ë" ><!--LATIN SMALL LETTER E WITH DIAERESIS --> <!ENTITY Iacute "Í" ><!--LATIN CAPITAL LETTER I WITH ACUTE --> <!ENTITY iacute "í" ><!--LATIN SMALL LETTER I WITH ACUTE --> <!ENTITY Icirc "Î" ><!--LATIN CAPITAL LETTER I WITH CIRCUMFLEX --> <!ENTITY icirc "î" ><!--LATIN SMALL LETTER I WITH CIRCUMFLEX --> <!ENTITY Igrave "Ì" ><!--LATIN CAPITAL LETTER I WITH GRAVE --> <!ENTITY igrave "ì" ><!--LATIN SMALL LETTER I WITH GRAVE --> <!ENTITY Iuml "Ï" ><!--LATIN CAPITAL LETTER I WITH DIAERESIS --> <!ENTITY iuml "ï" ><!--LATIN SMALL LETTER I WITH DIAERESIS --> <!ENTITY Ntilde "Ñ" ><!--LATIN CAPITAL LETTER N WITH TILDE --> <!ENTITY ntilde "ñ" ><!--LATIN SMALL LETTER N WITH TILDE --> <!ENTITY Oacute "Ó" ><!--LATIN CAPITAL LETTER O WITH ACUTE --> <!ENTITY oacute "ó" ><!--LATIN SMALL LETTER O WITH ACUTE --> <!ENTITY Ocirc "Ô" ><!--LATIN CAPITAL LETTER O WITH CIRCUMFLEX --> <!ENTITY ocirc "ô" ><!--LATIN SMALL LETTER O WITH CIRCUMFLEX --> <!ENTITY Ograve "Ò" ><!--LATIN CAPITAL LETTER O WITH GRAVE --> <!ENTITY ograve "ò" ><!--LATIN SMALL LETTER O WITH GRAVE --> <!ENTITY Oslash "Ø" ><!--LATIN CAPITAL LETTER O WITH STROKE --> <!ENTITY oslash "ø" ><!--LATIN SMALL LETTER O WITH STROKE --> <!ENTITY Otilde "Õ" ><!--LATIN CAPITAL LETTER O WITH TILDE --> <!ENTITY otilde "õ" ><!--LATIN SMALL LETTER O WITH TILDE --> <!ENTITY Ouml "Ö" ><!--LATIN CAPITAL LETTER O WITH DIAERESIS --> <!ENTITY ouml "ö" ><!--LATIN SMALL LETTER O WITH DIAERESIS --> <!ENTITY szlig "ß" ><!--LATIN SMALL LETTER SHARP S --> <!ENTITY THORN "Þ" ><!--LATIN CAPITAL LETTER THORN --> <!ENTITY thorn "þ" ><!--LATIN SMALL LETTER THORN --> <!ENTITY Uacute "Ú" ><!--LATIN CAPITAL LETTER U WITH ACUTE --> <!ENTITY uacute "ú" ><!--LATIN SMALL LETTER U WITH ACUTE --> <!ENTITY Ucirc "Û" ><!--LATIN CAPITAL LETTER U WITH CIRCUMFLEX --> <!ENTITY ucirc "û" ><!--LATIN SMALL LETTER U WITH CIRCUMFLEX --> <!ENTITY Ugrave "Ù" ><!--LATIN CAPITAL LETTER U WITH GRAVE --> <!ENTITY ugrave "ù" ><!--LATIN SMALL LETTER U WITH GRAVE --> <!ENTITY Uuml "Ü" ><!--LATIN CAPITAL LETTER U WITH DIAERESIS --> <!ENTITY uuml "ü" ><!--LATIN SMALL LETTER U WITH DIAERESIS --> <!ENTITY Yacute "Ý" ><!--LATIN CAPITAL LETTER Y WITH ACUTE --> <!ENTITY yacute "ý" ><!--LATIN SMALL LETTER Y WITH ACUTE --> <!ENTITY yuml "ÿ" ><!--LATIN SMALL LETTER Y WITH DIAERESIS --> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isoamsa.ent����������������������������������������������������������0000644�0001757�0001757�00000012473�12753310630�015370� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isoamsa.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isoamsa.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isoamsa PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML" "http://www.w3.org/2003/entities/iso8879/isoamsa.ent" > %isoamsa; --> <!ENTITY cularr "↶" ><!--ANTICLOCKWISE TOP SEMICIRCLE ARROW --> <!ENTITY curarr "↷" ><!--CLOCKWISE TOP SEMICIRCLE ARROW --> <!ENTITY dArr "⇓" ><!--DOWNWARDS DOUBLE ARROW --> <!ENTITY darr2 "⇊" ><!--DOWNWARDS PAIRED ARROWS --> <!ENTITY dharl "⇃" ><!--DOWNWARDS HARPOON WITH BARB LEFTWARDS --> <!ENTITY dharr "⇂" ><!--DOWNWARDS HARPOON WITH BARB RIGHTWARDS --> <!ENTITY dlarr "↙" ><!--SOUTH WEST ARROW --> <!ENTITY drarr "↘" ><!--SOUTH EAST ARROW --> <!ENTITY hArr "⇔" ><!--LEFT RIGHT DOUBLE ARROW --> <!ENTITY harr "↔" ><!--LEFT RIGHT ARROW --> <!ENTITY harrw "↭" ><!--LEFT RIGHT WAVE ARROW --> <!ENTITY lAarr "⇚" ><!--LEFTWARDS TRIPLE ARROW --> <!ENTITY Larr "↞" ><!--LEFTWARDS TWO HEADED ARROW --> <!ENTITY larr2 "⇇" ><!--LEFTWARDS PAIRED ARROWS --> <!ENTITY larrhk "↩" ><!--LEFTWARDS ARROW WITH HOOK --> <!ENTITY larrlp "↫" ><!--LEFTWARDS ARROW WITH LOOP --> <!ENTITY larrtl "↢" ><!--LEFTWARDS ARROW WITH TAIL --> <!ENTITY lhard "↽" ><!--LEFTWARDS HARPOON WITH BARB DOWNWARDS --> <!ENTITY lharu "↼" ><!--LEFTWARDS HARPOON WITH BARB UPWARDS --> <!ENTITY lrarr2 "⇆" ><!--LEFTWARDS ARROW OVER RIGHTWARDS ARROW --> <!ENTITY lrhar2 "⇋" ><!--LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON --> <!ENTITY lsh "↰" ><!--UPWARDS ARROW WITH TIP LEFTWARDS --> <!ENTITY map "↦" ><!--RIGHTWARDS ARROW FROM BAR --> <!ENTITY mumap "⊸" ><!--MULTIMAP --> <!ENTITY nearr "↗" ><!--NORTH EAST ARROW --> <!ENTITY nhArr "⇎" ><!--LEFT RIGHT DOUBLE ARROW WITH STROKE --> <!ENTITY nharr "↮" ><!--LEFT RIGHT ARROW WITH STROKE --> <!ENTITY nlArr "⇍" ><!--LEFTWARDS DOUBLE ARROW WITH STROKE --> <!ENTITY nlarr "↚" ><!--LEFTWARDS ARROW WITH STROKE --> <!ENTITY nrArr "⇏" ><!--RIGHTWARDS DOUBLE ARROW WITH STROKE --> <!ENTITY nrarr "↛" ><!--RIGHTWARDS ARROW WITH STROKE --> <!ENTITY nwarr "↖" ><!--NORTH WEST ARROW --> <!ENTITY olarr "↺" ><!--ANTICLOCKWISE OPEN CIRCLE ARROW --> <!ENTITY orarr "↻" ><!--CLOCKWISE OPEN CIRCLE ARROW --> <!ENTITY rAarr "⇛" ><!--RIGHTWARDS TRIPLE ARROW --> <!ENTITY Rarr "↠" ><!--RIGHTWARDS TWO HEADED ARROW --> <!ENTITY rarr2 "⇉" ><!--RIGHTWARDS PAIRED ARROWS --> <!ENTITY rarrhk "↪" ><!--RIGHTWARDS ARROW WITH HOOK --> <!ENTITY rarrlp "↬" ><!--RIGHTWARDS ARROW WITH LOOP --> <!ENTITY rarrtl "↣" ><!--RIGHTWARDS ARROW WITH TAIL --> <!ENTITY rarrw "↝" ><!--RIGHTWARDS WAVE ARROW --> <!ENTITY rhard "⇁" ><!--RIGHTWARDS HARPOON WITH BARB DOWNWARDS --> <!ENTITY rharu "⇀" ><!--RIGHTWARDS HARPOON WITH BARB UPWARDS --> <!ENTITY rlarr2 "⇄" ><!--RIGHTWARDS ARROW OVER LEFTWARDS ARROW --> <!ENTITY rlhar2 "⇌" ><!--RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON --> <!ENTITY rsh "↱" ><!--UPWARDS ARROW WITH TIP RIGHTWARDS --> <!ENTITY uArr "⇑" ><!--UPWARDS DOUBLE ARROW --> <!ENTITY uarr2 "⇈" ><!--UPWARDS PAIRED ARROWS --> <!ENTITY uharl "↿" ><!--UPWARDS HARPOON WITH BARB LEFTWARDS --> <!ENTITY uharr "↾" ><!--UPWARDS HARPOON WITH BARB RIGHTWARDS --> <!ENTITY vArr "⇕" ><!--UP DOWN DOUBLE ARROW --> <!ENTITY varr "↕" ><!--UP DOWN ARROW --> <!ENTITY xhArr "⟺" ><!--LONG LEFT RIGHT DOUBLE ARROW --> <!ENTITY xharr "⟷" ><!--LONG LEFT RIGHT ARROW --> <!ENTITY xlArr "⟸" ><!--LONG LEFTWARDS DOUBLE ARROW --> <!ENTITY xrArr "⟹" ><!--LONG RIGHTWARDS DOUBLE ARROW --> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isolat2.ent����������������������������������������������������������0000644�0001757�0001757�00000025415�12753310630�015311� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isolat2.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Latin 2//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isolat2.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isolat2 PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN//XML" "http://www.w3.org/2003/entities/iso8879/isolat2.ent" > %isolat2; --> <!ENTITY Abreve "Ă" ><!--LATIN CAPITAL LETTER A WITH BREVE --> <!ENTITY abreve "ă" ><!--LATIN SMALL LETTER A WITH BREVE --> <!ENTITY Amacr "Ā" ><!--LATIN CAPITAL LETTER A WITH MACRON --> <!ENTITY amacr "ā" ><!--LATIN SMALL LETTER A WITH MACRON --> <!ENTITY Aogon "Ą" ><!--LATIN CAPITAL LETTER A WITH OGONEK --> <!ENTITY aogon "ą" ><!--LATIN SMALL LETTER A WITH OGONEK --> <!ENTITY Cacute "Ć" ><!--LATIN CAPITAL LETTER C WITH ACUTE --> <!ENTITY cacute "ć" ><!--LATIN SMALL LETTER C WITH ACUTE --> <!ENTITY Ccaron "Č" ><!--LATIN CAPITAL LETTER C WITH CARON --> <!ENTITY ccaron "č" ><!--LATIN SMALL LETTER C WITH CARON --> <!ENTITY Ccirc "Ĉ" ><!--LATIN CAPITAL LETTER C WITH CIRCUMFLEX --> <!ENTITY ccirc "ĉ" ><!--LATIN SMALL LETTER C WITH CIRCUMFLEX --> <!ENTITY Cdot "Ċ" ><!--LATIN CAPITAL LETTER C WITH DOT ABOVE --> <!ENTITY cdot "ċ" ><!--LATIN SMALL LETTER C WITH DOT ABOVE --> <!ENTITY Dcaron "Ď" ><!--LATIN CAPITAL LETTER D WITH CARON --> <!ENTITY dcaron "ď" ><!--LATIN SMALL LETTER D WITH CARON --> <!ENTITY Dstrok "Đ" ><!--LATIN CAPITAL LETTER D WITH STROKE --> <!ENTITY dstrok "đ" ><!--LATIN SMALL LETTER D WITH STROKE --> <!ENTITY Ecaron "Ě" ><!--LATIN CAPITAL LETTER E WITH CARON --> <!ENTITY ecaron "ě" ><!--LATIN SMALL LETTER E WITH CARON --> <!ENTITY Edot "Ė" ><!--LATIN CAPITAL LETTER E WITH DOT ABOVE --> <!ENTITY edot "ė" ><!--LATIN SMALL LETTER E WITH DOT ABOVE --> <!ENTITY Emacr "Ē" ><!--LATIN CAPITAL LETTER E WITH MACRON --> <!ENTITY emacr "ē" ><!--LATIN SMALL LETTER E WITH MACRON --> <!ENTITY ENG "Ŋ" ><!--LATIN CAPITAL LETTER ENG --> <!ENTITY eng "ŋ" ><!--LATIN SMALL LETTER ENG --> <!ENTITY Eogon "Ę" ><!--LATIN CAPITAL LETTER E WITH OGONEK --> <!ENTITY eogon "ę" ><!--LATIN SMALL LETTER E WITH OGONEK --> <!ENTITY gacute "ǵ" ><!--LATIN SMALL LETTER G WITH ACUTE --> <!ENTITY Gbreve "Ğ" ><!--LATIN CAPITAL LETTER G WITH BREVE --> <!ENTITY gbreve "ğ" ><!--LATIN SMALL LETTER G WITH BREVE --> <!ENTITY Gcedil "Ģ" ><!--LATIN CAPITAL LETTER G WITH CEDILLA --> <!ENTITY Gcirc "Ĝ" ><!--LATIN CAPITAL LETTER G WITH CIRCUMFLEX --> <!ENTITY gcirc "ĝ" ><!--LATIN SMALL LETTER G WITH CIRCUMFLEX --> <!ENTITY Gdot "Ġ" ><!--LATIN CAPITAL LETTER G WITH DOT ABOVE --> <!ENTITY gdot "ġ" ><!--LATIN SMALL LETTER G WITH DOT ABOVE --> <!ENTITY Hcirc "Ĥ" ><!--LATIN CAPITAL LETTER H WITH CIRCUMFLEX --> <!ENTITY hcirc "ĥ" ><!--LATIN SMALL LETTER H WITH CIRCUMFLEX --> <!ENTITY Hstrok "Ħ" ><!--LATIN CAPITAL LETTER H WITH STROKE --> <!ENTITY hstrok "ħ" ><!--LATIN SMALL LETTER H WITH STROKE --> <!ENTITY Idot "İ" ><!--LATIN CAPITAL LETTER I WITH DOT ABOVE --> <!ENTITY IJlig "IJ" ><!--LATIN CAPITAL LIGATURE IJ --> <!ENTITY ijlig "ij" ><!--LATIN SMALL LIGATURE IJ --> <!ENTITY Imacr "Ī" ><!--LATIN CAPITAL LETTER I WITH MACRON --> <!ENTITY imacr "ī" ><!--LATIN SMALL LETTER I WITH MACRON --> <!ENTITY inodot "ı" ><!--LATIN SMALL LETTER DOTLESS I --> <!ENTITY Iogon "Į" ><!--LATIN CAPITAL LETTER I WITH OGONEK --> <!ENTITY iogon "į" ><!--LATIN SMALL LETTER I WITH OGONEK --> <!ENTITY Itilde "Ĩ" ><!--LATIN CAPITAL LETTER I WITH TILDE --> <!ENTITY itilde "ĩ" ><!--LATIN SMALL LETTER I WITH TILDE --> <!ENTITY Jcirc "Ĵ" ><!--LATIN CAPITAL LETTER J WITH CIRCUMFLEX --> <!ENTITY jcirc "ĵ" ><!--LATIN SMALL LETTER J WITH CIRCUMFLEX --> <!ENTITY Kcedil "Ķ" ><!--LATIN CAPITAL LETTER K WITH CEDILLA --> <!ENTITY kcedil "ķ" ><!--LATIN SMALL LETTER K WITH CEDILLA --> <!ENTITY kgreen "ĸ" ><!--LATIN SMALL LETTER KRA --> <!ENTITY Lacute "Ĺ" ><!--LATIN CAPITAL LETTER L WITH ACUTE --> <!ENTITY lacute "ĺ" ><!--LATIN SMALL LETTER L WITH ACUTE --> <!ENTITY Lcaron "Ľ" ><!--LATIN CAPITAL LETTER L WITH CARON --> <!ENTITY lcaron "ľ" ><!--LATIN SMALL LETTER L WITH CARON --> <!ENTITY Lcedil "Ļ" ><!--LATIN CAPITAL LETTER L WITH CEDILLA --> <!ENTITY lcedil "ļ" ><!--LATIN SMALL LETTER L WITH CEDILLA --> <!ENTITY Lmidot "Ŀ" ><!--LATIN CAPITAL LETTER L WITH MIDDLE DOT --> <!ENTITY lmidot "ŀ" ><!--LATIN SMALL LETTER L WITH MIDDLE DOT --> <!ENTITY Lstrok "Ł" ><!--LATIN CAPITAL LETTER L WITH STROKE --> <!ENTITY lstrok "ł" ><!--LATIN SMALL LETTER L WITH STROKE --> <!ENTITY Nacute "Ń" ><!--LATIN CAPITAL LETTER N WITH ACUTE --> <!ENTITY nacute "ń" ><!--LATIN SMALL LETTER N WITH ACUTE --> <!ENTITY napos "ʼn" ><!--LATIN SMALL LETTER N PRECEDED BY APOSTROPHE --> <!ENTITY Ncaron "Ň" ><!--LATIN CAPITAL LETTER N WITH CARON --> <!ENTITY ncaron "ň" ><!--LATIN SMALL LETTER N WITH CARON --> <!ENTITY Ncedil "Ņ" ><!--LATIN CAPITAL LETTER N WITH CEDILLA --> <!ENTITY ncedil "ņ" ><!--LATIN SMALL LETTER N WITH CEDILLA --> <!ENTITY Odblac "Ő" ><!--LATIN CAPITAL LETTER O WITH DOUBLE ACUTE --> <!ENTITY odblac "ő" ><!--LATIN SMALL LETTER O WITH DOUBLE ACUTE --> <!ENTITY OElig "Œ" ><!--LATIN CAPITAL LIGATURE OE --> <!ENTITY oelig "œ" ><!--LATIN SMALL LIGATURE OE --> <!ENTITY Omacr "Ō" ><!--LATIN CAPITAL LETTER O WITH MACRON --> <!ENTITY omacr "ō" ><!--LATIN SMALL LETTER O WITH MACRON --> <!ENTITY Racute "Ŕ" ><!--LATIN CAPITAL LETTER R WITH ACUTE --> <!ENTITY racute "ŕ" ><!--LATIN SMALL LETTER R WITH ACUTE --> <!ENTITY Rcaron "Ř" ><!--LATIN CAPITAL LETTER R WITH CARON --> <!ENTITY rcaron "ř" ><!--LATIN SMALL LETTER R WITH CARON --> <!ENTITY Rcedil "Ŗ" ><!--LATIN CAPITAL LETTER R WITH CEDILLA --> <!ENTITY rcedil "ŗ" ><!--LATIN SMALL LETTER R WITH CEDILLA --> <!ENTITY Sacute "Ś" ><!--LATIN CAPITAL LETTER S WITH ACUTE --> <!ENTITY sacute "ś" ><!--LATIN SMALL LETTER S WITH ACUTE --> <!ENTITY Scaron "Š" ><!--LATIN CAPITAL LETTER S WITH CARON --> <!ENTITY scaron "š" ><!--LATIN SMALL LETTER S WITH CARON --> <!ENTITY Scedil "Ş" ><!--LATIN CAPITAL LETTER S WITH CEDILLA --> <!ENTITY scedil "ş" ><!--LATIN SMALL LETTER S WITH CEDILLA --> <!ENTITY Scirc "Ŝ" ><!--LATIN CAPITAL LETTER S WITH CIRCUMFLEX --> <!ENTITY scirc "ŝ" ><!--LATIN SMALL LETTER S WITH CIRCUMFLEX --> <!ENTITY Tcaron "Ť" ><!--LATIN CAPITAL LETTER T WITH CARON --> <!ENTITY tcaron "ť" ><!--LATIN SMALL LETTER T WITH CARON --> <!ENTITY Tcedil "Ţ" ><!--LATIN CAPITAL LETTER T WITH CEDILLA --> <!ENTITY tcedil "ţ" ><!--LATIN SMALL LETTER T WITH CEDILLA --> <!ENTITY Tstrok "Ŧ" ><!--LATIN CAPITAL LETTER T WITH STROKE --> <!ENTITY tstrok "ŧ" ><!--LATIN SMALL LETTER T WITH STROKE --> <!ENTITY Ubreve "Ŭ" ><!--LATIN CAPITAL LETTER U WITH BREVE --> <!ENTITY ubreve "ŭ" ><!--LATIN SMALL LETTER U WITH BREVE --> <!ENTITY Udblac "Ű" ><!--LATIN CAPITAL LETTER U WITH DOUBLE ACUTE --> <!ENTITY udblac "ű" ><!--LATIN SMALL LETTER U WITH DOUBLE ACUTE --> <!ENTITY Umacr "Ū" ><!--LATIN CAPITAL LETTER U WITH MACRON --> <!ENTITY umacr "ū" ><!--LATIN SMALL LETTER U WITH MACRON --> <!ENTITY Uogon "Ų" ><!--LATIN CAPITAL LETTER U WITH OGONEK --> <!ENTITY uogon "ų" ><!--LATIN SMALL LETTER U WITH OGONEK --> <!ENTITY Uring "Ů" ><!--LATIN CAPITAL LETTER U WITH RING ABOVE --> <!ENTITY uring "ů" ><!--LATIN SMALL LETTER U WITH RING ABOVE --> <!ENTITY Utilde "Ũ" ><!--LATIN CAPITAL LETTER U WITH TILDE --> <!ENTITY utilde "ũ" ><!--LATIN SMALL LETTER U WITH TILDE --> <!ENTITY Wcirc "Ŵ" ><!--LATIN CAPITAL LETTER W WITH CIRCUMFLEX --> <!ENTITY wcirc "ŵ" ><!--LATIN SMALL LETTER W WITH CIRCUMFLEX --> <!ENTITY Ycirc "Ŷ" ><!--LATIN CAPITAL LETTER Y WITH CIRCUMFLEX --> <!ENTITY ycirc "ŷ" ><!--LATIN SMALL LETTER Y WITH CIRCUMFLEX --> <!ENTITY Yuml "Ÿ" ><!--LATIN CAPITAL LETTER Y WITH DIAERESIS --> <!ENTITY Zacute "Ź" ><!--LATIN CAPITAL LETTER Z WITH ACUTE --> <!ENTITY zacute "ź" ><!--LATIN SMALL LETTER Z WITH ACUTE --> <!ENTITY Zcaron "Ž" ><!--LATIN CAPITAL LETTER Z WITH CARON --> <!ENTITY zcaron "ž" ><!--LATIN SMALL LETTER Z WITH CARON --> <!ENTITY Zdot "Ż" ><!--LATIN CAPITAL LETTER Z WITH DOT ABOVE --> <!ENTITY zdot "ż" ><!--LATIN SMALL LETTER Z WITH DOT ABOVE --> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isogrk1.ent����������������������������������������������������������0000644�0001757�0001757�00000011162�12753310630�015305� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isogrk1.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Greek Letters//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isogrk1.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isogrk1 PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN//XML" "http://www.w3.org/2003/entities/iso8879/isogrk1.ent" > %isogrk1; --> <!ENTITY Agr "Α" ><!--GREEK CAPITAL LETTER ALPHA --> <!ENTITY agr "α" ><!--GREEK SMALL LETTER ALPHA --> <!ENTITY Bgr "Β" ><!--GREEK CAPITAL LETTER BETA --> <!ENTITY bgr "β" ><!--GREEK SMALL LETTER BETA --> <!ENTITY Dgr "Δ" ><!--GREEK CAPITAL LETTER DELTA --> <!ENTITY dgr "δ" ><!--GREEK SMALL LETTER DELTA --> <!ENTITY EEgr "Η" ><!--GREEK CAPITAL LETTER ETA --> <!ENTITY eegr "η" ><!--GREEK SMALL LETTER ETA --> <!ENTITY Egr "Ε" ><!--GREEK CAPITAL LETTER EPSILON --> <!ENTITY egr "ε" ><!--GREEK SMALL LETTER EPSILON --> <!ENTITY Ggr "Γ" ><!--GREEK CAPITAL LETTER GAMMA --> <!ENTITY ggr "γ" ><!--GREEK SMALL LETTER GAMMA --> <!ENTITY Igr "Ι" ><!--GREEK CAPITAL LETTER IOTA --> <!ENTITY igr "ι" ><!--GREEK SMALL LETTER IOTA --> <!ENTITY Kgr "Κ" ><!--GREEK CAPITAL LETTER KAPPA --> <!ENTITY kgr "κ" ><!--GREEK SMALL LETTER KAPPA --> <!ENTITY KHgr "Χ" ><!--GREEK CAPITAL LETTER CHI --> <!ENTITY khgr "χ" ><!--GREEK SMALL LETTER CHI --> <!ENTITY Lgr "Λ" ><!--GREEK CAPITAL LETTER LAMDA --> <!ENTITY lgr "λ" ><!--GREEK SMALL LETTER LAMDA --> <!ENTITY Mgr "Μ" ><!--GREEK CAPITAL LETTER MU --> <!ENTITY mgr "μ" ><!--GREEK SMALL LETTER MU --> <!ENTITY Ngr "Ν" ><!--GREEK CAPITAL LETTER NU --> <!ENTITY ngr "ν" ><!--GREEK SMALL LETTER NU --> <!ENTITY Ogr "Ο" ><!--GREEK CAPITAL LETTER OMICRON --> <!ENTITY ogr "ο" ><!--GREEK SMALL LETTER OMICRON --> <!ENTITY OHgr "Ω" ><!--GREEK CAPITAL LETTER OMEGA --> <!ENTITY ohgr "ω" ><!--GREEK SMALL LETTER OMEGA --> <!ENTITY Pgr "Π" ><!--GREEK CAPITAL LETTER PI --> <!ENTITY pgr "π" ><!--GREEK SMALL LETTER PI --> <!ENTITY PHgr "Φ" ><!--GREEK CAPITAL LETTER PHI --> <!ENTITY phgr "φ" ><!--GREEK SMALL LETTER PHI --> <!ENTITY PSgr "Ψ" ><!--GREEK CAPITAL LETTER PSI --> <!ENTITY psgr "ψ" ><!--GREEK SMALL LETTER PSI --> <!ENTITY Rgr "Ρ" ><!--GREEK CAPITAL LETTER RHO --> <!ENTITY rgr "ρ" ><!--GREEK SMALL LETTER RHO --> <!ENTITY sfgr "ς" ><!--GREEK SMALL LETTER FINAL SIGMA --> <!ENTITY Sgr "Σ" ><!--GREEK CAPITAL LETTER SIGMA --> <!ENTITY sgr "σ" ><!--GREEK SMALL LETTER SIGMA --> <!ENTITY Tgr "Τ" ><!--GREEK CAPITAL LETTER TAU --> <!ENTITY tgr "τ" ><!--GREEK SMALL LETTER TAU --> <!ENTITY THgr "Θ" ><!--GREEK CAPITAL LETTER THETA --> <!ENTITY thgr "θ" ><!--GREEK SMALL LETTER THETA --> <!ENTITY Ugr "Υ" ><!--GREEK CAPITAL LETTER UPSILON --> <!ENTITY ugr "υ" ><!--GREEK SMALL LETTER UPSILON --> <!ENTITY Xgr "Ξ" ><!--GREEK CAPITAL LETTER XI --> <!ENTITY xgr "ξ" ><!--GREEK SMALL LETTER XI --> <!ENTITY Zgr "Ζ" ><!--GREEK CAPITAL LETTER ZETA --> <!ENTITY zgr "ζ" ><!--GREEK SMALL LETTER ZETA --> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isoamsn.ent����������������������������������������������������������0000644�0001757�0001757�00000014111�12753310630�015374� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isoamsn.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. References to the VARIANT SELECTOR 1 character (︀) should match the uses listed in Unicode Technical Report 25. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isoamsn.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isoamsn PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML" "http://www.w3.org/2003/entities/iso8879/isoamsn.ent" > %isoamsn; --> <!ENTITY gnap "⪊" ><!--GREATER-THAN AND NOT APPROXIMATE --> <!ENTITY gnE "≩" ><!--GREATER-THAN BUT NOT EQUAL TO --> <!ENTITY gne "⪈" ><!--GREATER-THAN AND SINGLE-LINE NOT EQUAL TO --> <!ENTITY gnsim "⋧" ><!--GREATER-THAN BUT NOT EQUIVALENT TO --> <!ENTITY gvnE "≩︀" ><!--GREATER-THAN BUT NOT EQUAL TO - with vertical stroke --> <!ENTITY lnap "⪉" ><!--LESS-THAN AND NOT APPROXIMATE --> <!ENTITY lnE "≨" ><!--LESS-THAN BUT NOT EQUAL TO --> <!ENTITY lne "⪇" ><!--LESS-THAN AND SINGLE-LINE NOT EQUAL TO --> <!ENTITY lnsim "⋦" ><!--LESS-THAN BUT NOT EQUIVALENT TO --> <!ENTITY lvnE "≨︀" ><!--LESS-THAN BUT NOT EQUAL TO - with vertical stroke --> <!ENTITY nap "≉" ><!--NOT ALMOST EQUAL TO --> <!ENTITY ncong "≇" ><!--NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO --> <!ENTITY nequiv "≢" ><!--NOT IDENTICAL TO --> <!ENTITY ngE "≧̸" ><!--GREATER-THAN OVER EQUAL TO with slash --> <!ENTITY nge "≱" ><!--NEITHER GREATER-THAN NOR EQUAL TO --> <!ENTITY nges "⩾̸" ><!--GREATER-THAN OR SLANTED EQUAL TO with slash --> <!ENTITY ngt "≯" ><!--NOT GREATER-THAN --> <!ENTITY nlE "≦̸" ><!--LESS-THAN OVER EQUAL TO with slash --> <!ENTITY nle "≰" ><!--NEITHER LESS-THAN NOR EQUAL TO --> <!ENTITY nles "⩽̸" ><!--LESS-THAN OR SLANTED EQUAL TO with slash --> <!ENTITY nlt "≮" ><!--NOT LESS-THAN --> <!ENTITY nltri "⋪" ><!--NOT NORMAL SUBGROUP OF --> <!ENTITY nltrie "⋬" ><!--NOT NORMAL SUBGROUP OF OR EQUAL TO --> <!ENTITY nmid "∤" ><!--DOES NOT DIVIDE --> <!ENTITY npar "∦" ><!--NOT PARALLEL TO --> <!ENTITY npr "⊀" ><!--DOES NOT PRECEDE --> <!ENTITY npre "⪯̸" ><!--PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash --> <!ENTITY nrtri "⋫" ><!--DOES NOT CONTAIN AS NORMAL SUBGROUP --> <!ENTITY nrtrie "⋭" ><!--DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL --> <!ENTITY nsc "⊁" ><!--DOES NOT SUCCEED --> <!ENTITY nsce "⪰̸" ><!--SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash --> <!ENTITY nsim "≁" ><!--NOT TILDE --> <!ENTITY nsime "≄" ><!--NOT ASYMPTOTICALLY EQUAL TO --> <!ENTITY nsmid "∤" ><!--DOES NOT DIVIDE --> <!ENTITY nspar "∦" ><!--NOT PARALLEL TO --> <!ENTITY nsub "⊄" ><!--NOT A SUBSET OF --> <!ENTITY nsubE "⫅̸" ><!--SUBSET OF ABOVE EQUALS SIGN with slash --> <!ENTITY nsube "⊈" ><!--NEITHER A SUBSET OF NOR EQUAL TO --> <!ENTITY nsup "⊅" ><!--NOT A SUPERSET OF --> <!ENTITY nsupE "⫆̸" ><!--SUPERSET OF ABOVE EQUALS SIGN with slash --> <!ENTITY nsupe "⊉" ><!--NEITHER A SUPERSET OF NOR EQUAL TO --> <!ENTITY nVDash "⊯" ><!--NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE --> <!ENTITY nVdash "⊮" ><!--DOES NOT FORCE --> <!ENTITY nvDash "⊭" ><!--NOT TRUE --> <!ENTITY nvdash "⊬" ><!--DOES NOT PROVE --> <!ENTITY prnap "⪹" ><!--PRECEDES ABOVE NOT ALMOST EQUAL TO --> <!ENTITY prnE "⪵" ><!--PRECEDES ABOVE NOT EQUAL TO --> <!ENTITY prnsim "⋨" ><!--PRECEDES BUT NOT EQUIVALENT TO --> <!ENTITY scnap "⪺" ><!--SUCCEEDS ABOVE NOT ALMOST EQUAL TO --> <!ENTITY scnE "⪶" ><!--SUCCEEDS ABOVE NOT EQUAL TO --> <!ENTITY scnsim "⋩" ><!--SUCCEEDS BUT NOT EQUIVALENT TO --> <!ENTITY subnE "⫋" ><!--SUBSET OF ABOVE NOT EQUAL TO --> <!ENTITY subne "⊊" ><!--SUBSET OF WITH NOT EQUAL TO --> <!ENTITY supnE "⫌" ><!--SUPERSET OF ABOVE NOT EQUAL TO --> <!ENTITY supne "⊋" ><!--SUPERSET OF WITH NOT EQUAL TO --> <!ENTITY vsubnE "⫋︀" ><!--SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members --> <!ENTITY vsubne "⊊︀" ><!--SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members --> <!ENTITY vsupnE "⫌︀" ><!--SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members --> <!ENTITY vsupne "⊋︀" ><!--SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members --> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isopub.ent�����������������������������������������������������������0000644�0001757�0001757�00000015062�12753310630�015232� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isopub.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Publishing//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isopub.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isopub PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN//XML" "http://www.w3.org/2003/entities/iso8879/isopub.ent" > %isopub; --> <!ENTITY blank "␣" ><!--OPEN BOX --> <!ENTITY blk12 "▒" ><!--MEDIUM SHADE --> <!ENTITY blk14 "░" ><!--LIGHT SHADE --> <!ENTITY blk34 "▓" ><!--DARK SHADE --> <!ENTITY block "█" ><!--FULL BLOCK --> <!ENTITY bull "•" ><!--BULLET --> <!ENTITY caret "⁁" ><!--CARET INSERTION POINT --> <!ENTITY check "✓" ><!--CHECK MARK --> <!ENTITY cir "○" ><!--WHITE CIRCLE --> <!ENTITY clubs "♣" ><!--BLACK CLUB SUIT --> <!ENTITY copysr "℗" ><!--SOUND RECORDING COPYRIGHT --> <!ENTITY cross "✗" ><!--BALLOT X --> <!ENTITY Dagger "‡" ><!--DOUBLE DAGGER --> <!ENTITY dagger "†" ><!--DAGGER --> <!ENTITY dash "‐" ><!--HYPHEN --> <!ENTITY diams "♦" ><!--BLACK DIAMOND SUIT --> <!ENTITY dlcrop "⌍" ><!--BOTTOM LEFT CROP --> <!ENTITY drcrop "⌌" ><!--BOTTOM RIGHT CROP --> <!ENTITY dtri "▿" ><!--WHITE DOWN-POINTING SMALL TRIANGLE --> <!ENTITY dtrif "▾" ><!--BLACK DOWN-POINTING SMALL TRIANGLE --> <!ENTITY emsp " " ><!--EM SPACE --> <!ENTITY emsp13 " " ><!--THREE-PER-EM SPACE --> <!ENTITY emsp14 " " ><!--FOUR-PER-EM SPACE --> <!ENTITY ensp " " ><!--EN SPACE --> <!ENTITY female "♀" ><!--FEMALE SIGN --> <!ENTITY ffilig "ffi" ><!--LATIN SMALL LIGATURE FFI --> <!ENTITY fflig "ff" ><!--LATIN SMALL LIGATURE FF --> <!ENTITY ffllig "ffl" ><!--LATIN SMALL LIGATURE FFL --> <!ENTITY filig "fi" ><!--LATIN SMALL LIGATURE FI --> <!ENTITY flat "♭" ><!--MUSIC FLAT SIGN --> <!ENTITY fllig "fl" ><!--LATIN SMALL LIGATURE FL --> <!ENTITY frac13 "⅓" ><!--VULGAR FRACTION ONE THIRD --> <!ENTITY frac15 "⅕" ><!--VULGAR FRACTION ONE FIFTH --> <!ENTITY frac16 "⅙" ><!--VULGAR FRACTION ONE SIXTH --> <!ENTITY frac23 "⅔" ><!--VULGAR FRACTION TWO THIRDS --> <!ENTITY frac25 "⅖" ><!--VULGAR FRACTION TWO FIFTHS --> <!ENTITY frac35 "⅗" ><!--VULGAR FRACTION THREE FIFTHS --> <!ENTITY frac45 "⅘" ><!--VULGAR FRACTION FOUR FIFTHS --> <!ENTITY frac56 "⅚" ><!--VULGAR FRACTION FIVE SIXTHS --> <!ENTITY hairsp " " ><!--HAIR SPACE --> <!ENTITY hearts "♥" ><!--BLACK HEART SUIT --> <!ENTITY hellip "…" ><!--HORIZONTAL ELLIPSIS --> <!ENTITY hybull "⁃" ><!--HYPHEN BULLET --> <!ENTITY incare "℅" ><!--CARE OF --> <!ENTITY ldquor "„" ><!--DOUBLE LOW-9 QUOTATION MARK --> <!ENTITY lhblk "▄" ><!--LOWER HALF BLOCK --> <!ENTITY loz "◊" ><!--LOZENGE --> <!ENTITY lozf "⧫" ><!--BLACK LOZENGE --> <!ENTITY lsquor "‚" ><!--SINGLE LOW-9 QUOTATION MARK --> <!ENTITY ltri "◃" ><!--WHITE LEFT-POINTING SMALL TRIANGLE --> <!ENTITY ltrif "◂" ><!--BLACK LEFT-POINTING SMALL TRIANGLE --> <!ENTITY male "♂" ><!--MALE SIGN --> <!ENTITY malt "✠" ><!--MALTESE CROSS --> <!ENTITY marker "▮" ><!--BLACK VERTICAL RECTANGLE --> <!ENTITY mdash "—" ><!--EM DASH --> <!ENTITY mldr "…" ><!--HORIZONTAL ELLIPSIS --> <!ENTITY natur "♮" ><!--MUSIC NATURAL SIGN --> <!ENTITY ndash "–" ><!--EN DASH --> <!ENTITY nldr "‥" ><!--TWO DOT LEADER --> <!ENTITY numsp " " ><!--FIGURE SPACE --> <!ENTITY phone "☎" ><!--BLACK TELEPHONE --> <!ENTITY puncsp " " ><!--PUNCTUATION SPACE --> <!ENTITY rdquor "”" ><!--RIGHT DOUBLE QUOTATION MARK --> <!ENTITY rect "▭" ><!--WHITE RECTANGLE --> <!ENTITY rsquor "’" ><!--RIGHT SINGLE QUOTATION MARK --> <!ENTITY rtri "▹" ><!--WHITE RIGHT-POINTING SMALL TRIANGLE --> <!ENTITY rtrif "▸" ><!--BLACK RIGHT-POINTING SMALL TRIANGLE --> <!ENTITY rx "℞" ><!--PRESCRIPTION TAKE --> <!ENTITY sext "✶" ><!--SIX POINTED BLACK STAR --> <!ENTITY sharp "♯" ><!--MUSIC SHARP SIGN --> <!ENTITY spades "♠" ><!--BLACK SPADE SUIT --> <!ENTITY squ "□" ><!--WHITE SQUARE --> <!ENTITY squf "▪" ><!--BLACK SMALL SQUARE --> <!ENTITY star "☆" ><!--WHITE STAR --> <!ENTITY starf "★" ><!--BLACK STAR --> <!ENTITY target "⌖" ><!--POSITION INDICATOR --> <!ENTITY telrec "⌕" ><!--TELEPHONE RECORDER --> <!ENTITY thinsp " " ><!--THIN SPACE --> <!ENTITY uhblk "▀" ><!--UPPER HALF BLOCK --> <!ENTITY ulcrop "⌏" ><!--TOP LEFT CROP --> <!ENTITY urcrop "⌎" ><!--TOP RIGHT CROP --> <!ENTITY utri "▵" ><!--WHITE UP-POINTING SMALL TRIANGLE --> <!ENTITY utrif "▴" ><!--BLACK UP-POINTING SMALL TRIANGLE --> <!ENTITY vellip "⋮" ><!--VERTICAL ELLIPSIS --> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isocyr2.ent����������������������������������������������������������0000644�0001757�0001757�00000006164�12753310630�015326� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isocyr2.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isocyr2.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isocyr2 PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML" "http://www.w3.org/2003/entities/iso8879/isocyr2.ent" > %isocyr2; --> <!ENTITY DJcy "Ђ" ><!--CYRILLIC CAPITAL LETTER DJE --> <!ENTITY djcy "ђ" ><!--CYRILLIC SMALL LETTER DJE --> <!ENTITY DScy "Ѕ" ><!--CYRILLIC CAPITAL LETTER DZE --> <!ENTITY dscy "ѕ" ><!--CYRILLIC SMALL LETTER DZE --> <!ENTITY DZcy "Џ" ><!--CYRILLIC CAPITAL LETTER DZHE --> <!ENTITY dzcy "џ" ><!--CYRILLIC SMALL LETTER DZHE --> <!ENTITY GJcy "Ѓ" ><!--CYRILLIC CAPITAL LETTER GJE --> <!ENTITY gjcy "ѓ" ><!--CYRILLIC SMALL LETTER GJE --> <!ENTITY Iukcy "І" ><!--CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I --> <!ENTITY iukcy "і" ><!--CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I --> <!ENTITY Jsercy "Ј" ><!--CYRILLIC CAPITAL LETTER JE --> <!ENTITY jsercy "ј" ><!--CYRILLIC SMALL LETTER JE --> <!ENTITY Jukcy "Є" ><!--CYRILLIC CAPITAL LETTER UKRAINIAN IE --> <!ENTITY jukcy "є" ><!--CYRILLIC SMALL LETTER UKRAINIAN IE --> <!ENTITY KJcy "Ќ" ><!--CYRILLIC CAPITAL LETTER KJE --> <!ENTITY kjcy "ќ" ><!--CYRILLIC SMALL LETTER KJE --> <!ENTITY LJcy "Љ" ><!--CYRILLIC CAPITAL LETTER LJE --> <!ENTITY ljcy "љ" ><!--CYRILLIC SMALL LETTER LJE --> <!ENTITY NJcy "Њ" ><!--CYRILLIC CAPITAL LETTER NJE --> <!ENTITY njcy "њ" ><!--CYRILLIC SMALL LETTER NJE --> <!ENTITY TSHcy "Ћ" ><!--CYRILLIC CAPITAL LETTER TSHE --> <!ENTITY tshcy "ћ" ><!--CYRILLIC SMALL LETTER TSHE --> <!ENTITY Ubrcy "Ў" ><!--CYRILLIC CAPITAL LETTER SHORT U --> <!ENTITY ubrcy "ў" ><!--CYRILLIC SMALL LETTER SHORT U --> <!ENTITY YIcy "Ї" ><!--CYRILLIC CAPITAL LETTER YI --> <!ENTITY yicy "ї" ><!--CYRILLIC SMALL LETTER YI --> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isogrk2.ent����������������������������������������������������������0000644�0001757�0001757�00000005547�12753310630�015320� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isogrk2.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isogrk2.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isogrk2 PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML" "http://www.w3.org/2003/entities/iso8879/isogrk2.ent" > %isogrk2; --> <!ENTITY Aacgr "Ά" ><!--GREEK CAPITAL LETTER ALPHA WITH TONOS --> <!ENTITY aacgr "ά" ><!--GREEK SMALL LETTER ALPHA WITH TONOS --> <!ENTITY Eacgr "Έ" ><!--GREEK CAPITAL LETTER EPSILON WITH TONOS --> <!ENTITY eacgr "έ" ><!--GREEK SMALL LETTER EPSILON WITH TONOS --> <!ENTITY EEacgr "Ή" ><!--GREEK CAPITAL LETTER ETA WITH TONOS --> <!ENTITY eeacgr "ή" ><!--GREEK SMALL LETTER ETA WITH TONOS --> <!ENTITY Iacgr "Ί" ><!--GREEK CAPITAL LETTER IOTA WITH TONOS --> <!ENTITY iacgr "ί" ><!--GREEK SMALL LETTER IOTA WITH TONOS --> <!ENTITY idiagr "ΐ" ><!--GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS --> <!ENTITY Idigr "Ϊ" ><!--GREEK CAPITAL LETTER IOTA WITH DIALYTIKA --> <!ENTITY idigr "ϊ" ><!--GREEK SMALL LETTER IOTA WITH DIALYTIKA --> <!ENTITY Oacgr "Ό" ><!--GREEK CAPITAL LETTER OMICRON WITH TONOS --> <!ENTITY oacgr "ό" ><!--GREEK SMALL LETTER OMICRON WITH TONOS --> <!ENTITY OHacgr "Ώ" ><!--GREEK CAPITAL LETTER OMEGA WITH TONOS --> <!ENTITY ohacgr "ώ" ><!--GREEK SMALL LETTER OMEGA WITH TONOS --> <!ENTITY Uacgr "Ύ" ><!--GREEK CAPITAL LETTER UPSILON WITH TONOS --> <!ENTITY uacgr "ύ" ><!--GREEK SMALL LETTER UPSILON WITH TONOS --> <!ENTITY udiagr "ΰ" ><!--GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS --> <!ENTITY Udigr "Ϋ" ><!--GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA --> <!ENTITY udigr "ϋ" ><!--GREEK SMALL LETTER UPSILON WITH DIALYTIKA --> ���������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isodia.ent�����������������������������������������������������������0000644�0001757�0001757�00000003732�12753310630�015202� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isodia.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isodia.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isodia PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML" "http://www.w3.org/2003/entities/iso8879/isodia.ent" > %isodia; --> <!ENTITY acute "´" ><!--ACUTE ACCENT --> <!ENTITY breve "˘" ><!--BREVE --> <!ENTITY caron "ˇ" ><!--CARON --> <!ENTITY cedil "¸" ><!--CEDILLA --> <!ENTITY circ "ˆ" ><!--MODIFIER LETTER CIRCUMFLEX ACCENT --> <!ENTITY dblac "˝" ><!--DOUBLE ACUTE ACCENT --> <!ENTITY die "¨" ><!--DIAERESIS --> <!ENTITY dot "˙" ><!--DOT ABOVE --> <!ENTITY grave "`" ><!--GRAVE ACCENT --> <!ENTITY macr "¯" ><!--MACRON --> <!ENTITY ogon "˛" ><!--OGONEK --> <!ENTITY ring "˚" ><!--RING ABOVE --> <!ENTITY tilde "˜" ><!--SMALL TILDE --> <!ENTITY uml "¨" ><!--DIAERESIS --> ��������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isoamso.ent����������������������������������������������������������0000644�0001757�0001757�00000004475�12753310630�015411� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isoamso.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isoamso.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isoamso PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML" "http://www.w3.org/2003/entities/iso8879/isoamso.ent" > %isoamso; --> <!ENTITY ang "∠" ><!--ANGLE --> <!ENTITY angmsd "∡" ><!--MEASURED ANGLE --> <!ENTITY beth "ℶ" ><!--BET SYMBOL --> <!ENTITY bprime "‵" ><!--REVERSED PRIME --> <!ENTITY comp "∁" ><!--COMPLEMENT --> <!ENTITY daleth "ℸ" ><!--DALET SYMBOL --> <!ENTITY ell "ℓ" ><!--SCRIPT SMALL L --> <!ENTITY empty "∅" ><!--EMPTY SET --> <!ENTITY gimel "ℷ" ><!--GIMEL SYMBOL --> <!ENTITY inodot "ı" ><!--LATIN SMALL LETTER DOTLESS I --> <!ENTITY jnodot "j" ><!--LATIN SMALL LETTER J --> <!ENTITY nexist "∄" ><!--THERE DOES NOT EXIST --> <!ENTITY oS "Ⓢ" ><!--CIRCLED LATIN CAPITAL LETTER S --> <!ENTITY planck "ℏ" ><!--PLANCK CONSTANT OVER TWO PI --> <!ENTITY real "ℜ" ><!--BLACK-LETTER CAPITAL R --> <!ENTITY sbsol "﹨" ><!--SMALL REVERSE SOLIDUS --> <!ENTITY vprime "′" ><!--PRIME --> <!ENTITY weierp "℘" ><!--SCRIPT CAPITAL P --> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isobox.ent�����������������������������������������������������������0000644�0001757�0001757�00000011036�12753310630�015231� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isobox.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isobox.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isobox PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML" "http://www.w3.org/2003/entities/iso8879/isobox.ent" > %isobox; --> <!ENTITY boxDL "╗" ><!--BOX DRAWINGS DOUBLE DOWN AND LEFT --> <!ENTITY boxDl "╖" ><!--BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE --> <!ENTITY boxdL "╕" ><!--BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE --> <!ENTITY boxdl "┐" ><!--BOX DRAWINGS LIGHT DOWN AND LEFT --> <!ENTITY boxDR "╔" ><!--BOX DRAWINGS DOUBLE DOWN AND RIGHT --> <!ENTITY boxDr "╓" ><!--BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE --> <!ENTITY boxdR "╒" ><!--BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE --> <!ENTITY boxdr "┌" ><!--BOX DRAWINGS LIGHT DOWN AND RIGHT --> <!ENTITY boxH "═" ><!--BOX DRAWINGS DOUBLE HORIZONTAL --> <!ENTITY boxh "─" ><!--BOX DRAWINGS LIGHT HORIZONTAL --> <!ENTITY boxHD "╦" ><!--BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL --> <!ENTITY boxHd "╤" ><!--BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE --> <!ENTITY boxhD "╥" ><!--BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE --> <!ENTITY boxhd "┬" ><!--BOX DRAWINGS LIGHT DOWN AND HORIZONTAL --> <!ENTITY boxHU "╩" ><!--BOX DRAWINGS DOUBLE UP AND HORIZONTAL --> <!ENTITY boxHu "╧" ><!--BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE --> <!ENTITY boxhU "╨" ><!--BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE --> <!ENTITY boxhu "┴" ><!--BOX DRAWINGS LIGHT UP AND HORIZONTAL --> <!ENTITY boxUL "╝" ><!--BOX DRAWINGS DOUBLE UP AND LEFT --> <!ENTITY boxUl "╜" ><!--BOX DRAWINGS UP DOUBLE AND LEFT SINGLE --> <!ENTITY boxuL "╛" ><!--BOX DRAWINGS UP SINGLE AND LEFT DOUBLE --> <!ENTITY boxul "┘" ><!--BOX DRAWINGS LIGHT UP AND LEFT --> <!ENTITY boxUR "╚" ><!--BOX DRAWINGS DOUBLE UP AND RIGHT --> <!ENTITY boxUr "╙" ><!--BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE --> <!ENTITY boxuR "╘" ><!--BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE --> <!ENTITY boxur "└" ><!--BOX DRAWINGS LIGHT UP AND RIGHT --> <!ENTITY boxV "║" ><!--BOX DRAWINGS DOUBLE VERTICAL --> <!ENTITY boxv "│" ><!--BOX DRAWINGS LIGHT VERTICAL --> <!ENTITY boxVH "╬" ><!--BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL --> <!ENTITY boxVh "╫" ><!--BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE --> <!ENTITY boxvH "╪" ><!--BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE --> <!ENTITY boxvh "┼" ><!--BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL --> <!ENTITY boxVL "╣" ><!--BOX DRAWINGS DOUBLE VERTICAL AND LEFT --> <!ENTITY boxVl "╢" ><!--BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE --> <!ENTITY boxvL "╡" ><!--BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE --> <!ENTITY boxvl "┤" ><!--BOX DRAWINGS LIGHT VERTICAL AND LEFT --> <!ENTITY boxVR "╠" ><!--BOX DRAWINGS DOUBLE VERTICAL AND RIGHT --> <!ENTITY boxVr "╟" ><!--BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE --> <!ENTITY boxvR "╞" ><!--BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE --> <!ENTITY boxvr "├" ><!--BOX DRAWINGS LIGHT VERTICAL AND RIGHT --> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/isoamsc.ent����������������������������������������������������������0000644�0001757�0001757�00000003514�12753310630�015366� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <!-- File isoamsc.ent produced by the XSL script entities.xsl from input data in unicode.xml. Please report any errors to David Carlisle via the public W3C list www-math@w3.org. The numeric character values assigned to each entity (should) match the Unicode assignments in Unicode 4.0. Entity names in this file are derived from files carrying the following notice: (C) International Organization for Standardization 1986 Permission to copy in any form is granted for use with conforming SGML systems and applications as defined in ISO 8879, provided this notice is included in all copies. --> <!-- Version: $Id$ Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML System identifier: http://www.w3.org/2003/entities/iso8879/isoamsc.ent The public identifier should always be used verbatim. The system identifier may be changed to suit local requirements. Typical invocation: <!ENTITY % isoamsc PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML" "http://www.w3.org/2003/entities/iso8879/isoamsc.ent" > %isoamsc; --> <!ENTITY dlcorn "⌞" ><!--BOTTOM LEFT CORNER --> <!ENTITY drcorn "⌟" ><!--BOTTOM RIGHT CORNER --> <!ENTITY lceil "⌈" ><!--LEFT CEILING --> <!ENTITY lfloor "⌊" ><!--LEFT FLOOR --> <!ENTITY lpargt "⦠" ><!--SPHERICAL ANGLE OPENING LEFT --> <!ENTITY rceil "⌉" ><!--RIGHT CEILING --> <!ENTITY rfloor "⌋" ><!--RIGHT FLOOR --> <!ENTITY rpargt "⦔" ><!--RIGHT ARC GREATER-THAN BRACKET --> <!ENTITY ulcorn "⌜" ><!--TOP LEFT CORNER --> <!ENTITY urcorn "⌝" ><!--TOP RIGHT CORNER --> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/ent/README���������������������������������������������������������������0000644�0001757�0001757�00000001052�12753310630�014073� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML Entity Declarations for Characters The character entity sets distributed with DocBook XML are direct copies of the official entities located at http://www.w3.org/2003/entities/ They are distributed for historical compatibility and user convenience. The DocBook Technical Committee no longer attempts to maintain these definitions and will periodically update them from the W3C site if and as they are updated there. Please direct all questions or comments about the entities to the individuals or working groups who maintain the official sets. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/htmltblx.mod�������������������������������������������������������������0000644�0001757�0001757�00000017710�12753310630�014774� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- ...................................................................... --> <!-- DocBook XML HTML Table Module V4.5 ................................... --> <!-- File htmltblx.mod .................................................... --> <!-- Copyright 2003-2006 ArborText, Inc., Norman Walsh, Sun Microsystems, Inc., and the Organization for the Advancement of Structured Information Standards (OASIS). $Id$ Permission to use, copy, modify and distribute the DocBook XML DTD and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of the DTD for any purpose. It is provided "as is" without expressed or implied warranty. If you modify the DocBook XML DTD in any way, except for declaring and referencing additional sets of general entities and declaring additional notations, label your DTD as a variant of DocBook. See the maintenance documentation for more information. Please direct all questions, bug reports, or suggestions for changes to the docbook@lists.oasis-open.org mailing list. For more information, see http://www.oasis-open.org/docbook/. --> <!-- ...................................................................... --> <!-- This module contains the definitions for elements that are isomorphic to the HTML elements. One could argue we should instead have based ourselves on the XHTML Table Module, but the HTML one is more like what browsers are likely to accept today and users are likely to use. This module has been developed for use with the DocBook V4.5 "union table model" in which elements and attlists common to both models are defined (as the union) in the CALS table module by setting various parameter entities appropriately in this file. In DTD driver files referring to this module, please use an entity declaration that uses the public identifier shown below: <!ENTITY % htmltbl PUBLIC "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN" "htmltblx.mod"> %htmltbl; See the documentation for detailed information on the parameter entity and module scheme used in DocBook, customizing DocBook and planning for interchange, and changes made since the last release of DocBook. --> <!--======================= XHTML Tables =======================================--> <!ENTITY % html.coreattrs "%common.attrib; class CDATA #IMPLIED style CDATA #IMPLIED title CDATA #IMPLIED" > <!-- Does not contain lang or dir because they are in %common.attribs --> <![%sgml.features;[ <!ENTITY % i18n ""> ]]> <!ENTITY % i18n "xml:lang NMTOKEN #IMPLIED" > <!ENTITY % events "onclick CDATA #IMPLIED ondblclick CDATA #IMPLIED onmousedown CDATA #IMPLIED onmouseup CDATA #IMPLIED onmouseover CDATA #IMPLIED onmousemove CDATA #IMPLIED onmouseout CDATA #IMPLIED onkeypress CDATA #IMPLIED onkeydown CDATA #IMPLIED onkeyup CDATA #IMPLIED" > <!ENTITY % attrs "%html.coreattrs; %i18n; %events;"> <!ENTITY % cellhalign "align (left|center|right|justify|char) #IMPLIED char CDATA #IMPLIED charoff CDATA #IMPLIED" > <!ENTITY % cellvalign "valign (top|middle|bottom|baseline) #IMPLIED" > <!--doc:A group of columns in an HTML table.--> <!ELEMENT colgroup %ho; (col)*> <!--doc:Specifications for a column in an HTML table.--> <!ELEMENT col %ho; EMPTY> <!--doc:A row in an HTML table.--> <!ELEMENT tr %ho; (th|td)+> <!--doc:A table header entry in an HTML table.--> <!ELEMENT th %ho; (%para.char.mix; | %tabentry.mix; | table | informaltable)*> <!--doc:A table ntry in an HTML table.--> <!ELEMENT td %ho; (%para.char.mix; | %tabentry.mix; | table | informaltable)*> <!ATTLIST colgroup %attrs; span CDATA "1" width CDATA #IMPLIED %cellhalign; %cellvalign; > <!ATTLIST col %attrs; span CDATA "1" width CDATA #IMPLIED %cellhalign; %cellvalign; > <!ATTLIST tr %attrs; %cellhalign; %cellvalign; bgcolor CDATA #IMPLIED > <!ATTLIST th %attrs; abbr CDATA #IMPLIED axis CDATA #IMPLIED headers IDREFS #IMPLIED scope (row|col|rowgroup|colgroup) #IMPLIED rowspan CDATA "1" colspan CDATA "1" %cellhalign; %cellvalign; nowrap (nowrap) #IMPLIED bgcolor CDATA #IMPLIED width CDATA #IMPLIED height CDATA #IMPLIED > <!ATTLIST td %attrs; abbr CDATA #IMPLIED axis CDATA #IMPLIED headers IDREFS #IMPLIED scope (row|col|rowgroup|colgroup) #IMPLIED rowspan CDATA "1" colspan CDATA "1" %cellhalign; %cellvalign; nowrap (nowrap) #IMPLIED bgcolor CDATA #IMPLIED width CDATA #IMPLIED height CDATA #IMPLIED > <!-- ====================================================== --> <!-- Set up to read in the CALS model configured to merge with the XHTML table model --> <!-- ====================================================== --> <!ENTITY % tables.role.attrib "%role.attrib;"> <!-- Add label and role attributes to table and informaltable --> <!ENTITY % bodyatt " floatstyle CDATA #IMPLIED rowheader (firstcol|norowheader) #IMPLIED %label.attrib;" > <!-- Add common attributes to Table, TGroup, TBody, THead, TFoot, Row, EntryTbl, and Entry (and InformalTable element). --> <!ENTITY % secur " %common.attrib; class CDATA #IMPLIED style CDATA #IMPLIED title CDATA #IMPLIED %i18n; %events; %tables.role.attrib;"> <!ENTITY % common.table.attribs "%bodyatt; %secur;"> <!-- Content model for Table (that also allows HTML tables) --> <!ENTITY % tbl.table.mdl "((blockinfo?, (%formalobject.title.content;), (%ndxterm.class;)*, textobject*, (graphic+|mediaobject+|tgroup+)) |(caption, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+)))"> <!ENTITY % informal.tbl.table.mdl "(textobject*, (graphic+|mediaobject+|tgroup+)) | ((col*|colgroup*), thead?, tfoot?, (tbody+|tr+))"> <!-- Attributes for Table (including HTML ones) --> <!-- N.B. rules = (none | groups | rows | cols | all) but it can't be spec'd --> <!-- that way because 'all' already occurs in a different enumeration in --> <!-- CALS tables (frame). --> <!ENTITY % tbl.table.att ' tabstyle CDATA #IMPLIED tocentry %yesorno.attvals; #IMPLIED shortentry %yesorno.attvals; #IMPLIED orient (port|land) #IMPLIED pgwide %yesorno.attvals; #IMPLIED summary CDATA #IMPLIED width CDATA #IMPLIED border CDATA #IMPLIED rules CDATA #IMPLIED cellspacing CDATA #IMPLIED cellpadding CDATA #IMPLIED align (left|center|right) #IMPLIED bgcolor CDATA #IMPLIED '> <!ENTITY % tbl.frame.attval "void|above|below|hsides|lhs|rhs|vsides|box|border| top|bottom|topbot|all|sides|none"> <!-- Allow either objects or inlines; beware of REs between elements. --> <!ENTITY % tbl.entry.mdl "%para.char.mix; | %tabentry.mix;"> <!-- thead, tfoot, and tbody are defined in both table models, so we set up parameter entities to define union models for them --> <!ENTITY % tbl.hdft.mdl "(tr+|(colspec*,row+))"> <!ENTITY % tbl.tbody.mdl "(tr+|row+)"> <!ENTITY % tbl.valign.attval "top|middle|bottom|baseline"> <!-- End of DocBook XML HTML Table Module V4.5 ............................ --> <!-- ...................................................................... --> ��������������������������������������������������������fvwm-2.6.7/doc/docbook-xml/README�������������������������������������������������������������������0000644�0001757�0001757�00000000357�12753310630�013314� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������README for the DocBook XML DTD For more information about DocBook, please see http://www.oasis-open.org/docbook/ Please send all questions, comments, concerns, and bug reports to the DocBook mailing list: docbook@lists.oasis-open.org ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fvwm-2.6.7/doc/fvwm-man.xsl�������������������������������������������������������������������������0000644�0001757�0001757�00000055560�12753310630�012504� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:ng="http://docbook.org/docbook-ng" xmlns:db="http://docbook.org/ns/docbook" exclude-result-prefixes="exsl" version='1.0'> <xsl:import href="docbook-xsl/html/docbook.xsl"/> <xsl:import href="docbook-xsl/html/manifest.xsl"/> <!-- * html-synop.xsl file is generated by build --> <xsl:import href="docbook-xsl/manpages/html-synop.xsl"/> <xsl:import href="docbook-xsl/manpages/synop.xsl"/> <xsl:import href="docbook-xsl/manpages/lists.xsl"/> <!-- we need to overrade apostroph escapment defined in other.xsl --> <xsl:import href="docbook-xsl/manpages/other.xsl"/> <xsl:output method="text" encoding="UTF-8" indent="no"/> <!-- ******************************************************************** $Id$ ******************************************************************** This file is part of the XSL DocBook Stylesheet distribution. See ../README or http://docbook.sf.net/release/xsl/current/ for copyright and other information. ******************************************************************** --> <!-- ==================================================================== --> <xsl:include href="docbook-xsl/common/refentry.xsl"/> <xsl:include href="docbook-xsl/manpages/param.xsl"/> <xsl:include href="docbook-xsl/manpages/utility.xsl"/> <xsl:include href="docbook-xsl/manpages/info.xsl"/> <xsl:include href="docbook-xsl/manpages/refentry.xsl"/> <xsl:include href="docbook-xsl/manpages/block.xsl"/> <xsl:include href="docbook-xsl/manpages/inline.xsl"/> <xsl:include href="docbook-xsl/manpages/endnotes.xsl"/> <xsl:include href="docbook-xsl/manpages/table.xsl"/> <!-- * we rename the following just to avoid using params with "man" --> <!-- * prefixes in the table.xsl stylesheet (because that stylesheet --> <!-- * can potentially be reused for more than just man output) --> <xsl:param name="tbl.font.headings" select="$man.font.table.headings"/> <xsl:param name="tbl.font.title" select="$man.font.table.title"/> <!-- ==================================================================== --> <!--xsl:variable name="arg.or.sep">|</xsl:variable--> <xsl:variable name="arg.choice.plain.close.str"></xsl:variable> <xsl:variable name="arg.rep.repeat.str"> ...</xsl:variable> <xsl:template match="section"> <xsl:apply-templates/> </xsl:template> <!-- don't escape apostrophs, but put them on the previous line if they start one --> <xsl:template name="escape.apostrophe"> <xsl:param name="content"/> <xsl:call-template name="string.subst"> <xsl:with-param name="string" select="$content"/> <xsl:with-param name="target"> '</xsl:with-param> <xsl:with-param name="replacement"> '</xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="section/title"> <xsl:text>.SH </xsl:text> <xsl:call-template name="string.upper"> <xsl:with-param name="string"> <xsl:apply-templates/> </xsl:with-param> </xsl:call-template> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="section/section/title"> <xsl:text>.SS </xsl:text> <xsl:apply-templates/> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="section/section/section/title"> <xsl:choose> <xsl:when test="parent::section//cmdsynopsis/@command = text()"> </xsl:when> <xsl:when test="parent::section//cmdsynopsis/command/text() = text()"> <!-- this is no good when there are multiple cmdsynopsis children --> <!--xsl:apply-templates select="parent::section//cmdsynopsis/*"/--> </xsl:when> <xsl:otherwise> <xsl:text>.TP </xsl:text> <xsl:text>.B </xsl:text> <xsl:apply-templates/> <xsl:text> .RS </xsl:text> <!-- We don't want .PP from following paras, this is a hack for that --> <xsl:text>.\"</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="section/section/section"> <xsl:apply-templates/> <xsl:text>.RE </xsl:text> </xsl:template> <xsl:template match="section/section/section//cmdsynopsis"> <xsl:choose> <xsl:when test="parent::section/title/text() = command/text() or @command = parent::section/title/text()"> <xsl:if test="preceding-sibling::cmdsynopsis/command/text() = command/text()"> <xsl:text>.RE </xsl:text> </xsl:if> <xsl:text>.TP </xsl:text> <xsl:apply-templates select="*"/> <xsl:text> .RS </xsl:text> <!-- We don't want .PP from following paras, this is a hack for that --> <xsl:text>.\"</xsl:text> </xsl:when> <xsl:otherwise> <xsl:apply-imports/> <!--xsl:text> </xsl:text--> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="simplelist"> <xsl:text>.nf </xsl:text> <xsl:text>.IP ""</xsl:text> <xsl:if test="not($list-indent = '')"> <xsl:text> </xsl:text> <xsl:value-of select="$list-indent"/> </xsl:if> <xsl:text> </xsl:text> <xsl:for-each select="member"> <xsl:variable name="content"> <xsl:apply-templates/> </xsl:variable> <xsl:value-of select="normalize-space($content)"/> <xsl:text> </xsl:text> </xsl:for-each> <xsl:text>.fi </xsl:text> </xsl:template> <xsl:template mode="small" match="*"> <xsl:for-each select="node()"> <xsl:text> .SM </xsl:text> <xsl:value-of select="normalize-space(.)"/> <xsl:text> </xsl:text> </xsl:for-each> </xsl:template> <xsl:template match="keysym"> <xsl:apply-templates mode="small" select="."/> </xsl:template> <xsl:template match="envar"> <xsl:apply-templates mode="italic" select="."/> </xsl:template> <!-- fvwmopt --> <xsl:template match="fvwmopt"> <xsl:text>\fI</xsl:text> <xsl:value-of select="@opt"/> <xsl:text>\fR</xsl:text> </xsl:template> <!-- * paragraphs starting with a blank line adds extra space in some * cases were we don't want it. Work around that, and make sentenses * have two spaces inbetween in the same time. --> <xsl:template name="normalize-paragraph"> <xsl:param name="content"/> <xsl:choose> <xsl:when test="starts-with($content,' ') or starts-with($content,' ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="substring($content,2)"/> </xsl:call-template> </xsl:when> <xsl:when test="contains($content,' ')"> <xsl:variable name='pcontent'> <xsl:value-of select="substring-before($content,' ')"/> </xsl:variable> <xsl:choose> <xsl:when test="contains($pcontent,'. ') or contains($pcontent,' ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="$pcontent"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$pcontent"/> </xsl:otherwise> </xsl:choose> <xsl:text> </xsl:text> <xsl:variable name="rcontent"> <xsl:value-of select="substring-after($content,' ')"/> </xsl:variable> <xsl:choose> <xsl:when test="starts-with($rcontent,' ') or starts-with($rcontent,' ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="substring($rcontent,2)"/> </xsl:call-template> </xsl:when> <xsl:when test="contains($rcontent,' ') or contains($rcontent,'. ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="$rcontent"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$rcontent"/> </xsl:otherwise> </xsl:choose> </xsl:when> <!-- spaces at the start of lines must be removed --> <xsl:when test="contains($content,' ')"> <xsl:variable name='pcontent'> <xsl:value-of select="substring-before($content,' ')"/> </xsl:variable> <xsl:choose> <xsl:when test="contains($pcontent,'. ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="$pcontent"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$pcontent"/> </xsl:otherwise> </xsl:choose> <xsl:text> </xsl:text> <xsl:variable name="rcontent"> <xsl:value-of select="substring-after($content,' ')"/> </xsl:variable> <xsl:choose> <xsl:when test="starts-with($rcontent,' ') or starts-with($rcontent,' ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="substring($rcontent,2)"/> </xsl:call-template> </xsl:when> <xsl:when test="contains($rcontent,' ') or contains($rcontent,' ') or contains($rcontent,'. ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="$rcontent"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$rcontent"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="contains($content,'. ')"> <xsl:variable name='pcontent'> <xsl:value-of select="substring-before($content,'. ')"/> </xsl:variable> <xsl:variable name='spcontent'> <xsl:value-of select="substring($pcontent,string-length($pcontent)-3)"/> </xsl:variable> <xsl:value-of select="$pcontent"/> <xsl:text>. </xsl:text> <xsl:if test="not(contains($spcontent,'.')) or contains('0123456789)',substring($spcontent,3,1))"> <xsl:text> </xsl:text> </xsl:if> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="substring-after($content,'. ')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$content"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="para[ancestor::listitem]"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content"> <xsl:apply-imports/> </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="para"> <!-- just is enough for most cases, and make less need for .RS in all places, however it reduces spaces in some less desireable places --> <xsl:text>.PP </xsl:text> <xsl:variable name="rawcontent"> <xsl:apply-templates/> </xsl:variable> <xsl:variable name="content"> <!-- normalize spaces, but not newlisnes --> <xsl:value-of select="translate(normalize-space(translate($rawcontent,' ','')),'',' ')"/> </xsl:variable> <!-- * Add some check to remove double newlines within the paragraph * but keep single newlines since there might be formatting --> <xsl:choose> <xsl:when test="contains($content,' ') or contains($content,' ') or starts-with($content,' ') or contains($content,'. ')"> <xsl:call-template name="normalize-paragraph"> <xsl:with-param name="content" select="$content"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$content"/> </xsl:otherwise> </xsl:choose> <!-- <xsl:apply-templates/> --> <xsl:text> </xsl:text> </xsl:template> <!-- fvwmref --> <xsl:template match="fvwmref"> <xsl:choose> <xsl:when test="@sect"> <xsl:text>\fB</xsl:text> <xsl:value-of select="@name"/> <xsl:text>\fR</xsl:text> </xsl:when> <xsl:when test="@opt"> <xsl:text>\fI</xsl:text> <xsl:value-of select="@opt"/> <xsl:text>\fR</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>\fB</xsl:text> <xsl:choose> <xsl:when test="@cmd"> <xsl:value-of select="@cmd"/> </xsl:when> <xsl:when test="@mod"> <xsl:value-of select="@mod"/> </xsl:when> <!-- anything else should be an error --> </xsl:choose> <xsl:text>\fR</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="section/command"> <xsl:text> </xsl:text> <xsl:text>.sp </xsl:text> <xsl:text>.RS</xsl:text> <xsl:text> </xsl:text> <xsl:value-of select="$man.indent.width"/> <xsl:text> </xsl:text> <xsl:text>.nf </xsl:text> <xsl:apply-templates/> <xsl:text> </xsl:text> <xsl:text>.fi </xsl:text> <xsl:text>.RE </xsl:text> <xsl:text>.PP </xsl:text> </xsl:template> <xsl:template name="get.fvwm.metadata"> <title> <xsl:value-of select="artheader/titleabbrev"/>
1
MAN.MANIFEST Note: No article elements found in " ... " fvwm-2.6.7/doc/Makefile.am0000644000175700017570000000051512773470550012260 00000000000000# Author: Scott Smedley docdir = @FVWM_DOCDIR@ HTML_FILES = \ index.html allCommands.html groupedCommands.html modules.html style.css EXTRA_DIST = \ fvwm.xsl fvwm-man.xsl header.html $(HTML_FILES) if FVWM_BUILD_HTMLDOC doc_DATA = \ $(HTML_FILES) endif SUBDIRS = commands images docbook-xml docbook-xsl fvwm all: $(doc_DATA) fvwm-2.6.7/doc/Makefile.in0000644000175700017570000005671513010103322012255 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Author: Scott Smedley VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/fvwm.ent.in $(srcdir)/footer.html.in README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = fvwm.ent footer.html CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(docdir)" DATA = $(doc_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @FVWM_DOCDIR@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ HTML_FILES = \ index.html allCommands.html groupedCommands.html modules.html style.css EXTRA_DIST = \ fvwm.xsl fvwm-man.xsl header.html $(HTML_FILES) @FVWM_BUILD_HTMLDOC_TRUE@doc_DATA = \ @FVWM_BUILD_HTMLDOC_TRUE@ $(HTML_FILES) SUBDIRS = commands images docbook-xml docbook-xsl fvwm all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): fvwm.ent: $(top_builddir)/config.status $(srcdir)/fvwm.ent.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ footer.html: $(top_builddir)/config.status $(srcdir)/footer.html.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-docDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-docDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-docDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-docDATA all: $(doc_DATA) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/doc/allCommands.html0000644000175700017570000003630512754306001013336 00000000000000 Fvwm: All Commands
HomeAll CommandsGrouped CommandsModulesFAQ

Allfvwm   Commands

AddButtonStyle DefaultColors HideGeometryWindow Quit TearMenuOff
AddTitleStyle DefaultColorset HilightColor QuitScreen Test
AddToDecor DefaultFont HilightColorset QuitSession TestRc
AddToFunc DefaultIcon IconFont Raise ThisWindow
AddToMenu DefaultLayers Iconify RaiseLower Title
All Delete IconPath Read TitleStyle
AnimatedMove Deschedule IgnoreModifiers Recapture UnsetEnv
Any Desk ImagePath RecaptureWindow UpdateDecor
Asterisk DesktopName Key Refresh UpdateStyles
Beep DesktopSize KeepRc RefreshWindow Wait
BorderStyle Destroy KillModule Repeat WarpToWindow
Break DestroyDecor Layer Resize WindowFont
BugOpts DestroyFunc LocalePath ResizeMaximize WindowId
BusyCursor DestroyMenu Lower ResizeMove WindowList
ButtonState DestroyMenuStyle Maximize ResizeMoveMaximize WindowsDesk
ButtonStyle DestroyModuleConfig Menu RestackTransients WindowShade
ChangeDecor DestroyStyle MenuStyle Restart WindowShadeAnimate
ChangeMenuStyle DestroyWindowStyle Module SaveQuitSession WindowStyle
CleanupColorsets Direction ModuleListenOnly SaveSession Xinerama
ClickTime Echo ModulePath ScanForWindow XineramaPrimaryScreen
Close EchoFuncDefinition ModuleSynchronous Schedule XineramaSls
ColorLimit EdgeCommand ModuleTimeout Scroll XineramaSlsScreens
ColormapFocus EdgeLeaveCommand Mouse SendToModule XineramaSlsSize
Colorset EdgeResistance Move SetAnimation XorPixmap
CopyMenuStyle EdgeScroll MoveThreshold SetEnv XorValue
Current EdgeThickness MoveToDesk ShellCmd XSync
CursorMove Emulate MoveToPage Silent XSynchronize
CursorStyle EscapeFunc MoveToScreen SnapAttraction
EwmhBaseStruts Next SnapGrid
EwmhNumberOfDesktops None State
Exec Nop Stick
ExecUseShell NoWindow StickAcrossDesks
FakeClick OpaqueMoveSize StickAcrossPages
FakeKeypress Pick Stroke
FlipFocus PipeRead StrokeFunc
Focus PixmapPath Style
FocusStyle PlaceAgain
Function PointerKey
GlobalOpts PointerWindow
GotoDesk PrintInfo
GotoDeskAndPage
GotoPage

Note: Some commands are obsolete.

???
fvwm 2.5.x
fvwm-2.6.7/doc/index.html0000644000175700017570000001102612753310630012206 00000000000000 Fvwm: Documentation
Home ⋅ All Commands ⋅ Grouped Commands ⋅ Modules ⋅ FAQ

fvwm Documentation

Getting Started General Command Reference
Developer Resources Licence


???
fvwm 2.5.x
fvwm-2.6.7/doc/footer.html.in0000644000175700017570000000010012753310630012771 00000000000000

fvwm @VERSION@@VERSIONINFO@

fvwm-2.6.7/doc/fvwm/0000755000175700017570000000000013010103346011237 500000000000000fvwm-2.6.7/doc/fvwm/windowAnatomy.xml0000644000175700017570000000263312753310630014556 00000000000000
Anatomy of a Window Fvwm puts a decorative border around most windows. This border consists of a bar on each side and a small L-shaped section on each corner. There is an additional top bar called the title-bar which is used to display the name of the window. In addition, there are up to 10 title-bar buttons. The top, side, and bottom bars are collectively known as the side-bars. The corner pieces are called the frame. With the built-in minimal configuration, dragging mouse button 1 in the frame or side-bars begins a resize operation on the window. Dragging mouse button 2 in the frame or side-bars begins a move operation. There are raise/lower operations bound to a single clicking on borders. Similarly for the window title. Up to ten title-bar buttons may exist. Their use is completely user definable. One popular configuration uses one button on the left that is used to bring up a list of window options and two buttons on the right used to iconify and maximize the window. Another popular configuration adds a close button to the right. The number of title-bar buttons used depends on which ones have mouse actions bound to them. See the command.
fvwm-2.6.7/doc/fvwm/shortcuts.xml0000644000175700017570000000233312753310630013751 00000000000000 %myents; ]>
Keyboard Shortcuts Almost all window manager operations can be performed from the keyboard so mouse-less operation should be possible. In addition to scrolling around the virtual desktop by binding the command to appropriate keys, , , , and any other command can be bound to keys. Once a command is started the pointer is moved by using the up, down, left, and right arrows, and the action is terminated by pressing return. Holding down the Shift key causes the pointer movement to go in larger steps and holding down the control key causes the pointer movement to go in smaller steps. Standard emacs and vi cursor movement controls ( n, p, f, b, and j, k, h, l ) can be used instead of the arrow keys.
fvwm-2.6.7/doc/fvwm/xinerama.xml0000644000175700017570000000615212753310630013522 00000000000000
Xinerama Support Fvwm supports the Xinerama extension of newer X servers which is similar to multi head support (multiple screens) but allows one to move windows between screens. If Xinerama support has been compiled into fvwm, it is used whenever fvwm runs on an X server that supports and uses multiple screens via Xinerama. Without this option, the whole desktop is treated as one big screen. For example, menus might pop up right between two screens. The option of the command command allows for specifying an explicit resistance value for moving windows over the screen edge between two Xinerama screens. Xinerama support can be enabled or disabled on the fly or from the configuration file with the command. Many modules and commands work nicely with Xinerama displays. Whenever a geometry in the usual X format can be supplied, fvwm's Xinerama extension allows for specifying a screen in addition to the geometry (or even the screen alone). To do this, a '@' is added to the end of the geometry string followed by either the screen number or a letter. A number is taken as the number of the Xinerama screen to be used (as configured in the X server). The letter can be one of 'g' for the global screen (the rectangle that encloses all Xinerama screens), 'p' for the primary screen (see below), 'c' for the current screen (the one that currently contains the pointer). If the X server does not support Xinerama or only one screen is used, the screen bit is ignored. * 64x300-0-0@p Xinerama support can be configured to use a primary screen. Fvwm can be configured to place new windows and icons on this screen. The primary screen is screen 0 by default but can be changed with the command. Xinerama support was designed to work out of the box with the same configuration file that would work on a single screen. It may not perform very well if the involved screens use different screen resolutions. In this situation, windows may get stuck in the portion of the whole desktop that belongs to neither screen. When this happens, the windows or icons can be retrieved with the command that can be entered in an window or with . For multi-screen implementations other than Xinerama, such as Single Logical Screen, it is possible to simulate a Xinerama configuration if the total screen seen by fvwm is made up of equal sized monitors in a rectangular grid. The commands , and are used to configure this feature.
fvwm-2.6.7/doc/fvwm/bidirText.xml0000644000175700017570000000204412753310630013650 00000000000000 %myents; ]>
Bi-directional Text Arabic and Hebrew text require bi-directional text support to be displayed correctly, this means that logical strings should be converted before their visual presentation, so left-to-right and right-to-left sub-strings are determined and reshuffled. In fvwm this is done automatically in window titles, menus, module labels and other places if the fonts used for displaying the text are of one of the charsets that require bidi (bi-directional) support. For example, this includes iso8859-6, iso8859-8 and iso10646-1 (unicode), but not other iso8859-* fonts. This bi-directional text support is done using the fribidi library compile time option, see INSTALL.fvwm.
fvwm-2.6.7/doc/fvwm/windowMovement.xml0000644000175700017570000000430112753310630014732 00000000000000 %myents; ]>
Window Movement and Placement
fvwm-2.6.7/doc/fvwm/virtualDesktop.xml0000644000175700017570000001244212753310630014735 00000000000000
The Virtual Desktop Fvwm provides multiple virtual desktops for users who wish to use them. The screen is a viewport onto a desktop which may be larger than the screen. Several distinct desktops can be accessed (concept: one desktop for each project, or one desktop for each application, when view applications are distinct). Since each desktop can be larger than the physical screen, divided into m by n pages which are each the size of the physical screen, windows which are larger than the screen or large groups of related windows can easily be viewed. The (m by n) size (i.e. number of pages) of the virtual desktops can be changed any time, by using the command. All virtual desktops must be (are) the same size. The total number of distinct desktops does not need to be specified, but is limited to approximately 4 billion total. All windows on a range of desktops can be viewed in the , a miniature view of the desktops. The pager is an accessory program, called a module, which is not essential for the window manager to operate. Windows may also be listed, along with their geometries, in a window list, accessible as a pop-up menu, or as a separate window, called the (another module). Fvwm keeps the windows on the desktop in a layered stacking order; a window in a lower layer never obscures a window in a higher layer. The layer of a window can be changed by using the command. The concept of layers is a generalization of the flag of older fvwm versions. The and options are now implemented by putting the windows in suitable layers and the previously missing option has been added. windows are windows which transcend the virtual desktop by "Sticking to the screen's glass". They always stay put on the screen. This is convenient for things like clocks and xbiffs, so you only need to run one such gadget and it always stays with you. Icons can also be made to stick to the glass, if desired. Window geometries are specified relative to the current viewport. That is: xterm -geometry +0+0 creates a window in the upper left hand corner of the visible portion of the screen. It is permissible to specify geometries which place windows on the virtual desktop, but off the screen. For example, if the visible screen is 1000 by 1000 pixels, and the desktop size is 3x3, and the current viewport is at the upper left hand corner of the desktop, invoking: xterm -geometry +1000+1000 places a window just off of the lower right hand corner of the screen. It can be found by moving the mouse to the lower right hand corner of the screen and waiting for it to scroll into view. A geometry specified as something like: xterm -geometry -5-5 places the window's lower right hand corner 5 pixels from the lower right corner of the visible portion of the screen. Not all applications support window geometries with negative offsets. Some applications place the window's upper right hand corner 5 pixels above and to the left of the upper left hand corner of the screen; others may do just plain bizarre things. There are several ways to cause a window to map onto a desktop or page other than the currently active one. The geometry technique mentioned above (specifying x,y coordinates larger than the physical screen size), however, suffers from the limitation of being interpreted relative to the current viewport: the window may not consistently appear on a specific page, unless you always invoke the application from the same page. A better way to place windows on a different page, screen or desk from the currently mapped viewport is to use the or style specification (the successors to the older style) in your config file. The placement is consistent: it does not depend on your current location on the virtual desktop. Some applications that understand standard Xt command line arguments and X resources, like xterm and xfontsel, allow the user to specify the start-up desk or page on the command line: xterm -xrm "*Desk:1" starts an xterm on desk number 1; xterm -xrm "*Page:3 2 1" starts an xterm two pages to the right and one down from the upper left hand page of desk number 3. Not all applications understand the use of these options, however. You could achieve the same results with the following lines in your .Xdefaults file: XTerm*Desk: 1 or XTerm*Page: 3 2 1
fvwm-2.6.7/doc/fvwm/expansion.xml0000644000175700017570000003670212753310630013726 00000000000000 %myents; ]>
Command Expansion Whenever an fvwm command line is executed, fvwm performs parameter expansion. A parameter is a '$' followed by a word enclosed in brackets ($[...]) or a single special character. If fvwm encounters an unquoted parameter on the command line it expands it to a string indicated by the parameter name. Unknown parameters are left untouched. Parameter expansion is performed before quoting. To get a literal '$' use "$$". If a command is prefixed with a '-' parameter expansion isn't performed. This applies to the command immediately following the '-', in which the expansion normally would have taken place. When uesed together with other prefix commands it must be added before the other prefix. Example: - exec xmessage '$[w.name]' opens an xmessage dialog with "$[w.name]" unexpanded. The longer variables may contain additional variables inside the name, which are expanded before the outer variable. In earlier versions of fvwm, some single letter variables were supported. It is deprecated now, since they cause a number of problems. You should use the longer substitutes instead. Example: # Print the current desk number, horizontal page number # and the window's class (unexpanded here, no window). $[desk.n] $[page.nx] $[w.class] Note: If the command is called outside a window context, it prints "$[w.class]" instead of the class name. It is usually not enough to have the pointer over a window to have a context window. To force using the window with the focus, the command can be used: $[desk.n] $[page.nx] $[w.class] The parameters known by fvwm are: $$ A literal '$'. $. The absolute directory of the currently Read file. Intended for creating relative and relocatable configuration trees. If used outside of any read file, the returned value is '.'. $0 to $9 The positional parameters given to a complex function (a function that has been defined with the command). "$0" is replaced with the first parameter, "$1" with the second parameter and so on. If the corresponding parameter is undefined, the "$..." is deleted from the command line. $* All positional parameters given to a complex function. This includes parameters that follow after "$9". $[n] The n:th positional parameter given to a complex function, counting from 0. If the corresponding parameter is undefined, the "$[n]" is deleted from the command line. The parameter is expanded unquoted. $[n-m] The positional parameters given to a complex function, starting with parameter n and ending with parameter m. If all the corresponding parameters are undefined, the "$[...]" is deleted from the command line. If only some of the parameters are defined, all defined parameters are expanded, and the remaining silently ignored. All parameters are expanded unquoted. $[n-] All the positional parameters given to a complex function, starting with parameter n. If all the corresponding parameters are undefined, the "$[...]" is deleted from the command line. All parameters are expanded unquoted. $[*] All the positional parameters given to a complex function. This is equivalent of $[0-]. $[version.num] The version number, like "2.6.0". $[version.info] The version info, like " (from cvs)", empty for the official releases. $[version.line] The first line printed by the --version command line option. $[vp.x] $[vp.y] $[vp.width] $[vp.height] Either coordinate or the width or height of the current viewport. $[wa.x] $[wa.y] $[wa.width] $[wa.height] Either coordinate or the width or height of the EWMH working area. $[dwa.x] $[dwa.y] $[dwa.width] $[dwa.height] Either coordinate or the width or height of the dynamic EWMH working area. $[desk.n] The current desk number. $[desk.name<n>] These parameters are replaced with the name of the desktop number <n> that is defined with the command. If no name is defined, then the default name is returned. $[desk.width] $[desk.height] The width or height of the whole desktop, i.e. the width or height multiplied by the number of pages in x or y direction. $[desk.pagesx] $[desk.pagesy] The number of total pages in a desk in x or y direction. This is the same as the values set by . $[page.nx] $[page.ny] The current page numbers, by X and Y axes, starting from 0. page is equivalent to area in the GNOME terminology. $[w.id] The window-id (expressed in hex, e.g. 0x10023c) of the window the command was called for or "$[w.id]" if no window is associated with the command. $[w.name] $[w.iconname] $[w.class] $[w.resource] $[w.visiblename] $[w.iconfile] $[w.miniiconfile] $[w.iconfile.svgopts] $[w.miniiconfile.svgopts] The window's name, icon name, resource class and resource name, visible name, file name of its icon or mini icon defined with the or style (including the full path if the file was found on disk), and (if fvwm is compiled with SVG support) the icon or mini icon svg rendering options (including the leading colon), or unexpanded "$[w.<attribute>]" string if no window is associated with the command. Note, the first 5 variables may include any kind of characters, so these variables are quoted. It means that the value is surrounded by single quote characters and any contained single quote is prefixed with a backslash. This guarantees that commands like: $[w.resource] norm/network.png work correctly, regardless of any special symbols the value may contain, like spaces and different kinds of quotes. In the case of the window's visible name, this is the value returned from the literal title of the window shown in the titlebar. Typically this will be the same as $[w.name] once expanded, although in the case of using then this is more useful a distinction, and allows for referencing the specific window by its visible name for inclusion in things like commands. $[w.x] $[w.y] $[w.width] $[w.height] Either coordinate or the width or height of the current window if it is not iconified. If no window is associated with the command or the window is iconified, the string is left as is. $[w.desk] The number of the desk on which the window is shown. If the window is sticky the current desk number is used. $[w.layer] The layer of the window. $[w.screen] The screen number the window is on. If Xinerama is not present, this returns the number 0. $[cw.x] $[cw.y] $[cw.width] $[cw.height] These work like $[w....] but return the geometry of the client part of the window. In other words: the border and title of the window is not taken into account. $[i.x], $[it.x], $[ip.x] $[i.y], $[it.y], $[ip.y] $[i.width], $[it.width], $[ip.width] $[i.height], $[it.height], $[ip.height] These work like $[w....] but return the geometry of the icon ($[i....]), the icon title ($[it....]) or the icon picture ($[ip....]). $[pointer.x] $[pointer.y] These return the position of the pointer on the screen. If the pointer is not on the screen, these variables are not expanded. $[pointer.wx] $[pointer.wy] These return the position of the pointer in the selected window. If the pointer is not on the screen, the window is iconified or no window is selected, these variables are not expanded. $[pointer.cx] $[pointer.cy] These return the position of the pointer in the client portion of the selected window. If the pointer is not on the screen, the window is shaded or iconified or no window is selected, these variables are not expanded. $[pointer.screen] The screen number the pointer is currently on. Returns 0 if Xinerama is not enabled. $[screen] The screen number fvwm is running on. Useful for setups with multiple screens. $[fg.cs<n>] $[bg.cs<n>] $[hilight.cs<n>] $[shadow.cs<n>] These parameters are replaced with the name of the foreground (fg), background (bg), hilight (hilight) or shadow (shadow) color that is defined in colorset <n> (replace <n> with zero or a positive integer). For example "$[fg.cs3]" is expanded to the name of the foreground color of colorset 3 (in rgb:rrrr/gggg/bbbb form). Please refer to the section for details about colorsets. $[schedule.last] This is replaced by the id of the last command that was scheduled with the command, even if this command was already executed. $[schedule.next] This is replaced by the id the next command used with will get (unless a different id is specified explicitly). $[cond.rc] The return code of the last conditional command. This variable is only valid inside a function and can not be used in a conditional command. Please refer to the section in the command list. $[func.context] The context character of the running command as used in the , or command. This is useful for example with: 3 FS N $$[func.context] $[gt.str] return the translation of str by looking in the current locale catalogs. If no translation is found str is returned as is. See the command. $[infostore.key] Return the value of the item stored in the InfoStore at the given key. If no key is present, the unexpanded string is returned. $[...] If the string within the braces is neither of the above, fvwm tries to find an environment variable with this name and replaces its value if one is found (e.g. "$[PAGER]" could be replaced by "more"). Otherwise the string is left as is. Some examples can be found in the description of the command.
fvwm-2.6.7/doc/fvwm/fvwm.man.xml0000644000175700017570000000656612753310630013460 00000000000000 %myents; ]>
Fvwm &version; Scott Smedley fvwm &releasedate;
Name Fvwm - F? Virtual Window Manager for X11
Gnome Compliance Fvwm attempts to be GNOME (version 1) compliant. Check http://www.gnome.org for what that may mean. To disable GNOME hints for some or all windows, the style can be used.
fvwm-2.6.7/doc/fvwm/Makefile.am0000755000175700017570000000467312773470550013253 00000000000000# Author: Scott Smedley docdir = @FVWM_DOCDIR@/fvwm XSLTPROC = @XSLTPROC@ XSL_FILE = $(srcdir)/../fvwm.xsl XSL_MAN_FILE = $(srcdir)/../fvwm-man.xsl XSL_PROFILE = $(srcdir)/../docbook-xsl/profiling/profile.xsl HTML_FILES = fvwm.man.html XML_FILES = @DOC_SECTIONS_XML_PATH@ EXTRA_DIST = @DOC_SECTIONS_XML@ $(man_MANS) sections man_MANS = fvwm.1 if FVWM_BUILD_HTMLDOC doc_DATA = $(HTML_FILES) BUILD_HTML_FILES = $(HTML_FILES) else BUILD_HTML_FILES = endif if FVWM_BUILD_MANDOC BUILD_MANS = $(man_MANS) else BUILD_MANS = endif all: $(BUILD_HTML_FILES) $(BUILD_MANS) clean: rm -f $(BUILD_HTML_FILES) $(BUILD_MANS) distclean-local: clean #%.html : $(srcdir)/%.xml $(srcdir)/../style.css # $(XSLTPROC) --path "$(top_builddir)/doc":"$(top_srcdir)/doc/commands" \ # --xinclude \ # --stringparam profile.attribute output \ # --stringparam profile.value html \ # -o $( fvwm.1 && rm fvwm.1.pre install-data-local: @rm -f "$(DESTDIR)$(mandir)/man1/fvwm2.1" @$(LN_S) fvwm.1 "$(DESTDIR)$(mandir)/man1/fvwm2.1" || \ echo "Minor warning: $(mandir)/man1/fvwm2.1 symlink was not created" fvwm-2.6.7/doc/fvwm/booleanArgs.xml0000644000175700017570000000115012753310630014143 00000000000000 %myents; ]>
Boolean Arguments A number of commands take one or several boolean arguments. These take a few equivalent inputs: "yes", "on", "true", "t" and "y" all evaluate to true while "no", "off", "false", "f" and "n" evaluate to false. Some commands allow "toggle" too which means that the feature is disabled if it is currently enabled and vice versa.
fvwm-2.6.7/doc/fvwm/conditionals.xml0000644000175700017570000004254512753310630014412 00000000000000 %myents; ]>
Conditional Commands Conditional commands are commands that are only executed if certain conditions are met. Most conditional commands work on windows, like , or . There is one conditional command, , that works on global conditions unrelated to windows. The syntax of the conditions is described below. For readability, the list of conditions is located at the end of this section.
Return Codes All commands in this section (unless specifically stated for the command) also have a return code that can be 1 (if the condition was met) or 0 (if the condition was not met). Some commands may return -1 which means that an error occurred and the return code is useless. The Break command returns -2. Additionally, the return codes of commands run in a complex functions are passed to the invoking complex function. The return code is used by the command. Please refer to the commands' description for examples. The return code can also be accessed through the variable $[cond.rc]. Non conditional commands do not modify the return code of the last conditional command. Important note: return codes are only defined inside functions created with the command and are not inherited by sub functions. To run a command without altering the return code, the command can be used.
The Ring of Windows Fvwm stores windows in a ring internally. Think of the focused window as a cursor on the current position in the ring. The command and many other commands search forwards through the ring for a matching window, and searches backwards. The windows in the ring are either ordered by creation time (if the !FPSortWindowlistByFocus, NeverFocus or MouseFocus styles are used) or by the last time they had the focus.
List of Conditional Commands
Conditions The conditions that may be given as an argument to any conditional command are a list of keywords separated by commas, enclosed in parentheses. Unless stated otherwise, conditional commands accept all the conditions listed below. Note that earlier versions of fvwm required the conditions to be separated by whitespace instead of commas and enclosed in brackets instead of parentheses (this is still supported for backward compatibility). In addition, the conditions may include one or more window names to match to. If more than one window name is given, all of them must match. The window name, icon name, class, and resource are considered when attempting to find a match. Each name may include the wildcards '*' and '?', and may consist of two or more alternatives, separated by the character '|', which acts as an OR operator. (If OR operators are used, they must not be separated by spaces from the names.) Each window name can begin with '!', which prevents command if any of the window name, icon name, class or resource match. However, '!' must not be applied to individual names in a group separated by OR operators; it may only be applied to the beginning of the group, and then it operates on the whole group. Examples: ("Netscape|konqueror|Mozilla*") 99 90 This goes to the next web browser window, no matter which of the three named web browsers is being used. ("Mozilla*", "Bookmark*") 99 90 This goes to Mozilla's bookmark manager window, ignoring other Mozilla windows and other browsers' bookmark windows. ("XTerm|rxvt", !console) This iconifies all the xterm and rxvt windows on the current page, except that the one named "console" (with the -name option to xterm) is excluded. (!"|*|") (!, !*, !) These two commands are equivalent; either one raises the next window which is not one of the named fvwm modules. Any condition can be negated by using a an exclamation mark ('!') directly in front of its name. AcceptsFocus, AnyScreen, CirculateHit, CirculateHitIcon, CirculateHitShaded, Closable, CurrentDesk, CurrentGlobalPage, CurrentGlobalPageAnyDesk, CurrentPage, CurrentPageAnyDesk, CurrentScreen, Desk, FixedPosition, FixedSize, Focused, HasHandles, HasPointer, Iconic, Iconifiable, Layer [n], Maximizable, Maximized, Overlapped, PlacedByButton n, PlacedByButton3, PlacedByFvwm, Raised, Shaded, State n, Sticky, StickyAcrossDesks, StickyAcrossPages, StickyIcon, StickyAcrossDesksIcon, StickyAcrossPagesIcon, Transient, Visible. The AcceptsFocus condition excludes all windows that do not want the input focus (the application has set the "Input hints" for the window to False) and do not use the Lenience option of the Style command. Also, all windows using the NeverFocus style are ignored. Note: !Lenience is equivalent to the deprecated option NoLenience. With the AnyScreen condition used together with any of the Current... conditions, windows that do not intersect the Xinerama screen containing the mouse pointer are considered for a match too. For example: # Focus next window on current page, # regardless of Xinerama screen (CurrentPage, AnyScreen) The CirculateHit and CirculateHitIcon options override the CirculateSkip and CirculateSkipIcon Style attributes for normal or iconic windows. The CirculateHitShaded option overrides the CirculateSkipShaded Style. All three options are turned on by default for the command. They can be turned off by specifying !CirculateHit etc. explicitly. Note: Do not confuse these conditions with the style options of the same name. Specifically, foo CirculateSkip (foo, CirculateHit) ... is not the same as foo CirculateHit ... (foo) The prior selects windows with the name foo only in the Next command. In the second example, these windows are always matched in all conditional commands. The Closable condition matches only windows that are allowed to be closed. The CurrentDesk condition matches only windows that are on the current desk. The CurrentGlobalPage condition matches only windows that are on the current page of the current desk, regardless of whether Xinerama support is enabled or not. This condition implicitly activates the CurrentDesk condition. The CurrentGlobalPageAnyDesk condition matches only windows that are on the current page of any desk, regardless of whether Xinerama support is enabled or not. The CurrentPage condition matches only windows that are on the current page of the current desk. If Xinerama support is enabled, it only matches windows that are at least partially on the Xinerama screen containing the mouse pointer. This condition implicitly activates the CurrentDesk condition. The CurrentPageAnyDesk and CurrentScreen conditions matches only windows that are on the current page of any desk. If Xinerama support is enabled, they only match windows that are at least partially on the Xinerama screen containing the mouse pointer. The Screen [n] condition matches only windows which are on the specified Xinerama screen. The Desk [n] condition matches only windows which are on the specified desk. The FixedPosition condition excludes all windows that do not have a fixed position, either set through WM hints or the Style option FixedPosition. Example: ToggleFixedGeometry ToggleFixedGeometry + I (FixedPosition) \ VariablePosition, VariableSize + I (NoMatch) FixedPosition, FixedSize The FixedSize condition excludes all windows that do not have a fixed size, either set through WM hints or the Style option FixedSize. The Focused matches on the window that currently has the keyboard focus. This is not useful for the Current command but can be used with the other conditional commands. The HasHandles condition excludes all windows that do not have resize handles. The HasPointer condition excludes all windows that do not contain the pointer. The Iconic condition matches only iconic windows. The Iconifiable condition matches only windows that are allowed to be iconified. The Layer [n] condition matches only windows on the specified layer. The optional argument of the Layer condition defaults to the layer of the focused window. The negation !Layer switches off the Layer condition. The Maximizable condition matches only windows that are allowed to be maximized. The Maximized condition matches only maximized windows. The Overlapped condition matches only windows that are overlapped by other windows on the same layer (or unmanaged windows if the option RaiseOverUnmanaged of the command is used). Note that this condition can be slow if you have many windows or if RaiseOverUnmanaged is used and the connection to the X server is slow. The PlacedByButton n condition is fulfilled if the last interactive motion of the window (with the command or as ManualPlacement) was ended by pressing mouse button n. Example: 1 T A MoveWindow MoveWindow MoveWindow + C + C (PlacedByButton 5) off + C (Match) on 0 100 + C (PlacedByButton 4) on The PlacedByButton3 condition has the same meaning as PlacedByButton 3. It remains only for backward compatibility. The PlacedByFvwm condition excludes all windows that have been placed manually or by using the user or program position hint. The Raised conditions matches only windows that are fully visible on the current viewport and not overlapped by any other window. The Shaded conditions matches only shaded windows (see command). The State n or !State n conditions match only windows with the specified integer state set (or unset). See the command for details. The argument may range from 0 to 31. The Sticky, StickyAcrossDesks and StickyAcrossPages match only windows that are currently sticky, sticky across all desks or sticky across all pages. Please refer to the options with the same name and the commands , and for details. The StickyIcon, StickyAcrossDesksIcon and StickyAcrossPagesIcon match only windows that become sticky, sticky across all desks or sticky across all pages when they are in iconified state. The Transient condition matches only windows that have the "transient" property set by the application. This it usually the case for application popup menus and dialogs. The module can be used to find out whether a specific window is transient. The Visible condition matches only windows that are at least partially visible on the current viewport and not completely overlapped by other windows.
fvwm-2.6.7/doc/fvwm/scripting.xml0000644000175700017570000000265312753310630013722 00000000000000 %myents; ]>
Scripting & Complex Functions To achieve the more complex effects, fvwm has a number of commands that improve its scripting abilities. Scripts can be read from a file with , from the output of a command with or written as a complex function with the command. For the curious, section 7 of the fvwm FAQ shows some real life applications of scripting. Please refer to the sections and for details. A word of warning: during execution of complex functions, fvwm needs to take all input from the mouse pointer (the pointer is "grabbed" in the slang of X). No other programs can receive any input from the pointer while a function is run. This can confuse some programs. For example, the xwd program refuses to make screen shots when run from a complex function. To achieve the same functionality you can use the or command instead.
fvwm-2.6.7/doc/fvwm/sections0000644000175700017570000000100112753310630012732 00000000000000authors bidirText bindings booleanArgs bugs builtinBindings colorGradients colorsets commands compilation conditionals configuration copyright cpp description environment ewmh execution expansion focus fonts fvwm.man icccm images initialization m4 menus miscCommands moduleCommands modules multiScreen mwm openLook options quoting scripting session sessionCommands shortcuts styleCommands synopsis userFunctions virtualDesktop virtualDesktopCommands windowAnatomy windowMovement windowState windowStyles xinerama fvwm-2.6.7/doc/fvwm/initialization.xml0000644000175700017570000001447012753310630014747 00000000000000
Initialization During initialization, fvwm searches for a configuration file which describes key and button bindings, and many other things. The format of these files is described later. Fvwm first searches for configuration files using the command config This looks for file config in $FVWM_USERDIR and $FVWM_DATADIR directories, as described in . If this fails more files are queried for backward compatibility. Here is the complete list of all file locations queried in the default installation (only the first found file is used): $HOME/.fvwm/config /usr/local/share/fvwm/config $HOME/.fvwm/.fvwm2rc $HOME/.fvwm2rc /usr/local/share/fvwm/.fvwm2rc /usr/local/share/fvwm/system.fvwm2rc /etc/system.fvwm2rc Please note, the last 5 locations are not guaranteed to be supported in the future. If a configuration file is not found, the left mouse button, or Help or F1 keys on the root window bring up menus and forms that can create a starting configuration file. Fvwm sets two environment variables which are inherited by its children. These are $DISPLAY which describes the display on which fvwm is running. $DISPLAY may be unix:0.0 or :0.0, which doesn't work too well when passed through ssh to another machine, so $HOSTDISPLAY is set to a network-ready description of the display. $HOSTDISPLAY always uses the TCP/IP transport protocol (even for a local connection) so $DISPLAY should be used for local connections, as it may use Unix-domain sockets, which are faster. If you want to start some applications or modules with fvwm, you can simply put app or FvwmXxx into your config, but it is not recommended; do this only if you know what you are doing. It is usually important to start applications or modules after the entire config is read, because it contains styles or module configurations which can affect window appearance and functionality. The standard way to start applications or modules on fvwm's start up is to add them to an initialization function (usually StartFunction or InitFunction). This way they are only started after fvwm finishes to read and execute config file. Fvwm has three special functions for initialization: StartFunction, which is executed on startups and restarts; InitFunction and RestartFunction, which are executed during initialization and restarts (respectively) just after StartFunction. These functions may be customized in a user's config file using the command (described later) to start up modules, xterms, or whatever you'd like to have started by fvwm. Fvwm has also a special exit function: ExitFunction, executed when exiting or restarting before actually quitting. It could be used to explicitly kill modules, etc. If fvwm is run under a session manager, functions SessionInitFunction and SessionRestartFunction are executed instead of InitFunction and RestartFunction. This helps to define the user's config file to be good for both running under a session manager and without it. Generally it is a bad idea to start xterms or other applications in "Session*" functions. Also someone can decide to start different modules while running under a session manager or not. For the similar purposes SessionExitFunction is used instead of ExitFunction. StartFunction StartFunction + I * * + I InitFunction InitFunction + I + I + I xsetroot -solid cyan + I xterm + I netscape RestartFunction RestartFunction + I SessionInitFunction SessionInitFunction + I SessionRestartFunction SessionRestartFunction + I You do not need to define all special functions if some are empty. Also note, all these special functions may be emulated now using StartFunction and ExitFunction, like this: StartFunction StartFunction + I (Init) + I * * + I (Restart) ExitFunction ExitFunction + I (Quit) Bye-bye + I MyBuggyModule + I (ToRestart)
fvwm-2.6.7/doc/fvwm/Makefile.in0000644000175700017570000005157613010103322013234 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Author: Scott Smedley VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/fvwm DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)" NROFF = nroff MANS = $(man_MANS) DATA = $(doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @FVWM_DOCDIR@/fvwm dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ XSL_FILE = $(srcdir)/../fvwm.xsl XSL_MAN_FILE = $(srcdir)/../fvwm-man.xsl XSL_PROFILE = $(srcdir)/../docbook-xsl/profiling/profile.xsl HTML_FILES = fvwm.man.html XML_FILES = @DOC_SECTIONS_XML_PATH@ EXTRA_DIST = @DOC_SECTIONS_XML@ $(man_MANS) sections man_MANS = fvwm.1 @FVWM_BUILD_HTMLDOC_TRUE@doc_DATA = $(HTML_FILES) @FVWM_BUILD_HTMLDOC_FALSE@BUILD_HTML_FILES = @FVWM_BUILD_HTMLDOC_TRUE@BUILD_HTML_FILES = $(HTML_FILES) @FVWM_BUILD_MANDOC_FALSE@BUILD_MANS = @FVWM_BUILD_MANDOC_TRUE@BUILD_MANS = $(man_MANS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/fvwm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/fvwm/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-docDATA install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-docDATA uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local \ install-docDATA install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-docDATA uninstall-man uninstall-man1 all: $(BUILD_HTML_FILES) $(BUILD_MANS) clean: rm -f $(BUILD_HTML_FILES) $(BUILD_MANS) distclean-local: clean #%.html : $(srcdir)/%.xml $(srcdir)/../style.css # $(XSLTPROC) --path "$(top_builddir)/doc":"$(top_srcdir)/doc/commands" \ # --xinclude \ # --stringparam profile.attribute output \ # --stringparam profile.value html \ # -o $( fvwm.1 && rm fvwm.1.pre install-data-local: @rm -f "$(DESTDIR)$(mandir)/man1/fvwm2.1" @$(LN_S) fvwm.1 "$(DESTDIR)$(mandir)/man1/fvwm2.1" || \ echo "Minor warning: $(mandir)/man1/fvwm2.1 symlink was not created" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/doc/fvwm/icccm.xml0000644000175700017570000000542512753310630012776 00000000000000 %myents; ]>
ICCCM Compliance Fvwm attempts to be ICCCM 2.0 compliant. Check http://tronche.com/gui/x/icccm/ for more info. In addition, ICCCM states that it should be possible for applications to receive any keystroke, which is not consistent with the keyboard shortcut approach used in fvwm and most other window managers. In particular you cannot have the same keyboard shortcuts working with your fvwm and another fvwm running within Xnest (a nested X server running in a window). The same problem exists with mouse bindings. The ICCCM states that windows possessing the property WM_HINTS(WM_HINTS): Client accepts input or input focus: False should not be given the keyboard input focus by the window manager. These windows can take the input focus by themselves, however. A number of applications set this property, and yet expect the window manager to give them the keyboard focus anyway, so fvwm provides a window style, , which allows fvwm to overlook this ICCCM rule. Even with this window style it is not guaranteed that the application accepts focus. The differences between ICCCM 1.1 and 2.0 include the ability to take over from a running ICCCM 2.0 compliant window manager; thus fvwm; vi ~/.fvwm/config; fvwm -replace resembles the command. It is not exactly the same, since killing the previously running wm may terminate your X session, if the wm was started as the last client in your .Xclients or .Xsession file. Further additions are support for client-side colormap installation (see the ICCCM for details) and the urgency hint. Clients can set this hint in the WM_HINTS property of their window and expect the window manager to attract the user's attention to the window. Fvwm has two re-definable functions for this purpose, "UrgencyFunc" and "UrgencyDoneFunc", which are executed when the flag is set/cleared. Their default definitions are: UrgencyFunc + I off + I + I + I 5p 5p UrgencyDoneFunc + I
fvwm-2.6.7/doc/fvwm/authors.xml0000644000175700017570000000101112753310630013370 00000000000000 %myents; ]>
Authors Robert Nation with help from many people, based on twm code, which was written by Tom LaStrange. After Robert Nation came Charles Hines, followed by Brady Montz. Currently fvwm is developed by a number of people on the fvwm-workers mailing list.
fvwm-2.6.7/doc/fvwm/compilation.xml0000644000175700017570000000076112753310630014234 00000000000000
Compilation Options Fvwm has a number of compile-time options. If you have trouble using a certain command or feature, check to see if support for it was included at compile time. Optional features are described in the config.h file that is generated during compilation.
fvwm-2.6.7/doc/fvwm/miscCommands.xml0000644000175700017570000000555412753310630014340 00000000000000 %myents; ]>
Miscellaneous Commands
fvwm-2.6.7/doc/fvwm/windowState.xml0000644000175700017570000000256212753310630014227 00000000000000 %myents; ]>
Window State
fvwm-2.6.7/doc/fvwm/cpp.xml0000644000175700017570000000101212753310630012466 00000000000000 %myents; ]>
CPP Preprocessing Cpp is the C-language pre-processor. fvwm offers cpp processing which mirrors the m4 pre-processing. To find out about it, re-read the section, but replace "m4" with "cpp".
fvwm-2.6.7/doc/fvwm/focus.xml0000644000175700017570000000116312753310630013032 00000000000000 %myents; ]>
Focus & Mouse Movement
fvwm-2.6.7/doc/fvwm/fvwm.10000644000175700017570000144742113010076222012237 00000000000000.\" Title: fvwm .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot_6661 .\" Date: 06-Nov-2016 .\" Manual: Fvwm 2.6.7 .\" Source: .\" .TH "FVWM" "1" "06-Nov-2016" "" "Fvwm 2.6.7" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH NAME .PP Fvwm \- F? Virtual Window Manager for X11 .SH SYNOPSIS .HP 5 \fBfvwm\fR [\fB\-c\fR\ \fIconfig\-command\fR] [\fB\-d\fR\ \fIdisplayname\fR] [\fB\-f\fR\ \fIconfig\-file\fR] [\fB\-r\fR] [\fB\-s\fR\ [\fIscreen_num\fR]] [\fB\-V\fR] [\fB\-C\fR\ \fIvisual\-class\fR | \fB\-I\fR\ \fIvisual\-id\fR] [\fB\-l\fR\ \fIcolors\fR\ [\fB\-L\fR]\ [\fB\-A\fR]\ [\fB\-S\fR]\ [\fB\-P\fR]] [\fB\-D\fR] [\fB\-h\fR] [\fB\-i\fR\ \fIclient\-id\fR] [\fB\-F\fR\ \fIstate\-file\fR] [\fB\-\-debug\-stack\-ring\fR] [\fB\-blackout\fR] .SH DESCRIPTION .PP Fvwm is a window manager for X11\. It is designed to minimize memory consumption, provide a 3D look to window frames, and a virtual desktop\. .PP Note that there are several window managers around that have "fvwm" in their name\. In the past, version 2\.x of fvwm was commonly called fvwm2 to distinguish it from the former version 1\.x (fvwm or even fvwm1)\. Since version 1\.x has been replaced by version 2\.x a long time ago we simply call version 2\.x and all versions to come, fvwm, throughout this document, and the executable program is named fvwm\. There is an fvwm offspring called fvwm95, it is mostly a patched version of fvwm\-2\.0\.43\. The main goal of fvwm95 was to supply a Windows 95 like look and feel\. Since then, fvwm has been greatly enhanced and practically all fvwm95 features can be achieved by fvwm\. .PP Fvwm provides both a large \fIvirtual desktop\fR and \fImultiple disjoint desktops\fR which can be used separately or together\. The virtual desktop allows you to pretend that your video screen is really quite large, and you can scroll around within the desktop\. The multiple disjoint desktops allow you to pretend that you really have several screens to work at, but each screen is completely unrelated to the others\. .PP Fvwm provides \fIkeyboard accelerators\fR that allow you to perform most window manager functions, including moving and resizing windows and operating the menus, using keyboard shortcuts\. .PP Fvwm has also overcome the distinction between configuration commands and action commands that most window managers make\. Configuration commands typically set fonts, colors, menu contents, and key and mouse function bindings, while action commands do things like raise and lower windows\. Fvwm makes no such distinction and allows anything to be changed at any time\. .PP Other noteworthy differences between fvwm and other X11 window managers are the introduction of the \fISloppyFocus\fR and \fINeverFocus\fR focus methods\. Focus policy can be separately specified for different window groups\. Windows using \fISloppyFocus\fR acquire focus when the pointer moves into them and retain focus until some other window acquires it\. Such windows do not lose focus when the pointer moves into the root window\. The \fINeverFocus\fR policy is provided for use with windows into which one never types (e\.g\. xclock, oclock, xbiff, xeyes, tuxeyes) \- for example, if a SloppyFocus terminal window has focus, moving the pointer over a NeverFocus decoration window does not deprive the terminal of focus\. .SH OPTIONS .PP These are the command line options that are recognized by fvwm: .PP \fB\-i\fR | \fB\-\-clientid\fR \fIid\fR .RS 4 This option is used when fvwm is started by a session manager\. Should not be used by a user\. .RE .PP \fB\-c\fR | \fB\-\-cmd\fR \fIconfig\-command\fR .RS 4 Causes fvwm to use \fIconfig\-command\fR instead of '\fBRead\fR \fIconfig\fR' (or '\fBRead\fR \fI\.fvwm2rc\fR') as its initialization command\. (Note that up to 10 \fB\-f\fR and \fB\-c\fR parameters can be given, and they are executed in the order specified\.) .sp Any module started by command line arguments is assumed to be a module that sends back config commands\. All command line modules have to quit before fvwm proceeds on to the StartFunction and setting border decorations and styles\. There is a potential deadlock if you start a module other than \fBFvwmCpp\fR/\fBFvwmM4\fR/\fBFvwmPerl\fR but there is a timeout so fvwm eventually gets going\. .sp As an example, starting the pager this way hangs fvwm until the timeout, but the following should work well: .sp .RS 4 .nf fvwm \-c "\fBAddToFunc\fR StartFunction I \fBModule\fR \fBFvwmPager\fR" .fi .RE .RE .PP \fB\-d\fR | \fB\-\-display\fR \fIdisplayname\fR .RS 4 Manage the display called \fIdisplayname\fR instead of the name obtained from the environment variable \fI$DISPLAY\fR\. .RE .PP \fB\-D\fR | \fB\-\-debug\fR .RS 4 Puts X transactions in synchronous mode, which dramatically slows things down, but guarantees that fvwm's internal error messages are correct\. Also causes fvwm to output debug messages while running\. .RE .PP \fB\-f\fR \fIconfig\-file\fR .RS 4 Causes fvwm to read \fIconfig\-file\fR instead of \fI~/\.fvwm/config\fR as its initialization file\. This is equivalent to \-c '\fBRead\fR \fIconfig\-file\fR'\. .RE .PP \fB\-h\fR | \fB\-\-help\fR .RS 4 A short usage description is printed\. .RE .PP \fB\-r\fR | \fB\-\-replace\fR .RS 4 Try to take over from a previously running wm\. This does not work unless the other wm is ICCCM2 2\.0 compliant\. .RE .PP \fB\-F\fR | \fB\-\-restore\fR \fIstate\-file\fR .RS 4 This option is used when fvwm is started by a session manager\. Should not be used by a user\. .RE .PP \fB\-s\fR | \fB\-\-single\-screen\fR [\fIscreen_num\fR] .RS 4 On a multi\-screen display, run fvwm only on the screen named in the \fI$DISPLAY\fR environment variable or provided through the \fB\-d\fR option\. The optional argument \fIscreen_num\fR should be positive or null and override the screen number\. Normally, fvwm attempts to start up on all screens of a multi\-screen display\. .RE .PP \fB\-V\fR | \fB\-\-version\fR .RS 4 Prints the version of fvwm to \fIstderr\fR\. Also prints an information about the compiled in support for readline, rplay, stroke, xpm, png, svg, GNOME hints, EWMH hints, session management, bidirectional text, multibyte characters, xinerama and Xft aa font rendering\. .RE .PP \fB\-C\fR | \fB\-\-visual\fR \fIvisual\-class\fR .RS 4 Causes fvwm to use \fIvisual\-class\fR for the window borders and menus\. \fIvisual\-class\fR can be "StaticGray", "GrayScale", "StaticColor", "PseudoColor", "TrueColor" or "DirectColor"\. .RE .PP \fB\-I\fR | \fB\-\-visualid\fR \fIid\fR .RS 4 Causes fvwm to use \fIid\fR as the visual id for the window borders and menus\. \fIid\fR can be specified as N for decimal or 0xN for hexadecimal\. See man page of xdpyinfo for a list of supported visuals\. .RE .PP \fB\-l\fR | \fB\-\-color\-limit\fR \fIlimit\fR .RS 4 Specifies a \fIlimit\fR on the colors used in image, gradient and possibly simple colors used by fvwm\. In fact, fvwm (and all the modules) uses a palette with at most \fIlimit\fR colors\. This option is only useful with screens that display 256 colors (or less) with a dynamic visual (PseudoColor, GrayScale or DirectColor)\. The default depends on your X server and how you run fvwm\. In most case this default is reasonable\. The \fB\-l\fR option should be used only if you encounter problems with colors\. By default, fvwm tries to detect large pre\-allocated palettes\. If such a palette is detected fvwm uses it and a priori the \fB\-l\fR must not be used\. Moreover, in this case the \fB\-A\fR and \fB\-S\fR options are forced\. Note that XFree\-4\.2 pre\-allocates 244 colors (if you use a driver with Render support) leaving only a few free colors\. This may lead to some color problems (and nothing can be done)\. XFree\-4\.3 or better pre\-allocate only 85 colors\. If no pre\-allocated palette is auto detected the defaults are as follow: .PP Display depth 8 (256 colors) .RS 4 .nf .IP "" 4 PseudoColor: 68 (4x4x4 color cube + 4 grey) GrayScale: 64 regular grey DirectColor: 32 (3x3x3 color cube + 5 grey) .fi .RE .PP Display depth 4 (16 colors) .RS 4 .nf .IP "" 4 PseudoColor: 10 (2x2x2 color cube + 2 grey) GrayScale: 8 regular grey DirectColor: 10 (2x2x2 color cube + 2 grey) .fi .RE .sp These defaults may change before version 2\.6\. Note that if you use a private color map (i\.e\., fvwm is started with the \fB\-C\fR or the \fB\-I\fR options), then other defaults are used\. .sp Now what to do if you encounter problems with colors? The first thing to do is to check if you really cannot run your X server with depth 15, 16 or better\. Check your X server documentation\. Note that some hardware can support two different depths on the same screen (typically depth 8 and depth 24)\. If depth 8 is the default, you can force fvwm to use the best depth by using the \fB\-C\fR option with \fITrueColor\fR as argument\. So now we assume that you are forced to run in depth 8 with a dynamic visual because your hardware/driver cannot do better or because you need to use an application which needs to run under this mode (e\.g\., because this application needs read\-write colors)\. What it should be understand is that you have only 256 colors and that all the applications which use the default color map must share these colors\. The main problem is that there are applications which use a lot or even all the colors\. If you use such application you may have no more free colors and some applications (which used only a few colors) may fail to start or are unusable\. There are three things that can be done (and fvwm does not really play a particular role, all applications are concerned)\. The first is to run the applications which waste your (default) color map with a private color map\. For example, run netscape with the \-install option, run KDE or QT applications with the \-\-cmap option, use the \fB\-C\fR option for fvwm\. The disadvantage of this method is that it is visually disturbing (see the \fBColormapFocus\fR command for a better control of the color maps switching)\. The second method is to limit the number of colors that the applications use\. Again, some applications have options to specify a given color limit\. With fvwm you may try various values, 61 (a special "visual" palette), 56 (a 4x4x3 color cube plus 6 grey), 29 (a 3x3x3 color cube plus 2 grey), 10 or 9\. Also, you may use the \fB\-L\fR option\. However, limiting the number of colors is not the definitive solution\. The definitive solution is to try cause applications which use a lot of colors use the same colors\. This is a difficult task as there are no formal standards for this goal\. However, some toolkits as QT and GTK use color cubes as palettes\. So, the idea is to configure your applications/toolkits to all use the same color cube\. Moreover, you can use the colors in this color cube in your X resources configuration files and/or as arguments to colors options\. Fvwm can use any color cube of the form RxGxB with 2 <= R <= 6, R = G, R\-1 =< B <= R and B >= 2\. To get an RxGxB color cube give an argument to \fB\-l\fR an integer c >= R*G*B and < (R+1)*(G+1)*B if B=R and < R*G*(B+1) if B < R (and different from 61)\. If c > R*G*B, then some grey may be added to the color cube\. You can use the \fBPrintInfo\fR \fIColors\fR [\fI1\fR] command to get information on your fvwm colors setting\. In particular, this command prints the palette used by fvwm in rgb format (the last integer gives the number of times fvwm has allocated the colors)\. .RE .PP \fB\-L\fR | \fB\-\-strict\-color\-limit\fR .RS 4 If the screen displays 256 colors (or less) and has a dynamic visual, causes fvwm to use its palette for all the colors\. By default, the palette is used only for images and gradients\. .RE .PP \fB\-P\fR | \fB\-\-visual\-palette\fR .RS 4 If the screen displays 256 colors (or less) and has a dynamic visual, this option causes fvwm to use a palette designed for limiting the "visual" color distance between the points of the palette\. Moreover, for better color sharing, if possible colors with a name in the X rgb data base are used for defining the colors (with the hope that applications and images prefer to use named colors)\. If the \fB\-l\fR option is not used this palette has 61 colors\. This palette is also automatically selected if 61 or 9 is used as argument to the \fB\-l\fR option\. .RE .PP \fB\-A\fR | \fB\-\-allocate\-palette\fR .RS 4 If the screen displays 256 colors (or less) and has a dynamic visual this option causes fvwm to allocate all the colors of its palette at start up for reserving these colors for future use\. This option forces the \fB\-static\-palette\fR option\. By default, fvwm allocates (reserves) a color in its palette only if it needs this color\. .RE .PP \fB\-S\fR | \fB\-\-static\-palette\fR .RS 4 If the screen displays 256 colors (or less) and has a dynamic visual this option causes fvwm to never free the colors in its palette\. By default, when fvwm does not need a color any more it frees this color so that a new color can be used\. This option may speed up image loading and save a few bits of memory\. .RE .PP \fB\-blackout\fR .RS 4 This option is provided for backward compatibility only\. Blacking out the screen during startup is not necessary (and doesn't work) anymore\. This option will be removed in the future\. .RE .PP \fB\-\-debug\-stack\-ring\fR .RS 4 Enables stack ring debugging\. This option is only intended for internal debugging and should only be used by developers\. .RE .SH ANATOMY OF A WINDOW .PP Fvwm puts a decorative border around most windows\. This border consists of a bar on each side and a small L\-shaped section on each corner\. There is an additional top bar called the title\-bar which is used to display the name of the window\. In addition, there are up to 10 title\-bar buttons\. The top, side, and bottom bars are collectively known as the side\-bars\. The corner pieces are called the frame\. .PP With the built\-in minimal configuration, dragging mouse button 1 in the frame or side\-bars begins a resize operation on the window\. Dragging mouse button 2 in the frame or side\-bars begins a move operation\. There are raise/lower operations bound to a single clicking on borders\. Similarly for the window title\. .PP Up to ten title\-bar buttons may exist\. Their use is completely user definable\. One popular configuration uses one button on the left that is used to bring up a list of window options and two buttons on the right used to iconify and maximize the window\. Another popular configuration adds a close button to the right\. The number of title\-bar buttons used depends on which ones have mouse actions bound to them\. See the \fBMouse\fR command\. .SH THE VIRTUAL DESKTOP .PP Fvwm provides multiple virtual desktops for users who wish to use them\. The screen is a viewport onto a \fIdesktop\fR which may be larger than the screen\. Several distinct desktops can be accessed (concept: one desktop for each project, or one desktop for each application, when view applications are distinct)\. Since each desktop can be larger than the physical screen, divided into m by n \fIpages\fR which are each the size of the physical screen, windows which are larger than the screen or large groups of related windows can easily be viewed\. .PP The (m by n) size (i\.e\. number of pages) of the virtual desktops can be changed any time, by using the \fBDesktopSize\fR command\. All virtual desktops must be (are) the same size\. The total number of distinct desktops does not need to be specified, but is limited to approximately 4 billion total\. All windows on a range of desktops can be viewed in the \fBFvwmPager\fR, a miniature view of the desktops\. The pager is an accessory program, called a module, which is not essential for the window manager to operate\. Windows may also be listed, along with their geometries, in a window list, accessible as a pop\-up menu, or as a separate window, called the \fBFvwmWinList\fR (another module)\. .PP Fvwm keeps the windows on the desktop in a layered stacking order; a window in a lower layer never obscures a window in a higher layer\. The layer of a window can be changed by using the \fBLayer\fR command\. The concept of layers is a generalization of the \fIStaysOnTop\fR flag of older fvwm versions\. The \fIStaysOnTop\fR and \fIStaysPut\fR \fBStyle\fR options are now implemented by putting the windows in suitable layers and the previously missing \fIStaysOnBottom\fR \fBStyle\fR option has been added\. .PP \fISticky\fR windows are windows which transcend the virtual desktop by "Sticking to the screen's glass"\. They always stay put on the screen\. This is convenient for things like clocks and xbiffs, so you only need to run one such gadget and it always stays with you\. Icons can also be made to stick to the glass, if desired\. .PP Window geometries are specified relative to the current viewport\. That is: .sp .RS 4 .nf xterm \-geometry +0+0 .fi .RE .PP .PP creates a window in the upper left hand corner of the visible portion of the screen\. It is permissible to specify geometries which place windows on the virtual desktop, but off the screen\. For example, if the visible screen is 1000 by 1000 pixels, and the desktop size is 3x3, and the current viewport is at the upper left hand corner of the desktop, invoking: .sp .RS 4 .nf xterm \-geometry +1000+1000 .fi .RE .PP .PP places a window just off of the lower right hand corner of the screen\. It can be found by moving the mouse to the lower right hand corner of the screen and waiting for it to scroll into view\. A geometry specified as something like: .sp .RS 4 .nf xterm \-geometry \-5\-5 .fi .RE .PP .PP places the window's lower right hand corner 5 pixels from the lower right corner of the visible portion of the screen\. Not all applications support window geometries with negative offsets\. Some applications place the window's upper right hand corner 5 pixels above and to the left of the upper left hand corner of the screen; others may do just plain bizarre things\. .PP There are several ways to cause a window to map onto a desktop or page other than the currently active one\. The geometry technique mentioned above (specifying x,y coordinates larger than the physical screen size), however, suffers from the limitation of being interpreted relative to the current viewport: the window may not consistently appear on a specific page, unless you always invoke the application from the same page\. .PP A better way to place windows on a different page, screen or desk from the currently mapped viewport is to use the \fIStartsOnPage\fR or \fIStartsOnScreen\fR style specification (the successors to the older \fIStartsOnDesk\fR style) in your \fIconfig\fR file\. The placement is consistent: it does not depend on your current location on the virtual desktop\. .PP Some applications that understand standard Xt command line arguments and X resources, like xterm and xfontsel, allow the user to specify the start\-up desk or page on the command line: .sp .RS 4 .nf xterm \-xrm "*Desk:1" .fi .RE .PP .PP starts an xterm on desk number 1; .sp .RS 4 .nf xterm \-xrm "*Page:3 2 1" .fi .RE .PP .PP starts an xterm two pages to the right and one down from the upper left hand page of desk number 3\. Not all applications understand the use of these options, however\. You could achieve the same results with the following lines in your \fI\.Xdefaults\fR file: .sp .RS 4 .nf XTerm*Desk: 1 .fi .RE .PP .PP or .sp .RS 4 .nf XTerm*Page: 3 2 1 .fi .RE .PP .SH USE ON MULTI\-SCREEN DISPLAYS .PP If the \fB\-s\fR command line argument is not given, fvwm automatically starts up on every screen on the specified display\. After fvwm starts each screen is treated independently\. Restarts of fvwm need to be performed separately on each screen\. The use of .sp .RS 4 .nf \fBEdgeScroll\fR 0 0 .fi .RE .PP is strongly recommended for multi\-screen displays\. You may need to quit on each screen to quit from the X session completely\. This is not to be confused with Xinerama support\. .SH XINERAMA SUPPORT .PP Fvwm supports the Xinerama extension of newer X servers which is similar to multi head support (multiple screens) but allows one to move windows between screens\. If Xinerama support has been compiled into fvwm, it is used whenever fvwm runs on an X server that supports and uses multiple screens via Xinerama\. Without this option, the whole desktop is treated as one big screen\. For example, menus might pop up right between two screens\. The \fIEdgeResistance\fR option of the \fBStyle\fR command command allows for specifying an explicit resistance value for moving windows over the screen edge between two Xinerama screens\. Xinerama support can be enabled or disabled on the fly or from the configuration file with the \fBXinerama\fR command\. Many modules and commands work nicely with Xinerama displays\. .PP Whenever a geometry in the usual X format can be supplied, fvwm's Xinerama extension allows for specifying a screen in addition to the geometry (or even the screen alone)\. To do this, a '@' is added to the end of the geometry string followed by either the screen number or a letter\. A number is taken as the number of the Xinerama screen to be used (as configured in the X server)\. The letter can be one of 'g' for the global screen (the rectangle that encloses all Xinerama screens), 'p' for the primary screen (see below), 'c' for the current screen (the one that currently contains the pointer)\. If the X server does not support Xinerama or only one screen is used, the screen bit is ignored\. .sp .RS 4 .nf \fBStyle\fR * \fIIconBox\fR 64x300\-0\-0@p .fi .RE .PP Xinerama support can be configured to use a primary screen\. Fvwm can be configured to place new windows and icons on this screen\. The primary screen is screen 0 by default but can be changed with the \fBXineramaPrimaryScreen\fR command\. .PP Xinerama support was designed to work out of the box with the same configuration file that would work on a single screen\. It may not perform very well if the involved screens use different screen resolutions\. In this situation, windows may get stuck in the portion of the whole desktop that belongs to neither screen\. When this happens, the windows or icons can be retrieved with the command .sp .RS 4 .nf \fBAll\fR \fBMoveToScreen\fR .fi .RE .PP that can be entered in an \fBFvwmConsole\fR window or with \fBFvwmCommand\fR\. .PP For multi\-screen implementations other than Xinerama, such as Single Logical Screen, it is possible to simulate a Xinerama configuration if the total screen seen by fvwm is made up of equal sized monitors in a rectangular grid\. The commands \fBXineramaSls\fR, \fBXineramaSlsSize\fR and \fBXineramaSlsScreens\fR are used to configure this feature\. .SH INITIALIZATION .PP During initialization, fvwm searches for a configuration file which describes key and button bindings, and many other things\. The format of these files is described later\. Fvwm first searches for configuration files using the command .sp .RS 4 .nf \fBRead\fR \fIconfig\fR .fi .RE .PP This looks for file \fIconfig\fR in \fI$FVWM_USERDIR\fR and \fI$FVWM_DATADIR\fR directories, as described in \fBRead\fR\. If this fails more files are queried for backward compatibility\. Here is the complete list of all file locations queried in the default installation (only the first found file is used): .nf .IP "" 4 \fI$HOME\fR/\.fvwm/config /usr/local/share/fvwm/config .fi .nf .IP "" 4 \fI$HOME\fR/\.fvwm/\.fvwm2rc \fI$HOME\fR/\.fvwm2rc /usr/local/share/fvwm/\.fvwm2rc /usr/local/share/fvwm/system\.fvwm2rc /etc/system\.fvwm2rc .fi .PP Please note, the last 5 locations are not guaranteed to be supported in the future\. .PP If a configuration file is not found, the left mouse button, or .SM Help or .SM F1 keys on the root window bring up menus and forms that can create a starting configuration file\. .PP Fvwm sets two environment variables which are inherited by its children\. These are \fI$DISPLAY\fR which describes the display on which fvwm is running\. \fI$DISPLAY\fR may be \fIunix:0\.0\fR or \fI:0\.0\fR, which doesn't work too well when passed through ssh to another machine, so \fI$HOSTDISPLAY\fR is set to a network\-ready description of the display\. \fI$HOSTDISPLAY\fR always uses the TCP/IP transport protocol (even for a local connection) so \fI$DISPLAY\fR should be used for local connections, as it may use Unix\-domain sockets, which are faster\. .PP If you want to start some applications or modules with fvwm, you can simply put .sp .RS 4 .nf \fBExec\fR app .fi .RE .PP or .sp .RS 4 .nf \fBModule\fR FvwmXxx .fi .RE .PP into your \fIconfig\fR, but it is not recommended; do this only if you know what you are doing\. It is usually important to start applications or modules after the entire config is read, because it contains styles or module configurations which can affect window appearance and functionality\. .PP The standard way to start applications or modules on fvwm's start up is to add them to an initialization function (usually \fBStartFunction\fR or \fBInitFunction\fR)\. This way they are only started after fvwm finishes to read and execute \fIconfig\fR file\. .PP Fvwm has three special functions for initialization: \fBStartFunction\fR, which is executed on startups and restarts; \fBInitFunction\fR and \fBRestartFunction\fR, which are executed during initialization and restarts (respectively) just after StartFunction\. These functions may be customized in a user's \fIconfig\fR file using the \fBAddToFunc\fR command (described later) to start up modules, xterms, or whatever you'd like to have started by fvwm\. .PP Fvwm has also a special exit function: \fBExitFunction\fR, executed when exiting or restarting before actually quitting\. It could be used to explicitly kill modules, etc\. .PP If fvwm is run under a session manager, functions \fBSessionInitFunction\fR and \fBSessionRestartFunction\fR are executed instead of InitFunction and RestartFunction\. This helps to define the user's \fIconfig\fR file to be good for both running under a session manager and without it\. Generally it is a bad idea to start xterms or other applications in "Session*" functions\. Also someone can decide to start different modules while running under a session manager or not\. For the similar purposes \fBSessionExitFunction\fR is used instead of ExitFunction\. .sp .RS 4 .nf \fBDestroyFunc\fR StartFunction \fBAddToFunc\fR StartFunction + I \fBModule\fR \fBFvwmPager\fR * * + I \fBModule\fR \fBFvwmButtons\fR \fBDestroyFunc\fR InitFunction \fBAddToFunc\fR InitFunction + I \fBModule\fR \fBFvwmBanner\fR + I \fBModule\fR \fBFvwmTaskBar\fR + I \fBExec\fR xsetroot \-solid cyan + I \fBExec\fR xterm + I \fBExec\fR netscape \fBDestroyFunc\fR RestartFunction \fBAddToFunc\fR RestartFunction + I \fBModule\fR \fBFvwmTaskBar\fR \fBDestroyFunc\fR SessionInitFunction \fBAddToFunc\fR SessionInitFunction + I \fBModule\fR \fBFvwmBanner\fR \fBDestroyFunc\fR SessionRestartFunction \fBAddToFunc\fR SessionRestartFunction + I \fBNop\fR .fi .RE .PP You do not need to define all special functions if some are empty\. Also note, all these special functions may be emulated now using \fBStartFunction\fR and \fBExitFunction,\fR like this: .sp .RS 4 .nf \fBDestroyFunc\fR StartFunction \fBAddToFunc\fR StartFunction + I \fBTest\fR (Init) \fBModule\fR \fBFvwmBanner\fR + I \fBModule\fR \fBFvwmPager\fR * * + I \fBTest\fR (Restart) \fBBeep\fR \fBDestroyFunc\fR ExitFunction \fBAddToFunc\fR ExitFunction + I \fBTest\fR (Quit) \fBEcho\fR Bye\-bye + I \fBKillModule\fR MyBuggyModule + I \fBTest\fR (ToRestart) \fBBeep\fR .fi .RE .SH COMPILATION OPTIONS .PP Fvwm has a number of compile\-time options\. If you have trouble using a certain command or feature, check to see if support for it was included at compile time\. Optional features are described in the \fIconfig\.h\fR file that is generated during compilation\. .SH ICONS AND IMAGES .PP Fvwm can load \fB\.xbm,\fR \fB\.xpm,\fR \fB\.png\fR and \fB\.svg\fR images\. \fBXBM\fR images are monochrome\. Fvwm can always display \fBXBM\fR files\. \fBXPM\fR and \fBPNG\fR formats are color images\. SVG is a vector graphics image format\. Compile\-time options determine whether fvwm can display \fBXPM\fR, \fBPNG\fR or \fBSVG\fR icons and images\. See the \fIINSTALL\.fvwm\fR file for more information\. .PP The related \fBSHAPE\fR compile\-time option can make fvwm display spiffy shaped icons\. .SS SVG rendering options .PP SVG images are generated from (XML) text files\. A really simple SVG file might look something like this: .sp .RS 4 .nf .fi .RE .PP By default, SVG images are rendered as the image creator intended them to\. But since SVG is a vector graphics format, the images can be rendered at any chosen size and rotation, e\.g\. making it possible to use the same icon file rendered at diffrent sizes for the \fIIcon\fR and \fIMiniIcon\fR styles\. .PP The rendering options are specified as a string appended to the SVG filename as follows: .HP 1 \fI\fIimage\.svg\fR\fR:[!] [(1)\ \fIsize\fR] [(2)\ \fIposition\fR]\ [(3)\ \fIrotation\fR]\ [(4)\ \fIscale\fR] ... .HP 4 (1) [\-]\fIwidth\fR{x}[\-]\fIheight\fR .sp -1n .HP 4 (2) {\- | +}\fIxpos\fR{\- | +}\fIypos\fR .sp -1n .HP 4 (3) @[\-]\fIangle\fR .sp -1n .HP 4 (4) {* | /}[\-]\fIfactor\fR[x | y] .PP The option string always starts with a colon (':') to separate it from the filename\. An empty option string can skip this colon, but it might still be a good idea to include it to prevent ambiguity if the filename contains any colon\. .sp .RS 4 .nf filename_without_colon\.svg filename:with:colon\.svg: .fi .RE .PP An exclamation point ('!') transposes the entire final image (including the rendering area), i\.e\. all the horizontal and all the vertical coordinates are swapped with each other\. .sp .RS 4 .nf image\.svg:! .fi .RE .PP \fIwidth\fR and \fIheight\fR specifies the dimensions of the rendering area in pixels, i\.e\. the dimensions of the resulting image\. The actual image is fitted to fill the entire rendering area\. .sp .RS 4 .nf image\.svg:60x60 .fi .RE .PP Use a \fIwidth\fR or \fIheight\fR value of 0 to keep the aspect ratio\. .sp .RS 4 .nf image\.svg:0x60 image\.svg:60x0 .fi .RE .PP A '\-' before \fIwidth\fR mirrors the rendering area horizontally\. .sp .RS 4 .nf image\.svg:\-0x0 .fi .RE .PP A '\-' before \fIheight\fR mirrors the rendering area vertically\. .sp .RS 4 .nf image\.svg:0x\-0 .fi .RE .PP \fIxpos\fR and \fIypos\fR specifies a translation of the image in pixels\. A positive \fIxpos\fR value moves the image to the right\. A positive \fIypos\fR value moves it down\. Moving it partially outside of the rendering area results in a cropped image\. .sp .RS 4 .nf image\.svg:\-30\-0 image\.svg:\-0+10 image\.svg:\-30+10 .fi .RE .PP \fIangle\fR specifies a rotation around the actual image center in degrees\. This might result in a cropped image\. A positive value rotates the image clockwise\. Floating point values are recognized\. .sp .RS 4 .nf image\.svg:@180 image\.svg:@\-90 image\.svg:@30 image\.svg:@57\.3 .fi .RE .PP \fIfactor\fR specifes a scaling of the actual image (not the rendering area)\. Scaling it up results in a cropped image\. Floting point values are recognized\. Division by zero is ignored\. If \fIfactor\fR is directly followed by a 'x' or a 'y', the scaling is horizontal or vertical respectively\. Otherwise the scaling is uniform\. .sp .RS 4 .nf image\.svg:*2 image\.svg:/2 image\.svg:/3x image\.svg:/2y .fi .RE .PP Scaling down a translated or rotated image can prevent cropping\. .sp .RS 4 .nf image\.svg:@30*0\.6 .fi .RE .PP Repeated usage of translation, rotation, and scaling is allowed\. Translation and rotation are additive\. Scaling is multiplicative\. .sp .RS 4 .nf image\.svg:*2/3 image\.svg:/3x/2y .fi .RE .PP When combining affine transformations, the scaling is always done first, then the rotation, and finally the translation\. .sp .RS 4 .nf image\.svg:\-30+10@30/3x/2y .fi .RE .PP Use a negative scale \fIfactor\fR to mirror the actual image\. .sp .RS 4 .nf image\.svg:\-30+10@30/\-3x/2y .fi .RE .PP Mirroring of the rendering area is done after any scaling, rotation or translation of the image\. .sp .RS 4 .nf image\.svg:\-0x0\-30+10@30/3x/2y .fi .RE .PP Transposing is done last of all, after everything else\. .sp .RS 4 .nf image\.svg:!\-0x0\-30+10@30/3x/2y .fi .RE .SH MODULES .PP A module is a separate program which runs as a separate Unix process but transmits commands to fvwm to execute\. Users can write their own modules to do any weird or bizarre manipulations without bloating or affecting the integrity of fvwm itself\. .PP Modules must be spawned by fvwm so that it can set up two pipes for fvwm and the module to communicate with\. The pipes are already open for the module when it starts and the file descriptors for the pipes are provided as command line arguments\. .PP Modules can be spawned by fvwm at any time during the X session by use of the \fBModule\fR command\. Modules can exist for the duration of the X session, or can perform a single task and exit\. If the module is still active when fvwm is told to quit, then fvwm closes the communication pipes and waits to receive a SIGCHLD from the module, indicating that it has detected the pipe closure and has exited\. If modules fail to detect the pipe closure fvwm exits after approximately 30 seconds anyway\. The number of simultaneously executing modules is limited by the operating system's maximum number of simultaneously open files, usually between 60 and 256\. .PP Modules simply transmit commands to the fvwm command engine\. Commands are formatted just as in the case of a mouse binding in the \fIconfig\fR setup file\. Certain auxiliary information is also transmitted, as in the sample module \fBFvwmButtons\fR\. .PP Please refer to the \fBModule Commands\fR section for details\. .SH ICCCM COMPLIANCE .PP Fvwm attempts to be ICCCM 2\.0 compliant\. Check \fIhttp://tronche\.com/gui/x/icccm/\fR for more info\. In addition, ICCCM states that it should be possible for applications to receive any keystroke, which is not consistent with the keyboard shortcut approach used in fvwm and most other window managers\. In particular you cannot have the same keyboard shortcuts working with your fvwm and another fvwm running within Xnest (a nested X server running in a window)\. The same problem exists with mouse bindings\. .PP The ICCCM states that windows possessing the property .sp .RS 4 .nf WM_HINTS(WM_HINTS): Client accepts input or input focus: False .fi .RE .PP should not be given the keyboard input focus by the window manager\. These windows can take the input focus by themselves, however\. A number of applications set this property, and yet expect the window manager to give them the keyboard focus anyway, so fvwm provides a window style, \fILenience\fR, which allows fvwm to overlook this ICCCM rule\. Even with this window style it is not guaranteed that the application accepts focus\. .PP The differences between ICCCM 1\.1 and 2\.0 include the ability to take over from a running ICCCM 2\.0 compliant window manager; thus .sp .RS 4 .nf fvwm; vi ~/\.fvwm/config; fvwm \-replace .fi .RE .PP .PP resembles the \fBRestart\fR command\. It is not exactly the same, since killing the previously running wm may terminate your X session, if the wm was started as the last client in your \fI\.Xclients\fR or \fI\.Xsession\fR file\. .PP Further additions are support for client\-side colormap installation (see the ICCCM for details) and the urgency hint\. Clients can set this hint in the WM_HINTS property of their window and expect the window manager to attract the user's attention to the window\. Fvwm has two re\-definable functions for this purpose, "UrgencyFunc" and "UrgencyDoneFunc", which are executed when the flag is set/cleared\. Their default definitions are: .sp .RS 4 .nf \fBAddToFunc\fR UrgencyFunc + I \fBIconify\fR off + I \fBFlipFocus\fR + I \fBRaise\fR + I \fBWarpToWindow !raise\fR 5p 5p \fBAddToFunc\fR UrgencyDoneFunc + I \fBNop\fR .fi .RE .SH GNOME COMPLIANCE .PP Fvwm attempts to be GNOME (version 1) compliant\. Check \fIhttp://www\.gnome\.org\fR for what that may mean\. To disable GNOME hints for some or all windows, the \fIGNOMEIgnoreHints\fR style can be used\. .SH EXTENDED WINDOW MANAGER HINTS .PP Fvwm attempts to respect the extended window manager hints (ewmh or EWMH for short) specification: \fIhttp://www\.freedesktop\.org/wiki/Standards_2fwm_2dspec\fR and some extensions of this specification\. This allows fvwm to work with KDE version >= 2, GNOME version 2 and other applications which respect this specification (any application based on \fIGTK+\fR version 2)\. Applications which respect this specification are called ewmh compliant applications\. .PP This support is configurable with styles and commands\. These styles and commands have EWMH as the prefix (so you can find them easily in this man page)\. .PP There is a new Context 'D' for the \fBKey\fR, \fBPointerKey\fR, \fBMouse\fR and \fBStroke\fR commands\. This context is for desktop applications (such as kdesktop and Nautilus desktop)\. .PP When a compliant taskbar asks fvwm to activate a window (typically when you click on a button which represents a window in such a taskbar), then fvwm calls the complex function \fBEWMHActivateWindowFunc\fR which by default is Iconify Off, Focus and Raise\. You can redefine this function\. For example: .sp .RS 4 .nf \fBDestroyFunc\fR EWMHActivateWindowFunc \fBAddToFunc\fR EWMHActivateWindowFunc I \fBIconify\fR Off + I \fBFocus\fR + I \fBRaise\fR + I \fBWarpToWindow\fR 50 50 .fi .RE .PP additionally warps the pointer to the center of the window\. .PP The EWMH specification introduces the notion of Working Area\. Without ewmh support the Working Area is the full visible screen (or all your screens if you have a multi head setup and you use Xinerama)\. However, compliant applications (such as a panel) can ask to reserve space at the edge of the screen\. If this is the case, the Working Area is your full visible screen minus these reserved spaces\. If a panel can be hidden by clicking on a button the Working Area does not change (as you can unhide the panel at any time), but the Dynamic Working Area is updated: the space reserved by the panel is removed (and added again if you pop up the panel)\. The Dynamic Working Area may be used when fvwm places or maximizes a window\. To know if an application reserves space you can type "xprop | grep _NET_WM_STRUT" in a terminal and select the application\. If four numbers appear then these numbers define the reserved space as explained in the \fBEwmhBaseStruts\fR command\. .SH MWM COMPATIBILITY .PP Fvwm provides options to emulate Motif Window Manager (Mwm) as well as possible\. Please refer to the \fBEmulate\fR command as well as to the Mwm specific options of the \fBStyle\fR and \fBMenuStyle\fR commands for details\. .SH OPEN LOOK AND XVIEW COMPATIBILITY .PP Fvwm supports all the Open Look decoration hints (except pushpins)\. Should you use any such application, please add the following line to your config: .sp .RS 4 .nf \fBStyle\fR * \fIOLDecor\fR .fi .RE .PP Most (perhaps all) Open Look applications have a strange notion of keyboard focus handling\. Although a lot of work went into fvwm to work well with these, you may still encounter problems\. It is recommended to use the \fINeverFocus\fR focus policy and the \fILenience\fR style for all such applications (the windows still get the focus): .sp .RS 4 .nf \fBStyle\fR \fINeverFocus\fR, \fILenience\fR .fi .RE .PP But in case you can not live with that focus policy, you can try using one of the other focus policies in combination with the \fILenience\fR style: .sp .RS 4 .nf \fBStyle\fR \fIMouseFocus\fR, \fILenience\fR \fBStyle\fR \fISloppyFocus\fR, \fILenience\fR \fBStyle\fR \fIClickToFocus\fR, \fILenience\fR .fi .RE .SH M4 PREPROCESSING .PP M4 pre\-processing is handled by a module in fvwm\. To get more details, try man \fBFvwmM4\fR\. In short, if you want fvwm to parse your files with m4, then replace the command \fBRead\fR with \fBFvwmM4\fR in your \fI~/\.fvwm/config\fR file (if it appears at all), and start fvwm with the command .sp .RS 4 .nf fvwm \-cmd "\fBFvwmM4\fR config" .fi .RE .PP .SH CPP PREPROCESSING .PP Cpp is the C\-language pre\-processor\. fvwm offers cpp processing which mirrors the m4 pre\-processing\. To find out about it, re\-read the \fBM4\fR section, but replace "m4" with "cpp"\. .SH CONFIGURATION .SS Configuration Files .PP The configuration file is used to describe mouse and button bindings, colors, the virtual display size, and related items\. The initialization configuration file is typically called \fIconfig\fR (or \fI\.fvwm2rc\fR)\. By using the \fBRead\fR command, it is easy to read in new configuration files as you go\. .PP Lines beginning with '#' are ignored by fvwm\. Lines starting with '*' are expected to contain module configuration commands (rather than configuration commands for fvwm itself)\. Like in shell scripts embedded newlines in a configuration file line can be quoted by preceding them with a backslash\. All lines linked in this fashion are treated as a single line\. The newline itself is ignored\. .PP Fvwm makes no distinction between configuration commands and action commands, so anything mentioned in the fvwm commands section can be placed on a line by itself for fvwm to execute as it reads the configuration file, or it can be placed as an executable command in a menu or bound to a mouse button or a keyboard key\. It is left as an exercise for the user to decide which function make sense for initialization and which ones make sense for run\-time\. .SS Supplied Configuration .PP A sample configuration file, is supplied with the fvwm distribution\. It is well commented and can be used as a source of examples for fvwm configuration\. It may be copied from \fI/usr/local/share/fvwm/config\fR file\. .PP Alternatively, the built\-in menu (accessible when no configuration file is found) has options to create an initial config file for the user\. .SH FONTS .SS Font names and font loading .PP The fonts used for the text of a window title, icon titles, menus and geometry window can be specified by using the Font and IconFont \fBStyle\fR, the Font \fBMenuStyle\fR and the \fBDefaultFont\fR commands\. Also, all the Modules which use text have configuration command(s) to specify font(s)\. All these styles and commands take a font name as an argument\. This section explains what is a font name for fvwm and which fonts fvwm loads\. .PP First, you can use what we can call a usual font name, for example, .sp .RS 4 .nf \-adobe\-courier\-bold\-r\-normal\-\-10\-100\-75\-75\-m\-60\-ISO8859\-1 \-adobe\-courier\-bold\-r\-normal\-\-10\-* \-*\-fixed\-medium\-o\-normal\-\-14\-*\-ISO8859\-15 .fi .RE .PP That is, you can use an X Logical Font Description (XLFD for short)\. Then the "first" font which matches the description is loaded and used\. This "first" font depends of your font path and also of your locale\. Fonts which match the locale charset are loaded in priority order\. For example with .sp .RS 4 .nf \-adobe\-courier\-bold\-r\-normal\-\-10\-* .fi .RE .PP if the locale charset is ISO8859\-1, then fvwm tries to load a font which matches .sp .RS 4 .nf \-adobe\-courier\-bold\-r\-normal\-\-10\-*\-ISO8859\-1 .fi .RE .PP with the locale charset ISO8859\-15 fvwm tries to load .sp .RS 4 .nf \-adobe\-courier\-bold\-r\-normal\-\-10\-*\-ISO8859\-15\. .fi .RE .PP A font name can be given as an extended XLFD\. This is a comma separated list of (simple) XLFD font names, for example: .sp .RS 4 .nf \-adobe\-courier\-bold\-r\-normal\-\-14\-*,\-*\-courier\-medium\-r\-normal\-\-14\-* .fi .RE .PP Each simple font name is tried until a matching font with the locale charset is found and if this fails each simple font name is tried without constraint on the charset\. .PP More details on the XLFD can be found in the X manual page, the X Logical Font Description Conventions document (called xlfd) and the XLoadFont and XCreateFontSet manual pages\. Some useful font utilities are: xlsfonts, xfontsel, xfd and xset\. .PP If you have Xft support you can specify an Xft font name (description) of a true type (or Type1) font prefixed by "xft:", for example: .sp .RS 4 .nf "xft:Luxi Mono" "xft:Luxi Mono:Medium:Roman:size=14:encoding=iso8859\-1" .fi .RE .PP The "first" font which matches the description is loaded\. This first font depends on the XftConfig configuration file with Xft1 and on the /etc/fonts/fonts\.conf file with Xft2\. One may read the Xft manual page and the fontconfig man page with Xft2\. The first string which follows "xft:" is always considered as the family\. With the second example Luxi Mono is the Family (Other XFree TTF families: "Luxi Serif", "Luxi Sans"), Medium is the Weight (other possible weights: Light, DemiBold, Bold, Black), Roman is the slant or the style (other possibilities: Regular, Oblique, Italic) size specifies the point size (for a pixel size use pixelsize=), encoding allows for enforce a charset (iso8859\-1 or iso10646\-1 only; if no encoding is given the locale charset is assumed)\. An important parameter is "minspace=bool" where bool is True or False\. If bool is False (the default?) Xft gives a greater font height to fvwm than if bool is True\. This may modify text placement, icon and window title height, line spacing in menus and \fBFvwmIdent\fR, button height in some fvwm modules \.\.\.etc\. With a LCD monitor you may try to add "rgba=mode" where mode is either rgb, bgr, vrgb or vbgr to enable subpixel rendering\. The best mode depends on the way your LCD cells are arranged\. You can pass other specifications in between ":", as "foundry=foundry_name", "spacing=type" where type can be monospace, proportional or charcell, "charwidth=integer", "charheight=integer" or "antialias=bool" where bool is True or False\. It seems that these parameters are not always taken in account\. .PP To determine which Xft fonts are really loaded you can export XFT_DEBUG=1 before starting fvwm and take a look to the error log\. With Xft2 you may use fc\-list to list the available fonts\. Anyway, Xft support is experimental (from the X and the fvwm point of view) and the quality of the rendering depends on number of parameters (the XFree and the freetype versions and your video card(s))\. .PP After an Xft font name you can add after a ";" an XLFD font name (simple or extended) as: .sp .RS 4 .nf xft:Verdana:pixelsize=14;\-adobe\-courier\-bold\-r\-normal\-\-14\-* .fi .RE .PP then, if either loading the Xft font fails or fvwm has no Xft support, fvwm loads the font "\-adobe\-courier\-bold\-r\-normal\-\-14\-*"\. This allows for writing portable configuration files\. .SS Font and string encoding .PP Once a font is loaded, fvwm finds its encoding (or charset) using its name (the last two fields of the name)\. fvwm assumes that the strings which are displayed with this font use this encoding (an exception is that if an iso10646\-1 font is loaded, then UTF\-8 is assumed for string encoding)\. In a normal situation, (i) a font is loaded by giving a font name without specifying the encoding, (ii) the encoding of the loaded font is the locale encoding, and then (iii) the strings in the fvwm configuration files should use the locale encoding as well as the window and icon name\. With Xft the situation is bit different as Xft supports only iso10646\-1 and iso8859\-1\. If you do not specify one of these encodings in the Xft font name, then fvwm does strings conversion using (iii)\. Note that with multibyte fonts (and in particular with "CJK" fonts) for good text rendering, the locale encoding should be the charset of the font\. .PP To override the previous rules, it is possible to specify the string encoding in the beginning of a font description as follow: .sp .RS 4 .nf StringEncoding=\fIenc\fR:_full_font_name_ .fi .RE .PP where \fIenc\fR is an encoding supported by fvwm (usually font name charset plus some unicode encodings: UTF\-8, USC\-2, USC\-4 and UTF\-16)\. .PP For example, you may use an iso8859\-1 locale charset and have an \fBFvwmForm\fR in Russian using koi8\-r encoding\. In this case, you just have to ask \fBFvwmForm\fR to load a koi8\-r font by specifying the encoding in the font name\. With a multibyte language, (as multibyte font works well only if the locale encoding is the charset of the font), you should use an iso10646\-1 font: .sp .RS 4 .nf StringEncoding=jisx0208\.1983\-0:\-*\-fixed\-medium\-r\-*\-ja\-*\-iso10646\-1 .fi .RE .PP or .sp .RS 4 .nf "StringEncoding=jisx0208\.1983\-0:xft:Bitstream Cyberbit" .fi .RE .PP if your \fBFvwmForm\fR configuration uses jisx0208\.1983\-0 encoding\. Another possibility is to use UTF\-8 encoding for your \fBFvwmForm\fR configuration and use an iso10646\-1 font: .sp .RS 4 .nf \-*\-fixed\-medium\-r\-*\-ja\-*\-iso10646\-1 .fi .RE .PP or .sp .RS 4 .nf "StringEncoding=UTF\-8:xft:Bitstream Cyberbit" .fi .RE .PP or equivalently .sp .RS 4 .nf "xft:Bitstream Cyberbit:encoding=iso10646\-1" .fi .RE .PP In general iso10646\-1 fonts together with UTF\-8 string encoding allows the display of any characters in a given menu, \fBFvwmForm\fR etc\. .PP More and more, unicode is used and text files use UTF\-8 encoding\. However, in practice the characters used range over your locale charset (this is the case when you generate a menu with fvwm\-menu\-desktop with recent versions of KDE and GNOME)\. For saving memory (an iso10646\-1 font may have a very large number of characters) or because you have a pretty font without an iso10646\-1 charset, you can specify the string encoding to be UTF\-8 and use a font in the locale charset: .sp .RS 4 .nf StringEncoding=UTF\-8:\-*\-pretty_font\-*\-12\-* .fi .RE .PP In most cases, fvwm correctly determines the encoding of the font\. However, some fonts do not end with valid encoding names\. When the font name isn't normal, for example: .sp .RS 4 .nf \-misc\-fixed\-*\-\-20\-*\-my_utf8\-36 .fi .RE .PP you need to add the encoding after the font name using a slash as a delimiter\. For example: .sp .RS 4 .nf \fBMenuStyle\fR * \fIFont\fR \-misc\-fixed\-*\-\-20\-*\-my_utf8\-36/iso10646\-1 .fi .RE .PP If fvwm finds an encoding, fvwm uses the iconv system functions to do conversion between encodings\. Unfortunately, there are no standards\. For conversion between iso8859\-1 and UTF\-8: a GNU system uses "ISO\-8859\-1" and other systems use "iso881" to define the converters (these two names are supported by fvwm)\. Moreover, in some cases it may be necessary to use machine specific converters\. So, if you experience problems you can try to get information on your iconv implementation ("man iconv" may help) and put the name which defines the converter between the font encoding and UTF\-8 at the end of the font name after the encoding hint and a / (another possible solution is to use GNU libiconv)\. For example use: .sp .RS 4 .nf \fBStyle\fR * \fIFont\fR \-misc\-fixed\-*\-\-14\-*\-iso8859\-1/*/latin1 .fi .RE .PP to use latin1 for defining the converter for the iso8859\-1 encoding\. The "*" in between the "/" says to fvwm to determine the encoding from the end of the font name\. Use: .sp .RS 4 .nf \fBStyle\fR * \fIFont\fR \e \-misc\-fixed\-*\-\-14\-*\-local8859\-6/iso8859\-6/local_iso8859_6_iconv .fi .RE .PP to force fvwm to use the font with iso8859\-6 as the encoding (this is useful for bi\-directionality) and to use local_iso8859_6_iconv for defining the converters\. .SS Font Shadow Effects .PP Fonts can be given 3d effects\. At the beginning of the font name (or just after a possible StringEncoding specification) add .sp .RS 4 .nf Shadow=\fIsize\fR [\fIoffset\fR] [\fIdirections]\fR]: .fi .RE .PP \fIsize\fR is a positive integer which specifies the number of pixels of shadow\. \fIoffset\fR is an optional positive integer which defines the number of pixels to offset the shadow from the edge of the character\. The default offset is zero\. \fIdirections\fR is an optional set of directions the shadow emanates from the character\. The \fIdirections\fR are a space separated list of fvwm directions: .PP \fIN\fR, \fINorth\fR, \fITop\fR, \fIt\fR, \fIUp\fR, \fIu\fR, \fI\-\fR .PP \fIE\fR, \fIEast\fR, \fIRight\fR, \fIr\fR, \fIRight\fR, \fIr\fR, \fI]\fR .PP \fIS\fR, \fISouth\fR, \fIBottom\fR, \fIb\fR, \fIDown\fR, \fId\fR, \fI_\fR .PP \fIW\fR, \fIWest\fR, \fILeft\fR, \fIl\fR, \fILeft\fR, \fIl\fR, \fI[\fR .PP \fINE\fR, \fINorthEast\fR, \fITopRight\fR, \fItr\fR, \fIUpRight\fR, \fIur\fR, \fI^\fR .PP \fISE\fR, \fISouthEast\fR, \fIBottomRight\fR, \fIbr\fR, \fIDownRight\fR, \fIdr\fR, \fI>\fR .PP \fISW\fR, \fISouthWest\fR, \fIBottomLeft\fR, \fIbl\fR, \fIDownLeft\fR, \fIdl\fR, \fIv\fR .PP \fINW\fR, \fINorthWest\fR, \fITopLeft\fR, \fItl\fR, \fIUpLeft\fR, \fIul\fR, \fI<\fR .PP \fIC\fR, \fICenter\fR, \fICentre\fR, \fI\.\fR .PP A shadow is displayed in each given direction\. \fIAll\fR is equivalent to all the directions\. The default \fIdirection\fR is \fIBottomRight\fR\. With the \fICenter\fR direction, the shadow surrounds the whole string\. Since this is a super set of all other directions, it is a waste of time to specify this along with any other directions\. .PP The shadow effect only works with colorsets\. The color of the shadow is defined by using the \fIfgsh\fR option of the \fBColorset\fR command\. Please refer to the \fBColorsets\fR section for details about colorsets\. .PP Note: It can be difficult to find the font, \fIfg\fR, \fIfgsh\fR and \fIbg\fR colors to make this effect look good, but it can look quite good\. .SH BI\-DIRECTIONAL TEXT .PP Arabic and Hebrew text require bi\-directional text support to be displayed correctly, this means that logical strings should be converted before their visual presentation, so left\-to\-right and right\-to\-left sub\-strings are determined and reshuffled\. In fvwm this is done automatically in window titles, menus, module labels and other places if the fonts used for displaying the text are of one of the charsets that require \fIbidi\fR (bi\-directional) support\. For example, this includes iso8859\-6, iso8859\-8 and iso10646\-1 (unicode), but not other iso8859\-* fonts\. .PP This bi\-directional text support is done using the \fIfribidi\fR library compile time option, see \fIINSTALL\.fvwm\fR\. .SH KEYBOARD SHORTCUTS .PP Almost all window manager operations can be performed from the keyboard so mouse\-less operation should be possible\. In addition to scrolling around the virtual desktop by binding the \fBScroll\fR command to appropriate keys, \fBPopup\fR, \fBMove\fR, \fBResize\fR, and any other command can be bound to keys\. Once a command is started the pointer is moved by using the up, down, left, and right arrows, and the action is terminated by pressing return\. Holding down the .SM Shift key causes the pointer movement to go in larger steps and holding down the .SM control key causes the pointer movement to go in smaller steps\. Standard emacs and vi cursor movement controls ( .SM n , .SM p , .SM f , .SM b , and .SM j , .SM k , .SM h , .SM l ) can be used instead of the arrow keys\. .SH SESSION MANAGEMENT .PP Fvwm supports session management according to the X Session Management Protocol\. It saves and restores window position, size, stacking order, desk, stickiness, shadiness, maximizedness, iconifiedness for all windows\. Furthermore, some global state is saved\. .PP Fvwm doesn't save any information regarding styles, decors, functions or menus\. If you change any of these resources during a session (e\.g\. by issuing \fBStyle\fR commands or by using various modules), these changes are lost after saving and restarting the session\. To become permanent, such changes have to be added to the configuration file\. .PP Note further that the current implementation has the following anomaly when used on a multi\-screen display: Starting fvwm for the first time, fvwm manages all screens by forking a copy of itself for each screen\. Every copy knows its parent and issuing a \fBQuit\fR command to any instance of fvwm kills the master and thus all copies of fvwm\. When you save and restart the session, the session manager brings up a copy of fvwm on each screen, but this time they are started as individual instances managing one screen only\. Thus a \fBQuit\fR kills only the copy it was sent to\. This is probably not a very serious problem, since with session management, you are supposed to quit a session through the session manager anyway\. If it is really needed, .sp .RS 4 .nf \fBExec\fR exec killall fvwm .fi .RE .PP still kills all copies of fvwm\. Your system must have the \fBkillall\fR command though\. .SH BOOLEAN ARGUMENTS .PP A number of commands take one or several boolean arguments\. These take a few equivalent inputs: "yes", "on", "true", "t" and "y" all evaluate to true while "no", "off", "false", "f" and "n" evaluate to false\. Some commands allow "toggle" too which means that the feature is disabled if it is currently enabled and vice versa\. .SH BUILTIN KEY AND MOUSE BINDINGS .PP The following commands are built\-in to fvwm: .sp .RS 4 .nf \fBKey\fR Help R A \fBPopup\fR MenuFvwmRoot \fBKey\fR F1 R A \fBPopup\fR MenuFvwmRoot \fBKey\fR Tab A M \fBWindowList\fR Root c c NoDeskSort \fBKey\fR Escape A MC \fBEscapeFunc\fR \fBMouse\fR 1 R A \fBMenu\fR MenuFvwmRoot \fBMouse\fR 1 T A FuncFvwmRaiseLowerX \fBMove\fR \fBMouse\fR 1 FS A FuncFvwmRaiseLowerX \fBResize\fR \fBMouse\fR 2 FST A FuncFvwmRaiseLowerX \fBMove\fR \fBAddToFunc\fR FuncFvwmRaiseLowerX + I \fBRaise\fR + M $0 + D \fBLower\fR .fi .RE .PP The .SM Help and .SM F1 keys invoke a built\-in menu that fvwm creates\. This is primarily for new users that have not created their own configuration file\. Either key on the root (background) window pops up an menu to help you get started\. .PP The .SM Tab key pressed anywhere with the .SM Meta key (same as the .SM Alt key on PC keyboards) held down pop\-ups a window list\. .PP Mouse button 1 on the title\-bar or side frame can move, raise or lower a window\. .PP Mouse button 1 on the window corners can resize, raise or lower a window\. .PP You can override or remove these bindings\. To remove the window list binding, use this: .sp .RS 4 .nf \fBKey\fR Tab A M \- .fi .RE .SH COMMAND EXECUTION .SS Module and Function Commands .PP If fvwm encounters a command that it doesn't recognize, it checks to see if the specified command should have been .sp .RS 4 .nf \fBFunction\fR (rest of command) .fi .RE .PP or .sp .RS 4 .nf \fBModule\fR (rest of command) .fi .RE .PP This allows complex functions or modules to be invoked in a manner which is fairly transparent to the configuration file\. .PP Example: the \fIconfig\fR file contains the line .sp .RS 4 .nf HelpMe .fi .RE .PP Fvwm looks for an fvwm command called "HelpMe", and fails\. Next it looks for a user\-defined complex function called "HelpMe"\. If no such function exists, fvwm tries to execute a module called "HelpMe"\. .SS Delayed Execution of Commands .PP Note: There are many commands that affect look and feel of specific, some or all windows, like \fBStyle\fR, \fBMouse\fR, \fBColorset\fR, \fBTitleStyle\fR and many others\. For performance reasons such changes are not applied immediately but only when fvwm is idle, i\.e\. no user interaction or module input is pending\. Specifically, new \fBStyle\fR options that are set in a function are not applied until after the function has completed\. This can sometimes lead to unwanted effects\. .PP To force that all pending changes are applied immediately, use the \fBUpdateStyles\fR, \fBRefresh\fR or \fBRefreshWindow\fR commands\. .SH QUOTING .PP Quotes are required only when needed to make fvwm consider two or more words to be a single argument\. Unnecessary quoting is allowed\. If you want a quote character in your text, you must escape it by using the backslash character\. For example, if you have a pop\-up menu called "Window\-Ops", then you do not need quotes: .sp .RS 4 .nf \fBPopup\fR Window\-Ops .fi .RE .PP but if you replace the dash with a space, then you need quotes: .sp .RS 4 .nf \fBPopup\fR "Window Ops" .fi .RE .PP The supported quoting characters are double quotes, single quotes and reverse single quotes\. All three kinds of quotes are treated in the same way\. Single characters can be quoted with a preceding backslash\. Quoting single characters works even inside other kinds of quotes\. .SH COMMAND EXPANSION .PP Whenever an fvwm command line is executed, fvwm performs parameter expansion\. A parameter is a '$' followed by a word enclosed in brackets ($[\.\.\.]) or a single special character\. If fvwm encounters an unquoted parameter on the command line it expands it to a string indicated by the parameter name\. Unknown parameters are left untouched\. Parameter expansion is performed before quoting\. To get a literal '$' use "$$"\. .PP If a command is prefixed with a '\-' parameter expansion isn't performed\. This applies to the command immediately following the '\-', in which the expansion normally would have taken place\. When uesed together with other prefix commands it must be added before the other prefix\. .PP Example: .sp .RS 4 .nf \fBPick\fR \-\fBExec\fR exec xmessage '$[w\.name]' .fi .RE .PP opens an xmessage dialog with "$[w\.name]" unexpanded\. .PP The longer variables may contain additional variables inside the name, which are expanded before the outer variable\. .PP In earlier versions of fvwm, some single letter variables were supported\. It is deprecated now, since they cause a number of problems\. You should use the longer substitutes instead\. .PP Example: .sp .RS 4 .nf # Print the current desk number, horizontal page number # and the window's class (unexpanded here, no window)\. \fBEcho\fR $[desk\.n] $[page\.nx] $[w\.class] .fi .RE .PP Note: If the command is called outside a window context, it prints "$[w\.class]" instead of the class name\. It is usually not enough to have the pointer over a window to have a context window\. To force using the window with the focus, the \fBCurrent\fR command can be used: .sp .RS 4 .nf \fBCurrent\fR \fBEcho\fR $[desk\.n] $[page\.nx] $[w\.class] .fi .RE .PP The parameters known by fvwm are: .PP $$ .RS 4 A literal '$'\. .RE .PP $\. .RS 4 The absolute directory of the currently Read file\. Intended for creating relative and relocatable configuration trees\. If used outside of any read file, the returned value is '\.'\. .RE .PP $0 to $9 .RS 4 The positional parameters given to a complex function (a function that has been defined with the \fBAddToFunc\fR command)\. "$0" is replaced with the first parameter, "$1" with the second parameter and so on\. If the corresponding parameter is undefined, the "$\.\.\." is deleted from the command line\. .RE .PP $* .RS 4 All positional parameters given to a complex function\. This includes parameters that follow after "$9"\. .RE .PP $[\fIn\fR] .RS 4 The \fIn\fR:th positional parameter given to a complex function, counting from 0\. If the corresponding parameter is undefined, the "$[\fIn\fR]" is deleted from the command line\. The parameter is expanded unquoted\. .RE .PP $[\fIn\fR\-\fIm\fR] .RS 4 The positional parameters given to a complex function, starting with parameter \fIn\fR and ending with parameter \fIm\fR\. If all the corresponding parameters are undefined, the "$[\.\.\.]" is deleted from the command line\. If only some of the parameters are defined, all defined parameters are expanded, and the remaining silently ignored\. All parameters are expanded unquoted\. .RE .PP $[\fIn\fR\-] .RS 4 All the positional parameters given to a complex function, starting with parameter \fIn\fR\. If all the corresponding parameters are undefined, the "$[\.\.\.]" is deleted from the command line\. All parameters are expanded unquoted\. .RE .PP $[*] .RS 4 All the positional parameters given to a complex function\. This is equivalent of $[0\-]\. .RE .PP $[version\.num] .RS 4 The version number, like "2\.6\.0"\. .RE .PP $[version\.info] .RS 4 The version info, like " (from cvs)", empty for the official releases\. .RE .PP $[version\.line] .RS 4 The first line printed by the \-\-version command line option\. .RE .PP $[vp\.x] $[vp\.y] $[vp\.width] $[vp\.height] .RS 4 Either coordinate or the width or height of the current viewport\. .RE .PP $[wa\.x] $[wa\.y] $[wa\.width] $[wa\.height] .RS 4 Either coordinate or the width or height of the EWMH working area\. .RE .PP $[dwa\.x] $[dwa\.y] $[dwa\.width] $[dwa\.height] .RS 4 Either coordinate or the width or height of the dynamic EWMH working area\. .RE .PP $[desk\.n] .RS 4 The current desk number\. .RE .PP $[desk\.name] .RS 4 These parameters are replaced with the name of the desktop number that is defined with the \fBDesktopName\fR command\. If no name is defined, then the default name is returned\. .RE .PP $[desk\.width] $[desk\.height] .RS 4 The width or height of the whole desktop, i\.e\. the width or height multiplied by the number of pages in x or y direction\. .RE .PP $[desk\.pagesx] $[desk\.pagesy] .RS 4 The number of total pages in a desk in x or y direction\. This is the same as the values set by \fBDesktopSize\fR\. .RE .PP $[page\.nx] $[page\.ny] .RS 4 The current page numbers, by X and Y axes, starting from 0\. \fIpage\fR is equivalent to \fIarea\fR in the GNOME terminology\. .RE .PP $[w\.id] .RS 4 The window\-id (expressed in hex, e\.g\. 0x10023c) of the window the command was called for or "$[w\.id]" if no window is associated with the command\. .RE .PP $[w\.name] $[w\.iconname] $[w\.class] $[w\.resource] $[w\.visiblename] $[w\.iconfile] $[w\.miniiconfile] $[w\.iconfile\.svgopts] $[w\.miniiconfile\.svgopts] .RS 4 The window's name, icon name, resource class and resource name, visible name, file name of its icon or mini icon defined with the \fIIcon\fR or \fIMiniIcon\fR style (including the full path if the file was found on disk), and (if fvwm is compiled with SVG support) the icon or mini icon svg rendering options (including the leading colon), or unexpanded "$[w\.]" string if no window is associated with the command\. .sp Note, the first 5 variables may include any kind of characters, so these variables are quoted\. It means that the value is surrounded by single quote characters and any contained single quote is prefixed with a backslash\. This guarantees that commands like: .sp .RS 4 .nf \fBStyle\fR $[w\.resource] \fIIcon\fR norm/network\.png .fi .RE .sp work correctly, regardless of any special symbols the value may contain, like spaces and different kinds of quotes\. .sp In the case of the window's visible name, this is the value returned from the literal title of the window shown in the titlebar\. Typically this will be the same as $[w\.name] once expanded, although in the case of using \fIIndexedWindowName\fR then this is more useful a distinction, and allows for referencing the specific window by its visible name for inclusion in things like \fBStyle\fR commands\. .RE .PP $[w\.x] $[w\.y] $[w\.width] $[w\.height] .RS 4 Either coordinate or the width or height of the current window if it is not iconified\. If no window is associated with the command or the window is iconified, the string is left as is\. .RE .PP $[w\.desk] .RS 4 The number of the desk on which the window is shown\. If the window is sticky the current desk number is used\. .RE .PP $[w\.layer] .RS 4 The layer of the window\. .RE .PP $[w\.screen] .RS 4 The screen number the window is on\. If Xinerama is not present, this returns the number 0\. .RE .PP $[cw\.x] $[cw\.y] $[cw\.width] $[cw\.height] .RS 4 These work like $[w\.\.\.\.] but return the geometry of the client part of the window\. In other words: the border and title of the window is not taken into account\. .RE .PP $[i\.x], $[it\.x], $[ip\.x] $[i\.y], $[it\.y], $[ip\.y] $[i\.width], $[it\.width], $[ip\.width] $[i\.height], $[it\.height], $[ip\.height] .RS 4 These work like $[w\.\.\.\.] but return the geometry of the icon ($[i\.\.\.\.]), the icon title ($[it\.\.\.\.]) or the icon picture ($[ip\.\.\.\.])\. .RE .PP $[pointer\.x] $[pointer\.y] .RS 4 These return the position of the pointer on the screen\. If the pointer is not on the screen, these variables are not expanded\. .RE .PP $[pointer\.wx] $[pointer\.wy] .RS 4 These return the position of the pointer in the selected window\. If the pointer is not on the screen, the window is iconified or no window is selected, these variables are not expanded\. .RE .PP $[pointer\.cx] $[pointer\.cy] .RS 4 These return the position of the pointer in the client portion of the selected window\. If the pointer is not on the screen, the window is shaded or iconified or no window is selected, these variables are not expanded\. .RE .PP $[pointer\.screen] .RS 4 The screen number the pointer is currently on\. Returns 0 if Xinerama is not enabled\. .RE .PP $[screen] .RS 4 The screen number fvwm is running on\. Useful for setups with multiple screens\. .RE .PP $[fg\.cs] $[bg\.cs] $[hilight\.cs] $[shadow\.cs] .RS 4 These parameters are replaced with the name of the foreground (fg), background (bg), hilight (hilight) or shadow (shadow) color that is defined in colorset (replace with zero or a positive integer)\. For example "$[fg\.cs3]" is expanded to the name of the foreground color of colorset 3 (in rgb:rrrr/gggg/bbbb form)\. Please refer to the \fBColorsets\fR section for details about colorsets\. .RE .PP $[schedule\.last] .RS 4 This is replaced by the id of the last command that was scheduled with the \fBSchedule\fR command, even if this command was already executed\. .RE .PP $[schedule\.next] .RS 4 This is replaced by the id the next command used with \fBSchedule\fR will get (unless a different id is specified explicitly)\. .RE .PP $[cond\.rc] .RS 4 The return code of the last conditional command\. This variable is only valid inside a function and can not be used in a conditional command\. Please refer to the section \fBConditional Commands\fR in the command list\. .RE .PP $[func\.context] .RS 4 The context character of the running command as used in the \fBMouse\fR, \fBKey\fR or \fBPointerKey\fR command\. This is useful for example with: .sp .RS 4 .nf \fBMouse\fR 3 FS N \fBWindowShade\fR $$[func\.context] .fi .RE .sp .RE .PP $[gt\.\fIstr\fR] .RS 4 return the translation of \fIstr\fR by looking in the current locale catalogs\. If no translation is found \fIstr\fR is returned as is\. See the \fBLocalePath\fR command\. .RE .PP $[infostore\.\fIkey\fR] .RS 4 Return the value of the item stored in the InfoStore at the given \fIkey\fR\. If no key is present, the unexpanded string is returned\. .RE .PP $[\.\.\.] .RS 4 If the string within the braces is neither of the above, fvwm tries to find an environment variable with this name and replaces its value if one is found (e\.g\. "$[PAGER]" could be replaced by "more")\. Otherwise the string is left as is\. .RE .PP Some examples can be found in the description of the \fBAddToFunc\fR command\. .SH SCRIPTING & COMPLEX FUNCTIONS .PP To achieve the more complex effects, fvwm has a number of commands that improve its scripting abilities\. Scripts can be read from a file with \fBRead\fR, from the output of a command with \fBPipeRead\fR or written as a complex function with the \fBAddToFunc\fR command\. For the curious, section 7 of the fvwm FAQ shows some real life applications of scripting\. Please refer to the sections \fBUser Functions and Shell Commands\fR and \fBConditional Commands\fR for details\. A word of warning: during execution of complex functions, fvwm needs to take all input from the mouse pointer (the pointer is "grabbed" in the slang of X)\. No other programs can receive any input from the pointer while a function is run\. This can confuse some programs\. For example, the xwd program refuses to make screen shots when run from a complex function\. To achieve the same functionality you can use the \fBRead\fR or \fBPipeRead\fR command instead\. .SH LIST OF FVWM COMMANDS .PP The command descriptions below are grouped together in the following sections\. The sections are hopefully sorted in order of usefulness to the newcomer\. .sp .RS 4 \h'-04'\(bu\h'+03'\fBMenu commands\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBMiscellaneous commands\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBCommands affecting window movement and placement\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBCommands for focus and mouse movement\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBCommands controlling window state\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBCommands for mouse, key and stroke bindings\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBThe Style command (controlling window styles)\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBOther commands controlling window styles\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBCommands controlling the virtual desktop\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBCommands for user functions and shell commands\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBConditional commands\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBModule commands\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBQuit, restart and session management commands\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBColorsets\fR .sp .RE .sp .RS 4 \h'-04'\(bu\h'+03'\fBColor gradients\fR .sp .RE .SS Menus .PP Before a menu can be opened, it has to be populated with menu items using the \fBAddToMenu\fR command and bound to a key or mouse button with the \fBKey\fR, \fBPointerKey\fR or \fBMouse\fR command (there are many other ways to invoke a menu too)\. This is usually done in the configuration file\. .PP Fvwm menus are extremely configurable in look and feel\. Even the slightest nuances can be changed to the user's liking, including the menu item fonts, the background, delays before popping up sub menus, generating menus dynamically and many other features\. Please refer to the \fBMenuStyle\fR command to learn more\. .TP .B Types of Menus .RS .\".PP In fvwm there are four slightly different types of menus: .PP \fBPopup\fR menus can appear everywhere on the screen on their own or attached to a part of a window\. The \fBPopup\fR command opens popup menus\. If the popup menu was invoked with a mouse button held down, it is closed when the button is released\. The item under the pointer is then activated and the associated action is executed\. .PP \fBMenu\fR is a very similar command, but the menus it opens are slightly less transient\. When invoked by clicking a mouse button, it stays open and can be navigated with no button held\. But if it is invoked by a button press followed by mouse motion, it behaves exactly like a popup menu\. .PP \fITear off menus\fR or \fIPin up menus\fR are menus from either of the above two commands that have been "torn off" their original context and pinned on the desktop like a normal window\. They are created from other menus by certain key presses or mouse sequences or with the \fBTearMenuOff\fR command from inside a menu\. .PP \fISub menus\fR are menus inside menus\. When a menu item that has the \fBPopup\fR command as its action is selected, the named menu is opened as an inferior menu to the parent\. Any type of menu can have sub menus\. .RE .TP .B Menu Anatomy .RS .\".PP Menus consist of any number of titles which are inactive menu items that usually appear at the top of the menu, normal items triggering various actions when selected, separator lines between the items, tear off bars (a horizontal broken line) that tear off the menu when selected, and sub menu items indicated with a triangle pointing left or right, depending on the direction in which the sub menu appears\. All the above menu items are optional\. .PP Additionally, if the menu is too long to fit on the screen, the excess menu items are put in a continuation menu and a sub menu with the string "More\.\.\." is placed at the bottom of the menu\. The "More\.\.\." string honors the locale settings\. .PP Finally, there may be a picture running up either side of the menu (a "side bar")\. .RE .TP .B Menu Navigation .RS .\".PP Menus can be navigated either with the keyboard or with the mouse\. Many people prefer to use the mouse, but it can be rather tedious\. Once you get the hang of it, keyboard navigation can be much faster\. While fvwm displays a menu, it can do nothing else\. For example, new windows do not appear before the menu is closed\. However, this is not exactly true for tear off menus\. See the \fBTear Off Menus\fR section for details\. .RE .TP .B Mouse Navigation .RS .\".PP Moving the pointer over a menu selects the item below it\. Normally this is indicated by a 3d border around the item, but not all parts of a menu can be selected\. Pressing any mouse button while a menu is open by default activates the item below it\. Items of a popup menu are also activated by releasing a held mouse button\. In case of an item that hides a sub menu, the sub menu is displayed if the pointer hovers over the item long enough or moves close to the triangle indicating the sub menu\. This behaviour can be tuned with menu styles\. .PP Scrolling a mouse wheel over a menu either wraps the pointer along the menu (default), scrolls the menu under the pointer or act as if the menu was clicked depending on the \fIMouseWheel\fR menu style\. .PP Clicking on a selected item activates it \- what happens exactly depends on the type of the item\. .PP Clicking on a title, a separator, the side bar, or outside the menu closes the menu (exception: tear off menus can not be closed this way)\. Pressing mouse button 2 over a menu title or activating a tear off bar creates a tear off menu from the current menu\. Clicking on a normal menu item invokes the command that is bound to it, and clicking on a sub menu item either closes all open menus and replaces them with the sub menu or posts the menu (default)\. .PP Posting menus is meant to ease mouse navigation\. Once a sub menu is posted, only items from that sub menu can be selected\. This can be very useful to navigate the menu if the pointer tends to stray off the menu\. To unpost the menu and revert back to normal operation, either click on the same sub menu item or press any key\. .RE .TP .B Keyboard Navigation .RS .\".PP Just like with mouse navigation, the item below the pointer is selected\. This is achieved by warping the pointer to the menu items when necessary\. While a menu is open, all key presses are intercepted by the menu\. No other application can get keyboard input (although this is not the case for tear off menus)\. .PP Items can be selected directly by pressing a hotkey that can be configured individually for each menu item\. The hotkey is indicated by underlining it in the menu item label\. With the \fIAutomaticHotkeys\fR menu style fvwm automatically assigns hotkeys to all menu items\. .PP The most basic keys to navigate through menus are the cursor keys (move up or down one item, enter or leave a sub menu), .SM Space (activate item) and .SM Escape (close menu)\. Numerous other keys can be used to navigate through menus by default: .PP \fIEnter\fR, \fIReturn\fR, \fISpace\fR activate the current item\. .PP \fIEscape\fR, \fIDelete\fR, \fICtrl\-G\fR exit the current sequence of menus or destroy a tear off menu\. .PP \fIJ\fR, \fIN\fR, \fICursor\-Down\fR, \fITab\fR, \fIMeta\-Tab\fR, \fICtrl\-F\fR, move to the next item\. .PP \fIK\fR, \fIP\fR, \fICursor\-Up\fR, \fIShift\-Tab\fR, \fIShift\-Meta\-Tab\fR, \fICtrl\-B\fR, move to the prior item\. .PP \fIL\fR, \fICursor\-Right\fR, \fIF\fR enter a sub menu\. .PP \fIH\fR, \fICursor\-Left\fR, \fIB\fR return to the prior menu\. .PP \fICtrl\-Cursor\-Up\fR, \fICtrl\-K\fR \fICtrl\-P\fR, \fIShift\-Ctrl\-Meta\-Tab\fR, \fIPage\-Up\fR move up five items\. .PP \fICtrl\-Cursor\-Down\fR, \fICtrl\-J\fR \fICtrl\-N\fR, \fICtrl\-Meta\-Tab\fR \fIPage\-Down\fR move down five items\. .PP \fIShift\-P\fR, \fIHome\fR, \fIShift\-Cursor\-Up\fR, \fICtrl\-A\fR move to the first item\. .PP \fIShift\-N\fR, \fIEnd\fR, \fIShift\-Cursor\-Down\fR, \fICtrl\-E\fR move to the last item\. .PP \fIMeta\-P\fR, \fIMeta\-Cursor\-Up\fR, \fICtrl\-Cursor\-Left\fR, \fIShift\-Ctrl\-Tab\fR, move up just below the next separator\. .PP \fIMeta\-N\fR, \fIMeta\-Cursor\-Down\fR, \fICtrl\-Cursor\-Right\fR, \fICtrl\-Tab\fR, move down just below the next separator\. .PP \fIInsert\fR opens the "More\.\.\." sub menu if any\. .PP \fIBackspace\fR tears off the menu\. .RE .TP .B Menu Bindings .RS .\".PP The keys and mouse buttons used to navigate the menu can be configured using the \fBKey\fR and \fBMouse\fR commands with the special context 'M', possible combined with 'T' for the menu title, 'I' for other menu items, 'S' for any border or sidepic, '[' for left border including a left sidepic, ']' for right border including a right sidepic, '\-' for top border, '_' for bottom border\. The menu context uses its own set of actions that can be bound to keys and mouse buttons\. These are \fIMenuClose\fR, \fIMenuCloseAndExec\fR, \fIMenuEnterContinuation\fR, \fIMenuEnterSubmenu\fR, \fIMenuLeaveSubmenu\fR, \fIMenuMoveCursor\fR, \fIMenuCursorLeft\fR, \fIMenuCursorRight\fR, \fIMenuSelectItem\fR, \fIMenuScroll\fR and \fIMenuTearOff\fR\. .PP It is not possible to override the key Escape with no modifiers for closing the menu\. Neither is it possible to undefine mouse button 1, the arrow keys or the enter key for minimal navigation\. .PP \fBMenuClose\fR exits from the current sequence of menus or destroys a tear off menu\. .PP \fBMenuCloseAndExec\fR exits from the current sequence of menus or destroys a tear off menu and executes the rest of the line as a command\. .PP \fBMenuEnterContinuation\fR opens the "More\.\.\." sub menu if any\. .PP \fBMenuEnterSubmenu\fR enters a sub menu\. .PP \fBMenuLeaveSubmenu\fR returns to the prior menu\. .PP \fBMenuMoveCursor\fR \fIn\fR [\fIm\fR] moves the selection to another item\. If the first argument is zero the second argument specifies an absolute item in the menu to move the pointer to\. Negative items are counted from the end of the menu\. If the first argument is non\-zero, the second argument must be omitted, and the first argument specifies a relative change in the selected item\. The positions may be suffixed with a 's' to indicate that the items should refer only to the first items after separators\. .PP \fBMenuCursorLeft\fR enters a sub menu with the \fISubmenusLeft\fR menu style, and returns to the prior menu with the \fISubmenusRight\fR menu style\. .PP \fBMenuCursorRight\fR enters a sub menu with the \fISubmenusRight\fR menu style, and returns to the prior menu with the \fISubmenusLeft\fR menu style\. .PP \fBMenuSelectItem\fR triggers the action for the menu item\. .PP \fBMenuScroll \fR\fIn\fR performs menu scrolling according to the \fIMouseWheel\fR menu style with \fIn\fR items\. The distance can be suffixed with an 's' to indicate the items should refer only to the first items after separators\. .PP \fBMenuTearOff\fR turns a normal menu into a "torn off" menu\. See \fBTear Off Menus\fR for details\. .RE .TP .B Tear Off Menus .RS .\".PP A tear off menu is any menu that has been "torn off" the window it was attached to and pinned to the root window\. There are three ways to tear off a menu: click on the menu title with mouse button 2, press .SM Backspace in the menu or activate its tear off bar (a horizontal bar with a broken line)\. Tear off bars must be added to the menu as any other item by assigning them the command \fBTearMenuOff\fR\. .PP The builtin tear off actions can be overridden by undefining the builtin menu actions bound to tear off\. To remove the builtin mouse button 2 binding, use: .sp .RS 4 .nf \fBMouse\fR 2 MT A \- .fi .RE .PP and to remove the builtin backspace binding, use: .sp .RS 4 .nf \fBKey\fR Backspace M A \- .fi .RE .PP See the section \fBMenu Bindings\fR for details on how to assign other bindings for tear off\. .PP Note that prior to fvwm 2\.5\.20 the tear off mouse bindings were redefined in different way, which no longer work\. .PP The window containing the menu is placed as any other window would be\. If you find it confusing to have your tear off menus appear at random positions on the screen, put this line in your configuration file: .sp .RS 4 .nf \fBStyle\fR fvwm_menu \fIUsePPosition\fR .fi .RE .PP To remove borders and buttons from a tear\-off menu but keep the menu title, you can use .sp .RS 4 .nf \fBStyle\fR fvwm_menu !\fIButton\fR 0, !\fIButton\fR 1 \fBStyle\fR fvwm_menu !\fIButton\fR 2, !\fIButton\fR 3 \fBStyle\fR fvwm_menu !\fIButton\fR 4, !\fIButton\fR 5 \fBStyle\fR fvwm_menu !\fIButton\fR 6, !\fIButton\fR 7 \fBStyle\fR fvwm_menu !\fIButton\fR 8, !\fIButton\fR 9 \fBStyle\fR fvwm_menu \fITitle\fR, \fIHandleWidth\fR 0 .fi .RE .PP A tear off menu is a cross breeding between a window and a menu\. The menu is swallowed by a window and its title is stripped off and displayed in the window title\. The main advantage is that the menu becomes permanent \- activating an item does not close the menu\. Therefore, it can be used multiple times without reopening it\. To destroy such a menu, close its window or press the .SM Escape key\. .PP Tear off menus behave somewhat differently than normal menus and windows\. They do not take the keyboard focus, but while the pointer is over one of them, all key presses are sent to the menu\. Other fvwm key bindings are disabled as long as the pointer is inside the tear off menu or one of its sub menus\. When the pointer leaves this area, all sub menus are closed immediately\. Note that the window containing a tear off menu is never hilighted as if it had the focus\. .PP A tear off menu is an independent copy of the menu it originated from\. As such, it is not affected by adding items to that menu or changing its menu style\. .PP To create a tear off menu without opening the normal menu first, the option \fITearOffImmediately\fR can be added to the \fBMenu\fR or \fBPopup\fR command\. .RE .TP \fBAddToMenu\fR \fImenu\-name\fR [\fImenu\-label\fR\ \fIaction\fR] .RS .\".PP Begins or adds to a menu definition\. Typically a menu definition looks like this: .sp .RS 4 .nf AddToMenu Utilities Utilities \fBTitle\fR + Xterm \fBExec\fR exec xterm \-e tcsh + Rxvt \fBExec\fR exec rxvt + "Remote Logins" \fBPopup\fR Remote\-Logins + Top \fBExec\fR exec rxvt \-T Top \-n Top \-e top + Calculator \fBExec\fR exec xcalc + Xman \fBExec\fR exec xman + Xmag \fBExec\fR exec xmag + emacs \fBExec\fR exec xemacs + Mail MailFunction xmh "\-font fixed" + "" \fBNop\fR + Modules \fBPopup\fR Module\-Popup + "" \fBNop\fR + Exit Fvwm \fBPopup\fR Quit\-Verify .fi .RE .PP The menu could be invoked via .sp .RS 4 .nf \fBMouse\fR 1 R A \fBMenu\fR Utilities Nop .fi .RE .PP or .sp .RS 4 .nf \fBMouse\fR 1 R A \fBPopup\fR Utilities .fi .RE .PP There is no end\-of\-menu symbol\. Menus do not have to be defined in a contiguous region of the \fIconfig\fR file\. The quoted (or first word) portion in the above examples is the menu label, which appears in the menu when the user pops it up\. The remaining portion is an fvwm command which is executed if the user selects that menu item\. An empty menu\-label ("") and the \fBNop\fR function are used to insert a separator into the menu\. .PP The keywords \fIDynamicPopUpAction\fR and \fIDynamicPopDownAction\fR have a special meaning when used as the name of a menu item\. The action following the keyword is executed whenever the menu is popped up or down\. This way you can implement dynamic menus\. It is even possible to destroy itself with \fBDestroyMenu\fR and the rebuild from scratch\. When the menu has been destroyed (unless you used the \fIrecreate\fR option when destroying the menu), do not forget to add the dynamic action again\. .PP Note: Do not trigger actions that require user interaction\. They may fail and may screw up your menus\. See the \fBSilent\fR command\. .sp .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br \fBWarning\fR Do not issue \fBMenuStyle\fR commands as dynamic menu actions\. Chances are good that this crashes fvwm\. .PP There are several configurable scripts installed together with fvwm for automatic menu generation\. They have their own man pages\. Some of them, specifically \fBfvwm\-menu\-directory\fR and \fBfvwm\-menu\-desktop\fR, may be used with \fIDynamicPopupAction\fR to create a directory listing or GNOME/KDE application listing\. .PP Example (File browser): .sp .RS 4 .nf # You can find the shell script fvwm_make_browse_menu\.sh # in the utils/ directory of the distribution\. AddToMenu BrowseMenu + DynamicPopupAction \fBPipeRead\fR \e 'fvwm_make_browse_menu\.sh BrowseMenu' .fi .RE .PP Example (Picture menu): .sp .RS 4 .nf # Build a menu of all \.jpg files in # $HOME/Pictures AddToMenu JpgMenu foo title + DynamicPopupAction \fBFunction\fR MakeJpgMenu \fBAddToFunc\fR MakeJpgMenu + I \fBDestroyMenu\fR recreate JpgMenu + I AddToMenu JpgMenu Pictures \fBTitle\fR + I \fBPipeRead\fR 'for i in \fI$HOME\fR/Pictures/*\.jpg; \e do echo AddToMenu JpgMenu "`basename $i`" \fBExec\fR xv $i; done' .fi .RE .PP The keyword \fIMissingSubmenuFunction\fR has a similar meaning\. It is executed whenever you try to pop up a sub menu that does not exist\. With this function you can define and destroy menus on the fly\. You can use any command after the keyword, but if the name of an item (that is a submenu) defined with \fBAddToFunc\fR follows it, fvwm executes this command: .sp .RS 4 .nf \fBFunction\fR .fi .RE .PP i\.e\. the name is passed to the function as its first argument and can be referred to with "$0"\. .PP The \fBfvwm\-menu\-directory\fR script mentioned above may be used with \fIMissingSubmenuFunction\fR to create an up to date recursive directory listing\. .PP Example: .sp .RS 4 .nf # There is another shell script fvwm_make_directory_menu\.sh # in the utils/ directory of the distribution\. To use it, # define this function in your configuration file: \fBDestroyFunc\fR MakeMissingDirectoryMenu \fBAddToFunc\fR MakeMissingDirectoryMenu + I \fBPipeRead\fR fvwm_make_directory_menu\.sh $0 \fBDestroyMenu\fR SomeMenu AddToMenu SomeMenu + MissingSubmenuFunction MakeMissingDirectoryMenu + "Root directory" \fBPopup\fR / .fi .RE .PP This is another implementation of the file browser that uses sub menus for subdirectories\. .PP Titles can be used within the menu\. If you add the option \fItop\fR behind the keyword \fBTitle\fR, the title is added to the top of the menu\. If there was a title already, it is overwritten\. .sp .RS 4 .nf AddToMenu Utilities Tools Title top .fi .RE .PP All text up to the first .SM Tab in the menu label is aligned to the left side of the menu, all text right of the first .SM Tab is aligned to the left in a second column and all text thereafter is placed right aligned in the third column\. All other .SM Tab s are replaced by spaces\. Note that you can change this format with the \fIItemFormat\fR option of the \fBMenuStyle\fR command\. .PP If the menu\-label contains an ampersand ('&'), the next character is taken as a hot\-key for the menu item\. Hot\-keys are underlined in the label\. To get a literal '&', insert "&&"\. Pressing the hot\-key moves through the list of menu items with this hot\-key or selects an item that is the only one with this hot\-key\. .PP If the menu\-label contains a sub\-string which is set off by stars, then the text between the stars is expected to be the name of an image file to insert in the menu\. To get a literal '*', insert "**"\. For example .sp .RS 4 .nf + Calculator*xcalc\.xpm* \fBExec\fR exec xcalc .fi .RE .PP inserts a menu item labeled "Calculator" with a picture of a calculator above it\. The following: .sp .RS 4 .nf + *xcalc\.xpm* \fBExec\fR exec xcalc .fi .RE .PP Omits the "Calculator" label, but leaves the picture\. .PP If the menu\-label contains a sub\-string which is set off by percent signs, then the text between the percent signs is expected to be the name of image file (a so called mini icon to insert to the left of the menu label\. A second mini icon that is drawn at the right side of the menu can be given in the same way\. To get a literal '%', insert "%%"\. For example .sp .RS 4 .nf + Calculator%xcalc\.xpm% \fBExec\fR exec xcalc .fi .RE .PP inserts a menu item labeled "Calculator" with a picture of a calculator to the left\. The following: .sp .RS 4 .nf + %xcalc\.xpm% \fBExec\fR exec xcalc .fi .RE .PP Omits the "Calculator" label, but leaves the picture\. The pictures used with this feature should be small (perhaps 16x16)\. .PP If the menu\-name (not the label) contains a sub\-string which is set off by at signs ('@'), then the text between them is expected to be the name of an image file to draw along the left side of the menu (a side pixmap)\. You may want to use the \fISidePic\fR option of the \fBMenuStyle\fR command instead\. To get a literal '@', insert "@@"\. For example .sp .RS 4 .nf AddToMenu StartMenu@linux\-menu\.xpm@ .fi .RE .PP creates a menu with a picture in its bottom left corner\. .PP If the menu\-name also contains a sub\-string surrounded by '^'s, then the text between '^'s is expected to be the name of an X11 color and the column containing the side picture is colored with that color\. You can set this color for a menu style using the \fISideColor\fR option of the \fBMenuStyle\fR command\. To get a literal '^', insert "^^"\. Example: .sp .RS 4 .nf AddToMenu StartMenu@linux\-menu\.xpm@^blue^ .fi .RE .PP creates a menu with a picture in its bottom left corner and colors with blue the region of the menu containing the picture\. .PP In all the above cases, the name of the resulting menu is name specified, stripped of the substrings between the various delimiters\. .RE .TP \fBChangeMenuStyle\fR \fImenustyle\fR \fImenu\fR ... .RS .\".PP Changes the menu style of \fImenu\fR to \fImenustyle\fR\. You may specify more than one menu in each call of \fBChangeMenuStyle\fR\. .RE .TP \fBCopyMenuStyle\fR \fIorig\-menustyle\fR \fIdest\-menustyle\fR .RS .\".PP Copy \fIorig\-menustyle\fR to \fIdest\-menustyle\fR, where \fIorig\-menustyle\fR is an existing menu style\. If the menu style \fIdest_menustyle\fR does not exist, then it is created\. .RE .TP \fBDestroyMenu\fR [recreate] \fImenu\fR .RS .\".PP Deletes a menu, so that subsequent references to it are no longer valid\. You can use this to change the contents of a menu during an fvwm session\. The menu can be rebuilt using \fBAddToMenu\fR\. The optional parameter \fIrecreate\fR tells fvwm not to throw away the menu completely but to throw away all the menu items (including the title)\. .sp .RS 4 .nf DestroyMenu Utilities .fi .RE .RE .TP \fBDestroyMenuStyle\fR \fImenustyle\fR .RS .\".PP Deletes the menu style named \fImenustyle\fR and changes all menus using this style to the default style, you cannot destroy the default menu style\. .sp .RS 4 .nf DestroyMenuStyle pixmap1 .fi .RE .RE .TP \fBMenu\fR \fImenu\-name\fR [\fIposition\fR] [\fIdouble\-click\-action\fR] .RS .\".PP Causes a previously defined menu to be popped up in a sticky manner\. That is, if the user invokes the menu with a click action instead of a drag action, the menu stays up\. The command \fIdouble\-click\-action\fR is invoked if the user double\-clicks a button (or hits the key rapidly twice if the menu is bound to a key) when bringing up the menu\. If the double click action is not specified, double clicking on the menu does nothing\. However, if the menu begins with a menu item (i\.e\. not with a title or a separator) and the double click action is not given, double clicking invokes the first item of the menu (but only if the pointer really was over the item)\. .PP The pointer is warped to where it was when the menu was invoked if it was both invoked and closed with a keystroke\. .PP The \fIposition\fR arguments allow placement of the menu somewhere on the screen, for example centered on the visible screen or above a title bar\. Basically it works like this: you specify a \fIcontext\-rectangle\fR and an offset to this rectangle by which the upper left corner of the menu is moved from the upper left corner of the rectangle\. The \fIposition\fR arguments consist of several parts: .HP 1 [\fIcontext\-rectangle\fR] \fIx\fR \fIy\fR [\fIspecial\-options\fR] .PP The \fIcontext\-rectangle\fR can be one of: .PP \fIRoot\fR .RS 4 the root window of the current screen\. .RE .PP \fIXineramaRoot\fR .RS 4 the root window of the whole Xinerama screen\. Equivalent to "root" when Xinerama is not used\. .RE .PP \fIMouse\fR .RS 4 a 1x1 rectangle at the mouse position\. .RE .PP \fIWindow\fR .RS 4 the frame of the context window\. .RE .PP \fIInterior\fR .RS 4 the inside of the context window\. .RE .PP \fITitle\fR .RS 4 the title of the context window or icon\. .RE .PP \fIButton\fR .RS 4 button #n of the context window\. .RE .PP \fIIcon\fR .RS 4 the icon of the context window\. .RE .PP \fIMenu\fR .RS 4 the current menu\. .RE .PP \fIItem\fR .RS 4 the current menu item\. .RE .PP \fIContext\fR .RS 4 the current window, menu or icon\. .RE .PP \fIThis\fR .RS 4 whatever widget the pointer is on (e\.g\. a corner of a window or the root window)\. .RE .PP \fIRectangle\fR <\fIgeometry\fR> .RS 4 the rectangle defined by <\fIgeometry\fR> in X geometry format\. Width and height default to 1 if omitted\. .RE .PP If the context\-rectangle is omitted or illegal (e\.g\. "item" on a window), "Mouse" is the default\. Note that not all of these make sense under all circumstances (e\.g\. "Icon" if the pointer is on a menu)\. .PP The offset values \fIx\fR and \fIy\fR specify how far the menu is moved from its default position\. By default, the numeric value given is interpreted as a percentage of the context rectangle's width (height), but with a trailing '\fIm\fR' the menu's width (height) is used instead\. Furthermore a trailing '\fIp\fR' changes the interpretation to mean pixels\. .PP Instead of a single value you can use a list of values\. All additional numbers after the first one are separated from their predecessor by their sign\. Do not use any other separators\. .PP If \fIx\fR or \fIy\fR are prefixed with "'\fIo\fR" where is an integer, the menu and the rectangle are moved to overlap at the specified position before any other offsets are applied\. The menu and the rectangle are placed so that the pixel at percent of the rectangle's width/height is right over the pixel at percent of the menu's width/height\. So "o0" means that the top/left borders of the menu and the rectangle overlap, with "o100" it's the bottom/right borders and if you use "o50" they are centered upon each other (try it and you will see it is much simpler than this description)\. The default is "o0"\. The prefix "o" is an abbreviation for "+\-m"\. .PP A prefix of '\fIc\fR' is equivalent to "o50"\. Examples: .sp .RS 4 .nf # window list in the middle of the screen \fBWindowList\fR Root c c # menu to the left of a window Menu name window \-100m c+0 # popup menu 8 pixels above the mouse pointer \fBPopup\fR name mouse c \-100m\-8p # somewhere on the screen Menu name rectangle 512x384+1+1 +0 +0 # centered vertically around a menu item \fBAddToMenu\fR foobar\-menu + "first item" \fBNop\fR + "special item" \fBPopup\fR "another menu" item +100 c + "last item" \fBNop\fR # above the first menu item \fBAddToMenu\fR foobar\-menu + "first item" \fBPopup\fR "another menu" item +0 \-100m .fi .RE .PP Note that you can put a sub menu far off the current menu so you could not reach it with the mouse without leaving the menu\. If the pointer leaves the current menu in the general direction of the sub menu the menu stays up\. .PP The \fIspecial\-options\fR: .PP To create a tear off menu without opening the normal menu, add the option \fITearOffImmediately\fR\. Normally the menu opens in normal state for a split second before being torn off\. As tearing off places the menu like any other window, a position should be specified explicitly: .sp .RS 4 .nf # Forbid fvwm to place the menu window \fBStyle\fR UsePPosition # Menu at top left corner of screen Menu Root 0p 0p TearOffImmediately .fi .RE .PP The \fIAnimated\fR and \fIMwm\fR or \fIWin\fR menu styles may move a menu somewhere else on the screen\. If you do not want this you can add \fIFixed\fR as an option\. This might happen for example if you want the menu always in the top right corner of the screen\. .PP Where do you want a menu to appear when you click on its menu item? The default is to place the title under the cursor, but if you want it where the position arguments say, use the \fISelectInPlace\fR option\. If you want the pointer on the title of the menu, use \fISelectWarp\fR too\. Note that these options apply only if the \fIPopupAsRootMenu\fR \fBMenuStyle\fR option is used\. .PP The pointer is warped to the title of a sub menu whenever the pointer would be on an item when the sub menu is popped up (\fIfvwm\fR menu style) or never warped to the title at all (\fIMwm\fR or \fIWin\fR menu styles)\. You can force (forbid) warping whenever the sub menu is opened with the \fIWarpTitle\fR (\fINoWarp\fR) option\. .PP Note that the \fIspecial\-options\fR do work with a normal menu that has no other position arguments\. .RE .TP \fBMenuStyle\fR \fIstylename\fR [\fIoptions\fR] .RS .\".PP Sets a new menu style or changes a previously defined style\. The \fIstylename\fR is the style name; if it contains spaces or tabs it has to be quoted\. The name "*" is reserved for the default menu style\. The default menu style is used for every menu\-like object (e\.g\. the window created by the \fBWindowList\fR command) that had not be assigned a style using the \fBChangeMenuStyle\fR\. See also \fBDestroyMenuStyle\fR\. When using monochrome color options are ignored\. .PP \fIoptions\fR is a comma separated list containing some of the keywords Fvwm / Mwm / Win, BorderWidth, Foreground, Background, Greyed, HilightBack / !HilightBack, HilightTitleBack, ActiveFore / !ActiveFore, MenuColorset, ActiveColorset, GreyedColorset, TitleColorset, Hilight3DThick / Hilight3DThin / Hilight3DOff, Hilight3DThickness, Animation / !Animation, Font, TitleFont, MenuFace, PopupDelay, PopupOffset, TitleWarp / !TitleWarp, TitleUnderlines0 / TitleUnderlines1 / TitleUnderlines2, SeparatorsLong / SeparatorsShort, TrianglesSolid / TrianglesRelief, PopupImmediately / PopupDelayed, PopdownImmediately / PopdownDelayed, PopupActiveArea, DoubleClickTime, SidePic, SideColor, PopupAsRootMenu / PopupAsSubmenu / PopupIgnore / PopupClose, RemoveSubmenus / HoldSubmenus, SubmenusRight / SubmenusLeft, SelectOnRelease, ItemFormat, VerticalItemSpacing, VerticalMargins, VerticalTitleSpacing, AutomaticHotkeys / !AutomaticHotkeys, UniqueHotkeyActivatesImmediate / !UniqueHotkeyActivatesImmediate, MouseWheel, ScrollOffPage / !ScrollOffPage, TrianglesUseFore / !TrianglesUseFore\. .PP In the above list some options are listed as option pairs or triples with a '/' in between\. These options exclude each other\. All paired options can be negated to have the effect of the counterpart option by prefixing ! to the option\. .PP Some options are now negated by prefixing ! to the option\. This is the preferred form for all such options\. The other negative forms are now deprecated and will be removed in the future\. .PP This is a list of MenuStyle deprecated negative options: ActiveForeOff, AnimationOff, AutomaticHotkeysOff, HilightBackOff, TitleWarpOff .PP \fIFvwm\fR, \fIMwm\fR, \fIWin\fR reset all options to the style with the same name in former versions of fvwm\. The default for new menu styles is \fIFvwm\fR style\. These options override all others except \fIForeground\fR, \fIBackground\fR, \fIGreyed\fR, \fIHilightBack\fR, \fIActiveFore\fR and \fIPopupDelay\fR, so they should be used only as the first option specified for a menu style or to reset the style to defined behavior\. The same effect can be created by setting all the other options one by one\. .PP \fIMwm\fR and \fIWin\fR style menus popup sub menus automatically\. \fIWin\fR menus indicate the current menu item by changing the background to dark\. \fIFvwm\fR sub menus overlap the parent menu, \fIMwm\fR and \fIWin\fR style menus never overlap the parent menu\. .PP \fIFvwm\fR style is equivalent to !HilightBack, Hilight3DThin, !ActiveFore, !Animation, Font, MenuFace, PopupOffset 0 67, TitleWarp, TitleUnderlines1, SeparatorsShort, TrianglesRelief, PopupDelayed, PopdownDelayed, PopupDelay 150, PopdownDelay 150, PopupAsSubmenu, HoldSubmenus, SubmenusRight, BorderWidth 2, !AutomaticHotkeys, UniqueHotkeyActivatesImmediate, PopupActiveArea 75\. .PP \fIMwm\fR style is equivalent to !HilightBack, Hilight3DThick, !ActiveFore, !Animation, Font, MenuFace, PopupOffset \-3 100, !TitleWarp, TitleUnderlines2, SeparatorsLong, TrianglesRelief, PopupImmediately, PopdownDelayed, PopdownDelay 150, PopupAsSubmenu, HoldSubmenus, SubmenusRight, BorderWidth 2, UniqueHotkeyActivatesImmediate, !AutomaticHotkeys, PopupActiveArea 75\. .PP \fIWin\fR style is equivalent to HilightBack, Hilight3DOff, ActiveFore, !Animation, Font, MenuFace, PopupOffset \-5 100, !TitleWarp, TitleUnderlines1, SeparatorsShort, TrianglesSolid, PopupImmediately, PopdownDelayed, PopdownDelay 150, PopupAsSubmenu, RemoveSubmenus, SubmenusRight, BorderWidth 2, UniqueHotkeyActivatesImmediate, !AutomaticHotkeys, PopupActiveArea 75\. .PP \fIBorderWidth\fR takes the thickness of the border around the menus in pixels\. It may be zero to 50 pixels\. The default is 2\. Using an illegal value reverts the border width to the default\. .PP \fIForeground\fR and \fIBackground\fR may have a color name as an argument\. This color is used for menu text or the menu's background\. You can omit the color name to reset these colors to the built\-in default\. .PP \fIGreyed\fR may have a color name as an argument\. This color is the one used to draw a menu\-selection which is prohibited (or not recommended) by the Mwm hints which an application has specified\. If the color is omitted the color of greyed menu entries is based on the background color of the menu\. .PP \fIHilightBack\fR and \fI!HilightBack\fR switch hilighting the background of the selected menu item on and off\. A specific background color may be used by providing the color name as an argument to \fIHilightBack\fR\. If you use this option without an argument the color is based on the menu's background color\. The \fIActiveColorset\fR option overrides the specified color\. If the colorset has a non solid background it is used for the hilighting\. .PP \fIHilightTitleBack\fR switches hilighting the background of menu titles on\. If a \fITitleColorset\fR was used, the background colour is taken from there\. Otherwise the color is based on the menu's background color\. If the colorset has a non solid background it is used for the hilighting\. .PP \fIActiveFore\fR and \fI!ActiveFore\fR switch hilighting the foreground of the selected menu item on and off\. A specific foreground color may be used by providing the color name as an argument to \fIActiveFore\fR\. Omitting the color turns hilighting on when an \fIActiveColorset\fR is used\. \fIActiveFore\fR turns off hilighting the foreground completely\. The \fIActiveColorset\fR option overrides the specified color\. .PP \fIMenuColorset\fR controls if a colorset is used instead of the \fIForeground\fR, \fIBackground\fR and \fIMenuFace\fR menu styles\. If the \fIMenuColorset\fR keyword is followed by a number equal to zero or greater, this number is taken as the number of the colorset to use\. If the number is omitted, the colorset is switched off and the regular menu styles are used again\. The foreground and background colors of the menu items are replaced by the colors from the colorset\. If the colorset has a pixmap defined, this pixmap is used as the background of the menu\. Note that the \fIMenuFace\fR menu style has been optimized for memory consumption and may use less memory than the background from a colorset\. The shape mask from the colorset is used to shape the menu\. Please refer to the \fBColorsets\fR section for details about colorsets\. .PP \fIActiveColorset\fR works exactly like \fIMenuColorset\fR, but the foreground from the colorset replaces the color given with the \fIActiveFore\fR menu style and the colorset's background color replaces the color given with the \fIHilightBack\fR command (to turn on background hilighting you have to use the \fIHilightBack\fR menu style too)\. If specified, the hilight and shadow colors from the colorset are used too\. The pixmap and shape mask from the colorset are not used\. Hilighting the background or foreground can be turned off individually with the \fI!ActiveFore\fR or \fI!HilightBack\fR menu styles\. .PP \fIGreyedColorset\fR works exactly like \fIMenuColorset\fR, but the foreground from the colorset replaces the color given with the \fIGreyed\fR menu style\. No other parts of the colorset are used\. .PP \fITitleColorset\fR works exactly like \fIMenuColorset\fR, but is used only for menu titles\. .PP \fIHilight3DThick\fR, \fIHilight3DThin\fR and \fIHilight3DOff\fR determine if the selected menu item is hilighted with a 3D relief\. Thick reliefs are two pixels wide, thin reliefs are one pixel wide\. .PP \fIHilight3DThickness\fR takes one numeric argument that may be between \-50 and +50 pixels\. With negative values the menu item gets a pressed in look\. The above three commands are equivalent to a thickness of 2, 1 and 0\. .PP \fIAnimation\fR and \fI!Animation\fR turn menu animation on or off\. When animation is on, sub menus that do not fit on the screen cause the parent menu to be shifted to the left so the sub menu can be seen\. .PP \fIFont\fR and \fITitleFont\fR take a font name as an argument\. If a font by this name exists it is used for the text of all menu items\. If it does not exist or if the name is left blank the built\-in default is used\. If a \fITitleFont\fR is given, it is used for all menu titles instead of the normal font\. .PP \fIMenuFace\fR enforces a fancy background upon the menus\. You can use the same options for \fIMenuFace\fR as for the \fBButtonStyle\fR\. See description of \fBButtonStyle\fR command and the \fBColor Gradients\fR sections for more information\. If you use \fIMenuFace\fR without arguments the style is reverted back to normal\. .PP Some examples of MenuFaces are: .sp .RS 4 .nf MenuFace DGradient 128 2 lightgrey 50 blue 50 white MenuFace TiledPixmap texture10\.xpm MenuFace HGradient 128 2 Red 40 Maroon 60 White MenuFace Solid Maroon .fi .RE .PP Note: The gradient styles H, V, B and D are optimized for high speed and low memory consumption in menus\. This is not the case for all the other gradient styles\. They may be slow and consume huge amounts of memory, so if you encounter performance problems with them you may be better off by not using them\. To improve performance you can try one or all of the following: .PP Turn hilighting of the active menu item other than foreground color off: .sp .RS 4 .nf MenuStyle Stripping namespace from DocBook 5 document. Processing stripped document. Unable to strip the namespace from DB5 document, cannot proceed. ID ' ' not found in document. 0 fvwm-2.6.7/doc/docbook-xsl/html/sections.xsl0000644000175700017570000005365012753310630015771 00000000000000
1 2 3 4 5
6 clear: both 1 1 2 3 4 5 6
fvwm-2.6.7/doc/docbook-xsl/html/footnote.xsl0000644000175700017570000002304112753310630015766 00000000000000 #ftn. [ ] [ ] #ftn. [ ] ftn. #

[ ]

ftn. # [ ]


The following annotations are from this essay. You are seeing them here because your browser doesn’t support the user-interface techniques used to make them appear as ‘popups’ on modern browsers.

Warning: footnote number may not be generated correctly; unexpected as first child of footnote.
fvwm-2.6.7/doc/docbook-xsl/html/keywords.xsl0000644000175700017570000000222112753310630015775 00000000000000 , fvwm-2.6.7/doc/docbook-xsl/html/graphics.xsl0000644000175700017570000015335412753310630015744 00000000000000 1 1
0 0 0 1 0 1.0 1.0 1.0 px px px px 0 0 middle Warning: imagemaps not supported on scaled images 0 middle height: px
background-color:
calspair , , , Warning: only calspair or otherunits='imagemap' supported in imageobjectco
middle
No insertfile extension available.
No insertfile extension available.
No insertfile extension available.
fvwm-2.6.7/doc/docbook-xsl/html/qandaset.xsl0000644000175700017570000003311412753310630015733 00000000000000
1%
fvwm-2.6.7/doc/docbook-xsl/html/admon.xsl0000644000175700017570000001037612753310630015236 00000000000000 25 note warning caution tip important note Note Warning Caution Tip Important Note
:
[{$alt}]

fvwm-2.6.7/doc/docbook-xsl/html/formal.xsl0000644000175700017570000003111712753310630015414 00000000000000 1


-float

-float
before Broken table: tr descendent of CALS Table. before Broken table: row descendent of HTML table. before before
float: ;
fvwm-2.6.7/doc/docbook-xsl/html/titlepage.xsl0000644000175700017570000007516312753310630016123 00000000000000








copyright

,















: ,





3 2 RevHistory
,  



fvwm-2.6.7/doc/docbook-xsl/html/biblio.xsl0000644000175700017570000011430512753310630015375 00000000000000

No bibliography entry: found in

Error: no bibliography entry: found in

No bibliography entry: found in

Error: no bibliography entry: found in

[ ] [ ] [ ] [ ] [ ] copyright ,
fvwm-2.6.7/doc/docbook-xsl/html/ebnf.xsl0000644000175700017570000002354712753310630015056 00000000000000 $Id$ Walsh Norman 19992000 Norman Walsh HTML EBNF Reference
Introduction This is technical reference documentation for the DocBook XSL Stylesheets; it documents (some of) the parameters, templates, and other elements of the stylesheets. This reference describes the templates and parameters relevant to formatting EBNF markup. This is not intended to be user documentation. It is provided for developers writing customization layers for the stylesheets, and for anyone who's interested in how it works. Although I am trying to be thorough, this documentation is known to be incomplete. Don't forget to read the source, too :-)
1 EBNF for
EBNF productions
[ ]
  Error: no ID for productionrecap linkend: . Warning: multiple "IDs" for productionrecap linkend: . |
production Non-terminals with no content must point to production elements in the current document. Invalid xpointer for empty nt: ??? /*   */
constraintdef : :  ]

fvwm-2.6.7/doc/docbook-xsl/html/html.xsl0000644000175700017570000002050312753310630015075 00000000000000 # # bullet bullet © ® (SM)   ID recommended on : ... fvwm-2.6.7/doc/docbook-xsl/html/pi.xsl0000644000175700017570000002031512753310630014542 00000000000000 filename filename dir / /
No cmdsynopsis elements matched dbcmdlist PI, perhaps it's nested too deep?
No funcsynopsis elements matched dbfunclist PI, perhaps it's nested too deep?
href ERROR: dbhtml-include processing instruction href has no content. ERROR: dbhtml-include processing instruction has missing or empty href value. fvwm-2.6.7/doc/docbook-xsl/VERSION0000644000175700017570000000660412753310630013513 00000000000000 docbook-xsl 1.72.0 6553 $Revision$ DocBook XSL Stylesheets snapshot_6661 Major feature enhancements http://sourceforge.net/projects/docbook/ http://prdownloads.sourceforge.net/docbook/{DISTRONAME-VERSION}.tar.gz?download http://prdownloads.sourceforge.net/docbook/{DISTRONAME-VERSION}.zip?download http://prdownloads.sourceforge.net/docbook/{DISTRONAME-VERSION}.bz2?download http://sourceforge.net/project/shownotes.php?release_id={SFRELID} http://docbook.cvs.sourceforge.net/docbook/ http://lists.oasis-open.org/archives/docbook-apps/ This is a bug-fix release with a few feature enhancements. You must specify the sf-relid as a parameter. : : : fvwm-2.6.7/doc/docbook-xsl/highlighting/0000755000175700017570000000000013010103345015150 500000000000000fvwm-2.6.7/doc/docbook-xsl/highlighting/Makefile.am0000644000175700017570000000003312773470550017144 00000000000000EXTRA_DIST = \ common.xsl fvwm-2.6.7/doc/docbook-xsl/highlighting/Makefile.in0000644000175700017570000003506713010103322017143 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/docbook-xsl/highlighting DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ EXTRA_DIST = \ common.xsl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/docbook-xsl/highlighting/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/docbook-xsl/highlighting/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/doc/docbook-xsl/highlighting/common.xsl0000644000175700017570000000403112753310630017120 00000000000000 fvwm-2.6.7/doc/docbook-xsl/manpages/0000755000175700017570000000000013010103346014277 500000000000000fvwm-2.6.7/doc/docbook-xsl/manpages/charmap.groff.xsl0000644000175700017570000045305312753310630017507 00000000000000 fvwm-2.6.7/doc/docbook-xsl/manpages/Makefile.am0000644000175700017570000000036012773470550016275 00000000000000EXTRA_DIST = \ ChangeLog.20020917 \ block.xsl \ charmap.groff.xsl \ docbook.xsl \ endnotes.xsl \ html-synop.xsl \ info.xsl \ inline.xsl \ lists.xsl \ other.xsl \ param.xsl \ refentry.xsl \ synop.xsl \ table.xsl \ utility.xsl fvwm-2.6.7/doc/docbook-xsl/manpages/lists.xsl0000644000175700017570000003137012753310630016122 00000000000000 \n(zqu .sp .PP .PP .br .RS .RE .sp .sp .RS \h'- 0 ' \h'+ 0 ' .RE .sp .RS \h'- 0 ' \h'+ 0 ' .RE .PP .sp .RE .PP .IP "" , .IP "" .PP .\" line length increase to cope w/ tbl weirdness .ll +(\n(LLu * 62u / 100u) .TS l . .TE .\" line length decrease back to previous value .ll -(\n(LLu * 62u / 100u) .sp T{ T} fvwm-2.6.7/doc/docbook-xsl/manpages/Makefile.in0000644000175700017570000003540013010103322016260 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/docbook-xsl/manpages DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ EXTRA_DIST = \ ChangeLog.20020917 \ block.xsl \ charmap.groff.xsl \ docbook.xsl \ endnotes.xsl \ html-synop.xsl \ info.xsl \ inline.xsl \ lists.xsl \ other.xsl \ param.xsl \ refentry.xsl \ synop.xsl \ table.xsl \ utility.xsl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/docbook-xsl/manpages/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/docbook-xsl/manpages/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/doc/docbook-xsl/manpages/table.xsl0000644000175700017570000006667112753310630016067 00000000000000 : allbox center expand
.PP . *[nested▀table] .sp -1n .TS H tab( ) ; .TH .T& .TE .sp
T{ T} Warn tbl convert : Extracted a nested table [\fInested▀table\fR]* . ^ c r n l t ^ s .br ftn. # [ ]
fvwm-2.6.7/doc/docbook-xsl/manpages/synop.xsl0000644000175700017570000002641312753310630016136 00000000000000 | ( ) .sp -1n .HP ( ) .br▒ .ad l .hy 0 .HP .ad .hy .ad l .hy 0 .ad .hy .HP . " ( " void); ...); , ); "░" "░" ( ) fvwm-2.6.7/doc/docbook-xsl/manpages/inline.xsl0000644000175700017570000001260112753310630016236 00000000000000 ( ) © ® fvwm-2.6.7/doc/docbook-xsl/manpages/info.xsl0000644000175700017570000006340312753310630015721 00000000000000 \n(zqu < > .SH " Author Authors " .PP .br .PP .PP .PP .sp -1n .IP "" . <\& \&> , .br , .br .br .sp -1n .IP "" . .sp -1n .IP "" . .sp -1n .IP "" . . .sp -1n .IP "" .PP .br .SH " Copyright " .br .br fvwm-2.6.7/doc/docbook-xsl/manpages/refentry.xsl0000644000175700017570000002402712753310630016623 00000000000000 .br .SH " " , - .SH " " .SH " " .SS " " .RS .RE .RS .RE .ti (\n(SNu * 5u / 3u) (\n(SNu) .RS (\n(SNu) .RE fvwm-2.6.7/doc/docbook-xsl/manpages/param.xsl0000644000175700017570000001750412753310630016067 00000000000000 0 0 0 0 0 0 4 BI B B B MAN.MANIFEST man/ 1 1 1 , 0 @*[local-name() = 'block'] = 'Miscellaneous Technical' or (@*[local-name() = 'block'] = 'C1 Controls And Latin-1 Supplement (Latin-1 Supplement)' and @*[local-name() = 'class'] = 'symbols' ) or (@*[local-name() = 'block'] = 'General Punctuation' and (@*[local-name() = 'class'] = 'spaces' or @*[local-name() = 'class'] = 'dashes' or @*[local-name() = 'class'] = 'quotes' or @*[local-name() = 'class'] = 'bullets' ) ) or @*[local-name() = 'name'] = 'HORIZONTAL ELLIPSIS' or @*[local-name() = 'name'] = 'WORD JOINER' or @*[local-name() = 'name'] = 'SERVICE MARK' or @*[local-name() = 'name'] = 'TRADE MARK SIGN' or @*[local-name() = 'name'] = 'ZERO WIDTH NO-BREAK SPACE' ---- ======================================================================== 0 0 0 0 0 0 0 (($info[//date])[last()]/date)[1]| (($info[//pubdate])[last()]/pubdate)[1] refmeta/refmiscinfo[1]/node() (($info[//title])[last()]/title)[1]| ../title/node() refmeta/refmiscinfo[1]/node() (($info[//productname])[last()]/productname)[1]| (($info[//corpname])[last()]/corpname)[1]| (($info[//corpcredit])[last()]/corpcredit)[1]| (($info[//corpauthor])[last()]/corpauthor)[1]| (($info[//orgname])[last()]/orgname)[1]| (($info[//publishername])[last()]/publishername)[1] (($info[//productnumber])[last()]/productnumber)[1]| (($info[//edition])[last()]/edition)[1]| (($info[//releaseinfo])[last()]/releaseinfo)[1] 20 30 30 0 0 0 1 fvwm-2.6.7/doc/docbook-xsl/manpages/ChangeLog.200209170000644000175700017570000001532212753310630016710 00000000000000Note: This changelog is a record of descriptions of all changes made to the DocBook XSL manpages stylesheets during the time when they were maintained in their original home in the [cvs]/docbook/contrib/xsl/db2man area of the DocBook Project source-code repository at Sourceforge; that is, from October 2001 (when they were contributed to the project by Martijn van Beers) until September 2002 (when they were moved to the [cvs]/docbook/xsl/manpages area and became a standard part of all subsequent DocBook XSL Stylesheets releases). 2002-09-17 Norman Walsh * README, db2man.xsl, lists.xsl, sect23.xsl, synop.xsl, xref.xsl: Moved to docbook/xsl/manpages * db2man.xsl, synop.xsl: Patch from Joe Orton 2002-06-16 * db2man.xsl: commit patch sent by Joe Orton: This patch adds support for using the productname, date and title out of a if one is present, rather than having to add each of these individually for every refentry. * db2man.xsl: Tim Waugh sent: This patch normalizes space in each refname before displaying it in the name section. 2002-05-21 * xref.xsl: from Joe Orton: this patch allows cross-referencing to a specific refname. I need this since I'm documenting several different (but related) functions per refentry, and want to cross-reference them individually, rather than just by the title used for the refentry as a whole. 2002-05-17 * lists.xsl: apply glosslist support patch from twaugh 2002-05-15 * db2man.xsl: slightly sanitize the filenames we generate. again from twaugh * db2man.xsl: Apply twaugh's fix for making the entity transform stuff work 2002-05-14 * db2man.xsl: generalize the tip template for all admonitions (caution,important,note,tip,warning) * db2man.xsl: Apply Joe Orton's patch, modified to be indented. Also show "Tip" in the title. so if foo, you get Tip: foo * synop.xsl: rewrote funcprototype. It used to convert all its children to a single string and the split it up again through recursion. Now has a nice foreach loop for the paramdefs, which seems much cleaner than throwing everything in a big string before processing it. 2002-05-10 * db2man.xsl: add support for simpara * db2man.xsl, lists.xsl: fix refsect2 titles * synop.xsl: also from twaugh: I found some input that goes wrong with the synop.xsl we have in CVS: -o FILE --output=FILE It gets rendered as (with *bold* and _italic_): [*-o FILE* | *--output=FILE*] The desired markup should look like: The following macro does the trick: [\fB-o \fIFILE\fR\fR | \fB--output=\fIFILE\fR\fR] The trouble is that the named template 'bold' uses value-of, and so strips of its significance. Another thing I found is that the arg/replaceable template is superfluous altogether: db2man.xsl has a 'replaceable' template which does the same thing. Here is a patch to make those two modifications. NOTE TO SELF: must try to fix bold template so we can use it everywhere 2002-05-09 * db2man.xsl: oops, removed too much * db2man.xsl: remove stuff that's apparently left-over from sect23.xsl * db2man.xsl, lists.xsl, synop.xsl: batch of patches from twaugh: * This patch (based on one from Jirka Kosek) adds support for block-level elements inside s---s for example, or lists. * This patch replaces entities (like '舒') with sensible characters or groups of characters. * This patch adds support for sbr. * This patch normalizes spaces in varlistentry terms. * This patch normalizes spaces in terminal varlistentry terms. * This patch allows variable lists to be nested (once). * This patch prevents variable list item paragraphs from merging into one another. * This patch improves the rendering of itemized lists, and adds support for ordered lists and procedures. * This patch makes some small adjustments to group/arg: don't put extra spaces in where they aren't needed, and normalize the space of $arg. * This patch makes adjustments to cmdsynopsis elements. In particular, they can now be wrapped if no is provided. * This patch adds funcsynopsis//* support. Again, wrapping is done automatically. * synop.xsl: make synopsises work for --arg=foo s too * synop.xsl: remove unneccesary adding of whitespace for arg/replaceable 2002-05-01 * db2man.xsl: This patch adds support for multiple refnames. (another twaugh patch) * db2man.xsl: modified ulink patch from twaugh. Be nice to content-less ulinks. But we don't accomodate silly people who don't understand ulink and put the url as the content too. * db2man.xsl, synop.xsl: db2man.xsl: * temporarily add some params that chunker.xsl needs * fix bold/italic templates * update calls to bold/italic templates for new syntax synop.xsl: * add support for synopfragment * update calls to bold/italic templates for new syntax 2002-04-30 * db2man.xsl: Add twaug's patch for xref support * db2man.xsl: This patch adds support for: - Multiple authors. - A (single) man page editor. (another patch from twaugh) * db2man.xsl: more twaugh patches: - Use refentrytitle, not refname[1], for title. - Upper-case it. - Use date, productname, and title. - Pick up author from main document if not contained in refentry. - Use refname[1] for man page filename, not refentrytitle. * db2man.xsl: add varname support * db2man.xsl: This patch makes userinput (an inline element) have inline formatting. * db2man.xsl: This patch adds support for the top-level document being something other than an article. It also emits a helpful warning if no refentry elements are found. * db2man.xsl: next twaugh patch: Instead of writing to stdout, create a file for each refentry. Plus, for bonus points, a file for each additional refname within that entry (pointing to the main page). * db2man.xsl: Add named templates for bold-ifying and italicizing stuff. Inspired by yet another twaugh patch * db2man.xsl, lists.xsl, sect23.xsl: consistently use instead of a newline * db2man.xsl, synop.xsl: * add support for informalexample, screen, errorcode, constant, type, quote, programlisting and citerefentry * use the 'bold' and 'italic' named templates * xref.xsl: New file. 2001-12-01 Norman Walsh * README, db2man.xsl, lists.xsl, sect23.xsl, synop.xsl: New file. fvwm-2.6.7/doc/docbook-xsl/manpages/other.xsl0000644000175700017570000007121512753310630016107 00000000000000 \ \e . \. - \- ' \'   \ .\" Title: .\" Author: .\" Generator: DocBook v <http://docbook.sf.net/> .\" Date: .\" Manual: .\" Source: .\" .TH " " " " " " " " " " .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" store initial "default indentation value" .nr zq \n(IN .\" adjust default indentation .nr IN .\" adjust indentation of SS headings .nr SN \n(IN .\" enable line breaks after slashes .cflags 4 / Note: Note: (soelim stub) Note: (manifest file) fvwm-2.6.7/doc/docbook-xsl/manpages/block.xsl0000644000175700017570000002455112753310630016061 00000000000000 .PP . .sp .RS 4n .PP .RE .sp Yes .sp .RS .ft .nf .fi .ft .nf .fi .RE .sp before .PP .sp .RS .RE [IMAGE] [ ] fvwm-2.6.7/doc/docbook-xsl/manpages/docbook.xsl0000644000175700017570000003011612753310630016401 00000000000000 MAN.MANIFEST Note: No refentry elements found in " ... " fvwm-2.6.7/doc/docbook-xsl/manpages/endnotes.xsl0000644000175700017570000004726312753310630016613 00000000000000 \% \&[ ] .SH " " .IP " . " .RS \% .RE fvwm-2.6.7/doc/docbook-xsl/manpages/utility.xsl0000644000175700017570000004517312753310630016475 00000000000000 \fB \fR \fI \fR \% .sp .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .sp .RS .RE .\" fvwm-2.6.7/doc/docbook-xsl/manpages/html-synop.xsl0000644000175700017570000013423512753310630017102 00000000000000

. . ( )  

( )

⌂sp ⌂nf
    
    
  
⌂fi

.

( ) ; ... ) ; , ) ; . ; ( )
 
padding-bottom: 1em
( ) ;   ... ) ;   , ) ;       ; ( ) ;

( void) ; ... ) ; , ) ; ( ) padding-bottom: 1em
 
( void) ;   ... ) ;     , ) ;   , ) ; ( ) java Unrecognized language on : . ⌂sp ⌂nf
    
    
    
       extends
      
      
        
.

	    
      
    
    
      implements
      
      
        
.

	    
      
    
    
      throws
      
    
     {
    
.

    
    }
  
⌂fi
,   , , ,    ;     void  0 , .      ( ) .     throws  ; ⌂sp ⌂nf
    
    
    
      : 
      
      
        
.

	    
      
    
    
       implements
      
      
        
.

	    
      
    
    
       throws
      
    
     {
    
.

    
    }
  
⌂fi
,   , , ,    ;     void  ,    ( ) .     throws  ; ⌂sp ⌂nf
    
    interface 
    
    
      : 
      
      
        
.

	    
      
    
    
       implements
      
      
        
.

	    
      
    
    
       throws
      
    
     {
    
.

    
    }
  
⌂fi
,   , , ,    ;     void  ,    ( ) .     raises( ) ; ⌂sp ⌂nf
    
    package 
    
    ;
    
.


    
      @ISA = (
      
      );
      
.

    

    
  
⌂fi
,   , , ,    ;     void  , sub { ... };
fvwm-2.6.7/doc/docbook-xsl/profiling/0000755000175700017570000000000013010103346014475 500000000000000fvwm-2.6.7/doc/docbook-xsl/profiling/Makefile.am0000644000175700017570000000006012773470550016470 00000000000000EXTRA_DIST = \ profile-mode.xsl \ profile.xsl fvwm-2.6.7/doc/docbook-xsl/profiling/Makefile.in0000644000175700017570000003510313010103322016456 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/docbook-xsl/profiling DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ EXTRA_DIST = \ profile-mode.xsl \ profile.xsl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/docbook-xsl/profiling/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/docbook-xsl/profiling/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/doc/docbook-xsl/profiling/profile-mode.xsl0000644000175700017570000002013712753310630017543 00000000000000 1 fvwm-2.6.7/doc/docbook-xsl/profiling/profile.xsl0000644000175700017570000000342512753310630016622 00000000000000 fvwm-2.6.7/doc/README0000644000175700017570000000750312753310630011076 00000000000000# Author: Scott Smedley This directory contains fvwm XML documentation. It is configured to output an fvwm.1 man page & a plethora of HTML files - all from the same (XML) source. By default, only the man page is generated. If you would like to generate the HTML documentation, use: $ ./configure --enable-htmldoc If you do not want to generate the man page, use: $ ./configure --disable-mandoc Once it is built, you should be able to point your web browser to: file:///usr/local/share/doc/fvwm/index.html (Change "/usr/local" if you use ./configure --prefix="...".) For developers, the XML source files supersede the old fvwm man page. Please make any documentation changes here & NOT in the fvwm/fvwm.1.in file. If you are editing the documentation for an fvwm command, you will find an XML file relating to that command in the doc/command/ directory. Any other documentation changes (e.g. general description) will most likely need to be made in the doc/fvwm directory. The XML syntax is intuitive - a cursory inspection of a few XML files should suffice to allow even a novice user to make their changes. However, there are a few idiosyncrasies worth pointing out: Formatting instructions ======================= * The name fvwm is spelled "fvwm". At the beginning of a sentence or in other places where nouns are capitalized: "Fvwm". It's *never* spelled "FVWM". * Use when referring to an fvwm command, e.g.: This will create a link to the Style command (in HTML output). Caveat: don't use to reference commands that are actually being described. ie. In the Style.xml file, you won't see any s to the Style command. * Use when _referring_ to an fvwm command option, e.g.: when _describing_ an option to a command, e.g.: This will highlight the option name & allow the option to be referenced elsewhere. * Use when referring to an fvwm module, e.g.: This will create a link to the FvwmPager module (in HTML output). * Use when refering to a different section. * Use <... output="html"> to wrap text that should only appear in HTML output. E.g. This text only appears in HTML. * Use <... output="man"> to wrap text that should only only appear in man-page output, e.g. This text only appears in man page. * Use for filenames. * Use for environment variables. * Use for links to web pages. * Use for acronyms. * Use for key names. How to add documentation for a new fvwm command =============================================== 1. Copy a similar command, e.g. $ cd doc/commands && cp Echo.xml EchoFuncDefinition.xml 2. Edit contents appropriately. Make sure the section id, title and cmdsynopsis are correct. 3. Ensure the new command appears in the appropriate section of the man page, e.g. this line is included in fvwm/userFunctions.xml: 4. Add the new command to groupedCommands.html. 5. Add the new command to allCommands.html - this content is auto-generated by a script in the util/ subdirectory. First add the command name to the alphabetically sorted util/cmds.txt file, then run: $ cd doc/util $ ./genAllCommands.pl cmds.txt 7. Add a ChangeLog entry to doc/ChangeLog. fvwm-2.6.7/tests/0000755000175700017570000000000013010103346010655 500000000000000fvwm-2.6.7/tests/Makefile.am0000644000175700017570000000040412773470550012652 00000000000000## This is a -*- Makefile -*- ## Process this file with automake to create Makefile.in SUBDIRS = hints EXTRA_DIST = README.test_options test_options ## The files in the purify subdir are NOT distributed, due to controversy over ## the benefits of doing so. fvwm-2.6.7/tests/README.test_options0000644000175700017570000000125512673746443014242 00000000000000Run the test_options script from this directory. It will configure and build fvwm multiple times for every selected combination of configure options. Parameters: -0: build once with all options disabled/enabled (2 builds) -1: build once with any single option disabled/enabled (2 builds per option) -2: build once with any combination of two options disabled/enabled (n * n + n builds where n is the number of options) -a: all tests (2 ^ n builds) The default is 'test_options -0 -1' since '-2' can take a very long time. A summary logfile test_options.log is generated as well as an additional log for each build (test_options.log.*). The names are self explaining. fvwm-2.6.7/tests/Makefile.in0000644000175700017570000005140113010103323012636 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ SUBDIRS = hints EXTRA_DIST = README.test_options test_options all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/tests/hints/0000755000175700017570000000000013010103346012002 500000000000000fvwm-2.6.7/tests/hints/Makefile.am0000644000175700017570000000042012773470550013775 00000000000000## Process this file with automake to create Makefile.in # Don't install this, its just for testing. noinst_PROGRAMS = hints_test LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm \ $(X_PRE_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) fvwm-2.6.7/tests/hints/Makefile.in0000644000175700017570000004623213010103323013771 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = hints_test$(EXEEXT) subdir = tests/hints DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/etc/depcomp README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) hints_test_SOURCES = hints_test.c hints_test_OBJECTS = hints_test.$(OBJEXT) hints_test_LDADD = $(LDADD) am__DEPENDENCIES_1 = hints_test_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = hints_test.c DIST_SOURCES = hints_test.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm \ $(X_PRE_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/hints/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/hints/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) hints_test$(EXEEXT): $(hints_test_OBJECTS) $(hints_test_DEPENDENCIES) $(EXTRA_hints_test_DEPENDENCIES) @rm -f hints_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(hints_test_OBJECTS) $(hints_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hints_test.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/tests/hints/hints_test.c0000644000175700017570000004424712773467231014312 00000000000000/* -*-c-*- */ #include "config.h" #include #include #include #include #include #include #include "libs/FEvent.h" Display *dpy; Window Root, win; int screen; int has_focus_proto = 0; int has_delete_proto = 1; int input_mode = -1; Atom ATOM_NET_WM_WINDOW_TYPE = None; Atom ATOM_NET_WM_WINDOW_TYPE_DESKTOP = None; Atom ATOM_NET_WM_WINDOW_TYPE_DOCK = None; Atom ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = None; Atom ATOM_NET_WM_WINDOW_TYPE_MENU = None; Atom ATOM_NET_WM_WINDOW_TYPE_DIALOG = None; Atom ATOM_NET_WM_WINDOW_TYPE_NORMAL = None; Atom ATOM_NET_WM_WINDOW_TYPE_SPLASH = None; Atom ATOM_NET_WM_WINDOW_TYPE_UTILITY = None; Atom ATOM_KDE_NET_WM_WINDOW_TYPE_OVERRIDE = None; Atom ATOM_NET_WM_STATE = None; Atom ATOM_NET_WM_STATE_MODAL = None; Atom ATOM_NET_WM_STATE_STICKY = None; Atom ATOM_NET_WM_STATE_MAXIMIZED_VERT = None; Atom ATOM_NET_WM_STATE_MAXIMIZED_HORIZ = None; Atom ATOM_NET_WM_STATE_SHADED = None; Atom ATOM_NET_WM_STATE_SKIP_TASKBAR = None; Atom ATOM_NET_WM_STATE_SKIP_PAGER = None; Atom ATOM_NET_WM_STATE_HIDDEN = None; Atom ATOM_NET_WM_STATE_STAYS_ON_TOP = None; Atom ATOM_NET_WM_STATE_FULLSCREEN = None; Atom ATOM_NET_WM_DESKTOP = None; /* wm protocol */ Atom ATOM_WM_DELETE_WINDOW = None; Atom ATOM_WM_TAKE_FOCUS = None; /* Motif window hints */ Atom ATOM_MOTIF_WM_HINTS = None; #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) /* ? */ /* bit definitions for MwmHints.functions */ #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) /* values for MwmHints.input_mode */ #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 /* bit definitions for MwmHints.decorations */ #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) /* * _MWM_HINTS property */ typedef struct { long props[4]; /* props[0]: flags */ /* props[1]: functions */ /* props[2]: decorations */ /* props[3]: inputMode */ } PropMotifWmHints; typedef PropMotifWmHints PropMwmHints; #define PROP_MOTIF_WM_HINTS_ELEMENTS 4 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS void Xloop(void) { while (1) { XEvent ev; XWindowAttributes xatt; /* Sit and wait for an event to happen */ FNextEvent(dpy,&ev); switch(ev.type) { case ConfigureNotify: break; case ClientMessage: if (has_delete_proto && ev.xclient.format == 32 && ev.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW) { exit(0); } else if (has_focus_proto && ev.xclient.data.l[0] == ATOM_WM_TAKE_FOCUS) { printf("WM_TAKE_FOCUS message\n"); if (input_mode == 1) { printf ("\t...do nothing\n"); } else if (input_mode == 0) { if (XGetWindowAttributes(dpy, win, &xatt) && xatt.map_state == IsViewable) { printf ("\t...setting focus on our own: %lu\n", ev.xclient.data.l[1]); XSetInputFocus( dpy, win, RevertToParent, ev.xclient.data.l[1]); } else { printf ("\t...but we are not viewable\n"); } } } break; default: break; } } } #define XIA(a) XInternAtom(dpy,a,False); void InitAtom(void) { ATOM_NET_WM_WINDOW_TYPE = XIA("_NET_WM_WINDOW_TYPE"); ATOM_NET_WM_WINDOW_TYPE_DESKTOP = XIA("_NET_WM_WINDOW_TYPE_DESKTOP"); ATOM_NET_WM_WINDOW_TYPE_DOCK = XIA("_NET_WM_WINDOW_TYPE_DOCK"); ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = XIA("_NET_WM_WINDOW_TYPE_TOOLBAR"); ATOM_NET_WM_WINDOW_TYPE_MENU = XIA("_NET_WM_WINDOW_TYPE_MENU"); ATOM_NET_WM_WINDOW_TYPE_DIALOG = XIA("_NET_WM_WINDOW_TYPE_DIALOG"); ATOM_NET_WM_WINDOW_TYPE_NORMAL = XIA("_NET_WM_WINDOW_TYPE_NORMAL"); ATOM_NET_WM_WINDOW_TYPE_SPLASH = XIA("_NET_WM_WINDOW_TYPE_SPLASH"); ATOM_NET_WM_WINDOW_TYPE_UTILITY = XIA("_NET_WM_WINDOW_TYPE_UTILITY"); ATOM_KDE_NET_WM_WINDOW_TYPE_OVERRIDE = XIA("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"); ATOM_NET_WM_STATE = XIA("_NET_WM_STATE"); ATOM_NET_WM_STATE_MODAL = XIA("_NET_WM_STATE_MODAL"); ATOM_NET_WM_STATE_STICKY = XIA("_NET_WM_STATE_STICKY"); ATOM_NET_WM_STATE_MAXIMIZED_VERT = XIA("_NET_WM_STATE_MAXIMIZED_VERT"); ATOM_NET_WM_STATE_MAXIMIZED_HORIZ = XIA("_NET_WM_STATE_MAXIMIZED_HORIZ"); ATOM_NET_WM_STATE_SHADED = XIA("_NET_WM_STATE_SHADED"); ATOM_NET_WM_STATE_SKIP_TASKBAR = XIA("_NET_WM_STATE_SKIP_TASKBAR"); ATOM_NET_WM_STATE_SKIP_PAGER = XIA("_NET_WM_STATE_SKIP_PAGER"); ATOM_NET_WM_STATE_HIDDEN = XIA("_NET_WM_STATE_HIDDEN"); ATOM_NET_WM_STATE_FULLSCREEN = XIA("_NET_WM_STATE_FULLSCREEN"); ATOM_NET_WM_STATE_STAYS_ON_TOP = XIA("_NET_WM_STATE_STAYS_ON_TOP"); ATOM_NET_WM_DESKTOP = XIA("_NET_WM_DESKTOP"); ATOM_WM_DELETE_WINDOW = XIA("WM_DELETE_WINDOW"); ATOM_WM_TAKE_FOCUS = XIA("WM_TAKE_FOCUS"); ATOM_MOTIF_WM_HINTS = XIA("_MOTIF_WM_HINTS"); } void show_usage(void) { printf("Usage: hints_test OPTIONS\n"); printf("Options:\n"); printf(" --mwm-func \n"); printf(" all, resize, move, minimize, maximize, close\n"); printf(" --mwm-decor \n"); printf(" all, border, resizeh, title, menu, minimize, maximize\n"); printf(" --ewmh-state \n"); printf(" hidden, shaded, sticky, skippager, skiptaskbar,\n"); printf(" maxhoriz, maxvert, modal, staysontop, fullscreen\n"); printf(" --ewmh-type \n"); printf(" normal, dock, toolbar, desktop, menu, dialog, splash, utility\n"); printf(" --mwm-input { modless, app_modal, sys_modal, full_app_modal}\n"); printf(" --ewmh-desktop\n"); printf(" --wm-state { withdrawn, normal, iconic }\n"); printf(" --wm-urgency\n"); printf(" --wm-group { window, root, }\n"); printf(" --min-size \n"); printf(" --max-size \n"); printf(" --inc-size \n"); printf(" --p-geometry \n"); printf(" --us-geometry \n"); printf(" --input { true, false }\n"); printf(" --delete-proto\n"); printf(" --no-delete-proto\n"); printf(" --transient\n"); } int main(int argc, char **argv) { int state_count = 0; Atom states[10]; Atom type = 0; int i,x_r,y_r; unsigned int h_r,w_r; int ret; int ewmh_state_arg = 0; int ewmh_type_arg = 0; int mwm_func_arg = 0; int mwm_decor_arg = 0; int has_ewmh_desktop = 0; Atom ewmh_desktop = 0; XSizeHints hints; XClassHint classhints; XWMHints wm_hints; PropMwmHints mwm_hints; Window trans_win = 0; if (!(dpy = XOpenDisplay(""))) { fprintf(stderr, "can't open display\n"); exit(1); } screen = DefaultScreen(dpy); Root = RootWindow(dpy, screen); InitAtom(); hints.width = 170; hints.height = 100; hints.x = 0; hints.y = 0; hints.flags = 0; wm_hints.flags = 0; mwm_hints.props[0] = 0; mwm_hints.props[1] = 0; mwm_hints.props[2] = 0; mwm_hints.props[3] = 0; win = XCreateSimpleWindow( dpy, Root, 0, 0, hints.width, hints.height, 0, 0, 0); for (i = 1; i < argc; i++) { char *error_arg = NULL; if (strcasecmp(argv[i], "--help") == 0) { show_usage(); exit(0); } else if (strcasecmp(argv[i], "--ewmh-state") == 0) { ewmh_state_arg = 1; ewmh_type_arg = 0; mwm_func_arg = 0; mwm_decor_arg = 0; } else if (strcasecmp(argv[i], "--ewmh-type") == 0) { ewmh_state_arg = 0; ewmh_type_arg = 1; mwm_func_arg = 0; mwm_decor_arg = 0; } else if (strcasecmp(argv[i], "--mwm-func") == 0) { ewmh_state_arg = 0; ewmh_type_arg = 0; mwm_func_arg = 1; mwm_decor_arg = 0; } else if (strcasecmp(argv[i], "--mwm-decor") == 0) { ewmh_state_arg = 0; ewmh_type_arg = 0; mwm_func_arg = 0; mwm_decor_arg = 1; } else if (strcasecmp(argv[i], "--min-size") == 0) { i++; hints.min_width = atoi(argv[i]); i++; hints.min_height = atoi(argv[i]); hints.flags |= PMinSize; } else if (strcasecmp(argv[i], "--max-size") == 0) { i++; hints.max_width = atoi(argv[i]); i++; hints.max_height = atoi(argv[i]); hints.flags |= PMaxSize; } else if (strcasecmp(argv[i], "--inc-size") == 0) { i++; hints.width_inc = atoi(argv[i]); i++; hints.height_inc = atoi(argv[i]); hints.flags |= PResizeInc; } else if (strcasecmp(argv[i], "--p-geometry") == 0) { i++; ret = XParseGeometry(argv[i], &x_r, &y_r, &w_r, &h_r); if ((ret & WidthValue) && (ret & HeightValue)) { hints.width = w_r; hints.height = h_r; hints.flags |= PSize; } if ((ret & XValue) && (ret & YValue)) { hints.x = x_r; hints.y = y_r; hints.win_gravity = NorthWestGravity; if (ret & XNegative) { hints.x += XDisplayWidth(dpy, screen) - hints.width; hints.win_gravity = NorthEastGravity; } if (ret & YNegative) { hints.y += XDisplayHeight(dpy, screen) - hints.height; if (ret & XNegative) { hints.win_gravity = SouthEastGravity; } else { hints.win_gravity = SouthWestGravity; } hints.flags |= PWinGravity; } hints.flags |= PPosition; } } else if (strcasecmp(argv[i], "--us-geometry") == 0) { i++; ret = XParseGeometry(argv[i], &x_r, &y_r, &w_r, &h_r); if ((ret & WidthValue) && (ret & HeightValue)) { hints.width = w_r; hints.height = h_r; hints.flags |= USSize; } if ((ret & XValue) && (ret & YValue)) { hints.x = x_r; hints.y = y_r; hints.win_gravity=NorthWestGravity; if (ret & XNegative) { hints.x += XDisplayWidth(dpy,screen) - hints.width; hints.win_gravity=NorthEastGravity; } if (ret & YNegative) { hints.y += XDisplayHeight(dpy,screen) - hints.height; if (ret & XNegative) { hints.win_gravity = SouthEastGravity; } else { hints.win_gravity = SouthWestGravity; } } hints.flags |= USPosition | PWinGravity; } } else if (strcasecmp(argv[i], "--input") == 0) { i++; if (strcasecmp(argv[i], "true") == 0) { wm_hints.input = input_mode = True; wm_hints.flags |= InputHint; } else if (strcasecmp(argv[i], "false") == 0) { wm_hints.input = input_mode = False; wm_hints.flags |= InputHint; } else { error_arg = "--input"; } } else if (strcasecmp(argv[i], "--focus-proto") == 0) { has_focus_proto = 1; } else if (strcasecmp(argv[i], "--no-delete-proto") == 0) { has_delete_proto = 0; } else if (strcasecmp(argv[i], "--wm-state") == 0) { wm_hints.flags |= StateHint; i++; if (strcasecmp(argv[i], "withdrawn") == 0) { wm_hints.initial_state = WithdrawnState; } else if (strcasecmp(argv[i], "normal") == 0) { wm_hints.initial_state = NormalState; } else if (strcasecmp(argv[i], "iconic") == 0) { wm_hints.initial_state = IconicState; } else { error_arg = "--wm-state"; } } else if (strcasecmp(argv[i], "--wm-urgency") == 0) { wm_hints.flags |= XUrgencyHint; } else if (strcasecmp(argv[i], "--wm-group") == 0) { wm_hints.flags |= WindowGroupHint; i++; if (strcasecmp(argv[i], "window") == 0) { wm_hints.window_group = win; } else if (strcasecmp(argv[i], "root") == 0) { wm_hints.window_group = Root; } else { wm_hints.window_group = strtoul(argv[i], NULL, 0); } } else if (strcasecmp(argv[i], "--transient") == 0) { i++; if (strcasecmp(argv[i],"root") == 0) { trans_win = Root; } else { trans_win = strtoul(argv[i], NULL, 0); } } else if (strcasecmp(argv[i], "--mwm-input") == 0) { mwm_hints.props[0] |= MWM_HINTS_INPUT_MODE; i++; if (strcasecmp(argv[i], "modless") == 0) { mwm_hints.props[3] = MWM_INPUT_MODELESS; } else if (strcasecmp(argv[i], "app_modal") == 0) { mwm_hints.props[3] = MWM_INPUT_PRIMARY_APPLICATION_MODAL; } else if (strcasecmp(argv[i], "sys_modal") == 0) { mwm_hints.props[3] = MWM_INPUT_SYSTEM_MODAL; } else if (strcasecmp(argv[i], "full_app_modal") == 0) { mwm_hints.props[3] = MWM_INPUT_FULL_APPLICATION_MODAL; } else { error_arg = "--mwm-input"; } } else if (strcasecmp(argv[i], "--ewmh-desktop") == 0) { has_ewmh_desktop = 1; i++; ewmh_desktop = atol(argv[i]); } else if (ewmh_state_arg && state_count < 10) { if (strcasecmp(argv[i], "hidden") == 0) { states[state_count++] = ATOM_NET_WM_STATE_HIDDEN; } else if (strcasecmp(argv[i], "shaded") == 0) { states[state_count++] = ATOM_NET_WM_STATE_SHADED; } else if (strcasecmp(argv[i], "sticky") == 0) { states[state_count++] = ATOM_NET_WM_STATE_STICKY; } else if (strcasecmp(argv[i], "skippager") == 0) { states[state_count++] = ATOM_NET_WM_STATE_SKIP_PAGER; } else if (strcasecmp(argv[i], "skiptaskbar") == 0) { states[state_count++] = ATOM_NET_WM_STATE_SKIP_TASKBAR; } else if (strcasecmp(argv[i], "maxhoriz") == 0) { states[state_count++] = ATOM_NET_WM_STATE_MAXIMIZED_HORIZ; } else if (strcasecmp(argv[i], "maxvert") == 0) { states[state_count++] = ATOM_NET_WM_STATE_MAXIMIZED_VERT; } else if (strcasecmp(argv[i], "modal") == 0) { states[state_count++] = ATOM_NET_WM_STATE_MODAL; } else if (strcasecmp(argv[i], "staysontop") == 0) { states[state_count++] = ATOM_NET_WM_STATE_STAYS_ON_TOP; } else if (strcasecmp(argv[i], "fullscreen") == 0) { states[state_count++] = ATOM_NET_WM_STATE_FULLSCREEN; } else { error_arg = "--ewmh-state"; } } else if (ewmh_type_arg) { if (strcasecmp(argv[i], "normal") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_NORMAL; } else if (strcasecmp(argv[i], "dock") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_DOCK; } else if (strcasecmp(argv[i], "toolbar") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_TOOLBAR; } else if (strcasecmp(argv[i], "desktop") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_DESKTOP; } else if (strcasecmp(argv[i], "menu") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_MENU; } else if (strcasecmp(argv[i], "dialog") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_DIALOG; } else if (strcasecmp(argv[i], "splash") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_SPLASH; } else if (strcasecmp(argv[i], "utility") == 0) { type = ATOM_NET_WM_WINDOW_TYPE_UTILITY; } else { error_arg = "--ewmh-type"; } } else if (mwm_func_arg) { mwm_hints.props[0] |= MWM_HINTS_FUNCTIONS; if (strcasecmp(argv[i], "all") == 0) { mwm_hints.props[1] |= MWM_FUNC_ALL; } else if (strcasecmp(argv[i], "resize") == 0) { mwm_hints.props[1] |= MWM_FUNC_RESIZE; } else if (strcasecmp(argv[i], "move") == 0) { mwm_hints.props[1] |= MWM_FUNC_MOVE; } else if (strcasecmp(argv[i], "minimize") == 0) { mwm_hints.props[1] |= MWM_FUNC_MINIMIZE; } else if (strcasecmp(argv[i], "maximize") == 0) { mwm_hints.props[1] |= MWM_FUNC_MAXIMIZE; } else if (strcasecmp(argv[i], "close") == 0) { mwm_hints.props[1] |= MWM_FUNC_CLOSE; } else { error_arg = "--mwm-func"; } } else if (mwm_decor_arg) { mwm_hints.props[0] |= MWM_HINTS_DECORATIONS; if (strcasecmp(argv[i], "all") == 0) { mwm_hints.props[2] |= MWM_DECOR_ALL; } else if (strcasecmp(argv[i], "border") == 0) { mwm_hints.props[2] |= MWM_DECOR_BORDER; } else if (strcasecmp(argv[i], "resizeh") == 0) { mwm_hints.props[2] |= MWM_DECOR_RESIZEH; } else if (strcasecmp(argv[i], "title") == 0) { mwm_hints.props[2] |= MWM_DECOR_TITLE; } else if (strcasecmp(argv[i], "menu") == 0) { mwm_hints.props[2] |= MWM_DECOR_MENU; } else if (strcasecmp(argv[i], "minimize") == 0) { mwm_hints.props[2] |= MWM_DECOR_MINIMIZE; } else if (strcasecmp(argv[i], "maximize") == 0) { mwm_hints.props[2] |= MWM_DECOR_MAXIMIZE; } else { error_arg = "--mwm-decor"; } } else { error_arg = "regular"; } if (error_arg) { show_usage(); printf("Invalid %s argument: %s\n", error_arg, argv[i]); exit(1); } } XSelectInput(dpy, win, StructureNotifyMask); if (wm_hints.flags) { XSetWMHints(dpy, win, &wm_hints); } if (state_count != 0) { XChangeProperty( dpy, win, ATOM_NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)states, state_count); } if (type != 0) { XChangeProperty( dpy, win, ATOM_NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&type, 1); } if (has_ewmh_desktop) { XChangeProperty( dpy, win, ATOM_NET_WM_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ewmh_desktop, 1); } if (has_delete_proto || has_focus_proto) { Atom proto[2]; int j = 0; if (has_delete_proto) proto[j++] = ATOM_WM_DELETE_WINDOW; if (has_focus_proto) proto[j++] = ATOM_WM_TAKE_FOCUS; XSetWMProtocols(dpy, win, proto, j); } { XTextProperty nametext; char *list[] = { NULL, NULL }; list[0] = "Hints Test"; classhints.res_name = strdup("hints_test"); classhints.res_class = strdup("HintsTest"); if (!XStringListToTextProperty(list, 1, &nametext)) { fprintf(stderr, "Failed to convert name to XText\n"); exit(1); } XSetWMProperties( dpy, win, &nametext, &nametext, NULL, 0, &hints, NULL, &classhints); XFree(nametext.value); } if (mwm_hints.props[0] != 0) { XChangeProperty( dpy, win, ATOM_MOTIF_WM_HINTS, ATOM_MOTIF_WM_HINTS, 32, PropModeReplace,(unsigned char *)&mwm_hints, PROP_MWM_HINTS_ELEMENTS); } if (trans_win !=0) XSetTransientForHint(dpy, win, trans_win); XMapWindow(dpy, win); XSetWindowBackground(dpy, win, 0); Xloop(); return 1; } fvwm-2.6.7/tests/hints/README0000644000175700017570000000473212673746443012641 00000000000000This directory contains only the hints_test.c program. To compile it either try "make" or something like % gcc -g -O2 -Wall -I/usr/X11R6/include -L/usr/X11R6/lib -c hints_test.c % gcc -g -O2 -Wall -o hints_test hints_test.o -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 should work. The program does nothing: it is just a 170x100 black window. However, using options you can set various hints (XSizeHints, XWMHints, MWM hints, EWMH hints) on the window. Here are the options: --help Show usage --min-size w h Set the min_width and min_height XSizeHints to w and h --max-size w h Set the max_width and max_height XSizeHints to w and h --inc-size w h Set the inc_width and inc_height XSizeHints to w and h --p-geometry geometry Set the program geometry and the gravity accordingly. geometry is a standard X geometry (not a F geometry) --us-geometry geometry Set the user geometry and the gravity accordingly. geometry is a standard X geometry (not a F geometry) --input Bool Set the InputHint to Bool where Bool is either true or false --focus-proto Respect the WM_TAKE_FOCUS protocol --no-delete-proto By default the program respect the WM_DELETE_WINDOW protocol. This option forces the program to do not use it at all. --wm-state state Set the initial wm state to state, where state can be withdrawn, iconic or normal --wm-urgency Set the wm urgency flags --wm-group win Set the window group leader to win where win can be root, window or the id of an window. --transient win Set the WM_TRANSIENT_FOR window to win where win can be root or the id of an window. --mwm-decor args where args is a non empty space separated list of the following key words: all, border, resizeh, title, menu, minimize, maximize --mwm-func args where args is a non empty space separated list of the following key words: all, resize, move, maximize, minimize, close --mwm-input arg where arg can be: modless, app_modal, sys_modal, full_app_modal --ewmh-type type Set the EWMH window type to type where type can be: normal, dock, toolbar, desktop, menu, dialog, splash, utility --ewmh-state states Set the EWMH window states to states where states is a non empty space separated list of the following key words: hidden, shaded, sticky, skippager, skiptaskbar, maxhoriz, maxvert, modal, staysontop, fullscreen --ewmh-desktop int Set desktop initial state This is just a test program there is no full checking when the options are parsed. Do not forget to use xprop and xwininfo. Have Fun! fvwm-2.6.7/tests/test_options0000755000175700017570000001221612673746443013310 00000000000000#!/bin/sh # Hell, this is really difficult with /bin/sh. I want my zsh back! testdir=tests fvwmdir=.. myname=`basename $0` log=$testdir/$myname.log typeset -i c1 typeset -i c2 typeset -i c3 typeset -i i1 typeset -i i2 typeset -i nopts typeset -i copts usage () { echo "usage: $myname [-0] [-1] [-2] [-a] [make options]" echo " -0: run tests with all options defined and disabled (2 builds)" echo " -1: run tests with one option defined and disabled" echo " -2: run tests with two options defined and disabled" echo " -a: run all possible tests" echo " default is: myname -0 -1" echo " logging output goes to $log and $log.*" } # #parse command line # run_depth_0="" run_depth_1="" run_depth_2="" run_all="" custom="" while [ -n "$1" ] ; do if [ "$1" = "-h" ] ; then usage exit elif [ "$1" = "-?" ] ; then usage exit elif [ "$1" = "-0" ] ; then run_depth_0=1 run_all="" custom=1 elif [ "$1" = "-1" ] ; then run_depth_1=1 run_all="" custom=1 elif [ "$1" = "-2" ] ; then run_depth_2=1 run_all="" custom=1 elif [ "$1" = "-a" ] ; then run_depth_0="" run_depth_1="" run_depth_2="" run_all=1 custom=1 else break; fi shift done MAKE_OPTS="$*" # set default if nothing was selected if [ -z "$custom" ]; then run_depth_0="1" run_depth_1="1" fi if [ ! -x ./$myname ] ; then echo please run $myname from $testdir exit 1 fi cd $fvwmdir rm -f "$log"* > /dev/null 2>&1 ################## # some functions # ################## # clean up before next build clean_up () { make clean > /dev/null 2>&1 make distclean > /dev/null 2>&1 rm -f config.cache > /dev/null 2>&1 for i in `find . -name .deps -type d` ; do rm -rf $i; done > /dev/null 2>&1 for i in `find . -name Makefile` ; do rm -f $i; done > /dev/null 2>&1 for i in `find . -name "*.o"` ; do rm -f $i; done > /dev/null 2>&1 } # generate parameter list for configure disable_options () { CONFIGURE_OPTS="" while [ ! "$1" = "" ]; do CONFIGURE_OPTS="$CONFIGURE_OPTS --disable-${BUILD_OPTIONS[$1]}" shift done c3=0 while [ ! "${BUILD_OPTIONS[$c3]}" = "" ]; do echo $CONFIGURE_OPTS | grep -q -- "--disable-${BUILD_OPTIONS[$c3]}" || CONFIGURE_OPTS="$CONFIGURE_OPTS --enable-${BUILD_OPTIONS[$c3]}" c3=$c3+1 done } # disable all enabled options and vice versa reverse_options () { CONFIGURE_OPTS=`echo $CONFIGURE_OPTS | sed -e 's/--enable-/--xyz-/g' | sed -e 's/--disable-/--enable-/g' | sed -e 's/--xyz-/--disable-/g'` } # call configure and make (with logging) build () { echo "+++ testing (logfile $1): $CONFIGURE_OPTS" >> $log # clean up echo "cleaning up..." >> $log clean_up # configure echo "configuring..." >> $log echo "./configure $CONFIGURE_OPTS" > $log.$1 if nice ./configure --enable-extras $CONFIGURE_OPTS >> $log.$1 2>&1; then echo ok >> $log else echo FAILED >> $log fi # make echo "building..." >> $log if nice make $MAKE_OPTS > $log.$1 2>&1; then echo ok >> $log else echo FAILED >> $log fi echo >> $log } ############################ # end of functions section # ############################ # # get the list of possible options # c1=0 nopts=0 copts=1 for i in ` grep "^\(dnl dummy: \)\?smr_SWITCH" configure.in | grep -v debug-msgs | sed -e 's/^.*smr_SWITCH.//g' | cut -f 1 -d ","`; do BUILD_OPTIONS[$c1]="$i" OPTIONS="$OPTIONS $i" c1=$c1+1; nopts=$nopts+1; copts=$copts+$copts done # # now do the tests # if [ "$run_depth_1" = "1" ] ; then i1=$nopts+$nopts echo echo " +++ running $i1 tests for depth 1 +++" echo c1=0 while [ ! "${BUILD_OPTIONS[$c1]}" = "" ]; do disable_options $c1 echo build ${BUILD_OPTIONS[$c1]}_off build ${BUILD_OPTIONS[$c1]}_off reverse_options echo build ${BUILD_OPTIONS[$c1]}_on build ${BUILD_OPTIONS[$c1]}_on c1=$c1+1 done fi if [ "$run_depth_2" = "1" ] ; then i1="$nopts * $nopts + $nopts" echo echo " +++ running $i1 tests for depth 2 +++" echo c1=0 while [ -n "${BUILD_OPTIONS[$c1]}" ]; do c2=$c1+1 while [ -n "${BUILD_OPTIONS[$c2]}" ]; do disable_options $c1 $c2 echo build ${BUILD_OPTIONS[$c1]}_off,${BUILD_OPTIONS[$c2]}_off build ${BUILD_OPTIONS[$c1]}_off reverse_options echo build ${BUILD_OPTIONS[$c1]}_on,${BUILD_OPTIONS[$c2]}_on build ${BUILD_OPTIONS[$c1]}_on c2=$c2+1 done c1=$c1+1 done fi if [ "$run_depth_0" = "1" ] ; then echo echo " +++ running 2 tests for depth 0 +++" echo disable_options reverse_options echo build all_disabled build all_disabled disable_options echo build all_enabled build all_enabled fi if [ "$run_all" = "1" ] ; then i1=$copts+1 echo echo " +++ running $i1 tests for all combination of options +++" echo c1=0 while [ ! "$c1" = "$copts" ]; do c2=$c1 i1=0 opts_off="" while [ ! "$i1" = "$nopts" ]; do i2="$c2/2" i2="$i2*2" if [ "$i2" = "$c2" ]; then opts_off="$opts_off $i1" fi i1=$i1+1 c2=$c2/2 done disable_options $opts_off echo "test $c1 of $copts (logfile: `basename $log.$c1`):" echo "$CONFIGURE_OPTS" build $c1 c1=$c1+1 done fi fvwm-2.6.7/Makefile.in0000644000175700017570000007035113010103322011500 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(srcdir)/config.h.in COPYING NEWS etc/compile \ etc/config.guess etc/config.sub etc/depcomp etc/install-sh \ etc/missing $(top_srcdir)/etc/compile \ $(top_srcdir)/etc/config.guess $(top_srcdir)/etc/config.sub \ $(top_srcdir)/etc/install-sh $(top_srcdir)/etc/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ AUTOMAKE_OPTIONS = 1.4 SUBDIRS = \ default-config \ libs \ fvwm \ modules \ bin \ utils \ $(FVWM_PERLLIB) \ doc \ docs \ $(POSUB) \ tests # Usage: # make dist2 # instead of make dist # make distcheck2 # instead of make distcheck # make distclean2 # instead of make distclean DISTCHECK_CONFIGURE_FLAGS = --enable-htmldoc all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am distcheck2: distcheck @banner="$(distdir).tar.gz - ready for distribution"; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo "$$banner"; \ echo "$$dashes" @if test "x$(ISRELEASED)" != xyes; then \ echo 'Warning: ISRELEASED is not set to "yes".'; \ echo ' So these can not be the official tarballs.'; \ exit 1; \ fi distclean2: distclean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/default-config/0000755000175700017570000000000013010103341012375 500000000000000fvwm-2.6.7/default-config/.stalonetrayrc0000644000175700017570000000017413006057357015236 00000000000000decorations none geometry 6x1 icon_size 18 max_geometry 6x1 parent_bg true transparent false icon_gravity SE no_shrink true fvwm-2.6.7/default-config/Makefile.am0000644000175700017570000000141213010103313014346 00000000000000## Process this file with automake to create Makefile.in configdir = @FVWM_DATADIR@/default-config inst_location = $(DESTDIR)@FVWM_DATADIR@/default-config config_DATA = config \ .stalonetrayrc \ FvwmScript-DateTime \ FvwmScript-ConfirmQuit \ FvwmScript-ConfirmCopyConfig EXTRA_DIST = images \ config \ .stalonetrayrc \ FvwmScript-DateTime \ FvwmScript-ConfirmQuit \ FvwmScript-ConfirmCopyConfig install-data-hook: cp -r $(srcdir)/images $(inst_location) ln -sf $(inst_location)/FvwmScript-DateTime $(inst_location)/.. ln -sf $(inst_location)/FvwmScript-ConfirmQuit $(inst_location)/.. ln -sf $(inst_location)/FvwmScript-ConfirmCopyConfig $(inst_location)/.. uninstall-hook: rm -fr $(DESTDIR)/$(configdir) fvwm-2.6.7/default-config/Makefile.in0000644000175700017570000004304713010103322014371 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = default-config DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(configdir)" DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ configdir = @FVWM_DATADIR@/default-config inst_location = $(DESTDIR)@FVWM_DATADIR@/default-config config_DATA = config \ .stalonetrayrc \ FvwmScript-DateTime \ FvwmScript-ConfirmQuit \ FvwmScript-ConfirmCopyConfig EXTRA_DIST = images \ config \ .stalonetrayrc \ FvwmScript-DateTime \ FvwmScript-ConfirmQuit \ FvwmScript-ConfirmCopyConfig all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign default-config/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign default-config/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-data-am install-strip uninstall-am .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-configDATA \ install-data install-data-am install-data-hook install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-configDATA uninstall-hook install-data-hook: cp -r $(srcdir)/images $(inst_location) ln -sf $(inst_location)/FvwmScript-DateTime $(inst_location)/.. ln -sf $(inst_location)/FvwmScript-ConfirmQuit $(inst_location)/.. ln -sf $(inst_location)/FvwmScript-ConfirmCopyConfig $(inst_location)/.. uninstall-hook: rm -fr $(DESTDIR)/$(configdir) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/default-config/FvwmScript-DateTime0000644000175700017570000000152713006057357016067 00000000000000WindowTitle {DateTime} WindowSize 120 35 Font "xft:Sans:style=Bold:size=10" Init Begin Set $Time = (GetOutput {exec date "+%H:%M"} 1 -1) Set $Date = (GetOutput {exec date "+%a %b %d"} 1 -1) ChangeTitle 1 $Time ChangeTitle 2 $Date End PeriodicTasks Begin If (RemainderOfDiv (GetTime) 15)==0 Then Begin Set $Time = (GetOutput {exec date "+%H:%M"} 1 -1) Set $Date = (GetOutput {exec date "+%a %b %d"} 1 -1) ChangeTitle 1 $Time ChangeTitle 2 $Date End End Widget 1 Property Position 0 0 Size 120 20 Font "xft:Sans:style=Bold:size=11" Type ItemDraw Flags NoReliefString Title {} Main Case message of SingleClic : Begin End End Widget 2 Property Position 0 20 Size 120 15 Font "xft:Sans:style=Bold:size=8" Type ItemDraw Flags NoReliefString Title {} Main Case message of SingleClic : Begin End End fvwm-2.6.7/default-config/FvwmScript-ConfirmQuit0000644000175700017570000000116713006057357016633 00000000000000WindowTitle {ConfirmQuit} WindowSize 300 80 Font "xft:Sans:style=Bold:size=10" Init Begin End Widget 1 Property Title {Do you really want to quit Fvwm?} Size 200 30 Position 25 0 Type ItemDraw Flags NoReliefString Main Case message of SingleClic : Begin End End Widget 2 Property Title {Quit} Size 60 28 Position 70 40 Flags NoReliefString Type PushButton Value 1 Main Case message of SingleClic : Begin Do {Quit} End End Widget 3 Property Title {Cancel} Size 60 28 Position 170 40 Flags NoReliefString Type PushButton Value 1 Main Case message of SingleClic : Begin Quit End End fvwm-2.6.7/default-config/FvwmScript-ConfirmCopyConfig0000644000175700017570000000423713006057365017751 00000000000000WindowTitle {ConfirmCopyConfig} WindowSize 500 160 Font "xft:Sans:size=10" Init Begin Set $DataDir=(GetOutput {echo "$FVWM_DATADIR"} 1 -1) Set $UserDir=(GetOutput {echo "$FVWM_USERDIR"} 1 -1) Set $DefaultConf=$DataDir {/default-config/config} Set $UserConf=$UserDir {/config} Set $BackupConf=$UserDir {/config-bak} ChangeTitle 3 $UserDir ChangeTitle 5 $BackupConf Do {Style ConfirmCopyConfig Layer 6} End Widget 1 Property Title {Fvwm Default Configuration} Font "xft:Sans:size=14" Size 500 25 Position 0 0 Type ItemDraw Flags NoReliefString Center Main Case message of SingleClic : Begin End End Widget 2 Property Title {This script copies the default configuration into your home directory:} Size 400 12 Position 15 30 Type ItemDraw Flags NoReliefString Left Main Case message of SingleClic : Begin End End Widget 3 Property Title {} Size 400 17 Position 70 50 Type ItemDraw Flags NoReliefString Left Main Case message of SingleClic : Begin End End Widget 4 Property Title {A backup of your current configuration will be located at:} Size 400 12 Position 15 70 Type ItemDraw Flags NoReliefString Left Main Case message of SingleClic : Begin End End Widget 5 Property Title {} Size 400 17 Position 70 90 Type ItemDraw Flags NoReliefString Left Main Case message of SingleClic : Begin End End Widget 6 Property Title {Click Confirm to continue and restart Fvwm.} Size 400 15 Position 15 107 Type ItemDraw Flags NoReliefString Left Main Case message of SingleClic : Begin End End Widget 7 Property Title {Confirm} Colorset 13 Size 60 28 Position 100 130 Flags NoReliefString Type PushButton Value 1 Main Case message of SingleClic : Begin Do {Test (f } $UserConf {) PipeRead `mv "} $UserConf {" "} $BackupConf {"; echo "Echo Backup: } $BackupConf {"`} Do {PipeRead `cp "} $DefaultConf {" "} $UserDir {"; echo "Echo Copied default config to } $UserDir {"`} Do {Restart} Quit End End Widget 8 Property Title {Cancel} Colorset 13 Size 60 28 Position 350 130 Flags NoReliefString Type PushButton Value 1 Main Case message of SingleClic : Begin Quit End End fvwm-2.6.7/default-config/config0000644000175700017570000005313313006057365013535 00000000000000################################## # ____________________________ # ( _________________________) # ) (__ _ _ _ _ # ( __)( \/ )( \/\/ )/\/\ # ) ( \ / \ // \ # (___) \/ \/\/(_/\/\_) 2.6 # # # This is the default configuration file shipped with fvwm. # # This config file is organized as follows: # # 1: Functions # 2: Styles # 3: Colorsets # 4: Menus # 5: Bindings # 6: Decor # 7: Modules # ################################# # InfoStoreAdd can be used to store variable data internal to fvwm. # The variable can then be used in the configuration as $[infostore.name]. # # You can also use environment variables but for data internal to fvwm # use InfoStore variables instead. # # The following is used in various menus and also sets the terminal # that FvwmConsole uses. Change this to your terminal of choice InfoStoreAdd terminal xterm ########### # 1: Functions # # Fvwm can use custom functions for various tasks. # The syntax for defining a function named FunctionName is: # # DestroyFunc FunctionName # AddToFunc FunctionName # + I [Action to do Immediately] # + C [Action to do on a Mouse Click] # + D [Action to do on a Mouse Double Click] # + H [Action to do on a Mouse Hold] # + M [Action to do on a Mouse Motion] ########### # Start Function # # The start function is run right after fvwm is done reading # the config file. This function run after each restart # so using Test (Init) or Test (Restart) can further control # actions that are run during the first time run (Init) or # actions that are run after a restart. DestroyFunc StartFunction AddToFunc StartFunction + I Test (Init, f $[FVWM_USERDIR]/.BGdefault) \ Exec exec fvwm-root $[FVWM_USERDIR]/.BGdefault + I TestRc (NoMatch) Exec exec fvwm-root \ $[FVWM_DATADIR]/default-config/images/background/bg1.png + I Test (Init) Module FvwmBanner + I Module FvwmButtons RightPanel + I Module FvwmEvent EventNewDesk # Function: MoveClickX $0 $1 $2 # # This function runs variable actions on different events # and is used with the mouse bindings to allow different # actions depending on if the mouse is clicked, double clicked # or moved. Use "Nop" for no action. # # $0 - Action on Mouse Hold + Move # $1 - Action on Mouse Click # $2 - Action on Mouse DoubleClick # # Example: Mouse 1 T A MoveClickX Move Raise Maximize # # Click title bar to raise, double click to maximize, # and click+move to move the window. DestroyFunc MoveClickX AddToFunc MoveClickX + M $0 + C $1 + D $2 # Function: ViewManPage $0 # # This function loads the man page $0 in an terminal # and is used with the help menu. DestroyFunc ViewManPage AddToFunc ViewManPage + I Exec exec $[infostore.terminal] -g 80x40 \ -n "Manual Page - $0" -T "Manual Page - $0" -e man "$0" # Function: SetBG $0 # # SetBG is used with the background menu to set the background # image and configure it to be loaded the next time fvwm is run. # Note, fvwm-root can't use .jpeg or resize images. Use something # like display, feh, etc. DestroyFunc SetBG AddToFunc SetBG + I Test (f $[FVWM_USERDIR]/images/background/$0) \ Exec exec fvwm-root $[FVWM_USERDIR]/images/background/$0 + I TestRc (Match) Exec exec ln -fs images/background/$0 \ $[FVWM_USERDIR]/.BGdefault + I TestRc (Match) Break + I Test (!f $[FVWM_DATADIR]/default-config/images/background/$0) Break + I Exec exec fvwm-root $[FVWM_DATADIR]/default-config/images/background/$0 + I Exec exec ln -fs $[FVWM_DATADIR]/default-config/images/background/$0 \ $[FVWM_USERDIR]/.BGdefault # Function: IconManClick # # This function is run from FvwmIconMan when the button is clicked. DestroyFunc IconManClick AddToFunc IconManClick + I ThisWindow (Raised, !Shaded, !Iconic, CurrentPage) Iconify + I TestRc (Match) Break + I ThisWindow (!Raised) Raise + I ThisWindow (Shaded) WindowShade + I ThisWindow (Iconic) Iconify + I ThisWindow (AcceptsFocus) FlipFocus # Function: ToggleTitle # # This function will toggle if fvwm shows the TitleBar. DestroyFunc ToggleTitle AddToFunc ToggleTitle + I ThisWindow (State 1) WindowStyle Title + I TestRc (Match) State 1 False + I TestRc (Match) Break + I WindowStyle !Title + I State 1 True # Function: ChangeDesk # # This function is called by FvwmEvent every time the Desk is changed. DestroyFunc ChangeDesk AddToFunc ChangeDesk + I SendToModule FvwmButtons ChangeButton desk0 Colorset 10 + I SendToModule FvwmButtons ChangeButton desk1 Colorset 10 + I SendToModule FvwmButtons ChangeButton desk2 Colorset 10 + I SendToModule FvwmButtons ChangeButton desk3 Colorset 10 + I SendToModule FvwmButtons ChangeButton desk$0 Colorset 11 ############# # 2: Styles # ############# # Desktops and Pages # # Fvwm has both Virtual Desktops and Pages. Each Desktop is built from # a grid of Pages. The following sets the name of four Desktops and then # divides each Desktop into a 2x2 grid of Pages that are positioned as # # +---+---+ # | | | # +---+---+ # | | | # +---+---+ # DesktopName 0 Main DesktopName 1 Desk1 DesktopName 2 Desk2 DesktopName 3 Desk3 DesktopSize 2x2 # EdgeScroll will move the view port between the Pages when the mouse # moves to the edge of the screen. This set the amount of distance to # scroll at 100% (full page) and the EdgeResistance which is a timer # for how long the mouse as at the edge before it scrolls. # # Set EdgeScroll 0 0 and/or EdgeResistance -1 to disable. EdgeScroll 100 100 EdgeResistance 450 EdgeThickness 1 Style * EdgeMoveDelay 350, EdgeMoveResistance 350 # EwmhBaseStruts [left] [right] [top] [bottom] # Reserves space along the edge(s) of the Screen that will not # be covered when maximizing or placing windows. EwmhBaseStruts 0 120 0 0 # This sets the ClickTime and MoveThreshold used to determine # Double Clicks, Hold and Move for the mouse. ClickTime 350 MoveThreshold 3 # Sets the focus style to SloppyFocus and a mouse click # in a window will Raise it. Style * SloppyFocus, MouseFocusClickRaises # Default Font DefaultFont "xft:Sans:Bold:size=8:antialias=True" # Window Placement Style * TileCascadePlacement, GrabFocusOff, !UsePPosition # Sets all windows to OpaqueMove (vs a wired frame) and windows will # snap to each other and the edge of the screen. OpaqueMoveSize -1 HideGeometryWindow Style * ResizeOpaque, SnapAttraction 15 SameType ScreenAll, SnapGrid XorValue 55555 # Transient Windows (such as open file windows) Style * DecorateTransient, StackTransientParent Style * !FPGrabFocusTransient, FPReleaseFocusTransient # WindowShade Style * WindowShadeScrolls, WindowShadeSteps 10 # Ignore Numlock and other modifiers for bindings # See http://fvwm.org/documentation/faq/#why-do-numlock-capslock-and-scrolllock-interfere-with-clicktofocus-andor-my-mouse-bindings IgnoreModifiers L25 # Decor Styles Style * BorderWidth 5, HandleWidth 5, MWMButtons, \ FvwmBorder, FirmBorder, UseDecor FvwmDecor Style * Colorset 1, HilightColorset 2 Style * BorderColorset 3, HilightBorderColorset 4 # Disable Icons from appearing on desktop. # Comment this out or use Style * Icon to get the icons back. Style * !Icon # Window Specific Styles Style RightPanel !Title, !Borders, !Handles, Sticky, WindowListSkip, NeverFocus Style ConfirmQuit !Title, PositionPlacement Center, WindowListSkip, Layer 6 Style FvwmIdent WindowListSkip ####### # 3: Colorsets # # Colorsets can be used to configure the color of the various # parts of fvwm such as window decor, menus, modules, etc. # # Colorset Convention # # 0 - Default # 1 - Inactive Windows # 2 - Active Window # 3 - Inactive Windows Borders # 4 - Active Windows Borders # 5 - Menu - Inactive Item # 6 - Menu - Active Item # 7 - Menu - Grayed Item # 8 - Menu - Title # 9 - Reserved # 10+ Modules # 10 - Module Default # 11 - Module Hilight # 12 - Module ActiveButton (Mouse Hover) # 13 - FvwmPager Active Page ########### Colorset 0 fg #ffffff, bg #003c3c, hi, sh, Plain, NoShape Colorset 1 fg #000000, bg #8f9f8f, hi, sh, Plain, NoShape Colorset 2 fg #ffffff, bg #003c3c, hi, sh, Plain, NoShape Colorset 3 fg black, bg #4d4d4d, hi #676767, sh #303030, Plain, NoShape Colorset 4 fg black, bg #2d2d2d, hi #474747, sh #101010, Plain, NoShape Colorset 5 fg #000000, bg #ffffff, hi, sh, Plain, NoShape Colorset 6 fg #ffffff, bg #2d2d2d, hi, sh, Plain, NoShape Colorset 7 fg grey30, bg #ffffff, hi, sh, Plain, NoShape Colorset 8 fg #ffffff, bg #003c3c, hi, sh, Plain, NoShape Colorset 10 fg #ffffff, bg #003c3c, hi #aaaaaa, sh #999999, Plain, NoShape Colorset 11 fg #ffffff, bg #1a6e99, hi #ffffff, sh #ffffff, Plain, NoShape Colorset 12 fg #2d2d2d, bg #ffffff, hi, sh, Plain, NoShape Colorset 13 fg #ffffff, bg #006c6c, hi, sh, Plain, NoShape ####### # 4: Menus ########### MenuStyle * MenuColorset 5, ActiveColorset 6, GreyedColorset 7, TitleColorset 8 MenuStyle * Hilight3DOff, HilightBack, HilightTitleBack, SeparatorsLong MenuStyle * TrianglesSolid, TrianglesUseFore MenuStyle * ItemFormat "%|%3.1i%5.3l%5.3>%|" MenuStyle * Font "xft:Sans:Bold:size=8:antialias=True" # Root Menu # # The root menu will PopUp with a click in the root # window or using alt-f1 (or menu). DestroyMenu MenuFvwmRoot AddToMenu MenuFvwmRoot "Fvwm" Title + "Programs%icons/programs.png%" Popup MenuPrograms + "XDG Menu%icons/apps.png%" Popup XDGMenu + "XTerm%icons/terminal.png%" Exec exec $[infostore.terminal] + "" Nop + "FvwmConsole%icons/terminal.png%" Module FvwmConsole -terminal $[infostore.terminal] + "Wallpapers%icons/wallpaper.png%" Popup BGMenu + "Man Pages%icons/help.png%" Popup MenuFvwmManPages + "Copy Config%icons/conf.png%" FvwmScript FvwmScript-ConfirmCopyConfig + "" Nop + "Refresh%icons/refresh.png%" Refresh + "Restart%icons/restart.png%" Restart + "Quit%icons/quit.png%" Module FvwmScript FvwmScript-ConfirmQuit # Generate XDGMenu PipeRead "fvwm-menu-desktop" # Programs Menu # # This test for some common programs and adds them to the menu. # When adding programs you don't need to use the Test (x foo) # lines as this is only to help make this menu portable. DestroyMenu MenuPrograms AddToMenu MenuPrograms "Programs" Title Test (x chromium) + "Chromium" Exec exec chromium Test (x firefox) + "Firefox" Exec exec firefox Test (x google-chrome) + "Google-Chrome" Exec exec google-chrome Test (x gvim) + "gVim" Exec exec gvim Test (x xemacs) + "XEmacs" Exec exec xemacs Test (x gimp) + "Gimp" Exec exec gimp Test (x vlc) + "VLC" Exec exec vlc # Background Menu # # Backgrounds are located in ~/.fvwm/images/background/ # Menu icons are located in ~/.fvwm/images/bgicons/ DestroyMenu BGMenu AddToMenu BGMenu "Wallpapers" Title + "Floral%bgicons/bg1.png%" SetBG bg1.png + "Circles%bgicons/bg2.png%" SetBG bg2.png + "Space%bgicons/bg3.png%" SetBG bg3.png # Window Operations Menus DestroyMenu MenuWindowOps AddToMenu MenuWindowOps + "Move" Move + "Resize" Resize + "Iconify" Iconify + "Maximize" Maximize + "Shade" WindowShade + "Stick" Stick + "" Nop + "Close" Close + "More..." Menu MenuWindowOpsLong This 0 0 DestroyMenu MenuWindowOpsLong AddToMenu MenuWindowOpsLong + "Move" Move + "Resize" Resize + "(De)Iconify" Iconify + "(Un)Maximize" Maximize + "(Un)Shade" WindowShade + "(Un)Sticky" Stick + "(No)TitleBar" Pick (CirculateHit) ToggleTitle + "Send To Desk" Popup MenuSendToDesk + "" Nop + "Close" Close + "Destroy" Destroy + "" Nop + "Raise" Raise + "Lower" Lower + "" Nop + "StaysOnTop" Pick (CirculateHit) Layer 0 6 + "StaysPut" Pick (CirculateHit) Layer 0 4 + "StaysOnBottom" Pick (CirculateHit) Layer 0 2 + "" Nop + "Identify" Module FvwmIdent DestroyMenu MenuIconOps AddToMenu MenuIconOps + "(De)Iconify" Iconify + "(Un)Maximize" Maximize + "(Un)Shade" WindowShade + "(Un)Sticky" Stick + "(No)TitleBar" Pick (CirculateHit) ToggleTitle + "Send To Desk" Popup MenuSendToDesk + "" Nop + "Close" Close + "Destroy" Destroy + "" Nop + "Raise" Raise + "Lower" Lower + "" Nop + "StaysOnTop" Pick (CirculateHit) Layer 0 6 + "StaysPut" Pick (CirculateHit) Layer 0 4 + "StaysOnBottom" Pick (CirculateHit) Layer 0 2 + "" Nop + "Identify" Module FvwmIdent DestroyMenu MenuSendToDesk AddToMenu MenuSendToDesk + "Current" MoveToDesk + "Desk 0" MoveToDesk 0 0 + "Desk 1" MoveToDesk 0 1 + "Desk 2" MoveToDesk 0 2 + "Desk 3" MoveToDesk 0 3 # Fvwm Man Pages (Help) Menu DestroyMenu MenuFvwmManPages AddToMenu MenuFvwmManPages "Help" Title + "fvwm" ViewManPage fvwm + "FvwmAnimate" ViewManPage FvwmAnimate + "FvwmAuto" ViewManPage FvwmAuto + "FvwmBacker" ViewManPage FvwmBacker + "FvwmBanner" ViewManPage FvwmBanner + "FvwmButtons" ViewManPage FvwmButtons + "FvwmCommand" ViewManPage FvwmCommand + "FvwmConsole" ViewManPage FvwmConsole + "FvwmEvent" ViewManPage FvwmEvent + "FvwmForm" ViewManPage FvwmForm + "FvwmIconMan" ViewManPage FvwmIconMan + "FvwmIdent" ViewManPage FvwmIdent + "FvwmPager" ViewManPage FvwmPager + "FvwmPerl" ViewManPage FvwmPerl + "FvwmProxy" ViewManPage FvwmProxy + "FvwmRearrange" ViewManPage FvwmRearrange + "FvwmScript" ViewManPage FvwmScript + "" Nop + "fvwm-root" ViewManPage fvwm-root + "fvwm-menu-desktop" ViewManPage fvwm-menu-desktop + "fvwm-menu-directory" ViewManPage fvwm-menu-directory + "fvwm-menu-headlines" ViewManPage fvwm-menu-headlines + "fvwm-menu-xlock" ViewManPage fvwm-menu-xlock + "fvwm-config" ViewManPage fvwm-config ####### # 5: Mouse and Key bindings # # Contexts: # R = Root Window rrrrrrrrrrrrrrrrrrrrrr # W = Application Window rIrrrr<---------^rrrrr # F = Frame Corners rrrrrr[13TTTT642]rrrrr # S = Frame Sides rIrrrr[wwwwwwwww]rrrrr # T = Title Bar rrrrrr[wwwwwwwww]rrrrr # I = Icon rIrrrrv_________>rrrrr # rrrrrrrrrrrrrrrrrrrrrr # # Numbers are buttons: [1 3 5 7 9 TTTTT 0 8 6 4 2] # # Modifiers: (A)ny, (C)ontrol, (S)hift, (M)eta, (N)othing # # Format: Key # Mouse #################### # Alt-F1 or Menu to load the root menu and Alt-Tab for a WindowList. # Ctrl-F1/F2/F3/F4 will switch between the Virtual Desktops. # Super_R (windows key) will launch a terminal. # # Silent supresses any errors (such as keyboards with no Menu key). Silent Key F1 A M Menu MenuFvwmRoot Silent Key Menu A A Menu MenuFvwmRoot Silent Key Tab A M WindowList Root c c NoDeskSort, SelectOnRelease Meta_L Silent Key F1 A C GotoDesk 0 0 Silent Key F2 A C GotoDesk 0 1 Silent Key F3 A C GotoDesk 0 2 Silent Key F4 A C GotoDesk 0 3 Silent Key Super_R A A Exec exec $[infostore.terminal] # Window Buttons: [1 3 5 7 9 TTTTT 0 8 6 4 2] # 1 - Open the WindowOps menu. # 2 - Close on single click, Destory on double click. # 4 - Maximize (right/middle button will only maximize vertical/horizontal) # 6 - Iconify (minimize) Mouse 1 1 A Menu MenuWindowOps Mouse 1 2 A MoveClickX Nop Close Destroy Mouse 1 4 A Maximize 100 100 Mouse 2 4 A Maximize 0 100 Mouse 3 4 A Maximize 100 0 Mouse 1 6 A Iconify # TitleBar: Click to Raise, Move, Double Click to Maximize # Mouse Wheel Up/Down to WindowShade On/Off # Borders: Click to raise, Move to Resize # Root Window: Left Click - Main Menu # Right Click - WindowOps Menu # Middle Click - Window List Menu # Right click TitleBar/Borders for WindowOps Menu Mouse 1 T A MoveClickX Move Raise Maximize Mouse 1 FS A MoveClickX Resize Raise Nop Mouse 4 T A MoveClickX Nop Raise "WindowShade True" Mouse 5 T A MoveClickX Nop Raise "WindowShade False" Mouse 1 R A Menu MenuFvwmRoot Mouse 2 R A WindowList Mouse 3 R A Menu MenuWindowOpsLong Mouse 1 I A MoveClickX Move Nop Iconify Mouse 3 T A Menu MenuWindowOps Mouse 3 I A Menu MenuIconOps ####### # 6: Window Decor # # Buttons Locations: [1 3 5 7 9 TTTTT 0 8 6 4 2] # # 1 - WindowOps Menu # 2 - Close # 4 - Maximize # 6 - Minimize ########### DestroyDecor FvwmDecor AddToDecor FvwmDecor + TitleStyle Centered Height 18 -- Flat + ButtonStyle All ActiveUp Vector 5 15x15@4 15x85@3 85x85@3 85x15@3 15x15@3 -- Flat + ButtonStyle All ToggledActiveUp Vector 5 15x15@4 15x85@3 85x85@3 85x15@3 15x15@3 -- Flat + ButtonStyle All ActiveDown Vector 5 20x20@4 20x80@3 80x80@3 80x20@3 20x20@3 -- Flat + ButtonStyle All ToggledActiveDown Vector 5 20x20@4 20x80@3 80x80@3 80x20@3 20x20@3 -- Flat + ButtonStyle All ToggledInactive Vector 5 47x47@3 57x53@3 53x53@3 53x47@3 47x47@3 -- Flat + ButtonStyle All Inactive Vector 5 47x47@3 57x53@3 53x53@3 53x47@3 47x47@3 -- Flat + AddButtonStyle 1 Active Vector 5 45x45@3 55x45@3 55x55@3 45x55@3 45x45@3 + AddButtonStyle 2 Active Vector 4 35x35@3 65x65@3 65x35@4 35x65@3 + AddButtonStyle 4 Active Vector 8 30x70@3 30x30@3 70x30@3 70x70@3 30x70@3 \ 30x50@4 50x50@3 50x70@3 + AddButtonStyle 4 ToggledActiveUp Vector 8 30x70@3 30x30@3 70x30@3 70x70@3 30x70@3 \ 50x30@4 50x50@3 70x50@3 + AddButtonStyle 6 Active Vector 5 35x60@3 65x60@3 65x50@3 35x50@3 35x60@3 + ButtonStyle All - Clear + ButtonStyle 1 - MwmDecorMenu + ButtonStyle 4 - MwmDecorMax + ButtonStyle 6 - MwmDecorMin ############ # 7: Modules ############# # FvwmIdent # # FvwmIdent is a module that can be used to get the various info about # a window. One use is getting the class/resource/name of a window. DestroyModuleConfig FvwmIdent:* *FvwmIdent: Colorset 10 *FvwmIdent: Font "xft:Sans:size=10:antialias=True" # FvwmBanner # # This displays the Fvwm Logo for 5 seconds. This is displayed # when fvwm starts. DestroyModuleConfig FvwmBanner:* *FvwmBanner: NoDecor *FvwmBanner: Timeout 5 # FvwmScript # # FvwmScript is a module that allows one to write custom desktop # widgets and various other tools. This config uses two FvwmScripts. # - DateTime - uses the output of "date" to display the date/time # on the RightPanel. # - Quit - This is a popup that asks for quit confirmation before # quitting fvwm. DestroyModuleConfig FvwmScript:* *FvwmScript: DefaultColorset 10 # FvwmButtons - RightPanel # # FvwmButtons is a powerful module that can be used to build custom # panels and docks. This config uses FvwmButtons to build the RightPanel. # The panel contains buttons to switch desks, FvwmPager, a system tray, # FvwmIconMan (list of running windows), and a clock. # # Note - To use the system tray you must have "stalonetray" installed. DestroyModuleConfig RightPanel:* *RightPanel: Geometry 120x$[vp.height]-0+0 *RightPanel: Colorset 10 *RightPanel: Rows $[vp.height] *RightPanel: Columns 120 *RightPanel: Frame 0 *RightPanel: Font "xft:Sans:Bold:size=10:antialias=True" *RightPanel: (120x45, Icon "fvwm-logo-small.png", Frame 0) *RightPanel: (120x5, Frame 0) *RightPanel: (10x20, Frame 0) *RightPanel: (25x20, Id desk0, Title "0", Action (Mouse 1) GotoDesk 0 0, Colorset 11, ActiveColorset 12, Frame 0) *RightPanel: (25x20, Id desk1, Title "1", Action (Mouse 1) GotoDesk 0 1, ActiveColorset 12, Frame 0) *RightPanel: (25x20, Id desk2, Title "2", Action (Mouse 1) GotoDesk 0 2, ActiveColorset 12, Frame 0) *RightPanel: (25x20, Id desk3, Title "3", Action (Mouse 1) GotoDesk 0 3, ActiveColorset 12, Frame 0) *RightPanel: (10x20, Frame 0) *RightPanel: (5x80, Frame 0) *RightPanel: (110x80, Swallow FvwmPager 'Module FvwmPager *', Frame 0) *RightPanel: (5x80, Frame 0) *RightPanel: (120x5, Frame 0) Test (x stalonetray) *RightPanel: (120x20, Swallow(NoClose,UseOld) \ stalonetray 'Exec exec stalonetray --config \ "$[FVWM_DATADIR]/default-config/.stalonetrayrc"', Frame 0) Test (x stalonetray) PipeRead 'echo "*RightPanel: (120x$(($[vp.height]-225)), \ Top, Swallow FvwmIconMan \'Module FvwmIconMan\', Frame 0)"' Test (!x stalonetray) PipeRead 'echo "*RightPanel: (120x$(($[vp.height]-205)),\ Top, Swallow FvwmIconMan \'Module FvwmIconMan\', Frame 0)"' *RightPanel: (120x45, Swallow DateTime 'Module FvwmScript FvwmScript-DateTime',\ Frame 0) *RightPanel: (120x5, Frame 0) # FvwmPager # # This module displays the location of the windows on the various Pages # and Desks. This is setup to show only the Pages on the current Desk. DestroyModuleConfig FvwmPager:* *FvwmPager: Colorset * 10 *FvwmPager: HilightColorset * 13 *FvwmPager: BalloonColorset * 10 *FvwmPager: WindowColorsets 10 11 *FvwmPager: Font None *FvwmPager: Balloons All *FvwmPager: BalloonFont "xft:Sans:Bold:size=8:antialias=True" *FvwmPager: BallonYOffset +2 *FvwmPager: Window3dBorders *FvwmPager: MiniIcons # FvwmIconMan # # FvwmIconMan is a powerful tool to list and manage windows. This # is used as the window list in the panel or taskbar. DestroyModuleConfig FvwmIconMan:* *FvwmIconMan: UseWinList true *FvwmIconMan: ButtonGeometry 120x20 *FvwmIconMan: Colorset 10 *FvwmIconMan: FocusColorset 11 *FvwmIconMan: FocusAndSelectColorset 12 *FvwmIconMan: SelectColorset 12 *FvwmIconMan: IconAndSelectColorset 12 *FvwmIconMan: DrawIcons always *FvwmIconMan: ReliefThickness 0 *FvwmIconMan: Format "%t" *FvwmIconMan: Font "xft:Sans:Bold:size=8:antialias=True" *FvwmIconMan: Action Mouse 1 A sendcommand IconManClick *FvwmIconMan: Action Mouse 2 A sendcommand Nop *FvwmIconMan: Action Mouse 3 A sendcommand "Menu MenuIconOps" *FvwmIconMan: Resolution global *FvwmIconMan: Tips needed *FvwmIconMan: Sort id # FvwmEvent # # FvwmEvent is a module that can run an action or function # on specific events. This instance changes which desk number # is highlighted when the desk is changed. DestroyModuleConfig EventNewDesk:* *EventNewDesk: PassID *EventNewDesk: new_desk ChangeDesk # FvwmForm # # FvwmForm is a module that can be used to build a GUI # form. Used with fvwm-menu-desktop-config.fpl. # This sets the default colorsets. *FvwmFormDefault: Colorset 10 *FvwmFormDefault: ItemColorset 13 fvwm-2.6.7/default-config/images/0000755000175700017570000000000013006057357013666 500000000000000fvwm-2.6.7/default-config/images/fvwm-logo-small.png0000644000175700017570000001335313006057357017344 00000000000000PNG  IHDRn&%PbKGD pHYs  d_tIME &]P xIDATx|yx]uoϝͲ$YYfM0~L P m$ 2W^^44M$mILM@@-ydٚ;Ogqd ߽9a~䃽w O~v?~O"1/͛ {8KܡAY;#d &_嵚$_l ԃQ Q% ) X h 9XZ^#vEl8޲|PYK%@Qxi ^BdK@+ ZYpDQǍM @Tt#K/VHE7%kT vʍ*X!;|wګoYE &rƆs =b']ll?|3D{nU->@L )@p`X_$ kTįH5+~1WH^ 'uXkQȲ$bӫ ߇_ ;B'u*o=9="\+DD$BV)X}3cχB:lrvGdlҥ":EY-vP+\5噲 `@a'PxGigrXC;U3o &ݷY z4{{7Ua'E/-  _ܕ]*{,q@δ8YLz6seEFMVďq._eB8 $Py.S}VRd[f+4`lvQ3IJX04wf(R?7gxC U о*}JONz>(}}Kڋ_"Tm_Pp5j dg-} "b5{< +!mg 6F}3|oPپMVcջg "Dˊ)Ӎ(k7j[^L N=OۣBsn`bHqEH`hsgtvOڂWk0"}dϱ}@žI z'A+m/~P*${W&$bA2 #XFWrp$ @9 "(ߊݱEN 6_Цq'܈#vzrA8ie9Fd[t/^V%Y7,)?,x{ SМ78dT@ fhADB}*$~\h}逝8?P8괲] ))ڵCplB1Q"-Fb6@[J!8"u)YJY (gT@\|(i}\UƁ8`A)_q%mٽoqݱKnF4he{i@0 vϡкWٗc `5%$HA&]R_%AA@ABv.}f2P4ED5֓ ڱ~G!&[t3y䷛5@ r`:gsx5[+G N"R^./!e UH ɏyU`h*';8/ `'ٳ;fϾR徚WU\&Y"Fz26wPzĈ8@&$H @ /^1nQPwQm/ 6}ꯨ@B ]p+I#B[FU#|uQ=6Am=/:CxgM,CFx GeY5pi[{uq)o<%[4N80] v6sXH08\n(G/o*O15H f ZAC|pD0r)I|bU_#vfrWL^Bj-a&f )EةД&:Ky]-b UL@.OǻW@T}6wT/hp_$V 8~\R"#P΋,5*!NrCNf`iq!23%*zM ,, ob#v`lI hejG5_/|x:'0oYC㯟Y8R *ʒ+wip;#޲s?Yh[޶0/(4c &oI|-$4F@?6GK#Hl?_e1~-.@2V&!@Lib!)LcjRrCZt)^6>%~пvz174"@%8:tq?ajBQnSŮ Knȵ^0*z @d;6ŎmȬE1D$Yu[jtDG0"M]0%{N௟aCR=Qѐc&ur ޟ܁5_w[_ћ:zN`ƹh,2{1j{dh%Fpl 6O 8#hlYZ e6_"Dmm9m̵n_k5 aMh̹jzY +&6#6kk \0Qn}0iʂTpw lXR쓪}գ膠۶jHDRX2+CU,QOH1ܘҧmC =++*',`U[.},n^> 'Aj;9~~:Ayh- 5Hx%̞jEFbsҽ*厒 2 Ah>uQzNo"I59Gč7x`4J)],)KyUhU^Ćn.Oj""C &0qO׌6,;տCg{^`,C;S"h\U"~-жд(Mݯބgh3B||uSˋ'ߋYޣS"s4ܓ UHAVćq. ؙaXC=Ў m[Z +Z±bW1=k? ٮZSgUh૙ʫn8d8ny Aˡ̾5?ĺP=D+?s, Ul3xG+7X^`A`P ^v#|zkNOl!Q٘DF*~Z2I kŮ.oKqtq 8 v`O';C(Fz3':[v\/Ba$ :@ov7_y>o@}NUsq/ 4m>tX:N=okP\V;mhhGXn0gSd[721).]9Nf]N!9Խعo9 2$D0Uiɥ~16m]}>]z}Mx悯x /j+9p k{f8xG\jg\)Xk!CA$=;5+>޽2Azjn)0?7=!C!wy`-.NmǙ]ks#%_?Wp:Wp_յ᰻`Xl}UO8Ϲ fZ";c{{-ˡ3_3{HAGe ^2G/6~{Hj &T `"lj@^|`'"nbt]vWl)?x!HPOɳdRv~IENDB`fvwm-2.6.7/default-config/images/icons/terminal.png0000644000175700017570000000031313006057357017237 00000000000000PNG  IHDRFbKGD#2 pHYs  tIME !.$;.\IDAT(c`?!hV%3f````b`````i+BAF, D'YEàЀEV6 kxdD!r*"2VIENDB`fvwm-2.6.7/default-config/images/icons/restart.png0000644000175700017570000000034313006057357017113 00000000000000PNG  IHDRFIDATxcBJv?JЂA˰AI^ 08r$e@T~1v> lb*eϠ7GI]v3a`Baf@_TE _g*Y+69@ 5!  hG 3#ZIENDB`fvwm-2.6.7/default-config/images/icons/programs.png0000644000175700017570000000032013006057357017254 00000000000000PNG  IHDRFIDATx1J!88;,'(:,kK`SN|ElClX]i2ѱ0nJeWVFE[]7NZ(+'_n&\iDMԄW݇F=$8k|z ^{a1sQRoGsYMA8ֵ`iNNK)K(2?hIENDB`fvwm-2.6.7/default-config/images/background/0000755000175700017570000000000013006057357016005 500000000000000fvwm-2.6.7/default-config/images/background/bg2.png0000644000175700017570000206364713006057357017127 00000000000000PNG  IHDR)gAMA a cHRMz&u0`:pQ<bKGD pHYs.#.#x?vtIME --$IDATx,}v~oU989c 2 ҔD=Jgsd+{ŵh[I "r09tOOU]97|<6`L;`:dh']>[ 3wն1vROa Ou!eǡPpE 9D}BnF%m$TFsǫ+  V }{^ib 4ы̼}r mE)2I br1-nz6ComM(r Rb?F`?^ۙW#d?\Hm:% e`}f1 _qדն0ӓI'.n(lr;mٴh<8Re \&C>Sv'g¸뛶[a3+%4Y;, u|=O?eqR$}J,,&#tMb#2T[!BDO1}xTJ5 [%${~u\>Pè85GwH:"jC1_0(gC2W :XCkphwj9l\_˜&֐5FFtYl=8 Q"+3P"]1K#RM krah"$Z3WC96}e{~74Df vNr{lxfu;=/?ڷRkK9H @ Kd#S&`ԂLl"4t(e(d)8i®Izv=ո?eVl`): ԉSX T܄7& ߒ+ #)**+[ZB:؄1) I2(dSY$5 T4n LR/%X@ 8znB5+/_jRiIH8I`>O;8Lb 9Ȳ#nYdI EA[@@脧X3T({vEsT_֕m`y.2UJ67(E1nS}Zċ4r'A8@T %nX wv(6+E(RewsFB@%; p4pĻSBFۢ-*9YYś& Mi@xS!;wc(f"/kZRuL*@%Sd [1 pDy#\S >1>>J{ NK4m0b(ؔưzXF\g+(؆H}T.l ƍaT(4M4RgZjʁ Wsl8cX1 +>,L,ǁ-1dEb |F(3}RPȽigb.kX7#(:j$GiPL*%@a FR@(r%|RK  d4,y2⚄is̢AN-vn1đ~3aLN)RDMC:TL Sd:"pETuG-F(fk7wZdnQQlx:B*7eXi|n )Pđ4(S e_@=蟿_U}&L,̷DUu_>!3ҹ=z\ָd X-:A&=Ȥw'꤃C,vdUHO/o}Z5!rzɎQ|(vf=q‘`+v.1D `Љs_*|}w{[/?Br>3SЦF 4 -D|5d&(1˞*$O-#;2 ;(pAp*'}kΘBi.66-1Ga=ˤQq;ّ]c,Km\ H;i?Gw3q|NRS+(=gɈQ8~SXEME~qҳ s96ȤC8mh67stac»}Ԩk]dڶ˺ @( I[o u- c$n'] [QT3Gxƿ}4߼냻ۛW+yFdB",M;\"Hm{ ;&Ҷ=@5uI% QLc-58`ɖWyJiZI6wYYc&PͤU&q+LI Ć87T^0?0Z:|mG*%MP0lnڶ {1WJ.qfCwFJaOeӊA Mܕf4]YI@mr/%Z1n1R2{{怙ϗvRg^]%` 2bLsG8 JCs8Kh*MmB Ӕs|{FnwT[}yOS#Q",vU!cDAd8jS [2$!9WA ( `Q$.?̞$G;m?w\v:Q*1c}!SBY- ݄vqjL_$̱hvͣ'RdeQB(nԩN CZԞpC;YlDS@k>䙳in?ޝ#p):Bͭ R ! [{ 0!rX XFz4c4>DIE-˲d* nǍC}o:w J26kf(\E*?`=:OϾg4ˏZhTdS=\]zN{.n6YN)U` f؃EJFJRii艇~QtdHp1X ڏzLWtn6v8}vM,*>&.™)$9|hEHcEϤ2A\V[f7105OVFZC]Lv "|;Ħ6Ogy3bR.:hn.GÈ麩<߱cR)F@8Β u_gVpь?Hkg^LGG||͋ Vڗ骶 `" RdUSokG;Pȁsmϴt-1۱k[gy~dCZNrJX>29H[Ʋ&BgYdEi< Gcl]ㆎ8[GZ3P>-PU[kb,)8\'5ڲ@jhCrQmi l[$5['Vvh͏/>Bwq/ zmiJ ǧiY8ia8s"W\za"WgVydc6Lx=g~S*{<~|ٞIb>pT]5BN`z[<@%:R>K8ᣳp ftsD8TqSk\~N6vzVM-)92ZZ` 6<@7sA.*EAkCJOB ]\hpX,Q[uWgYJmpC@gtO&~ɽZFvytx˸ڦq=ZEyҸt~왋Fa$qQR_uCf̬*E]?G8y&CwTg׏Oo}j[h'ݛ0stWn"DP!]fֱ9-.ңd4ئ0=$%~(Rնg_1?O.4JWԗFȓΗ M-,9dlUͱgʘ+e6^;D+ PO£<۶QYf"ROff[$8Ji7ǖ}'/'GJ;MF"o]mm\6]p{SU} Vz痍tp}aP;aeVGsWͼ.|׿[oe`39u:n+|qJPժႎ@! A3sf'Te,,c@mXFZbqt)pU~^1ZA ZGPh۬oB1- mi"hvWюrrJVکGO'ěU/?(ʅX$2y^PKTzXy7YRKBPҘ^jўoҁ}P̷vN]Jk#k| -/j1dfؽq{(uK\wcy2gW&?M- XXGowV!}x~,:{Mtc#.dhh.9`ˢ&OKrZ(E-Q*@iu9YBؠ EQ8/:Gl2GH{"|8WR[.Ӫ١fru-2!>eLOV,2%XaA]*(*Klӹ$nGV^y4CS{՞WXT=vBYs:ZwPL}&ӽHӀۣ$ce\/?Z;хD]e5v ]rB) ȗLR__+?\[^LE Hl@R!  eXyjü@n3joPӁ,?L\jB[,$[(0{J{ӎ{Q+@{fD(V#_`Vvd^ K&I"幅 Ж0v[*{(>0tFCNy=go.͛k*9#5P/[n|z5:O'F;\[|ֺw8дFkr)`@kۼ1Z/EI#3h-X2 o/-bue (.I(Q* *AD&<&R5x)T B5qmd^Vb! {Ҿ3upJE{l"7f pADCL[ Xϲlm7aEꂭʝ3-vuvYiF"<6 8i ETyX5{H?T6;ӉOAn3[o9$F͙ V0k_Zőŕ"UNY(=I~Bd^Fe,W&z v$RՍ4c|MotL'S4e >8w>>^Z Y\liF9Wh%a Ke-`HTYr-`ו]=s'-ĥ}Il՚nn6'U>zwN?C&Jс * ;U_A#:X4Θ"*Sy]GSQdDz|_Xb[ӟVX yE3f3A[~0-2YNr06ˈoI8=i9-ɴ? FO6pⳛ%%/KѬ3L51/<czXeWf:*0d*UfH5S7H9`B2 ^v_9N^AڊhuպGyC ԠX]ohkԺ0iKCh.N8:GǾ^s+>8)ҏ̞T:ډXDZKySp,"mq 4h@R?N V ,~e*j.ZGUȏ 2^v)DI@yU #'ĮA~Qc!x>c>Lsҙm"w`uAhۘk 79mڹBn\[BA~79S^)O }0UHym8C9b}:j5nuʝ(Kyu vXyC7rѧOz&[w<1vڦOփxa4L D%f!2U>n <3FGƊ>kؔ\b[TdM"=bd<^pu /{X;u%gaH .peDik$oƁLN\8{ڴh6xx)29`p!С)~~V֭ОR}+L^h@Yjl1%Op)G+>Qi|cQvƖ1ܸBźGez]x8a)/OLۆ2A̴w7q} 9?Y14L+q=p/yk3spnlI}Qp׭6nӰ8.@jxz⚱G@ V- RDWhnك':0!Z.݉& S*֎f„>_ӯzVz]Kje^^˵ԸGls@s4x.)iG.]je=i}^<#߽hy&ave tRB{2B';tʥ O|!DTb -6v޺O2{5нrW#-K<_Bes ׋Ԉfq׈^1Á4'v+Uk#hv0k}KmP{bZwVr?lrՕOX#v>63vLxXĬ8:*FlctCFq;D: lTjNn7l:[YD{":|#*}q?/0ZH5.8+XV0ћN6zCѺSUSY۔\Nҝϯv=k Ki^^RC;Ƅ{t?{' *NβܼTq ̯^Rt;?| tdJ70`ldv j0#HPoMF!2i:,mb2Wyc[ĕ5kC%@:pBKib?r橽իz'Bld΢8yt,mgEFv\U0բ=m}${TfE3z~o|iđRd)7љN޴gN]]ǓG1's M : W>=SY ҘYhڽ8YBj-b\BM{'dW_^߹:Vޯ>jZ3[ZRmrp? $!;Bq@J%y+or >$,m@DKC(,^=P( y{3N]aM16n 1\޼xySn\8=3 RlVyd LDv%Ҩz 4 .4Q+'R:Qȴ24)E˫JLh N5bz7+a(5MCj 'z_=ovs%ŅBx5BhʓbZgQ?x{[?ϏޜJ8nCH9rRԍ™؆͌LIN4gD)D1dr#۳/q'5eqՄ7w>uathΐri)H ɾ{2&ɛU5ГXf}o\uxf4YJt|}2!Ҭ0X&U/0ّpP@VAͻ5aY7mJԼY! qvgq~w:Yތ{t >m9Ͼ4lT+3F*Gv' m:a o?~Ul;uݶJuߨx3pUϮ05aqw%mI -<qOXZZFpoMuQ25* JjmXl۹MJepBa2dtQ\b4P)K(S K$qT~!BءVS2Q߈3=xOhw"̽\>)H 󗽮!;qR0tϡ,dhfDJ?/3\#NZ K9{2i_Eby5̼=̧R`L`7˛dj{?f՚'FXE Ԁ[}A^ܑD/>)yiڋݝ(\ޛ0R"W\X o|˰J T>|}ÿ*evhBm%=1Q+V[!R :0|ʌT76M!^;~P(AlddȨwf=dOB-Ӏ\.s0$9 ^|5hF2E)csV$岑,eq>zScP2*5(ZjsdqeMH<wѿNQ[&һ1CHYȈw&5bA;a,p6/h%琈n-l/+ ãwq;k zSy$wS79=u|Rz #hy9 E{fF\8!pb:oZjIr}ݪQ<(=&9:i&_zհ7 /@Nhz+U99+۝Yݓ>>deK39QWN!auTZQaabܟ}@ e =[qס2H0dv].<. O7?,`XD)5Y~מ<쵰x^Ol uo)n Ht c|.|eii#E#-b5W|/ם BFFR6 M XP0#FI JA Q0AR0 wL"R qA&;E:uuE4Gd= PWqhg`g+}',zr+N EA/barӿ9\uJ $`%pJ֝N3geGnMEViSdx ;ET ]r˷'תK%hpboN*մ^0pi+$<9>+ϼ†nj+ϕ"IG7tb SEԣvLa%Ƽ6芹Nd@aWoӴ <1|.9Rlb5鲺r]>q4g_M2aHQwrPm7ފ,qak%Ҷ?L:M7H Ɖ|y]JUf|GTu-)Fe*吳 b2! P2r:Pm)2eb6Q`Z]u9ؖ 'ؿtøPSom{3*pnk*eˏgY71%jb֒эl[ӛZ5cvYʡHr/^@K-]  cO@K"I@M)rdI pDʎw׵?DuLq͙} ȋgCZyY6'-='Jqtg0w̧N|cڨ@^Tru£j&љT뀸b 22E0QjE`7~:IBjaR$GPZ㕒vi.7=+klJ%I-y|P~<-OYwnΖc35L YuxJ2XB1չ"+.n6L -L"ҲscZfN($R&=od}r"(22́94pl4>Shaὕ\Q _hϔEsv~k Y.\I,\i԰w N{#EN?wjJ1tFwd Ν3v6>o6r?Il+>OV)uT4n7(w\YrRV 7)!U6T!8/h97v Ō1#Hcl<4c 91qؔXj"K 'rADT-J1u5uϥ 2%^~ܞ*:w8[)ke\ܫP}Dedq-a\/l^[NUk {KZ8&M-#sLJ$9Bw^% "-> ;QbC V͢ky*Uϓ9zʢ,٘d.3V`w'W[bESvly5wT{dw\g7[\Dw|%P =si"+i#M4)A=`Q_Tqƴ&JĽn#t ^1lD4EitiģGtҼιvBFM^F@O|;Q\4Gziה;I0=(uy9w>OV6@"yvѥzuno;3 9O?+Oc(-u19A} G.Tdw^fUU-1R_DW#rRRXWaLrqE7ɓU$"h!R Ђp mJcP+9y?p tp}zםSX2.GKMrHDQ7 |t{;:w&q'{ڃvxwVxJ< p¬3ӋպKZR4O`w3.wjZ N$[IQԑ\eKj?LPm58 D¥Cp49iߝ?&p_#9{+AfH$  d J>YhӼ ;¦Spenr`xϫTE\#|RL6q ͛{Wy(81(gmv4,-o'C06Yr7xYr ipT02.6Kَ?\r#k;Y Gc4 Y =y͕CN+}7lE4)%n-h[k?rȡƤ℃f䁊^q&P˯]XKU0K(^>"-4 %I7}+ÚK8(`ЃH/'JHC#a\{ON6u3+-Qm~aiLNeA˄ͷ߲ #ii._Po֜N~qx3Ą8p <']0]K0H24Б>T_X|l$`aG LW1SӱZȌZo2 Kz)Vn/(7Jsx+p |KUWAM @y[hg䁈|iAP5#QՎFWd3)W=LkO^.:&m +B֟þd\cKЀeeRyiwc>5If8 ^]GRx~gsK5K%R#Q$fڮF=h}v  U{o86,`Ok_PiE<32Iɵɭi`Jg P4@EQ7@ :7XC5&[wo[H?w f+L qEIb[mNO7V';% v ǕN{POt+ϟ+?ӷViPWz޼Jx1Lk+]v|`FȒ n#4+pC9A (9*"8&H<$s.d7yQK@>F^,=q) zҭtnff:ޏ534#t[[ljdфq:XEFĨa.&t7bnŦy \153F6hC.Biwn0!q.BhX0?./^ X 7DhBY[Zd`gM7W-H*yM[V0<|2زt~p(v~i嬡RYJT:&'陮xjR[L7pE 2v^yj_Z(aZX Tg(sl8ԍG "nU_&՘mLv`C#bM$/O̷ #1"ĩ1 H nJI<\^_]AcŔB)+8j'g5W=h\Z\ŢD]3bKYm4UF5ϱbXZe$6V}?/mG?hI/e Sb ˩՝V JuȽeR xf6*5t)*vmSyw@ՋƞXP;u$!cU*o #~˨nxKKr7z WU7 v=mz)ߜ|xRGd~zl"1Z$u C߻D#$d2y-8oaq'N ڌi/Ǎ|IU (j6HQOK S1GH c+ ۅƌO//H!EZ=mYѢ}u23m8/oNAM >A:GV@;.x$BJ ӼH`v7灴T 0[iRcWs`wfnN(X#u2L‘\!Z_*WυpBYӰ_sS8EW=,Za`ǟ9gÏwn_ԵJX)JȹK?@ۨYn0WA(不O[&$)ILz[i ʭd1#!,逢\wJa[nf|ߙ?̯/B7;RYo4#"*75Q(`1u/ɢt_œon{mfp+{i8̔ҡS|qW' }!Q+FD,'-Z+T _=|U߹4L QMw.R I֎w1I7uet2dD,Y#`lg9 ltv @ N5^ʮq(lo'T|T Ŭ\i^ID.ջ@g3brR*;Q2} :43 ɭ;vdQX\m?\[)tE*\UR'ͥ4kjba,*سWNRçV8QJ5ĹjoXfS']ݨLڮ[Œo#5lv1q {,d[o`O~^Fs6,w_(lw{'}Ei@Utl3eiF;-#p N)i!˗}F ?_y뷿wX "D RK~bRl9Kw6FywNy/4MiQY074 ,8" [ hV֮Sih \W'hԸSYHμWbzv64#B$@S5)zoP %5|fHzkkaY4Tɋjdo$d1AACLWp4T, >ȾbNaZ9;,xÕhN@v& az{g)L19?L(]K>_I]T,oTwO~YrC8 Iab;HM#$`)wLaü@?o.%쁩q)MG' hI\_~@w볏@"a:| 7+v+)}Yb|UϘ|֨CtdIT;no'9svX +_{76;}s WЎ @Nwv=иC_(f2.=[1.=Vr{Fb?I6#U5g׃>JUy~U K7B%~_u}}at{!ZuoԵ)"JSt1[dg4oB8E@bLQvC膵 DkLYB`يU_? ]wi- ai&I٨-nĊ"75E#NTPO8|-b| C& E8vX^mΓ- D?Տ9qg"RƫZ2]`#0d+XSKC1Jo1lya ώ]<1Pei&83ӊK9'Wv>(ail̎ ug63tOKBd88 \)\6:V(TR5i6N3S) ">d{ՋۓYy=s) ɺ5__-A z7 ƙPJja+j٧ēGZ OgNڛds0f&9;/g~7SiD `1,Qbh*ƮF`.$_=k,RYP2WY0zd-ݓ3(Zyȣ?c+o,oOXj ^*jmc|MJUَ&Qy,dz;S?v% X̺F xFXs kسpT:ÿ9 KII$k@GS!p82$5rLU|~/fD8t1YynH 00bf&93/~Vl 7-cO hZt8K}zognPeܛN,MU\.\ԅ~ZI JngicXTceNVa/,HieJ~q}"bk2"v^(ݦ?M\%}ct?x7K97)ν<{y,aOxNp)UScN:/;wr$ݫ/S"=]Z_QVSlf=g-?8h t*ԕ/Rj0I&` @̮y3 a#K"s]IQpA;G3ޛK`V=g1ZEsf7kkOzIdQgآXemddME!a[N`꯻U+ė~9WN;RCJ Wׂo?";w/?.0IH U ZAP\ 'uY)BP&;6J|35 =Hu?߽Kٺrsn2 TBL~>?4kNUq>Z: y?ܼ k|gd^W_ GKvN Od6` %HHòPޭ~]EؓԻa H.KHAB( pN$VO@8& ֺJӕqkF ٞ2-g0}+{WV "7,9 S7^#D-aLuY7~֦ߩY+kv_cm38S޻[wwoߍhrՏwn|ce * 2YIT빽 kW DP)/j?|!@ 1ng 5 3*5a$@-TmpL՞Zy:ϿTxiecRAD*4_zh20te/9=㒍^9+єޛI'vb€%JkPr:lS-v)sd4:"B 9]K%Lbtx䡂A:)XZ4\ͮl'Fb/]l/s7UZE:*qCF#t 335?M\zoܯLnz̍呴${x|.{+,ƮV?Z[JcW{YJ7[BDRKAɵ5i{vHS9*l KC*δPHLj'V4]S{lZ(k`|d_ዐ ƒ zH# P8o|VM)b`L9jǷoN' HPRV`i~=3`)r. i`::kuuL &1 eyFPo@[˖ V{16߀=Zήj|ޫ70ӕ{Bl%a 24妠G_J YRl?|m3b#O ΰ!- Ѝ 쵂؃9wY;Hp BXcOoɊ}o45\܌z}3,bJB+B=TB7Pf$("f`iOQXB㼛i1G:^gS._ྲts[w[BE+*I= PES۶B-C/=V`@m1(KP7zp(:]gh4`.ȗ=XV0x%Xx_6Z.OtT#'Pãu*V聂 .<f)Ck]^G-gi$PL,4`f8 u?lj4,C So%g5g6gqkpg=c Ή AUko.wt/O ,ab1,]ǽi y90L,‹6z-ԹZ`{* _׃lqI_[-*a5$jJJE`IKs>md<99&=j_>4)oGGdw@,Lvo.suӎۇk.?66 yj.e[ xvR:2\D3[PirP)0{R=CqxS-|Z"\0d HE놄7c>NfJ1+XYx [v,P]Ī'|童 ǓiVRjX,#%-_}Z cYy_/(RSK{El5zP\D'1m3#mh7pe?oLd |l3 )!BApT2U'>uL]EJ`b+[.qHtH*PZ K.OfRZ,p \s.lD24\QǎE a~LG$S, _K7֞~X 8݇;b5E,4PAM}gn]6zN:}g{+G6wDE)ZGGV9N\A -T3Ǥɞ~xXuu#Bw ;
  • Ow%|RZFfnxψo]73A}U]YlZD6@neT:嵤F, S#2R&R#2hf~o2++{ ޓ@QQS *$vF=Rۑ4Hl5E@gUJoOǻ{=/~ץh  ղH\MUhl%9+.ImHØWi*f+t /tѴϹ4-, klJ p}S͇N;*!-\cgLU]X]~CW̸w?26i#όr?q0 \ŝok}S ?$zH3DIKQO>%f7쪀'@bgmv{l!.URW|̒;" MDhE ) {E]2eJsjs(CbQS(()]RrpGYF@u3U I;rhm#!U)on.\63:R{:W%θ=/\kp9'Zר._-'Yj!DF\?l#O듻:k;2nWw+ԝʹ?v*L@>2rJN!Nom#2n|n2A!q 5F\FO]K֪\P]TA(6V0Tzr-B[ImRY 撴)>i/d<{W)t2>"QОVm*$#IP6\{>D{֎;I.޻߹>c8wֵ}GMy+_{V1y}Ź3-"ԭD?E},%FFydnt: [lTmFgfדuŚOF'܍Utq]|6z!PsDÊ%o搩eBQټȽ%MNh, Gw0WzEQbn"5s4Ւ:6xrfe)!%ZF*C1T$ >Ph'-8Xwd`1Ʊ\|܀Uݔyjklp9dF-ϋw{{4Y{sŰ+X9RLe"YXb4eJ)+U* o U+X<|ƒʉ3n[都 m{=jh{ zɈ\4nYjרJ'caz}uG;Kp]GAɑu"5U<=LM%8qYdh@2jCz+>{Xeka+ |ͯم®NU0i$﹐kDNU G8'Wz%{wdh7\,k0 w?k ^$P3ؒE1ܻťs Fآ:$ + _;8/}9Nv,nwC)~"_~5{]>Dq|{=CXΥh(TSx+UDR:@em5K &pJ0,h> SR|@nyJT bƱB`5öնI+WgoTnͷJ#ѡ˧k5wKOFo5gf8";l,D7$!SsX~ f]e;u h Nv4^' V;JsI/y7?ſf fRU`\$Ix>lDO@+ 0@2Ȩ"vl> ȌuǞ e{I["pʖ%.$΍֦G}ukcpjwgWsM\>J7rQYUkYm1̭YФ(=nyl2@okWX-3rrnҊ]d~0Ty9Fue[Vvh- *ReeN( h!qCN>m\ݤ1I68 tOj12N߱#TzjAe)sRʖG.֥)"WWT\(;`; ÃM/–Cg`hJ~hKmG$jI^9!IϪȻpHZ f<];zK^F7gG (%WWċin̎oZvǃ wkWɟ<0qef1w`0\eow,LN\a2jړYi'S?AtWF۩1G2-qMѼ jCnOcI H\b>3)S<8hX6+y^aׅjI2 ssyNyz\3{۝Ty@~r?d[pvQ&3X0)]Pt qƺpskYՄ&0G:+ߍnMnf ~Zx>ϓRZ 1F MZr,52der([4eG'RrBKi&,+WA[ga|4FIL5Iip #-220/ՙi:'etÈ>>3vYwyũOgNXH9Pm'֊韙SpMox?I XC0o5iy0dyB=rmu0Qoj+xY:O`=uг| 7Q9H*zx!دAZr0+Ïɶ$@|` -P5E@0Ѳ;astf6KҗMUɡaAMr{L߾n?o5 5-V!XBةseq-&x~d3o&m$P.]>ve:~A!3$nFhk ~1OCdvb&b8єjJEԳ:&@h(- >4[¹bAzm{A22nUjexޱ}|Y}_"9c} %LnY4>݁Q?{Y2X:9=Z ,LJMt!>?cڽzY.UP P]V M39d)5`tXOp35NZԟx6t|}-kL{]_k,k[GCpR_vr^%Wx9! X-~࣏AK{l1^vov.fܹjn\ :Nj }T9DQ "H q% r@!Ht|)5'spu_E-ccG06b D]5,͉Ў)sh|#uLᕴ( -Q2 Ha E"`(aQ!)ZPw7;jGɤنZLpCmcj5|鋾vƬ2z" rC *j;2ARˏۂnkPW$[vN޸޴G^x4سudBhdSrBaD-޲䬖:C+ID8GĉҾdb7KfZ﯏ k2\~t(rQgf텰}m5]Ki+{}U~8*qxv?#AsC5B:Gǂ3vFw;q7i O>:<@60c(+C`GW{@[m:FS@hC J 8B.ho#5W'B.5)fMu#L!_~{3c{Ó=QW$!*,O,V#D4;F7cmB 1+PSPꠡV s)(j#] B: i7NvL{lX;Õ5whM0$aql=!p>~ hO6-ralЈKt|} 9|cb0 M| cuh!K$Z}ܞPKhO~?fk Z q` UkPih\lsH塭IWHS%U=쨊N|,X-wd{/[dC|q',i2_$A~hW>\U6P$IDAT^-򜙡/e;|h )"e S5}O;G|i a}h:{WZƩazoX'ZAkV6 (3`@8LY}=""_3'gq+|MҪ?,\lW~cv1I ,dU>ؿ7Y5]_g=,SOgxdtlRg2[ 5xLYs&!`Ĩ8CD[+f(h:~M`rt޹&Gܓ3[͟jmrqgx~)c] k8 }[p#_qKmXް u-tΧ*||ccXv! κx wҭ7SĨ23X#I./S[ĆFy8C0 ee/=w#d ERF8B-~iùVqFݥGr"LK2S{n\s <޴թgb/p9M[PQ㱝|NŕkfsvϼmlXdž4yBnz2-Kwkstyd-{W q,a!ĩr uh'_h 9h[x n޻G#F޳:= ZI,BQj@'<GF 899K<~T=rEQ̮e kϩG=OM`](ſfyfRJnI]&Џ9C⏾|=;c;wPv`_S۷_O޾e xZ/G-w{^{w?m;nSWW}O7FK]^7ữv':>w䘲ӶʔEi ki]B=`d&q{JQtHr(kE̔GJǹ1:c;WY5k2+PyG'J[;~ ( Ԑr_Y7$R᰷f+|6o~A$`O[姩#-k<d7tbN/_E=M2h,yEQR=]mv%UN/^%k"^}7_ݰFgV[v,`xPPBɷXm&H88dwS-[kޥՙLx9X KŻmŨToaOh>$tZRuD-7qM d>OnI!~T&FYfm|߮rsk%Ԭ9#J:J"tbjPD.sDtӒq &^H\ӥ=?דe3Jg;G& g!񘟳!phl*xTܟQt9񁝚9M\C.|_^LlKcۊz8,\ڹ՚$bh3R2=7>=:LUYf }hÏŻ}娏.V竟pOLn`sȐ~2^}\ڐ|,M a'K0t(p8p'VH2@?XJrf@ܒBT[n뗋uD<OC[-eTLLij zauTpxdWKnfĆGo, ,qM,Kď4W? I=t޼[ZPe*z]=IMlozN2S6'l1׭B ^zjezX ܧ[^zр+yeL)}s^idqWjrlXe_16&z a>P9l,yaC;]zƿ}nsi\~_؈dFxXZs4- kF 2Fn;ǴDA;GdWozܖvѴ[@EfC}DAfFLW91ĭGA@Ԑ@G;KB `67 7z3k[UrM#?եB'>l-翱r5 $7N;EG_}zGW0Ar{[HL+2@%Z'uanYj亊4`EWXެ:kKX Z9Fd087@à  t_:W%]U)P(%ѝ o*tn=3uy ?Ym*˗ʛ7!1M] > &bޖK(DGK״x!s3vko L@F^Um2ea8Lq1ilUM:/a9b6C _Dr#@P _[7oثSq:g/厖kw>@1GgӎA87[52=͕l_% !@Mz+8Iv^vw^Ltd΂O ]5!$r$0ܺKXhSI6!u*#WGK,"ّ顭ίH5#+N[;(dY/Å-]DvJ]3~zWwUjgD4 l8iM5ټYB.1Kb0Sk()EldbDGh:J=a|*Y6ʱny%#ڱjD0MW uX^W)C /+؟#W2~quw?u{s7dXF,lMnr!J TjTv $3=X.-@B/m$AuDy=0{bĻS}E>GL!A-iʶ&pz 8ŋI_g>qGgGNVK]EQ'rn+ι203XDCeBƜ |b%۸=$qLtVׯWntL튷\b(lۆѫ>$3FX ǹݠAJ@ L.j6+ uÃXcٖN\)& g]v\Gd׵qkL1`X9 qp&ޫ@yaDe\K; F/]k]6;dl\nFSQ:_Á]ltŸohz@:ݎP]04Eƴ93n*uATGjSO]S7^_v5q+|x@Sh! &P *K;GL3lFXL -4@YO)rGю_OдݫɵT:;oE&I5޼2~GCm5qI(rKd\4qJ3a zVo=XM8g 'j@_Jll6vgлfjE9ϻk``|4$:5)&$h`.L9dG574&BaC]gJi\K"y@ ,A*bpԋ&]m"ipKYz F[ID@9E7z^s1/϶r5Gb|m?+F-yvAf҂0@ǀE Q=Y NĠ9?SJɌ,e g!CFr+: ØqZN' ŝ3N/F\VB˵D[.7޶|ۏz-ZyQ][x̕XQ/gOt͈Aݑ\1Lz HXLX5-{y}v1nJO8>̞<`&~hNs->_̶=w3``,чc9h^)>IJ?8.?B7U3#ծ(q% ؗ@JuICA~ Յ5p5ڱ s$NPU5p?|>~(ypwā@P~>HH/GƈUr?zؽzAeBr[zTc#d{#_[W2=edn_P~^RruJ)a@r ViLY-~s|dvR3g]"2!shQЦ~r#"&dĵG^?pTOƦ~7P"o̔vs@IQD/v/|?Jk<͌:s2*^_V79yzeJ..!:&F;{_|@*NjƕwZ2;`t OctF pgʕl4ek3mye*+Ig;3/'4s7t}Gpstwko1y`ݮQfs>xkz}8|KѬvUojDB.}o?}^^U)0Cw5 Au7J⍱3: UtcGkzvaPm4mt.ܲ aBNd:C`щ>߹o;Xyv<շޏ܌WfQ qh)"eJ4#'T-SpʰUàDtj3>5'_gVGR=ݥTq~ 1UJ^[a찻1fC{jc;ް+؅f~cgMi_r:qtⱢLVNo)E"͒~'sUjGd5 Gh80%cL0X "7_fgK7{yw{q 7}%suWC^7#JjP b685g2o٭κ>S?\G.߆'ۋcyhkG{KѭrN(nҢ#M"@NFC#g# `8@F8. dN 9)s~h֗Rl % XInU/3qUz) B,b?uDbHqsn~>˵VҞ_hE*GFi})_Y_wJõɣ3O׃ҝbd9..QV+5v‘[{yJCXHQm6i[gB*' KsND؝۲k-t>rx&ȩ;TQńz~ %@0ػNQLqHomfW6*{%YIlHt9V4b-y'J+u-ꅦϞN?ZBS$M*͐k)jn6T%2 b1ʪap(f[ʓTNU +m/}N|罣bXnwb ׵Ƽf]?汕zvzh)[]ƘPSӽb) ')>w$] z^HʌdЂ&*QZC~U27=A61 B)8` Ժ Bd7ÉVy4nTS+s֔PC@1](;+IE J]C(fxCYkbpu0lr ;}/Aړ,-eܴj< !$ sDG5$Vʼ5 r.牭:^(P@)3&r"ñ#s9y*^g%V}߼rPLNZDV8ܳ["9&DCGCMRP; ۂEh;RSS,9)w+vw,bM8-c6 mx`oyMKJ!!U襹~M}shJ66^qYKqj3&M`-' 6LU P<0-&Y/lwcAB IWfh}|㷘@ XHoӝ+z# w\"D[R':*(|r ymZ/o% {mHZ+=ƭFzͩW{?p b(w(yC[EI6 Scd4\ 2?}-na0E}e7ws(ZXl/߸]^ԭ[zZ1`tgb[{;='β*K e27T:'1XTS9SFqK7rgrxKE|GNۑq>9!9ŗOO*7Į9'1￳M1FAײp*7nV{oJv.NuGcJRA{5w5}Ռ?߀S=KT|A9$[w|loCokﱍ&+fx*htMq`AX V 8WIHeKHHunex g6ejEiuc&'w+N 7<&RS-`N?8 `KfWdݔ{_U('uow'*IgijR"l䃲K.^ F*=Tm~Aap<K*nY9"!* =凊FFF]X9/~-D#|B~iozovmBn/D7[wbBW n[Sܣ`.wtRo W#jk!gEgKwN^{P%Zަ_¥Alk{!MxpC% gDy]+s$J 5d@񀢡XY9|o8[@zhCG< h9ֱ70>hUIp(Cr]=TٕY꽹{.oAY ߺԇ/ϮVwnn mȴ5|h8)Tv?7~樰v\7k ȵv$yWrN0V0롻ṇAOėŽMpiPݗP,R ]@`f>|'ɷ#a/ݾ~{~bR LZd>hukd8e=s]NmTɯ|Ty^Q&iynGm|W,] PYGiG8j6g-ke$ޖ|Jr.|1|_>%3N+0}cDhyWW&V!p4&B>ޣ-q"nYARU\㕀>ujSSynLѫ#\'(1-U;vrUOY+,e4dLTPԷ¢ev4sV0]zT זIxg?MLsg܁u=gSuqz!豱׿RzT욮7e͟aǃoJ<3mUOrpFuz/ N v,:TݛPeȀQX~& .r5cR_!l{=U 6v9ѡK~p^5 C++x~sGwnA?b7o-? F?6"9}}z\kWVqv%WZ`ɔ=luYrIBh:8z884so%0;zC29"h&j AbN8"&TOlT[6XW[ ,cI7^.iӵ]N'/y\=-G\7_'?=çgORcWe.y!ʗĻ{>Y`KU{ڃsS,Жq$\>Cx_oʹ[qLklJg҂+%gĆ;NlbG^[cqk h % HeJ$YbXG[ǟ"SVo#놱1Ϟ'ivw"*.8ZC=rtտMWރG4Jܧdf'+ؔOswƦ׿624}UXKVp*z/ M0v+3wmhgvGZz&h@: he^.2yxm~бe^)<̎S{齻ܺ->}h2|׼vYcez mnm2o;kw<*@KAvݔɉn;oe?QdL!};p8ZmB@ }4C;ً3ZQx0DW^4!`xsV_qJ]nW~:n]t~>.হT(a˥BGP1$$c]u:,!ѯ)vV ͍`h'7̛ٻbCXethCTv?hd Ѐ֍P[j<0VSn^<lG[.*ms!F9b O.w' 1f|vJ@4fuP_%߿"~9-kRQer&kw|jO{|%B4Vn29+bn)|kwoG?n5ǷGHTXH XygOjdƹl ɇuhS%+;wwY0b>w*o_hR^[rG*JVGT*+ R.Qd^*jrWs#[jS쑀0l*gAiCڲd='H[mm;$}/2הE^BdL+ƣ[dlo2 6BwSl57ֲs!8pt>1ڿw(ݹq#In{Z["\\ڱ=ݤ~1Kde޸1)O7]˦vaӢa0mQj!P { 8io+$@c؍[&,Wg^*C]re Ց굍P04{ݫ+foD8XBa?"*yaH7 "!u~e{x⸴qTV6$9g#h&)hJDOï= gR&5ū䆃kMcoA|9SRUH3;9"'|MJQŬ[TPՒVƠ 뻠*E: W39NA:H}crc 䨫 KDPS@P~gyo,x}W ,p3?hш;f %vd  %C. t['Jȸ[mRt#QNT(7e(@FK]I@u{#nҿGvS~|wQ|_?3cOn1o^ {$+z`XIL+' U 1}}lAcP^+;zH r$us=ˡTv$T{PF 7o+ `%0"gH C(XJ+585)2 rH-_3I,zXc4q3NP.zU>0RD;HJ]ߋ+i+C5=_NWgt\,&&61!ɑ*EyN+ַX`44N(`ޠA(|P7z[n﫲2]֠2 Cirf)  hb{aoIg4jwC/s'mߐ|l>vO|i]x=a]! t$$l+̜'-TBq;lޑ)z(eN-ÀR2;ŧ?ܡ.7nEb}:󟤤mC-ɥ\^߅˧ʣN0l^ĵo`a!5[PӤqag\k~{P6<b6VJE5&KOYj*}ne26tT?{;e).psN4uL0 Q]#eE HtAr]%p RhXN: !"Xd9Zs@P LCF`< ="hnr0^95NKrÞj!SJwWU z̕V4,3 zGutW Ƥ`^pZ~J Dj=oI,i ϐ@q6Nkn]A./mTXƢFs0vbkK?\ ZH[%8닑vYKA"\_E5҃eJgݞQnkW?Qxn(18V:a/ji+VtHPPbeI1zvCe p?'=|w.k~ QAi/3JZf!M,(gQ@g`,* Q؇2N6`%dR9ts4K@ `JI H53k2Z %j߾b ?DZ^@^(('tGg<땆$CiS.̯[ʝ%g,.Rٷ \0 LRԧ?}pRgks Nh2(EF/?_޴U)(#)Ol_ldK;'SyNk#lWR-t5yp{uŬ (zUuep"\$M,c1ogvWdxѺiܛK^2Ra:|r 9p]w>qYbp˨AC$?kқl,`Z.O|Jd}Lx>\jy\RpsaӋ3HAΙo(a_m33Mljߣ5V/Ji 2#Xˆ-.3@Z $:=3q0g!H)ɑh`Fm1(K p#+YXJXJ 4]6T h"CO ƴ+oZבՒ}O٨< +Qo $0K%=41*vﺭMW[i.X;ؘLSεryB_tPȃ=;a~k|c<﯀Lν%=[6'ϥ5weDž/ ;WѸņ$vʼdݮ'!G{} u?}B9pV{Ci7sK}+>X@JHGkxqJ@`!FЛF)CC;@<〧IsR5Z,0 K64+.̙~ zΕ,]9LLPgK=*۷ۧC۲#" c/O'{_\X>5duHdd6)Eӯ|_~_~/n꤬Uۡ`跗K΍5۳>u2C6]xdZdlWAA?ZЀV2v5y_~+A\Z۬ɚ yV_ j'Q8g~۞ g;lMlJ[(3 v6jaގwޞ+gӵ{H;&Ϋ 9ȔŬK@R[3v暑kB&Ƶ[~ N̴5q&ڠ0&9: 5mA(Cmm(qQIv9uxH$a]tZ]3.֠)%E8C̆AI]ϓSqz F7w[i3Fl(#4m>HXvs9 (N8ϲyXl8Y㻖yn<9>;i!KNmוϾߩΨ}m ?ZkJ  oZg&/ Iyv[{d<"跡Do>Tx/r祅7>`}?T_(BdD| [/_CS [M-ܔH :6{}\7(-Q"R({}1@Qo[ $ԉq}vǀو\ % b@Ҥ.,hwJvéEDg*wˑ%_.tdgm9Z>&οHo5.Ook#rb2t1z5W! KNDsDe䙇gه>h۹x/OeTi z4M붏}}̪,}uUwU1f3XbXIRA1 +p.Mi}ݥ *B|5zƋC_oL1َ?xF,o7gʑV$VZkXb_zjJb ϩCcwz|Xt"U=@l]E-wu믳NM]L/|ާ3OZDdK 늂Fu-@2p!xr#*;܌)>J+1=vHlkYԕ͖HXbGVuOr+ӔU %` (=Q-XT #;4(ӢިTH\-7w"s$~&6Ƥn;:e`S&DR} T(*%Zr,e^ 0)T3O{w A\/= Rp Tiχj!8DcEzR KվoZ"oy%U}S/)alL֚KoAu㋢7{-yDua')5ܜ*ۛje*T|},2_[ 긬&|QR{E?Ǫ¤{K? p^/w7H~r~ o0Vo=0 7<:P ~Xy|"Rr`+eFy)@uU))sG;T覌9䲐,2 *c EeK۠ ,Ȱ'kڬ8sW 4J.[uN#XJœK `= :tyA[yuA^=̗ǽ+wZAC @k, Pt&uR|B5o'U{]ƇɍEŢ0YrW?}'Tz߾o?L9x\_TF1?Sq{u2 MbScӷ෿}|n~>Nmٓ@ODdW⊳/A<^ShK: v쳠vc{HkH6If2)7TI+ Z3 J> om5M1) 72n kg{/t7͠L0t@B@1)IjWW$FmIeM'$6˶DDA 9'L傖Hjt'WC#$5ELX* !@!'ЅqH"R*+7a(,gܵr1C: [WkSU y'|H=9gG} )ynpܦ lkx{q'/gsbԉf67(ZYeIԞk٘L^?vvv] *~s;[Y ¨A7?^dȐ#J0ƾu GH/v?i7na9숇ߒlGde=9I@ AI7l6!yuvHhJWqƷV3vDI:]ݔS#`Q֓NxD5Xy`zdTW턷7?u!ϱA&~yUS'( Qq$} I҃AH` #$qV/kPۢA-?`9ڎN.B2@,p =Y QqYzv=gƲuBj`- _2_H 4e0 @Z+UYec& 2/|3xE;c҃l$%cʁ騐nxԿ{v]< U>X}FvT&-ŧffM[Qf4P&m֨fDÅj0z.^zD|7B0pZxU3ҷ=ӵl%{n0~ůɃP `DQ;vЍL1ھ|߿+B1U{NcNa~q?Xa[r-]7<=|/mmg+O#`{ڣ&t5?H]Le&<{ɎfQyc}zhmSͳ-N̺)\KZkt68Vyͷȱ~UE-6Fr @|WZPڑ]"(J #tUG0ݖnfQ~<[  ~m!AFLX'Oij|*̐5B|^~X\[(BЂ.Sc'a#/9fEͻ -|^}~għUpЬ|dj,9R~܅;zN^gcogLS!D"Pkϖ/_PLˆWѭpe"Yj/ _1߱2=C7hW_iU71W's\TA|$1pB!M _ wD#* CϗHʯrQ=ZzXl+"rps2 'KnJsYlw;\~:Ep5w['+Kh\ę{vWXe/ͥMͫg7rAۍ_{J޻W{^l5D%6}qt`s^}Xsf淟I 47Ky5Q3]~t^P_$ؤ&SbŝɊL$ [sܽw3n5I穵~ g_͏lvs@YdG'[TR[=6{!zKε*QNK,{R~4lt@"̳#3DC̨0'|ڋ!Y1'TK8aX7$4 ~!0' j; Aq4@(W h?yXή(ژً?m[䨿d}3B'xЕ83ͮ$t!q@0C>f9GC?;xi`BH,yYF?8yݺ]yX~=Rs$m7=j7^ʽӷ37?j lOvyl?^מR-#i흁Z8Sk77q$y [gyՇSÉ[#7YW.z;cׁۡ(4pUCtwwȰ8-`zm_DEjxH9db|C=uIZ5R?iF6@Oܢ&>z(KDn9žz-l:UEDZL cKq|@P"ؚEXH P&,=]L+}݀icuNf3nwXtMALMBFa{VQU(А_[l<AH2Ky,n# d :$zR#LKy}HW +LgƢ-}64DЇ3`@P #gYFʒÍ;7$8K:89r@rš5묐˶Zt8~޿DZf7"1ދްz'vo{a%ܲ=;<_ה*h&^,NN^: r;+ ~e$F3.쑷~gw{+HrmX-LQ|)o6ܵ_qh$xbȓLw7~C>R+#~PL(?AYV[\ebd@-}.<9ZvӂE{{e}$3AQ}afѐ Ɨqp@B!nj$[.>ijf30ۖ'*{d. A %au=OsƩ%bR!8dqY Hb6awRiu(!{,Р^:'G0#juRh#@"c)&NhV88D a@ZO&OYڮzD5XoCi;fe[}"Ǒ2 xK1u'yw㉃ kO=ƶ[?h8/ NoJAU֩~¢:*ܳm'$Qo&Gj3x}֒v{NHT6<<j~}YZ\:8PhT:P?%޻!(OgC~ɘI)LE]Ƅ8=|@&)w֯q~C㕝"՚߻C`*/+B:셓{,;0٦{'z-;<}ԡwK8Ay"re~dǚ|ZI6= ց/7 %Iהb.Uuu_){t ooJ% <<?Ht <$1M/Lu a&+pc/SoOʵ7%+~kƧX^gY`'|N̂5A 6F<D;Tl*jI`8 B.OQ sq' -!jq5@:S#rsvr wg $J3laPꎂ̮!p`0;V[?U/!+u?ԒrȒ6CHb>on{?t6.n'$xe Yp ; E``>0޷^Iyh589rzp흂t<oap';U Kajג%R?v~nm2%Kp~6B|M^.{1X[f<Ø=#c U&lg޿]\c[ぜ-yfB 908qn>u :T~8х>/+L8W\?"MS-0kRM`)81_I){ym?Fڠ@⃙JT67egeUv,ÔZpPe1NOaGyrSORqDq2!*Se._ Ǫ;bZfA3~\$XO?4wd#6EsH\볒j36Ð6X@ s[Cj0_q۪Cġ,cV»uw[h%fy:Y|=Ӷ ]$FpZ,yXj0;-/9VnOJʀcȩ-nU/W?(;<|]yT eeh0Y[' i$}zSd7n݊sSaw9 W=uKGk{HJv77gXًYo>`W<||DmkEɝ=?m\Qdү٠AITnan{E0|93݁VC 18w1@(KX"gO VـqNDF)e*cұC#s!%ڡOX $ϹhR@ՅET+ldp>8wMRCmuhd&)Ioy rє ` :]cO}: EMEX*N4ا)ktD05hGOXk`:phÞ]cAtw:x=C@G\agV9/@XH,&2=?Sal 9ցT9FeV~E[:J`PZtC C:}&G!a}{~s0n(knJ, S5Cǟoȍ"Vޝ+'yԧŻsW4O>6:Qe_fN:;^}∗Chݱ_cŽ|1w[9{Hߓ&gwjIom-=w_@R7U ZRAz6ϫ &L&6&+#!pl/ 'y+hݳ'wve=Y-WMt%LJ_]Mײ~E"h" AdS"Ug0raBb ^29;Vݻ@AtV2kps$p#quʼn Úoz7O yVã$JUZ>\p6}keM 7D*^l4]`״]me,sƒbO-RDpПręuK(_f6 Hg̈Xťg, f[婗bᦁ!5Ьy` @YU^"|s0f>n.,"JZXWs&N"l,dN޹oG)&~0I:P!{8']yb1OnK/S'r(m83Ƿ?ɳ3k0) ;yK)agH>>7U'H( t`g7S7rgb5p|sfȥlOrTqbW\&N뽓zbn]qFƇ]e.]ܔh9KЛFBu`;jz+ppᩰ|oD݈~bbǺ z4p$X-#R-LLUʤNnd&57|ٛ>8-JE)rl E,y*-ht~NNCtfH%)(V"ܫ%nKx/:kVYOAc׿.$7Cҏ۞\|`^{{/ g=;@:;Q\tͳ 8bitFbwk`!˙W ^Wq8W_e  '`Ժӗ& ̳7̻7w]-CMp$XH1J @:s 0پE>gF``?O3lM@06~ Ӏ.Ad#_`AECڅ]xk&ZiNSQv6]ZǁbKhYFyo]j״?{|ھۜogSp"k[I](hDG(߃>9&Y;blBu U3v+6B*,]3n40l csP}{)sp`%smT7\JcA̓&8 xh@0PU:`0ٲ _]xzʦUHXE 9l[|EvӦjXhs{[J&_y F:VѓN yY×ۿ3hB9j{+OJ-`$!"hS'X'̆^Bysjh=JJUHrI`vɗ_cOY˷ˆ.u2;EWL06jX;,#P63ۿٰ59(pDe)!bM`?[T} pIz` ]nktSL6tZf$ݸ;x:hxϩ&ǐF/K:{2e:˓=%t#hj3SfN aUϑܡ6)Ef^fӍ^a{HkY U<; U~a *9nCghޯ<5Oz&H˞2̄~NS p҅O@aM4_[*nRTs~lPX 5O[h}Nu}@խk M{_ljϋ U>|L'0"PX23:/޿N{.ljhz%s~=1PG''H&uSH/)7O-.{Ac4lW5)2S#QOp/rU3+vw0xR˶xYN:ľHft*>:9v"nn({tKk~T.Sq>q @zK7{J6ĕPf~gIV!W~P[TJF+ey7+^{@S*t2#fQRZՎޡ ZƠ MH_ A S_^?T)j@ #<l.Oow6>#oS6CQ9(jUB8sAogol|P牦e*>1Oo%Wpqڭ? v8ºA+IlVV!a;qCelwѥ35&<<Į.nџ~]m!]PFth0ukrj`+KGЮw,sGjc}dnݺHQLMrnu?Uꤜ 5([ 48G$nшJIVߘ39Bc{Dʇk34\@kQTĕkU lGGN Cܼg芾anZ%4uSgNѧ7.>FwmӶgKjiԫ+C +.*\`"2X)@@UɎo|CLMFc+AKZT'pYLЏ`?t )^a1:mPcݹxB叴95U\K)c5P' jvw"fFWtAjjJ55Bggfp|d|"w*6Œ@o$9PTQ /Vh~y'.FcWdńdȣWsbA/nOYn?Ģ'f QCKw ֨YlEhR2m5? |߾^'eD_8B5*Ku`bқ&[3 9Pʫ'=Rd!j#g'mV˔ӄRv'}IWaNwOj6q̢+4| iBTk_#CG}cyXB&TT"pH!IDAT4UBIF{v#VKwɔ!jNO38>ښG6K)ٽE3{"A"䓻v 9峷_ǀgT/"J%V[XQ$<-%\tJRtm% >=EUSǴqvFg 9H* =ʟTyÚrSG\L|&$9:Qy[W,XHxbha : OܶeѲ0I2*/hRZ@ cOe-HmBFXd<.  AP)49&RI|̦QΑ2F}´uX Xr5PX*yflS SN7\ވ im (@rEiy9{nZl/UWZKl0N7s$uoMF6-]7rm2Z͘`;h!7 aKUk$zCjRp5E9g^]7I䉪q$nߗs?I: ?>Hg)A41ưJ`1VVM_׶|WbԧPZe M)ۏ7^vnP~Mv;iC-G+gVQ = 5EY2{?[i{MUcq ЄTzfDpbm޹7Ti-n{g` B D9-kD]1Ν| , ރ,C@ hvr`G2JպcE` tء+GfN?uW̷mh Bw4VNsP8 eLt`/'fmP-: 2;[X0h ;9 ζul=1h7~,ro3:=Li, KR(sw9t1y3腲? [5a2o+*} qnwP|+aډRm!/~[ZNN)+"_Q܀A?h%}{ غlpITSz"#&^տ)5Q24G-7]A!s0H TGfB2˝uDxKZP<2urU ;Wc :0vcgϏŧ/V2kYdGph`KE8R IZ2Zw4V?޾U6jvG\iD, AZgۈ؉]k#[Ft2jamP%S; 2efU=ͿS-`w{@z{*_R4wj/UHl j A 9G![[ !`P?H2hۄ:A5ɯ9oU80t4eֶ`C5+7e8BI @E9 CbIqK~U>ֆh% ȷ_ԁ->U~5dtNhD-x|R|i^4x?s;tg ZBK ۇ?nT ?rٛ bę&(@qCi!43UCJ/AϦ=DZr @8#(Ny0ݯ3ոӢI5pݗcnշr`N =ED̮Ke ¾֚.m֌]CӧlIYAHB ZttR:G%p᠓9k,>J+1"_\-N{s.10(C PZZ{zr*:GmNHh}D10@h߳Za`T^쪵V7#gir7d|҉*=J%8fdh(3ȫ])2m>6s+ٞw]ϔK+s$Xiٕ27wQ=p\gMpVkGJg !" g5.b4,BY{94sف:yTwS'aGס:(\NO&~?g5gW?^|{uTxNoJCS*WMmQ &H4t-HY R3! 6ϔ~kYĉ"S@#dFu=&/ΰforUMh/ԧڮwUE.'=F@bZi)躔Pjݚ32$ea&aʎі1 0}lO#"2[\mG 3{뗮c)uBUOXBQ ^ԉ+=A+4) {VxLfƺH_=}fu}p:OYIBOҩA64gܝYm.`o]6ŠY>˲@^:0j>A(Lps*8ȚIT0H#8k:@{Z\RSƔDLnNiú(guz\>]vG|(]6'^Hr60slkkŭͷI$ `Ҏ[:Ȩaޓ%_Vm]?T2Q-)/b_f0dGAsO)kGo!r3HL(X:훃Ǣq/3V/j O OR O(;BeIY0 C@,W%: ƀCk"d_i\cֺIE|Cm gX+Uy`qZK#/ӺY\ է Ͷ.H\_;$a!;PdJt1/ё6 Pio:pOPP |aX;oT*Dzz1+mG}B@kx3*sY]{{ uX}sOU@)qv0@2;* m(H0Щ/9pH[Kg-iY(@/˥ _.o ٧_b1h\1(=;Sy ~/چV~~s_!&{y8ATS-7BFe䓬PO%?2o#?)5QC cr W)B#© :д  9hZ`ٙٙZplw#="{ YhZ~r ˜1ȜH9bmeFA@X$@,8QBhPM 16^QC!Bdm%#^i{slMo+Ə_5]'ÒYy(0;0`=UZzsn.-k⌙_'y7 V%$\n*sýtx4lTIZm~[׿Q 4`,|`" |ѣ pqSz>df擠52n.põHaXZ~ʘe"uKtے< 3R~"q0Lm"IB˯=f2Oչ<"u0P Q-4 Ǧy4É X,Ph%qYmr[yUƩLqvoF;csO4G,\j3Zp7Oԗ§*OUޝ~Jg\TPkRK*4 `&m>ĸ!oqъsarR[)O\`9jIQj qq\:m%rg,9pG90 `5p%}v8F}9~66u$TV!,˴(A:k9DdBdԟ<1:zvX7r8Br=iaiC4uT@I*rL)i*];}pls9J˛>*Djt8E*( 1Lp-J?!7P @" a!p Bשnv}Yʍ9Q4|ۺόך9[ 咈:R1F5(3Ā5` ht"q`,Ն_P,Vc3RՕ&Vü tvB<c(B]i%GF]wPl'2$5k@GsQXד^"Eb)Nx#vȥd[ӺjZc3ۏ iuƙ[@P2%XG`J[ުʧ`%T B fL NSD{_`OC;0A.ǼW$C1v .#BW!Fx]_7I{ёBڡK/^ۨtoXCH+_dn&bZ unm%E"] }%Ά鄮_'1 |lϲQ(m.aУ';Ѽ Q2u!䑃 p!hg9>lXZ g;L{nv=Znj*hF)}jRpeZF.Ȫ)F ]}ӭ?>ak >~bW.t}tn?ZU"5">h]3a}]h^JN&ֲAco;W(+ _Tv`w]9v_ QO]*nq1Hus 6U{ z=adh3r*W y?M#5H!n=[owȬT2j@7 +*=vPV'zGW!RZJQ6L W(%:ߥ4SCݰ$VoܯyoޯuIoMA(֣Ɨt@;ާpAk$7Wn(OؚfU 2ʕ'rWo-(kA Mttّ~j$=m%b@hHql hϧ+R$Nc#N[/| z=F}hy8 \N C/ʰeG$0Y; ftoMD:(S; ꍐSux?;?u'gͮf|߷ӻ+_e5= R`wS 1Oy Q3US"#x{3VS8M`P /Yp1n/gɮؾ+\9zN]01/w`};t''v?ɏ;{.DI.1jT#ծams?ozQ5luӻa  OrCpv`%5wz(  h_Cjd(GHrZ!-cRVhAP1xt+9ef{:/j5Z=nDXNCQr] 2Zz%F*Y4\9{N=[ؔ"uCnCo/a,"^-=I C 8\tJY>Av` ь_ soNh~di[ӗ;e'Ѽ1?~7(V`Qdՙ*,v{9#ikڢ 3"B`5WՉFQV–+|g ,9=\AtI_45Sytm߾vȡ7 PpelL;b+&9i `S! *-7N~|Lѫ_zm⑉˿w$ע8dz? S^?( R) J+ٍ͹=}d}ך|}iK\M{o0oŖP (l,y] 2.eW/0"eзu:C^Χ˲B0rr&z˿v 6Ut[ CoK@ '8p6)yOz9tz~/ *-Lfמ/?٭PP=v>{\Ǯ%Xͦʹ%)T0FQLSĎPR+'8Gd~CYy/~~W\:VmL뾦_\p;xfFnXkOg;[̿B:@:53P:,9tor=mMnKl zkIN 6沱 QRE18ä~>>a͸}xN4TGV fi7xN뭰xUvpD{ʢ%!nfoо;Ժg}SASK<3piH1r5P[Qte;־|(,R'hWUaW onG$HstuzK-GXGE/^:$de"4jieY$VA<ƖgS^.8=ޠ13_G`y[]!٦VXf71cmhW b5;2)fm.(d/\/HgS\cy0}u_9me'YkRyP^kEnP|GS@zm/lXMW.p^G(CSGTB;AXu'>ZTXHjQ_kj恨J_>3=GEf ݩQbK‰g\B!: c (d ?Ӿ9\56{__yEe{//V] Q 36Mu2 b*Stj jq*m`gDm[.ّC)~"N-{(n,94TV:e%-"1"mgJOo#_fG2PkbiGZD TvyLbiÐ!yUX  ۵1`NG^5 J!=퉩 Qʎ69Tm*>\mSɆP%CtHd¾loYz/@LE?,k26\}}y;$ G'ѽeg ;5uƞڮ`vTKo_^a!?||T3mYj TժP"=QU  +>Jۙrpt؀#`y:t瓌m)!'bsԔAND ׶p8MZwJ-goΞr uMv,vWKH}"het[p|QCM6Kc85 'JV;9'llέ;Cv.'6pQw F/kb0pxPv˔PІrS%HS7ʝǪPh;Ƃ ]d)/:bV;鏨-~joHJb#F!3ÇNA9x78}v]T$=('w]Qz=0cOkTvL8'j35ɠ8y=Άl4 ϱջR;xzLF, o_+A{3o츖ߺ86c݃\ vy2HL&Y,}HaLSgh{_~ith|oYYf593Y|ol +{`S3:h9smj[Y^U\{̟', m =)$$kBJ8U^PtmT.GЌ V:0etV~IܘƘKoSgA%jPK%[bV>a+(8.+C#}X0Tkfxm5;Ҝ ]q6W+3/nW~u6v)$,|Q \idԎ? ;y(%pO!XXO~Iޢ|tsK{ĞK$(wXOw_^7k?lyRk^dhw: >yнy+$T;hU؈Bd zy[\KlI#Ȁ,?jq-c ԶRiY6KV:.^N:qgUhqDݢ7P2m$ꀒ*/[)%Qb;1yL\g;xmҐ:g?^++ 4{rѯ *y#ivsMZCT5XG'mbwQ(_5ƭ/?ń ~>wRy fJLvKO?YדGYX4"}Kr>Tȇi4|bRd[@?_Vҡ-3f^$ˈw,4juڌ"]z;4"a*KPLۋ C g\ &(I rK<{ex[GW.(.$жX!5 15[T~AtcSq[ Ȝ )Y';&W.Rw<',gk"@f ٵ_˹?\vASDƔݒw<|8y =v5{I@:0ʣcKnfwh'BռeyJ=(myDv!vy 'Ih[y'ök=x.mE{N7 NԺbt]cfBDс/ F5JVnymlGQ4;ŏ=KiljyP C? `vykhXJW6٩Bjts/^ "m,= GL(~"~;ig^>> 1gFil|| MsއWxu4VeCq?֣L b6Vʆ`Ӳ0|Ib K*6.cI+lQ*dʊIFF\̫M2TYK/'fap}gOgٱ/2.cp W Hj]O& [ݿx׹ȬV ͕1 %|Yk/gvc#U+.`gHVUL҃@N-zh[n2̢~w2[)fGv4^S]ʆjznҍO;N:A!|pasդN 8Y+_8۾|Z|pψzuGEݗz*sךl]}lya0o΍ghD}>0C~~RDۛ6~y!omQSNӞI-uuᾬ7 ~٘`J͝m{dy+qX.Á& >7aLސ_ˤQĽa#,{n[N&S>s9s+Hfet,q߷ "c+TGZ'V_B_Nc8ݸ+[zw \N.RV5*& /$j:1 rz9_~`np.PRQT'ڱyRGouHff6wU)4+ɉhzpqkHLfHVL,)ŭ}ҩToQ"W/X6CEfWewPTl>T+C~LR 5ū,[mpn$UurK:#Gj:Ӝt8h;kX__}&}i^H8xzﬞ /?I~f24V~B=jĿb~NM :l+/nԪqxm?|>k ڽ?OGhEm>cjP+=I j+4jLd#m+&+m:+ J9-LtFQnB6qŠm9 7 g nkC><79PyE>FSCRun7;O:ϤMX!WR?1{y2#8ߚ(ulr,$4YͿtne}tɎ1dve#lU‰VIrvuw{/.(K8 6 GV& .jB$>򈭷k{:_:IʦI@(t6" SȜ>O W njonx$7ވ,BD:QVlZrǿܷ6PZ*Z槴pE" ̔rIc/YJ:[ Yn$Km;U;.ݭޟ]>83@W-{{U{J+ޭKq'/{xP/VZ2XccV2u]diDF0#DdsՍTlaR ]ogQ;Yb$'*ܗ^>=M]Ik( X-% ->t 2T#)偺Z@0C5By/! Wz&"TS0hQMWOk X[2o~<: bQ4Vcddx|+^gνH/~7~?Wchv ְmAm>H {# ,W\^S"(lZ,X?k5S+"@0XSW:ZBf`E_|>rQAA-d[~J%JI',̰˚[O <ʗ~Y iq\ljc"ߨ XSؖZ#熞U ҁȱs۠s .Yo@lvIDԃ{[#S{_8?h;/oVd͈B A%gR7$Udm}|x@R&O.x=e}Զc>5Ȑ̂,R"wEP௭OѦ55NKECVU]0pozU572\QApSO.0*k()ZwL!n=)K]&zMVP~ 20 SnYl#OltTl 8Bc*ͲzN/VvTpãvdFq Ar; 8?~q?'±o!Ssqݯb*$ϟ.LL(>͘`!wix 2v8߱5N~day9!urR3H" J)/[sZ;3Ԏjř W1IYI0\SbhZ}ĮDIN@`;r@H8QrE*(Yk㜡ۖHՔiźW-8=ܗvIU=Vv YzVq#4y![>/DOs{{r7ܴv OEC'vm|2dcV$KTu4A3Snh~X9ӯzU y+gVIᅲgYgJԕw' -kLA~FMC%FvM {t6/k$9bSiR`˧QV0W7!e"{`GV;՜Y/9<[5K%v3p& HE,8XO>ws]Pr0(kR80TkP#3{!N8xg;NF'$Za\5=Tf1]%ה3Kiܚ[_DݏRG-ޓFv0은WN}'g;w$*nBn@xZ)$<dp2?d+INpwW-xhOSZԥUu,I( kAK=1+}ߒ+}Eɴ>orVbD.e6\>X <=A?G"g~Iab\U 7oG@zgT޽ԻX^F!Q~PDsCQS\W^秝9q c8$̄lٓz P~89gm(oܼ?WHvEޏH+C ڂ*/km x'9~$(rtjm6FmVv.(W8z\Z{vwu *!f8ԫR~̛/d'/7G7t wEﴩ(.ߌ|hc6<іh'K2"f13$KB^N{_0I/ iLXQnfg S_+Upzd_JfHZf&8>A9]m<᳉Ihzj;Vߦxhe7HWmN0@X:Hǯ{ױ8]C7,OQq0>CG}3GhjMrA<6;.mF(< {Yȅ+TFnѾr^XiakMK|y~a^sMp8jq$zv"DI޵ά[)gmu)+.oݺ ?zO~0}YG ((-1 < u_ԐQiLe~ᜀa,g6%ԄÌmE{c|Fsb-<ϻ4k,@4bh=w5mN[,UO/ ~{?"Z) kGj 83e1@yT .AZJׯ ]p|1K*0M!ol+Vu6(V"dDi0?-nVc-MVi”6sldzdD7mF,VZ9ԹL-]ZIpƑ<}BuQJk%k}rǡT2L:DنX;Y:uUm\qo\JnoYJ"NS>m>p5i#ﴜ]λ-3u_GS'UE"P5RXtLs;Ʒ?{*XiⲨeƲムS| wmXD;F]Kg7#-o~/oh恥 ۄ,k4X^bPwV[qL7ѠU&/<6T@Jz ~7mۯ} ˾;QKaA7]ܑ]ueiL-ea-o wvrgw,kwtc\n[Y\*s飫r x6IH{-\g+7p#Ȣ)d XmV40XYI|A "v6nh뛰Y7IkE,Q-}dPQeKnOX f4$_AO_rõמn~=DLvTnR⹿d4LK,+ Y]e+7ɲaSZ|vI#ΪC1#垶(àd=HrbXXD-8(ɉd}嘿}ՋO>T`{[I-c,]B-G2bVO`ߖ5VƻtIMEFkыeyk-fyH%/ޚՋW+$S) e дdeDYXR-uP* 󕑵NV-^["1Hq%|~6:4o)ꬳ8# ,Zr|L,Q$ j6{!\_/ eeFD i+@x5y[O4c (B<ܦ wq(on[FO/w;iE[4 12d?wqc1dQr>:tYW/o$Jhǥ͜m_'7l4-+o˛nSR8Oup:}x9ҞG?yoΛ_^ˍk]C+}SJ'k8;6xˤ"cOol dZ4Ҏ &@0ͅT@@@Jm(uj&Q!={5YkhG6,eH, 5uY_Q5b+AZPoIyOFƂ*^gUݟ}swfښA e, Z#UѴde˒0F(D~ӝPZJtT584]|~6:m$#k8pa:$`S"O5A$Zj5raQ%OM\=|_pXwIC*(ȳm"6qY(Msu׊:tyTE6<˝[[Iyj`Ӷ;[XtxP%7V )gn^U7˄^v m&t7†=w1-{F!r/;dOYiнp#E!w}}?|-_\ WN]Jnˎc#ŷ;Yxk;5~N+Kiuru*YpWr7I2=Gh Xlh#Ɨ0l>>ewchYbVbnfifZpzUGP,Ļ2c$0̙Q$3t|![HBՉVں`rz4E7o9׶DCBbe :!dKRP-wPx Vcc /ܲ3{gxd3Ypjʸ%:X WcayY5`ZŠtG*+gďԓY0d)&PCƤK"sz"zs?C Fc&!Z˿3L+o:#6 <&,ޅ]C#ӝъP/mg-=`V-`mo??ZjQAv]CfrhCmW"ZeR[ FģN3$f%A_n5ӑ7vGF G6 DŽ,vGR_kg{e'Eq[SЦ{NB ]0VBaj Fڳ}N:h:qF#iq,PibT=;l_dQ},J6~%YfZAg\h>qVx_" e+AAN.B~{u1{ۈ"p5!;ה{[ƿK-0fƇ_^fou$,JLDKNeJKbzjq1qF-hM-Xjk-B| d5PmV|Set4ƒ"ن1$ڑ,'wͮcwk x*?NaN kkGZvn\=,I)Z b+)r: ƤԦ*"fXcUb&|ûT]Y`C> ]bcn^8/l}AR'sdL/<m L>)̆_T("d)a/.(1 ZXe%hK 6C,>_|#\(st;`"h&Yjw:#}ybGz{MKEXo# @ɔ0b) Ǭh)N2&D+ي4 + `R9_lJ9.+. f,}l:2zVcXZ}oLV_}y -W/Z?}ֆ*Z40;`b5qǔjdjo=)qcZC +ES0#3 (VQ.t͓ (=D]K/e{Z]Yl|iA3FP&;07z=~pA MHfuTyjE;qUOJ[̓f=Z~+c#In+!6hnheȆx$,GRSA٬<"n~qWdqXU}#󹏃tνV&NC\ԤȀpسX9[<]ށ !A5fN8IJa_Wj$׺`w6Ƌֳ \6:0v"Ƹ)p-V@W_)Bsl1|q({yR ropf5:}'X˼q?:WDun]2/+9>:h5= / ;uz I엓|P:1V2fԕUԶ1!8B1IvT^ ƭYϰқӧ>o%ʂbY^iKn]/}02H-SNrq&""Y7 x+uJViRsډjRdNMD4p^Ja_KLVVx# dÒ<9E8LAso=K|ъ&v)FE}u=g+z70oɮ?(a8̵ F )8) I"aG("u۫=ؽ^Cѿ͹9 >禭slʘJFƙݚP(ZAfRkbN(z͂m$VtdJۆt'qQ֒b5/zk-֘&ZL }C 1!< $oAbrQcCVAq=& ^J1\Ѿg_~u**\KڝOj5Bk6wVz& N*5}kA|z}(](0) nN-@ |  O9eD,œK/u y1[6Œ1_t½tH׮o^?JSZY6W)zYSkX3 ۅʅnFd8 %݃={jN2i wl4_sl; y_^GJ{}i7NNx#~b3tbqmUM7(EdAc[q65{# =0StVS`c=MhR' hʂ!a egEdJ8_[wo%s;W<`t,_=LE9uP\]<>=r ;Gn.Y\SQZnMX4QV'0gNU TY敒 eZ,.b!9AngnI8i 8-gi{W] =ڍ~VY-9&e\VݠWܭC2O 6Ɛt{iRKf0z64*e~TM R V0,XO Z.RvaܻQfQ+-#:y[:q hV0lq~Jqu٭Qe*Z?U( b{]{}+imlW S)-e0sD?rFQyV#c2C,ah&0ߵD_Ѐ 0>BL~X8ٟ۴k~9Z/``&YZH]Y7 Z4 SͰ2wYihinLpاN=V⨆1rRrA \r$nnћsG]oz#W 8]Kk f*S)W6+A5 mf.>G=|} r1M%)Zz5sXGD@e"kށNG.u4 Od8 Ju]p/l& 1 )p2`ÂwV=|omUEkJ.r_DfȈ B -Y1d&5$/=~ѭNn;{g9mcO&Ⱦbz(n]fXKh.U!;M/~vK䶼rݸFQ7w5kzh-4VL{)x>X#F8Qn^Pk0 (_O6[ћPkxMq޹?|HMw>Qa]3ΆnYVI9uaT&0 $4dGcg%g?sLU1j5bTKm3}߻ZvaSRI9I5@&J4v;|X:LmR;qx'DdhGͯS46;O O.wT3̒@. B8`]G]睊_yt[xߞI#H|MaIs'mWc$H"mGSeGhQUa4UG?]oܵ@ش0(((0RVKhiҰ{[RZ)d: Dկ~U"5POeBÐ/@y%F4tMc<;`'WJWbQ^k(G2OzySvRRlȘ@8.]gRh~[t'YU6 | -w0)Jѩ2*KO Z&ojF\?u?zoQӈ0շBV:C0;c%˜ZACV̶9>Qmbwe_M *h1(DxӋwo?]z؉ dH3hյ~nhn. &G;{&Һ!Hi%"뿁0HG;_l(Kʸ+Qb2NМ2Q/?-5iKreH4/g/gڽgޥOm#MeYbIlR1yԿ)m If\W3FHy@Kg*'!d1ĨiuB-r{\_24_fP·tYw\=+ڙƦ5;bG3]VRf({Py^M_?9wnr`SXXPΆCHb)k=K9 9wg ^G/βM-0xy\Gb)1ۧP/^L\2Qgz*ºG$ʶn T Y;U;Ǡ?<*})h0e2xL</9b~}te@12nY[Pqj9U֙dpm9AA36 ;'L."L&}#d(y9U@{d(z% /ԏg;z-FQ_b%+ yA(8Vp\)fVk}2/$ԤrlqyG|yNU!-yw"uǪ-fb2-b 1>*MH9je\ㆬ*4`z$ ^Djm=˪sm= I /]vvZ"89jQP3iēk *8A7W O޻ Uc*>tV3f<]6zVszx_wѰnipK-uegD}9ζ^}V rMQe\\q%]oj>oOcSο]?~eIRJk sr#o^ Rc#(O"r>UVK\+3G*zg-҃˫w`=U0¡:,6uOq'S02=1DniT0kAOV&0R61LWS+(%>h;<)㬠Zk32*,/ҋk[g?77sC𯿄;_| ج_t)}}>ZMPRZAی·$!W(NP|9 s p͢{}K#M )CL-5BǸ7F1 K"S`7Zu.^XEtaw~5*Qis4V gzw=0s 7i(.7h&R〈c=ˡht6xL`:9άt6>kR/ģ`i^ڌRZ5#sc rU gl ^Ɗխ'/\A޷/.6fS|~^^[ܺy_Q>#On[mޞ󮒛'[ LjK3\6a&A a)2p ZY 5RM s=?kI6 2KƢ_C)/%ܮ\n9ڤ[Rw Vz Sh~ -J|QB$w7kE!Q湱+ݷƈrF|hJ@GTXk 澰)%DfLSʤíU6[QHf7Oa1TJkud@>VHj('ﺽ 3dQbeέD55{+l4PQTaT|pXslraLj}0;E{TmC ^dL\uܺ#p 7|F.Q[&AuY޲kZ`rG[M-J#`>jo'}\סRs.,MdLR6#siF6/8Wʫ" ɾ\k?|?¸"lUn۔fޓA]?M0QMNP7,Wo";lܸݼjȼ-dPAARϴ#M،T/FDҮIt E%P.G+rΠ9QV!\XekTnxq4\\ -2xЬsgF[ʮF%QzB#rwX0, EAb7*_G70ƒߊcߟ   >7O؜%*!6(혦dHSE "Qk|eRֱ6aSe +Z t=G?+Dtph3u;N;/puҲH|f{Po^\)9s0%a_W12wulJ-lحWɃ-!5 S&l#cYѡ ꃷ:۬-#͕|T 7Hjmd(tv ;FBuNt sEa}[wKiz{hN!*}LaRn97n+9(q#Fr#{ ^GBqT/5j9:l˚叴j Dp{|EH5ySЩ!Ѵ\#%4UH m賍 m{v )-ZD(+M`P]⇫RxTJ$$AdAs?;Qm9oڷ*5洒a}K4v"^K6o-WBܪkQՃ*f ǎnPZAm#OB=7~saS۽u6/i\R7N"tUP>yT(h?4`\MJvuE=|V}lW~R u w9:.c4.ik\xl ˝7U)M|9vLZ}كDJcGiźH bp'XC s!]Lj.x$l}K;ֲn_ŋ㨫m%]ʨ|%zԄ\¾RjfOI^on |<ʗ[N=̇|%wu.I@b 2:)F :Dsj]  M3| ! (cOgǹhN| K ARbxU<]ՏF7)!ո+oش UI28(CӇo>h^iA?*-wwZQ̪g^1ב)0=b9i9,5mJ#-Qe09歮ޢ%)QlutX;E"P%f:4(,#ҏ4A׆!>>ji)wO6Xyv`3IDATk+yJguKN\y^o-B'zmxe^E}7sl ǜ7øWv\ "Mk/6Lw^p wtZ(k+(1C!aL{JZ:U6JDҳu~/X50(`(=<鞦~3'%?z&k ޛwL67(q?x^| V͎,چBzXh-m$)XQD*zK2<Ӝcr/PAd"|ӕoAȝ}x{l89ێ^j&~i é A4 D7~Bֻ%,EXSr91傑R NOyNl3T#kq0^討ic>0Km9)Ta4sn6tcnJZ`ADlǰ:W؜k(5pw {-34Q1ڶ Za!9ǬQ*n=NC"'Ly: > d1KV$0_9b i"ztQ4;J0<~t:6s%wJtjIy` n*Rkhf!Ec&JÏ%?eqG guaʺ7l-<|'&tahS*{[% fKZi0e\&O{, p\rn:Jj  Y̕=lĕaHfņ%?um lBsk MP-4vukKp>ȁf78LY-d:[L⫋} KKSGQ5ۨ(A9<'=vDĄReWrLǔ59PV0hjp\FS@MPX)[ _T?/Mv[y/NQ5i'wםV ͍U8DlWs/ lk/x+KȨ3WdECPЉWHkۺu:nyJa!{Ն:ǣ< 1䨕ZDGMŧOeK2-CV)IGf}4Mb_dN⮭l 3akL4!T,?<92UP}P֮eK,J +:ҫ+˻VU. c-H__d sOtF~/ >` h128׹]"mFrHXtZݻoT߼LMu3iMx׳~*i=%K>kqoxQF{1]ݬy?RA@\{ŮϠ]SY0#h]+`2 Ϯ&F(]Er)NwZ-DдajcW޺ }d ݚr5{}Í[o_3:Ug21)A;vK } 60Υ&oNqf󍯢1X;jTskiBۘ6u[X*gG"y_zxI컥7{JgԔ 2>*cQ@9ϓb)G|mFroݼW<[ea4a R#!Ko=RZg[NZ,٭\\[խ4رhw# k̹Q$L@FUw,v˼R3HdTBݱ6r<+, r^Dss#y^`n4SYtM9ZGz`p46YdeqGC,_~TBa_ ľ~=/?z8Gn仵YjǞd\;hbW: Hkڀ&wWG7~QΗ>* 'Đ*XpAun[R soU1OIkCJUXi#DnRG=lQd%Uʌ̕毽#CnrevPwkG9LW;Uj8iJד}˷jnݤ&8¥-֬p*;}*>lQ̗p,I :{q7;-anv0zeE  :,V}6ɊuFz稸ݾ ^T:0|ݑ "{VdE"Taqd{a]?~=hs'3m7L'P=J֭K;ۖm);d:a\jPyeOxl[[R AF rRi`2F  l ߡ:f oajː6WI:$hB̪ujaJDtYYM9u}{†\]] -KJƺD= 8(³;jodk!'P\$Y.87ƀI[/aߗMrP^^4M6/[bZ{,`ҍS@Gr5znMA< f=4߹lrpڒls?/_SHXi3k}ܭGI^A碏Bh0EN.gdp[gdqb 2Z< }姦rGEԊLk0s$ʗ2T%`jg3u(z=ӘWKp`S3*6Y=\huAdM *CA>lur}la4Íwf=Q6/:AǙ^edwĖ/=$bmdj%*'d |B Q`("Q(7`~3)jkvIs/J%3 rH!eYqD}䴑WqįRHQU=zJ6Uidw?|ux]ji%;Ousڛ٨QȲ~[Br͒l)e_f /ahhx h#0QDZfB/ȷʳ"x:*j7lo捛%OGf0mQb֡rS08?]]84ſ2nmFq'@4M }68^*.30Wz2^{$0SrnB|2cyHU,aly**zh}.Zl֝dEحfPH4zFVIKxst}lF@L77ν РZݬN3J3Lg2u3k9qZ}h܀d@-p.C2ܔ HQuS@9)/4CqL"_!#YOI Odv9_GNN+e&K1 Q-Xkxn@ʲ5U`}3F2ѯDPwVpG8uc!yʆ645hZLh-I4u@vO/w* 2,!{x'׏ {_>s'ܹ &~ -V;BJU[-зH0H׭0ilKf&;{ݭ"4: wocLf2X J q{汪qVz G;GgۆMEOyp11a?@2¶8fAQ7M3zkzk=H8N"o-4 gbS"GXؾ(5?^5B;{T!m;e2~MC±bڕ^y-*?۳7NnaIقzȚOUo>e5rej!F1Ef!{ .A38T(X~?P|w&&=":-3`OYuUBj;a߅9bbֳ#^cfJ[;n2hS=ȅD0{4O=do8q/ۃ+"NEL7d脺pҹ-iq[x,;m21J~AG~T[pbg\y`@p~; emz&lu5w;:q'UHAY`&ڀQ% IWԾp#.iIظXI~Bo'342Qշ;FWvfJ$x -scs-5eߞϴ `tctМ~=ydzdzCMu1'V+bСOY"I[fL M2_ )#p<1MeVEqEj=%-a H>\F^tNڧ7i>׈ztKfSBSǜɾӏS\800W.>4 ʹ8}5BemM ARX1瀤Vk2_:Yz;Z|^:]*%);2,^ ڇ/68.8~R{-eR=%WWhM?df8Z}<}6*w{rVv #VN펁Is,w]YiHF=P6ޢ7n 2 Sc':ylcaZPC=HsQq^ޗZ5Ѫ];i [K JFeJ:Q;_Rmx0\4SHC_; "yž 7m [Gc)7/v{ie#}#zTTiDLG/>>thsjvP6O !Ǫa@`1 Wqr:Y K; lnoa{N>Cur8"EJ(REٔeIVrdY{-+_Zɤa097:T9W|?rgJ"[0&+s MirQ-߫ൌKokKRNo;x +ЀW(?=b 7#~B}` VRq$J_`$1_GKn׫.B?0Nw z<@\t ~[8i6NngA)r(84t[(dSQUk\l#''Brxux\U+jny X\uH䉌ð!Łex 謹(ĶT2r Rѷx`~CgB?bv[=7>-k=0>2Q Dn˅$#4J޽R%9ue=AK72Vp+ A Il!N~Iڄ$+,𶵯s 6H!=2&zJN88!f}1^g?\R09o탑x^Uؽ,zH-W\ӎ ==3_Q6`u3!40nZU)#-JՏ7۫\`΋a h==Q>Zx$7Qv5͞zf_pKZFcw? ΎI;] H ^YE(}rۦk`3`zn7r9Hvǿ>\ľtBU A eʛkEGRQQ{GJ[}-GTNO:}g@3Yd Ⱝk6g=1C@=\ܩ LaiS%A/rqQ)Mr!o~}{%pyJ]B. g xIѼћo辡ssF\9Ź9e-ܑOYa;GpT vg~-NrMvc[@4z @Ǭ@OV@#0@Wx"0yRhD eo=;._T4{k[ȒhȡBBXҢDPByKsxLYjߦ:md=L8s/qeݺc{Ѐ/usuVfXk"\LYe'ʪoM3jDf3R)p93-6 tY*" gdqgONg'ױ X!w^֖o]k*&-=>ϯ7>9<5po?SyӔзBO:4UF[>Ŕ*­3VL.AAY!A9z|w ۽ e Ⱦ.¿/;p#@` Z^?x6Dr:tv7Tu[+m{ wP߽iNE:6j%U2E~aAFgBZ8n;wI3ta#X: $ EmP]ciTGU==X"'2{6-w.Z-uR|rFmfĐLտ~z?k =c4CemHԐΒ5 ד@%xX+R,rcB2^/1nӏ68w?O'bءiW>ͽm"٢AR/浼蹄Eܔx1u1^͌8IReN@KkG[2;+yku v-YGt;3P֗{B9MDRg~9yQS2W[ s\G:";N^:w]@jfgUO[,+}Nt^o-0Ԣw05q_?(0  7 ^,A(*~tڛD" *WZ],U}EݡR_^Ro} kD[_/>7fokqڋ݆U/{4U;Zae5!8G9 Y4N+&\sr3UwCUgS#>n>a09os2o;~nǑs mK''SO.^zU,1TL^j_[xRrgw'+{[f=0 jA=%nB^UJ 82p#GXIE0mQ% B6Z6eut/{jSU_G#ØcjƵF՜=av?^1 x-z^v!zzf3w][ҹ9|HSf !3ydRR S3B4J @=]Mpa߻%efsw=/d\mߋcBmȠ䁥֎#S4:a-1tк6Qg&p7#$Ɯ(]p:3{^~82n||oog o6n?7,][J[ tkԻYEOhS[HLtHd5Y>'e_ AGY *y. o)GHs:H~r4vB4[Zbp؁Vĝ=[ЃsIGp#URK@r6}7NӖ6kgu4x\}]imzeQ4'r`ij M{s}甝n263O"Tv1vg03@h;WW('V*?O#%0(+O~VwgGȨaY`gHl 4rb/|d84^Dx]ǕE ҍ2*qz sbQhh j)4.K\խrX0NE)0( .~/y~R]%64X`}?2GIS[Vo81s) je{lpsktK;=KeVfӢ<6SD0`:B.rA J^nvLg&@UE[ؗ?}~~~q6+[D1gzTcZΖ|NV?߾<+^fRW.hd GC}X-_hJ r>gS^n3FѮGd X g C>+&77IpE!)6&NV𓙩;c^WSkKwVM;D#b2#FG;qѻ^#wUE~ vvu>\c.I(:^ )b Xb=an#d`ځ(] 4XFtP)2]{/ _,E8+x*Ҧa&X:,TSw7HKm[`e*\zl4t`nrNDgrJ,EZqlOUGѥsbx.q@%P"0ii!# {7E ö_LH 2P֎$F Fa< 5iS8$KgNR>'rT}j)ȝVKCԜu+Y}1S;78'b@aQ D]}''31fmƛC^:ѡ=[s H֨a羼L3@&VqNg뇠نIׁ Q1nZ#wsN. wHGbdzm- {FW.s.KujxT?}&Kc@ol3 ٩o$}%'7v.~{A" Pzf򄱻Z\nUyi$M]>c\+~CzWlf Ĉ#Z9g:ex0leÑg f5S@ԑ}$~\Msx&F0αG+׬_i#rEmRqg}2"Q98)իw##gZI뵬L~I}&pԀKwg*{k1`a0ȋ2saG~. ==ij`L=n$Jv)s֭E4syH7%I v÷ #HV9tcȎo>VE\DLE#gX0C^藐'^ϚԆU`qHEq=w/HS@E')i|lOɼxa_([IU`>v|,!6 MeTcvyO@@4S)aiFk ]KC;^ܘѦ\hԺE)&(H)x@:2nnVN`&Cir}A|g֩44v@kÃÊ+>HyS`Gr۸q3R+51و6Ǭ cxOR#Y YXq#u@iTҹcvV0aT N=*:GAX|&R5Z{o.+™Se>XT7&S ܏t'tF<5f &]tCסgrr%/M+` P#$Ҟ1%:cBK\0)+2٪B gl* wZ=>]"[n 9jd0I23|zs7?DzA5§vxW'$yg:e[GTJ 82P8 hȐښ-—cnfa`V=|R} `694 Rk'zBWJ`Eo9؃.΀E&Z":&26\ch/Xݾ @2)C,$5eLq"<護۝uå|mFCdHQ\[mP9\-TK3]jiml.pӂĕڹ,{6r3uTQ i|]4ڴYD884=` c@ZIg_k7&6WD'Juذ޿m.ޘ1uzt.v0} Z}]O3]0l`ı3h&۴4ImA_~p2_ ]F'¦ G|V& 3!Es cpx\Zg\Sj'(Yɡk<1qmS>cG!ɍ>3hYn6Q:0΀V{so.\hLANC7F׾R9{F+Iެ1J`ƣH(nG'fok?u5J)7lB426QG 5vi H)8+{8cYuewZc7Ҥl 2W⎱X@cz{2bLϪ`; 2;N! ć 5 RWy.Zɇ磫m_ߛ+?wJ }.mtޛwKޭf%iOMz/% _!v)F;i#A/h}P[UPrvXf I}keLiNĔhKi\#-s@{}3ε&$(RZ"T:=51N;nxOŀ28,Y.RȦynv]U֯:k wolm~e>vAnF֧ѪFJ\f>(Uf+[[Mg5퟼S/?=߾VzoDFྱ2];W~f9{x!;d}bZѡt9GƸإW=5E?oX$0n;g&KO&at A ɰIN{{$`^'˪[\N'Į2FpXwN.P{X̳F4@֏/~,׺^أ/ln jCBڦZ+o}3xf|(O=y` 6jB@ԎaZ-Cq5՘'5‘K"ߋ]In8]*l\Wҝ RC39Pvvbs.iEWF3J>Q 1wǼyRVo U'ELho:ټ7"%2g=F;3,E٘S`A@ar hԸFV󾖄$2=aiABd e=4o?'73&2Ij60ә ZW/Q/SScO~Ì.z f^}p(1 6}tu0Epp{ʭ}pr<0?G?yAc&S;77oʌȷV8ewOL׎mW=+|\6t%3rsm͝S@ρNV`R --&Vۓ)UۡmAHHnU'fJm,l *mX421ՌWWP;L&=dSʈhQ|WHp*eV,L!{•2):,()j-_B3:xk8br጗]c͎Pqd גW& [4'1kWD@&^t:#"UˁaK0V&f@ {pZ p#V{v8yV6J]8Vmƪb {a[e|r54ъ8=Um<Є؃-2maHf$o!.<i@+krѲwyF =,W.8H'Ax6*_}85oq&j/4^5=)Pb(4̔[" R&#]Gn# Ig7Egʝ U5e_WiwcdZȲ@wR7t9+=e4Bǜ* ;NU*K+29ab)GBapzEK\pA!`[F5xvꌘ[>Mi_˟{({!2V|/ /"UdSm dNNGZ,\pŷ8\ݨ~V󩖹~(ab 34d\O?gQ_֗fkWđdA@h5|Lb)LߗSv}.YŴ(TF2JUVljHnh׎x:|9gLp6Mr_dww#{ vyZ1i欳(|P`^(m!p }+B_[-l =-o^ɒfd Įcmf4RE7H* yy$Yh{cg{e:sK}N'ky")#)=@y>;^kuB6Z/o[ OϛY5@8ъ32;욺 &0I-P*PFHަBݧYr94]zf+iArVx6Uʋ\5̐/˔vEreSN(ōC~? jhYG_8~۲6\: #g7ᓻ]賓x{[f7nӻCeN;/(Ц1ljRZ_"[r=s&0˜@@B MmPٷĖ'g^`>Z}H't*;Abbyݡɹy; Cf5u-0 )O#Pr"zјD Gml>da WNYb,6LKm~:]jQtr/l!$FcL X dQa-4 O(GͻE`lf58"fՋcaa0ڣrKfZ[OU(k"x 9{V7hoބ*DʻbΣQtldϬz{H= !J +EX<4"*iD˝l_6CY(ح=,ܱ W%bcvGvڡ]zEϞӂk/nε.˳f詰427]d0VoX.R4t"t枔PL>._3[cF_RD$8(CH˽u JNnޅnͬm;v .;&SgE 췟~`a_׶]ekиʶn]Ʌ )=eawGPffIp߼3+KوZIF@hh,=X4M[xB`qD(RSZC#RR`]t;˗o~7һ|7k."Uy]=?iֳ 2i4`r= ithi^c#dM;fH p=U.~|Q ׎ygV2җ}'Z޽RRKHZ/?̯.[T;]Ԗer^*+ Kz6VXMa9;-w_9Ӟ4b8ӧ DW/tSO>Vo]^I5pm3I` nOX $[_6cvGI$P0xm8Xz0{Uޢ!k4w @oq u`8 iZ Ңݲ]V<7Zw(ixx)1,7w}c9ߵ;:xܯV|;ښЂ frep zk~|^1$ODq%4-GxvӁ~feETv_}pg=>tRޫzfB%Q ыLG'X[mJA/EUfg8&C_=nlF:2!#z/[0p-9:]Y3:ԸĞh"g@*'23Ɖ-!slp1u_eFle[Pje]k;P*}yO|| ]Ofcf#Xfc7\x]/ Ȁ}&-KŏL^OOt:qah Q \9s/k`heP[ŞtUN̘KF}iF.5IaB+{,hb>hm^3阐73#gq2b!WzL/PCw2*Q  xY^#EI7w oIvMًaγ s3"^Yr&8qv/_w}q4d}+q _il^9PRJM48Y(HOD"<P3&ϐG`AI.8-ج9Xbg_2~V"Ԯ$Z$9ͦ(9+3:Їxrܷ:(ܼLW- 2{y؄1Q_$p-kc4K{B[g9+q")XЙJ[?zsr ɵl3 A 7a׭"7<)Ѓ'&L"Ƿ|05LqK(xUÖPFMrq=4h>8:6+;w07մe 00`&PʠFJҌ#V2B̹{ ][Ah)K9Aa}wp?( XW7NF)L74ʒ~HO M4SmvSC*GX@.r ^qR WWε~Iat<>x{`} Fˬ:p(_^.lIzs 0/e ߤ>$ 2dv4j`z@|rvi^mK-8R@^diƉ@ɪ [y3)3{2 f2!%P.P_`JV1`%u/n#)77hۙl-ԪV^[k re849wk༬2nz"lMfe0_o·ßƷ;/%ե P.ksЬbf /W1qWJpRKK[Y;+Vs.NO;RJJ(A`D9e|M 8rJ甚sz`ί瑣es$B¿ v̸b4/z1Bȼ >q6b_+3T2k?ʡ xΔޚ w>Gq~ȷg#C8苁ZRP=vr ,q.U['>=JB]\.7 }Btz+\stY 06 O:lm@FAX<Rë[?9Tu)n'T}uPyMW#oDl;Ǧf,Wm ms=`@Y PM/!! ;_'j[ͅZȊskm=p@A:m{^˳ N0sӁ-RCo_`k UUvqE~fkC C%cÅ^F*g_ 9J%9j82G@ɱCKH( -U@X?q[mj`ERIp@ h!3>8OsY^MUK=ubFRf'XI5H(w.u3Ɩ'"lH]>vpLJΔ݉m>FPAFܵ9eUQ1HCwVjVW<(<j%wóGlsKcw^/ ["V|;x=v1p]@.2,4 9C2oY=1d52V_Rtst=Y \FȈnJ_9%IVYP_zY[h1:m`Hy=)]5j Id- {gwfOT\ gD 1Re0-[X?ve*Յ^X- @4ցCS qQ_{ 9 Y,x/)9L-Nk;5XkCX-7. R<"S֧qIo DԌFƒ6iDECdӖ:ɐ :_ct!.9v Ü1DRɍI=-7gJ,7 y!:$M7$ Bi\d$|4(:ټweɯ󤷷`[CKxaPv\ŏ> zG 6LUV UՃ_}>p&> ]?A܊vUE{|R޺y/}`Ȧi%rCa8~,)B`Xq6mDJk t%\-E)qrO_#[/>^X[G&*As9c@{Vc@obs_ g9kzznRڀԌgK0U&βp}4XGf\ڼvz/){fS8`Sמ`X0͍5#0 V1(rÆ_y,2 )y}F&#8XHh~|T{iփ蛏N{Vw\K$s0=xRĠn#NC@2](&B pVsWYH#&IFv /oGDIeU*ROœR' _5V۞?SQo,|I uKTEN^lŚçj?fHNwbtRb6D̯{Zn]gItGJ֍AJTb*PH#;~+tFD:GJNظ3-mcKԆ*fф" %d%稾 8! ?Jx|b$֋_{{0{B5[538*>\?P]jU/Jڀ\ s#{ Щ%%()s;fѠ( ":\F!Flxi"q/j^vIknL# 3(Wv^t8'%@!)L_֨x)`ʐ5X?-WѶ[RYDM&ew㯝_{?۴uF:$?4a~w؟_ n]!c jS9w@)h#޾vA9}vRL?˴}|O1**]7[D к_6>pL>?v48>&i ђVd/~xO$G]^#NZAN98|xt޾,-{k2'Whn:&8yLX18ϛ\ʲ}7HVx[,E7rpxӊ]@v踒cpm֍1OwIg^v.i=#lw-v_]~N^Z 7˥JÛ6աEvR;\.ML c >8L$G`h=LSE, SiglRQu}E:4a3ovj?|/dh5S~䪦v7}iJ^zxyCzDH>/ŋЛa͈֕wZ^V-܁#֯=qg!Ro([ʷ:`ŇĒM>F͞4ˁ>nʐV3֗Atk1]Z+U[twgim*-Ֆ< Xj0Bg5B: &GXqs3a|,/lp`uSjgoz? f짌 Pȏk1.jr S'M>!(E<ޒɻ`s B~{`ekɸD֥IHpFw ,[;f+ o;q|Jk !}do~O޿L+X܏6Y~5cXxնuk;<Օtf@?" w!bica4! 9X}xen 'k/+ Z]ȅI-ƈ0+*Ï~ 5nlrQ@6 ۥ @ʜS,IXaNjkktÛ|E-@|z>8i2Uߨ\e߶S3]LsL< <;UpFL~Qg\~Y'~}zލµ[מ?Mhy&5{=,@"jyy| :\yv D¡qxz _}8:I*>+ YP @dS:`픎:t&6 ޶Z=/4?|/8^ ~B>߿R<>R) @F+A Z8,"z,H]scQ&E vZp~<8ݥPPMh 5:@ 71n4syioxwpo̓_}묫)&&Gt!<,z22wUXuVUOfA^Ztk߷gojtI~(v2kOI_c-remWE&@li,1eJl YOƦJES)mM-A GRR@!9(փk5W+ɥ['ӫ_Cq: YӎfpϚSeř݅O>$[rF>$!,iwAo<'ywYwJkgԄ^ ޳/${ UR~ϝb>V/[C}ӬJV{;knH^`%W|,(`$tEp|0X%9 M CMwĩ2tW;?..pp0|axwOhzu1b eB5^!bKHjd2eLn_ >)DU?锄Xs5T+B7 |~Ǎ!1'ZA.xXY'H ׿C z*j +%";]"w+h6p`pp{>?ۈR?2y?QpXC?c3,`p&-gФpSLjVz ѾdJgGi sE=\aÐ2R^?*yΉ6ͻ8'8udŗ]蟨⏮Wf;jQ:X)5^i) vvb#]#4ۺ\ydb\J7ua]j1WRHf|ߞGv?\XX[8^_K'A@x!Yy7~.{L*'_90T7g߾PRy'` wu{fuƟ"G&:<%u[ѵ/)Kq=r.,?}%:8@~?r K4ͥn0]!!F 9M.eX6<6iQ|qs ccN2ř Zl[ZhD}d=[Xu=7PK`̕~1 R  jg#Ơ-*8۪֞xޖy*[P)l7i?HRR:VU_+_:hC-T~gk3.Tt<7e> MEx( R@2j9M#]Gz`oRJrgLaJESo54/WESbeu5&ͮגNZk35ֳpأʐ?B6?ϦR "PA{am[uP)px=H Z<-`d (hC<ۂ,$ :ipXėf^}a>7M7."d; #AEiGpN/zI|, XwX(n;ZKJBYi0hZ)vlb0Qqv/c{[ b[AkVn7ۇ^~Ff'dxT i>\5V83H~صVYgVOmhGI7mYIM(/ ]1,NF~of]CB)eڦOm9POɜ,{, ~Հib\V8P<4Ѣ$ߔc(/j(j yM/,Bˌeח*s %8!L7C'@8im$eʇbWT7SXTTZөMAl.U:ٴ.#sFmsx$[Y*wyJf9PZ VotVԮWߓ-lp H#+?p; (V)vO{)6Bʀd} ?/--}F4(c >괟x`R'B:(lik(Kխ}1RfVJLS0՞:(к;-D47x kE¦MGCTғ:xmVYzpG-Ro1;3`)nr.RfecݍRކe6L6`ohO'J7X";vGZۻ=2pQ7$ ؞pV/Z >ϺpN:Xc7\uOEccoBƴV 4M|e=YS楈; f n?z0Mp +]eٮ|E@{1 v!'r{酴!OcA3~ RY9*ģ0=sAY3H#4C?cuWVScY#xHbCHA90GfMJBE[A]v]_=;(pHf# M"GkQYcPc$~C~|㝔5Np$/A֡6kFH+{ҠXw5?*pT C|A{h 0;J 2ȠHV}q}XU/]A/ijf6/J ֆykrp?YmK{B6v{֥1 In2+R2~&΂(ֳ)l8!IZAX_ư!U-re;9`xnM.JU s@.>|&^qr@1`SZHq/9y?tmoŋ}L4 ?%tZ >keZU[-s7Sdn\l *^ .Kؒ}]-nx~T2u^ hCo9(AY ڏEs,+>UPnbՁD1N%B,xOPT+˛Ҭ۔r ʔcҁt}r@z'aJ00#[7?ˌV{McEGGj7Mu0)P\E4?I/fPoO 뛛{7.ӗʽ0'/o8fܭ؎?kyf!PXޟSQ/.w ZsO*!i,XD,痦}yp_wzb=sndL"%{dYg=3ggzw;9g=ʲ%*@H$rnts\]99 RLS+7]X7? }.) j9XXcpG M ߾_ߙo=j;'߫Lm˳e!* T2gp=Y(QYxhXJK^+ jókIP*֚ie,hB7]-yL?"1%yQAZpRQP *`itmNi{w ՖNazFֱ_{ݖ`Atq6B`_㼄*xCW훳 &V)zm8cN*"l'.0t5"qF]2) NF < 800u̩,Es(Mʀ: "(/sDzGyU 훳SOkjTct@mjB|4Nٷ^hx;mD,d"-npuۗTG ܵZKXWEp7Rcz9y{_>q6S)"EFn=99uhn;Jsz0uyy糏 W_$t`8i`s `'85ȃn,A/W? [Kpggo2V[d,,S͵˓Sa&yfAz/"%_equDaawg56+Wtu˃m"Cs Ii[M|{θMwQ{.cl9j^(JXʙ@ q-nu,lj2w*lxq;|S PE!\s6k? #:a^Pْ@Ps_\]߮b1QEHM]cԡ*VA]* /;튀CISvhHJ)}7J[w$܅Ц0qUK9z4zr: ~u^Yi0Y3) +̾ڃE[V8XFb.4ZARq"H7Q9 R`eMP@L>Rlg~@+ZJ#ԨmzdywpZc:HWnR: . Ӛ}Z=w}ؓV}O^^Z.-rЖq'TK"˙E,PY-o>4ѱAإ*şF 8*4iv+&6eKdudzZ{=\\xi]W{>{ C:tnԆ??|/pب.|˺WT4u%0UQݲsV4$}ފyz9;иf(PQph0өfd@bl̻.RL!^_y2[ ȀZO0ͭuwR@x$t=oyרtCҗ.c[@:/[ )~},r5"Z ~v` PxxVEp"5HñUg*f إkAklJʨkE#0E&ylgJ5{jD,tuvRoie&ȋSupô4 ;RWiBPdt[(cԈ0^!m7Zk[ɀg8XSF.'NJ ec U}ޫ*Sۅ`Uk>DzWJK}O11Nᶩε[woZ͢zU*,u!/V*:<ԈoߥON^x(u., 8ϒ5_sZY}URjd4T}(߽ {Dw}Rd}RCde$`UP R at¶@"4˵0U$8G,BRkxs>y:heS0bسy fGGf0mp|N{`f,d͍@ ˤ(uJlVOz:3&dRO2p=u2)ȸv(sRޯ!Rc)۬􀠦Lj6-eHEO}lDL,`p2O;yRs w\xD~Q q~^Z#fhPZQ=ހ2N0Cm`~xtTu_A֗RC%pYJ4ѓw)HeTY%һ)q Jg>@?z! o_<{w;a<3ޝ\¹]Ǻz;BJXxwXxZ3BߵtzsV~HJǝ͖έcG,XRK/{>ǦeX0Ga_@ !7(YF B_bA}+|֓wraE@n{.*K0J@Oď]OS_*!aYd@14*x_%=D,\6~.>vx0%tfyWFp)d{#Ov^ym,H"'<{/)H@5*gԂ|%U]0J@e*5#xZRlT:%Jn`ą5qZ=T;n&z\pFo^=LR!R!nSH ƛ"6p扄v֢F釢}m+4@[\- Z]0i &?ӧy$ul-K|G\ՍZ%K tI'䑲oL;_7|, JLT\ļify jg;'lUn&RQXuM !BG*mu=3\}R&DHYam(7أX~"S@%%f؉a i!$1N<{=TT @:+vV. OYWKq@SRu(obbT/fiA =\{wG/wHGB Pp ^p?-XGʬѽꈫzº %q\|;wW,`4"F,t%RwGz$! Zµ^tstŵKHKR_7`YDr>E P8䃜?ӌ(jC0+ GxOvXt7>]Nu+@hAR0 oSEϱJru/&-4W.(T"Ec.:ԫw 4覧s۷ nhX`:$69ts W^PI^|wGE"bm?+XEРZyi BD \%1ͤ23xbD# |  0,TOx*-P %\΀3p4LPbRUJpwWon;C}qwͯ$K̉6'>fIg[ w~҆kS.rT־ K坓9D/byPL] g\zU]8>8 Z|99FWd~>`s:Eu~`(KjᲩ(=HVǏfѓP5[C0b CӂX[`g@/"5# 3PA9`E@6Y>.<{fo;?V*""eCņ'2TR@qD@TK 8 Lqef |ԙysnRK.qEvdиv`S ' w+ڔr@ѾDG0 QƲBkyy g`po+]F#~y%% ͤZ=5 UQ2R(.hQOQ3?Ch7:;'a^ ׅ7D[XB-`;ؕ(O,ansHMg`?@U,Q:O=4Ǫwt)?)o 5% %!.O䃿]5ghE=EKvʩ'Ri 񍒴s4x9?90W_IxX9P /ғ;kלGc N, CV_ʘ࠼uYL+TN~,RC}9en p!@Ʉc D9U܊ьHֆk-N7 ,ί;󭅕&lʻ;^'wEB'-噲.8C:r3EAG˝*5 RaA\vL 6؊,J9*ƮjQʱcbA 79ztА9g0.Pԁn];u4e3@YMσfGR8vQ̄TE`JR Hd b#kP#E82?v a*{{v ͌ؕ𓷒LE`5a2z ԒA.{VHL"b+ljEa~#@2`"6Q/( r<<݂*QǏt>K8+0T,}ߤk)+wn]1TfPg\x4p+v (TM^-O#^k]|~t%8~ E 3q SQ(,,H $w6S]YY*}㛞ébsDc=m}9Sn޻&Bԓ(2"`- `em`WM8cdp`$+_fj**~X@p$g 2f'H}mWH[+eK¾s_y0\ mqX, l(&iM'_}LQ ic%"ܽ6K|wʺVHlSvgMZ%FT.2Oluc~w+2g`qa$BvDDAHNlg WX{աA}`(($Lu nKWެ-G'yw:CmnrOXZ(=}zO m{#e.Cc?_q:'6~WG͑Ęp@G*Ւ-R"[K1?T&ǎɜ\XKno+'Ǐ'.+3ZX7]?X( @˰mD6C6@Ƒ$,8q:#}9B$bY]&F LwA6z JL&] e H9p1Z;_ddX#)\<6TJTPAkE'q+LAM.cR $HHK#:F 4LW$PR@ȂKB lH ;'a5EQKv8xgAVKqI)TFp L@@U캚 A2@ĢW(* B *kX5ȀRZk)R@a2`a `0`##p\v2m+3r8h !AP9 @@fM Ʊ@J FOxem]DAL`LALEH #k$0KEP A\@،X[dC]$ȩR 3@a!),@ d@KH Xt[hЕGac*`?xm=$WhM7?̲}A^@439 lt+N{1 BkWQ K܌ o/KѳN9 ܷFU p"\W]v=<bP{&Uũ^cZPzX0ʋbuV T{d(o!Tѕ°mU,R@D5wUofKtQq+xDi#:;L$z8FUO9N,y_*"PzdvKED)~. wh^zgJo><įZ<'0P|yrd9@=. BfcK7˥ѨMXE!d PD| Pao=;1Tcc$8tSΞ 4Wڂ"(ި,ZFyr@, CcT!PP2N9yh-YXSJ y*5E$RߩΥ 2TO>4;YoV=:E 8(.㔬]2H" ' 'ǀy,l?ϖgdf>r6rk`XoA1(4j95V.3yH=8M!;n@  ]$*TB*s QPCo蛋4P&,>ǺϜãްvgY m-K ( - ew&Ç ˃wf(yc<"ˁSką~( DPM-Hd^]lT8ڠ7zǠ^8>#~7948]%cKy2BPu2=z<(2 wP%2.ȂTX3ܹt߁0AX&U˒X5][w I"<3X?XrKJ m͔)nԘPX|fp Qb1C\l؛,ư$exYvLSZײpo9$Ov"Ƞ6Cj*|@>5H)#< D[P1R`S@CB:`sDxЪS5I|kCYP(\agHic2l<{:31ra-PNFcM>jmp\d|B?!*Wq GR}\ "}%;3!kDfJE>AT.o6KH@w#m Fd}kiYxa)5PFaIacE9P7ߪ N_]970HS:{.G"-%@e%B`+: +F%)&5a>1ZǑTVqXjWٖz׋+':%9Vn.{*Cd3ij鶂}2eb|O~/k=**XiV(59k"N6WõǔhC(Q^Tc?".M*Vt8x4'ڀvVhJ@)A$;pA1@iq* s1 {'S[_st%x=KO` F[)RīȤPsgF}V~Q@n_m%Zz&ySC x zԖࣅXm˵s!cDւH{bHw{}beb 5XAXtj4)BQI 3`AEwK`۳{ƜK ZO!ÅU=U2JHP,r˻E͊Xp@ Gpr`C1"@;^3 o5O3%]N)!Kvk\1[d$|s3ϘZJ!L2Bvo7dig.>ΊQm9ywhm7#Ċuqm`H.GI2ۖq 3X!9ȉzʵ2}ƒX/(J| cX?~2חK/)mմJa-mtAMpuxJa-[~g`%01q|͓[&yέRdW/~r Ա]$I >`Kca4$~JKOT(תMs@MH%@V O.{_?c%&漻AzBKD3c\s^yGy}qvh_ʐ/)qDC7/y;͎  6M_OA^x6ޚRT{t*ZLV< BHJ#v􎆘d$𼐶gν( A0*Zs( ZNRV((` 6*`֥( @/+YѺotqqWϬUq^X-$%%;A0=%Tn7˗R 8.㘤 ,6RA%?qt <{authqarn+M_ф}汃Lb<.0@'I=x3sN|Y pkլaʵZAs-Z'K(ɱ*#1+\ 3ܴ `?<^ry!'{? rP k &h;wMiY(i[/ĩH\ckBI|zU"XȶWV=hM-cەTp˴SAL ╉p{u~t"ܳ;)S1!?ɩ_;ݬ6dO/gѐP{t693^>Q_8sݲ)D>^|z=8$6·J2fh #: q=ZB$3 |;#;,m>ۭH~l я9UoEØr+X=ܓzfd aS_<-|@ono96'q1s5SІRb9N@cj)ci|S O0*9%l]fυXSB#Q;n3+'#ΐ||QrWBs)%7^x?۞M7olX`NCp5sVr?g@goV@ųT'y`H~xT}Y~=`Ce Ku5$UW{s}wn%Sj3\޸VXUB3(r8+j@B$ŪD!xDHaMkV[C~H]0ɍ[A1ƇIl8"2<|i%h<} H = ˶Tk&A' PP熭uy66^ϜgZ̍bpT_Fz`5CּWݡ pj8f}@}JaS ?z5VX#;҉̆6lN7߰7Ֆ僣/ t\Kw{;:Qwci/ %e2ii³Gwf31^#8$LXܱEY6~0_i!u2:*,hl.3KLxO+Vꑰ@=[I$躃H?D/>z|ooW6onF3,#L~N(XPUbDjCCZ=g ^OzfX]DŅ1df-o_rx2s\~4􃷐V\Nn6};!UICƐG둝ʉ,y }9t!=:o"}Ɲ-"8Pw}.'#Xn(ꔄ= @`p9¿\7%bg-ue=yMtuFn+e M-/QW5"հ! 찒#F˭CsxO2l5@0ey Ib};Vq9 RA#eṕNm EqMj/0Iƣ),Öv27{ Q@=ѱQ~qq8#ٴVHdb8-Ml\80r=Пwc,J@4FU9AwKߖj;HYT*VM\FYy4 ڊ'[8L__<#cU%0lVן:\DۯI[mox-$; k{?o{;2M30ߏIzM7ҁJig}^Mc'{s dFTGVY w<[ < !̔ rV+. /m). V8" D:OC,>[my.Fk$L@σ]-3 `v%qю Ȓ(9\1\^{}e´)ˁ[:[ p#'EwL60)9~›7֎"4Ӳ`1C`KI3zQwWT? CF²j\pm~mꯤ'^?3TRuqp:5nb e'x_ڭ2dFw˹EVh40PI<Yo1峨ҢDtR[54jcnIIR-ъ O) *v{v;K?n75:lCT^ 3DT}ssdiyB^z6>5߽|TiH>f Kao뭑+7C 1JgQ{}~^_&{i}Y)p|O`3nd4CARqK]U=7"<祈6 E ApdMǮ7FO\v)]M L@f `vsw@0܇""c㺽ϴ$ _$`]l#KrNTAC|}_zEpˑPA44qy{2 B<=NGJ)B8I1TUXFS|=aPѷ`=q neP1 DٮP#@ -A}֙wm1Dzk;Ld0vHe-$zK.+HG*e:Zn@'Du PGb_=*.NnXw< #4Bl3YVRuهQ#v5*#[*۞VV>>ɨn?MV C'],e*C^8;l5,-DI 9A5L< %U_)zROôy#EIPS[4h:3 khKC¦ۼNb℣ҁ.4)]舛GD3C?xY&+9Z07ƫSͻ:|yom[f1!ԠxMGFYw!. 2dkk+_-&Eg+$z޸@VL]Yo8~2i?;U^jeK)`Vd왠ϦĠ2 O+ {d/Sv-4y~'Sm4Ŋ\@>̊>}r9{-+) zݍуbYZ#/o|2}g{'̽|\_܍g+d﹁*m S0&/|);}:2  I-(}(8 d}W.[M:pVdH`.ۆە[N̆7_{={_9.T3%pTe-+ Ck!(#9&E1 6lGK[vޚu(J?WIKb6`vGioρVX1(ۿ[,%Gj0{]OOKCY 囋v'`;0m{b|EH:r|oO a[Ooͳ'Uo_NfQgnv((kkg }ȋ~vi+* ͽGJVK͘u7j_x6Ne"E\8[jWpR)f";>]~(:>G׻b\Z͕cwO+[ndP8֩λwC/)تWyov ZkZumMK\ Bld% cn|?[;% қ jZH^T5ҏ>P]ԩ>wo.ʓޖ}|'3gϝ4HۯJڅ?֖6߽wdW"80WOz`{35+ځrG M9ՙE-rZ;՜}D>GPTMv% n>8{h3VX dӷOnk;zl2qVv%FF2\ < (_&>o?j4r*k^IjZ;…X/{% LN݅9'"\j*ȝt*{u%ip.u&q;zo=U`-b #}O><Vvn>NZݱnTnn+fvߗ}.׬M5*Yiv^~)4Ag`3ie^Jp:\Nd=iR / SBV$M M칶NKNxf:.U1;sݍ*v+è$1*dAPYӲe ޘ۟[pj87ďՙX9hd2%\&KLSHw,̖>)-ys]rr o}n1t 9,sA; "S x|>y(^ɏgaC4?xj8Nw՗gf8}=Jn}G6ﵳm[Otv{0əi{8=j%Qɳ=:m,>,O[EW{܆6ظZΛˌj]7F FPrnRӗӻ =}>TER@ ,3aeb; jϙ8c$8A$+iW؊fgF'sJ/"(w`¿}/8TMa/ieKNc40b=[-:{1C-dF6[nج Ղ"$wp}cz:@;fo„/̤Sؖ@,L0)]<ߦs$w}$\֫|q.J2G<vKa%63S)đ }2^5>V;pKYgg 4Ԡ5Aϭ~>JsŦV%>i{g~_ڽ|:cfeM[a{c,\BbIGxPKX =Mޥu;<[}Xwx_.ӇgN;g𕇇MpxRcu]uqBh|J0Rc>x5ڳ\R=~/(vAdp,}|&|w[[bUՄ1uׄΗW?,sBڨР be]+:oڶ9DN~^'i)4[TXHtTui O״ҍ]'wʎdH;a$01O<߷hÎ4Oz/ܸ[cF5_dglï}r'ӄP8FDo-ok6[e꠼6e֨hG`Ó.7ǟtSy7WdPZkLWc3sTqim$oԪ9/omchU]\AVn)ĺLYn7}޿~{ui`2~.O_֙S(dS4 nwvYxL.]ۚM;6~6^:Rʵ>k/ACdl^A䈻ʹ&xIJ3^_#dܶ"`Ns|v' !f;¢▛nk%K.U w2@~iK YXƯ~Ty"hPo=BIB$+&kj[ǹTů:?mEq,N^(ճM=)n9EUcFqD* 2Vb`8M5.r 6h$DB:iK.7nr1dVR꧿Vُݻ߮2烙CP({ N/<>0* gTf]ݼ7*3gNʃ3q)D̪ esE/+ߦ|V{;gpgltY.EjŅĮ{Qcvy]ևڕ"i0}\Jt$kb1%IAol{-]S׿lap]fOvA== gM+;T҆VPٕ槟ɧ6¼W惏$-m+}eVک1pwd p6y;^2Te;Z3x?cyQ ّ1𡰓FwA g[.AU7)K 2Rihk0r]п_y{u *rF3o~4co}.|k:B6Dw7筎ΌW* }8;kv֯_N~S@/s`7YaOzp~8)XP7+ H_[⇷AZZЀ^buوuS(7?I_^*\-6%rC`1 Q-Ceנ76i0wUa'+6mM  RuO}+夂2hN mh˷{y&S(zןZ;{kՇU;UgVdŁSb l*[B_ |i.()$Efm,|K~[ۓo2K]yrwtFm<-ƃ55h&; =l$Q:PZR_;lޜGp0}qBd1d.t7`̆t%3 +wO(+>!?rӬ £Rޝ^,{:~t}e i9Dubg =IԠp  n1XRQEhr_UmZ`O*f,nnTh7=߽߹Rwh z~=؄!pVKc hQ=)}Wͭk. R跟z|44޾֊"ֽ͛`$],jM FJ ,–W6yk@r;!N8LԿm  eKNӋ{Ďڕ{-'"0(W_?8Za32pYlTeA0}}E'wȾpˍ0* +VZ8zbOcTnkbe.+waGq<g9XF5'wCcU2dm{^w₃*Jaْ3ZzX?Tm*hе`|0(ra/Mdey US\"rȦݒ!V.l70)(F3֤(*Nyb K⇆+<@1lp0hN_Mkj'egf&wPY^|~TGewm0%G UM`xpFy3x:no;2RN%zͧZs6*;Bsާ\`4jy~; QC6Yfr[AnA$Oa;j;4 9) eGb yF?QYgQ$b ke6y~[OO_]8c X @ND%?M7S Ckrwh%\6b~Rn݃Tqq )MH+ .ip5!`TG92btE"Uߚ|j`(\v,\Gu)(|u1#r ja8rǼ77QY~X_ڂ!\ e^DG5pNR}6AS:}3d;_B+n!8`Nr"_1.AH-W~sħn %v[aQYFƦ`]?#Hc z4 .Xض:v-!tã}Wl輲t):ttT eG2uA;P@d-/mwaÞT0QeGvG m^C;FĞ=Po~қo ZgE̎78nq21YޞC/=UxʏZ>KϟV[ k@cRPiJA7^I MypФzn9y>lɪi$N+ӛ ??Z\4W&o#Pgh3`5q?g!>$¤jU' |uPCm9c'۟%[J3Wm-R!C6$Qs2P@z߀'I':ϞjzYq |h{EuюDwC~`{j)HdPj8a9.J~Ô84h,'7;%P'3H=}Ez)`v|864(Yl Ɗl !@hL-UH 7` v'])m2U!^j?o;6 fT#UD-Ȩ.d>5F_xm'`Þ}J4~bW8Ãly?f$<}̬NAzӋYbv)¼{Q|߹ մn,t \|J\Z4֙'s)3s^F߾մ),T?_ t]vrN?&wK#\ݞR}}" fxti~/zMƂ1szET*S̳Q8TS;ysq / N[E.JUk\+kJ'wv{O{eyd:~ DYbY>yo$^M#J\Iu_ ;7#:B#@xRZO?VVCAAb^ٓ|v00yȷ7 "1 d73 +ly;At,7anReL/mZJt|ʅbn1YzG!=ȳx~l]]. QºnW''X_fPHPUΝT &釞ee40bfKh\ۊHAjFd[R1/LfSk*#G8Lw* / P^SS,^올[ 9ah%#bqc/}lm)iKn\"F#'O:^"nr76Gtف:ǙaH}wD\Aq3V؅,Ҟk1M ©'&H>sڂ-|CO/žq2Bg7HK 4FϞtJ7|ocj箲:R× y.+ڽrmN袎ňBKzc6 DU]gcz%CK#nDQ[Izi nЍ8:bۺԪxuG{ޱ?^K@ϩRzkD!%Jqpbo~?{>9-^`MM⼊lrHQ4Jޭ.DpmlŃ3^uUgUE dەK<U@)[@h˺%svhlַwAC[XKqg/ڻzhϿ,ܨf '*Ud8nUqjdɶb_q aY* ~qownqsN2ڧ-SB_8\Ib`]vUH4חiyjq^Vbp42~,u ee']4|DxlwtLŖMum~zc9zرRM1z<+M@P7t)c(4>yvKB~6!Ds 7ZPnrcn`m[+| PLNrztG%,7&!ZL |ЩUu]U \_*~ F\vjBbo{ؓC-;#?̙(=8`/bg׊?&wVV(sn50JG}Wըߧ<[@hvipLDYk.m7a&(NsKZo:K3 ̑ejFwmSarS5IRo[½O$Umdž2{b'I?kEa-,& (eODSjcO?sF^v]*C[it@ $#*ea^JKN!棐=+U++7h֋ɋ G_vH wEupQinu\7+[ݼ GѯV_t=W'\)Tsh8|; 4͍RH:dɴfwzmwAA3 J^x`Xo9r2k *s[7YTvag%vUa%"0u*̵x&Z)DN>9Gڣ6(nwtu)ڏ{ ORC%v>Zyc!YF78:uBWc2$AULS+ȧOnv2.7v;B)<FN콖JmGbN]uCjcc/E 9+Ҟ)q6JIQ?3|Q^i,-'1&ӏ u,zGO |Q_4{rݿ$VʢHݲ&C3]ru?}s{e#'8MX^$)QYL-pm6 v4QPAf yoHYA) ru XǓou*_G AIVYcbN'AP  Te<8xMjoO"r~%zfFVzdm\IM<9a6P $I' ag[/fjsO#U{8q6y/7&05$5c~t8[_^dž /GE""&$aj:Bub +jONE,Bb9udv/|Yh斴81BD+A7lF2N\i }{ڍz,.K"*QwT6+{Ig/XdKs_n?zBv}pAk(ʢ@Gxe* wVg]{ԣX;i/meGguom^>lQK+$UM%q ؏7)Lb\:=~` 1 l9% Ύ£yk?NٖLӈ钓G yPSe\k^<7:ٗ-Wtm0+V@s xO|^Һ{rtc1Ơ+zZ':Q?Tu< Y<3s#_.0͞sFDl%H)~-1p48C&^1;CDto͹%٣w?= ލnd,ż>9U:++xe-s vwjXo?FBqޚKx&PSv1 U_[MZx@o݁BǃC=pcrڿ=W 8mկf%kPЖ4nw8;`6/Z; kk  e+E>yz/Eł <վ{;_; G)Xm? m)@Eд K?Qz K7t-ƶG00VZOkhՊ3Cr-f^y^InwaQ_z=P_)eWڣ5G @ Tцx:ξ]U5Y?YԢ,7RkpWƦj FhOX@8x6X7]p>Krwg ٽ[$_[nՂHy6ϿǜZ\J Q Op3;R8Tqw}{Wg?ߖ<[1X4^(<7! ≠Ч YFܵn <{'@Zh(J,(,j+-烏_YkOt5i|mCq<~xMϾվ!B⟽P||mwlrgbܹ#@(`J}TZ*H淚Cz,"luӬ S&4w" Vm HX{ ,בz(^?Ϟ߼?պA'R{:-h]zxl؜Cm~yO4[t=Ǖ6Eef};^ee+lo.WWo^xű?&}cۯ_NXO{)+A kV@H},%I^mr蚐ruրsƐ#y@{9rD,|x])ҜrTr9>_xx*2,s e~kdWr'Up.J#rGYk&:@$)a-. Z֭wpNkP[Eql{/H+4 ^6Q:HI#aS!`\ܣ;ڍO`6c|`%y q(}}Hsl; yc|Oؽ;݇Yx剉s![_IH%(r]B,CM*M ^켺;߼wv|Ci`6¨溳ɱs:5)r@ɧ7n ] Uc2J {keZ (pͭTϭHĩqkEcY|X{*VO'y'y*#UYkvᣨ]kMYeJ$i;L KդO= ;ڭLnlˆy>,s?$=u*h fGgҍGJ);q͈+3r}C8.S;@ʳڙ%[V3G0%R_QV.^zМ[L~ѱia7#-Wd/>x_FM?Z"V؍ˤSUX%9ZMM1 1QjKŤM=?ea!X g;ҭNL6sTN_|Bz2 ճV e->hE:J# MbMV[Ϲ(>*^3˗ k%oWN:3(G` #`v∆!㮮]Κqp c۝ƂUe`-)3ۀDjtcvN&yr;;Mce \D}GF(<4l[D0ԪxΫGFٓd{%xYCʥCg:Z6RIe~_Zq\m].c3cRT?3e2@7H(tްpkiWWJ|Lh;0@v* {+έjёEIױIB"A$ R ݔ'\wJRe$EfUg" +|bP4̧1굼f,1y[c)43O 6 *p#;j7ʻ&31]@&v  (B+gRYjSz{FFJAlrznvÏ _/}y}gkV SB3E1#.z-̕2T(X̌W볟ܼڷNL& b0q!0b -uEmw7HQʷp$34&!.9R-PsObbU9>uaݫpCeLq֪ZRTLPwXW`lWp)Me/Arx\uXےN{e..j`Y2;sA2׮M1)\8U][2yt"pʾM2_;}5jRioUOYdoujd(9c#gr(H4tDX<*`~ \rA@]|idBoH<;C}0|6o Ejbjð:uXیsaamJq-}Ãzsc]Uz094Mwjs{d'5Gw/Yoϊ?h_, rҲuK"RyPrkq+,BIג,\تHSMB*3ƖRL QHĔ%qy:DBmv NLBAECJ+J?&X*c یNG/vJs^.Ňe10)Ayj4; G'+fRjt"pخRMDV7|ոj^_} -%G7+Av7~nE՘\Fs r66$~r'++[iU~3(E2PPOsڟlQFۀb~Qm$HdS@O2VghBgx6"B:0ϠeѮjG$YIADXil4D·rBhn*GXy@{,އ(l_\OM~b/ݶ$'x~Ɗ3;mRaM1(ER%8Csi+)̸za,/Q@JHݖ6C}HX5b V,1:E5K$|B[6KM(7N.!џ*擏NR_y yMb)I?zTʂda_e [>kI9Q/ڽ3AnK#pX^Uw I ר۩PҬQL`plIĵ@*o4a@Bt0-h $+"`i)OfcK\mE Y =K( *C)ЎxӶR)]Dauoi5̣퍮^e>p2Flä#Qf2SL= u݊=pAZމÉ1at7 s&2_ IȐ]#w`qv@S0e r#򒝎bwbF wdA~[U)snDDCRthäZd]GDB[~?iLd@QĤ5A0GXb, !\c;!PAv`"Z-eCQ釥k*FjX0sdWv;u KJ `st}wn*fu7is7n-uLӇwfܦ{}x_Yʦ3X+I].Tǧ_?"=KZ*ԍ)`R`¤IKΞ '<>>՚JώT*gn!zJymKZˆPA hQHlQE> vujrM쾳%"X=[Vwܻ"?߽Ą ;̒\WN!WP}Z),Ivۤ}S۷ P a.@bO=iwX|@P+w.ƀ6;5omy01Ȩ H`,0( <@]$dAh b#J9נP,Z!h+ɻsp,%<~&{95VjNI @Nkdo+J"eX'ڲD9$Lj(I Sa@j bfZQd7vhXRp%WcJUy&wّBa1*̈+ `Gग़AUH8 MK Tf۝ަ, X\-@ ӷ۳JEG#S+K㚪 =PX}}䈱KoQQUIA2 DHJU(=Iix>8NPqrsC\$zXUtWQ?{uR߫5DI&h-00tdC!Y)N_R:0Ou /LgfԚ[`7;ڸ\؉wڶPY&&/Ly Vc/ۍɡ[Xp "2)|qHq#G\q(.j բPSS{LBуoJDpTin]{Fg501!J q,%XK &8hُ pYl+C%qy0%ׯSjW X+͍@N {C I(%b}N8R9F!0AA 0*Dl_^5qwB:'ݝf P̨:}x`2w^Zw+ 8`eI %h%d_6|x55š#KPLX.*~_Te[egQV~g"n/UwҰmuQR{bN t%-j C.pRE'c,Š_NܼTvGDs=so@xD-c(R)A?w;0T4I|}'{YVҨi%PH*` !"P62[JhBnmH bf;D1RZm'~t8ywI,&NAҵ.mciI13 T)TIU2A@ )F*ɐ M1 ,!mǤ5ؓlQ]}،TeKt?^=XmLk= -)c49go\AzɋwCBC?wD})n R(kJN" Hgr#IJ F-~veJo- 6 yzΜ룰k ]vq##bZZajD50KL pa~㨯Om6z6߻]#{^o{i5'//Myf5d#h ={)e0_!z(ľcظ{VhdSk0m*9?gWFnLjyՁ3YCSo~xg9T =UjjLq1Plgs>ʾxbbl$ZprLr}ZK@`@c6 z(c b(]@T㯭Gwn NvbW;^i}d_nfu„s!%G=MoFY=pkՖ\lcvĿ9vv eo~\Չ7ϯ7F0GA;Y\}7 `gCJcIҶaMX3YyD)_ 1߇!~⬏tBjܻt%ثN `ii#@ t(EH2F+uѰLgN =mڅX=@- TjKekRizg1 Wr|+g/,k[F)p1Z" l2e 7E"`0Xy$\ۈoޢ=lN'yg<X^mo/(lAғڲGc~@^b}+6ȳU_|і;6℞ ;Yػ_:w{R9!# =Ewk6?=wQ>)mY^q]BݟǤwаSzhB;uK;rc1nsKWIr |*ճhL@*g@}C֯ФnC~R9SZu=]֥^(:i0`{տbZ mɐ64t]$7^O>_> y/ٶ[r}^ӅDt>ӱ%KLD9ɞ|2ЗvCdۗwޠ]J|piG[  6" th1'"z Eœ>tD"V/wtsTX,W "X#.G("{*Pе0+ls`Jt7&Vʩ(vڣB[tAs0ҀU(ۘб,dC"E*3YJawMҠy58?y<7q XQ ￞,>Ŗ. cԁ#lro5xɕ0ݧq/e'ϒ I=^Έjֱb&qآ2˜T] 5*5\2MEE)3~"uߕQmڻ"EœvNPKvݸԪoV|i4cX7BlƁ޴ kYVzﺑ\93Wǿ% 2GB1IsmŤ%j?~bt}0IWL<0ran_6vâ\ܲ)T4sp6F{o{+k_8sZ~f ]YHr)VVF8` 躥SmDM`}@F@f$UD_K;F!'O0 U\{O%B聢dV1L4XzJo^c&^ Z]@"drkpW6XJӡ!ôRN6FIȨ; ׶["A4^ٱCin>n..$`,R]+4j,2mXGC G{K.[qP}{ .g%Nv7VFGdAܣ.Ȏ&qCe6PMLoRr%\ʃyC>1M:k$"mLz"?,~pkxfM{6*$GcU[RI:Hߵ:nsЋN׋QB>gHD  kEԹb/~"h0x \wxE\'2e"g /mߏkk_l?w-;o?/Y}JsxrJwH6•M3bFKd> `u@AetGydoN6"I @ll;:Evm):K/kJI v9ABF9tto3r>hmnѩλHJr|Z݆nenZѶ /N<&ù{0S%8Q`{: q\;Ƶl!1NP.ޑ@JKˢ5,2)5ƱYΰ] -e 0 |peIJXJ[R3@HQKD:>H3]+Dn>d[>[JFquiAeV0$|';wy~qTK% QPg#W;'Z7 t4\ƵNTB!%BK; * ] dۄVlow]_qvڢLvV4JXzs[T1[++-_`JI;sv^tW.,vL=DPFiݍ7-+Ƅ\f@,lLEJ!)J)f Lo`g`{>bz,҂7yvF;,Ƹ!<+Y҇-)頔>KPzY)cm(9\ :+euug=N"Se2Ѽ@3`$ l mC,i+P .Ђ)rsh0P0f/rL7񪫯 hK$l$=cJs[B(6Vu75NܔzW~ LCd2>͸&\d.!_eܴz]Gz猁6΍e@G}[ElM=dt_N?6ܗ* Х2)/ ׀D) ph;8SH6 )t\u MPV/ Uw{ҩ֍ jN[;-V#5sպ+e⛭_ae[.u9Lt=ѽtAWrOka;gU@= Wu ۢ.#:wJ 6 B2]LxLF9dd;ZK 0-䠈g8!2I+VM첉ST녽sOl[_Z}\p Ҫs-I#'ȄPڇ=Og{~ m[3r117Hd=kEoWm+FX[CNܚfEUw%ʍV&W u ē*xco&Ice$¨Vh[tsm-J#I!4q@ocN!"qJIawĤLzr.lgDnu޲#Yo|êZrn/py+vKg2>ȖD6VE6XgaDilOo*>lyCMiY )H C7LF=֧~ݳA", ǤIc᥃u N?)o}8iz,{#&)ΆœVWɅ=|Zc|r7^MW:gnGUPnk~W>h0fP@d'S5j{$gC,m,M$Q 'IG["+qUfQ޸YL#sOV5ts (Y!U'[v%L+D]XzC={\爘WWz.I?kٷ>|彖WֶeLXѬM,>1eZeVmܓ(3Zr)E3ԎWLLhƁ(|#3\;o͘k\+?&L=pؽDv̇-eӥƀ5hK) &n|ҥMdM+9d"%x:à 69+Nכ7JMGw5:FDHگk-}۔[J=ylGO|huE,cO A\R-$ u:^ZOJmE1j{x1LqMSx%+4;EIt{_+-AQg /T~nAFqVΌ^ u$ 6̐qP] DS>sXN*5|lp `c 8(M^ inm:}REpTW|320eE)9gx j@fW{_>k;LBS:iX1Cý|y wFx鮲)EF+X%^~BN)𬅑P>At`yd(I?EW"9n6`I)QTaY $ fJRGg5Aoeh_ pw| ]5K/5ZInBe] R4a/ɽRp8s-UeS#Vxc,,nSjO|Ջ(v?Λ]qi(ꨂo?t9f:'^Ӧb[ZHȀ(` 4 izs˙f UQp>_BD9~yӥ012fppLL>%3c1O0&RzWIibљёx7:$K$ tݱ:VL98|eo_|t~-Ӎ%-;:$膥9~f97%%ۗfvzb&ޤt%UNT?T<ā_~7#=S-Ȏ%Iz8Vo{쑃;͒!XIIt_SR/mC'gKsgóX}gvW6-X%;"ո*cJִLz)-AG`S"W컑'5{C\aݳ/픁" W6=5m[;:`9O:%UiQNt6tږnRE#L׼2}ݯ^@N/ 61S/yYP0X#sWj%#,JC%QGH괯C ɗШ]X9"3eZR=0FE w`I50Ť)Ȁϱ*S FdYQT <05dRj[ .tƠӦL)wʞI/;ˈR8&Eu#Bb ~}A;I{kq:}3% QqsqVTd%yܙTkm ,,q߾45$NPoHA$"% eK` 6sʑ(h9_/v/}NCnP=fÞ [)GҖ=.b[Aߐ:hs-dY>vJC2lu`Hu1/x@`=Py*PR%,(pC[&_Ф|E}gnUAm 9PxWE3y 459imzb!v 2 S=ݳUP3z*+ 'JW a3فwt]qT:vkJQzG=XO6+vroQ̤`qSV|] ?{L1{#WR.'FJ[eMA G"Y`Q螶\D#BYK.6=ܾP)k̖r)2qeKvЂj~B}eڥ bvO>r7%FrS,JU3ї/hѓ +옰b@ ֬wYJhJ;Ä[:Sk(, TjFN85v˽~8ݦ?Eֲn2=ipat:{;{odԍC#S퍍RXQ85ZφϠ^8zdpɞKD7f56 >!5| cFIc _di@驋yQA6P^,A%ZJ=ʪ8WCO$ AD`*v!8,IqOiN*׸B)"i!|j?~5^Ǭ}:[jg\e)9*֖m`[nL]lhvaˀVr$/RJhhcE78"G?{t˟z(p_ K)ld d0F4 57uO_1.mȥ<{C{]%rY/ + yd#GM<7/vZ6'>HEM~ G_׸itG ފ= >R 2x4ϠMY;˹crɑ;V- ZTfS]$ P'N'mjNҊy@|y>}pNGBV0Vb1a&Ou/]`츑K+@Y?+;޵ScI,_"𤄃FYpmYuj!J1eF޻20y&VGdѭ]H3j A13O^S*avV\J7]OBE'qpj<9U}w'v ӏ[oz)O a]#3bWPenPbhGo௾>lU[Zu{#-l0<+5onI9H69vTb[zrP[UJvN|+:b-i/ScG5Me (M7vQPy6E};4^wcw?\v$_tx`H e/2nBKɭNr%69aCEi+_WEo-7?s]D@=V]vt|vy|g*IiPPs ԍkPg-YdO|p7mZ^[+|f^FX92Yp~fќlp{2!Rwo>;|ar_r6=nݣydᄒ|#xYveKvE,ے.kP-}jB.uai|,ۣ]w=-A_WҠg坝ė8sOpYT D $"6 *69lgWy7آq,i:άq>p-uS[suX iO:\M5xU9/D?,f??{ֻ9c&M$h^sjR22BfsœǢT&FWMuC̄!eZ'V|ZaӴXڨZC(sFfZVHtAJII^&yvԄ—>,ow- fG3ǭo|&j~ӖDZ6qH@څ{|'# 764'w&i;/?.]Kb nZ$[:tu(8Z{&i=>YilYzd798pɛ{/ eYN͵F˙(6.q \޸/2;?Krڼ1'! ~xsƥ>v/H&=gNt 7d_vDk|\I3GmzfqToC!5ycM}KjcյPŝw;L' 70 , cE9xOEtWr6ͯԦFaeng`aS>o#`ްz| UL4 ͘QT@oH;/teOoQ&0t-]VxĖ:pm,~Ir*=|^{n¸9o w{uWnٻt|p9Ky)P{cD4uBd9c\-쩠}KY{9NTɇ h;/(D-rm/Ã*+^n\H<{(e캇;1O-wBK+c]>?Zm FtqP 0eqj# R-fdS Tf6~|Q;.6Wd}k/ڕ6PDXMΘcKh7Cw6_)Rfմ0.7 ZA^nbT[Rfi0 D{a _w+ʊTVn  b2F!GS{2KɢK}IwmkRU]!M;"菍MF =Qp_z/huˆE MOFjMΟvޫmx@fo7Il+lvD;%7EJ~ `!iKh{PڒGOXGcwe% [Y)E%ܖH(Zc$xP{U7&9F+i' 'KN'}@Agct+r vqfWW_V` bO§;yLoEWnEv9piRZQM,\Kpe!߿ZP&ߦ_|$5gxg6v4kء2>W55;0簮0JPŖmeE& )=6:OT0,ыOcx޹y)F3ϽNLЫ˂2%nZ'ng#thqA+#Iŷռ^럾/=0vǯUkczkCt2dq ˛E"v29,$uc L #5'4m xȥ!Hk.ƏJxnLwwtRy a.|'TѠkn[?H("c5 Yj΋ηÅ[ء۽݈[n+ng>`*5EkgD''#_| Ji"$l d La X-BFdAAH!]0;JOMNʤaM#ZG[u+iaޮ B->xm!" ^~zEmM |( >i;zE Hbi-On$Y$Y%mn޿d~kl5*MXl犟* ̑ W 3=y܁57uAа|iG'jJ)ZzGV 1 mkx9 2* |yon]zlvĠ+hѪ7hapHHj@H KzB=XN|U>lGd_.1h_v߽)K5;{共N#QF2EJ7ir~] ELU!Qi0UKOTPlj|8r)6عlED*:0A9"Vn1`|xWK /Hl+6Ӓ1mS} ~PŽ?mii `LB*PG1'O[]"8Z~J%" /䯝ҽXuM@h%QH۸M-,k'"e䇗 =S;WpX䯜Nz:)A/Z˂0H(1}6V5C yE=܎]ݑ;Ͱlf;{F5AG{ԣpC㭼xݤ7Gw!3+,ir+l3#G`Fc`!]#6?mS] –/P82 烇w` 2dPMlOO>՟Mv®uw6hA21F.Fog];Hiʢġ{Wȏ(EnbQL %XkKS1Hs,##ˏ؏D+l-vH$MpH6+/Od[+OnTeBڢ|#]w\y{&z<|$Z95VLs4ke\S4: `dbi.8L,b2v)MIz *WynHZRٞpNoC?Xːvx~푕jX)#c!Ϸ,bI$0mw66]L5sznl.m|zqƈ g3`r'*řGVN/cBQک_q1ߞs/N)qއJ}(\.b9:4tX2k'XX)RiNG > HC[#J+T%XiL il>dZnQc$O2@@l9Qqћ͵P5;АGT4i0sϾc&d]hE{߽yh-X\Mόu{f'z's* @!g 0MLO 3+iXexW+iw]޵.I+G;<ٙL H$"P@\u{?̵k[O>o;P|۴1 ʗ`=ȐSm5L0J~{~L]Dhs{pЁF`dwj*7Kt%f7薵)viL+_61w^5 Yh,j[05`зEIRkQZvAd*iAP>dS-}EҔ4nN:5pd)OWAiƆ﯉^J=e W@f;7GR %}|yW(1ZI5*X6/(nJe-,'>OMlN=^zi\)4 &yąjʭQ؞:X n!@rW8mɟ/_,{ R|F|vR 4AW}ׅP1(dwZ@jaؚpvRqɪ;Ĝ75m w ;G )!ܸwsՑv"P;ѭ>_*A>X7;{ 5anqXeY0c3ߡLet5iR\+#Zs_R'H喴 9Ƣa!H$S;/S*,ɊvR4md._KWE$׵m`Ͽ} [)'4Nɂb)&ġ[U'{X%CR1`h5xZhK  H4͔ f=YAvrXv.YnAF>?7'ooA@]gX晧a=Hs{lUYgux ě,;ii 守|s=_~<7aciwY'_ gըvD3P}fejW?&eJcPVP~ N3d})veo$%# )#~o?݅b]e*j5rfB]}%:FH!"Z|>2wV6\RQwMJe3 rf`2`c `-D"*&<hy%` g@v29 HcбrUB*/Nf4ٿoXvk儣fntSg|ɧlyD X-MU%2zxXau1肟X0c])ꬌ#:Q22Zwλro4)Ք6PbB %,#C;Z^o+wکjȺSsof +g$w~+}jPo S' nYҔK8I 9fo_0ڕ:$UozG;s&$%*VU88;澠B.^>HEws>RŬ!4?{#-id8.WfR#{;`D.2qmsi0rM e _ror5|^m5y=QN ўL2OڿV4xȵ,yqT *uЬ ъm*p!3߬ھ2?XWY@.xHo)x(CVh%1.JD@%'!iVĢĵb&*4ŰDՔh$Gk\ *%F6zҽ=x"0;Fu~뒾#Q!m #=N wkje1'nu8;{(3DK3e(WneܟIby^~ޚqt3a5=}hB}b#_[kotKB[,W7luWo j?}_<>QU՞o?t~Hv[fH6|UK#-]tg-v Uc#ZbxȑM_|ן1vwޗ^~dy6٧a߹2tFG_4&աܢ^]H7J|7I~)lZEƬJ1UGtM3b[7[[>`l#OS0 hL45Ÿl_ UJgSO-T'+K鐩?"1n r#q5,."LiEC<"UC>!h`PJY`iŲ@2K%ZXt,suH`b5@\3*I0 Մ3N5!%"'#=nJ/'z0V&x~2ma9m }~ƦhN5ӳj82߅0L=bAf'{7vCDΎ?o3=)}n=Ф5 Ɋa|`v6YڎƽqKw1uF%64Oot kdϟ_=jZI8'&D!-Z6-@V i`Ǫ&5ezA:\8qJ/={`p|˵Ed>y$Ō վPd걱)fvs>qBӎj)9-wb dF(J a?w2XN?3ҷxC*@&KOTԗ_]tUW8ǛXֿ2B\.|i3ӹSN+9ܾsYO 7ImsL%m9, Y48ѳ*p ,a6xRBQHqW"\H- Xj9f[VGLEC`RJ})*T"HB-C6-#v†]_x7N<>H ngcE>B{AFxhhcuTģi4zӡRɔ.i@u=QA*dRX,TTw$|XkK{Fy׀}+ ->z˚M{xoyiвY\ }jE9E J%d$+T֠k3\{&scgorU6~jo}"oXUp5=[oZ4.o=];I5tNJ<98XtY3'ڑ[|t~ZU1zR@#lA{Rb*)vRZ\rj+{{4^ydؿGF?d*ANJްAղx< vCr|є Cva8e}^S K/~_^kZjR04 ɳw@/_vd~/wfd-} 8Vh\oZ +٦ƨ_ 4 P( 1H5 rnH[7 nJ8JAYYCsa?|>WԿ]یp1\A(SS_{QNAN?b\ 2uFf/Rg_ĤuwÒ%O.K)JC2Xw[;A.IuzKށ z[/a]/9Tg[w߆BG"s@:JAn@"Z{ , % ! A#E˓|V?mvS#5ᚳ؉} Ÿ^N P.JIJu0!K@iP CTC%z 21d#e^SG~WkI&& As2=Є*9jJ/:QO݃p?v~kL w׼Ӣ*:6+:,Ħ_k߷s'7^/I~޹7 Klq:eSIñY\l `*Auz/CύW'?.:R;w;JOfjkJL 9cw/a+SWqL-./Krx̲y?Y`٠GI)}u[vZ@#m(R;JLJա?0Ffs5BCNm FJ;0tfj q7@Ҝ( R]]Fhhi<$+!Ȩ'#kH1a !1#Ym^@Q@g 5> @0k81X$8`.@iFF = ђ 9|gl4*ծv7 Yd%͌ 0kkZ<֔5<#([T蔟{֡=[Ws*+-"a62ڵJ?j O5_}%=:qBnRh{p8eyr rҙǧk2na6𴋪_~31 Oظ5k|ca 镇|g?~~P&.fWyTg_+:O?d1][=Xu#^ vLH24 w1y{qszRy,c Д؍> v@nNg^-wc;R2;qIEʼn'h MchDxPZC RfUpD&\2m+Z#0`yL3ng%*4mIPE9L aMpAyu(I`na xb\S-!Zե0gaBW͘BsBKcPp)qcJ;}5N^rbW$VrQikV钬1; s{ar`l^*!'z|MzYx5ޯաlS>e[tQ @ōz.,e>+W{wsg~,eiwGOXzvvAӶwN}(}WJ}S0fx}'w``vvErn#ޏ>n5(-g)n;G_?~d#*_DT4gTmrϽ> ui_v_8堸{wXއWҕ{8 z#*6`Sf, wR.i:wV-uRfT>޽!;qh!dE:ȩ4¢("Fsec( -p0;y):9XSV 3eFea,Hb &pTq2yXA&nJ].[1zRc0,8Y>fA8T[iYZ /7 lz}~`hhuˠ fnflecoyx-O}t( L2"1h:0̡J/{nakV -5d+Uw .ѷ3>y1L`%ZTPe{]#S;D++ԚG//U =sqܣ wǶR)xSO9C?0gu9-Dpknb"'kUGw쵕Vы|/-u ւeH :5 [VuYzLQc<6l}88 #V F3bQ T7f銆%}B@VlA$=hnoA?J;RRa[Dۯz&τcko%313&}eW>5]q ɗWY+ %= o]UB)s}暾$lr$ήyߌ7;!gp?W `s?>'`s9Iю:Ǐ:2 6 , "Wf+a5qcfZ&6W[,Utޤ3( wh CMlT"q:F^ǴeSX/ޚNWqKB֏ ?(Ɂx$o| < Obs& `5K,Ѹkd!N&%E,)fHR6)H!4aI+ayX2/(8dPa %HLV 0J[UgnVZ?GJ=onp;GPyGb6-J4DR/Se5KƵYB,]voj.^EFEhlCŝfN~+g _=8=}y:lboMq!ȗSݫRU7:DCu8;vg@hom% @# ZFB*\gR$^#VtX)eK0l;T1yI6Hbmgo: !/TF*[}X+͔f77B 9~),p+QT8 _zF r2:Lsu';N߲]HjvJ41as)jܮzy"əy{cGFILj~akEf "[0;?~'uyPWIkE(=4?-/EQw=N+~7Y/p# w\|r+■T ےfRG"feZcQϺ#;7A!)DY @&AYM(B>&ߺ'pO'y=[evB@z[ڽ 9՘3nm^xM}ĿdENIqa%~Bl͖Bd\4H {ڠz`e Ŧ`:B6 W9MMYE ئ(oPãؼR߶;[FǍ_`Q.[Icۍn$gUƐᩰg]HaiUS`h9~\OfQov >=]ᖩ:/ kcIO7c" n6CG@0f n귟åZҨ/T<\j攛8[~/:$2,4M9/N SW}@P-o;O17WQ߂HLy9xq=gs=޻K+3dѧ#t{pk=WZiɋԤ27fNSh0ۦ҅;yb@|,KN`P!&͵,?29 GG?q`ɶe%!Ӥ+zޓӮ3H {7{&=p껸=U_ ;+_ͦ!룶 ,Cj,MYf&jt"Ԁiʻ,7KgG7'^̗|]DB܌Y,JcSM Kv1¥:6FH'O3fI=: KaV`=)uMn(&A mq  Vk ʄT=cnOkpP+V0D$H- Iػ4[˒o޷6^gJud|eO¤HC#,%QJr]3p u,d.3n:V[N̸E#ܺ8_ CT GUov_E#A,61O.磒2YlzcO=.^~i^r5-N`~x/!g7n5yݧXὭpf3kEM EAz!1irBc^U΃ ~-˺֥ݹ`:w:ogo)V|HlaHG:_r© OwLŲC;(D 3خbhR Sc!2>xGe4~8 ]µAo C!-#zTɣQs`-W@Ϝ>7+q4&RB`cWzO#Ha#vȾ=vɼv^߹e 4~f9VeP<1:`W/YuQr4i9HCSb,YRNq)\Q0%$ zp7,Ȳ)m)sT,~ѡA)a}߾B6KaZM)FDsjߜ5/컯c/ssKܘ)G%,6~){;Ҳl!%R3|}iY>?@?e96YV3KV]+}apQ% V#D&%E+J4Rػ]Js-#T&@YS=22llF* RE#WdקsomV}IēCh,:ۃT NgVZԊ2; [GaC^:föR3|1 7/g.ҚhL۫^](noHYK{wc~I4C[2iǵnuxX) ї:YҸvc'|dN^nUdr9xyl nޖ!M} 5]uknt}+[|*QTLz,p~;n%Le"G@ʞb씂rAXfvՄgo.REQ)d+R L*i$!v1'{As""kpCĐUh- W J|+YpmXDk)ٰb&w4ą݌D%}/Bѹ|nvbɫs3C $a4XY&v7?CÏ=n^xvxsǟ95ˌ|E~%ƒˁʯ~ ի?ŸǾuK:@3~dOfW:QG7;L7$ YX,)${fddr'ud0775M[Cj)Z͊YXC7~6sG>x/%؍Mw;Ư':B85ab jjAѲ5uJy Pd+xGGd7Jp wfu L ;tڰ 8>Cbk]8s4GksN(=pXSOEjX+d^Th7+EV%Fr0o mq< ǚE7 n*qh@ Y=VV>:c0D *"Бh iO<†Pv;ߺ7@*'t8v;fǭ:XڷV#܀ѢLqv9Srh+L fp6eUP޻K8 $(2k30!:hqf@nN#gg^]֋)\uy gvBI9e[ƒOA'P8|z/7MWrO~2KRo߯Mwy=asr(_vWNE!GvlE3{ldo[lӡ3ֹ}ߴ]Xggͯj]l&lKĪ6=Gb0YPnjJ}w[lla E"S%"#yO{'vofagF5XNd<1b?3=@%;L#lSp Y;uY2;Y{GiU{}]ކp P.f#5}Z6!:1p9ƒrԅXADw])!u8Z .jdc9P): |+ss:qy>jW|.L:387K`[rKh/L2V4Հ@28j '`;sRsD)ikZ)O-$zaU?/g<ٸp Z\! 7gFƮo9IDATfmYѓb'GQDD3%zOae{a@x1_{$_^v|I#YKI=[}Yƽӟ ʷ7UwO@sa {ǚ Ms=RKڎ-ނ$/M{M8a_; ^X1@&@\(I+?ر'xic'ۨN~Root3s" Tgnl:8>à TdcJ{a`4}]Re$IݰC "I-:ޏO/zm=+$;yЖ͹8.O&)/+] E׸ćXB-@ϪhRZR*'QSr.DGPћ K" (&X@p'! 4HPƼ<&qzi g$U4+ Pc-ڮxChJ]쳓hҏ} |׃smu$1r徆x;RB>s*ZLk[O/)\ {-tVVjl3L۷H^]BU=5J~HkX]},Z'Nn:zv[uŀ |S6O޾Xt2 #K6):k{\lほdLZCyR`pc4ܶǎg3c.[`Z%l wЄH0|{48ma36~(.S3 #a}p/iǬ,*BA9Psj"&eK?) 9%HՋ Ӻ)갨f̂ e4e~_'Ԟ4A2uHq<8:5%o94/S>J=@-0?lX-8öl7?ݟhptѹnrӊ<~MsIs~&-TΨ[RĔ_{aoͥUK]x$-PTF'+o ?a.]p_pM>;G޷ޠáI>ɗv:E77X±b͵W<͸Lx!x ~݇luMZlmծ.!wMrI5J}VTyӃƽ+ g KA Es`^[5#G؏[7K7&͵Y@OiN]߱%=аZjIf zef#)AmwAyvQ>F'l.A"s[~9u0lX?<(O\19{}3ͤc]8B!g@Hà"b(1=y%.<^Ne$mLR-tDZ+J87(=TH{)kea|_3T6G@MX>uɐFCXLuJs<΃N[W错J\YXvq\xj+镁0IYZ\% -KeQ{ B:͇Mb]I}AETqvrأ^p߲znѽⒷsS}~(̞ȔŸ 睱fB1֯ ʖo$|p/ ̱Dj;u鑓呀|+S3Z .um}|yMy*ʘ=T{@|GnP)+ <7q k?Y[RI{ʬq-`,B@Dˠgώ Y,mKRxVĹ {VhH܄qXrR hGLq)a6"Sc9>i2{17PU5D;Mh1g+.]abdǀ7*QeS-+=1N'Zxŷ$-s,HΌaks,D{U6܇`@l{Sn9V$  $:#Vnq ԀE`Zˀ;~g`("&,Ҁs|gW9C8fKFq iP~ I=/tݵvzݠjU+w2D)絃лk>£;4ﭔ޾F O9{{.ȏ>2 Nw-M yϘr{7CmxIg\!P=V%7ר9x: 4ӻӰsy7+b v~eg*-<Ϸ M׮ea5!$h%gbtIlpF~# PUSs>VBQH[D\A d?3&3 +Jc#ms:~VJ8>J~&~r]-GfAQ`P9 Yyf3)ᔬG}GJr>O~S%UFw.wM;1Z>w>߼loV2u ۜ~=vI?x&+`]Ӆ+3V<6^8]N؈1/tf6?\gW>=/W_aei0%AN/&".JH9uBt;gbcՙËRj@(D(x!`ۼɑiE,}(=-!vaXK:tSDc2>\Nl%HS%̱BJ1I Ia'[:o2p w|ȸ&HĒ d0}89s#û$.ʝ쓽Lvqhbr܎-ra)Z&C 1G،G_fR 6B1tdÿuYv$ml^nuE\]bp\Ӂxg0ڈ؏=d[=PIYU΅"maИ7V*ss Uc8@{ ["TG۽wz| 7!20B9SSD*նFFĻJL9Ѱ2gBjcf[6{~~+]Id]:M||=:JNm7;]MgM>rpfWdo)#%єZS 4U3G }ңN ( 7dBk Oc~'HMpf5a & ǘ[5 qsU3>TD,5X&)A|j! t2jSKysNC/hhjd.o.^lr֨4 |;@\K Onu*n|IE=§:f6^ڼۖ^7Tc\3۷\'5`&HLI@'(j\nxZ.aJX(=GW.*72O{,Թ#ܷh> rQ]ܛI-5ºdjlq=z`Zr87<ӓ2N.7("kj ւg1t\>y>l%fv4:_8>{s\ތ1iw=1>yBSjL Dsa;nm&7"Et3w;-;4 ϳ,7^`ɯ;m$ {D ZFJbj^/I%\:?]|pwkP{P'E 2F39GXqVL'm{swmЈ %^b YV^`8`edPGϾ"FG֠ߥ5νFuQ><<`]K{L= 5;T3.T(< |fhno*]JG|1[Pp^E{y~b8e?řNe4GB\- `UhV(w;c5ZρDXi(q u ` F)jDsS_ cز%is#d̔"&2T݌Yk3;>¹-{{m !*]㕴 h!j_3tUhI{)QFbЇzenNg)R+vٴbD?/oo`*߆I Zkdq`J\Jƚ|V-M0tP[5uk -ڌjQ%_ 4Id-(I)aX;WT dF{R>urVٛ>ܽQ4b%9{ 3܈ZWc!$aL0AhBleTk-L9C3">?iC EbSK8(BhML1Ҷ "@}WIY&v|?SA! #cõA#Iv}I5eR0Dsh(٢$嚤&nw?}{yA mϯwg{K{ww? &棕sye{mH3+Y B4Yndyګ[N.u6웬;1ro6r0YHaY/K<;۞VQoPseB gFau k7s;E]a'ewv_V A+9(dLBP99{C%`ٳi+\juO F(XYG|RM[ɓ$z؀VXݨ@]WWq:uXU:/dcc1ezd`͓AZefRj5#fъ':]=wZQyC0y $T.6{9EHVg[8*|c wQQ=U1T;۰rA朄ڐ*Z C\dg] 'PGszX# (|NnwL(q njeςLa7d>C/7)E#,u-C4;T`2 sMD +PJxN 󵖮 ) /uy%sυLX_^s٥|#6Mʌ6c `PjF B@ACtwN Mh(pb;vLY gSPc:fh;HrIm<َj4N;v8}ϛ}5>̃MDRxπV1R\0f{ (M2jd#'L\u $xO.y9uL?VP-.T ڹR">BV3DcSle=c2kOV% c(`y{|Bf#reY*RF LLOr]І( GtAYkAdȺ8 )|?Ԫ΀EƖ׷Z,v[̝jAH0[g.B0T5H h(ZAk@NGg9@ e` pYRєhQ4#I)/p> o wʍufAI;F !6jA cH;4fԑg SO73HK"hjgAW YbZIV[pL;Zs#L-z.{XVwe̼es:Qܴ+gx82VPf}u9t$ -@[&^@OmtЁ[5WW_ euwa0K=ڡ!ObI G ;4@)"K Ы7y .fdA[Jh4PV!ert>G;T/;; NX AdSu+m6oWCʵlaI`s(pI-\TP@ 0 qN2|^ \)j *2TBj CRjdʘ.\k0 dT%Zyxr?<8ʋշzJ _8' dnj >f^SoZ;,ꛝ,4&,! /46>Z56.ζ_[pa ke.8R) h ClX*жgG'yt(s,MIAZ1u9ɸt~Sὸ!=uN9X-69ڷjtFC Ɖ-JBnzۗ/}i2V֛}@xp4evz,2a Yf Ezq='Z=[&RHPhSԒsf2D[\0 #Pyf-x 0p280z:6~jwsu+/N81;RC3{kaMP6Udp`Lx_y!88hmu5pPssdx'3[̖t8 3"TĬQq7(8v:/ѼFhKC "}&tzK+Ykbiz)^TQn{Cjc ,jdC@ 99BL5 uZ:a 0P$bK5,YXTGGVO-jT=Qːj!!)G˹M'~ĭxݣq? c6A+(s4!JK=nQ3nm[U+'J}~O\Gs rcW?ux]:~mgڥpf%szȒ/<>aN E7A[3AaKN$ ÂF0ʴQZ%F5"X4h !`]N$yD#SX}9a~G#c- &a[fսbzsNa'mAMhNEM??ï ePD!:9'j7n&P#0J gFQg41 tzLFVP5z}sHΛBnk %Ģ(.r[O~qkGj6ӬFt]ћwFS­` {gqtlJ:W.Ҧ`efĔ)Nj7Yqlҽ!ҕeɱ{HL6DTSrK ZFܘDQI%wyAܙٍxtDέA0kR1S9E4Uc[3gjAE|MMϝan F 9Z$(915A:Rϣys޸,6Ю' enrgΤVXR=e{xqOr`=A#*k2@Q0wwNb‡{Qi&[L'񗞗efߺ.mܑhcf6h5؞oT -?v5xp2@-~uegۛC0@2KZŁ] XS@Fl8k]"WR $#sP[ݵwOSݰh~W_Gb܍71=3؇oLDКQO u*cĶuTG'E"PpS1ef.Z(X([[Ebk*UʎeQ񣆫1IVՆܗuב@JiPmOiVR9B^xvqI[>tcQqYzDcY|>2O~Y=iP'kP,_t~f (rN ԉv #"]H;;ރ~h*`c~drgȑYhǹ O(1"%# qp03=`N!&` BP 5tC`zI {$Ǧ%%f=-oި39]썄A.XJ>Me6:%x7ޞß1'f2#@8H {jV(ћ͞`! :x/ͪTI|m AROO0{S=UZdTÖoApDci u[7E#AH  h) @EB(FH& A rjC.2 [6j3nK"a@?kg^ѝ>[ps9Yd=e-CB5eVUvsc~j|{ {gmq:׌0 r'6ԑ/LlM0lf;0TmlOͬƄ\ (׽7GGBjݬ̮w2a"NI>fYxC譛g-n(ONM@uhۂLj*Ԁ%!: DkuBmxv$Âs1uSn^*[jjמ}G'&@;%'ǹ[$UnaWo3崛&F O~E3A1I&7&/3kvNj?::[ϳԷ}'BHxIg&xW珃0'w)@Fd Ж0` gpx@>ؚZ ,<fSC7A 2!`4`APc0cݱ6={[eM`k(V8A΅IOтOT1Yw*CWJ[!11F,Fܝ8>4|Y@Jfo8.55j"Fkt͈e lp%sk68:~%$*t?@]Ks .`!}ʍurV\O˛|.GH,3CG \=}ΛQo2 xp],+pQ=$o2.3!4P@Z[efe:EOnlkܵ0o'4J`k.kQ&_r;x;E5ZMyb c~j uVNEIZ({H6TVc0_x?҈ZQ^޺]*׽R!7gJ(T\`.w%et³IJ?ȅ2[~ =~p3'9B`xr;|1qx&蹄\a`R -Lp m05LM 0j̱bG$댿h*ϗÄ^~>}:X{#* :L P7<2ߛ07?nj-x $sd_|:|tlpcּBw79o1! rj(8!Ln!H9>8@vld*sb K +UhéYLQۖ~`C^ (2#w1u)}\m z H 3e(@D+8# |!V XC rPCX=]T+| ,VSHƸLJ0t zN"hCaT.s54~ID,q )HzCx5!/[>= 2rE y^S90iʙ_zaX9P@Pș d w=>y1;c,˒jZ$M6&H$ (*'gϻ9߷(Gf cSQ$eS$:cyl;W2lU8Z4bk L%2Rf -{ l{ !2C:6C$~g.o݌\,ldP=7ylڝEi2g{ T@m%Wwc/e*%),Fu*VSz/Ev]jVicKMT\Z3WMs}‡2%BȚ >#H P^Ogs]u]]ŅtW!0QYUռ!@ݿPtiPie C'n+uQ@ցjL5=5kZ:kYGpg &c]3iz oStM2P\+bS˵Mեnn^.ݪb{,y'*vw,FmYҙF AnA;\ðLXzQ}oό'@8+a/uۜ̎n=epȌPր Z8K0/#h'ŠXipJ܂0GzcA){$㋛Ww-W0l yQzYrIuIsphҪt8hDahņHG>d=+,+^7u w6@Nma8f17k/`գ5zv5A[kEY'h5P.Wf{`@|(nKA$(||SLYVe@S ;h"B˰., v`ˆC,9*Cn^=|˥0yW7FHFc% cq_*M:s`kaa\"a(f 9ID`*hva8_Aj$pcUTfW/:]kBvi:7/tqOBf쇚ֶfևk(g#LX%Sc~9|qk}=m".+]6~_<"-Awꖨ{*VwU,|i~aaIU5ŻJlkAwoYRaLPȋt$\ %aVG\Pe]\N["=l 4!5MB!&~E۵Zc:Oإ)]DdDQt@ 2%m9Va~8v-z $7@sL C1{ā;sR^n0EBH.0lpߠLOLS$#2bt;.޴84B9^,-~nq'0>]R*"mXrdm_=a/k^E079՚ĒD{҃+$ JR'= G HNj4Q*JklGS[ݾU"hsygҔ *3pwӤ *Ic&o N ֬ŰE5кb~ *晢<%! L.2\S]aQjN<&0(s(P ov}HjG~ 9glm]9{.u)CP!297QӵFdQwhFiE6ujjHmv=U.+$sjD,8h |a}9@czF< ]ĄDMLVE o0ZˢNv9?B޸ַ18Eׁh_?f)\P{ 8Z+}JFd2--㖉SW  +nbD0UT& Vϯ*)ֱq֣Txy[bT8G5X'ڍ_;tgD߯Kk{bPcV`{N[UJ q]ļHI״s uπ}{ ?G:)=Ut݈p4 ҶxĖ r̊C\) aMA*6)2yҭJts3pMP1]i^aNMY& v߯[) amp2w$=\pE+a\cm<i_Сt}|:n|hs *۸69c53OͿLvtQM ʀjHXm$1NFmlj&@ZK-֘\0szTE/ "w}mP߽d׶0B(%C@ ֐$ Ԭk.?;`#ZuXt NB5b|_Sqr,hUQJI5^&kV pU F!U wcw MK7Ǧ>yTuLvm-w%q@,w;'6^K34UնZ z"0WAv贱LtNψ{_sf莅7/-+&f[w}(,!98wZqe#80<CEZb8鿰h8n+_W8mAG'Vy+?*k{8s.>;Q4Z4y^ܐY@4>x-=Pd@#dY*mAkEfqψU%/o "G[q@^6G`DIl'=[㕐-=:/6-m}1F*5п]_okĀ = ;BI nitz^mʤү堉zq=\Vɬő?Zj%߄v'PNG *h=2À uYOJEyb]~a`d`unp6d;5-7›K@&De_~m]kmObPZ`{9DE?&IW̒dfa a}ՀŅ==z}[mn˃c~"{\0$o|t蚯{@C񦴚ҷ>2s\u/#-A)xq}ʕ\Vi/CMoLZl[Cq=;ڰ9c7&N]^T`kBӨXձ:X 98=^5+|4d*a1#E v mnI M(Y ۭ̀ klu1in*ӏm93Z+ /__k62 $T#-zpͫ5o$yE%'zL# P@,$&L>U<&ŏqjtl?HVJ/_kM7oRȌd#TEȼ[\Ab))Ix% h'v|8\Xc_PYwsKߟO yahl|M?|odecS߾KGQ[LACл 2ʋ5ا*tR/fg \fajt;hT|]dAYg)sys{b?' wC|[sX}<$)F݄ :tØ{RB?٠a;c.܍t=K_ۻw avW &?C{3K"}͑x K9XC 5lF 2GN`;E=^+=Tb!YPBPow>^z|uͥU8Pl5͓"Qϊ\eC[1(W>sLCt`gxXɦ8r- ; m( o\Mv;Hd#n RTFGe&/'e,+ZaDh1$X)atUH mk7SZN@YȐQ̰X_1el@;=CzeŖҹOFj**Bz (C'C7n6" x(!Uʈwӱk}GE‹@q1(- Gܫ缿zr+oCm|PR{vVl=&m.43#*lPoT{VfHX=uIkK DyRT~]U CJ %eX;Ȑʸ J=Jtfbybl:֨` ҨfHQ@T:PJGW"~gY ΕTH&/6EYr b3 #@T`6AF]6:8틲 CR$r2tӲACM$swcżw[]>}Xt a\4#qE<(vsdkrm3̫iHQ>W-e:i<Kč"oVwuw͕0$6TN{q9Ȍxڐx߾f9آfv~-\aiɇ#䀰c cݣ^9dI@ QA Oz~)uQOioo_W7?}]AJN [: V!B}w̅+荫7F3-|F.<ΐJX[.|j7Vmxrne϶B{:yZ#F_Q9(R?<{6}-~"'Y|_]7:L`ǐg;dp޼RwƲKY!Œ޻9uvg[n bOUzi|J6?wo ~7sxmlHa,tbCR)jk2ǀ'KG˜ (R~AwƬa 2Xq5IAE xF HtciF)l*LFj&# ,)kK#˲c! FpI[j'ERm: ʰ1A4x# haر/_aΈ#,_7C]eܒ2DDws -1_}vZW0pR%k~9Q(q!3s,̯x/= GreMSFM Np6$W[RPR{ҔP`J;"#>/;qzF=N2ڄttQUڵqyJ u~+EQR@5/<σΔslߴz ^pmpZg7W6Lj>ϲ^h4 H R' Iݛ{&}{Va.u.;xf{+ *k53\[G\^%s2_bKkA6l'?ƃ"փ{U4L!Ue9'W.* 29L.&(έTףۉX;R<Q&;Z4RіaGe_n\i$*;}o#[jדgёM 59Ǯg8*-d0:_f:Y* 3ca@E_nfX*9W 0.EK_|9G,0@#kD: K78OG 2a[WÅcK {<; ej9b JZ!lg3k%Lae[2)-J~"nԸ]LŅ'ߩ{x_ AeJK.:D 0U%YAe+g_;No| n:uƱ7%9D>5 Jz_~8nl߿4((GGO+p S(ޮr]rXJYsARZhI);N{^Lc>4luurݏi*s|vmsIUz=o㽑WRNâ(|+%$31l vy@BOYHKjU#wzo|r*L b! &d@i=.ϱ'K^K?ZjcúlYaG'|˦> 4׮ dq܋z9T:Uv%+L;h+TSvSӟO?R&ERK*TJdFaM|K{I>ZYLY@kk"D0[z؉*2֌r-m;*d_Fd#7]Ȉ0;bl>Gk{Jծp=;Pa+~iNw᪔f@Ȕ<(Ν‰ 'o ʰXcO+VF#AHɿUiX\;&QՍtf?dFڵ",i]LAUmfc; l9'jwzH6:9y˪9,J5!>nT{zԐ<3 ?'c=owb9A#N+L~䠧*,mt ͙y&jF}@MPN%͔N G*]' Wh`0`Pl6z$^C||wJC RcTDޠ`k"H#c(2֨:t$C5֖n|;'M#S%(A`U\|Kn~*=Xș7ؔ]LFp(4!xʫ_P +L#T(pqݐ/Nb''ñ+RjSF0<,V(u: Al֪{ cC)yGI?+slw\]~'ﲪZ$o_ 8-H 6Tr,G6s`,s|i^ J,*;'ÙJf73'|*{Wۣcjݒ|I!n!#SzGUnVj NNZOG˨b{i/ 3ꁗϿ/gRD-ו1WyuCu]:@X)U)#];cdie -Y|BrdH;"&P&Hu2\eL 3/< <85?QiMB# 88e[tfBp~G| )L?VD6!UO%a_wJЌ^i8#ecxMpRمj-z.&e ?gJ;]P əYqH) (scZvw?y|ߨn0Vvn'[i{AKNDALE/?[ĄzdXuc5 MɱFdsmyj2= Zxtũk%b/G1Vg+ {݅#"b͌w(g,8rÇzf(!R}?Gwu]h$-Mk+I7[Tn.z.XT7A|]@m%Q|mhƯ_{.~n:oȅΎov{jfǃMZ'fј8ta.7C:3_ Ț]Eʡ/7Hyj)26uF&!R HDCWVVYw~$H*Aaa8X4VpRc8AD ˿X߽:rfB<2;=XAM#M% kak۰g\qͿ ]䠬CX{̕5-W}ٛG]Iy6J~gD!;΅zl0\)rԓU--"C|_whEi[qWc~,%qwBiAOtSwyQQ3DS8Lg>~0^~|ud֥Z[9ŧ+|xxȄ=6ƞ:o.\:?&3E\x xϙuO>ȶP}ueYoi])ɑ~\F^v1c~9(7 O SOCb>ӻ:CqSē =bz/?%= E۞ݩ$SMcCj{wWK1/W}f Ls?|G|MNToo[/7/zn_+ߧ|~û+q&ӲvYlbʡ *Ф˸4!Yh)0U_-o-u։*9M(1C P7%`sԆE$Ƌ<>SԍW.EF8ӓ zyQ;]H!zOX,zt~( LZenZ]|NIgN.u./{b/l/Jŭ+uǧP)[7]dv R =շ\{@W ؕ8׃e 5ן"C 6aH7`Vr+t1&JடS<>q يaϲXBA-̩sXn[G0U! ?0cq;u[ ]Y&7t.LGutsǺwaD<<9/]W@Fļ97^,ӻz>..>p851!^A-]Y>^Lw8;}` lWareT쏮$8PpN8Kƿ'ctGTqw;P:5 $+*7,Ae{W+v4 :whR#R鴳$:>n儡M0)@sT)WQP,$<9-d# dm,!38%MP}7)=lI Cd"hwBi跿R*5󖸳%S%ݮd['xe:=i5}pK^΁#{¸>}eMߐRHK^cam٪G{#k7h2ĔBl|D6S|9猪J_=L SfzPHڋęL{ 4 6Q[qa=),]dKY&0Hc9Oea 7 bpIu\d䆔u'O޶gG.N$I0/'=0>FFZ(z/ZYӓկo[[ݜM/t޽&{o]}!<~TWZ\OS{YfQ[zǿ㉭rlďyU+\dbMҐ1s~,ajl[(9f30~k"Ln5gMn;//88z\J=%28_X7ԀQn=q@8PGNǻwc+nb}}"M*~d|AQU0]Bi 8Gu=:%U]Nx7 x%EE>.dJ9lj#LvHP2o=7L ˶2΢L錛:d=2zL46Z /3[{3y,9ҟ%$~Q5'Z/Wt='i$Wiv= )w\?(]ر?ۄwDݒͫDH1ԕi|0<ĉ\uVkIm J@=l}?,iMj,!8{c}S]^22rc`pu.!B3Fu U= ޵ =J#}&"~hG SKKXnkX^Hak~gEd(u u/t_t9ʺΠ=b:r(PE(-Χ&ݑSh=0A 냰vo>t=gHݔqQ;М].u$Cf]q8K uљ\w11(9H}(11C԰Byu/1UލȷEk{,wŖ _:oZ}xd KjAŻtB<[}` ;Bm ճs5%scDnC=<^^E296[+֟8)%݀x_}t[kC&`VDUO +)_{bxrGߜwLou\S9<؞X df`WtyPb(O' jHƒ xtS4tW˟#OO̬rV cl^9 ZJV. ~"=O۹5=`L8ʔK b"?O7tY뀑HdK iVہUsr3d+".)0$[֊X7<ُg%;9X.] *,›!QʰǦϚ Qqx@wñ'7xrXM:} @HЌ#1ؓ [YNY!u5ڟ:ʠz/q OQmN@P Ȯ]*?>f[~CMtڋ ޾ipoJtf.[ H8Z<{rtvcZ`}/N޻ҋ|xp 7UJ<;OJ{^)S͌w5gGw*7δe; @'`;r^8246^Ij\H3ֳYjMa}kH?6 :3`X;`@Dļ"^OB<)iIY /CN~,A|v#; >xlƿ<˕GVZduH3+5+by"~X _Bm|k@Rob^¼=/S9FjyuRS! /xvKȰ$xĊ" ?L$\$[7hX8LgJdW!Waܵ\Ajď̠jڔԍth9DVOaWaMFla, 5(Ikaf.+~ akuƂ:BHy`}Q[QmxYq=;n \RUuw?O i.;şugvI@d0p_z/9튈qA'OT?4qيD?z6jg9:(e(P[Xբʨt}{~7U ?įV /V4O.ʿuλF_yUͶMI'|-#ljR>Dkϳ_P #JA]HPR q;JxP\Us? OZ qC]grC|n Yɂ6{>&Gp`:_HIV*8 ,]]LZ4- 2X^r7x]SR E4 AloF!IwgFTVcJ:zZq{0մkd#(:ԁޤa7(*j_~G}+o;mZ9JEۤJȹUZCL =.FO!хP]E][Q#O#ͩ:Lf xUYvDiRPff{:~~x˓'}`nlxgk?~MR_ݮ rkufn#On%",CG2ӥ=Z&Jqa`pì\'?/K+WtSk/-^ӢdG|̿}> Z嗊-[ZX' 22ռAMkAob Z8S檚lSR/>%ºs= ߄˜5BFF)$\vds1g=.W>z! ( @U0 KEn۳1]ߪTyE 9e4jeCh#)|-iʎJeqXL.8Y&ȵs^WgxE[y8kE$K%4Hcm=XIظ0p3T=ン:X܄XK0chsG;^7KXJZ31:3S_ }}A?K!TBtD>V¹"YTqbOrEX>v6;ޅbuO"Tso qrݕ`yo66I#uܑzm3T$+=y,͖M?X ċSG-5mCڝCy˅>mXz}#u||Zʯ?Μg6+i(c#+ﯟtvO=Â9RG (phZ 2J0*2i BD(&ht= [5zY!Ozȸ9&TA$BMٳj,3BMq9 w;.֘=^tr[Ub"+dg_lq \jؚ1}1q9T0Ő+HŖe?CO#׾>vr?Ymd6] GP$AQ]WVMEę0?2 S61z릦LM½%h-F Sv Z?l뜺tې4C:a=+˓F@Mq`ܚ7= b(Ɂ[治:˃[vmO_S:@$NOʃfuM'wsE)-U&^y)̶666{'7>qXqNJ?vTn:y(T~^֡5λÃKYoCye(~:փtg<0>zQgxzd1m* s@W!I M})cjL-v! @/ ^fwm)lavbʃczf]UEk.#'UcL;8X 3 T0y NwDc?n6I &9Ns^o}nqڳsUdp Ӥi}4Z)VMWGV V520)*zIe0 =m( t_ VWly0XMV[bMڙ!'5n[;QR#G ̓5rqQ5ϝK˜)c^#XgLxYRE`pcSK+QIzv[g7lBkJGW߄wg=6eUwӃCJ-mWg}Ul^)EOB-nw~0Aɮ1?敼e@[!@-aj nGw/{;[+@Cg_Fl7_\>fp_{ Mg{Wyg>#d֍bVh"ˆv ]tJ@d}pKଡ_4V)oj=h ;v+qyjSZJ:y4iH?ooő(QkyrIC^^SV;dQ緶=l{N*8 UPB!Hiʹ@P.^HT w#\<|-OFg'OѺ2lb.4I]8h+P<Ԃ2 DzHAlBu~=.]-32=e8{f`t>ȯ?d)~ZT?~p~`=5~nh&p L^P;3e`q  Ŋc˧jk~ \.*pnہm|f.Fą]4<̺ZJy bs;βWPƭvhP LVЩsŁbEΙ9!SA.K {<Gv%i8 mg2=,%9Lj;ᖕIG%vXLG9BR 1m|֭=Aкԗ(vU2nCzR){iwO<xq1ʲfW҃#lz7>OÖa_.W#A3O5N2U%.{-X̏|W7K?Rpi;3=^3q)o\kj⯿;ʆ w{x>lbJY50n8o0?bw!9m]*š.@fvl\Ꙉx  GN]x2ɐ{725F4@Qo,5%ηHRљQRgώ'r3enUmI,+j1%)QDdc[v,ss.a Bhh-{ f{L߼cfD*)JcNCRVILnaj DLqfV[˜~SheacTaOIe-I1NmbĊct0#pOx/R-kn`5<\[tm5Tkp$RW ́wE,N;?#myu!?y]}uL@7[Ybغac1úw{Tc6ɷΨ">̢J@uvN{46Fx|5eAYF2^0g7pg#8Gz\o #d;ƊhHo򆇓Q!7XEV#%p[KEtb2DX{ov76GF\*UƲ1&5z;1WYPv-F;̌<]R\*!Du;[[/EGSj.wq u=P)Xnx$~d nFL䟮diㅡM:/1<)I@!fl4vt38I þ-)Wr$ "zJyH[gMruU <ໍ>_A{7{o(vb?g=b!i8y} S1.10SG-l^ nvcv] ŒJcSkk^MzY E{rjCQܟr=Z~Y|GC$gAf$WZNu9g>n%$ eME>] NoI-jgiWv 2:b,Vha3C0w\kIW7d]#]׵F&U0ḪG]5<"8 F|4qKnt9S;Puv:jy9G@V}@gzg8=הͬ`F;8C~MP7}1Q@z8,bΨPZK|pك1 id=W_TʹTEJΦ_7}O䧏W>ֈ°"鯻ę$`=uCVy'Z~̽TLE`q<4E…9O.gĹPOCKK%%5"օKZʼn|xVcr,AٲI ]&fq/O7u{#Vzu7#U{ xňd Wqh5AW@ב_M}#.eȶ[;>6sWEמށy/̤@նzk[8l|U+xQ.Y\= }>ƽ&.#b4J=~P ?\XwB'˷vkC![SiO&^*4N[*t;A½o?^|r\sT U =pRu1;2.w2(7CI`Dig;l #W`W E_U'?#MQyUpI73st-S~d_zKml*sRX=^!LS̍ +.yFnmUUNN})9Sis4.?4iĕ4m`ld~"+:Jjw?-OOnVMs 6ŹcǽbY)==0 j&WI Q8~^E3lymxY\#߸ƏzQ" u IY\Ď3 d}spf :>{nYCb0}Q?*D}qM#,|R=EyZ/<ݎ$8wIC!g݉+6VÏHtaq?Kd.@pTҩpDHNQ<=x-wt\co Mk[R XܿljP֏ӹ^ %X5c ~z&^|~oЀŵ Jx}.AOSZ4n \}@P,Zn4gOc*:9BqC\1i)DƍM!zɡltUWPJWnUM(.[ۨSs`!t]mxjǞT݀S寜m~8 ;6w _x{۳guBDvRkEr>O.Owo\nq3kV ZuҘddHO8k#as̶V|qf%(uܨRQE:̑\l?:7~}T$u1;Ngď?IBv0/ZZkezTuF tX^@'Asu|` mMpr?⩮V P># 2v)haT+IQ1 P &ul&l.~_].[WsJ"tks8mM&Fo_8wHɛV+p0MmWwjsN>|O]=j|4L|Sk7撙[u6F6HJ| (2=2tMk=k3bOIǸDz̨mg)!c'1=][ 1iKga* wv*NWO;#frG9VUcZMYԱ8b^/5Ɔ g~o Ok_\i\)%9)N:(xDH`̺}#.RF4N8tYp0t.S>aH謠Im $]嬬 Ip&2:VESѝ͵H?~/{,kd~e`찙x60OvS]tH]GX6_ klJO~8ub`_^jCq4zkUL<H>SS  /u7^EKn#mHk.mܥ@d 0ܡx̎ V|zGq{6TItb+4'ZUdE[k`R20+M&4B>6s(<9/'F==A3A@uIj]4{v9ثttw4m+S [&َ@ cD )G@QGʡ+sݼ_^RLH [ztoR'mP"1Dv,(`= @(õxǦPAЪ0)V Ҏ}w96^TqJvHKau+W">x^>j<~s"I\E9$糦}t'sFшD HDJjfv7TmƮ-Wݵ=wVYL"O9Oӕbϫo}|vy'9}=ƒn{>ߡ}TtHs`[R LwET>Cm{mQf:Z+\nw (Z[uТk&9 GH?GA:눰#+lo03>tTj%юN"z5C^'դ ӟ _avVY7m*#IOwχk|Q#_)D{ oN$nuF-!?,uX '7o숾C#O!Yt%1Ax:!Ċ C(=|H%=b{#vb<4^o2{S `JEkZ۳n3'~;:.Vbx3n‚-30"*/п dҏWoAޝv{E-C-X4x`LsS`:$'MOUfǧ : H7GPh}uP-RX27  ӗZGɑ2c W?""8jb Rm~o~-tUacOFbWDxsƋԡ1Viu!;bD#AwAΈi )cY7_E4gG4 +3&]y[ĊĘ:65)Zku}Wp .!ǘg6 [Jm5] It[haq;y~ح~!O'E i_Z:w4Y>o66 7f{^O/h>4D!4t[ m !l-UB2y恴 #;D杺8PF\S 4&5( $-!:4 Wz_̭pWsu%ʼtm3W g:w7ʊ+[[;q.}>@MWda]!#h! .eؿe`/A|XAǚ0Af0T"ZQK)N-7z3EWCzw)'jL݇'Nk4q̻HE'IaJIsq$Kq}C)]`7Dե\;(Uֈ$|u#N]!^#-g?@P0HAFxL_|8vgR1yTygs;h͒BC-I \{ ^F[^oC6X YLcC1ڼ>gK]_Fv}Z\]%Xa zVw+y3 ֪³L~ *BLPB]F=_&-xT[we4`cM Sk Vt\e[s&%qN/=4h;d " ?;GܹnU-ksU{B]C̓y}Ia`s cm\= GWP)+۞ qPT"u71m0k'\~%@ys`QAts7,BUR )wpR:{rǥ%66י`cnR2hO;'M>{9}^X!zq& }nyNj]U~VqtId3;`{eI#+^ֵ^x ՀWa1[ptni׈tvݡ$H ;Sl"LxuQ(CVgg/V:OɍuxUמkv||˧Am(,pdӵS>R unS{YGǏ'َM(m=d#>efO.PamChKWg=FI mPC1iVܱTL{[:5{{ݾn5bme9W6Ը2+,~7g I#ɽ/7x^(>vJs{>zlxҟZiB|㦬%,řbfH-q?ߥ h?-(!+f~-'`gFK yPV :9W-r)ɉds J%MjRDީ9%ъ2h/CU^\N o\Du[k~XSѻ[ HnBbW)dK~[.,0MT]#w+{1fëj{|̻EP!'SJZBy XgEp-7Vaw,pnw3*ͩ Gډy3%}gԿ\_~},Tѹ/"$W^( ߫*.*N<]<(X!cqөĹj5;ŏBwYl$ z=䫟g$/ R2-8D 1W ( vn@lH)lSVoH(b)Lk|Q:A(qŖREJ$Tjo|I6<_?erPB'`P-67X.󫏖vfȩG*JMFPrUQWkfFXK+NA岯sF3Ƀ7ՇC,uRTaH,sl&@~Jѐow]pǪ^|M[nk];89l4LӥI-tfҞ'۟N?|V8ʏ4jykv882ը" ۽[.ЕT -ς>43>CՁ4ȕFo).Ҝ@ǐjG- v7}skYf~vҚP+y7Tr[ߡg>$u.uLBn"i? ~W?.zݡ-V8Fz VAzl"|R " bә_)kUL/SYkɁQkA+gkBj5 ;xjC|ظu`{{0K[Q^Ͷ" c@##cK7?1]TOy ],RZ_,wLiwj>ݳh;]+_y̻9'D[9OJJ~Y4 ADZ$s*lkI2⭡5 '1s[= 0"y׭ ge 2@;6WIi n'6R6|Wm|P7gѲ}VzOvvp|)׶r7C47ϦZߤmak0OovÜ ZZhKcku27.Vj} A!qg"cX W>2]N%=/b{cr@rS3"P7[YFgXar%Lpf4?y}Jú?}?7 63˵ 9X9w80YU6V,xa%5[ho)X=[Ar{:Y24:NjƱ}mBV&7eG^w^\jISM/wޟ_:U>8p Z"kȠnTqeak %fjn6YO\scQhS;oi?`˘ =C'h+3g$focP@0y ҡ YF],/҂MFH)lTg_y }|q)_ ?_767fpУq3s+o^$E6뷦rМG'axDW*u;b,h990f] CBN)߹R럓yMNG%VWJmAKЀ;{D|fx 6cWX[6n@$+ Ե tI])3 H[wwv vx,7~f/U/t8C pv a$B[]<غHZ Yj.%Dj:h#tȡoȏ& 够W*$]<);/r22ig_FK EdSm27'^QgQkw-t"K58.R"rRE^ߦ@Wku<cYt@1t&|.v AĵpR#ۂj'~LcaL\}Wz?p8է=G# P(+H\:I$.FRZS-U^=rS}Yw6EH~pC%R!X] E;L='})TL^,C '{e-+(0 eD&GQP}'r-C~qngz1țMk'^Z;h ArbG!u#e׀$#/?᧩}${K3>u 1N2kW*q-`LezJ^wlo=^[#W`݀ S:y)Ν٘pv r6 ʉ!o,<_eEFpւ[D>hLC t2,.fGx9nk PҸ Y!~v.3i((⣖cX3re#`AK|vh3#']ʠמd?-ǥ__mq,wё]gI ѤM18v:|'?U*3YJu n@5 ;)CqhnhhufPJP=t҄m]2O#Ef?RkQ P4޷xh0<)I4m^)A w"+TA-fd[Qlݞr+B7F C%K c{& X(8_xh8-˒3|PhƊDavC<`+Xw:":r20J1{wZsŒ1"N@;9[U|V99^0{iXlU/P}+|8g^J- "81ԢrC vZ6 Ɂa%, ͓JseCYxLөlP;*y?bE hد9Ks,T<~$Z#&Q}A"~S )8 ^l9 tzd\0W.sL/%lSu?Y[ 0>Yɗb%[VP5aKN*(xYЌk4zw-yn^RSVH8>ƛe:Z[FQĎwЫtEsVޖ00u%2Ԛ*aǏҋ/>\)$.V[\й3R|r7/nF,vyJ;y;=mNVs0|6*bEs9>=l+>wf .;ZIAD-H nK] ʇ'<33MJ~I֙+0 4Mgx%;\y)MCL#w KS!2ٹ>!gsf})*fl`CUBw+/{> emu<$~EsN"TPؑTbJmЙ<܎ xch)D@&ީR%X}-&UZrwoY-Hb,vR CF/39s~~Eg[aᾁN~r%uP)]{{)~_|VhZ x~ж0k6N0|sb`[k,T!9#qN5)*i3-q!pt)w⠲A4.^F/ㆰY#FFW1R'#/=i_e}1t?+ׂ뜾 ܙxNQ ^'*s_I~x*ʅT5bm+g`\˶@G#5"FK70Zp 76ꉡB5*?pX#Ym% vnwI-kp6ZZ$i͖jJw>p'%-3MNɣY 'P&z9Ak'iߝ"W~ಣռ#>Z飅Jc9cb֭gQS`5A<,6+aH*u! +cHtzqQOɷ}+s{Ai߈6g"@ǒYҡj@u&vh^@œϛC-1^ӝ pJ {[x~o~WI/>)Ooo.ytQ; " B$"-4̅g$_˃'EK~?&Vpl236+EHZ$r?݂X3]*2_ @!hIj hxR)}؞ffN8gUi FC;7ҶMÏv\^ݰJbgG+ϋ_|QFƝ4|l }~}"VLٱců>ovތ~֎ܜnl4UQ`ΰ#8ٷt0U5:3TRX c?Is `cf(cHu;2YGY 6p!oimQ7onnn‡7>ww2jQɞ[s\kyi˕D@Px;+t K̼=4lی/p\mwBcTWzWN 7*-٩X_2L<zEW3O?Ck+P`2${ hܤvMW6fk$@ `|iOVvV7?Dv_,暈sY;eO4\1He}S? dvrF~芁CKdy(Y>PNO@X?6G,Xjlm*՞jh ǰ3mk'{}vyʇEHireH7W8?TP @U\d 1;~Ӳ.Wpw|1[% c%B3cQKaA&E'{?^2"-4kHtv&̕l[n2uݨTO|Ue"Y6:?pF(bM'?;͓f>E?o<3Ѝ ң/W/]y sW b~),[mSM bK%bzKqmͶ+4c~Hɯ)|\jZs+cn)iЄn1)Q gpc6}dRb ^WXAgw07A3"pDc- ><ȇ[^^7yy+B6 .5:DoˍM7W;>8E0Q%a/>/ZEnT9w)zZg-x‘ꗟO$J-kl? H)3G{dX0V"v=;H@)>cҢw@ eB]p4.2Zr K=pF,Lq]Co\:4yѢ*7 0!fݹ9M{x-_lH0/۶Dsq-tɻR+V+-QTF x\DI_kGȂFG$$)y/R`.u)l*k#Z@GmVo^yYWXi9+!,OEn77_T]xoJo9)6: .i62mj;r:_@o$c69N4J7NTSQ(P0kՖdܸ%HQ`~L"Nf-PP"d?īI8Z?}k/ ֳ$t,ȇ+ P%RwCo9Y82CJ}ΧwvK<7*DB3YL-۱ͩt!y 3Z.̖ CȐA%+\'.7>zׂfjk a}ڦUA 6B_#D\tsk rG^5 qa;1nznmRUVɽI.4Я~j}!$!%G0.BS:Z:mez}\s1'3~5(="ʉvߺQV{q-lK=kqb0udJf9oN>.<ȱ9B=9u/_~ıW׾l3rl\QZ'ב[[9 ~M; ^%#xe GްKTc ڙ]7̀W]BG>E=S^֎H )5Pd3 J}咩0gv;bh6~aEĔ0Jbrwlਖ਼l'1dd//9Ӻhb#KG͔ak; x!mAD^?Vv:\w*&EEQ\&P F"V]3Xr1< y1tYmZ*!C{aٶ2,;$eR`~ЍO+yx[=^+otݎ6,yr XY=a\B=`i-(:lBI^KbʺFFqF(8oU:M/y%鐅5S KƮ" ٽt~5X-񴖆A`=nlS)@ИDҏKӃuzwVn|c+'sV+|z*[ny}VJ[ʺ5wyxj| @;!k;Q# }N{̤@'!d%bjz;$V- Fb!vuW~\+{qPKAN†Ж f`ŏ_+GVeݏ\#KXŵ<лx d9 ӡOƢͷs/ ,O7պq2HM W#^ߘgXqC VIw ]rVl8ƴVk|;+5W9WJ<׾rxz A'ihؙZf@fWPjk.1abԀA:JOrH.C1"ᗛyK;|~CYVvǘ Ƙ3"'Q@.>~)I|#堸`\ukT -FR;85]-9ϙ[Ltڸ\YϺ(5 7"CX(|eT'Kj}ٍ&| vC-U֞WDq5 V1Z !轩lͻB@C-cX\}t ,! 0c\`i3*;HRj0X߸TѮ=a~K?v\=|pQɿ4 ɾzJn*-[ϥmNn/ o<0]Up+ZСJ, Q+^9B4ofʚF0Uw˴}[%A:L>{-abLu\Oi튗Qu\Pa0^5t̪/`'Cqs;⬌4 ?K|6~=_WSoKhQuF:< B0"ƕ c3)h@RQ hɣVNҲM7ZL)b ;3;jn5 q+$(QPe5X M_)աWr0Tqp%0ꘓ׋E AAo$s:pϭ,tR9#e Q|w~cڽDC60 p԰"E* ȥ굩Fwg7OaAHGxvp>TAՀBH!ruhAnpGfyD*0<;gs5S #O;ӛڤh~ {``]*ӱ=<=!W{+y;pr"{pcI/KՎɸs{{ 禰/n>%w]D=l{YBbvp{uHYCpY:0 "rhf:vQ{tBL6x1F@p~I 5iJOe my?o_ݖKncg||pNR@n8W9&=ԅ=d$TՎв\/ 8n>$MAbOlBHpe.ȇ9Ƌ̵Dy}ͷ}hr*` LZ-p#|7os )`/(8!]H, #D@1y*W).kKAzmӽſ V×цH6n,ӎ qt>Ɲԉv!Ǡ%ƙ]f!= .RKHvTZn4DnQM5`d!7-M xlyR\YBFAbUm(ȵ2Xr&ٽNIRۮh֧u, Pf)Ƀ:|31TʕݭVyycu~)s|4u_훎.]ǽ.ƛ*Tr-)xH dCK^SANj0 %jTQWAyz>x)hi# c=Z)'zwϗ4񑲵OK02퉐 %IB~,u2yvCXo qgANjvW rI)֮ 200ʱtButD6t6_Ղ]q\< [CQ2>xm!Twu!EԆ:t\hјrQ_wۈ[py)؏\>@&R㹂A}j2\XD݊ud]`Z \\49D{,fy@yXiV)^ uȫs^Ä#ve%R1s5?cM Q6&»C,}ak,hv.O=Da.(!k|v8Y ٸH2:'5ߚkL=Kj$X3Yɺa38ϻvPokL.K/6u@ 0H[8#ecȤ@^bKܘ5ԑ8-˯ziGgFP+պ>U-plN$5é|<*7MyBw]/Gr+pL*斕>fpȌ`.RVbd AVwuѼe`S#` $\iktK`1tUA:@; " ΰqY~tHSIgQp{-F4Ǫ}q=>D݅9ٲ%LmKu<sIW VCWP7m;.ԸcqΞ+zEoAk/\#2'4l2{ɖ$k =M:<.cS4+Ŵ)zʣ TmߏMg(בqsZXcSr%!XkvҶuB!eb9ڏ(67?\v6l;j4y.k L|.CzǍ? FTڍюyӗe5%?-U-60\pZK@28u) c(0\1 hQXn>bhWhͲF(~fn(wY70hzS a٦f[f(I!i?n\[RfjjݞsΧ^h /qK 5IݒB1kkH`)j1gb.MuљR(Di7H\{X3\ ޢ֒ |2(˧H(Z)41(՞.uv7hԚHcg.p;eޒ+ϑ#gл6 M PqRnhAl|dFYͽ}M3gJn+yɮfUZP;(;|,ohaZIsVV‘c/?dɼܛ\/O~IbsB,;TN?I:%/ Ykˢfc !tA ʪ51C(V)EYїڻyA=։FDw+o7ۭf6!o;oh:xnѡ=.ǔh{O}ߊ%{{İ; EVxȵp(IfPm3L?nH(aV ,{_99P6eZ hk s hD\䒂crmY/JuN(&ωՅpY#ڡʫg@)тV"ϫ\7?_[IFɑR21^E>Y5*pV4:w /mVx@B5=:C?%,|/yhtyi]h B),%+{K~. px긱eŸwEN+KxٮBB0D9(dV[ߥ YK^` hk/zO|y80&s ;>U-o8sGsAӋ 5{!]z >`l%b5j_BhRP"- Ya]VFeIBz5F1Ckq=-33QAlށ`qM(N]PuPK@.B1.xH9@KûM[k@T4H2( ^JU 2V_}Wscn-MN9;Ұ|^czs;iiRg2ԎqIvyF oeu`EN#4'r8OR]˖rܙ_ZdlᡡL4p'O_/\!sY|@^ W`+(w=[bY0hA侫ym 91S.})Eu+ѫǫϟ*p eZ݂\J)R'$';EOI_2SrNt2Ɉ@¤Oeh+[VEv_+nD.ԦSՏ?~f¹z-t*iF Zde =V;X;3j4zrN;k8pؖS"{c#ʁ'U7뻖\[KpŪ4lj(*4;y2.J?-8Kr5O]ٷ0?)J}2,K%yKؚh˶ͬ.Q=iU_wLşn O˻`Y-sVcO_:Y:3O &*Ϝ|8NdӺ%aDZ ݴk53tNef^pØ_U5Umƥzt<Ȭ _ GˋAqѽ%;9ۭw76.cA L=+R;O3_+eRr&;\MyoCgÀ"դ}/DYOx;'J@{Ίx>[FϜ'wз&j'rEj:8h ny?;jq]DCi3 I15gCeJ ]RjzQ}4쵯"c&|Gd8Y܎wT8H5h uʎb?u69{(]E69W#C8'-(lB8<ݳ↎HɊ]GAٿ`ZIp3\| 4tw&ne8U'[4bޑp3yl6yޙV:9^xY3\FT^5>[;-sq rVp)a'|7{Lv_$ 'xy[tHڤ# $s5оǃraqKMtDO!8)K@Fi:Vw aJ>/oϚ4#| x?.|>Y2J&5ƷE+n[ .-Ϲ(a>VA/=ӵ+Do5S(|^h~1'۹(kR洙]gk_?-i| GjL "*+'ŭlwo!SV*Y ͎TU)Xy3o]i^;3 y+8[vCFg: sbANyzDᓼGɆvaL`U~JeC[ J8tt{8!V Ycv'h=q"m/u칧'ַMN왯noޢ)5kW(n|lyv;n Oh.p ^|R=t&Ίl]]k9i&mG^7e8*u=ݺpt|z{* V qO?Uz1\ٵL`$(9U`sL*ԍmC=Z#~Ym_O駛[3~ :ï\]#5ZrB&mW!t-S6 1  :閶Ǭ49Uik;w{@0 ;kU;4XNˏ]>}|pY1K^:J; R>P0k;7V{uLqU<#q1[]ޤ3.nD2hijDmQjq4G'H]؂҈O=* Jҟ_t <6/~N$_7ހt 0GFyi@PRxC3A.)Bh$Nz;c,h%+e:TeGzp3貆%c)Pr}dkw A苞%OV%RS~jgCO_6WvnKC~k72RH:[&,I>[x u}2oKHH_{g%sUr )PvQrz.U4Jy\ z{Vg˺#1fU6#:uݴ 6'%`s)( =z0yhv ~IYO\E7aE96Cgҋ6;w@YuAE%b<$x`!:<+۝(&DDav$Zyִ'c)rNvm6L0NtwmvOekA]!c#S5jB3)-nD?/ky_}y͝Ū#f=`fJ=B$"jPQ#.+!z83z4~Dj 4> k@1G#FXٶMrޒ |(U"MH Lt: "1 [;קֶ#Ǫg./z#v3M :$YVq T Xsi[;o.&|Q`>4E){T+]B/9P=:ݫb[u4z0#CڢถcFl쳸8X3T-rZrؤ${;-["C-b8Fp̾>밲W3Ys=vMPAfm ,jnH{ms,?OsJ^>^>_b7V%2|hfAFfUƘ]nY$!WFD) XVl[Ym`&JWGhE׎tc,-h&"j :췓/zZ~:=PZj\Qprh_}"DrlCLkJyvv͍7UxtXaS56eV)ӄJQmB=|/]JGVt1ƫPnΨ/OwBqC|,nhq(ՉɳȫM)K?nnmr-!/!CISAxvvOS7DHa ?abM,Asa SFަ/(+p4GO^D/Ot: >T4#kA|XE3>c-[լ2fvZx sJ" ¯~fYPQǿ>[ߎtr "% " *ӵlhw]+nn|Y NlY[nӛ2ץ"1{4+[eωBrm@FnudG?J Hk]Ɣ}犦 #ݟL-a=!)d ;e2jk,G N:L4N(@WC'N&-9B;Ry-KO;Nޟ.]L-ϴ̔ ju PtuJ7pE6]AuD>9vwA?f`H5ѣu71J_hwۋ+$[goe\79^A5sGNO6bؕTS"}Ո;^%FK;D.@ mg^Qc=q6gQ<х?{ʦK 6Ryyu}1Z$iIy)J$_N)s\byamܫ:TxD)f$pՂ)M a5:4/#ތilA*FQ)PUQ/?&*H1Xȩ(&w5M] iMmnhRsiǦ9gnB`@=(t5ʙ${_\9>s"hXO3ў+g7@i˲/߇ [:mNs%AOR i'qkQnB.-n);V|?υ2;`mkXZ&~U]w0׶4VI'| oh]OZK 3(_ [90QsQ0˂+Q±{"}\:yw||q(w~e ~'QRq}lcħN|[I,4a%E)*@9e2}:YSI X'׺rxjD9p;aajiccy,۾Z8hHTɓ7`Bgf:K5V ԟj& bI2.<"R{Ȧ>̟zLauyzjmI:) gd!J݌Pk q۠Yh!־%QυcMW 1j!gG4(˕)vޙ19v}PGZ3ҧOom0˦Þ+ѷO%0_ _H$q9Uy~C,vtIbG9>U:]:iQCӘ'qȱ)pJxoo'ϫ%A#1c!FQ1t:SB/aӌ1LNP͠ q?ʁj [豃<ܸm9fpȶ;}#y'X,lX"1Jw7$Ű8dn~:Z e+`^h1"QrpH< VK|yCԔ*ev"~ZI}K?x>?Ez9Lg)+:*x9ܜY,Ҁz&U7wXve\݆MAY%vÒ!~kf6 Ch!S*Pdn.Y,Ԣ 9ޡ$!bn:<^qk1R'J^jݕs߄EMC4&ܗHېb =gy{p}06tI=/_C>k8ЖPIiuFdwوqefI},7)Ev_<J=߸?fЏFΥIP EbD{kǶN$\>KݟK!J޺+{ldK|²kۂPSGK Hx@!7&˖}lBEA:׷x+ í|$3 6D ߚ?֕CS'RmA*CHj#'0J3lRR2b$2(l9&hSH)zks~c]Bwsu.]SmK N gFo?ؚf^^- sYר"CALanE}9,VF]J٪i7P%iuO>6:ӿ' Hn=F"2:0zD A5OC(l\, &(ZR}R{uR'qq gT] @ BJ>Ԥ'M9`혷 ([v A#dH{vk]秖Msfǩ+RMqCqi7ٍ?.J%_p-roTZaÇusGJ79Ngkj ʻUNx ATr^ђ#A '8v_"elW5"*,2VM c\I0VZcШbP"2eW2 NRWIs̥w~0Gl~xZ n_߄ՂO j_F2 03vX'7aTEw֙Jt;pb~}FweT۞_ɽ p,{lk`aѴag',oѿ8,@{N:P;:TfF ו*U՜<5\0ѓT ,{0;8PPX]ʌeZbeD=T#i,UUE +*2We[}R)hYppΈ* J}vD7|sgt>H6ݴP5 N = q(aI [+;ݏ:-,zol쓛e |O?޻5VhE~%t;4?{V)n-ԓ8?ARwKzw;+fWd„TTP4~ق50vrAe&3/|LMPݷ<Ϭu ykk4歸.v̀sܷAPvfIotϛZi+A`>~wjcv@X EAs׻U0~7K@Bf -~ ][{e4wUM;ig) YRUM[YW8jWg Ӷq3J[4gp ]Ov k`Ovd:(RXnIy + ϥ5,Js7*|_>(w;4?dK[]m`~0[^8_ dkwooC|g1&Rwg[ܖ%|9@Cr f*XtEIpDp%dbI 2ise+i?Cnf.[qBi""$ρw@݆xoBؑXjiՈQ,oCOza 4rN0䰓6r.HQ"e-K2.%KvJ:%9l03 4'|\ͨ(V,d^_{wTFs5^/un"L=D5G,ŠwmTA*H:)7RN=;rto݋([T$݈; GX^i]Qn05$kGOV?ڽNUvW5!x`RʕNeU`*z̈́%lQy؊J;ڪXx5VHL ١e7\o[X3PoO:}Qa'zYɠ$NԱ9  20b7VŐ gXyerx HJON+ 'zu \*¬m=Uܦ">q'_:5}y'{)Y=ZGf|bG]HPK\9\oɇ [âF-Oh扚mUNjs{ '/G^^^dZ;8nӥϞ? Vp؏ %Q)Qd//A¸(r{X:;Ѳ%>4]{o ~pYá\7à'3KXP0UU2W|IOnj޺P:V:}mW^sIłZ3<o4ziRW&6ERI0pT_ZBᚳ )ǎJbE)Q;w1 @w6`Plwy*cqk'S?}wۂQ7O>;_9?O?_;^VfhcM *uK|B0<6ƑNkD*3Sbc;;Q $"ُ7bʈIDATIΞm{jC;*r3]mP> 4Fc* 80~TqI+eO2\0Ѫ+گ`ȥz' w7'C9eK)<}AŇ陉A v- MWyd]njN83۶JveVG>hi•КYrc_ KDfX5<+tUt^xk,.fBSh {z֞gwNtbTraE)gb;J@ԒsPT ofNx&kO{;7h0 œ7>!=Gm>ɊOMr|KfZ(}Z(s|{]`80֤mH'sgszB1K{TJ@=11DYrfJ 7l'gNgO?-'{%vl3##ՍT"OYp~Zym$ OXw7KpsCçv7;[@:Y%8z'w3\a0þSJ۴'X5/g/bs=b|oA>,m-}{L@cV";cCF+G'Q[ߐ!J≳FLz})fܔ_TJ/]¤WXr5yQX ۊS;aEW B EmZ eF~E|Md5*0E-gOK dSa ey|Xg41 {P& 2?iֺ=+LaT*`a|Ogr>W98AAN4gM>s,'g8TK$Txb!8Q3sQ9+v`Af#]J@;H89P×hY}ubΤfi%eGN WA6CկMLO=D4 Ͽ}szd~y4c]>;$m̨[?3 G5gp.c!0]-0öؓA*'#Syp8:5]^Kxо.߿ 8;=pQ<ywTS}es @np.[x#ov14Y XQ@"}f<; % *H'+f{@0$ Bˆ[޽3 y_~/g ׏HΩtıF nJo%b lT8iK֎0M(1zssRyXm9k-~͹Q AI F,7x@kWԇ.[Cxr |D04y4C2vX]vޕng!z~.m}c;5i8r,% ë3{5rݦn~/>z ҧ?{wvo}iǁ`swLiRgLU8jD/iC y|'Y%2"#jSyb#&@Rnj0o `6J$6&~VVQ`slåiЙwA_}/g.Ukȝt:j{$_{7#,eQh=_ܾ/i.x/7 }kx~ YTl꛲øT8X!AFf4=,{)1mc>` M%C (-@sdjm 8t7ߌ [$?8g.%9W;v$SeͱKb!G&fvϏ'L^߀ۥ??u|7>tݿ~kٳ{Ogw; i! ¹D-?/'_o[d=6[KtI!D"CPnӝ1D5 tێl׽r%^'U߳~54ijLekBw'Cb;a(Dۛk`D A0D}a3K7`i."[Fs_+DDFM/ei$dtFLm-2%]W4g0T89ږe2ͭuHuҍF,$XjͷFG=l.:xf~d:@Pm0T`# XU6᫯kw>9[#Fq堐9PRnD9x:N^\1GRFde'M]{mD(V&|@X|Tcs;?Hyxྣ'eIxn{@ ЀC2skt;F[{۷?_uwLդחs5keCsb5l {m^=fq2vF!lQ+wcYohn"g_ :u_S}BG?oΟ-lkɓ߽'?zzs'lkysxk:ȅ &C3>Vq曠lG_vM鞐5ZR bYnZK[ṃdb2xsJvv1 @XGAryƥ)d}?Hʗ߅LEʊpPc~ƫs_.W[ƙ{*܄4Eq#vYΙO/sg-58@]Yk0Ahd_̧phN1>uzo`/<4΍,iKd^}??Xz ~qލꑙ()ZaZj8-ѭ̟/cӊ@FFnnչjmn&ϻsݯE{e~q}l:+BÊ4&XK6_@:EK{ԑ>gy^?޿NQ݋w>,Z-iF2̪ujޥ ݖ.dz-}#@d+M_85tyƠoUrO#!Yk< ,6??srW_ssN?[*5 ωITY-M<_x%_Q,v4Šp0qQ*a6h&p@"7V>qHe"20?~wnfbۥმ ݩ ; ^7g |`k+/+Pf~jkzp4/x2RyvhպD@]Jk \^x9F~"!9Ǜ u By˚HA:`#~ vi<hhmx^C+9\sK[3,Tbn*2zzuu4tGՓ~#9Ӱh/|r{˶6E[*23'j'eå'dlvhMĤ@~y={* VOF5]c=+|3mBU =)&)>ڈѠ+YHj7Vi{NAjW;L mM^*6L)n {=1SJo-宭KU޼F>xV-6ش7=3r^[6l#\^%SgSSnC)W^ڽNmR #^ [ٴP*ð"K[7Ŕ'ՈBv ZM08STO2Y1pc]9fhj*ErNc[["U )Mlhө}x;>]ieUAm<zbTS#g 16iKj(kAÌXDd[jURTF%9zz¸\66M<TWx!}WBQS$wNevG`x:p"Ͳq1@)ͽVZz"Ⱥ]뾸%ޟϏlAY*eC'dQ<ɻ72 Fg7#$#0Y+[p!3A?}}5*T2 y3(|mvϖcYWO݈\Qi61Rq)OSFj@ F:QpkTf!|&1kPL8(+yzWo qRL HΗ[J +Oj4v4dBaU{BU`et>p=Ϗ u,rCH"EDiٷx/Ȓg+rKTQWz.T†*VY çP}B*} O6汮h2Nۻv%j.2-mj o l~pEےr[ ص|-7gRq['x6ZWnDs֢(Eر>; +nd4DŽ90}$lzuB`M‡B,`]>fCQ޽+F8Ebd3BMIx|cY]Z~[~?Edr-`}\:U!HU.EZUUWWvRGܺvj<ڱC5L@PS˭Y?7WV 3Wx禸yn2_uMN0)HV^|CXe>X(ſ;rvlr}8?e86 WnY@ZY7Tm߿E_~CW8C5URE 2U"oуu?|e-p("%5OWuwE~o`kupFVM0˷@"8\]VZ]$Lģ Pp袼lIdN <. s4]>\zu歍vhZ 礫) 7-ʣb/Y%dR] qVDH@  !hJ554yC؂Tr9t x 3 (b**m@Ŷ2mV[QWo!d% @io-7R{`VH*vп&PAX!MPwJDž_2E+!ςV%:cK"b$&UֽZf!]2G`V%n`n:"" Jg 5Ve( 40b˕pЖm,پN7DyqJ;5i`s!*w DƔ}>#eO2^Q[Zxo76eRy賏ϗ,@ =Ӄ w|4a5 :k X@ <ܘ@]ȀQ ̱bUk6ʑ z0YXlhph c~K: E C*7uן 0;Y[q%P Ԗp%wK Dsx"pA;7!2  R2h`V{K֡;)׸i7{>85gS}3ŒA>c=1M:6f |}G[^m-Υ/\@p8읨ռ+<̹UnPwW1JjJDUF[~u(#9,O3MRc0%XFIqc u2IE8@R_&@};z/.3Zz)y=cg x͑kP͐]Pr(k=>p4z%5K|]]Q28r|T.MlA*JmmN(-+4v{@AL,^;˚74|9!5GC1f4`Y02B6 4"EZ>O`{Vu/ѻg>=7A6BH.),|M'$P6Y ㌇Q\JM%<; 5䂸<@5 h ?K!96/Zk9ف=kz5a"33jZwoV2D ~pq+| <_>ُGsKM^老fhw桯@cB?e[D?pckz 7toܾ=ջ0@p L6p@n.t3$S z4-$i.?eO?M3VͭG$10%Y& Elp;}Ea:Ql| Y 0Q|DgJInAb CÜ]ƪtz Ӛ{_he9`{$g O~ -1A 6UntD+q|cŭ޻WX=G}C"ߠ3?iG_ڦ--yHWhC#nxMg$DKvv}G޷WP/]{lv(ȍCY?)f-a#))8А}PdW | rčc1SW{w?PIo|qE3¬51V{`&leq9U)x@VAՐZkk BE| wvxN[.} SA1`?dKM%#z4B.ovrTRCa& Hu{贤C '~-wfԕEf Bd<%o(Ss5 ƹ< u~FW#C@,լ1k]Mth#CQ 80o-+;25 &@@d٫ 乣Lk0JvV>?|)jZ~釯8׍4G٬?.\LBUphpNe1z^;Jg3][ w{^R=iŲ .oo:언]%.Y6mZ` & e77K.ӽ*}pR&Exg(qf ;|_G*/}n,`vB_<ء)y1@ "W s\ʠ)+P#*U7W߃P@ڀFF-^}kj^>.q,~QX5HeXڌ.N?7G.݉/߆J]>~?F*@3N4 )xm[F[Yr)lL0"TQJ7fQDבvloSi-wN>99'Ua۬j欱M<[v`wO r5(1G>h[#Yh]!ʮɶRY 7ۍR|),F5pyBlaS^ʐj#Z_+w +g ?8YY:q00TطJ#0Hn .ɬ!=䦝@>Xc }:fyywY|lC/sMRvl1W>coTieγ%iR#̞ݤnJΫ%([^Cߵ_8<:!-M9tt2ur{)z|nQUYW!fy|gpR{՞{ DN"Q5)3+I 1!P('csxn:*awJFÄH#ߕi`X#bԊM2zUk2ꬲ }Xݦobsg ?(?r>P9]%$ Hcu9Cؤ/d 'x:TqoWVFۉfȠK #'W/s~TVba6tG[a5䏾qԍH%;Y)9EiO1 d *0@[q~wPp<ˮ̢oaP_ǂ10) uMHIb%iC~!NF%) ș Gz.S{S[YfHdLL$a5BTgp>3h^{b"ż(i ۽cmnY)+a]~V7)Ƌmh[s|v'o~d߻}P\GA$41 ]CJNNwRrY(o#l[^-[j4RO`J} ;E͛oaQ#ES^ 0uuIPiPԁ l{.. RW.W8s!m By  s@4Er!2T{- ĀI%x%W*(WʵoOVs}$#*3 Ҡu&nqKB['g~<[[Ϧ?dk<(lf2߂@FJ!Ïnk~'OQ+KSƇoQDlQ, ^S8*JeDԝ/u㇃ˣ#'@{XaW)bٜb971 Shc# ۱,U-㤒Ka}#W/vp;}vUrϥ#0 [rcϥPlTtߪc@g'JD<]+~B će5aR^d xAWr-fu 7RCFeP0qpΚ11+d^A[@7?>9 %0h. QaT$ ]K,xcZ߇ y1/<<^h0XeϜ lod9 [`n U-R A8jQy>n=+>(wscV2EyH g|z=_PMUGY+_h#]_ ޲F-U^XG.4N;m9ʔq@.@;t1 7x%{Co\ӭ d_QۅYC[pHz!ǥp>&f׃崈+%:Ix Bs~P3dg6Ǡ kYZY__ڞ C;&de>+{٢tzbG GS:w4,}\ׇ&0>( (wRahrp^m|xݞ1rytQIl\V3. ob|125(DNc2 `:)R` A@F1n(0(  rP/`@!k@,`)C,Xږ)Ie,&ıĀ juZ !@`sJ1sA80$@ Ppt_2SG D@] /,)ÐYJ/a5Sh,i.^l՜_ѹ2e?V)bkǐ"(ŏ~br1VWb chhFY@.]CV2k" ?H%2nM4ˡ~ݧ :vеRPXl+ÕZ#v80X@@Ps rlǐ Ӓ !ABiV;Z\F1!䇃ؖ 5qSh `.)ek#e+%d (B1GѠ - ,P0 4 NsH|e-(0KbTOe 5 -8,πoA2B&'ń dTi:uuy SR 8sV; !!(0 <4M9LY 6dE(b:!-gSb x>nSV@#~ ں5?G zbh% g ej}os=WpϿBƦV6x*+ 6 yUyᲛ"?k"  ^*{Xi1"4tb{pVH%K"R+e 6 N%pp(4(p QftaAcQ*Uf>-\ˀ k@Z"s!Th#0Y6aP$ B(et(ْ'B\7686^A-S\b#pܥŋC5tIӱtL6A6 ŨԵ@0L'VehbM?jD]tCK1wifoKr=`i~,t7;&vP졒D(oTh- 7;u}#C);. 1N4uA=xoߩVоv " x] `c 0 G{1xRhee K {6Htzc!~a XvwٖTok+=d(mSJJaLMw⅍}ATdPUBQ 0H#0 h @"bL= 0j)3Rb;.B@r , 2cag{^Y.WH繲D$LAA 60S@Bey :sq!9, dEwh>zFGl #;TZjɤSZː9k|`ZxPcj>*c>$TH 6ͥjΉCphuONۊU{Y*ECtۉ@XP` ;Bl}BFEXvK`U0hy屡w?xs0Vn2@] PI[C;rOQg k区7>p+ ֫0{٩kj@╨ӱGg-](50_hp.(a#T:aS9FP)k?9{2 򉳚^tt\+kzP RPDXrT -v&hU$2Y*݆΀x:o!!|~+[ۡZ+ը%vu7'+7ܖ-qZs`ߐS2r?Z*Ħһ4wMĵ2R"߄ќN#`pҔDˆJePc@CUQQ?AKS;(EЪ5A9S".eѨhKl\fR(Tt5N;~"NQs#>3 ?FKPbpzs{۞|Zu^V,@hC)lwoƪ˷+P#fA!pJPVNxcS&t8P μ| XV>LVV. 'UvO gC2N,Lh7rdV,ZRM@{pd3$ Z08"#+|cݍS="1E<(.&HyVǢFٺb \rvޭT1r`vBbˁh}?w,d?ܚ NJk?)i`R5ү 4SaD$5' gBHOFU J)`І@H`y՛nod|':5O7`$\)"b4oESaz&p` %;Ez5&b?~>Q/jSZ Aj~E/QRT J-"=:U[lgppQfa+SV}a!ѻGwյ\RX&2NO5Xo@Rj$FtT:Q)N"'MUa UrWZ7y__z nV:q#hWA㨘:~|:{F}Ca_~SWֶehNҿx%\Ԃ o_iuf԰7^({cJBj*G'@u;0O?VIy"3,(jfړQ~Rkdq~CymSl '/~(hɒi sbN' KCBNK05$!`A9ɀ1G`dzր60nz,`y@BX$`/3#ʌsؿӦ5Wi {tqyo0`4OSڶv^-m=u']QarD,O;׳c"KMi ?4mnAHMw=3DvVNMVvk֖K5, dѺ':3-Uh+F~ƱVn0&[ZE u+差ƦI g 11V]>UrJsA !\N-^%J;}ǰQ`5QQt D^Q˾[\$y_x#~%wN֠7['|9bTaO'#ЉWbaqkq8EcVs61dzz-Fs"̽i Əs/>Pl_ X<]g/L/_F}/=w]{Hrq/н\pqs[7腏Z/W8UtZsCO }T*xDFἴȫDmvrE%xQbg.5w6XO3p)Z?HaSn/F\LLH˒Cp3zh*9 LG@3eh B[b?]4>|9xqI>Qyfhf<{Ha{^5j@"^ GvJu#<_POp/57ܿuotM5hs]!n-347]#$`OAt["2#0z/5[z\nT $remN֭ tfJzf̽bv C.A[O5K&<~,ͭm#eDw*TFp8_NU'ydRm?){)v1Ikhpy,w∻'NFaÏӻ+X9ÂLZ;.UK`u4/Kqm"cOi7u2āP2J`ր0V7nm:q0VZG9)/`@´ >)>Vg0a|_K`ra0w J-'9U4Y'W \ \dKUԷ>-:,_omI;xܾU:4_q3 6xk_۞QqmOOD;꠻8:zΡ0uq?e-$ZKP%=W}x&}>ֲ*4("2r*XmWnRT{G_]]*9{cTLVAlRRFu{NkN5̂ރD^ vGRq>.;>EJ8]Y׺Lb` @3tȭr߳|v'=#%μNZ>|u.27*[_O,mFo^5 wtk'Gk8 87 /nϮȪO4wH ׬&g> wfKb~sp҉ݽ%z/~_! Qy-{YHˢXS(,{W.㘲]^y+e<۱OdmwV x.9q>>ŽE!"xsflbMAPA^ɈCvuL{"wgG>{5xxUZżm?(@Df7-HpM##جcUv3#*R)+1*;-b. @ٯ=Pn >Fv^yD<3l$ #2qP9JSp^]=vXl6ˉ.G? pd)Ѧ72ه+; *5;ۨW~ź7$UpoNO,Tcf}$>Ҫ>m3X2q6#l-r~i+s*>rBֹ`tاpT6jQ~F|0leWvns'Ί机<%w\FlsdiNfEkJjm׍vMȣ0ީҰ~F)JjajWGWE9 ąܗ&G.$ R)Z2G@KB 0v4~:EzCy5Et@NsFG6Lp81V1Y9&9ļfx=81?E)}d0qg-#~;s,"_OoaHl )bvr 输|D;Cl'IF6Pݠ.o*;^ظgPZMX}FnλN37^NhTwQf運xt{=v Fq-m1v*" ˏ>{jCJqV\{D<>}I=\vy(`|_zb#@*>x2>Ap)KuaUNL,4tR#ywBy]|pTL{o|=g7Z֑.͈yjqA}> KD[PIy}2{9١mУnPݓIxydFƥc!VngDџ7ٰYO4Bl{r:"לFq&֌XS_ 04%SO6}6l+04 ) xFK`xG\LCo{Wl] xQldR nRG(0dSf&Pp8ub'{ CGz)j- +b:RSm]/ΒlwRW!p_*V5]s*5C6SQRsߩnCSպ:t/QI>~"k(71?._Wm5R\{υ.U;Gؙts`<+oo?nzkFIVw@C F O;!A,@«G:ԭ[kY'ZT:v7&'K}>Cß9ѽt^hEY@[vXNQw}yjx+iV t]J{s8`YxgVͧ-``hmIy QpϘmAj܎6ڢ. t/JGfƺM\_ UE,&O~j8mK;lwM/KIH m*ԝBl2ՑʃG7DdpjOۑD{ <|6} b爯 I*!>=pn6:³33G{lMkwNJ`oH0S{+\xغ'­bbj Μw4dHQ#5̺!G%_:[w]^7oeG UVm'ΏvIRY3&q߁UqyrlwJwuG#TpMﯿ[n1 :p~h훈.SXi.$HlvOVz2cS ,d~}"5%EFCwz9DvD"C.EQ$A@)q. Kp+thͰ7wv.g Њh9kD .M!<ۑγl7qwxA'c6Ay$j56fdNCG#{7H6pm՗mGNr'˷~e~مc=+OF1]qjʕlr}/*=H%'_8zJq}-ؾx__<|?йSlat<A\+%#Q} #5O_:+ߝnyPK.j}VU^Ø н-\S{ѩrl!:u}|pG*w֪m1RCBs~eJ^mgTxV +k(΂zŷzs=*foxpa_vR=NrCw.>̢me, cEJ#]\'2ˬytuG/Y_kƫRQ.ąAb;/[MN--Е&ˑY(MhAj]N7 X槣ί:TCA&<ϝaر;펜$u2iwQ0]RS R_0`95voU.q䱰O>Vk}r/Ϫ3GngڡBAlj鞑bGEO0/ߺ^lH{x n QK}dЉ:pWC/MkN&3]7:XY/~CNO\؋5>15\ݓV[Tޡ'YoUDn oyq!].{ZÈOi(Xbzw>r.yCfǔ]M:vxD>u!fЎr;7sldg|Arhu$P\atnƐ0h."E w?&o݁!`:U?,s:S=z1zX᣻k9BB9knʃ'/>}jx!WvҕP(&P'~*>^SI2nm-F ZuQն !EI wl^:qAZ8&~'eBKlf16oNFpbtڭ6'/)٠ !x<|޾5#5(W+84wLA9XHf0F.Ί㈸`?"ٝaMxP9:sLd 䐔(i-k9xݵǻk")If:'(UoՍA~S;4ҵ݉JwFauRJ"Jg<Zur|N#!ٰGLNYVy`| Gv]<=?:O>s.}wn"O;&`?å[;-"/2x鴻3kN,xoI3^lTqG7bEZ6SF!A5k^wV£q=Nl܋6"]@ GO][m׷gR #W6d}S ; H8צ7qɰU; 93q8pt뎙yPu{Sf묈힮ފjAMabK&oͥAXask9B4+Jij TN}:qmq-HE4DJbdB>hq&WN)s<)o߾m/x@dKp+< (yc7To6\Be&Ƅ22}@^]*2!d]2ðC(XqZ@Tkĕ ;ʻO[Wϳ8 cϦLHB&#g=I{8B!V^" I/:-6up50_C)g]?Xsa^*ؿvt,z(!)Ҍ%78 ZAFwiؤݵ{7{ȢOյB ^@ee[2 Y )ɮ Qp<^KffSV:Y@nRNzl~uZGڱmt*na 6V4lrdqX/>e|/W?zgQ,w'8p/*W_'kMQ֬:/8 LoEr}XR(Iq-,KF̮NkE20LE/ X2͍5c%,C6zlܯ88`` 57D96-m{^!q%WD9 3783T#0.s}<~G4b+גv.OD}lď??{ OnD G%ј˃WVZI1pjY}ȹ1"B`KشY>e> ^o.¯kU5:wk nl7FCr{~"S y՛<;oS>5\yMꛨL=nc&!qoő٣T7!ִs38r?+R/^lҤU_S^ҍ+iJ3}w QK9h(pvm9ts21I0bTmZF?⎢ׄ,*@VycA$!g]W"fF.8{vhdۣ#Ikqfn˹EQ#VҤAi<^2T%5 K|ĥLo~QM;+ Z3BA:o~eST卷:kmU2om^nV[ n}a)H]形ߋ2$TEz(DNKK)aʼH!3lvč/EBўv§WLi[mDyJtˁ/x>xC4M'wy'{ɣO^xFKb,V[twita,It/Rk+k\N˜0.ez1.&pwce)c$uǎxឱ.S"q= 2/ 4/t.#{w惭O0?8wRW70j)?u66R8fk~bji> U+ALTNP)u4rȴ7nwb˄T|8bKMxɮNO?OԮ*+Ժ%%7燈@< ɭB`*HE:mbRͩ!Hqm8SYw0|)|I]T{E[0ъ3e>ՠHd͕M6(`N28JN܊]_QLIa"'_o 1Dí\ L!'W$IjK=7@0d,7T-JZE׊ޡ /KwisLKnɸ1^=>Rtcf<;z"N/>>}XtvN\&;Xp~?mu[+ 537H|$[i4 YǵU0q9p|7h C/'zJϴ綽5.i{oQߌWMmI+=Zp Q=ž8?lwCʬ;i7h3dXf$3}ED\mkV(p%x妔+^,ZE5iEvӧw] `ĶowұU=(:Kf mhkxحW#r(GB[s׌ W*IBJab}B{*fPai#1;`$&͉}`Z5ke.rʉZ`PɠaxN'b"3=BGT/8 kf *qqsn#u bbNϝDG|z@#D~=;uov$iUX -l|rikF/cR)F*<86. V{ҽ _3j-}ǟxk^5H6B3vM8/K1-ux/ogx-l_O7Wol S 2k!no"$jC{ȭ^N_<[]b!bRCILu{jd}i+:[q'>paZju_YBő !CjD^{o:J,2զ)R'e˰rSH&ڥ%r⻜91-TbF imf ǐ!sqw﮻dVX&*M\(m{t;ȼF͵ɛտu2̅K)[N-=፼]$ QI>hvŽY^͍ f65k/m ! rOo$=8jÁ|~%p*Oo/vwoX-@sQ*(@#̗_*W:Z\S*3psuh~oɊ&NYVʃn5+Sf߁gFfu+@Vo,4 JaJD9/=vGwKu피|/pݞC0PMAc?t͊J֔\@xҿkw" Kᜒ H0^f [=;ULIʵ_{B% -\<Ś٧Q^pNLξ.#a!b9Vfڙx/(ʟ(}ZݱAh. HY8:aΈ(!Dxqۄ#nNis# AdtcCOaڶ{TEhW|*v'*4-Xk+hă_hS8jKpEh,{؈Pshcg'>۶D ;2ŧ->(9#\XQɟPZv2WjQۛ>B2/䷥*[!˜< +˘»&W7.9$jxͼ9Y#'/ƻ{3:J)fl2$XAX0:*u%]=z*˾\އY_^|xg:*ҺPaM4Quˆ}7?`uW>M9>|VkaC3C?y_@!3AVa݃޺f Xmkeu7D`Jum_Hdm;Zi91Zt(~" $t͚1 *Z2hCmvxd/6n җw7 WgD)^{WF7ztC=]F1"zSAy*><˽4Z'<) Pw/v8KGYp^HjBgD7dmV\ZO9ȋҁKw'ɟ>󨹵Mh  AWEō!ӫ+P!c߸hGY_wZ7?ݥ2o +]mTdy9Mb9T~5yx]tϜrl[sLo=O+M5hi_zA~ɬ,pb .Il^VMUZG? +Ԫ1bU-i},*Nou= pP1nHYU\5={a%>/g[z/G?I,pA]Z.iB!+8?ao&6ćpUPȻtS0Q~lãݔܾkMX.N}M[qMɹC!W2 y{]Z;Fhj1l#}eFG'7J$UjeKC΍[˕>Vmn+dڠ6e;V0`e'wlmw7Ĩc*zZbxƃv^<Ն{g?~Ѝ[~bJo05ie Y3,PT+#EQyC NmI"Ϫ4qMI7KI+b:06~Ó0c9eK. yђe#[K2@-˕|BNE1a6rɹ3!?5" .!}U1I3\ 'w/)J9YuS=C--w5Oui1%Lf}Qen S'nxHҙU󃥉Co}Fa}Jb1D!6oNn# LԞ/u:9ŖoQg*C28]0PrO@-/9ozE`JdYGvy}u/?/. ?AFG_pƹ2&U1)vPqtcdm#M|vb|07//4F[ʹSI27,^* }hBeHUU k,&qw Ϧ8/NsM~pl2E^-b;3 "?]jl<"nSU3SWowCFj|ظ-oc* n)j^x1wZM]Tťzf'`=ҍfߝnP*Sޟʵu+rϸGzK 2IGb,J `[yKI_ heeeZ t"Ck~^藞LzV;~XI~D{{'"BX)"71heSRN>Ɏ+͡(4DW+p1H;3|sO[:آMz&) z?*9_}ZnocCNoߜV%Z(UBæk{iթ%6Emu@vlҎ9ET(KA~llGu~O> ISB Oy Vw?*Z &ypuҿMŗ7db7O . Y3RVXaldʊl #{} _;ycG e  kˇ(/uLoAZguol6v#jWYfvEq7 LW,1&Ct1Q(:z  .Ok tH~g5:=sиnz4x5 ZvL cf}7^r׻)f: lNcz|k3簕"Bf(/ҳ[ Ҵ\C*迵I˯~U?/gF`7 v,|苐`71P]B3R3a/> U߳v,'(/K ཹ湇_s7W|47-oL'9D< ZL5}jEOT. 4~3a`4,RBQ/G!QG"lnTL#/nwJ{}7|`/۫o!_FC 7~îM˕ayE(^'!i8u_2{n~RWQҖi&TwH-_yg%s}tufWZ JVl)1QЁ0̨6C@H &SK !8ڤA@7uw<49B9KiGSgON}^.u,P |dĒ s-{a\Xv{:Ϸq_@/$Ya0 ­+ΧCa[(xҾw!PYxcP# #Љ-ଭ#ᕏx{8eHSXe}ÌtpRUHjI OpҎƎE!G0#P8pA(⌷ɃX+9p7 Mn%v~+l@8/T:+~bfjkҁ`_YmI i'_ҝu|3i|ت3noa1gen"[! 6eb J)yfC)-8&64g.EF3.Z4 ż67=o$93)O>9ps٤JCR^y<ݲ F*άi5AY}rGy{s휭R1Ǻhmg{x~ံ&pV%)X_/D|Ofx$5S=*dR<HCGmSF-<?1b31k>jӀrs;sq:_}|~{xHWbXa2B g+זhk:2īsjQm2ooER:#Ds:P"A2sk{i/;c.o)s*Zb481ds+82C{KIJ:{T>th1}iذ ٢+6%[,j:.eۥڹLpaNXFG_]dLzh.;^eڸxٹ?T?@vDބr[xNoݙ5+}=Ha -&*)7Jrَ-5IZSp`Pl:waЧ:h{ l5WDOܩ :7qz7[ǫ<5#ӿn<0y]F*n  XN:mHI[ɉ"ab2,~S(.#q70ߘ Xݡjl4K>#Wϟ̿zT_9s;\hk V]; -:HA6ZIV)1wsӗn-׬,I/$9CV`7V9c(Gylnk ֽyk_Bz`#!:"@6=yRǵK^HLfZŭe0u~ ej@ 0:B 5AI&<=2Q?!wne2)Tm"&)Bo^gcWh@}xǬ7#0.N_mnŖ)Rİ??ף@oJ.};=ENَÑPYMNA/U~i֝ɍy#DqXzҘ& MS[M]8PiWlX&{ڭMQXX]-p(D?3 uɺlg[Y"uɰ\rI f#NϦU4ֈl0XN?\vwtM+Y#:ֽZ+C0R~ 'K T 3KdOߏ~K!N{Zz4t>`s|r>T,oZ3*_8>\UA׍+SqhQSݫ0wnEτYLFGSn[©VmD[q%Z{jn9W\"oflj16 \׀5L_PjӨ=a>f4aĪwVG ?37ŠƔ=8DM u (ƌ?zz`o^4ЎsGkt\]o$]X|<%;Ĺ̀8~XLԔI$<Q[XTYiqz";s\oǝ{7+SGKRvr)lژzÚMsZ_6Y8vpabpj,V6uخVT#h+dB"ۭ jh!UmzAv^u-Ms[O ]t[{~l~8[ x_pD߾)PM<'lMWȧ7vyP3Ƣ нyͿ|Afl~==Pp--z7}RC0 Q|33a0C-M$ B‚0 "4րY4QF+ 2 QLWD\sGXC>9kcX(mU*cbTc)~iy[AOsA7za> Ɔk ׳|BZY3JS w\}w֤`@Lv؄||I чv 3*[{|s_t{/v<ͱq+ݭ< ئǷ} 26et>v_,+z0U~!ͨjtxYp)5%.i|g rORkš~atu%vr sM.-Ғk}w.VI)iJ|bphJcƋ>ffRˮNg9T"/*y0Wo}6ps ,*}=[;Q#w|:vĞowqypiMl "V .[XǴmNWRY ai p|2a)ЂŹU[ jH561WF! ĖAj&MqiJZ"2@חo:`9F-AUFU䃈lMRa`5W*ɨ#Hr0";qΟ%[Yo:Qܮe"OG;}n{ϥ2$<{Fl3zFMXG SfBozuO zWAo Sc+@knE>et/%S 3uR( "hsX:N]Npԣ#{',ˀ~ն +׉L!Ǣ`JMb-If9cJds^PAi^wZ@:g{fպ}{\[ŌɗΒMzR^YY Y^f&U[H kw-P HqRӪ8XDʑkX .PK^{'zWSyqdͶ1-09 aE!_#@PV6!l+nQ̀ [Sne&%F46EB0>f1w`f_9+]b&d☄ါL"PP mM eTTur/sň3 ?ދk61-0u` KүC?Mض6-8RN{[LY5ޘ} 1\bjN5ͯW{R}6~Ww?yDkV Ğ1,$=g{WE lˬT"-gĦ=db3Av5=;OWO #i1ccף(e7CdrP&dž" EHGOpK99YxҬ'f}^׊=7éF܉zOM77f]o`ʞF3NѢX@7J>;whI>O>lwI??#'3j]+N$ ?oȡ'ܧ:{?':a_BrðTOǿ5|Ϲv¡qb`ɋVQ6}+.ܹEj~-&먅%*!RW΋=tt?ZA?,Mlx.wZ)\-FĞ? \@6uCT 23z)nma{a5)kvE2rH qll@3,1D1 8X\KQ&҂JebȚ&HE(lzOOd5nRU>N9678T $hd$2pP&FZ94TZjC$Dai@M5 b֖`4<B}k.K-`Bڴhψ~[f": _HXd$=u1=,ŬhO}-o1V!糋"xAI Yq18X2ClK 9o7KR^a%P ァwDb9C= *mBEn "@$9zd8byUS&#yuFuf(๓顲ඒ)?.f k;o.oMu$;ųRPYc8狰]V*/%-`￧:vಖ9"Unɤ) g@>[81ŢɁK)vsr+HZvƶ&;DJk|ݵVRA~ B)8Ԓ!~oT1ӡ-bgV^]9ݣS nYqK2fbwܻt48&Zpx|zS$ԶY`RaR6P]|4?uiYpG0w2JJzW'3l!B8idL[%n*c:a FYJ@2OrA) &b&c[ɑ@ؔ,@=C/2>/]8$NLx`NБz=`UYPZ,2w 5w\'Q-(+UVDA8&`<Z,DZR$jog]3xL :{;`z:PXT3rPݝ:XHc]EKbw{Y?0,L|BƁ␕,:dc's3]Ǽ<˶H,BNqR[])(|OA-@=:!:Zb׻Nu_wK< |O Rg}w} -BDI ) zgBŲZ*Fю5{=>Y/Jh9 -(BpDh$ƉskWG=sȘ{i62y}m4o6ohEr ]q}pgo)„CE+4@>ߨx&=7C;dz\ k&1eN"1!X?@gI XXiwG)nw[2#ؿp̣孏_j}x+j,yTbRCxBtp=A3_Or\4.uo5Z(Rߥ%{P{c3~R^Z1Xryϋ`APfԔ; C]Z BHc9hDVݤx@]PEOMHu͗06^*%NC[x疎czrKVΣaLiG\cE&&|hW_vt ӽ~7 I砏J7 O>ߍc~t]v9LHSUgJRO}@=G;Aif[GhհɺRzLMՎ*j:$1 r( i]P mI*؞7z)1!G=+ܵp`)SAKFJYHZ6Rnۯ?h+ Ct\#M(96o?J%qoގS: ZtfOԌ)  mb%}^gr{F.um&X@`1d$7+d"L(oȂ~! 31o OՀ77^G/Gq(^rГ]aYY5jLLQ}h<8V)l͉V?jAfVn,E!dg*d5H&CH-,HykpWTk+T4~݁)WqL4ნ#  st.PPKXbSUpR=0\k!#)1^'9XmL=o+'}ޭR)/8޷~jm,8~XȔSByaH_$*aGGGa{.T~wޥxEZ(F*._I7 b=:S6n8^uƫmA Fܗ'w^' S9vtNZ%b\z[#乓Zhk?``*L{k E!Az/#G8VzepU6Zuv;%t)`3RmXZaR|KGCcY:ZS  ɪq.|!vmo$m?'hm .ՃR 9ңρS),NM:AԤ.F _/}*ϵmw)}w6Pf%0BIǂ(i|O&7)aG=cPhB=B3J$x`݂_zpK\y=XwHw q4Q˞<0ݕCD>GTb|tvR_~T{o6?!-vzͼOV-dFu @H@wZxR8c5&.Sµ֮GQ[%4"ӚJxN)%sTP6m &sHUKO~xmVLr&th\(|ׅٟeuO>DI-kףҵV$ʿ_opr؄L;p_ YP C-+vvx:XוP:'rdzZ߇ˤ@>[eQ-:>e-/A}J]qI]6F<v1!ՠ pw^*щ ]{}+h]2v1IBo٭Qz$͍m+rX}`DcvX?ۢH)6cET4wM 0SX0AJ.S 돢sgȹ]S7KEQ>* }읐=!!!N4Eg5p&H%>ޟQh ~qo3nV=NfNr7Vz(JAb=& `mzx,|aτHݞfVm=5UXΦKĉ1Ѫv\ccmKmuʩu(^fdMaha.uSTA/,ֶoU ԕahE%_ap|̑Kٸ,"O4 G" }ij90;0 n edQH{\[P%ۖlP.X^`$ᒸFc?y*#rmN^΃gN}y"M>x˜d" 2ຟ5=^I?V 8Y-mv"9솉HQiI ɱ*xtRm^FEpѺ2-+xu2yIEDŁBvP1,!Fnö~60_7w4`?D1X9*UonS8EkZ Y;8( Mzg-G_3~ɯ]Ї!̊V4Rn;HXpoOPjqWON;_$]Bl [*̫a_[IP?}U3eӱzR&\Gy0oM<]NO9ծ+RjԭV8i ^6s8paa300aBguխ*R+Ó;]`-?|^X#YTŌ{j#Ce[ͽJrn/#lj&0;4 Js_34-< ޷%H7FTgpr$=xLv!K_Ѷi?X@mzT0w P wV2ʀֵJ kOX qޒU\NsTuq D`6gHY`mz$BYK@<\~;Ox]nogt*n$-"+b( m'# Aos}Wnնf34rm'}v*{wAW/|ֶM?$[f-Ƅ ߧE@ܝrjd(緬vXZhI5$ARv]M3zh)Dk{w ~Ò)qȀam`$[- ?h_.{7I9zJb68Ә(QC|&#m-9n^a-q&DYUb< f]k.$- , babHҞA|z𽇀^S_**iaHq!]6]*Yvvtڎ nvE NT"wwkp[ U=92"Zʜ<*64Һ[B' _ceWV. +S^{,fbpd@4eң*Pu}3HQD}[J dW_y;.?PiS(B#C;HɠilùNduq{v B Fodco~"җ[rM#O4S ڌvƙIτIʭ<~֒Bρjsa,`9aRpA3^=$x/~ ³τY~UiI |c? 쭙яձȗӇM2b6JW؅Vy8yfd鹊g,4\ 5)pHǶ\`sg1:rO~x1#kJ.%FiZ"\:M2el!o}lL"n"hSF&Settꡓ:lv rqc^ ENqF ^]Wb>*9io@z%Ҥ}g,b⧷bS#jW3?7W@_е=)RAxHyOG< 7m4gº7z[} zns~b`rlK83ڥK+LUjgqooHpgB{W@lˉٱbLNP=U;`bzD=ۿc۫"Y;Z=)Cx[I4DEmp%+`:]{]'Nz [KMRpL++vcx.A# `~ci?n<#SU_L{qqHط.U|$i W*&Tvuht \Vzzwn#O^Ⱦ8`Zi\}Q>” ?a A1C' #@9`!jj8,7cg_;t7ziմeenjϚfyؖ?p_ndv`ooyvhOh\/oe5L_<-r /l𙮤)VpGA4P~K^Ѷ0]}i`@FM (d8 އ`F:Ќ8 _7X*3B- $5Y8OvUH-ȳ^+F@>=Rw`e5?+QD=EƠ-tLSo> u{^xbjy܀֖"M9@!F[>ĉ y_{E+fti9ftq;"~t݁A-pwJ0#$yv 2M7[|0S\$SG&ɵG3O!ϱб ~uc@$ ~HC5٥Re[%cBsɉkh0Z08($N!\LdslF=WlI%ӧGr`iv!R"a9~xfي֪3g/a#`)v[j祓Ńʳ~J C~ &(yX½\H!b~䙴';$Dn1 \9Sc,c#skGdAaCtPN&ML#ى 34lVެ ok{LsO VVW|Uu3u䡢*`'Øiw>fƈSOW|SԻ%=K{)ө58v9Gztƿ,N$ǃZE=8D:$>=6%*)R!LopDq2OQQ.)S"77^F%US{KɃCL6R&n@X9JuBӅq-:gPk' ʾwI,ܐ*^ݪvALJWкa[ [)2 b0HX^.(yWo&Ǣr32=W#4B+ua*}Gײ{V jrsO{zA\  Jכٍ#"dw8C-.xӨ"^0we3 5FnI|./FIm9<60m r3Ncg A=-xbƣ^l xGb\%t־d.^ެ=v89~sZϞ.Wi䃻z3k&,YBKBOLՅ4_s=345:yo}-WH8P. iQYIb PD GC1j?= 'GQ/TV|ߩG'"Ib1-k;=tppBm >H~_#{}ɂ0]2Z~ߞMz#?z3<첝xiY@H"2;֐!*~l~g{#Pמd%w߼ъ$at$2.Nix_z.enPnahMTLbf˓LepBvk󮷉uu~f=c7wkYWU.)\J%$/^L8vZOMWtauyN_]Qoj+=+g#mrJoX4tڮU;D~rL*,n*~R;=h:\Ȧ'O dw//-?r't5?չe? UGr5'3{! ;%mDٹ8N߿KZhƱ"u^#SF6S~ma>Ʈ=ZO{ogv-WLol@ aY+<j9g^pz˲UY ݈b+R*xPJ-|owhqЧ&Rt}ᘛ1B_wQ~`{tt% ,@/怲Ҙ ccӈjQ!Pey}-Pw0' wwKt#G{G=A6]_DruΧ5Ŗ:Lq,ePnjV'gRS/~ML;29Ɲ$.&0qlN,3krķohӽŁX 2ʕ7Lf,6gϥ-WyZ6GTf,ز-2Ch8hضG]Zۘ~Coɼ%ƖŌ0C{򯟧߽ ln߽ Lǽ_wɃlwSiZ==CK#VϜ- kg%b )Q zhP;ͥE mMfRm&3# #cpd#Ҙ bVn!yx\]%B:c #m4鱡f/?t3傱P - *xdINe-D-(R {7p##2ڗ}1-Do,G}YW w|\KX.gx+ge)͓v5$xpnһk0f IZ[.+n!k @ dPCi1K;lԤ_^녲Xө⹉/쏍׮x˙XԪ}ĥvK\sZX? {z/{υwv:7ʕ|{uzԹC*Șdk4'M2:.PuУƁԞrhE☱emO#_!㻩#cZ*ё{sW7vy p瑦f,2/?cD?ÝC=QT)9}\I}wwltǃiƏβ}TXnSGx̱‰/}ؔpJQ2Y-}F\ݓj! e,~7>r쐇WBsʓ#rW-%F<0)b(U!<<*_:>`j\ #_3@od,$Sk#ZE#͏J>s³{ld$Z>3/%y>3 ̙1w ԪN/{} Q_: *Cs>tو`07HItWzR\qxw`m6 ڶ߰ EevЁ0K:lG"m_NZ\JyúUTPX(}ɏJs'~Y~0;ŠsKIIC!^*]i9jTȭNGppJt3QN Kޢ2 t54#VcT!mMWqdhs]5~d|5lhz {~_ 3ޑ9ZP^"51f=g馕M9ę9SdGqF;y=ɪ ÇhQIm4 XG,vҋ_7N>{,d#Y=Tخ됇m rGBHa` :wBkB f`(׎|aE0<:g6pFҏH,,wQTytk >lvvoyS`ԱzMV<}|G\CP ռ).AnrK #V^gXez^|m;Mfʔ~ LƂ%.]AЕ]d ™BHQ(xn#lj.6&G(c!ٱiY{y'< RݪrsPv~u44D[Yg VP⹉oP|zR)>Q_ `yvb:A~x~]Sqg%/9/R=4RlEi$!Kقr$Oc]%:15f0vC ꮚbNp^Zkc %WQRyvf/ >5RiȗS]rӎhT@mѹr7Rd@ib8 +2h `=P~wԃ &>^<\aV/OLǎ;};V<V4) Aܘt}%(D̘@gָIIcӛp_:tu7XޱFZD%Aʬ4WGG,~NsK[ꌿG~>2cJi!R*R+}|N\/Ӥb!@ jtV-^C8tn֓CUO%e\yYG܋ouSDŪVyq{mQn GO}剃2ۮb@ |€ˆ0r<2fB QG(x*@PY'X0 g`v k <0X:|… "`6q Tm2~4?j42lSj_՚]Oq5eNNTm 5XKwZh@>q :gHgTUӍ"]IXgC`"bbC;_'ꪹNkj)%\F]u˥|,6WN{޲g>~#-ߘ\Di Vwm7 ۀdx5Oo HtO[@ `r0F$ k@Fsf?w!:71Z|F)!]sZS{V~rbmhwi&Nb*,C!+2`ăOe#舾D" msȀoAO?SǓv"[TtMXOf e"(ul y>w[V"`=m<#˕s,w`B)_Ϙ+dQ P8| em r 8K C`s cjqhԊWv1ȡrhꉴVf*(˅VJ]1r> A5TzjpquQA(Yj8 m lX )pmM3PR}+]ǒYD l0҂CS6jϣv&>u;rk#+ ||47? 'wWמakjMr)R t আ>@l0sV?d9.:dSkT[#[? =S 3)|۫)nf{/0hQPϠ^[}{j6<^Y}Ɠ=:P[]7; :ɫ=\u4wz֭[ 81Nʝ?Eַ$F(~:Ma['L~|Tav^ɔAu__) J)#Ý$S+;iTΎ ^L鱋lÈ%L7nb1]/?< ;a^]~2KUڍpI7[;{x,zT*0%8}L4#I%]p;490i`ա5'!l9SNZw!@z9KEطG ຝc,{w]/<}LHwMjiCHKre!ߚ#n]l7M ^ku!&[ ,@+{x0n5lPͨ.Lb+({u<rD{ `yLȩ;G3c lwTTQ`v67?P?TR.@hIo|ѾwS?n%M;7۝ޛL^LK6X5Nt5hB\*/mܸ^RV:VׁLg`hq<\aF:U~Kw=-N ۏ:M~ oo{G$a tQmH0E@BG~8-A ,Vsi8Ȑ"Y+lv"dm0VfQ 1P* @;F!*<*lI y(IցY & 7xx/z6)Ze;9vZ]M4OFBfB_wN-c2\hmvq˔|;_xanQ>$1fP)Q;+}$~o=^۳X/Cέ@Fr$h{[>˒." @̂# J8LTH\*(<7JX^;Pr\Y=;o kVV >s;}sʌku:^zK,vK>~q4qmtFjO}]ŏI*EX @ODBZ#oc\jK|%&_?{`_{eEr~ѕ7 Q޻k*<,ZH!ՙ 0$@.mWp նfMq`kȃ|ß G;^PiuZ?ȳHoS#-p(2吧% s-ꊃA$**!˻,]ahg s CKhSb'v;h"]g9k3wRfaYTb}ݣ2lUQ?ic#! þ_.^Z(&!5$ 5ko-kIR, ɢM2+MSѵV/Ea9!wg%wNf}__Z y=XoW5s׾8; ݛ,S1+<רgIв-J3bi;cUˣ7f c%,Uƃ/b'h??ᛪAlz'߁'P| hC o+IlF l蹇sbTJaZ###%,v+1>E]6Z]WMKo86evCB32] T!ʝȴCHH HB3Sv#(`DO,aJ9E LQ,p0 IbJ|)/!IC~ @&PQ:Bܜ m@hqdrE4!hREasNb2RRJRFj.NwΊn\@ŽmI=ܯHOeΐE!M(_}H4Oa].@+n5QaA=.k {4W}ɧ?|xPosAj,EU[So y(paXŤ__yDf9W _[a{9$ƺ'ɩ•{?^׾ bccvƫAך'B,txW^{Gf=(zaش?H&=?{?lȶ5] ? ~IB藮kIP:u[@dSU§gvGBo{yKJؔ"dդ}þ`KQ8y2LNsa(i.fX,҇(L("hH1S=-2$MKlYe0A8q08"Gq0@0$)eD d. ,/#AJ&"bC 0 [XGOY {rT-ԍ`.Zǝ `cm!.4h!Wq LF0Tthb495Qo.X["|s &eЗ>%k5î_$ݯ'# sHM_^j]<<k@,7h2(& (Ka#эGq(Rm{ת/?x$똶 f#X1PZ)+GA8֓Mw"؟a0nFF" &E=ʜ7Qp;lh e @W#<̜$u̺#Nph),ځAj\d,ֹ>t%^.fyX},3$&ωCTMv;[wJ5.`S>BJ7XTcNK8 z36R7n; =P ZeC 7n&@IDAT!4shCr:d} D3NeJ+W-fD1zG'RSA6EGڿNR/kM8%T CLq2瞔マ4 #f\Avq膜Q_9EtrXeO🿇.5ɓ}$AuJsD+݇ILU5tfOgId_h55ζF|] < %k&/`{7jӗ&jZjTgsyq0R4!fNҌS!L%zHyJgw8+MshdHSH룶JI^eaG,g80EiǬ7vaZ!2= KF[Vj@iB!zK9x+gCj؃^`N6 5ugcN&9L]&$XHuu5CA$̠ӯ#-PIdER(/鈴݈_UJA,1BKUسK+>ZOOvtO4zmgA90@1V1]~Qkg^Id'w ߎa 9tx+Ϯv& _ >EcKO]wWs0r~'ލɕ3|eFI%&'O̊Z iy-o+귑ዏ?,KEq`O_50qXvhY#5j ;aal\@i / 1]htA $`ɿ[3Ivx(ڝW AȢF.oN)e9!ԝȇj" ": QwIe'KBǥ2Kr-7-z04ZyZ,{m4g"r`+I!T$ԧI^)SAEp^ha;@2s 0>O%GS呢E>ch\ \955Q`0EQ 'A985 6ɥ_5yrL̯<[y Z2# (d 4mƁRz-0qճe/JS `;k!.Z8K30N;<9h8V0Q`Fap tX#GLƀvJQĸ e2CFn! LqUMyZЂ?<_ tv3ɐ5̤?u~`P?ئo|gw|PnQҷRb:cٟ0wfWOP;r)rR;hzv xIA IkKm~j!Sm$Ϝ81EAY71px,`y_ x:WG~q")W_}|ϊCCm=s<?~EaAYڏKs Zu3B~}˦}4awt=Ko !5À()} x_~-20d;]&@ X7={%^]Aqg& #?{x盏(lxiiq\FP6fc]j5R`2 =aԫ#Zti1katP!0T(d!H{3F[`)3u:3c'E^Y[z4Ax4K Q(wثU@j?M*(S}GޖѶ:)fR}"R|?3sޠhQtZRB9 f*&?LQF:*Ntw* rDO =9}J@V>ϟLobxgq˒[7'9O깸ln#τ#9r+r9h=urgd3Vj88>eƇ$^"w6@o6%¯N''1ֽR-=΍]2̓[s|d}}eb2)ց H~BȺCċmOg녕b|NA#N7$PH۱}(DQl{eoIN]'#Ѯb|r`-,YK>gEBW)k(C/pL^6JtSd~,%B(rXVh\-hJ@|6nޙ钽|W#fU.jJ:ҿq.De09w_/8C+-8b}cAƳ]r鮉7&ϑEl=ÇY4{3d!Vn?1ZşΘv4/FXe=B6D\]7~!V@.Ljw~*W _ܾ~[)AlnН ^8E8A۳4Fi)OI]G+wF /P齣?xR-f&7Vڋ"~t)Z!Spdd J6Owh4"`52)e!xy_OL{ewP{:{=u<v7. 2*H5uLaj0L/ؑC"v.GhϳSOը24ajaю.vC4dDv\O`OvC''tzmGc4hQ aR?4} E[K{ WNJLcywEP{ c"RH\O)v;x>m_Z1gKI=Rċq1X- E ou.]nܡ<4Ob{A$lfHP#I^T]j֗PU׻u?$LT>k#y}I"?p#GfO-kn ] [ajsX{(g@?'`c b&c+i߸+x{ڄPP!8%.ovK=GfLs(T`V5*n}d[(u zs܀NWI?S{G$07X j:*p`F Zpe ?,\4u;B(5|ҭɛ&˳@O_^G.Au66OEaPGO94h,9ίg"x%ډ'J!MsT6zTaj^~|ף{C<}-r`7o%{+Rl\{lK1@6U1((_ (o͙5$!Dap2D%hMwB+eڂ2?x" >^Guۓ5>smFzc?iS>82FBb` @hM2@LY @ ˰0\`l͓[ts7ѦM;mU; !Ug(G{3{2`sؖ4?^4RlZ` 0s`$c֤[kkpQ~w-oʏCp׈>^|jjF1yi±Ƀ'|V($sC.[2l(ΜyX>R^}:ɨ 5"xO܏]}uFsݪ0\Í a@fWR{a~̙hvׅo>MNbrkV2/Q S%]j'=goW*rGf?vI3̭2\[;]m"2+ݹizn{-"V&jg=]_ &SHI QUS TW,*l6cak0 G$yͻ# @E [z053[Ld M:rc43 5-Zf+QȢ!̯tNd6뼆n9wZQD 8]$}ϐބ'rU6t6kKs8y#lpm.)e00e&,jZא_+=cEda2{*! s9Ơk)$A &(>)Rl<Qg\=fzPr$gKd%V9.pX)~5$qԷ?q|zOgl^U.,}w~+"L"+6ԣDX~)xi'kyi~i"잣ɗ? aV=;2/tJV~popJe_>.n{prOݨ pC`횊ܭ.ǃRǖp~KwM#Û+pv,w{o|_{p|4V;+}Gԁ`c!c nHlX~[!YS͙NG{wD0anu#Řc1,2.w048@^bƬmR{r~d6zv7]!YX3WbAͷQ \LuKOh;v/$͹vO95oq* N/}Tnj 0sϧ nz@@u>x-.rk9$6~RTB_>>^qcPEշdvk")@]2 6,=P 3bh#ٺ8ls 96x[1 Qo[ l=hne'[x7%glO~&$Ϧ+LrXFTzP; (b9 #vo<@zɯnHH31(sbT[$z&JxIU5W% T AĪ̂ `jb ` 貋JZE ;z(V0ͳU>n_'viVzEhY25`w4C`}H+ U}9 *> u"S Fisa*BސMT7{SS^–@XDU u,5YRu'.+U*b龯=swn( 6x,Bm?u4_M/[QzXCْV(m0vcւĹyw}']Ͽ Gm`4&껭U"#,c<3|0\ wA==\^?HE4$ˆ9f9FP&PPu<#xaM?U^![.Gf/~D€t**@@NX1c*d8VV*P,[ؖQHT@O&M\E6A["eҝfvSU~e998A{2_m/-2ڙ_í2vk''8=wT_ 6j7}b?\sdJ秬gi 0{m\.Vz9VٵVĜq}%ɩ#"]gSy+fRWɱ~vg[RfϠn:s50ZYQX45 NS@AHك6֓== ZR5*L,0LǜG.Ӕs>Cf1[8Y}Cn u}p;H069XKPhFy?e`JdX`:'_H]Il@wN tg&h++|?NShd,(AӚk2ftN 3YƀڢÏ.%A7q/  MP\ TwBZVN Ÿo15R ٙ/lz8QvuŌ;GlQ!7T:7(^f`+j~ ajT٧Qd*6 H1ƂIM< 2+/ G?w=WW[o/?lm.6PbQSOng$MAW]7ks80.X~c;NvfُI SF$o. %84=zq@$ jց%_ )w#ܠ!u;hVȿ)tG];7V tkTRHyH|TOv ~[1XS cց =n<^G2rgk[ Q({Sgvjf`41 V!C3bʱ#{ '-!Auso1v^DL:>8 g'{ÙǗ~KԷDbM d@CE+4!mMfegrչpk&S9l /rVF Ԝ{~1!X+~a^6ttNﬥ?9%pjW:='Q+ VG̢.Qܪ!G,%>nX~JYhv(t/nopz*ш"^g*I~3/EšO@esb)jӲbO;SN+ %bK ݼ呮 cbi0"JST6$Iȹ=OI/=Y{C]*I[oTu/BsOR?I~z=\={`҆@Ou{@ 7gzwu˝l",X,Zq$^o~|2{JJl%9gڵŕEG2d;B JPh&&=CkCz)oZ!x)}U);{/H{  8M1*ȡq$ {ǎ}nxU fLpza;B32T;O;W0E3YK-V䷝8..;rX%apd28Rt'=en8qWe.wyb24A; cn}K/RKJpsYґSz[q5 b0 vni lq\9?"l=bm6 ]|2 WD[V_#xaξ438d\(0`ל^ط^3)Jhf!Gc5+Me}Qoașufsr Km_V *%|mCWJ qNr+{ڧw?X9 7 n J҇Y/х|bLPA..8!}"_DV{E>w.:_7gOqXij_(=oemJ>޽kkr 9e~< cmP6;y;ٱ'L^nʆ{eG %H;D m !:DXrxHGSW-1/FL+aɶ $P}Mg\q,=:ɬ_ec1K]Q%͜TVu O9u!)hp v4SZ]Yc-㏳AWq+W%8A[C`ӟrȺj#3l U(~-O; fb0vaNNoZ;A'L{3Ax #RZ#h)˄੉]S~hn~vEά" yMdck hEwA?=ؤ/wمX|<}v6!)\Zͩ*~7枋a1/`BšyU1,ꍂCښ#j˸ \R`:kIDtՑRiIi, _EEk˜ӨySD>(ak[hi8cIhFqV"5Lc@xpAL> gX2cjl}`+F&l"hE>tZjvždءN `O[9ϝ:^wh@*p$1Nژ)BB٬\ 1n6q&*(S? z?3+dps{,{ש1Qe0%qeLjL= r;ٻx@)Q3 0=7E"tNrtkV`=G 818:qe}{zN>zn Mbc̒'B~(\k`UO I  p(i )U7b ej6+ٹivrWv#-߸ۄ#Ӱ9Mo|)5ZwmY3D5 v ȋ=V~|oMRcU!A7+LWy?fX#ئk"|Ӌ6SL2> [kwsiBUA+{;<`mP'y)9{r^8oœmd-gx .҃nx[w>2j楾|* ÜA㏋-6ĨeNW\,`>JO8W&* JkMDhCe`4WgE(b"),όtdq&䰠(A1Ii 3UCysEؚ2)W;3_B/=l6-xz4=3q|~My﫫wx8CJA)BAEA)bZ#1VHb, 0h6hަcŏg.k5Vy~}(;.gD-9˜{tkwf+!dz>T$Rįwa{}>78=cJ;ǟí)}aּr:/Sڱ%$ žɕ5.SkTuOS}E˻J?u_mEEb.]9vP8y9NpAۮW y~;>#M] NzG eZfY JyyrH^mU #! Cg:! d ۰{% ypG&L픇NSKkmNSr@P1 [Ѡr馫PHE9ۙf.?u#x G4u }ձMHo43/PaMtIB.ZVās#?`ɬs[>JN2s҇9EDDFZ ;cobR x?6(JL-Pk[2 %HI&&jDNٙfoE4opI&xӍd5H؇=XhؕEb=K ֱ[4ayw/sve~}rO>|x3\&ZK+;}>#i*hF E+Ҡ.oFN]6xJV^\$>@Hk6!dXk=w[" I0 y\ lP2mvXTI",^9?w;+ZǙxY/{lՀ*Iw}+MT.1H"7q (dR xlt~qywk۱1&vLR˸&5ʖQ:* G Дr6>8hln"J{){sP_}=ovOh:6(UmS>-MiCLg1/|R`|!}2 H3.5RֶüA8F/܋ǿKډW W< ,0.܋=kU k*vBg?Ȧ&&k*ٌHhʥгR/ 16|h/Z2:NKxƷBC 9i36}|N{T.G'2_F 4(ЈD؀'jAQ:皠G,Ṣqgzn):#-Ϣ'^KW@@YLI (@7@h.EM(@2KjzTڐ ?RMH93f !Au6i6 [PW rd잱P_ɩ$nV&6j]w_7<ݸ-"a -Ǒr`"eFXk=Al4D9ܳ=bWcv.1U0j+}:} > PzP%cǪi,X@'F- y% Z| !QX)( kHWXH #H(2>PQ9j8G z sl9cMRw`d3P1$ ? A>J=ĂhN/ T@6IH C>!TA@<) 0h2 % &bZfWA%u%= K dCV`pA7tPrیEYuH ڀɜH=EGO<Φ5=*ك3r]=,2J`sy`0*Z4-Bȅh$*iRiNE>#`!3_6lGfXM4kY\sVʥ+Nw.E&2jXJ17E@EbV4Iu*JZ{L' hPCk)DfbdBzzCQT1@ ) E OaeZFKy p5Cl@},^" .~X W-#iQSxۊ$sp>bFM8PV-JPQ3&.EB-E^j{xu KUR~ozBIXĶ-ضCu`^y;.GTgՁ*s:@B `dyoLLtBO^\hTNn[̳ֈo"rK K)J&HDTuo]B`b`Phރv?reHiZH7V'#Z#uliDNA¦FO+=@(Q36N +Pﵮn@Q>ea.䮲%̏[Ų!Әi;Af8V (z-)wL)H% OKHPl:MQ})q)PPX) SiHgz @97j^:gagN5݉ؽvҸDiRH$7PD meVYtq-knvzDd z^F J@/2;EO<{xld5 [w+hES(mCQwmǏfxq.}ZӦWi6S/D?([7`ˡ(B }eL pZ e|lǵ9h)V &n,yx/TRG/iP' _`%)yͭP~(!T9(إKMWĉ¸~dW%c)NzoKm'bLpBlo(i8ݲM3$@NK #iG#0$)*Z;(GDe!,8yXɭu)!rA(PM={1B 7I&]U0iV[ h6 Dc@jܼop =Sw1j&G^: [?-[޻W6X'Nd@`X\q W84Nc{?I 99c}^Q[qJ1G-"j Xt>.j IO8$ ꑚhcO7_6͐~xY~0#9287Rqb~h;)W'N٫+a1CGvOˏM$</v{.O稉Q2GAnYlsǞj\")1ⷅʎG *[ irLݶ_ӡi#de!=^g%2υy-Zqfw#7ԘWymr{jp-ykC0ex R[0/:&'_9o4zHoIwĿ$7u|[זgH  2(|Tk6F!@7n񔃧۫V -|8EMGDZljM{e΀6ж:@2>j{9pyxڳl{7)HC ޛ `T>10;xRx 1ʹ̲Fxf/[?*n?P4pv {~^n[$*Uevx J{bƣ 3x4z߾Ͼ=@IB8MR1*` ãL9,H/G9($mb@U%Du^~<a/ˑ((jޟ&RUjz$S>L;Y8pd*֗j!GmV."tѽczo;Y}d$ LXuAE^8,2(7^/27`2!=FIA}FX** @JUdy|TV@'c9HBZ+eKVrssm TlqF p@,M>,R(q D6, $s`<7_X& ȞC}Cik <xӹq@(c!A`FnUS߀~٣SC1z@lL.`z!1 #7="67je*_n[+)󀁡 BCF?qb?Bx Č՚7n?358ڂQΠ0Oeߦ8D14J*۷#Za[0f`cۍ.ĺ-I;m&W-b8X.ܐ%G?w?xy>5>\s1$LSp  d:ɠspù-q_YRxXSQB"sOs]4cs,ׁMC;rh眬Yk6iX8!+,;Yq;L'* q-?x?j-?;[K3#yDy(Qg,{h'?ˑ YQɀg8L1 ~9q|4kTƝKQYSL;v)SǁHPcB@hH vԷfT;ju)AZLe6wo>tf@QF"LٴMp#ڵ4PF89N&@AUnQzω5ϩ̲#]˨1hw^>5!7(x94BMps@~;R9j`x sƃ"lnbc^ϹSgG9 q?*u!`t 7m&f&Vx*4:M٩V́9VJUN*c/Nl {in>pW]{ Sչ|Mg[|aN,Dq!0x11>Y3vjVbauNqt|{:oЀlDֿ6Ri M9 >ZB-Cr ր: ` 'P;k)ag@hbpuwpϙk-B k1B }r#7 i\, !8\+36c^7)w*D u)k+GXqb3S%LxZzw<Ʌ`o]H}a мCZ62 -ُۛ,A)b%Ě3/#.y^!ùUC 8ouƷP4/5~ZO4J03Y8$@ϑu ODY>i"\~Hʇڣ;w0@ee@e7*NrA_iC㌡h4<ү5\!~jHpz?/ف}U?:3;x*%1T>|@Ps!BUg*|ˆd&KX>yϊh i[fc\ Zטehq:u<&J>>"!]4WXF%)ň2k|K?TZ[hVfUy3b 8d6 } we(';طh IuF֌)%o]/f{RTSof\*W\%HlaЁBJM3f`,ћF֠G]kix3H{7XF92a+}؂ D}+AU<~&PK:a:h== bt=Kk5ߕ_?+^_W7,vuJ bhcGUӛ%ݴHZs-\ `8u{~᫚8<C_DBN b@_,&dAK,uzCqMkbN>J:=^C幁pgٖ5a]<˶U%AY$!@N@s P sFX0P+TDKB;B`4K8j,,PX.ux% W㵯Ϳ G+ Bv\^p#d-Љy숚W)C9Q#M'7Ueb}`'Q9u!ٸd_9S툿r&gM3`'~1U[oGzY+ jTVhE!we MI! ZtBb=*c%7<1-9/ ϸgiK'olljcV޲cI`€kK\1:W״Sa$o"~~s`1[ci*!hgyGu<\[2w~wQ@^ @%ZJyb\M tɱg".n%ݢv3jX5-\i3aeB+FMљ魺&+aѬ/YtP'<"޾UT^2 M)$i0Bn c;]!f=+ +LJȴ\g';96J'_"C#J佫 RGhT#A\He}]/wjM7ny;<fGL~\ n8GMLr1 ȨdIwwƟ ϘrQ,#pWjx]p@a(M.=_?>:؞ʫ{}hv[S)Ʉsd # M).FvO'DK׆;(BMg7̜_uQe&C,_wcp1ykIlźC,>L=*9^)q BPEouHJ>i8Q!}cUg4y@齭=k50{*<3⎺s٘u/$0yj0,mU6a2eBYO`H052-i!0K8$Y!(ԥNH8VIɥ=RXz-FR6c%7f2K( `ӊG?»P/|حko4֝zu{ l ota(ْC1} &*y*5"ȓ"tZTc3#s땻7=})Nnb-cOWdEkΠ_'p"|BB#Ix$\LԄ?8y 8gǀlZYC Spa;tpd#\<:w?,gWag^ _G~ˤozd@E9Bf\:D=(XLXsEQ3I(t 06 l dƱiBz¥OGBZOE:Vؠ|ÙfʓG*|ξ04 4l:^%BnWXhNU"'|ܪrm;J|'AwOlMgҀi-ܦzo˲߅O{_xn_]L8s@vђT%\DJFs#uQuG]-Oj_,ߵ3ZۤaׯWMq3{!8\eͼ<2jMG9O?b*'ԞV/S*VK HHo2Ғi1Jʜs&(PŶWyLdÖ_Ez`{bPɅCyګ|g^d E M WӞ݅GxhD{FKZ/AmC;S1.JF{iWOxTToH5_N߻n6HthZCvlaУ,萀) 拒9܅\E|W@G!5Z.$ HVsF*SAa l zr+3k[%E'ckyIK> U)k>D5(=i˔vpǸҦ aSF^Ih*/3E@X:=tZfh7 ,l0\~D񱀝5>HQ?GnGGN^16vV;.€8G,C+迓 ǘ/xڀI>Z/>n91}mp4EFl U@WmMx^#[-$՘wS}Wdd^|Cy%87Hۻqkykt3qvPvSO<;S kBqerpDŽ2J qCzUG*V'[9'Sb`]>m,9Cd*4P0"eT{ڋ+5w8}h7jaJ |r5sȱconFLIǵ;ٓ [Lsڭ81MPc Ȯ/O׏W- wΰq\m~ᦢҕK}zWynoCT5_~ !2*9sV ݡuP7g nv5 @M(ʖMҵ(2 e!K7Ahϧ~?ockfE "e& VKigC7f]X`1!:v{XXK$D#^;[kɌ=Uz0V^e8ҭ^/מ^{Ӈ#_- \Haj"_c薌``X@ĕ 40aVq)jum x۹bW Ks}+GNᢙ,OL |o-U ;rzK7mx'׶WoWﰜ=ϋkԇީÍ^MȎU;i7{DpߞNQ{[)-pΨ6+˙`ӐSB r 2>z잮nԍGϋ:+[+8喼PFk.q] X+w݄?*^> -(``I|PKt󏝸 {롊_XF9O4 !wb}nHׄX\]ӑ|d <} SȥUeտ]?/MM7c1 K;|ӭa8$FJ.*?Zj/{:֬Hd摎IŹ-_p:Z[]$ s4Zݮ λ+SFhmzƫ9bNDjԮrj9\1Dh,<|"k,x>uIo9 _S@cd<4UgO \TdS[;TNn7[0llZz&(H#l>Q]`G=i_v>>yϑÓaNG> ey+ rx5S)_uYIY`>=UÅO"S7FCj>%j VO]fZQ%V"/߶G9E|K]gεz> hTgcdҶ<6;KŴe$ߪծ[8]+^bWfke-f*?GeyU]3?2E\s'7)7@a˹㍮x["-ICWZ3+'Я}dP8C90CUv^ud'=VbV# jT0 @rކcHe,G,ޒPg[zQg ACҜ)qAj?M+&OG?M~;B1tK_>~OV7lZGDo ŃMYV)*c Iax=Mj#]/Oˋi0W'#cܯ {e,^x}$R!Xy^;=b}(%]IK;AA_o:OTjE<s?WM 3\~W1AV6lq!2a1ݤUy~Vy1kX\C"=t>9xxխm!,.XNsH* W9‘? v~.*`;fCFdA1* NvЎnp`t #!f)Cl3̋qu"Ya℘ ˪_k=&?5o7#y䂔ђ Qp2˲L Zu5Ww/Ҷp#@voQ(BIyZW# ; sў{9D\vB"C{OPYZ%fܠr&_֓AB|-/崡$&B@n2Z$"c f:23)[Hu>}xǬp_#+YeQdZ 9(n]~zS^6jRyZzN 𫮸܊!9Ahkǫvm5 A&%?4d=^2D ZV9o#`#eS!PQt;6T;cn8Z4`l\/mժnU:LiʙH_X6Fb`4 5U#"t3/{kw?~7 i B Y(Uv<U' WXv@6v-@XM`h0p[(AM7IuƘ,6" pGQ}'ߺpdVA V|wwYimRyk>) r/H>{w땬CUw/huO`9P$-;1~t84^6zlcz~Q1Pq؋҇5/nL=[eŽ~몜2bcݴJQVw݋O}YtR5(f%-~@ޯ;cO\G\tרE&`N*&5x-I絣Q U8P Ps΃4^ 7(QS߽ŭ)@6kM" F}?wEEmYq!S_阹-Y`ex P[`ur}&r ~ lQJyn Blc}b]})o7ێv+~a>62`y8UD в<.[5}x<޼_b5.=ad|lIvv4o~> I]{e 76/86zQms8 lҺ,]QA:.y!QLl{B\0sQ-;!=y 'x:mv!0eW7n?Xk*%\*)1v(;׻gSɸ ; #u1r^So~zѵ'4- "ǎ֔P?6woURoJt ؋ux,!u_\؁1s%m5÷.) fl xӕbK1g:T)%7ޱ˟Cu:5g@Z>WIA_>XB ˕EJ:!iwl"[bɓFt4WW~QXq:$VAAfAߏxO2]76b5],X7W>pOS 2k'՚3 &)+9=6 Tv~vssflwY}_eiC%7&C? '-mo}_Sm ^[Ol6~ο>c9KE3mRq[<=V 2bb,!Iz7H[} Im/S㻃S3Xu@rB-G2r KGj C)kJTU,'ψa/ÇuEԕrx1 ?]VBRZȧuIqjS7m@ГΩi:G[K%$6.ʼ0LFyO6Gc'wgϷQcn_n 8 l^JgΖ g[gG/i}x9L{cHrkk] z>]J?xn3,mӨ=_q[0S57 Ɨ_tZT/Ukfɦ}"p@/ʼ]:iW>Rn'eXJsQɐ08{Qug_~n|hr=v<<0% mmS[w2gk,C %m|XR-'mh׿^[qtTIEގ[W1rQ(4 dW9'dI)EZ4H &)JZ,c~X]K/ʾ9߈ijBdLyy=y/Ik;\۸q+}vV>Ga/Xn 1r`@eUrϋ Q݌K Pyevǎ6KO%W8.}Qf;ŷo4 ~.Ailvw{^~yhv߼ɣbv&YKϤ{icQwcg9›W^U_>^﬛V\BT, b[4|1;#1RL8CF&ՠf55n֐rnVi##lX&O68m^1mtD%u4Mxn~p4˼vNJҘCLܺM/7=,5LQUMY$09)[:'2 j%hƁ6Ig~>RN80sBD~EL<϶Doy&柼@ _mP\2`n8w=ڼ90naIü2APF3a^9iI- ?5쾂c`3i!shDȖ-`'52]=VC976Ht]`鷟һjvr#up4V~%)ܞP>>L~q92,̯n'׎?ER?ea|R.&I,0|4ɶ{Wo*ocSN:jP"Y>K?~t޻O?>'@ڂmarsOM4FF%hkǫ5FՕQ֠. kRg?T:@ H!;\6#݂?y~xk̷ `/D{3V2jVw$%.LRO&}< /~cb0QIu$sOѻM)vry-)apɁ^ӥ,-Wq^;7Noj;6x&iWk5~NZ%p㑋=֭ *竽#u>q^ς?PZe,̌4)#0V#&NUH!h{cR~h1p͍lo~[-I䝁\v>> Gv=(+c` ԏ5*%&PWJFR?g=f:=K'4eK͆Pt~ECLi4ЕFaǁ&Oc)NZYN!qa*W2e}tldi:I1Uy=`|F >Q۽s'.Ȩ?jO j&&wN_8d 7ζ@d~AYQ;> H׹Ul{0n]Ln-pȚe 9 C⑍s">GPQOhn|LZ1Db;kU]+cJkz荃Tzʒ3GTv$TS(پRy9?`y b̸ 7]zZrjiMawW VOR- V:)(\B<ѝM)f\WqN}é!l"/P_'JΤ'ƏYZ@]G3N(4E6s +,,~O-O/iwo/Z)BEiֻJ!35( wTɴlrfH A!g1=G?5g2nB)*sMkoSVfg yy_J8'^[w6؀tBP&C-p+O; AJMI,ogE0UQ:3y, lʃ؁;ˢ"#ȝpWb&G FnvڋWb[tn!:8罻k~Ƴ[e|#KppSXJ92EBJQ[O3{l(r]zP }veNU4[,%^t,Fr+bۮl!yST\~t?3Š1'`{K{FuSh?b2 IDAT,Һo/;tr"=4<6=Կ'èF[aݘl+nvC6OLV.b  , (Cy S&E3+|%9cġ׎WOϐSaqƧ{É oZP$A҂PX ovo>.3_ Ww+7o^G;X|o$ȄQoml{:c؈)|efIR}xC;'WEB%v=dG߮4GW8TNCsZހR9X2-4[t? nI ~_\| 3oxu KWD 2b ;`wUt8䝿˶B{j*ʂgtEZ+Kdž [EM..x||eqy6<ՕpNw᮸ےf `#_o%+ExAv`vq.[yD>jo^,n5_ B9Z;G9kҞ}6*ٯ< = d~K^lェ5v{ 3?pX{G=idzIF9v治: v/1n@!rRbR@}H- 8Y椁NOzMJ.}/lvLcXkŮ(%,f9GGz4esi0u$kùrzZUz=]YKxOAg 3YMB`xYE]JaVZU J93I {ppijU?N߹A0g|‘J3.(?2-E槫Amlm~rƳu.mղ|fTv׋8<5cA4)Šl"Ζ~YZz7 <33YY}Z²Er J|ebjl.vjK]kA#ob%1Cð Z3pS!`A< R#LډU{ޕ{2LEV"|Z\5U43>}]=[6VF~aDek'x?k<t¨ݞt{l^ V.28!~t뉊(Xv,$$ۍ<ɌSIX1p44"?[zc _7[D%rǥ m0\xė`] +&Un@;+H \q9l,((Tv/29qe( uksm|]=:PWGP&r;v5w^6OOyVX;Op4ZM>gB}|, 'YzLDʳcMKBhַՕ暚C;B'΢[\^;%5+ƪ?Fq+G𱾸_Ǿbw2^=*k]_d EU(~%(r%]2Uchݻ)7n<.+Va%):I,xP3I_Ei,bohs܆.thVCB_?'o6M~y1`:RFo$1V9{dZ é~3jr T纛fanI]еP|",tvʕ`2K3Ϋ#Cd*P[4RGDQoZߊLS5\y-N! .tv)7yEFYr X4 4qL3)-KnYO9Sr:(デ_%3}]筭@ãb ey(:,*ﴒzEMI\*ѽW6ƇDs \xȯ=ks'.*ܦLG߿N&ӧOлs&˄v_yn'//ooJËwZm9A>?޾T:wW.o~&GOR6sWsQw PmnӷoLFl J]ء9_wNjH㏟JCmn:GM2[bt YӒ%r`L1ȱE{Οyph S9:i2ՃBwO0~2ǢFĂCgi0 RcA8ݠui9:Φ :SHzŒhyU)_|;. U^  jSv"H Ǝ1t8L:+,^@Jan@l Xsk9Pz"Ɩ%(JyJYGN8~)U [$,b![/*EI*RtD;N3h,DjQa5)e&ȥwkCoO.OvٵH|4[C&D\~m8@/fPT;;WJ-%i<~v_/ĄP$}>e~y|\YgNH:ί]:_'7ewپy٨$~nIkB(85옩-9-7mZ~R[S+^!QTZ:O+ -=39H'0ki>!f|]uuvqMB|ZiU^w!3<*sBܫVrtD;03T=6V]]HN·+jO1u;?AZ B fLa[ #lYOi' p@Hbo/ޔkC^Z'K_=A?ڿ{sn|ag>g55S'sBL49jb+ikiX b8$("E [f6A0]<0K䍲P!<*)Rg`O>R,(H S'3ZS POFUVG9#O3Qa/[BP Wl4$d>"q.qQfnr oΙtķA4#q{Qw:JWOϢw ߨ]{>NܑFzrom#˽lcEo 9cl:[=Eĕ5h$@K7;ղfGhHL}U}b{z|F-MYz:7_ܜ2 io?O>k?Pe2U>'JYmVoyt/DLKں0H4[PTcT4w;G 0(8VljߒO>

    z.O5Dǚ؄bh+佰Vo>TԀ2 ygt4wFj>~3zWa`C9wvmT-1׊p$s ׇls _|JneQLL?S&WnΪUm G:6Lp=h rd-VQ t2 TSs4W;'*Cد~/>>[d'5B3+hI7֙A'HϱXB!(h2 T.CxRrthtVMOYcTH5^ Tya2h4jvy`p`fGXbW>Q~>%2'OȴF'| F߸MQceq曨;`$܂x &)b>؂M\ |R +nvCu"ʮPhd-3q5s@|ܣtŠ硲s2LN Ly™dlcz} -c'GgPaTkNR11'^UƁU1$LO 7_zˆ<5޼ `п,o'Ó?Y4? 47>a̓LL]]MjX-^ c11;{l˒[jbʢd8yn{ l6ۋJ2r= hYpP(2R8L,,@j .5 0y[$']ܜ>V_[Wo>dizxx<#T.O ^ )6v&{ːj YP04.c`Sͩp# gm{~K Ӳ3mF‰q31\~>].w 4Ȍ%L8cX92yνq ξ1vBnC-0[Z86$X:8'bTF.9x')C70&jP*MY%9[8WJVNIYI`$nbTqVZk<z靆gN{N#&%Orl0%xT"lAaܰA0gq{@XU~UnXï?}7_׆zrV6>vLev9={Gh9vS立eį_7ނl Y&,IAh4I(v˫R٨FG2_k)uDe!xJ$s٬YJg襋z4^}f᳣/k@XҿOnnXV1/s_t)S Lm8BABu)!j̷`ں)[o>mf$'9.[&^k!J%_3p8-{+QZ݇w+^wŕ͔S- !hբ3|v=b/deZzWQN5iđe se'6V8U|xV]u]b>:QFhS2D&%K˜0?C]ny2tTbv%R}h UrCkխq1|q3\o#6i,}{Sb`>Yp^^Riod}ғ#}=+3͙vNo.&޸w?ޙמ<ꥸ\8d^ Q'>"'0&. t\ʍ b%F8BdiE컸}>=w7>[8_:lX?|@>K9CHpԬPh"|A+#Hn)tC@)} $A8xpR4 m1co!2 q`mR2v~RR{V߾)kQG3 ֙󉕜9h?*I%u^Qn$Zۘg f>68`szu}Z$M`^N1 b 0 aԓPBu"Đ\c[Z>r' ʡ;@Imu d*Ўgz坹,r(.D@XQb6x㾴7R*ɯDssLPfB9V+XD4 KOn{߲s܌`sΘPPCH?&ڱh^nms:]Gc}MHjZOOshLᬸfmxN+ Q%&9az7#IOitc9#1kpzc; q4Dzl ស:ٵt[FQ0׊|[ ӿḪ߹)RTk&*}=~] G5$R̈sNoY8eP&B0<%e_>,Z$ݝj &\o pn/ |Twi% /R&ܧ!y"ipBG4U#p[,ztEhj-0_{(} :g,[4"9E,Ǝ\ Vi Z5+*!AJ3`W㣐FǿR(S`K,iILG<؊S5*L4΋0tIQK/Fz법nR81h'u5$xPrƽLmhp34Td8CނS\|s> AW,`(' jC/ΧDŽDM߰,{F1^ڛyE.}~qCd j.]8׶U(탓("M `3=)=Oq^8kqW2l+ `*:9(m`+{/};{zgFW*OЧ;'=yv'P)8P0G!(Ԟj\4d^+V.zT5{o`)Qr@c+ ɹ2]Z[3w-y}{ yyaS6"r]Cw9X7˷ZKQLs[EljDAW80_y2_OBǵްvu@f:p 69p5$Aєj$I+HC"}Wou 'ȱ(UUp:uԍF76 !h#=k:>MQ<,5yiBF=m4U+=SdI_+ Q~#*An| 3RFxЋj o:ܱBEnRӋ܉7/4/v<7:"۳gw{Nj_ =ɓE*=?O,U+5-jsp?r5 5u~fIpʨaFtHXۓoDdTMu2spM$7Zʖc>z{2xnazᅓlj"Yy[!c̊>)7b4<(lFwR7O>4[ c}9drXcqWe%k1%g}q?͚&` `Y{{9|4'垲]/owڡnP>|{F;{l9mwYn{9X ׀u9g(O|/<_Uߙ9D#ܜ7+y= ~- -lKўSvD:#l0o2G4]gQٹ·R[_2eEXRȄe Oh/Ad6?dSH[kQ}&)qy-~%x c;_1lMn:^;G̠ƦwDK?ukKS) =4}=;P}{Ǔ{7L6)?r:o1,v{v)Љoh\4lKctH.=K`0;G}NUi_?PZYN>_>ݽ":TT}n[mB /N1Sx$zb)tqԳJɠP#{8 mV GY VEbXY }֛gY9 g% g2Gz q`o2z`oB${yU;;WuN*+RARj-19׿DyS4sQ)zL)CȾ ;˟nz|~lLV|/̪탇Wlosmd`l4966$A49c\aB0J./d$!8d"sx 3ٶ̛c'ʾR:;wGqdaV2K>v4X+iUGJځ҉'jkd|)vc|gYnx~ezsuu索 ܜQ09c4.I㥓jRB5FN8>u Cq-A^i< Д!ݪvn64=)<#sJ3Zg\pk+ƎO/̝#͎W:Լ/-gWN Zё3^ cj,íмwIVk[ݩL(F*찞8h9?⫮0 ՌJ=zدqcq}]6k.^p( RLb-J6N~g=z%s鳏n7V5q*6f ^7yJf iSVFx6sGwh zz3E>ܼ}u&m<_}8x\v_xluJlYi2C΅:q$a4HYB>'!D0`/:h81:'r m }Rip*ӫrC(@)u- 'qFF3=J [[#gpAKzGʭ|6ڿZG@N', -.Hw; q5әJhXZ@$Ͷy WŅڿFz`wW_m(e0%X9ZCy븂 [Πo̒PjsD%$ǂܫחgq"4j[]]lш&*~IM ]1C[H-TwWRl]SؾJ[Q˷sL[88VVbH1XpҺEǬ@l2'lԎO?X"v <bi}2UȟUD-VG\_}ln#MG⤑Byd:g6&+3ŇN " 7*JVs>[\:-U:] 'm ;Cô/X!˧!ôӀ{!yw+|f>+2l aPT"GOT`B ;tβ/_85ԟ>Y xo]Y4N}ͅZη*fWWR yƋR</MBn4|=Svt6VK6?Q-5g{2Azv,KxƎD>YT{9uڡZ/iG=BrskB>>,( kQ?`|fShYFCE'3 hMw*4-POLd;ܰQ lac}_&_pc MHG8+{Ǩ9, v"QwT+GEUFQً~{~S.nc Ep;&F>PU[YFpG.{WJǜMPK˵nhT5 J&}>,pl{ Gm8HL = ]0ʸ>e+E:go cT%B|W/e%>b]į!ZZVsZbΏֿL]m!Łmv5Dv%l1C;UHZgeض@fbb?-OLLQ⚙rGwvUzKnhI*K3'wCdP\Y[1 Ȼ,^QA/ޅ!}x#h7Q$VxuPZ0ˋ+֬=Q{_I@tES9a)G:U\*+c aX=a6P쟴RMTaTQZ]Ij-snxЩ G ;p.ГQYc<6%$圑}|zl'Fc<´ DQŠ)LoW祈;ݫ{j?팞 ,{Gae~ -Te{!#(W hbC@ƬE'>%O{rΡ:ȥ9 T|iv%,TYZ:3Tͧss)_EMtk ɠK𔹼鶷ȴVIhj%7ǼOM*I*(L˱ YRCOKr:߈I0M!J Bw/GG;1碑)-rM3F>ﯪҌk?U^=MFZU`F)r F}qP6cHo`jYHfݍ3GOyzvʐ,U%pSH-s"jg/.t hZ b1a36^n,U; GđVܰ(̛ԂU[F /~pS(9,Ϯo>t{q8}Q sTssFv/uEQ}`hдGnP'Tk YuLsi֖=}Z YS%O{1dWjRVUHA`"H^/u Sj&i}O*${}ܪ?wᛠғ{Ǐ鷗x T l4Vvw>I1QQ%.'> pi- x"&:vɹ10z5}a53{݆Jc-Fl^F猰`TA[gXuO]*qySq3⊪Ȱ.Un2M>!fZ฾{n~S!#қ6C]|z2]Lv}~'*x~>n4`,L@yXt&:(AqL{!߰x AŻY~1D+"|ړVMo}_[cx[Jf+Xeua0-!U+&.'ry>Ϝs]}R빰uwK_g/[ =4F^|3K{'1L7fUC5*ip@(n)Hq.>哪wPƚ,HW۝wFze&N]}yeݗ&a}="hٞ;TKv=^Tbv>R?PX0 jQaǝcxS2 _r>rnl9Mb=JzNXNYE}p0`$/Vi`M 0z;0_~Ie0Ec N h- IjʼnadwNƌ.Sxz_k?,;idX ihM'[;kW"+f"9o(N`i2mȺ6m06lล5ashO27ûƆVDAXl~9qtנb6'zr^sۺzNX]w{,@nO/Woj-L*:ӂ\ĹjU#y~-UО6,K8[mY` `' IHiJ{=FQZ$M TIkVT _VwŢODp6bN <}uluJ kz#բ;[]L>H T&})V<fzqU6_PZ,!4!B _}"7.ײ@G&G7e)49D;Hh:#޶l[WCM7-Dy](FsK?tlwO޳`-|Y}4 54!Xltwxddzd(߄ԉWUzLv;^5Cֶ;f11T?M =dy|~Yz?_p*{ G/XTooJ1J|wUܸ8 аc֑>^Ў\u=1XUflRPN!j mAm/e;ej<-I6=/>Dr{}#u tjUcw~1 gݢ>pDW?oy?p~xĨ$PhmK+ҝ` %~qYKFnȳ}J 6g4v:xҜYl`#ntS]k\PD,afC`4S()Jcm!8,?þ֩b_f`Re]}{&N{pupʼnDYZ3(I f-7C$E4 ̬!V7FaS3*x/JN(RvsuB[ ̦%4J mЙlVj_߷ iwnK>0Gڅru|nn0.GB2*׎>b<3:Ek |IE8׸H_`scPDTnIP!<[CQ6Ҫp nȹ*{ɼA jB!$5f<>v1 ;ՕnT=w00 /"V8#$Fؽ")L-0'qJ!ØX zȎ2[Qx&C&8E7T,a):lcx69^U[\״b4E6…g^a)^dʫ^C]cYQx4o?Duy?v,ܷڞ':{֦? [5rX XL3\گ߻_WeՅqW4m^TH!JE^&v $0]̪r?q,Օ8k raG0 cE%j-souۑ~K r}{D`za okmҎFprV ㍖wF=޹"9e;4Z<||)O mL "X!& ֜hl=R wS^&coܯSFAyhOD|lXl`/U68*j=[L2e!lz.`E\?X:~b{Ӎ72m;۵;Qո޺Fa0J*ն.$f#D=IDZ?Rh ?,8]&++8@Еud²ĝ;I»h@v (4(B/<ӳj:[xq]mDԡ>iL%,ɁC A(:y}vCsm=I3QR {5;qurl$WoKMC,H({m3t£[ӝC9OvBd݃8` G<:5-rsH#lՠ%Nn.rXcd𼭢$IKo9#手Y<O?m^ipHQoI٫ve~'cp» N H䞓NqB ( xa&׸4$sZm +EJY7S` cPcGⲩ:osWnݫwse#SV"o^PR2 ka&GΤER4p֍JٳxwxUĈ=X009c4v8аTLVQP;XeÐN/KT 9,s4AN;T Um|TSOi-P!vS-k$4+  nTJP5v]/.-+}1Q[#GG0Qgg^À1M ,@&mEx/Ήe(Lxdi uHPҵA&Ȝ%|ZB\iD(1Ըl*`[bXv=F{@ /_/U덝' $î]#vj1#XkҏQ=FO1G|8ʶ='RrsEg7`in!^/xSO<.Yem01p/#ʍ>^doC74ZV&ߞ{f ];r|ڦ(s=:,&V (}{싚qfŏJރIV˻=' EA*HݘվR ./hnm`G]ID(2հ1;JG9cayo@LzyVm; KOh*HP2 ߟ6-3ud@wY'7| M~u=EZ: J: T,Lix@ 2VKJՉ%&.5oJp2O:CCWd{3czj/]+᱓@raʹ89h!u/*OKY&E M{NN PwO>i;sV}ظ/D'hsv +, i^'U8IŖ*^rZ81r 4nTd~-c,BFqETS:_/lh $F&'7A|j/ h$վS>{o._] $Iky>-oy |~K;̫L\'2E .qZ3)MP9UV#|N?Orsae-Mv9f&I-y%uO={X}zYVdڐ߳tY61Ag;,lXLZr(bǒ-ӭjT#|.k+3(mM,>]߿=ybAD3"94Vr|ʏo$Nܺ h,ԳeioTto*]vUAk5)K:<"+aςuWnfS@,9dsU@HU*yc,i??_;pgFT'K|,NQ,oߴ-2uC5R)ǥXv~Y"`HáS:*tXZҞ;rgd?̫]{>}tjt0(̴uiR> 4җ4)}YWeksYG .C#D6Hl1}͘"þ?t^0~jB[YbSÿ=͛ݜH9y6Gvو?>{:r'񠵴\x&HQu`U|]@77Fc *n1`bY#]O5Onۺ~@:^#{)mᠲ':\`wiHS)5mSGJBd&F,o*ciwAohF{o^ eͺh̺[01X6 (4 SNR Az%yc=ZWSQ8 #}eVk޹.>_m,7;X6?=J񊋮-w= P4Dcywn~T=2s[戯Yn`;(26)0au/ @S#7t 9urXjPҢ;4B%,2?jjwmit};}?ٶ ebe{67^nIXN]ޢ;n+-YgRsϟÕU\;iQe;D(u"{Q( V~i6-vDP2 ˫.|pC+sO9 y!h mEX9sHi|uՌcys@;Vm;`'HW|9ɴN=>P_,Z]n{(kHD]dGd)Z.7li)jv ~)t(͜*dEj 9al{X5:Eĭz0kk>j$V_gӞGA;g k,n J QgͲC*wW@"o#;9h.Es'mGC#NF_7ZY)aq(ݒYZ P0:ňba}Z""7S:Qh]Ya`hάOٕnn&-X6>pe'X\x2; ~_MqjI_Sle:U N]Cvmoɛe~hRh&g:zVo%j77uKɽ\S+3 SohX{xl^n$|1!oמؼ-XI3v YhK7Mpxu(izLFiU>zFi`NbS(̯R ,f%MT9e瘿Ke::sifǨ9"Eh`[1 #QPÎ$ulڌZ}/eFiY |Oܻ'gȰ׎|50%~rG]zP:4R%p9@![aA>i%3W!fZ'b^ҡMρbs&pni\Y>bnXA~t;:dP`A#,@6KCLR#g_ #+tlQPkD6{"l`v)6錢z' X#[Hz kV.20W/lep(XY˪AgWx2x^$ Ϡ#d X CeG,⮲#k vE)d*NnX/ 2.t[x۳Y}_qzaK ZP[n6S4m-kh{Q6 M@5c~XߤZyo;l6JZ81pdH) ^7*{UL>_tHJd_\>/,2BqGҼ{rv >\7kbGYKrjjMN"cxwVVrڿ|f.<y] -[f{:Cp͕XvB1`P;g m`z43-yIcz4,Z[g4RyGo49Z7qLSaY2J-oO5rl*to;3cݍ\>if#* vB̉:p=HQaJ5^(EK/ֿm0Y3 !1AH!k;/]VB"n4V` 0_=xmˑ bJ ΅s.@U!{`^ᠪW$J OX)145!2/4c]qW[Qrzz`Pj˴Ճd[X" 0iKL!Gڣ.bP[؂#8T R|hDm mێùmi 91~ Q+=ZY CY:Ip0;h/sGDpg QtLb=y;s#; =lǍ gNCۄk+ xm&1E7ۆ Ok75ʤ=.mg "!P8tg؎w 㨲#چ=֝QלP8[/77fny'Q&uG ݆FAl.*]/joz򒒷Ac8qi%S>)u[NY r(#t Dd~;0Q^tvmV8^Z'خX+U?&g/ %W7 4 _@G'XmtȮg=t6R簙f:gn[x~ZG9U]j1`"(Ҝ L3y̝q:q3 Bt}WTT^EǃwQ aSȁ`L,ԁc}:h!U4,#@Gϕgs3dt_%4=JmGp8Zg6gNUz-_[ +|c*夷 0(Fp??yǕ;i6 | !mh‡ו:i1ucX8|أ kw&4$'将G>f]mQ# R-^m CҶpqTc31[uu% S=So`.*DoPwAb#It[(nxNܗ=8R0 ⲁ+lYku, Yέy:Zs[SP*u^Δ~` (pjCnPr#<GёW6{¾ KF\\Fn)ZPmjִ.у)_ӿ;p` 3vٍؔ_g*zba,z8SAQxx(WfCf9-Bp\iGJ[r(8ߑن {ĩ5$D}g^%Fhhr q0+Rѳ 4ׯelmLDjJ ;:S) :MCpyܴmP3*7\~~yƮv]c}x.zA3* Q`7\;*2$Y*d8Z\Dc 3EZ!?#̐c_ҼD"_<8MwXPաKqpjl-VD=s4?5Qr8*GGĨdHpM1#HpVn$|N?мzmW;x7gz(m&eiV: F: =㳺nT 'yǎunEj>Dodh2+ ٗ]8hb+ X)hL08@&u{<͏I+=«ֶ:j8[.5V I8l{>+ȁ^܋S|jv4xlfrIבta9sRwlܸ6 ~znKEnz_n29,g;8/saO*zj!Ѽ&XߘN8Ӣd9_uF;T2ZWCX֦=Zz{&81ŵ&VwAr(&`ӹ; X=+DrzHVdM`s۶ NcP*2'9@r-jdQlQJWZ/])Rq+?mM] (`#rȹ'=lf2/3X#XO5UnEŒY| ZQ- ]ܓ +gw:1_=sdEɕKRRYHк+%3h#?V[e{2S T8PhUhIFН;]am-WLB\מzΌՏ=7@#>U\? xiO8O[|zA?y}0̭y7֙4`ڶ2jnCz@I(Pfع>o),%hI__;/k]*ž~ot&-^}tCkR*F: $^;5C@,hR!W2|*:*X4&+_Uc F˺T4VCM pX|ρ`klV <I#F#5H0$$fʲd[T$\Lk={%{WdY2  M"ݍ9_>ܸB߶"lϟta֖ ۷5FE)6`Ӫz$Ozp~vsU j3uY,7SObXڴfƻ)m«ڕDZ _TؖIܐV8݆61=݅dTipVNᣒ]>δU {F ?jcT,2<؛QG" 39^cn94ǝb≣̇\$ZP Hp-GE@MlV3W`qZK  r7o~%>5N5޻>C޻8||_Wow;C/,ʚB tEX;7}:|1@P:0噎`[TT$>/<~X - #bí0L>eȌCZB8DTVSjiBs'0FK`MR8;0u7'F%vBBeү֐&Tf`ҝ_('Sv1)+cى[q#,]>Ycyލ<qډY yl;xi>eck3c֮iPCC0$g퓣Z1p[XQ!f@3Q J@wCSr88G61la㒸3*vKZEN׵HjAxz|Jj>W/pʝٛ"8A6⢹DHYZvo_<|Y3[=vRuؕ6l_ ɏaU (_jEbnWE%=VpCv˩TkcA7oCFj Tˏ.yf+XkJ (ҒbEd>[oV#*R3KfR1 QpbѱmGl Ɵt'(e6ԶFew6rk#M`WYE5,m5  K[O:ߛgWQ7/"Ke:+ #Wc:-'sTVc5ߜ(:4Tb7>4kipr,s~$Ζ3WʕCA-ap=L$D=(,Y(5\ȿAX2?x\[ GkإXCu*knM4.h;GU:TYgDaՊH9b$LMS5v;EH k#XmӲ[wNk΀u QK7.B7Cw?zS}KS UYZΒҔwnYo.elN%5hOᶲRL~Im-\W?ZV{h*5t&jKJ VFxUo8?P1U| rU5 ?E?`-c+=16ʥ&҈La~,%ҶLJܷ^ZWGʵóbejg¾NTosu!YM6U)g,@%"AvWcMabֺ*gW+]Dמv{#!~a/7.F;<ӂOd9؍slj)]a A&{|gyVW3` aH6VMd]&=2.ʭ񌾻[*ߩ1^3sSAOjy1u25&kϱN>%ii8 <ͧC:bc!tٯ#¤>cE@ EZ [>|U5vlRȹ-{"/"[e/ndm)^^dfʛ^ƨDee'cۧAfu|w#SPOywUvMŶ@]w{^/oݖqnub8Wn 'W=^잛xM7:2câ6L-SUoٟ](Q^Ln90zt&o'Uʵ9oBW[lce+xlD!)!VC9Ԝ ,]) W)U)lmz&p kcJZ?r%qVσF FO}LO~vϞLxFiZY :N^ p,CZ)ձ8wMŪaM-䰫f,\,+A83pw*?ם ̿4}qo_: dh}jE9%8xlϢ}OGǷrfUGOۡȜ^8V1bJa`Q)Sn獎s r;ᕋ1r`nW[jcg^`HxYH)/NSyuq8zբDKxijBjN~&Zh+wG]<{ޚ|Z7DU v2@Cb8/ڑZuS!\ڲ7>t$yK3FtʚqV<1p`}-PnAq*ᄇ2@l!h!R>m v)mr1d'n k A˜cBHzĮnP4! <kuK[ZGcVBŃ*Bk 'OlzqF3hqܺ͞lGC^(f6+jt*]LW 罡t}Q];?Q: F}aɡL.2cfn>{# . 7y0~m%ЮNS;Mr@GvAm)VV: cP\Ac wUFPj& m|k5~t'\l]T㉏Vq|l7{\)5w_ ̤>7MК9:C[,"mMltC3UAي6NN{ s;3oYNNPnvk>'86RBQs%̸G}Lv\2(7.XH2t"2aK@?,a47;!l9!NQF1O  2uxR?&6C̰ӗPZxJk{qg}D2O%Xi(q!Spg^Gcxi: ODp T ,&*wEs6jfl x9v?8nRT8>1ݛ:21֞.*y}{v=@:o7?8w gKPci*+מ<|x6˂^}m[9LOzi;v to=LJ1gx܅\/EwTK.@Jv lCQxb zsJm1Ws}DDjL޿ϩaw3knob h p$/n'˦gQ cpzdQfXle5fTjvcaDh2h̦.E:nӅ;)Kotlp˅)pHPCTEΘ4j| TT]ghg׫#}]E1dH,CyYjDK rݑܵorb$!u׎e_9ٻoMV⺾ȋp1)N:#9»`,4c J[d2'u݋vcAGu2vpfhMEJxϬ{kQFQÒz&/d72(Ȳza(zTloڝ_*|hxyUPM[v`ލ,2ɱL@}\w -vXЉf"QBrux6U^_ 'Cξ3=p̢MYIgFw{iĪ )["bhY E4dۓ[Qc~R=Z/YC 4YPP%*EE^J$iVR&܃{oSz.^@ˬoqaa5'JCii)Lc9Ǣy'> ݻuOrK|5[z.%Q?;3r-]N~"~s草j>u|l)m4'J6p7vbp w^yЗoMv:H0R4]`%2Bm٩7I2P|T\'%RWqSb6)NUK"KnqcRo.5ab- @ `5_ѧ5z'6wJt>5V 6 p2E4 Ze9o~~'Nt\vhLSZ̑xdK ;*/#|~h\b0O|-"X"f>ET]5z5\LV BN ;|5IcOWCM\JwН"J U UY[}񨵒m+Gckp$;B]0񤥌B%KE+0S)TCNnˢW_V-AB~VGN\ɄInÎJ5m8mcюcK%Z{szPFtlz>岳DGvZV*x}wn- jVSGѯFrhK&ˁo_];FKWi+-Mm_U  [}}+>sLpG PS5f1PN/ѝaa6HaȤD5{ ]syFOenj@T!wo$:@-9l(dljx,N-&LS?) xZK,Vxe/NYZ̪<6eͯ> ?N~S)Yr@f_ tݞ9ѰU~ UR))0zKCY۵ԧ*wP7Bq,WOõf$ Uh iE ]` hCҍ\%6b>\4|b9YG|Ki#IKT#O6 5ˡbꕍvd$-eQHd]m 0 (sb2o:uK,C^"*܊VwZId]+j Sr?xl:UkvhGtE?s?9('4J/ϛquh|#ug9:72CH:ˡiwZ@jC4\0~2I@a֘<.elMg㛣PuzYB)[:*۱%]smX;/F; |ʂ5GABJ[i({b;r9xMغIC Zƪg+r"$|4T"`G?Qa,j4O cy~%w DYz(הya:pui!ki݅凰B5 DR V/8n! ׎%كϺ?0~Io9, 1-ߦup,^&Ȓ㈍ه!R}G co gNo5vc,,ss2STME!VX.52'dUWhf2ђNۗϿ\{a/ӏ~VYtloNsϝQ Vd`6 5al\NfPo..þQY* . p oi:`Ċ0ԓ*MLi:7-mP*5#gԁ}9 ϑ>& JjL'6{;̯j(Q;qVN@'O &>r\%~9^ Kx2֨Rp7c~(ā^ @= ̰')jC 3RҀ4ܐwCVRbkkYv*05c5~/>pSF)5'=LNWb`eJZd*:zj*-Z@n#g[Ila4}~?=>"o|ߩ/g"2{|q&{"FuS3N^ hrZy+%0BVNbm`$eӻN {T_iفYV{HjI)ClBUӮaG "A`/EiOqY@DߖZX [֑!.gwOCi^u 7/Yfm&6E ϺcΩ'zf$ ("X$W3~ozE&\)$ ('+t{ vb|oYgRJ{g&B5ggDZ >!Ua ׿G\˽?:쎲 #Јlo=E]tV4И:Va \n1`#nXBNh*i6*7m&+-?)O rTeIcnwt?;}6 G%PY"W) ܌_8lnӟLlmj7e:&PQ]o@{ILC`, bO=UiL ~9OWVd!zbg)=c83̜=F_Ucȧ}Kb0N%3>-LZp$ems/$=LLN_)!k3oܣ!B^yLé q}L %r=n˴ve+$-+b`bҖ[MhQXS1]. T^5$7z䅴nJ ǏwM}OT+\h_] 1 mҦO.wf: Gg6/|C%WJ.+?z5LJ|B2(] (&htKzE׼7M؟wGtA[3WKާ'nV$ۢ d8y~̥{9/h_C}27ێg7'F{Qym}U,>yԃΤ'k4@:0^ .sF!>D`JFʝ8@{€(5W~~ l3q5Źn;W/K&4N2-j-t BѰ,w[5 Uh>!W5ψ홼)GeD^óӣϼ8uQ5 M}Q .|G/eUD_@cfe3)RH _Qut]gKC+ھE!,FK|Exu 9rJƙ(,X$1ԟ* Ch ފX]bώ9z||~W%>mUpsrj/mߙUz 5"g[\uIj/Yì#/}w췾'A'JGV?u8}'ByOdq1lPDNmj{VR: oڕS#䝞j֒Loo_tl+M̈́o:ڼ24h \<8=O`[CkMmE'( Yڒ=~ \ .A⾯G{t4d PPC/IǼtZ5c sxO? .\ԦXӎfV 0Y"zdjq}NڛY(KU`d+ʽ+R]L꓏yXē- [ҍhXTi#/Oc+`ᖎe*d:g?8"{UΣs(,r! őE恂'&¤ްuC, \8 `pi@0W‘S:- Q' kU R %``:,(0@ۢ >Iag+' gv HVX6ZvN3|8I҄~nuqf/1*e|wڛVsO 5ʕ'OAІ~-R78C=2 6s?zթ'6o~kmE/?Cv&./`pc1lQ8R;"1dDV]бKWbyGǃNOCn^JAx_یpJ2Ds,RPo(àtw >0eDe]J Pjh4! '?t /C`'jwFC8By^Xc0B=5Y)_E"~UDD 0@ >'(irhjrWՃ;g;fkg7j̾mONX0@0d:R$LZ2]&mY@bVA$\hYIh:.ҢP, LCP<}gy&c_^f*A0uiJYn|482]{zhbzKno2Y @N_X*YLlX߄~\չ#޼h3/&]{^)L5;lci4~ԩo~mpjWګ+Aw׶{B=]b )2P!vQaW6aT8v;A+[q5 )ur.\~aķNM[K9_ak ha)w,'fWB@ŕmF`s޹|w;/?7oqr#XQu}]3] @wFn*}I[\봫[waHE.Y]82ö#3p<ܖb9 T} ԈWڒ epyp!;&(uvua) pSYd@b(C)B}tfVd:WI<(&9xU!h1Э6ljl7PzZ:((^*"sB'8ύG\!l2lITY~?}}jCRC;@b4ŽU;ݺOwheBFo۲(}jzw.}!Z@AEK|(Ȝ-0ɳDa@.9FpNqHExmL4z"s])377/(+XlIlxϊضI-KrTr#sWɈf<8۟|v6f `V-wC\G!Aj z'VUa^]fGZG'V`!lqS6Fm>̊J~6iLMZKa9m 0z)cX8v-i[4 S,Jݢ:8Z2=:.S"rj 𱓃[߬_1Ҙpjuᓕz(k8dZ#ƢlV%P68y[:NNE3G`iӴhs S#;^)vĐ{4UjriPMe$4{ku`zj!;gǎ.hgQF{R3/8XJ6VՂtٛ@5F?̾w58JGF GQ8m#Wg+P/ú.>1Œj=Bs7+k[ݐ2_?,:V:?YqV:8YU $lݳdZlaxdˊ3 ^VhQTqLͶ /ܱ__7,¶G"aAh:\}D7-&VF| i"3ҫ))\H`u?8+ wodSeAb5$0߹⸫>2"wv|u8uҤ,{>(]IO`U;[5@v2Vu5֥,*9riBirDen* !%stF+Sx8CUn#>u+U-ƹ_حEZlC-r8(rzJ @ۜVţ"]&2l4h󠯰om.8d̒*4&FމD!hBj1,6q4Gf9t6kHkjC$`(x#7U!Vgej>rCA)L+ob^Ke'a/aIw7TO9k<-"xbs依5vMB4wkCk(kjl앳p_?p٩ M2%ujbn(uȪAkn2/\š7/u=X5Ԛa>R)į\e -՚L~a': ŻTxc!ܻ|0|\~F<aT#mC^6eYnqM|E30zFeicHp$ʀu7^qI{H'= k8Qh#wbXg⃁J˞9 W((̩IPHsJI٤j ?,| {/֍z%7 V)Sa2iyVҒ`GKkez3ZlrOzTGpSxgem o#gWeoT@K!Jϩ.b2 .{ B)6n<ȽU-oh]N׸E, Uiwx9Mμ傂4ز`̹t=k/|S!Uy@"1o6 e>fphM?@Q[K_Þ@-U>Den~t(dXn`9vp*iXGBi2)lt%ċq$,lik\xֵ'oL `XLοK@N6=Mh:pFNi@PɿRj߱sbb{mZD;D7s3'T)lcC[v?ͿBlXEB6'b;];^DM7WN:nW}иKzBze*7*Ϯm=auf3'$:f QsD9Bڨӑ5Zx| %웚F;%V+?e%*B=$("11]&˂ӎVLbbE_"g \nY,"ڥQcg3R Yy-%{a]Kee,+*sW !zӁ_ާXFaV3,5PBrL37z򐳽^ht}D[K[gkw-0ʠ*uW-{D{ݨ?cO:>$Кu7H-pow7o*p5ǘH˛oT.UW_~4"tOcVzΡf .šT?R. pIS5ڞ:[ĤvMqb$cpm؜E-zwDz@' o%-FH(r80PȟQnvK@ a mĐQN.غ,̅TywC֩?nm?eV*Am a&Ԃ[i5[Ū) z|F(XT*9[梳w:-6% 'Xm0dP~!g22al}%q^z+k\T "ҙ ~L,yR$!Fݠ$AF0.kFHMLΆ٢KЀrcͽL0#]7ӊC]4P8ΐmXȼU<|1ؾ;0%Ao`$`[_pxmf)e _C!` +x%򛑼K4j+lNޝOއoBbA5[y,Vu"M*HBTN]gWte&-<*Bf1s^bέ$GgmDğ0% (`PDAU-d6 )x K _AR2/oEɔD)6eS0S:^*tw n'|Cr/6$Pd)m+x$Kiŀ5%kꚭ(rV%i`8S1` (< \5փ.jY0$eԸך--0 cC6 C 8'#"BK#TΔGOZ+ Їy;Ab; )sU[;8#m-+] 3I0 ;>6o[Dg&aj:Yh ^́>H+:mmSVGD!k(V[MZfy=8sW {d7ر&S% +jLqУ"/G|A3u(_-xnԨEIA uy9xG?-F1$-L J'PNfn񋺢DƱ7ġ[]ҁ2?*^\]/.CXcc %R.^aa|]GF~]X!uFoS4JW߬Zǡ*3咥g'Dl m@ ShL.T"Od /AgkkNƽ6DnQh V"=W㜔Al\5 M=;4{{7,Pى_}ܿ! y' 7獥VY`\GzyM\;%H)Ro"xzaIP`m)BAF_ j!:( GyL=M x[i׷Jмњd*- ) ?yOb3։i>f(14ZN0'|;t³z:iMB1Cے{ۑkɦfJFMRlQ F;9!)s(COCHoqF; _9&~`NfjbxYKΨAUZ,t~To!#J&!QЬ,Pj`% 0Y觎ENNp SܿeɣvW%+DoUE@jjHA&F 3C%`rUBA{luXHh! 5$)8Dx ʻF,J@web}\:!kqTXhI}X_QG]rMc 1$PjbFcanrj3/iJPr& A ;_ նq]Fy[ wԯ}ߝ[{iWu xGDx6:oHƚ%7BɥCY&: BnDka־[XKBEF ƣ^J,CyokP ; ?8{ XaZ0}s_af/.{ozn,4ĒXd ~Ϩ4@u9.ՠ=L5+ɒQm3d7-;>sFk.rߺ)޹:`6oWհ<*MVK`'770-܂@δSB$3^>=s]aq}=jGdu&JM \&ZрyWnjrVșgPH1Ly'Nt{A02@n~sDAF4a7O?ܳgb4ƖX*SxSy?t)P*<ߩ rhtz$ xCˣ:7qiϒ=4ӽ\ j!] N% v0KzU+j?5 zKaL:+eI~H@\&MD6 Q/JHL zRi8* JUCV P$ņlo@Khtsdޒ C`toK !eScHKiW P`` f,|IL{WwFP$I.b͈ʧr* &G "! =аg379<0qxeo0mޡ]هwPq8/JN v~CH=ue>s?z53"S<0 Z?u%xӖ08eؖ1Ġ<ݪ އ"2:R80h1l l\-  ]"Ǭ)v!j :/K'_ܸ1^n^zևі"k c hX;,T Jky. ($UVn` f8oL.Ǿ3&i$\rQ h!blbDgG>D\<Ӎz*u-o{761꫃`ϴN88Ѱ) \P""V%Gߐs^ Ï7F۷]|,]~@ 7@i(4R+*_pI; `Cx8j*y̡!Y(\,|]W'-w_u~P>D\y%ÏJ"M&D![ Od~Q+z孟o_pN}alb6%oj#:udJ7F'Wt< JUZ(b@Zo#?%jZHE,N.[=ygpM?]rOg}."m!1#AC1 `)d&9<bR7֋2ck(f0,+Xû*z])JPp# "F@-TXg%q>, Ѵ2՚!Gom>l˚`2ͻyXU mP1$ĐXI-  P}r1IOi\gOۚ=PgmPX"5KM% PkAN `,4hkbG'bse5:ny1Lw Gu?>~x> DP]ƌ2Q(bwª~Yza{ָp(@k?,"đS[)\(G;]"co]&}=g>ϕg' }ULNhۖTNp+v#OOn~/ً]Cֺt$Q%NQ ,;]K* *c`ØB# lR'U֋zs^Ӛ˷4dc_+.x& Zh~O_) G|bI "KW,;׼: Zu8M)Gqh*tQ |AYt sAZGC٧'4MRg(jY|_ȂXP 0f` ISmJff2Ehc# >aM2dՈ Gd=V>={˶g^L)?hJba6x J:"\KK::y:mWz(zH;^ATaפQ:w΍W1p>iccrgi'_'O;чp wdLARh+@ {rqL]Ɠǿ>x4}lo?{se3I=6.W cГyl+Z Md @,bwqL:Bx 1%q]T%ig6597PqDJ/bh 7shTsgsHQfWkcY!QixQmbj(;%S'K?ȋu;!mt݆߬stX@PąKMp6.XFaSj>~m 2oH<][\$=nN!7 44@i`1B}o%`^fPNJdɐ\pJxha׫TtT tù}\0^80Ԗ,#,S &)HKgUp^yjR#(]+0mA7*;ƭ7&]զD@۞@ 1en8#kcov~7>pOcc<|RGm5# CWZkK _аE6'ՐR;=n% ˽ev*22ʃ vGB2y R2BŁ@2 Ǵ=k% !Y⠌,( ka(ic,Db h(!(l@k@@L VH ` X0`RL0m5Zjр B-f8!">"`cY "l1pf)pA<@e u#%sxV !RP PR РH!B+k - @%ЌB@j[ XBFfiJhc-"$pB`2(U*˭Ckmg[Cj$혭w)F3h %p E]>޼\?ySDŽ[۶ӒgEaT$"! zK7yH niTRezzRP!0ǣڀd.4PTLs͔+ޯl 1" ,!E bJ؂5`4RM@a`H[M Z#) J4@t,hZkpT hJi PfR(G4$ l]%HY_Ii1 0cAZY 7L`2Mkd1PBfHDKE"m2H) V; 0 `@"@,h(uT2a@, FaTbalUP %h`Wi0¾ d2q&KٯVaȥ2jV63bxr$b@`>I( LҮZ\ܘ?].Dd7#hAc@ =F<2qQ;XYbYF.ՊވAbQָuoPGSL۞Z5\2J3V 94srV @U Y8I@AC.JOs[C'ֶ\o7E@۬,J(qӁeÐ7i%<3i>I3b8f:\[,| !saҨ:?QU,[|MXKh nѢCܯh;#tÐAZ~R`3+"PY"&t!SAf5~%$y&.Q)xw$ -Ѐ9QNN6ЙJΞxl?6[wz7ԧ{<Њ0*x1 1kǀr@hz #Ye9pAʱSnelqjT^[ ݕ,P#p;ŮS(qI:qsHDF7 Ztc)2@¦b R @3XUt:ṯw{+w#j!BbsP y)-`"֍G%(1X>cۃ¼ j4KXpB@Jr[ >>%oy!%$6 Pi3L=Azv"sNjK.|x\X &*g#8WZxqL~OJ,cxDkd}ThhLCrB|4@+奻rH)7mm*#60H*KL`4J*AhQ=k= @|ԕM8+C=fi Cj}_'&v݆#MQB5 JFH"um&Y22j[7Rj[lm/μ9ھ13)( RaǪ\@l̺gu "D$F"L&(JLp逥 -* d$۷t~b4\P!S?!tTtTxARhlيyM/%stnO+iF-qWñIP>Pg)Cz:cl#bB2Ln5^lHzh!SOjz [vB_"pיQ@ѕ!#, :#pD%!ŲڑŸ~xORg 9٧D~?A !*2dB% d#pk~41o`Fva BGb/F`=K `{M0K(  }(*2FBo+ !hh 7߾y>0lX܈Kky"#UHP6SoT"(۩U0KjzDž`80G=!|ҮTY77^Y&]:iu(!gs]}Z S޸u"+ M:Gk| rƋ$ RU{l@@1%*{qW`ue 5%k܊J $KhD\,A޸/g?>8DhT?~K"p~?R1& ,C*ZcY /y~z( zW3dmcT/ #)1%m>x6ʖz']bgqm] JP!hox@ QIdN/^!(ԉ_4 tpN"@dmJc9HcÆP%P3! N(hY0wo? SՍCC",≃BHPBQH. 4Ԃ2 F"bFd,nC`,;@J7{+.L1%|/MS@PY^fr5 Vn!,5^7%v":$ҏL7*4[J0mhm΁\鯑qW*kA?ZB`WY0!Jpy_E13i;}ū{PԿwk j@218H'e"oHA4=i0cj/@Rq Y_:lA̡v՞{b g+hb%7Ti:#!RjkUn;;W],7Wsۖk|WApKXhY&^Y4_"sy/bט^uǦ\n/W> F)0Pa QZ.!% >)+H].@>*R X?.Qe?>pso vi,rpEjخhVr]܃GJ.Һ uc(% (vTפh 2#kA,T'1峹8ƠrqUQn`_ dž9:|%4.զ@U"jũ6.MуA" bচ7AV. 4RqSPGΦ}uaw >_pj>')}0iU.‰  8`Y@tŰ/|%q ڿ+QEIaݞml&,H` A` dm8}z$:rlGٶJ L\/L?^O䂇;`q[}#mvJy̠Vb򫟵ՙlj7 Ek|UvZ.ޭ޸X^hsGoJvaIoA 0DY,A66Yƀ&Ȝ# bZ _ WLRBk#&OGk2{l9NQzG}I!Քv'P :57 ǤY opւL~OJ:vƋ, <:.4l5`?Dݶ4׭fnxx~3s)8Š*I-h5v 18gVfqfqv'V*JR1s^fo.5H>NjSxyʕJ/>|p^ߎZmv_dYNԑC=9D.P1Y:g$ⴈ}y8/lv#" J:*وFiB!欦=YÆ-<#y3 X+&-S ] Z*-5l*-A J6xN; +ֻv)>+Te Cz'{i$W(n@;%32\|T5}qn-ki"8Pvtn#FeAs@{,Pib*e<2&IMKy,JEEUlVpw)\kdITZ.s,Kq`Wp=P!_ZX(ڳٽc6 ]9}hԶOT1?l?*Ɛ葁˹RܾV3]hլ,f^ytGrWl2T +T'sNҾ`lLjk`@P=#"]hov8dy9|T'|r Xߤ`5Zsg˕nrr=ur2u y dN)@#Z,SA-y^ҽЇLu@}qP.\KTkkrN a|w!}7g#;EݤSU(yg6jB(I=q:tpwlw}~_b/^>e[Q9Qb6CR&3F-d!qJh 6\ʿ)2: ̲~趸mt3)^vnQuvhV-ljkx*XfO{ ^CoPYbX \ZF4A0T,a-; LVA؊4Oj#*x@|q(Wv7uxd!_lQ~.bPت`ݭwmrk/+!kv:ӏ3iC,o&LzmrJ˿*lDO2dU^}vDQ|[ӕt3̬T(]]:1!TgIZ&mC{8j㘛Z:T:LP@Yn>p zFBeI([۫w Q|O=\lMr^IJX7D*F>&И o_SFLp5~HO8Ȣ׭|VlQMd͇. pr=jD.- d&_:?}޷? Qւ^% ݛ۷# oǓsDHd#Cv}5`KܳDuR j_aԻ2͈Zv{3SW޹oۛWK~/eGo Ep^אZՙxڮ ;xtݺE7@gFVTd ővÎY]rV7R&D&a?x;K;VKݧ^[XiKě_m}K'FVmݟ mɟ}޸xؽ6h8EmR`M#M4֖T~0XLʁti+l+J7?Βpcxwx3LYT']q Ulw0(`ar9%.!k&DqqQuq:wuk- 4 cy|pOoU&wjTY (JH`8F * T$g|egƯ'u2a )Ud;y{1 T]#IKšv)g(ܮ ن@hӏ7Δ7(Kϼ_|D(*N;7_\D."X?6t~ [cH9 (#FSb \i3оPhbavt>|^oId@J MV}p&Y:']3 Bj#ݎWU׾fQL*,K֮XIgB9P}0ZXvY꯶5 }ehiiCWj7IR-4_}qMf k*]Q?hz008x5sPz:"%6TKf[HC)Iè ERz 5Or{,-M uӨj"HԬ]FswO,Rێ듍͉{k4sSfM'W , *^zͽQcNGbL ^;_:M=Gnpyh +ގqTѸܩm< DzMĹe[ɑD?XM-؝zo?^kKQ gvǁ\V0(lR@ڵ KO/Blּ}ףPW8Kۋ¦ń`!Fqő0x_yZ/Zu 5@8n1RpmhNJ'ZKbÕdW_[r(('%~٭3K.:">TTK ]+l.K "8|3=_؝39,N5Ղ=[Bbt}^H#/'y竐=Mj{W~<Ҁn&~!m>hrhw^;Y^~," NWJ"(fxm8\r񰻳ek߱`#vΧpRCBeӖ#QQf_Np`S䧦1$w2z*Mr8nW,n ?mg@+_]¶8|\~tZaZ]#GxTb2[U.K偑Jn7$ : ::|\?{<$ -Ѧ!;Y^ش;Il@^pD~ ;?SN, "2\r W}]T'"!XmJ)R<+1R'|6I nZ>6{p۲cK C !n^n۪g ¦N}47[H䂂=.5!4 @(3\L{v)!/p)^h+Axwk_jgVc!b RPr "zZUTwIeP)_yҳƇVlj;# Μ@Δmtc$q4zԻ#ǝjs}hF "&O{qK5LCnpnz8AT)[=cn3bˍe0P Z k{Rg{׭9?,ȒѾffe=ȭc(Ӄngcާy9veu;痣EF$͊YBQKž//bM;żrdo~Gwn{F 'z]시v ^LۛKeuBI.Mz.>X چnx՗za*a3ez>`o --K)&WuHccG\8NooUAq$wAwqٝm&_NnB&s@͌2hp2KRmzYI"{O&0=Dߺ>]Z(r N6clk5XDK#>mapvgA:_NڝI|6Ӑl$(x;] Ȝpܲxq;bB2yl"%&3۶i0nƄX;;xT_(/:B`):mo>t!cOwr L]H4UhM\=t Ѕ(^lNH`qqWkX!R#B7ֲX-`gxt譭9wKXM-F{FՓ_鱤@I nw:u;6 R5M;"!ѽb+D̈?}z"·Z_;^#nbXRIY\ qHs^W^;Rr,oX?/yVRGFgג3ȷkUZ['4Vd]& 1&2<`q6+Y oҐ%j9H2(t!>DS:h~f7 xvN9ﷺ_(\}(!r5OpX ƅOHR;/ď=* 횳-Qi&jk;{i{YS Mjmy렎;cgz/}ʊSAҮV#ϣhBI; Wh~BĘNo}ŝ\.qqu-YCJ$G}?l<ǛxZyS.7\i<{ 'y oTAfSGsyX"Cs?X}|΄; vZaψ}|uuRrѮq(5Z_ٝҸ=o}H%3dV:{wZ;m%XDz0d tyQG4DHg7s,M)bK6V?>/?y3i5RД&gɲq9cd+FTTkOg.wډRA# 5_v{v˽GQƑ&~K]DBPadF@xDnf4)\]|}'=O3p>.BL_/O031O'CwyɰذG={;>R}V}gVoyHkFɹcvt1bGhPUj/sbHX.ߘ: M8# B.= 2벉̐%x'Y,Lp[r.@el1³_? -aXٛ|N¢PpBϵx%4R]V^ BIs}N=f! ־gE/mi؅ɽKO.]7j񱌙=7Pf/BM$Y] ˺@V[ٳN[ %Um7-طOZP;1ǠG>pE@IbIyXC -?8Nt;Îk4^gMB&0Trzn p} K'(WokSSvu̍Tˮ/faCE"jc$ü 3Erde yOd ev$oS[粊gb^c9鎮,ctJ6]1k2NY1*@x!{b"G_~s?b'?<X'<Ν>s?K_8e?sgxhstb: P%b %A7uRL^APBv!~܈EPqPz :\kRy@O}5o׷a}>zD{FyCC_|) dԤa{d%ltO>L2[u1'gG3[jqw|Dɻbbw+ŃP3jr;F__i,-rjK%ي*^1ktz%:utn QrwI1 奂&z[x/,_p.?䓳)<eaw/ܼw!h'5'W%*{0j}g/aXb\^53!QY.OǙq,2Іs1$3߸hqbGGO":'Lw3ǒč& mwI}EmisAsAa"ögbڰTnn n8WKj'3?5ki~_O<;8˱O؇ϟ!ҋ*OW/?q(xpDKHh.f-qgǓ(}%EFrtaTf̊Ug3ҖZOWmi'NZ{hwVdpk^v'cȠ?.qH3@;5!Ъ!x#dFh >?y*8w A##$)h_%qqav9Kbq0|i[KӺNJ*Ѧ"x 5-psV}J8VىR.]eurB&+qPtlOKF="a~zfd`*@#N,}٠ }OiNT_6HmKtmsHml57ِ\:vQWΉnj[A]]8aaƃF(mxw1] OC\05 Nzfg E <) !Wo <E(9ںE^le6Vec`285 JgRWfֻnw݅;Օ_:P 6I ",CW); IDAT>?Gm,(¤_s~'l(=.ѭŸ)T_u5vhve BHYu/v|S F#Ֆ1&Hshĵ˵1B~WDR*Dؾ ($q(5\('ra9uѩ8fbʠ݊(ޒᇭTAf(\ җrqY{}wŀ9F,IG1 ϓ‚>w1Sq;‍skBg .9Mu@\ 󡠌G n},sFv+퟽o}Yyh:KOUgnz+V:Bb[4ת:z!Yu@roԅ7 2M\=-its_>|XZM ?*N廩'_{n܈;:IfOIv$$Nq߼%N;-ԍ)Ha7k2sy^XwclAQp5?J$+lrSe  }k[y!ީ.yx`XbãլեeֆF?-Z 88~*QuvYVd9Vr|B2MyE˞ڲUN;Fd-to\{1a\|m% ) UsƋ}Lt(39ib0ZhfmQS]V:X,?mq0Vh1˴6`mwlJ"ȃT ݡ=,N}jr4PXIMoߞ(h>((B鈋EijW*g*h9g?|کm9Xw,Yۀ{bM8 ]Ծ Y@TJrϮ< 둒 hř\{M?q yM\^uz<x)n0J<s6ZK׽'Rc`REU,E, x^4'%7˙|..L0|{0˟?L#'Z)^Nخ{ m*HgEXb'QKGAP*mHU4raݦiksakUFȾ[Z߻޸޼.&Dg`5צoj!% 7Oi"ԙ!?|l 0RiטrcVj5=?-& )%i!Ю,Zk^8vr]֛YlA+(%GbDJXL67jIHHRXoۮ#~a%' UouH[qoHV:d cl"@yf i\ɂiWWRJbC2|p/_Ed*EA[V.-7?~.cAqLuV77+Kf62;3, (%:<ŗ2 DIv?"~&y:vRdzb%cuwR-')FXSy)ܚb~?|.=e PR(5k rQX?G%uJ-|LzmE[V2 +!":"!;:)IJ4 {_uyЕ|~A|E ~9'̓QLO,oZ0^h&ڢɌM$6B6ꪼnmC?!#xӢTs'+&3ϩ3{RuQqwmJgʤ֒mElSEOx]YXHPT`+2vy "!n@`OXiAGaCލHQrm&S?]ݝ\*;~ˏG'ɭ%d%C#Z 91(N?Yrܮ͆Brs-XKu݌+*/n nO*`)rg琼d;۔o`NdѸVZQI sF9أbZ{JavDz<[6N;pU:GU&Ir Z:Ip)T$hy]þ *,U8|R\*@ ē2 ;e2~EvO4ɁK' ]ې0>4?Oi,>\u|X^PF.vӛ Dۯ KnMC|m;r}g{ uGFJ Z|LcTj .!;aɘHPRr2+#yV-.biQhf*r*]Pq}h =v~s֒U]I.6v#՛ ,` ۢtjޝnf(3iԣ)Y{ȷ^Hf80.}ldx{2$R㧃G8"`;"Jh{Y5'#G5F:#[A+IX^3[  vhw :$WLN+a᫷6khK8PG榛"/ܔwh@'b?gwC&ch]zzM7Su츺ҢQv{ocf]%5j 1uB?P@d.T_P8Xmp?$+[)KbG '+h!ٳׁeKP>4fۀ e`6ȸ"j%8;2f^k}"\f"ȓz)w68MvCo/}{Eq$cSz[S֮]^p/c-(ݕ >=jV6,*\ʌ=Jz1N2:#Kꨧ 8|zk[`zI (kى٩Io=DHa#m1,7MFF쉠/9:+%o$vl{w/Lm{թB)=-=%qv0 1ylpke$ !|GW/巗E ]" 9\ (3㚻ׯ~=P[/9W Kw gz+rbX2Fj[*Ja~S'?zCܾϨ @O6cI{4 xuq{][d=73[BЌm1ΐP^:L;Wn,c':;w?OIB`(}MMT.Al—ޖ'5@JyY,Xδ2{=v'Li0J-0ίXׁXg.߾9A[[ 3 p%d.[jፚ|خ˛i{ymHQeJ ~{״<YFA14rD*g+cYC4. TT| dmО#S&g:n'V2m|j0Mă,'+eWk{* s鱗)i/`ia`]⺑D")]c?~Ž WKfa4?,ðEqU|0\Gף3S?a_}܉E3iIDأ. Njj WEbW Cbv)$]?Ȱ^fcO eh,2\miBxў_*STK RE=c2?{OݼiB4N9Yi>ۿtK+*w;S["tn`Lqmd>/lnMJ;,T- ,ť7R#*z)&NKFk*oUl8peq|IS\{l~aEnL-v_&"o$@P}jJ Z fOS3 )Dh*AoU8+ʺc,  Q%:'(R"YG54$8;ꃫly- Uv#M@Hh-0gE|\f+)/\oA}w'/&w~۰0a6Z6 Q2zw Mu 2݂6(GWO_|A4Q *0ƹ*Bs|iKضSp//G'{I;ݩKxu [ZzZMJYO?/z+9Ow=MM Ȏ8tʍd?LC+R׌"CEsf͗'=-GIU4)((ElgI\GVDbJ&Du̲3n9YnÏELCja`H`) w;^_ήcq`7Wȿy˾ހ=aqIAn0UʜuɎem$56>-?c btcne '{f cg o~ol뼣W̤721܎;L= }抳`naѧzQoUn͔e.Ը6Mdj>,qusk[rg/#yf5ڥ{b|< Ƅ?!M4L-vID z{mzTlߝE{y' Po߽"Ȃ T'vW £Z0 d<ۂ;Ȁ{gUF*p]QNJ̉ ( `#* Xa3[sO^]GS8nbvgJW1 7岅>ԪZ*@X.h4NL)i-%vPVʃ/=9DD%mJ η|ܢ,>hTtsG˹"Rd!&wEp/ιk`晨;Yy7? #_1SjvXal%qk B:K43w68FmƴDh6m} œA *Vx 2>9f/cB{v&ī?|I߹F`P߷MbkWb~JΤlǐVVYVWuL |u u#ʥ$Dh,xv I5mF"bU6g@g"{]`V;6_;.=yvO"Ee̢d;O<^j _$QD(TJky՝{nfk-鷂q55S-v*'7Bmy 3'^4:Ɔix怒*'LDͥ$ `ҜsP\d1/_gx|յ@x"tY3垱2>*Α Ǽ%KN jnZ[_Oܲ/7z`q~t܃wrԑ[D^4(]X4/^R]oO^^{U[[6 hav\At\eFq@& $'~!vj$FK+()k@[Zq nFf<%NH=U'Սt~!i"hžrvdgo<7Co.M,"3R S/||yR>ZEO`[@9cKIPПϰcHP`Ôj&m˅5}_?{:yZǽ߭ H˼#Vfq,`5Å`z>ƦwGNF0):TjA#.?~ln.Fxr@GؘY}QZEwsXX϶Ο V_-QցlZkL[E{+eYvggy7U,;y4:vI(&?x>1˳tM#ӂ ޣ=h۫P͕M, өͰ?T%{CXhb_ȡO s #Xv"z3Cm I#*KddW]{֦x+[mzg%i I`PRe\+$vc Cn0OeHOf.k~5imU&f3Y|;Z,1UDKl$(mY~8-!eI®Huzkd.cq9?Gr[2khQ;%ip ,ml~-cR#u8Dӽ{6*"@_z<9@ocs L8Kt*As|i/}|6 Di+Ǿ?.;2w2cj()%PQq t` '' 03?=;ǫ;yEs?D06 N9ONg&W^˵F?0셪l['^se4Ƹ>ˏ:\0"Qtgں DJv@, =w‰]k];۵dno*XSa P}3ڹrymӰ*mW?jvt5nmAԭSˣlNvWcu.77llpzacwH _@r$[ie7OWsXm[ӛ8/jn^i."RSteK@T "B!t*x1?>{+/n=u\!1?-TNlmf+]ٿNs|4Μ `!!UuHz٬Y y+ebec$An/` %obĘ)w ^0X_z ~ |Rnгwo>5GG'bJl,D>2d7o3l(<6vqfV}%;\j;JVS%p\HS_|jH~{>a}};WD3c^؛oB 7h[*3_"QE,V J(ncz8s`Qĸlitt[{iݣ}kgyx}*/ݤ W* ?Z_=]\yn>l'U`fğ=WiULo[I1B2Mʊ>( m]d;T"z…m  cK I \ "vw˷?%L:c\b!:}{Gȟ< /ZĨuGgy9^J=7dm' m*֫vDzlSe:j7li{r6oVֶL Suõmݻ:}!6T@NNq__d;;[vimƼ(^ud#RU/"ˢBs )u(rM|69޾/e.ϴnoMꑢ7602E&FψbNX[G/Zm_B{m Q*Tlu&XpP>f헭>vmT ?VC#IsǮKG$Y' rzȹ"`卐.*Ɔg Ja-ZZKJlObw-4`8&qCC0Y!u7Zg(4Xlmu4x'//$m誼_9Y(G39E!;jŋ2꺘`zݶN4kȕyoʀ0k`db|Cf3y8@}%2җw3,C-d- myw{-p?䙯/_W/ójBV!2U@$1!ܞ\6023Dd blo/D;/JfC#]G䓙/ؽ25$­LFi"A%bhE|YAByHR *Z;R59̉_̷eέN:rM2KOҨk 4|b?Uk,nM%H`KQݶ}YHC 6ŢoHױ<"V*XH@eӍՐx}AWY=(z ͡ELIj}-=?%&rWQjZa G>NVG)mfds튤 B壸joMtLYnF[?6N6Y %%IE5@+z+GEL @NcVV9:Ğgqe#)xJ&Kֻ13F;c$|EY1\v5JBU2@gkm kIm<ィz'Vgi(af|.p1ܛ^hlEH$ɼ ;Bs4\jzM5#G)ka-,UYldPtKxpj{Jzdn%f|WǚۈGww%7FW>_1ܮ.B @S`rxwZfql#af"*KI TۆBJᙡZR< t4O![صHI]B&&8jFpcFN݆mnܹ· ͖v&H,ɌUR4gҢڌuCY 8`ۢ&p^ȫWV'N|zv+8_v/da W=; |h0m0E?~ڹ'[Q\) Hj>Gs'%6<};a9~=_AxMnxntyiWuҶ$\T6J-Zj6a` (rHnV;z\c U(nMf pN8n,fg5IpE!H=?x'??ˊ[H Nz/̣TtYno!!7F]~(%:NU[ݔY uIlұ"|gwuQ9"4R bbEN"L-> zql'uNr.25Vꆲ\,-)[m#/ӵuan*!VSmL pQʈ1˪qmR) UiCIq;mdč(BCJ֖CDd%-WEzT)U^t݋H&XOżsa$a9hg(:cDzArmZ~^4_wcpo?u =T&@ηoܨa-d<ϗ[x|85ƎPnHQSH#?S7L*R#>Ld-c|a? n3R a3'X*,mÍm(79 zQzAc'Փyh+͚'ZseE;FYA!b@) mOue={MFeuo ^/tj~~/3*(ѓ=|\qۋj4TrXuz/.5ܳ\tm2#OhE}Lfٽ%ԞzטΝ.5^[̢\gזv3&CpxvZ1ea m/be.DRZ" ôŪ $hy,(Ҷ)q(*cDX}0#4Uu ێaPjqS(}xn`S wnxk1hl>7X;9[G̮(u38Ο89'Wk6c[s[-A =1iyL~2]dbCF tf%iw4k8Y0=ؔq ޗTMW U A$ )IYBDKc2`^Ll@ԧ<7D!e*S̩4_Ϻ[Y=!tHӮ web݃_ qKOTTn┺ɯ7fT OR:nJ"Y6µ;յl=dSٶ(-8Qt?}a;piC'j;K3uX7ݏ; Z;cJt-i:]ey6]k+4Q{5sXsDRRqF:Md |2)! 6 STft˺"؉rAV1Abi1VΓީGͺZZH{mg{wg? nd4^Bd, dI;&ҩ9dFI#O>ӥ8so5VWUN'K$ϝz~@o1`hSt*oѐM/,=(f-ҩf;/СG}6UFnXe= \JP`p *^c,r{5rCf(a\"!#"i^N.h ~f\oف+CȤOps>-BRkWsnb[ͻT! ^h~<(Xqa/nUlPQ}Ea)J*Z.ӑq]۠4580NisT 2W}]gIx c4'`nVx}BA 4FmlRi @#4R kvq(ֈX!4ygm5Mґ+l盉(`6yo7_ <|(\Z"3%SeRB0v>Tyh/4عis]aKS7'uA3NЦR 0]S 2vt΍ZIE%BE-=Wrj`v Ȟ'n]k;rAd#B-`A@`bRp((FRde`cƙMӠD׌ QTu0PBڶb~8LMǒnQxC7K0='U]UsB7 (d%k$[(f3^{Ǿd[c[=H, @DΝCuO|0{'7{|!=3:+MAwT :}Z !l!ٗ,RCm֦|"ĥSқIީ?V>9R'3Pywj}t[XS$B (GꀪHc[);ץ5ܩ|R PwF [Evԃ8*fn_pMlw`c@rX/dKzf)SоS7l.=h;GU}jjR=^3uf .l[.3n-f~eZ@҃J0))h8kJ(2cd"W^&ti-#ᓬ^,8C$~wd,.![P::g]lWVtei>>0w/=nS[ ;3zV`ږ|p-,#'fQWk/ P݁XYMj \dA`kb|3kO8OU&W*H9g Uj_ 7'5gRs!%:??HNDk{^Ff+2#Ms޳ggLNT:˛XcB2))"< !m5a ,E@ۈ \$={$)VڣºRMϨ]٭n|xhHFeK "пLށ<#6oE[vW;"5)tLtL5K&=ҦY'Lw rI8VF|E9\Uvzn`.yfFu?&b| 0H!{%}cǪ~oy6:VXSw{~x6D隰aQI-- d N`h*<91Co?^9~hCՆHUc2 \S7괱bkԉ9bKc$*ɕ\ZU0#qDEPX6*ɨ #+(PGqFzEFy)(V|qζL4;u{[MY}Xamm003big-IѰMc!S{LMLE!zm%絽?L~rpvtTW4G]k-ᙶ9+s.Z\rdYkOeʛod׍Rn-3ǩQ++݉yDWo1'"6A,2K=jI˲EHqX*o_(OL7GYscCO9˘=O=#1!& 4FbsD!i ͊}~dhWt;Xx$;}@Bk( $ʑ XR#RL Jd롹eow25xlEei`^|w -{UGXcZ6!1G+vlLhJ|nv 5vŵ]^|4IH6\T@xy"UH2@Յv\4 agj/m$:,CrSF!3<8?*|S|F=qRFXjVٔ9+Y`p_הRE|ܻEsA!+KS44|XGqqF[Tnk n\Q\e)l"12:j+Vs" j(2(+QuHQ[l.>"g.+,i5`jyyKf5CjZxظ k(jSIgm7^4:)WM ٗU MnܕM])p{4hZpf"RMQB-;8aRӓo>YbXRvKڠ}CލyKka6^(`|֊kpY)DQ,%K Gk63nvEL][ɦB;vŊ! yzݺuO$s5C{ޛOT|m}d7j7?o5RvBME< o7h=u W#L9)j6CٹFWw RJD֗r)nD7IA6BtQ@;k*e#JHNlnlf(h3*vɷsΘ?[ۋjרmxme: p<#d.q[%Ipn($p mM}㎈v42!A2KK-RzbeFi<}@5Mf*\B4Z*%+r $t #-|d(b ^-o2^ml+ *E*NmumEo=])EHBXw?+L䨻-w,AykF vM(qs;' ,~7ND l׋sR'8VfPdȧUox>@&PXLoE :DPYAf<ݠs@-Qjq衧%xwnsYr& tV?U .śsh 5w 5CYxAvwόo~%ݶ;6gq=]jݳ=pd КcS/t܃2e_\;$ϝH2òZq3 lw)=)F̐.!(8VTZbxu(BFY=b8/ϗ7{ج,GVVO#Wq2}qqΔ.eY6Zh(aA9y#̦9QOUO3C=}ffk{0 Bp( o]M%=b>|E˖.Q(ƚlբ!,sF^0&y9. &z\;-W-h1#Lrmf{kjݭ|Ul9[nk%paWA"`2pՖST)eH]|y.O=hItMVOʼn( )-nʴ'u4~uanOu9gPD9p[?JU.șNdǎFEJ/Nt`5 >}&)Fon=c %wz[5ziKrȞ>O>08yH};9כ^_ZD*RƔjq.T޷DY0!_ wsT*{oTݏ{X~.Ӌx{uL"8"3en}+ifI[}3p=Lv07^4߾'yʫ*}P$X,WB7u:Ԟas0E0§Ѯ1F~1 EKm=me!po&& mwXuҞWP{r=uƚݶhA>m\!n +ǵ\Zww-(Wc`pa滖KziBA>|҇~N{!m6bTA.%ԚQO?N:'cA 8ԧL~'-n6=۳ڂBj V?|bGGO܇xE4;-}?.ZXD:Ґi#`Bi ʑxrŷV,Kxwjb=+%XZ9ِ' @|+Q1mǬ*兞~4V>OA{|_m28 63V;`2cYZ@#yucrmB(<|yz#4 98bqŇC})8uxnO +MA׏ǟDLy<M\X'!IgPuw.ɰ4s0^ut/5j6%*p2K| N2t) qrAj(a̔}2=k&( ܬ$LI̡tg`o=OߙW$}6Y R#d "Jfǽ ?~dX[6WdՇ=4do77jt͝+~ RauJ^(}):Q[ȭ-wx parO=HUy->g'['1huϷf2V&5y} ûڷڷ2gw{kBQd?@:;Z"G[j0'lXDޚ7`hēd}ggSL_9U׷mh*D$4/RWzh. Zib;7)H뭎vSg+=%_.[Peh[V#Ǒ+yuFg^gwcE~&IEuJr@ AQ }'gsh;ytfSx̢݈-'7R}qOE?2Vá! #ak~?e-قMIRd/.ze3ާ.]H re /Oe[%\ccyN6{wqY+;XK#Hh%g jŤu~c56h4g7=ۈRYCw_UҶvb.mh=o_jj>N~UT!봧TuQypJ `׮ q;a$z{.,Hax\$S@xV#ŝPCQGHbf \$s$f,|߼)`hؓqh8Wؕ󯘥y0F4;ud@(@fYuQ_YG˷z_vbiwZ{^>j;^z|'͏Tok \A!Fc0%Ḧ!pzJZS<}^Ϗ<5f ,5`* \NJ9dtۣޮۃS$S,MOU(99Du 7|N9;Y-=Gyɣ?ew$_w_=x J7TX@$7}E+Y/neVtAݚX+W =,cX5|?{=Q;,;ݓJ"_~_|7.Cךy(I2j@Qj"*qq\}vb z=ӴR.5oґ bKԽCڄ%Ųm곪:YeO/(> Ivxvd7[:%oE~n| }myA&ivXOӅ2I]nǧ-/:$G{k}^>7'd=Xk&% yc aBgYK!.(%lA:fwэ O~K5:}r~b`4J ;pUG$vj ~wV]{G&ҍq8Ǧ{&ua/}i]g$b2SXqj' k IDHy$5cTq_뽁J -+ ,.k X4L0=Jxe+VI&p8}P8d.4ޖNfsﬧ'N"J;+NUvVou yw[-LSP@Tr$֓X*z0 { ]EGykE9T~l8oS4#u.Jbt@ QVjN#8mHpE#iwhD79c{Pue=Wf9F"GJ)!o]wø7vx葽%<)rC'、Ͻo5$!-]DwoY4c={u=Hmfa.?}C 2 `[j̇ p}.>âim+VV]5"I 9d 3&^>lKgY®0}/V֭6ɶXs;f0]ѽgrnK;-xY,gGg[[c%)~t?3_ GLS^Xsn]eg5'6wET~i{fʴU"_ðP0@j:H u:O>V<^isfp/ne U U4oÆ8)/% N37$ȽL8n,Gͮظ@}ᡱQp ۵ĉ'k[IRiN4 '? 0`׹M)>uVuf+ooHLZjb )+{9D4ZSY>IzBVXH.R֝[-[yzlB92UXI1t^j .߆!Y{ Z=k;~])R-Q߼yDb,%iebfdy{4)cj!_c0bͿv)6Z,* ;]tm8\|1c\@!m€ f>(^2+R'sq G}"T]myG7\/'G!y=Ym`n;eڕͰ/їo | AZ16K;xL_lR*+";mQz+ 3Ƥ(P(Ep+I J=5Z3yO"wWyy!$5(佢S[S mNhq28~;$M$peΖb*Cys =T\|r:|Sm/o?fL)It08Pz&7V&0:깎̉@姼f^ז7ߔ]Pl_CTC=QoAʰa[F?DtmmA!1ZVH"o^i X K"|L)p")\~eǨp\ԣ _= #-x]߽`U$ٳtuRNEъkSjY6Ld!Ay佁[-;kwy8%Vھ*mG*8J, y%CЯK5nhp%8-:>{IWK{DKAk^Ʀ(WR8A)GbN͹RV#6޽5W !2I"o-ݾL hJ>꽳@1 j$XYfk %C3c #Pzq`}I*ÍlhH'`GdGk8{(.9Հsof~P5?~Z-E#/ J`]^\[pȨ 3N)[LNFyq aU`m9MHf#SbTZӣ`hP| y7@%aˁ[) `ѽ~;Xsi!k*5l~K/ZɅ}Xq6^WVƦi. kj)чûbzKﶿT^1ɰ`EЙ&nA "\k`rNd߶gWC?M@&R]<7#${e/W7.x)뗿nk1OTܩmU}dK77~{c [53.Dd dsdw$f g'/n.%ά"z3ɑr@m@۰zḓ &TiPHHP-)qn wɸY$m$šR!^pCQBHW*.>Kf$63ǝL@!/KY;6;)/]ITHr0ܠ2,)Nʔ.,w_@U!gU]l$*q492~*gAǗu. #rj̦SUN ,]DFk߲LI`VO1VcӠid121ùf\:\ lv6S= ٜD @2i^ђˏkM.޵ qSk"ulOk[߾btžJxFlJ ?Xwlv_})SFpM] YAJ$!Q6u8P"-H?ו*[+J}up8h}7FUXz~ <)xEە^<=&Juc$E& O`sesV\}Nw-~oD>s˩gb\^!wS'*'*;{Y.uRa|έA?q8!"镺mWxL8F}6`X}\+{Ri\׺$O`1m&PejTJܼ|!gZncOC">}?Q7%nd[)nu?}1W{.Zc|jmwZ:[H"o 7 _y^rgKh.^orCd-&ۏ3%:/3ec+n {3cV{@cP9-ֲ'gN=*Xl@t[Y`ZA/ߨ':m?|K*3ٹ{Cӟ,ɑb~ *R,TGN#˶rmj%wOF^}0̑Pm Rp,:/^p{l"nގm,bګ)cTtAeJָ7E3@6] mz)ٸl` $_}jy)HJb>3yffhkN8ғXްŴWh7#Q_kFs79-]QbefWNdIm`NbߧFEPEֆ`-Bu@Lޓ~;[ȸq\ fJs:>VR+گ쑇N[Ӓ]N= q 5s}VM {y1{.F;Z3ܽ[l>+dHs0qn-TLC2{*3LIe<$0iiDsu/*ABc3 ؚ̟W8?Ça ]w{S,KOd}Pypwo̊"2Z\'(>#k~SpbZ];q\ڸX2s*q0whţ!v{0}?>x~k?7wysGzX c2А8(X y3E(jA`:8vDF[r\ -u n]y$$+ KwɁQ|-C%$Wonu 8j8މ?dVoQh(Q7s^P@ZBRkH)W_e"3Eߑen R(F(o|=:!JUpΠ܋Ҟ|Ugpr"v^fND1x[ZvDO*.Ǽ Cfv*ii,PX-mWdp mZKE, A I9I\M[:&Eb:xv6'+{QM モ(X3C1;Rsa|lBw M["ij X[jT;ConwsSفQR>]k idB)׆x ,uILvMNKѲ̭5B*s(|LBQe)xlPdBLnM|.g]_^,qx5A1@ Gtw vzeȣ' a^^]镨?!ڷrӍJ\8Dϋ"[&R "ʃZiB63OzDpsEF$Y-`aK5΀2=Nͨbvqt4MK(!c62;:NdKg@沴C P$Q8Raд6cN\zHY5ķB?OTkJdk񸣉(2E`5FY2A,( TI"(G`M Z}QH;™TFŝ;za= ?znz:y|l7i j[dA$fGD_ ;4CYT0|jSc]*\k%UB>qomΐ3P[խ;)`kqoo̸7R#YBu?*G/?zn l2ؑFZe>d K:p/8O2@<;ҽ٫H_\.!r$%KzV&{.@.޷;{m?7E˽Q NV.oBad-W.> I W`#% А^Ut2v1냤(#k`,,K_=7eORD+W+ԨpY6%0n\ńomgGkcX)W&* ~n-Ih) HѫAsmXJRkD5#-`R`R@V"'E3m`+R@PLY"Rs֝72q/XP : S|i/d\UQk2dgleH&7EcBӣ{ 4c]`X悂<ǸRMhmogz`P\NMwƲ0;a7 =|7Vcӯlo$ guHҩ-ׯDK;GY/|-#Oo/>\>\\fx`Q۹5.95 ,dVлM!|`>+X0Z>uҙ3{W_x/'l *z'n}uWc۳Bk3>ThM04[XWb4^$w5k4TSI(WdD^چ.ihج|?^ܨ|Z/EӘ:cXc"„Cѯ>,BvPl Z6F )h}wi4SؖA5b#c.+;s@*kc1V\@@g¥` [c1@GE8F- RIPvT(;0v e "l{iN2/'T;JCv3'=øz}x>4uPݵsx3B2ZCeR]µE=gou Sm=kiI`}hJ?/NR?_+]4(sG K0+RYc~sh5%_C&w6VI]MՄT zwlf]膂5 [Xhiʭ :,O|V=*%=Tǟhw/SYޘO#GOT96\HSwxE3&oްFQ! UPw/𹇊?ho*lVhX1 %NUg`J~q,Ke4TweLAJѷ{xy;)R7_ýD6ePJG[= 3(A55sDjU~}Z N<04ZuAI6%ƣ$@ؘ%K4,JU:Ϭ{"c%@Lz-Ǘֆ>}n+7O>l-FhVR); N,n/VLZQȕaԦhĭ7z{fzeAm{;]!lKFnR>3?yB%IeN\+RHV˻?}eY;OcD5_ݐ􃋃??={DՌZY@Gcc-#`H %Ұ,6V;S@RJ #xIJ.@ {OA]G}A/*l}˃xȰV sqAY)3ƵBՉ<wcueOleM7Xqo<vUqQچ|>xQ{fjSk<  "T C/tL]RPgAyXfUlࠃ^2 bS7>M5? {̱65r_BŷRfx! ln>w)XlkaA" ̀EX>b; mJ1(h˔ CA `-BSR<|NxT>źj6&q3@.-p7+ofY{}1VѪ{E|/UչM;%PбiD!@?@q cPgZG}&1\4FYqcݱV AB=a?ms%qsj[ڟ^[ȇi+!:[}]5q=yn2`@IZ5b]KX`c}f=@`gJ}3\uyKwy~JXh& [o~?S[)JV]rcw7%pZ7 h^6`yPp-O \ntF?缢s"S.ˬKqu7-.C`4r/O۹X=;@CO\DNw:fmLTAMRqmtdr AduZBeXgfFʑM fȈY۳Lm ZS` km\@dB }`=,=auIRСQ  mqਭznMx,H<p) +`@[7^6*Ytk~U]HB>嚑n_,Ƙ(&c$l235/_f"qvvKc4lu3jlBmxK㍍&"_WWSH_zInI4#P1ȱ-vZ-Wallvha)IZ`rT);tZ\*h.& !0lp#S:m $YA 8pRj81iCL*@9HUD(X :(K@lmXv@!!4L(kBҋspHO ([o`\Be(s7FEkw2B&83X BdƐ}%{7>mVW ^; &,;1 N~|c -f1^Tɬ#c׊{I_w(+Wulv㵁xԵyi7! wݭT-}y*Pq+10!Q`rѦ*? %S/pzqGz O[c(&"R#K?Sx흸iAdZv>VژWh^2}J{JD ψ b-R x`OR9@cաm$[Zd\ԑR}/@=N$~wS0jJ :Tp#a]SCPPP5PB84ba,c&6E`qS0(/h;[D sWaKC X@0:. 3M@IJuVGfBPiHZŔ^ǩ+l JP$Ѡ]BٌO^`0̎'wDźp{pڅHYWD+O@P}v~Cr֦՟|uRSmo?zl{rKBn.n;]VIYp WilC_ #4nVW)2SΪ`)>rмs|_,Dfq!NT >+7EPI[$l?AO3R='g6mQfpI$|:9 E?ʝmZ<޾mu  ~t+B 3˻p Ԁ[ńJmwSmڭ#?'Bt@C A+ﳂ08D*Xm &Ts$sđQ% 0R¤!Jt47`8R+!( * 1"3ENHUh"0@vm傆LġVdJ.isRq u8h5Gox;3i;:V7{]VմESY)T{hG*gw鉃{ ak=` ɱkVY7GZ.abF~ԭ1=lgd1+KUi!~oF,gZWU=/APmC} y{ذ_paal͞3g{?OJVq1L :X6IgF:~ebz~q|VAז4S(ȳA_&WiR6>_ѽUEu+Ăq))1p@TS -uWѯtܝj^~EN *~D- Y!Ƣ`@JHm0O3jbx9 4aH ml"Za,tsj>H+hѫ?. ښAۚG)ukr%G N7pQRDB+ p.Qlxh HhQH?N>Y ݝ*k(`wz$ac$kE8gx`9`AZRlX:fw}=W[˛y788la3)4k'33tm3In|`N^<}֮逃|;ٮ//x?J^~]X#JU]nytzJLu(ZR'gv.% |5B$Cnv^^np=Igμږ!žnLz!~E?W"ZOYS#]},Èx]헼ȍ[P`PbbÜ< +N<|Ы9b*4 UNL |@3zpzڼӠ99Q<=:3oQ 1Xʿz7kL^zk/mLfo_wv{; Kͯ=' 2;7"(;J~i >^ xUS%}w7MFjfz1ʼn@Ӆ%7ſz\ASa?^$3K[f'0|=],Uz'^n=N|@q h)`D!0YUhu59`1a uvl&lD~[E#k6e>Pƒ\EN97mG$UImv]'gA q>HȓT]YqE%`VxslEq  -#歎  Jʐc|fD6%'xUw,PVAüәq,2ɣ(vm{T 蹱.]j!~'͟ƠI ,ݪ̽^m2ln2:Rg,Hk RX|Cm9l3#c /0zG-E+=$2do"5rs t,39~U:]CiHq˸ۏ ?z?"oaTTR!<Ϲs&_yt˔@<∪']+Xڬ ||J1eXJ"\kLA-c`iQjlY>(|>36W`]P0<]?ix)=<<0(ִvij%?|K(z~ - ptXw寜׶X(>rD^xȂ12x`>uGo bs`/BRgՀf3o7ڹc˕WHC2$T&uaKtg94=Dy$ecp]"Gq뭡ί]4bɁOolP:+S17/jՅp{('dfu|Gו2Vq1jjրE`2 "AՀ/nZi*hCp F e0c<hD!cFXdԃI n*B~KaȳiRAUV4ix?R3U^.QͥM)iV$0{vvW{-~w Oi HyVPRYRqaq7YajrH` GUK WvhAl}{]'SP,MqCn|}%v9H}ⱱ6T!4e/3=vRP"wL?~k{RGn_}mCVe;?b+/(q!3kwETzRpCwF3*oվ6cr5j њ髨6:d5ee:xl0*y-p9,~vquQw5Ac?__9P)6[%X)l0͙XSDFC=#Sy1a_dVh5"p[drntXj@`1H(e߂{]*npY|x0 =9\a0܃ H+]SN=2/ qןL!=4t`%+t5( =r鎼; z2RxB}B)%͔a?OFtN|4PF *~ysbmbÆ\;Mgɞj465@Ml=yڏLILթSo'k@|`"s9av?dخ꣏hh.$-3uov }3pyCll9&RvEm%j! EgDWH}߹nb1`p|`krmF(Juȩʁ?AFwo6}tjKIheǖgh!;8gFD~aN$>a{: xVw?LaZ-8&,Hb,'>/)GogyfD咥gͽOȵ2Oj.a. TM* B18.^Z>6nw0#'J3'S:ںݍvCò4x**,h.%Nb:b^Ca/|8+R}pPQdfMqwgM@%%0y1>Euky 6e6~?[jAՑG *hоd rPCEA/>ŃF[kd@5 u# לTka:~r5Iy]n`=}0W[edQ4Lp[Pҝ>m1Q.$bO>}̥+ll ҋiS _oNR(E!hHff7iʷM9Eб^Xsuz=;ݼ}lvA2׵MCw~hCS|JwhMY,LE,@ZS3i=u_)ǡ2-Ӭ~o1}sѻ;=?Nk{f״EB\ f!mOfm(CRHtއN%nKL3GjĢyK߳|  ͌]g9NGt$W/c**CvP3yݴ`:EG9(!9KyYݶl*rjX@Q1H#ej5EU*:RNu_i<Y!fY+>_oPH`\166UtC?ݛ,@(rՇ'i㒈cXuBT~H`h4Z(CpdVy*,J8k䏍t`_ʫż6GJ_&G4=ޥ2jfzzz%g8uX`!+ @$@ (r1=6]d>#"3"2|wKH`?47)csKTfY+uRW6igK:T)O"W`q@#I@+^{#t)X f\eGo Xx>Te4zķO?=EYrSgH-|u e eW`a^|9Ao-}mbHzejR*PœDZ0rHcL{C/;O0RG#n"uk8@Nu3("@B `BU<]U+!p 5iz) ;āHÉG}gi(ZW|ĿYe{ 'vyud RH;'|*(/h X[+Jv'Q?}ͱ/~dJVۧ߻ ]&~lWLjFY%NluL;ѻ܌:^jK%KZi{21،w烃&bwвvMٶ/֋0]dv{Gv˴%_$Ru&op=s,L:㭢~rJ-Bbr}xZ%#V7y}×_p]o#SV$xd T+, QfoBmp,Lǣ?};]:~ա,{ԚF/ wǷnaQ}Z5-=mw=tqsM|Ip`Ϫ?N-p}E;פjg-i᷂G&" ^2Tg?ql*E@'(2EY/K¦ݹoȃ,'䰄 w>%D48[ PJ搝6rlJDEjYJܝ'AfwhȲVs[!IPW,ssé;"@i<q0`:ꁟlĨ1 2HA.qĕ?>$~)- J\Z<yݥ ?3b/`nYt;pBӣ09,$'pnO_׭= vDAj.lS164Pt%ПD笤`7ċ0q\)`mp8@L^" | 9G, 12=7nc%&g(̀oIR54"c&b@hpRoK+;B0] ă!' E !uPݯscSϟ&`A &j{Εr EH*VPWQ=J)D,8h=O$ !DaRy:˝yS:"u(1xڅ>& }Y]* fI9Ս{n}xw5[Uf2~/, iJ74Ш3GoBy&x򼕓alN1][0tlt_EziԘPldoa7çOKZۚ5ۗ.~bd/vNsy81;`mg֕cd{ZABVI1weSaʯsƿqpzǟzt:r 8 '?Eߑ<,5cFҲ\a.p9}&h[7VΛIN!$Sbyhػ5=~kx7$/7#[AhIN2pt cz!ThB ]0( |۽3(Z` JJVH"`:_'vRr0#Kjn>;ԥx Dum88\] ZsJHܢ>'*-DX.}{KyO:,2i8*2&`OIͼucqOt:Sk#&WE*a%р3GoYԿq6e :]Oΰ/.웚mIsSj>ź^֎oYZxp6Þj dO!,|/+33n:0.OՏ@_f`ܾ=z*<0vvގ %͌mlY▖*$e~՞ 9[#ޠt@C3.%{&q t&+4q]yIxl-+2!ڵΣ1] 6fhTpܧ]GhD[?&IC2z{^\O?@{1t&(qrT4N?z?67M5Gϐ_}C<|hm\ w;QkE2Qn^C=7(/hCv,,MQpp fU@GM^f t?CT#pOa8uϟ3Vњ xoXqEhS[hRr^Ư.`Q`8sZxQ 8 !7< C ϟ:><:C0E]èr{ENrUk4q!R1!> O2#c1"%riqxƎN?)2r@ "9LʚjM#|95:u07ÚcA 8B[1y-FGXap J=wK/q2B-I>yD܈@wԯȔSG)Yv"JuP.d;Y w7G0 Чմ_[5|NQc4^FĨ8'EHp& JOy/,/?+Z|ZKK]δڤ|߱ œSsc墊Ccd^;` oϖG!M&1K$ 41* ¤MP\I& PEpI $zBOLڠWֲG<(Mg$fJQ"&%wLqs r B K~aDg36:27 89S./䍞֤#6$"HmXā%B~/4yEy ڮx|x40c%=4#xCy:c@d};u0:F۝a{[l{ySܽQH(FD7 u \ LP5Ȩ<54!,SsqᔫWScsy%XJ ~i kPDkVH21MV>9ݼ5p[:PtJD聦b4; - +W^o}0eJK޹~xuUFWFɕ[v=NN6LWek 8syxvv<&UGϔ @߹ G${ YiuMV?/nr2 Ј`C1ms4(-:;?Q /෗q9l!5r X1"Ah1JȎsc 6J{>%(&~aε-+Fg. RGQ|=b! Ap|1\_CgdIh w Hؐ0EzbϬ޿nѷ?6W. ٓgVu 7r u(sȑ04 M+Q~DMTM*b߻m6j;ݲc1iHOLlB :jCA:0'U2\cfƕ@JK_^SD§(D xmp):b=VI7vU!?X~ޥɘJ BPFrsÄu7\LG!Qdv&-OkGod {_,$  ƠAnK|(G'͏$Dҩn<+H  =O{#չ&Hv9ƘT y w^qA'Q3_@qHzuJ} bI|w:EO&/ioQH1`H$ͺóp~[Qa1鸾3 p=n*/SiDHPƒq!'[DG^fMdbmtE{O]NLNٲYFLȍ[8y4de 3gT#Z'J0u8CGkL &:_: _=kr/u5`E1ږELP {0FI'?~}XfjWȹ9(Oٮ nٕxЗ~E/®~ `XԔ7\ᄀ pw!űˋK cU(|L[ϛEI %T`v 8eP5!LOK}_C@Ê $EW_?it %o-NX0|K.ϯ @4n0^P5`fL7pr+]MilS`UQ}'+ͮ}R0 g8×hIIvPi$py2?!A7},{F<׏nD%(Q S/`Lؙ#l_ᵚQt.B}P+Ε,tnkg(KMuc*ڧx^9\h,H(Zȗ7{O?Ѱ CAIckto=j% )܀+R| MB#a븸cŧ7;.!0CUⵃ/wr28;^u1MȆ(HY["J. am%npaUxY;ޘR-~f4 `xV򗟚_ۆ(6MiY]6I|A)r_'vې{*|fĜ8I4se M\RYjMz*`"@@hͦ)q.n;k86s`M3\a@3.Ho #-gS` .rm08A #̈+pR>[P͖񜏼+}J/,PY ͈N^IX0q0qۛZzt!WeOU2C9q[I,VQ;HW-d/{CvXꁲJYwKFle$MoX6v! y )Bf YLCI{ih"f;->^&"'nO0k>b+Bd9AmKmgvjaLR)xLx1\_/v'ǎz$qdCNEf7;޼msm93n{GŻO kWwZ5fu%N7zsZ1 +:LadJiV ʴC>!;3'f†q0p9g/)YUnǁHۊ_߫58'KZo˫Ck88* 咼W5$9`=4> V8hDAD 4; zdNփ01!Z1չ̉6&)2KM`3'@"FZsN[ !0qhm [7wcJ̒"Q׿MWNxZS"pJo ȴ2|ȍwސb[qdBk%YR¹BRk%_5̀«LӫK_vRoԳe/YB,s\*.Q>nc4 ɉJb~˒Ya{R5y^Kh6K2CzDB:|:00* IJLuxn{eE> K;7Ͽ [VmugQߤk9IS8x4xGYYuVO7e\mrdb伭JG~8=(Lhҗ˽_e_lhad2𜳎@2`xm7w&tiVʡ`.V #!0Т Z5<+6. \3tI6EuP!x%lxH bp6Ox$ ÊN%GSgVn[?Nkr4 :*LҚͼ e&"GoAbV~iZ* \""1ܳ=m)%r_OU7{ͬpq/~h=HQLhEnU(ZbQa 0΅ l_cm2Vu5S0{6"0>V87.F,ѾOjV.ӅMvBH¬s8] ZPdY@x̔§>-0(N ݃uE,>T Fv*-{[@U(ԠL%,?? Jvء;xb፟N!z_G!6!GGf(.޶ *Ъ"Ju 34R*HiPF!%ZehF#E.pv%ޅR-3,2HG=Xt1< T&A9aDx@o%YGP@K%8@'ZX P € COCtA.|yaZ{ `ѵ{` Fsz:w%a; 9r`z7@n@- I8=~|wbd ]ӏl4ZUnԃ Ϳdu&mr?(C F z"XGp Hp*\cmZQ7<}/_1W@ W=9ث_7'3:YYꛍBΘC4֫FSxM{5 ^N4H8PB!XK}ƚNщ7tpY2$_Cp!ePy2P,zI ZlBMO)kMbNP< 2&ʓ.0f Nz@z}@g.AbE`fŐ Z\{+_"llk .p A5Ϥ:i3@h<[QT8g>m8CkdDosz9J]'Av?Jg5AX)o֒fR8q-eR^>zwk=*:ޱN{UwK8z3MDH4ʀIJ|,V;1Wtd'43'ū=N: @,Eg$K ~}`vdqYoI= 3$RY)%. k!#0*sc=+B?&j# A +1c/cgF]Z~Ag"9(e`M{;~sҊ.OvHiQ31~2/%r,ʒqG45=pvp=U$NsNońp$"8Br0 +3_:o}gn_HgDxXԖĥ~Ny4ttec߃{̹YN1- ,:@q3c1. '~_ ; pe91AX콫y^SDL* x#M\}RՏnWÀBCń_wN l Αs[$MM|GDˋ8C4:Àd .W&~(8  y}^N?q>ZrmwdڽΑ*&f¨or>o+/`-% Q фx{xK})$t{*{ΌzPa[U_V-T TxCpa+;} #%wJg=18=G9Uu蓍^<&-~ku.t[ wYiH#`*3;Il@ޫNGLEP8ǹhY~3l-ujbMI#$2USσ @64cq]'^?Yc6>7p:Qf^ .PC"KC f}8C":NZXtBsn8_kҤ>x阯h<x~ٶ$:.j (vD{P lv$ eFzO"e룐O1hUN򢈁 @x $\_iIJ!h`@4oMq:k,;Fݍf׾J>-HM "f6-:sB=asM&0s.]xaEuǭ%ؔR/[[:8z :(AGQD2FNnتZ6ͤMa~޲yv@A%N8RFL*ٸnX''?47,ro8^"e dmFy .Pۈ0"u<8UרEOD{>3P#[9 Q{UԓE8< 1X RzX7 qjNj^߳F\+&e.bMO_I0x8;1y,GB~vO¥nbc v(~rruެK=w Rs1kc\Qb=Ysy 5&N?WK)LEbcS΄ZesMZV-;! 8u겅e$8u t_~(>Q7'A!ntu_<]ZYL?KSJsҦyldZMV& lZȱC߁a!_(_MVyi|3ZF"9M{7W B: rp!z)1ȾYK6E;`JΩ\|(^"c !-."ʙK[t>{CE4}Qw,634]Յ2VB1\tŗHj<gOk2p;zZ3=椱p(IÚͥ_)?Js/~E Eg;JgqnϏV!GoU,ƅUP8 PpTF]ۡC4d`>VDsd>Wԕ׹k_1?'`TK4u%lZlⱉl</c;-!s P0cUf6{/ck+x/Ѻ^ 9c꺱[ p)01պro;|ݾ?ʖe!1 :8p*1,A\ <,B٣Ћmݱ恣;,Pj ᤡ9*G}!"Rg:D !uDPjК[DrUQcD2m1BoVvf}!em?- ^.ၓki1t<w=SDrht3Ț6Iz8D\,2hp{ggGFڍyO' d|/Iu;3Əl2o+#Bc;QT*t,`¶5/FGA@pC9ꢷD";낻0k,bY|ѥvO19߹C ws :o|ulȧד;w@00FBbc0?zΫFݖ?z3qP|瑺31 +B9WhxDek1^׭Lռqu_*oCR`Pb0Ns>tL̫i;GsjCi =bxKۏBmK-ӖQ!xK!uZ$ ^dRFQHRYh]*b@H| z#rk8vy3r)l-8nd!sD㫞%1=7bb4&xǡ'U<Уtלd,(9xIz A`4Sĸus6 N)t|^/Tn536@f rE>"?A~T)QJ0)\Ċ 7k='NLMSw+\ Yp&B^Q18*籍]@R~&Fq {((j$%g롻eTyUЙSnuWzdz=Ŭ fj\DR%ֶ#_|槗m̟pD{s1Ug/lZPa]Vey. f[y $Y %ķqx}ǻBn0KyeQUxn@+K#DYo5dZ9c핮HG ^8` @14AP>OP_PD4BPqY>,SsZ0(P[X@gY0 q+9yLX-8IP Q_߰V؁s5;-svД=() :)]"hafPUu֧ N)!M, A) u>jШ{˿wHF`nM;VF)O%Q㳭asN1 B*ah`9с`{Um ^^ua=~*ְA^?p&%ؒxO?i+<0`3_=>%92 P}܎4=O?rË.)0hr9ϥ /0Ae #Kh6bEw BDblץ1<3MVC@ : P?'nJ.&vns+nG`ih 6Xtɇ-h 4!PFP@x=: Sű Xy Ηr ^ܬ922]K4MƅV ȹf5`kwWAhL撑]dG,[Ff25ikVH L9߿]ϜGMzS `Fh(&Gw6hvyV- hC$)8uxd g#f.^Vkdyj2d:, >Dkۑ71^Rev$:]]f''},kf"q_˧R n[ cNf*[ HcU.Ph(#O铕Ө}.89<6>ya6wIznzjNFGrD@NXA9,bٍa)lm"d[æ9(,"Nx4&28O.oKRhyWe )O2MHhjBE' ?xW8εTqOIKXjƺ5{{UKoV?1U8Xi缮(xο{zwc1L+}`zoZ!+A!Fgnϰui0cNdlTxÕޤ 久LRq{ %z,E FXV+b쑽ꛯh}n4=w9AR=|KSj*W"ng_E#2"pR2Ajv_pbMVWO޿MlI!NJ*f'yz(EvY7C0[2 P=d-+SS ~%&1@Pv VdKmX8,pQDPC7(#,<,N3oR}p/]8hk{6Vb |wSI5&vv[]H :f&WLiuh 1G#G]Jҟ5:8~J/F;[~!W^,XmkO5($fni_]9 <Lи0H(NhgC7TAh"歙bgc'+7n 5MRkZo>?V'YGunmnj֚2HT5GJ Codi-CV8w$Z;,$1n4xSe[ 0),J:_16NZ1| FG$lG7"c4fmLfSpJh _u>-cF/ϲ=ՒUEQk;@|NW*N&_iYܵkŅS;-yC(]^o?Bn>tkcwOgN?₭:o jwO؛r Ja(L`4rQzv ڳq>m#6Ϊ[xs"{4$Zoy.Y=^i>lQH۵,Yx(oٴ/=$ӿn'B/FIk{,7(TJ~e{0DƯ%ٛ.1 Zv}tlD{ogys\%Kh h_F[SbޚU3\ ~g1 iu!Yo\.)&<'5꺾%c;X60r=Gj^ C\Z1Vqd_*6WmӝgYMh֢ۻѥ]Sg6v?LF2<|vt]wwʨӯ|Z싕wu/>)4VLgB- dA[-Ga9/~$`[G'$LOPooEGGF<}g s92|$bp+Q ~|q(m;-Xԭy8j7vdg^|B`ʤl7qAWɨj6џ2hnQ&l2e>o`[ :.uv6w+<vFwÈ@OG4#6({Lw;^?|_={%&Nї^)֔vi'0' bduB_f&K_7\9ϋ LN !]UTV;- MZT>OYI\kW$ݹK\9 ȑU V/|EƂ&Ka\=R{դ_Yec6Yzx9I 0H?`=-6fx>O}>+ݿ*M]Ha24;GJ#$A_%iod۹RŲω'/[֝Wq$@׸Otq]K j s1<2"ig 1*,_,30 EEmLgTGMxsI+ 6y4{sgY<7ܩ֞7-jZ {^#yq+*AYALR[#SYsMl(UOGڝ';RI|l`;ڣzQX6kO:'5.Q">/?;m[.n=d/?K5__hB}.jvwH!CUq@Q~`G{=& kik Kpį q롫 ]z!xv%UVk$l5w֯S4!0ڱtWC8 ڧt`"Nqz]3nyՁ]IP?!Zy6A]ZC$r7+{d]C쮒gX!Z@ņ_qkU.u XdᬒB;;v>\kkSƶd(DDmԹT]5wm&?EVuNܚPRhBD%Ԧ5t;BF1Vhz)cw,ޗz< IәaaQj }iMO-Q2֡ŀІ R AFJcjMFg-';K#Kh48 ys9ޖ}&sRZ)?qzv+5%CǔX~,pnGX%0,_%^'O2(4eWlq}D>pخ²dJM4n젨N&`g]$U@g'=tْۚa/޿mf=0 %C"i/;7ڼM;1:XFWXF^i#3Eo2E0|/tl1) |,LLy}q$JPefl4gm!Ral>:9O -Gp X5?O7rK䙳|p6NouMhvӇ-%YXfQkOmmܝh8i7iByv3M"-PHGSut2iԊE8(ۿN w7HYHW*v(3PBCȑpcB`˫!~jƴ;jEzuO7΂."1>i* -g_^Ft(Y<$<%:6<e:D: N4sHzbt$0BlJ242 cӒ_S¶;H~d^?oa? TIHCRVֵ~ Wqb3[aJYD 8'zcc@{,+sb17ŽcrN#("4D|Up_Rكbg=hlK[{iu a5DJd'd< q$Eْw'Ied=ꯊMrZ:WV\*M''`W:U5AR|lbnl⨙>/V*\G%ƹ@b`Q}IP0lOy̺\XsSs{A")wrd(z16ք}I}F62Vhy:4? pyPtRa(0`Hs=c|`~.Րv,wȮ3k'Ma="4H*zs6# z#t#/Mm%"ɔq, `4d(2LlHU;r<>7Yk6 zr5T S"8Qbr0fƋ{Vo~6io%^h``8:W%q&/?3mBxhrցʈmt,fT5鼽|^yP%+ @u,aJ$ۀpTfnM?#yxE@M|k.KGz^#a?%\HYZ9:Udn yBNIDATXMr&ޛTnk L~Jf_[^7_R{O??tx踔zՃ#~+_5B;ׯ9l8D;{(sP-+zK#RURfweMGfb'9ܑ닓q+r I/{ vWحl* +`8tK(B(V*ͯvsB#z=Pt󊷼}nG -Ֆ622y^ԇek5T[m+QJ;k=N[ b}VJ;(RH;n S-ci\\78I:@PR,=~2EuG)>0F>F2BlUEZ)jm {.Of0xt+W{jOۻO43c8uE |Vzr\u/~UY C}[ҸurUٕ +s77T<*#G{ڡ '*At`_+w[/LDUo|\殠U~M/y]tc;V9A'd##Ox!!Ei90z'y^Yz]ʡe}GI 5fuK7ų/_`P e`^w,Vr:9t|" }ZemeT'Dv1"hT/F= 0Nx%~]3:!F!u sI%(Ls!suG{I=$Y&`]}GC$'9Ø,kpn݋0yd9DDWnȇ4%5]n][̋ǴM0r$d.wˍSoeǵQ[xYbJ$eY!my HϝmW~$x+sR`˜L\0W\Iԃ;o}gvw_L sjvưoջCE~(ZE[g1u5U~VG]VrH'_(Tqbjv+9Q>/%d\W3-LGGvn{6-L6w>}-G{F[0n0Vk(w黄8+%a\~=2+݁\@2EʱWɉ&*j @-!C j[ZkfAj(Y% ,L'a7~2*#±n[[e^+s1 GQ5φr F74?̾ heˀGǣ%;E[QV2:t6J뉱7gˋo͊ۖ0c]h$O3ӕђjCXhB Q2e0JK4z>T _Wd{^zͿ7'Ïfov\nj. L!xI T|'놓έ3kp;:[Y{/_Kv{io7(cYRP퇺U2Oe+d~9ؿ\>{NvⵓՈ>"poֆaio\)5F^~5=Ե?Z/GZ_r=W!%֯ped0ZGwU:{Ogw!?7\B \׊Gh9}mVF}F0 JY bnhyV>e&s臭GK1 9w@5(!+~x6A] ̭#wZ>2.:, e _*TS|J8'" ] rDx׾6Dɻ %Ȃ!ž;1UjU4x8qMU`)/P"gW9>ŲEp8%9&ޯ)afsߌݽie뎑x]H2"$Z_ N_:^S^W]Z3O=zuO INVjU!!mVI}e>8q.@=5Ӎzަ;#6GKH>8o"0;Y?v*~|c~-"LI5 -[,E7s`u:EG\-ᯂg2=G18P*2p#k*AcuÏग2E+a5d'NOٓ'b扵eHc qE-<'4ږGou_dioHGckk4:̓龟Tĩ* {hμფ2t7M(X^*vąmY>T+< -Jq{w.O8`Pq}x{;[#Xh^@X_S4]ƾt^=sȜ&iXnmizI'Q18ehƼV45gbcYL+٣a8߿sQ W׋C{ڈ:(/o<~xy?\F{7zAbg%ր^?uw?|t~|Sܗ،2ty?6SS?gkx}f@ wE=_߸١L&gwF,~m.VT]17zKOfLAw)-٩'gڝ=NFP]n[͵1 Wwߋ 0IOc4 @߆Oyr^5ݧ ;/802@Mtﯴ7AV,uWQjm-p|v떎xlwyxv7tT>p+ÉBw|C_eop=82#N©=]%4<(q 1ؤf[vD}KSFHV-D ]{Vak 1!o=E%{ e">)C) H 'Z-ZR#\ãוȝ0~{}T9~ۍ0Z6 mޢ j1JbS?"Ł /y`gycsQׁC`מz"v[( F|hu/Q"*aa7qW]_N0o4;{`ZɜG>b;4-4m^wm7tkZz!Å,z. dVw]/ @0H6D>:7y,?{Ϛa|ޓS97F`r(1(QeKV֮6ԖWkK)"Ma8CN 95s{;Wp}0ziңKڣמȑ8G,J74P_\SnfL ˿.M\%H}l {6/N- nRo?7gե9^ou{~xdA=vJ{Y<4׫^9CMC|a.I`Ӻ4alskW(IgX_{cr p&im]dwlň:glCbCgv TKecCa%)ْږB@[Rkzc_l*LrK`hvo,C wacBN+d-&x U'zs[h%]Vp%u{v{ÉrCᅛbNZ 镤Gu͑?yUfłG"8䞜綝m)&{AO$cǎ4Lg `+m^X!<:bD0l^MiMPJ[9G[ PLpȵ\#mUj% sk8&T**v5K l63,'9Wf++RwRzG*S/Lo˭h{y',Mt;S/Xׄ7 {Gf*?7RvpuyOn3ވtmIMTw{U# k%6n>ΌMC%d7" /q6緦&s_ 8udžV=xmaQ&t*/7g/~E6w<#9(0Jɑ2c|G9;*,{'،P$,EZ gX@Hb?~An/xyn:h 23I[ Y-ܽ _|V{z6-}F U\A/(ʪDN! 6IZ (8 Kb0&N` Cn.]"h}b~_Cv$ͅ46{ʨgݪ3=zvga׿Ou"⁊cc)Pn]-wWeo~ [3sn?]BDHH!tS UsXPE4! %D+FP #.l}ȌrY0-9I|.n湉(‚c.TksG_>>5rAf6=\_Z/4sufǽ?q2ǁO`$rҌW7ḕ%i($]/jz>(m=bi?S2~fT}=~Ƴ-UV(ʎ3hT>Xn߻?OT9. mM,P#+ JD^š—N%d8oǂ>[)sTCXE=B)VXHc5i;}%TU6Wp[y?qt~௠BmBAt/NT#2:Yr!y `bUtk`(%zք[+כ_V"mhx4[f3;_[d2>ï%)6F0kz/^ٮۻ]щǘP1|t/EOi29D{/rIo=|-m¦ ]`5_lȀ۟F9ꁓ][wuyFn orcm9':zssR0lw ŵ} ?/_y2bWNbTÄ48kϓ믹_K!3jD ,*L21 iI]%.'nxN 7[ o1EJeJM Slf􆋈Zf׿ڛee&ugJ_V+$8/hݾSG֯Y*(i4qV!<1b֞M"^PH,4(cuݸ֮Eiuch;FQEhh 3޶Cj[w{.Fޏ16-+F2 k&>Bñ#d7ZB5Nţ 0񉕹 /S5Ip\͏"L#_.DxjYQe={|Y?uϑȻ)~v_>߭QT/ܮtzۂ+6g8{];Y";+L*]iBa$Y߫ϳn`QF X&δ:QdTVZ_˯OMwLyAS$:=/7w?v N{o*݉w}@mv7 d]fS|J&>۫%IUJE [+Ոd-_ߺ^5-Vݏ.Ǽ||ށ݊q/'yG_7apz*꯬".y2eyE>$ƨl5 (:HU (XbT+xϬɦ meTtR3Lo>Ud]컇ѥygyY%FVKXCSd"i"Mo)GXU}{3WӋ $Hc0GѻfUu;.I(5" XPBR Fz&pݫX$٧/G[ /ĹnUo&Ȫg]}BSmչc9\g6bgʛX1O^]N_IT#gm:zjleԋƆEK+Sq#MZ

    ulC!Cb3,lG*])AHb%+Fh +0h OHC^Z? KUK/Dk3 MD#ѩr7:+=a>وd@޸\v#{Jhdp ( ))e[z~Id$fEeo'6oc-$cr=ܡ}C,`Z0?~]ӛ̽=ie0_̂jqV Q4e42:utk>o .LD!Dj%x-}?PICR(/uvZ3&\ mց?(Y8 P?"1 ܂ 3m j)jyMR)U5(-}RyPœcyW>}<\wߎWcC}7JW7OebtmI,oN9m=1|6৷V2K,)Xݒ&Vcq4j;W/^K`+Ex_N<.;z=6F?6\.=Zt]DF%=QQJ-k3TJ sKk!i l e`8h<3rke(q$(Ǧ : z\M&.~Zz}-p E4Ҁe!SX `iu%Г\gf&*Wf◾U8qh176w}lyc級1lTݰ&7skX7^1^ :qJn0ǥkJI$+=㻊H[8liΙ5J DBzK=>xŃ1']J淰3ϊsZxf ?9{8E5 XOp6e "M9(IX:j Q.;^-JpzŹ{Bzy%_p>VĤss{i}h4jʶDR 7Jsĵ]kbrkV@(E 6RFHurjo:V90_rIr~`܋~#e׈}NI+1ƐB\F5 fg415D!K\úKjLC#[#NMQ4hVkq }^߿j[=4Ψ\@-bASld%ER9/|ƅe rDOk_ȣfe eJ|( {8ndm-l!ٰeILn$QԪ$6XPHӨ^)UGح۽q z䅢΄wa)&{I:`?ai(X F0٤+!gvp$k1[)ftd,":vW OT厄xMy%H"8[eLI=D)*+.bl1pltcC_4Mh?S;IB^GiEe[_vJCsM-(Xƚ  oS-zK "%#w NN8#hp{ZnZ5D6L8 aml=mJeLNYW`Yjo] :€f~i 5 ._%&Eߺ"Mm#mD zPشFoih"!ovu e@ƝV?u,Q{nY+Qd@^' =b>y\<Բ,YPAȖم6$qnhY;fpWqõfٮ1ChF-,@3c+Ot|UBR \J=̴R\%Љч2( Dϳ1;7ɳd[,N+bK:V7SFl|3D]\FneIc`Ȣ%j--5)9`T<3L[X(_< H~Qikֶ #7ټEkov95X;\T:7_8 I*ǒ4bM8{j5M1ݶбh,'ccEMrWIZCTiVӼpgN5Ό':'H097k0+86?{k(W 3 7u;±8Jr^(?|Ϸ2kWyy\#ReБJ9uM)]3P,uǰѯ+Y+˂!qiyCp;6]QlUn 񁁴÷RK}py JI]:)LK"*xr)k,0nu11 PJHA`M@mƢ+/-cA]&3?10b\i] ugĀZh]qhP )L:.bybTQ>d}76׮DR wstu<2f>\Ueb*Q=igT\ljQe:0F Ͼ=)]_\F)[lu6*?x'/ lrkOf3d~\_vfqpg3Mm iO]6EwF3x5^K :?}Ouʨ-]cӮŠ  +F`v'ӌ7}ϯls*uUޙO W-̣G\YNi|%y6ޏh#$S2apβIwK8IWL};3b aȔhȺB1K7|7G#"/aK&֞I 5wډa>dB!Q6ճ'qAY >(b}Ĉ̙fh6̸!Pd4VfurK;y*Zl+!)\˚VǶ3QσԣiIl˜U dիfYVry&fحNHޒk5ĸ(KuFsW9-Dmhkەiektq-S90i`<mg.2Z9@@64R=L>j]0^M1^*MLpW>-yn tl_ͬRJb c+fR჊AڇqO'{=9~⠆] -8= 2CWgSؽE7șL wo?՗16Ksv/=wS$H˙I5q2f.SLiflsA22 *xUzY-Fp3Jp] 5(˹ݪ0}Cvv>+ny.ޖLxe- '亿Α H';b07tmx>wJ+ѪRm6HJcJr)1؀BaVNNJJBGLԜu}9D݈ʖfVTY0"W"RV^I*~qWC, g,K+a)Oi =9ogMVND h Fxјm`Ǽ/\KKQMz OKu4 ,|bˡaſJ_oؑ\t}t5 8Gz̴NB]QryEOo"ωyhQ}-cxr?F\g7bT6 xϳcOA#{0*mIB-Ӆ̍T#T|x4|PK-?c8'?0$DtJF{ʽaiQ:1.<Ʌ{_AFӤ͙8;Id6`>)_^und@k dݑn=.}|>^K3YdAR$SKbkRcF–Q$-#vɓlhq4ؗ$w,75^ k4N-,&ϔwx^nqZyV5b(!B%P3T4TH=/?W,r҆ÁɇJn 3*l5 c|={Gۗ#$hLl 0JT4MUH PZsl>QֽLKVp44m: gE5*͂ww5-Xq{ul"Q`ݵT[1B #}̣Vv356dI+Ě_s,M6P2to;:I.JtZR.ȀA)ˌ iKܽX}#7gf7c6P}åja32ܻMdt SbBw{̼D6G,ʚ4 |:z^ů0@=pffgARAf\6xR(~`R "`$/gU8a&hAš4XNU۷;'7mv4i$(y_ZU%C[ZX<dA:y)1#G(CEʀ15Ŗo-H,+c:Ǿ;'!4dĎ;Fce^zsýS^v`7k#1az~ '=(WRzy/XT!2+.f{~ !ߌeXSUw{c R)1nZp(3\t (ca–pV|3N.Z&5ɴ%>?v=yZ=VD,vp;}JUm7$VO}YnlFXu* 9̤ k`&RYf}/=Sb]ćNw6oƭG=gJye~t:S ئ U`NrȖFnz6NS̑ IPҠG" 47@>`tCO ēY;O7״RZ+YIR/M)jD>"/4~Is 8kZ{bD?:&<|L_i6ro/KZZO ʜ ƿ# )ݧC'G#ݹTDt񏬼vC=?rAe{aZZ}Ѥ2a4ӗ *TM0+qJjA_ߕݏW_LE,r1~S"%S-~a9P{N@=l)sXӌQ^ ɧڒx;a䳶Bu~ϩAF[r @'q4KK̵J)F3iWQ.*ݧL߱R#+y3衚Ӵ{n-j+Tp;c޼wFoM;!b(n K*g'Vca틏F}% }Uk}g p%I8zdy_OJ>DV!+%̘yZd˸P,%Zϗ," РGR&9YV=h̘Xh͘ηCԞe+2Vu55>@r8 R\E@ܚH|>fӺnAG);u|bG`zy`!H7"{lj5\RRc]A|9 ~%+5!U_&N'{k&uMяcN$ʼn9/O\2F#[k.-dǬ:\b15F`ޕDw'+/Ͽv ?z7rR{De7 k-fte)!C3KH6V0=nl J N:nTi.m3ߡ3e^{W#vqYg ŘV3Iayy^hf6mrl%sdfH *y l_x8W!^*|Bszse޿FngiP!4J9\HUy2F7tp{|FʘQ> Gcpf6\QjqfчMguͤY{қVsuַfASB5Qm$Rb!#"5U#DB p =v$s6Tޗ~2*ghY#cVΞ3daVRI#Kؑ$ִhiBQDQǕxKV?|W쌎w/nkϒx{-p?<7ݹf Xc&cZ3EʉQbe>C.]hqN%)S'hF vdg.ǧP]H|;qF<-FV+.++QgEtcM>ToA~)5cOfs/.bbR&iBiR_Ugʕ?]sI.M$hjrD8k86jd|#}x9mC85rKlf*cX8Vybo?kB<ŪShs9A47tEf+*L'-YO:ܧ)¹wf 1ɢ_ەNso7t/|_eWYD_9O$x_7rN'{o}n۠ pLEmʍ?S2žHS '9=m[{TKժ.d` fG 0<&G2I3P8@!Չ =W/kR3kd]}x[nluwrL5F<_F5Xb:=PO$܊^\&>aYd Cǥ!UD5􍳾~̼ecXR9I`8š +1J 80|V_9[E‘ӤՔ#rBzѻu@wֺLyzVM~ hψ v3e$y}} R 6-f&6JE`oL*OB}+yakԼp*CB%RkI]IQPڿл]/W˿Nve4*xܛ볥/m&K۴s5N3E [ ]Pb5S?Whce쩬L}::Y^ 7qE!ꛂ:m[2K=Ls#&ex%1R>3]²Z1Rj /Ne6SAYlwe\("_g W);˥T2ZARP{81]͔8s>x([z}k]ќ}xi`03>a_mE@[f61/Gef CJegC,*[[Na*ZHMCvcg 6XOzY?ؠop4iK;n쉢, 5nڼ\P@?~S;a<:_zKqYі|J0Cx_Mi_ d&:R!nb h7۱6;>3~`Vh_ٛ6H-W?{*~g qY½"\ʵo~"$L yu?I͊Iz,Z k ְ :}gA{=uޜDiCuƃ2Bpx`` <ڜ Ň?}*6 ! @+e%cz^k=Gf]FQq:|AvMP\`Y7ӚFhJ4$Ϗ<SMuAnf}|%|dNc ݆{-@~JY;|D=2ĶY e :I376.R. ҂²VTRc7PGk^ͲZdgӌvVub{cb(dRah7GF!!~hhm3"+QiNC ֌,r:"uBZRŽMK] c&ڒǡ03DkL̸wGxaBu!M7mG3e懁KNOʸ(~ VW[_8a<;OѽWnHq&YJdnYq%'6"i|$Gzh(9v|n c'r-֮'7Ԓչ D99Xsui5Qٴ;@Awg5㜲X+ fv|P2h%*cc"4 l"H/[CVW6x= s,]4ۃ#m.G7{/Z8HTuA5qBA ґ&M쥯û!8Cx'ʚ2 + T|gxZ^I*`Tз֋]ehs+e:JnLjZGcxnJd:&U ^J8;$zeV\F} ķ9@)$@ 6rr܅unѡ:+%=QcjRt/ `)-n6E .m?bv :}VE22fy ]jY8A }X}Jze Zt Wi+SW@Mr?^YgW}~iC~ܾ%u$)>33K-1)Pd(tI+:nCˤi>3ŽBYqE}GEf^mc da+Xg5`Wmv2 ho7T?]Ah&(`8Vyoh5ࢿbMW\C)Wp?V2(9O\{Nrc=<9Ƚ^^zp/7JW{ϻ7aLY:֑gPqM| zt2,=(kVm0XY*d[${˕[h; HJ]:[$ 6#u4f<u}g#G"yJrDRBK޻W{\#wU1d kO/{ݨ:+Hz1w?kwvj{`i95(./=ƥ+=Nj8.~0#̫[j4CSHEj/]c*=oy^j  dÊܸ\>&;mv$!s~FSyo ʹȊVNϊ_eeūruza`[eoܼ^r'B1 %8L Z_(DX]uMuakz;3;(ytu5n_PIDPw‚X(cEuDrmC!,JqN_ NәXC+g,r*>nh9]Tˎ/vy7̼f k cAkp(ΏgkZE|֜حyЬn-AF,׹&d'pM猀$?F 3gV1;qiRrᶎRCʹ,kEZ4p.-{. s:MBeU&oB&ZGZoƑU" d y5uy)NHq1dq]tKqy= yq=q<jgY/-p$}.-84gVvy\ͧ/NpJOӡv.R! nR4&`Yܢݥj3YU<TڸƼ|t86&z M0ʿyhdB0XrPml̐JdfBz^3dBznM0vP nL,uL8ybkVnQh}@ =|x/?̧W$x1iRi#>I=d.a`Z%y4 M dt"ȭ+:`|SD-3^]ƺ.ӏ>-]\lMM|2f;aHa=7) ׮`#,%wޑKsL6ʷ!C% o>mhѕY{DxIՊ%?lc# A=^je[3$7mºS̠/1Y@ Y%s27y: b:0DiJ埃mJE7~*GІse'[4.ޣϞ<7KS%Oݞ:7à6<)Ui+;i;BNυgc_ۅtt8A{wi-˒lM8 f\ͪW4<pdA>QUt}R{E3@uHvxy&^b{DssOB" @+/9=SeUۼ=G>VJLF OnHu97e?̯KHxL6X(G ai 6;j'Xa_\|l"&,yk&7y1X8(OI-!mh4\7N0P3`c5NPJMP3k3?G-ҳo|kuWx}`өU֎sJ1\A|E4viy(j'Rq-/JM)#yݱX &b2aeY+ڶbзg4,./HHyNkZn"E\u2C-nk-v>dzWd얿 T}hoekZēmPjsG,'H0"-ᓽbs+_u dk] T䖘Y^l@.  &%ڱj\ J^]L %IP6#xQ"V10 *O7ӷލ .2GpDrpa<3o~s& 7C:ocf?-Utgᵶx\aVk-ȍ yKI9b=cbiU'A}y[,jBܴ4sEzo? "]X>x;{!D Zӗ(I% $5'79čvh@9mKm/J}()OK鲦h!_pzG)Vg^g"e.Ks'VVy;K0Ez]Wpïc)4O2H2%k:Gz"[ʫn/c2)0S Y[Nj!G,`VrY418z=p4\q]aJcca`f2LDBuSeRNITD`7jrW$iԃё^̲`M.n3z`?_⋺א/~iUSk(k9N ѲKwfBY 5YmX!h[hGn}%m^](2jrIWO]S#bn/UɆٷF,Q/kbѨPHƮ3ZNV~nskÝRpV1=A孙WNBx, F5"&Sr{5{J;~ ,jcs9RT*ÈÒl` QqCs\7ԠzURsSx`wfVwr\i5˭mgLU.)`mms7"8]ڈտS|nN;3<)|31Y7m22@ԭmc9<:, kl0KR!m3N/A&#)X+mIpmrYi&tY=lSyx5! KI݂#q`n93_)ApLIC!)vs{47 7x4`+&ޗyM{~Ԁz?|,{#gJGՕo?JfsD"B|dJ1DaU󿢦K϶IoJGPmk򒂘{1 r Gz%/l5ю7efa<d_GftVrOnՅW`.7"SNɵCp]w8$,*19}tn Ŧ`X)ԣ⩳ =T6b5y4$ }uAL)9>:D潾vQ&ڗQ% 4t^U)ljV佻ia臞11!x~`#tHưfm׮S8fg|td_ɷ6&"n~%BrvPNpYIEĜ#N\)TLʧ YkuU<4&f^[ Ju?rz'Q$NA  #0;R;׈8-v8wAV}㙺CT!+O(:?!;!Cc;{$s9":H@vГE`h$DϠҗS *Gʹ(o\00_0V/;RܬӀUѲ6vd&N,[V$? <|<:VW&-(;ʸ̿w; A:;*.+bٸֹz׹ؐ'J)NbH$.0/O?<0~c[(Iǚ[(8|=kadmM4ѫ׼fO9TZ*K@s uؾ覔u- &F|hnKF_({JcA9БT4&p'cP:)7uIù?g؈ā,u1>>] Ў蝵/|3cw4G^Etͭǟ7V,[A.(G˱Z23icNV8n{㽽< A\LFدFLbk߷=se)/deH@=4lO-BbLXSE7TRW3ϋA[*mGgO ԇ "_&:%XO߯snŹCYh]eTg ;VY0|SPX>yiz*e01 _+ܙwQ8q[mAxx1Y}g[9k ~fwDX[j*s, ZI$r WU7r1r33]UXNH:K/LN,%NdMy|sqT՞jlVC}Gэ% #C kAo^u l#C|ROtyvJ~Ju@ݿ~MEh'c01shU^<45WJMAKc}+:o:aΰ( (̽D6|vhv#' ?>_O~K6.^;wF<ؗ+h&4*8.k+$N956][ @պuShmk!2C7TuTOGjBgՔ,0-adtga>35?\:<\أ]{hq,m׉z衈"3_aXaB/?t~d`%X@vTS~xpTг$ݻ՛3j!#0 @Zp6P9r!,@(=p\"ͮ.@B^pւĭ}`!<:̳NqpC ?#9 K =' '۷W6lcἜG/?^t\*N:[bWwyڪ6{m‚Npё$,H/ v `p/)Tmk8O yx R>:"X#iWnܓ]$^ͳq%e X4 ٵgF-HYI:6Q,kl7;yJ1gɄ ݥNn-jqT?"Ts{rmCօR6b_=5'MAG>oՏ=Vyb!VKl"䏟.DBron:82y>e[m+cPUnSFf-r\r?R"E?UeݓE [lDaR+\=XqcvgʽFk;*6ݨ9W:,v6M:Ry)$7?Nj(yy51P[M~ËRɑCxYn=`ŽŋV i̬F8tOXXմMKj*B94 ]50&rۡ9 zi[4BPА ȿulGn^{Gƌ ƢvɽKMyxxqALwSOJė$\WS#mBU+E2K,*mOHhx(Up )!_2iOuٳguэ0 v{ @O??Kߚn4NOJ -uA__[:`8&oIukG3#ySS)I,{8&1E -E1ZܶNM(δ'x'M_YV ԇQ"0,b`@E:;0rgIbF>/ Qn[Ro̢@V |zG,.ꗟᅲɮ-2aeVkQ *ˌ]4ރ$~{ڽʾTD1eAֳvZ!U]ܽ#+H\&<5cTk(:*+9jМ &OcH\v6W+766ڑElPꍼ!0Z)Yk>~i?hz[T!Չeiauxh2-"m|DUWmaEF}.v>3Jc@Unӥ1&#`^[\\u7_XMrF3g芅宅!fbIF,&?T<{ n^NVz00 . \N;>ͯ{B_-DɥR~|W;YF Ta\]j|y}&H K1΀knJ0skֶ?~!ݶnC&֕}V`m#EƦZ)R|KZ_{v5JfEv⬗vvЍvWUދԉ~n,GpnC1JL BRUHL=X. tjcCkC%}C e0 0E% zG"'Qӏ{WXрxgFSD$'DKnJ58,)9 P6~S;uރtSj`{fK7Feijw#}_|w/Цpݛۤ`(sIɸu.ĶVn pR^T>>k#bSLt4G#;]tD^B!Qgޥ- 椝įk 59ܕʒk@O!d'ݑNDsKؘQL˜E#xJazͿ[h'L zx]8vdQy NfvUӘG__m0Cs40fz-.Er*kb$b ټRr"bf`GL̊xa-+~A #)k`Zm2Ib:=Y;r~}GSהF9G"A'wncݸTـbt+z߉nOk +i&2u 2V8}\EҢS卝Ci8>q]P s(%9wr'Bn7+ z Hp-uIkW)bцdF1c PYEQ]#@QK7> o#n4;FU8K2Ooɦg9k#@5r&s{0M&y")kD6DOC)d,EI jQ, &B|C/H2n8D!Y.t7_E)-OwĒs>G]&TS1tsleIzQ2{K~-T#MO֐RCkGSoW ٫ymv_[Tjb@%)l>&~tKƪbV%j[ ǵ6xRBV[ς_s+aw'cwJɲ[VoZ 9sS-'ٝGod6֩1(.׆\{YM z^PdL{ᚢTƾR/JXq#Ź9SDyQFksځ9lb nj=jmmQ I?W/^l7 0*@|c}4;m"b@%62P O!wlzpR gzu]r tw-yD~Ϸ=ϙsL} zA,I-YcIe[.ll+z+ٵƒ#QbHfP3O?7\܌?P3٣ 34?/چiAm7Z[t-Bpmظ~omUHI8qE x䊭-؅+b; ?䃏n*5殰IJoړ7hA3Inh ~F;↏PUkrJz1m]&v#$'֊r>B|nŗ~Ĕ܋_}7T7wU|6'ZE#I先eQZՀ|mhk &r$| <$F8b޸.~z1z%~ E9L.VoXcEi6"u5x[ThYސ"}%M"sX dN$ 5/+da.HO1nyNb#Pig_ &'&l"ec8jR=kB91Q{vC/nlĎF.˭ƂU}sLm\\j I@bP_LIyY̾-,vX=wOU =COf۫_=_:Ygh83==dP^]rn~j{jmwh}+][i9"|ڟȗ t`ԉ%A-#7lu*7',aŘ,y! (yS[@:޼nF{t=fB)=D 3[bQaq ?}"7pEt3L2ҥY!rB!u$>&HN+}WV(n/( X}M#y*T$AjG}dn-"rdasx-ZVb:`0đP6̵37.W^ {DdA`e+&0`Wԗ^_:^RH `Q\3ha~ن#fO 9LhZ(c|srCG\fpTq)l8n[Is:&MAȷZӠוh@/9E5Rr.cɣEgW%~J_f희>tve%hLX0߹gqɥo[3AҨIY,%}y0z][* L䌛1K&097Axj)(aJ)j 〦`&.LMJbN:v1,IXcuۗlϦF\Gf+؞Ͷ+fbQZ7rfRC\W‚߇HTfAs3j>V;{>%,8^07IAefX Ҫjr)I#$ZØŎӼJ(Gba=t͞)1 8&d0J3}%?xʼnn6 / :0J|yG( 9ƾZ^S2T'{B%2(@2?0(ch[^<bVNK bq#\0 [![aqU:1Px9Er)ԈX1ǘMXbZR(e}YdPJG3a*g/ 6=2r{vp^>&XyZ?G~Z/`֠Ceչ7sLt TE->婣ywضܾW8hegM ZU ϘE=D[ga :/27Ɂ=Lg\ϔ7p2pG&q&ҩZ?y/y +Zߖ)F#zeƉ` v:87-V brC`XTHzig 6)YVރ{R&B_"%odGV7` m H(Ð-1qP̮Go|l ZRӘ:SIe` [) Qܙ6:j[,pH>Vw>gv#{{,ˤvU+e=hLBeIDATpr}t!#*`0J(؊{SE!KD蜔 "zL 8dS@P C4n 1X{VJd-!x߉DGPs@Uvx#~jŏEY(-^^) V=ge/r5v*IU6fpC`MIöAQXOKu>),kG}I IEZarcv]m:l1Xff70jM<˛zƕ;f4tuwT)Y dP.ɖgd!2}b۹65b`ц+'jpy;>`r-bhdaAa@uB.%øcR" 5R$2p]I(5sU&Hʇ+Tp -cXا[wn>Luxce=2Q=n[zDcT87X?m°ʻm3^Uzv"f*e"t]=z@,]j qPi8ݴcm CH)crITPsq~Sd܅Ȯ3z'mt?ֽ:"hіvډxzXxq.1|6>YR껇S#7ЗV^5ҀE.mŚH5gsBeX#+PN+IFLBYVMcqaOYBBRo[;$Ǩ)MeVYpԐ~쟜Q(T<&!s$a7dt|[:;'.BVc>pX7*h~WϔJt#su#V#X!8r +iU]pjŅ} 1oʢMLg9 l bY.=%RĀF4]R~Gq\ȸ rR]#P(,ů_ ]ZigՎhGYw԰sPm~zcݓ/#Q1LW ~wv*NGR]88(f_q zbd_v YV4ʟ{f*"+BP n3)ev'w^Du@K J=W"j?Gߨn7ݝgGϷ@'!؉kʊI84 ذ3ykp3ٶg43n thIuџo֮raB,pG#k1q"\Q򭜢-)LYEX#G58Og)k\BgJ[*X;NV7mHFTNz 6L"&Vvfڡ)-Uϧ=Qp(l-C 8{|w[aL;cA/Z訉 `BtZQ1tI ]p!ZI "-4Ʉl+'-ʐ c=S%I ETG׬I @k,"eK  H|R_%# !\'_$n77Վ D*3QevZ5q,vDZ;NgAe!/nA7 6mwC3(v.:"7}'Dg:唰 ^ګCz8ҋ:b ˣϞ4y[iF\_ bV,+ 3"κO<ϜLLז>/|IC\lb"v`[\X%䀒, }@?K},\!oLZGg?ǨZ^t 4$'~[=R+r@׌Y^l]{\K R]6Pd/bh^>>vD-bl"ew=Cɻ~zj?<}'$*z^pf \y241` |7a!O?Bđzɡ_ylw#PPK%w]%žI!_Ѧv81|y:0ݹѺ ^N$,CSPeI!g_(!J[*O>ukviRƽR"M3=2A 3luzZ5G Qoi2|'CVx .0ƺuW^ׅ\qxd[E&nhe52V+OZJ_|뀷gzT/oh<ȿɥm rP\Rڣlе}&.n__&k|aǕH2WEc;~9%*in0dZ~zh/<}#֐Y "@. 6vpTɳb9h߫;mpF>YI7}&>nzqZ"۳2{,2:IdZ{]U#mfT6I$ c'Jۣk7mQv*ħ454d)\EJ(Ϲ djdnvû̏?K[f|GC5Y!ęvsj3JYiR^ZI9pR B)"}}\4 r)j~]([oj"u\y!󻿨]ڮDžl(_Sf5,3hxҚuj1qUަ`XhKGNd_ԞԶTr ke(*#`x׹߽Hq|4,;JsB(U$2g5qͩ5ҕfԭGO+ի+⡽s_VQAfv;]T s!@ߣc;C;s?|ln4FYEM0fD~Vv1j hܒ٦UFēJ6P_-X=*D}跿jLjkJ2'z?\~})&9";#7  r9CfȨ=`(CWzyjړG'~[ [6Fn 샂F*yy5yl_$N huUَmTrYƛtrlfAֶ#6ձصdC2WtU=ޗM mm_gJqfu4cygs[sfL~$$䋏o) }K\)Zs>a=HdЮ."5H]%V1tf'b 0U $p/<0/|ԎFrt{frۉC"&Za\s ؆Jm:L nsziDo}CJH9*]Vշ5 щ㡓(j"~fw)f_2.p̫mO!dN3x`{/ =yvb?Y{x@X-èQyRZX&TZ":[b,D>e^kiC,_r炁~1\RCli}u+3J+BSnO.2t OSǠu3 Oʦ];: r Q.G< p<ҩ)?Ka}~{ ^7BBbW7+yߩTȧ+T#𭦎Yo,o3nwl;5Jj.1SZWrܐ&׀s˨k;xT+/e{N!̞wG˓jqO)j@ÄbD34j&H7r7#2ƫ. q00+6,|wfjC^He%+ސܹw|)x̱:k8A[76FP!_|Eq+Vo ݯg:EJnxi#g'ui)kr˞(& G uEيr_^@-% VH ;`|U޻Zw}x;sxvEze>}&ܝÏn(?kv?oЀ}d @ĐIܘ./6y+z5ϵ i ʖHŮ9f]qK&S/?vWF;o)DN ;6Oo Ň{+DeV4qO8cdvG+X!&AHc+BZ_͸ .3FՑꗝm;ȽzQlO>/ #}]S%xfx{ $dk'ws>鸶72EWeeK38V1EZ \*̺}nBd`1* s-[^*,X3kuĸ蒨V>Yt c{Q- %W[dE(3POXP3՚[$kH+5s8@SQ+pb\qSbNܬ ehxdyA/ȻJW?}sI.'7nhYTWXn$I2gQQɄɊ;gukgGxuW-lRePi2!ENEFK.%}z( 3B m%v#оQdAޟd<ɍVwfwaj'΅U1@EWe 48.M~}O6@hflU)S٥>_.8$p Q_,88* ")X0aYiy݌yX(l=͈|nߖ6.rTR8|;EV-Ғ(S|;Fo]lCo~dΥ{EtΟtk+zn^]Y$8=Xbsۘal@ [ Z-]!QYZ2Bjjh|:\/~=xD='Bgyr0nz3 x{p^m W8 .*rZI@QV'.rד;y瘫ֹFPj <T8/>_:=uʱAV^c>-Cȵ8Й=*u)+9x6oa%'B3K/=](% ^[ܸyKdjOvlЈNUMt Wٞ Exp^WfoExw^\ͮ# =툴[PLb/Bgwo 닁sS"KZ GŐy{O>Nۺ~S^e\2;OA/l /\W/L\xŭ"K"s qIz>:d \um6ϖŔJ5$lzxmY riϭ,tG|b1gKܟ9-߷lOڭ]ɿ+% m<~+phȘ⸵}gH]i]Z{sf8SJ囚} `v{a#[KEQ *+@T ψpx%t %jen~c#AH\NcUuf9)N,“ח:g/9/K_ۄq08R).dN)BM5?[}tvr+%|xNSn3;j)|+rD LA *_`Eh\mmD|Nv6V>4"^N`*P!ƨ>>K ZL_Uaš@L}OE~Rh[]L1M10{mkD@LG_0wp(s! $! ̷[uݵ{5m4Ȅ'ȿjwKm˯ūagJ;>m7 5DZm%\4LVH=Y$ czw)Mf9gp@)1sj sWxgG}gg{MY_^<1_?҅É~WUK%KCXŘ\bnahm'+BTmveq\ƓcfLɜ|aYlQMU+ EAO?+G>$n܇&=za\SY5FC],"|#3NBӆVH`S 2ehb~3}t;ψ=: 2NhwgO>W \IUjh(2R\)  =,k^t(=88l-|@Y#I)agMN w(\(mve&n`b>F{_xRaJ%ƶGFh oٳ&2^8^u \V,pLV3<#RC5->S%sE_8fܧsmc_~ n3 /+zqj'I;j ;w tOK΍3rٍA*Cܞq> W6BZ.}9S'@6|ۿ@P+AV;vϮ>_8 |k"j[_F#_} &k}d=9Ι>-^)ǎڲn (fRE)n@bD ޠ/ѡ-SC`u4F)^Bc:O"汚>B}IU kk 0nUg;J>S`ǔ)9vVD[Raeh3Ծ|Tjq]g:LQvuueNovB;pL1≼vYHcr")Fy :1X;R13fռezj0lK.`9F6 ?"~xʝۙq-T \ !m#wLK o"6.GOZ%+es 7 )Xt2<(~:olB 8fIu|ksK9a(l`#J`s(b?.ޕ;B|AOݷ{ptrK հ8훜|JcǷkw.Ǧ?[Ӿ-3'y/iz|7\ʱ'0 4uVaZdr^CVspw_R7TH@M6F88oA`Ztsi]q6|MSaY.p|**bS@1IN̕3]ZrjqVa}ܑu1Mi|sY/ݥ_ۼzOv1QEy^*jf"(D1"\oxA7Gcz$nm%HT"=s B#3ۦpRSMɅLktXj) KX׺:R}*_Iq].yJH):\ '^s)M#ۂUx*<Q5uJ;*oZ'#2u=+]\C>8Ug6ĵu{([P@pOed;}yX)lg&{yG T',_Un_~Z }|\ $Mk'W>b9xl=q`tjٙ;/=C?q$vq M]uߢ{fֽ kpZ!_":xwiA~y1TGf?S vWG ȮjǛ;y1*"|jDW%qz8pw~b J]FJ5Ȃ͔X鰞1:V֢(i&BAAB( EaaI:F_[/Εe,|&7 LyђDdFlZ[ p7S#T>Su7^Fw`^o-ͥ))qjut uWLFPa3#IB4sQ{%B\LpzzA%Ϲk1tdk~n220f'GP_w3÷&)|' 4ZV> _sBoע'`؇߉.@NF}Ѭc{{Gacϼ1߁]a$wzBdy+i~Sg?_ UaiWYx]}[;\cc{?"}>]Xqm͏9>;,G^  -U^t( =D\lj6KL f >a?KeG;Hs4H6(kGf:␂-S ;ېnpGw3T; @ 1`6 Raŵ.{R"{a4;dܘ16\;_EV=P>1qvz 6]hx^K gJׯ~`Ԝٱ' y&j>`vo4Y?A44SQ[O;E17[}'Gj[`"Dca3vdTBE5 Qg,9:.%r/ A4Q"IO:*2Xr%aY,`%L͟'Mש>mۜ\ @|CFA5)ØР PDεKd+/ۋ(l?@ՉN~ibt;iǎnq4eo$niΝJH)Rv%%XUn!H+b 槆ޖn[RZq+HD.XjsͤhƘw!Ԫhlha:iDLk 3axTR7^p a5.{][cU.Uc~O|9\\ P(x'O{u;aў NIC!r'Oד7պ9bRtk˻@AN~Xњ{K|3G %85[3eIyE{5yldٺyj)HnB6_$4@cv"^Mm: 7'㍊d `]ʧDeRK.[CyaTp~eXQ֘`P)#NƢBYϤEoB~ EsKU$WNy= 3ίγ%hipLkݡT5Z~xu?\}Nv-en 2dZ) AW=+Rd\1م8IL#PRHߔKgSn&uCMDB< &:p~)7eWF}O5 U m櫟R5mSո&VM=)nGL`gsR $ _Q6W}6~_J8jߺ#A"BaU_{dtmk3C1)4(18ai nl$'O-v~ar@r /g"OIo5FIa_| O?}___f_?l j7㇁#9ţ >$(*J3Gg:7<5Jb,CL)w}|ekzT}t/$gO0b^. PaQƵ[$X?B 6록% lFVWW q2S6NW~f$4W|Jf3w׷MӛPŤh0.¯>S""m4?,V/|nx0]-ڍ|y˨pHl77J`-VC mIQHk4 u4,]&A$V_|`F!|q(hni{, z\l( an~LCǓ]ak=aT1V`pўL_̅f:g-׃R_4*@?||Ljꝩ:bt.׭| ɥ|)Yl`oG] 7L7WLŌ5#;vObO2QWDAvUuWe<EK_V^Zw}LcZ#u(2 ;-Bti8)GÄ8D%kN)M:PZbV$ ϖ͍ ;xma"݊2*LmYj#0 +hR>OzbV\hSv+y#|˷y8|mg7y^/.=~l4/ q`5&U x/f+dqrOqBi 8 Zjx"L6L'`YP63  (v9!)X~׵1uTgJ <+ݵN/[j ΟÓ dz~Ohipe=C!gL>A=wM-֪曇22l_~{|41%q\zlhqN{R2BKrX0R8={fg5୫jų)Vm3TLNٟwRF?s1w5DW}t}~3vB}T gޥyPo?<>^/+ݾ BPH‚MJ$-l>q LzYĆv4a$:UGd% 50g4ӸM 6ajn!бUnUŊ`g̓{YI_>_5vq[0}`ZZ,. lͧ.=Q'%I\p4vl7A,ra%(<2TLxxn+éD@aE@H`]GVTlTZ!FVk5mA H0!,i 9 ̎HolUeo > .7k?c¯ 4']*Z57sSw%Gnc>Zr1zyqف\8t>d,_.?|ھiO{7?iͧ֒^7逶dvR4YF'S'|~}uӐaʧk#}B_ʁ[O3)r\:ꩄ5"m*};2h\Т?ё>,`^`ܲgSK;@)?p=tnpntF:uIA e7<ߑbU8AUj˜'!nr5hF@@4t Fw yXVN1*g{MAՙ҆ljߟt{*)y~)u\h9M`yjޯD^ي ![W"E_O֍9 6(h?kV*m]U2|n$JjQPa@RFŽMM9/"5[0\֕R\n,`8%Z`alv~.T?P^YȢt6>%[SU5wv#l7(m?Z )d%gssQY&:{ٽW>\?O&Ou+0tɏ¶י=C9'v^CEi~-  'rX[mC`"`U&Y WzRX?Avl!wGa; D0qM0Ci][_&zD= n ɶ.ZENUzE/he 7\ҰGRw;_Y~h@{@PPM8`w;i߾MxS5xE(g2n^oa՝zexf=h,靏 g u|24" SW+jFjYSc`%[8;8QfB l;qr1KJ7a r!.|I? ϠT 6<3EI-7D>cRpԄ `(8b|t.xiEHqɃXïyТ`"lF;TZpD&4v6v!eV`Rgܨԡc( 2nc4l;J-ahF;sbO(gB-p|yWaHgvtyK\a >Nū\ ` rf I_bRO߹ 7F8,&hvKb`tXq`X`_o/zZƁK~1ȏ;[-R硝.z`T*GWC䦚{D;̊/5VU@a1G'hʉfdEB+RptnK%nճ e!vpO }\Jܼ߆b r@j=HD7Q~hOk#s/O@AA}R:hI7ymԄqJtFtvJ4 N1NHnsE1'mx@Z|h=o`S9&9?hmg(4-;Ɲ(?;=&2;:ĵ$ Q}x}zRGslc L{#~Y泾uЎ|s4\OdvdH"J Ww a ڜxs! w#T>\a^%KDpb6ּun;&Y76d]<}y>x] Wn+:etcz7e{T{]ŎB3h.x,]7%<_;WHY> M;Xo"9^>HX|ڕ ,leHROCHl7OZ/"{t@g[eqB^^o^QWn>Va9(ϳz~wC!t.Cd}ed(v ~UE F׏?x](Xe$S {T;L {T3dܸ>$uRJݒWWNR.swɜ qO̩.DQNrڼaYYPѿ]7q99y7^QloI)wlgkøC;""GF>twK20 i7>aCJqʵ!dߢם̥YppϻL+ r-**o':*b8ߌ܊!8ȸ0m JAW?Ÿ։meWRbM)W9}$-0씖V89KƆˬA{=^\Wk r1xd|v[wO3/Vpb6ffd[mŽ&Sv7s._&W,C=?TW$t2D(-4`&naHnk~57 -o02t "-w,9Hpv"u$^@7`=SRֲbҬTfnѡʤ/QzڛF3s 48ljD^ԇƒp|lm, `T+sڱFU֭Y îNl|%Pg.0 N"dp;KBVzrUJPXE%_k|-ās @0]k3(|2Tn^bhsq8K_Kv/%w (V&:}/L 6#.\`Â>#W/iRas18eڨDYbb 4 tH%vVnvTobfm1\ ;e `@JeD% .(|;xpoa;VmTCЅrH2Ko^ފFzn%UF63ЍUfLI7d_O]v |PlT0-SDƪ!\ǐF\W,0,̭̌r679ͷּφxBf.B`4zZC֯wTs%)Pw&j0P&+w7Sa,ɖ ~9(M} wlk]BRDڴ3jkƵ<0̚ JA!?\mEVʫۗnO{PD ZsE&\(ѨՖpQlX5KM?MpA/GLОt ;PO+K_Vs#'jbտ ])G*oyY]KmGy P[11hk$0,sDK']Q?;&PC}bsl tF (sZ)u@i21 hS ~wn[еD[I[-=wN8ͬ31?XI^Y/]~^オ8.%UЯ0cZWYo塇r}Y(l9{wIjvDU8N^I$ǹ $߯ &ȱ)G |򪱷F]i/n]ްRA\p03X Dkb]=6m5ݖ(-l`@ioT8MJr a#pEsޞ!lV?f \!zυ>M,.V,}U$Hw"q9]utaG  9 if.,+F Yޒ?uP'$YQ%t=gP2#_ >y`M4`+n8{L@O4Q1*G=(0!L9#a=Ca6{+x@F;$D+p^p2JaV ٳS *tu1?|Qs6DH[#B ۔%5hy~E2JXxx IAY3ksQ +I:E??|]x6K<~NVz_4q3BoͲk%(=; z{ |r W,|>G-!ku+H$1` Ā1PPHmv*6-/D GW~ EBvֵc (A[貎RK,hnKyvYzpU|'ug(KZĮQ ǧb%I1 Вi.4 C?)O7.H5:b;(h52 ΗuTB Oк(N8 ))4v|7+4<uTSEVU!(9 z|7m@)[218f{*ڒ!MȢ0T|1* Y] 5 HfJŸUgRuj jSc_=;8Ohzz^74iY?z^T{%me)ɇ5qa~r/9sWTIy[?WOrVGNV0: jA0$TCB6-7~p3mWO,ކ2-3K=o![v)hF5 #UCi/A4t4 ܬ7XX9X-?/ k%8qp As` `)@Xi*"^ s(!%g-Zza IVEyo`lU}"}2(0`G3=Pt>D2:&o" c:lQNm3 Pؾ:ɽ8Ld@F#t;.bD)r>!ȭ!.1"sa8%p8\-a =55aJw$ځ0 lCGItWI_+ n5?5mu당@}ϥggҝ/6W:+JXXDӏz'ݮMߵ2M/;l z B=Iabc=t@8f_\Q5 G]gIZtywmxns+(Q4+i_:z-=ȹB[¶ujV)0:@?Y+ր{0m;E7gIjʐТL@>OyS*AںH~MɠvɉQpi> `a:db1Kn-S !J)$A;иa- ӵL4~K;^JB)[ )7)t;z=׊}plPvcS$$q(tOo/o[ըX*`ef;yXkKQ*A&UM F@)* ݍ͐nyw}_1Uj)K(V@'9xqc.9 D$\:GC֎Kf%:@ǟk{Q?v +PA5,Z A ^c*?ߦ!Q[[l` \X';;Ψ/xU -|#S @KqeVV!2ݒwoeQ\"?"2-}=f \"I3ʵFQi!}j=4k21x ? y+ɤrh97Ww쀥Ic&XC!S`Ve2(w樵8VR R"$WǮo\93gN;{bP`DD411!Q_7|41!$ FҊX ŐR)CvngΙ}>{^[æmdP:JΟJVjа22x7ǨNwN͉M_#2-6X`з杨!=.oIO`*RV3^*w<'ȽAf,l}HH{=>VxO28ytq&%ms,|HzÏz|`N6OZpв~K!z)h'<ԄagH[~̅f\u&ahRUjxƱffbjO5+AX{ܸhS5 ^ $ 5M}FS l x^E20 N*a]KUuvF F꼤:bEǎoy &T߽py;'F'jؤ}k=ZNHKXڌ՜Inygo^vڛVur6M7.eصղ&8 m*̰PRRc?y_nZ22qE4'5 !M49$IE%|kjk ""UWgq/`^}xh]\Ϻnk730ۢ 2pqΣ*!9ƿP fB¤4ŵxkVwTОV$6BDzU1=qib{@\~Ѱ+,2hqt4ɩ{.q̚ULiұxl{RP_#XZB|2a{uH4ƭRd>b4v R&4%1y ^-YrJI$8x*@Tk(a_d+#|tԏNP"Ӷ &-:d˅_)sʋ/gwfO?Ku0 '(β^^;/>/V枇sO_9a忈wd1X3eCO7܁prcuȩ0/]FP) jByڗ!C͈i0pD@㊃&Q[24a ZtAg4 j;˽}st>_ftB^RxZ6lq~a-3u*kiMkĻKsJ"!ZHې6jɾ:8gINNvo!f6jLXcP{0%tEXtdate:create2016-10-10T23:41:56-06:001 %tEXtdate:modify2016-10-10T23:26:33-06:00ޗIENDB`fvwm-2.6.7/default-config/images/background/bg1.png0000644000175700017570000121007313006057357017110 00000000000000PNG  IHDRV: cHRMz&u0`:pQ<bKGD̿ pHYsddtIME --$FtEXtRaw profile type app12 app12 15 4475636b79000100040000002f0000 :rIDATxlJ, )*)#/ΝdTuy33u_ #L˺.S4˲Lmm\3>>eYߘoTUJum[5|kw]Eg/\[uZyYZ iUŗέV7lr>jʪ6yY8ؖys-8[x?9>ױ'r;;/xg܂y緤_۾:YQo]TzaDZӲzN״nxWvm|ۺ2 {,f|rmw {ỵ_enM7w~yo~c^ܺ)sMjn>εRyZ{Cuv󶌶jF_jc-ESaZ}YY7ygnqwՔ 7=OZ4v9<ؾQltV{/kS^xq~VMUuQ7ze#Ӻmpxi2ufqYߖ[5Nvyilp6o@riP)VZq{pγYjꮇAԝmey_Yy<8oħ3|>8yaf~_+MO|[87e 8iK&x9X7%zM3pl=>y<ߟ|_Nz1BRjÊ>:4>:;A-Mڲo{ںiϺ[xQ.dTEӖ(_YWY-45}-v{G1 -_[;Z%СFv / ӧOpJ|"3xFk8]VMpq725wXq:.,S {7O|aYT5\UQ}T0 &a?f?B",>Z4iv|[g:/BjYi7c&l M;-@} E5NYuŽQڲھnחazl]Htf:pqڎ8}ގ=e<>!8| o])`tyKͼ=}Imk:q':9Ԋ@1aAAh _ȋskCxò?%\!4[cʹn@L3O+ez5,wÂsSݭmquW}e< SgteߌW10/1ە9Z=C/é5j^euVjq\fN 3f"tB7>9}X>/ x(x*pk: ڷs|}kպwprfPjUfΈTv`絙{E4vj(zzuw٭;=1n.MV^8p\|vpysoW|F3)8j/TvCFd?:Uc}o7D4~.BZ²Qywed*o^>"{#q ̾_YUjy,oI]aQnk\鍶QB? |l#@NHQv37N?8Ou )^OZ)$3C,@&459Gs 32ȋ]x >! :x\]/=mg\?a#NY+^'g}9{A `^"V5J;,oG#lg5N0'8ȮrpQӹ@1o_fz=\ eՈi|u 7{@x~d9zy&녪q.aZ2 63~Fߗ|p`Ǎ?#> 8桹[X'F[89 c" {t#}M s5)Ϊ5?e>U-4b Z8"qa牏˥J BP#2Z`wcF<_̭J& IK^'\bȰ70e廠mwXeeF"sNsE2fG<;M1:!)ox. _ a'b<`H;mn N 0lM>93 H  wu'[ A|NHpƴa@Ui7f?Kì[$ q ] 茄8᧑~V-!<ja7yD:z?rG~efU9rrqҋo3_d 6D?|&}4#t:.[N3]C.U@m< n=8f,:=B÷ hWkYrĝofN ξ}=`0 B+h`Sq̼tR kd_u[+q) % L¸!X xEޖeux8}f!l8)eOj{$ϰs;nPU9C2Bv淞~@~y Ykqord8D bR6_zj鈷FϦKGX,S93n"HpV 4'Gu#n lp8f6[L{?oqkc[ܒ4{6)ѿ~P:-na;_i~@&DeGH񟛆nsh [֡t}ߚ d $-v En|VLUe֝oJD{6DCs`4ܨaC7 p}ݐ.+kQuQ}ڷ7hKP Ӄ$8 L>i)ДȎq'ЉV,|bˢRƉWȓkuCA+Wm̕?uǚb [K@~`(Q*ډ˿.fE4l"8ԙ[ӸyS1uy7k4eqOÏ=#{ʮr`o:9.>i%~?o4U`;›ewմ?UpzaimUr050y`q xI=܏ 8BⲋS">9VUqPT< KBHMP,[N:'Hg緙Gg?RCx.B Z <+=rUb1YR\?O18#m: XtjQ WSPøƦyV~h au8T5PfA!3n/9:d=kV0܂5 )RUWDWU-.wh2

    34s "r#EZ(uW;;NI*||p]mp:VYۻN2nr XZ:gT/|8/~:| g*:9o5-[R7v,yCW \0V1>`;/f,s5BI2 ?6x|ɚ;EV|Ζ1p*|'<,͙!iVy#N!aYBh}@=@b+vhGF 6 %3!BVEJMWC p qELGe]6GPͬ>_4p0q7t*H=x"XX#cXf>9X;.1 pݲa~Ȕ6e6V3ͭ |u}5 pxƴ{; *x^3~1t5<|t5/5][T=KlU!Xcz6mbpʆG c=hD1 H˴S`={o <' 9it󤪖-e_ Ou6:v8{]#е֙M\WTmSr8ְֺ?H$VTMe Q񖇊p+SUi\feH8Yp'bR6WՑY#Zd "іw٘Z*s @#t0&Uc 4𥓨g22eV'U8w 8K?]gE ml=RiVN$e Eu.o,ٺ]˶MX WZe NK*Nn9a ok< M& vxdZastC̬wJA$@Ć6lR]x1%3k)-6Țr}F|rcbG sc^1^,'[]_`I9!<;^F`>O~dF3J3b@i =[@fv^jtUôGߗ07`b,/7`Uy$BG^!+/$)@&kWUjr)p_O_T fמSVyCp(JÖ k~^}0X?]K>'|VDk[8&0kqɔ&6$8QRx<X|.FXa 0F="U47'x(<꘤r,1?x"< (&Jyδ"`qAʊ%+#A0 L32Udjr~?JI / LZix"ɋ qV< ǣbֈYRNO83Y?p |v+ ̖R`a sAHCTv$U|ä́i|\t"~rsV2m1ʾi"%ly6xJZwUf"JX] ڼd0hˢ$7%1:g6 K'v~$]t \ؙCRqyelMCؘOo03 ͕,i F69\[Cƛ,)MX<^ܚNeK a ,wxt+ 7kxS8ضn]Ybqq2k? %VSB>D|Z ,dgڌ?bLlT:x:Reԭ=vA~ I"uɌO%}ܭǶ=?_$_l (ҍN}k񛝃ޑnt8>t V!fZB㙥5Y3 Vڔnr,ؘZ M߀GO #˦x<:W %'d1qʓ:kB=\[{k[k5J%? (8@Q`6;KW^:DL#;#!)v,x h|i|'"OIIW8A Y7ca[DI)}t9:*

    , {`q`o?RYdMZ[0m`pܜXRum7/$Er1sg–b[tPBDMm2:ӊ[)5YM@P*7b"`AO Y%pmNM=3ɋSǍ2iF8bDH c8B$J ̜)Wn-9?bM8y" ׃52-Ŷnʤ?_1>߳F>Vs8msJJ2:p2Zdѕ𫘩#7Q&R 8sn i6,$:yU t&%2Ԭ\ʀj2"qbY+?ۀLQMz/LsC"7.$'ϥkRB_! QBf#Qf#QqHB! bѶ˲\y=}I%0 u>6]Y'ƥ͎9£]@&"Vr9Az ~uc8dvlU su_d^ 5V8RUA 7s}>޿<' gF_ag0Zޑ`uN nb8[r8k`>øq^/0)~f~$zf~VE_峃WB^qnG dQ-q]2Z/= 2F\( MNMrDLgyyo죬2 I?EH^pac@=2*KcMm 'gض!lBc2n n5r.<[ls2S!UhdwQI\8 IG<"^TN8?`u٪IQ ֜(D*ejE6 G&)Ǥ;]xOD䳽>](xaDBǡ0\O, ̡͓? X,=@(.n{ ʌ=&Bܵczfs>!1hǩphg^[޶ڽɪ֨-.z:D'CiHeRcAw)6 gm=pEx*-RZ3}I8đdBM5"C?L9tW\Rշ4V3t8--,|y^Kg*_ѡ/p:]̎H؎R=k}Z@ʳ1yEڶBvrd+Y:_VԀd`K*+gP01^V ]Z2y |,4oONMϏYHŁ^2(-O/1jq֐<0? w?uD)KF'psu,p$WW[0kj?B;Mx@ bJsvdǷq 0^wcUSn$s2ƽ1g$;X](|I Ew?f1HKl|IY.Ω&%YL^TGN{\R*j _٧ayr;)-}z|mu(&}9 p0Ȇ7A19e0[E!Uu ,,#!A+eg-+:p=02(po)kru!^(FZKsw#PȦ6=^"_G!%9y]x8{t=_ǡ:]ODΆLΪ; 237aKud䱰=?V̶rzϚSy̌5xm~V??fBu/e؄b`mDxGb !'Tzyx4Oen2ٍ7|?D(nھg"ҍAl R&&4<ӭ0NLC! Y$C*asa!юa!7Hɩf~;EJː3儩Yo-j ϑs \H3wN` ZYKv"h=tvVGcH]k{]QdVCrkjئ5[ۤaQ~Bׄrv,)b%RBH vw-m& dS *eI bޞH$XJ}[! FcK Hq_HE PC&A[Ugѡ]o#/a #fF&mI|mǑӶ@0O0s3A/ ;271}n `rDTUk={$K8Kk!1 .E|^f\F'X)x <ɼ2' S^Í@ ̡yqg-H58e8\ޢ\UTR#!D &;֓REje[ِk}I>\sx".a9:`l$/1Kxq0?bkH7U!e sgj̙7N>}}~!y|bӆ25x89Y&9bz6aBJGnqC37p055%z#-.cBDVe²CU2RD4͑t-|Cᬎ|ZݭN%Ǻ^r˶6wbp PbQ )k>Ū[m-b_c!e{ULa#lcV7sbb2+I҂X fX+դ\AךH5J0[LeYQ԰1#iqn䌠j(Rh_5CDUT^3Tg\l?8sd|LP'u Ssu +#Y9p~=BqB%#_$Z˖̊ ަlou*oH m?JXx4ӊL̏V Ic ŅLWjf'CzYcc;=wִnL}~{1#-l`}a;9JMѱ"Ss sRX^J'u#-by>/iyɿ'B] G^!QDvwMc$ZGfNF O}Grmo9e>q3'8llzIu"ߕ UlK+*J]>+:Do7$0_6Ԑx!.k>AT+s@1ZԟaW#kF ccKGa 8C:n*bp6$wm _ELB pa`YI#0H507YFj1d2dE뫌+-r7g#;50)s뱿tq xR/Oi&08ezQKpC8LN=4Hi†鍂@U7 ɳ+ee@Ng< 3f8Ɯ*7089NWdžP;R;6  ߙ>')Uwg9id(:Tܰ!P`bE> tZD+)5 1y3,Iga^r~3@H=# L1ge+,r8ZuR7Y)0/nj\ish]ěw"wcៜ $)e˩G[Ny,mDSa !)blR9X7ze+kBIm3x"MqL!5&yB{TTJGfvjEVۯȽp#~ey7D[1ސsC/*cp7JSȝUe9!ta^[uڎ#Dҧ|u}S'쥀[@si6ɖ#ev9slM^k`w2z,ʹdHL)C& 3Zл҃~c#>@6"{xA6\XY.]d}=/S2Fv=V̘R"5AܾM 9RNDkhyl_莵2Ȥ$|?`m'di\>mc?'U Zua' Q>}|?(3_紿fh.<}~{=̦I] 5sU&jpMT\yfvlԄ[deghDfaXN# , a~Efi|~>Ț:LrA"4|'vPL*$ᏺ 4;nK$]SJZE6[) ϵ( YpD"Zs#YOp:#ҦYb|1Va mQRX"%S"SRJt2Ym֮ ,H[Yǟxḣ p[{@-坘G1UZ>!ԶX}U }W-BwE0Ƹ X|  (L tXoq>?q1_䆮K47n: (-]Ùa'j]^cn]g#rvsdCc0ʳlN{BX0G󯿾^GdHQEGq R'y4Teؐ"=*F3G8ɱI(F( v$\g*3/gxuEOx.DtX+OНD,Azy])Xc]ђ sP\ErvnyeϴWjَY5`Jzl.FQef~+V-A|5L8Stꮻ'+<+jʛVpS_O[ S&Ěp0&|T9N*fآ{޲I[ ;#Xe Jg2ߒLG@Q CsͶ&e|S*TFMS46ڙTj.AU9U)!I2YȬ^ߧGi1Q e>h=zM)m@+WDcʃWq>oq m(y*!p: NқR 䄓xǝ++H?(CG*K['heFNL2sJ66'D$5x";sehj9k {|MGʴ; ^dpqκnݎCiQQpEd*KهI  '; vq8hUt@Bm,f٫˻ݸ&W !U{{#u䵋X6 3 zaܿ úT&SEDni=k)OpoW0T:%Rʡלnl 7X _bfG1NQ<݈qBH}m.l^fpD-yux;5EDF .ۉā>+Tg,YX`&Ǔ:[,9^Όʰ#ɻnA߲!gElu0-2X?FwsDehn!]6x}g`޹Y}&1­B,M]ܑݽUu*<I VyXraēe W\׿_^_~kl)[2TqT[h2|FVhk7qRjIpGq>D{q>wv >c3:FqKS|=x5>Yv?[4PWQqlS.xM D3L |$͜JKсI.uQ_ ~yiE9gע̎tϥ9&9R־jAAס $ *d"QX"L<0'?`R}U5 x{aj25lAGpkV*]q9`aˏ,ϴF~pIWp}xIFk`Y"`?>Qɺ6nzZ)9-5{E~nGl1D8_Ávq[C]}z^&sN$Y = $?%$̜q5If~krRz?Hb&a25"ڣMp:yvv"9AEm㾸)IHE0-zl>[(?V#c?'W 6q.RVgE?3I6xW;1o/yH<gز*GXWx}>i\8jvΞa{k3lk<3\ it%:R=Rn N!e2sr]hI3mrBH`#ֹ fȸQ zپ/UTJi5R'I8($j >Ec%WfUcco*Sz͎rGM(k{O%nQmmH'hWk[|ޭUl䓧 FWga-krvh{jnN9vjd\D15@ںT 5p R%ͩ3&CCj8qC*K'CxJk":co9nv9\X#qj%8Xqh8Dt@+'(Uר)(#qq2!y&d#9nS#C<(d]qe1Ꮢ8&̍nD1ɪkdcI8H/e}(-6 Z·;zᵈQ6EΕp5ʝ#= y͑\&5^YѤFn~ P13ko\o尃Ѳ&b Γ.]9[oc9.3?@vz)bX6?<`gj4 )gY 췶T@ZQB{S-#h]ظFZ!DT2ق\nBDLTHm_8U(]TUe=o<%_ꦩAWf]#vEN?11I&⢱0_& agO繗̜⺐7 .cͮ<Q *;r-a $x>Kv]GA@)"ɢ)J]_73_Y@B(+*;`/*-Sp:!_=S%E9#ߌy};A4,ĠߞC]壽nx r㯲a rVy1<佋i #F?a^'k}l_lđc^:?>Sv0p3fndʂ3.5ָq. l a}, NSI,HN9|-9&6)S`!vjI#> H yQk !طfDqpKW*:R<8QMC^bz JX̩]^@;"`ٿ܍ "aάA4|3̲zP0/N;aEWM9fH%`dpa*N ~/OcyL >SO19Æ[z7끌c_aNI웆(MyY܋ДTHÑU dWwNz0~Uv$srcN&Fa!jr| 7|<ߜ;Iv'ܰhpLW)lA@ ׀ԍjZb>X= 6h)siܬTXf^\oN,"uݨNqϯ0%S]\جӺSmas_?oyQ܋FQkgtN∍!|ċ!d3ne " +S+˺Ms+q8W},r /(inAȍ22' LcL=>Vqd8٩";A!YS`5S“7 aIVJE)♒G9mл?pt3z`nrIx￞9R q^{`H+&:VƸoɛrJMÒdSN;^AFM޾93anfrc1Z#R(}3gyQ>=Qv q6$6-Y\̲hXܡ/Sh"IǹsxiðrCvaԡ#Ϟ1$95qg9 !>?)W%` .<, r?K1z&v4ڢ_ 9zu^=\-#K YEܸ#\.?rv74EzDo{sYXs?ҨE=#Z<zŤH>np톸+j۷ou& ϟQԝzs`)TgQ$ht; v=.!:̇0fpr돁Z7Tb|fs'o)"[/RA A~%iy+ԑmR0cpP3p!㊋ݎAi'v[G%-$Pj`YylX`j(~ Hѣ;@`~Inʭ]DۨVF֎y2zuw-?7AøZ#FIfffP\#$E . z'nMN}Sp)a }溈g1As槞bF]ĈYVR G&5@Y:D}'F,^8*3xa `vI,KdSs)3-E{ /35q1x19UTfFëR`yn멒 N0t|Ny dCޡr>a$-g$"GQnQTjc Zy7ȨQGGYOɩ>k3 n0uPA푢-nܘ8F@cXydRId]1=0s+ 1HRfӌ6"YUܨc}AbFMu2~D9sӋrX+.k4yV:K e2㒉6则ʈJqVP7B RsƞCI?s|6w.CjLb g|j7s Xz!3{Rv.sƙyMIbVfh;Efdr 3e^lC(,lhr)nHD$KVD^N1\Oo5o8Ǵ{PB]0ں_#$W4US|/]a$ėY"f+!{FՁ?y"E*|RJq،I&Q ;HKbp_Z=y1F"Yre\p~ SD@jHpU#.HyrRFN6-50?~?;|711[D1i>L93F{v]ٗP## JrhlRUIl^u?t`.'%VNDfȽEV!G`е8SD#m󉒘if>Q[3Rv-povD kH?.m-kdCSj!?v-J d =Ҏ v!XvmPJ䥻)QÔkikD\&=[nE+1FGVs.$ q. }RRFb G L_ȱIb49TZ(hԦncQDG?%[ zpUrKRG2%n޽ _Qq=X "__p$:7V]9vNJ*qA(R0{n8GID*jNmW>Pwp\G@NlY,*ZZI1",LyJ8k{l-}m  a'lBM,]i月EVREeU`؎3f)C;L0g4bmh޺SCgw4U;m*IZʊ螣jm fi ,@2G#~JlW2dlU ?.rqrX(>k"F6^hjCp=F?\͍50KMk#亶cO{ćDͣT qM_瘦^]S̜w.H6Y94. IȖ9&ҫC.jOD*Vy!d9!m+a$ᙦYZ-ޞ͑lGi[HpbܓlvP,hJʈETe?|ާ}lԸE=(ddNUJ:6aG~($`|mnVXzp1 uE2)aWr#a1}?#3S6Dq 2B&<"roj<:= *6.WNIGXGr\#,qjE- 1!@9~paFq_nVZ:3\ѭ 9LnC$F{R|޽zˠH t- \5Yk|7`]I:*}F$t'%'f$]_.3m#lH5ȉ!qKƶ*N|}Yj,eb& FԳDzjGDAbC$$6O*]qKԫߜ 7gb|LTEKʥI[l5%1$%8bWouLM3,`o<ſ_D1=?oǍHxV_ Ar9=雏[WV}${M}PJԤ1kʱ51yFق"_x<ߑvU5׃tuBĄ95YCp5(c3?";okT{\+G;3]g\Ӛ+.[JVU E=*UEgǯ+Fhk UhkZV%/m{I-JxHW?հ-SEڐQFiu;/Iz?.R7ZFQkVm!ͶR3-@,UX @*Sh3 toȅZd'EZ1^y,7Flz"M\=lV'KJ+9~,8Nsll3 Ÿo?6^#.\N}$b{ q)Q×YsK 6BOW<쎁5HKص"~Op7l1c凾u9lb\`ϵlNNH֊C K*Tx]ݵr-Y9U0um .l)'QjD_0HoY&z&p7'nFI^"뼐6$8I9߄q7{r3TC#lAQvg̑Nx\n(|GgpR\K*lT9I~ޟHAַfKx'l<<*k떚";r"mc{F5[N zMP$ȨZ%`V(0oH3JH.]*ukYf ?b>OV▉}e SV iұ_ob,%$3t(c:||dpNF7C Rݓh= %U#m &z,BlW45{ɿ$6M uQ D)Ak \V|aKOw=VڅaF1ŗhqN$XAq6whȼ1_/JodɰDhaĞRk^fT<@ч?s-I1 %L ] 1q~rCM/eo־ Șdr v'h|%bu33keYUCګ{d잋iM%ATDc! MiE Y2Y YEPzǫ:XA;=&sz '-6\/Ix@GͮIx zT(U!>|qVսw cJR>HDX׊2Rξ{Z? .ʼ~gַJQ*:A r@4p󘛳;JA[yg*;-"f3D9F" e5pZvInUY2mqAy0%LȌgC1 h*LI{q$N!aaCk$S)†oK)-Gk࢙OkN\ޤ 0Fm .efc~"TWKIww{xs^%+{_9эE2[WnYX`t1iF1-% IcXoj#u܈0s瑨%_u!`-9Wew"3+xTփ:'I@Q7Tv&9y4mrKpN(焨^[ARn.t雭5>9xq$|%5L@5!2W{d)92'9 K Fk(W}n63NM̶c>DT="heɤV!s=a]VTmFԚIx?se _8Wmekf>fcLΔvY3Ra8A-$9E] wBZ _* bWFzJxq~J*p$#P'x -Ei㻰 - `]R'WZW8,6(KZTJtEqjH?+SC?_MN{zglY9sRvw誼nY"c|鞢0qo|TX @erW3=ů8qlg-H4YfyGPTUcҚfhkاBHs H]תusV `BͧtԜ‘d;̈́heXZ, ꉵ̏\-qѝHFyeÒt )bѐ( )ִ:J2fV%AH3l\ghLe G I2;Hؕkچ2횦:>9@2N_>uRy{}2!lu֬]RU1\QDk 7 4a OfR6DFv׉MTu:Q?9k]/{{w )8:QCA#KIc|=GWe2kc1k_:| H]]}bzA7(Wȸ s(3.%Ϋ6oxH?"ť$H5h!Lĥz &)EET7rTm rԆVyODd2Ɋ21zVL8,q&څ'oy~kN@/k+ʻ'oNy!rގD^r jeQ\[eq$&-$?sɇ({R_58aSwj)Kb\>("B= CtjWe|S-q|v8Au !i^.V0.f !UH~3V^mb4SICg#k>Dby 1tKF.&ZJ,oYRk^zjr@|.ޕmA/b rZ*XcM)5dGK,,wS[)2&g={ǎjzljO*VL(vH1}%pfW?JqΔ{gK|ᖔdsD0"m@%PV^5 n oX6•e%uEtሌsߟysг H%8=|vgfkv؞@R\zۑkw0pCS'ܰA(FD1>^i.CFUdÓ˩x.eqx WyE#oC2}0x6,4>Jw3H'qtpɔPju%O*2䊚Tյ#aֺ$e0ה,Vro *7TôA}U (S*W|\oG+% h'#/2(-!8l_veG-Ǒ-`zIĥymY<Wp@{`;,e1*ʶG$j0 i 7/SQԴG[v@`?CN$Rd׍TNUf% [sلh2g`;i#ad?#rTo$׃`5#aܒa;pNor'7J_MgB"..3.d864"c7f.B$VLU& aKB gW9lCz aRJZK2bhdc)|3Fh "AY]*hԹ]Uc/m;~Y(i)s,ߣˆxm-x%nxR]lNGgޖ;q܌]YN8l GTq@*{eE ^3Hs uiDI9y_zShg W!>W9z\}N37p%0HA? M(X1F~tWBO@ ;+y2N~e"{љv?zi=mW Q"p[8 9܍0J?Y &9<o-H;koLΎh;oS**׬_0Zn3!afe"c931K\)p6ov7<}y.!]%fq7{m,5ȯNᛒGt!9$NU X \W_;~Lcg&OK6p&U3q2D zXb·$׾$9 ʿ Gl\Dq89SE6H_HF ŁԪ* |{G=.PvmJ+ol[L\*|mF ́lq~id~t_8+ܵ_ד0,ʘtT9%2yw?ϭmYvhejL3_Yp^G2~C:*HN:zMM" I*rhسn,mY@Ujbd1\7ɨz{!ppU53[jBtm kMŝ!srEݒ#Aօ&HRD4]aBHmk4mgli`wf_ Oo+RR(GɴR̗࢘5H3PL4BY]7ʔE$}!zOQ]Yi_YA9Ymۻ>Έ+x>8G,He,F@Z{V=ܐ [:[&aj (35lk0RLƍp}W:'ﮉN{>p38vg |ԘtHuyH){ݟn8xF?p2es tՕfh&G"i_=ƱtY8!{b7|ϛysn` /./o:rSbdwkXOHw@Dˬu.a&Wu^yz8@Ar6"\.jY؏Ju+*{dmٓgte|X!l-?cu̔Y@a@~NXࣴum>qP"Mdy89$^Kg ݰ{!Czj7s.' F+;DO5(˼~ݪ,2Sd6QS8*0sǵB!E|f h߇H=ͽlll/Qi8.L5yKb![5COg|կOhqvA?f 1 nXmd Fɨ ,N;rGuy*Ȭ琊Tder9MADz=V+׎?T 2g#7>J'aFlWBױO8|@.ZY{[H{]n|Eo qIBU>Ƿz[DP|9(t}WEqrT363! vXD^q)eʬΨ4FV;KA7F=ʓ@׷.c+ ,NS5˒b2i7 &0iEQEFÖvOrtmh,pU+E%uxM.%,Xr\rh`0!D ğp>L5R(H +m {Rlز0"t9Q5#kԎC`5 1&<<:,K"v#i`;=JiE@W~/[,=rڞs|z>_iI󾥒~*EJ*+9XJr\!dgfep_H6|",Ŀ"l9bȖ&dV8!Z&8UR ]w΂S2ivV\YBihR+ r0;GD!uV ]F|ĜEtG$I!52pwSvdUǬpX沨l (~XQ6tQ@[FQ _h^q{ "rgdӭRdE&ݩcTGz&,qxhʇsooBL cwjyn 55kedSo񦨽ɪۭG$Ƶ@\Fb%Gw8b4g9_6=Obw{O##[N4lM伓@Lqd@S1sx>%lد fU}. ɱ/q[OJ PNu07ooffIYٟk>se!,{'f玍k?DS_[jʏF#"'Z`c#o3wT CTHY#6]hkd K Sfhh(6=$s^%8J.es!"@ON|@eD4$F'~QAFoG(s>r)۾笇$j9,}A<gǙ^)V.PMD߭NUiPyý3$torhx}B+J|pnS'Zr!׼)}f ~bl8fhl,եVu{wS8f+Qu2(jA "D8e$",6~Ʌ_ZJɮ(XX ت!!+&0F¶뼴ap~İf iiK_I`h)o7s1隹s;ހk|q%ysTedE{"[V\k,$%7ε=岼 ~ϖ['R8HbInD3zA"fහ5d F*-*}ѝLrVp)"lm㶣΁*Ƽ=\s!Hq(k4 =9KQ"WP~! ΛPQ:`Y"sL%ǣ&%deFHط,+".cpnd3+a]i?뫶v'#MТdpfD /wȍsg\?}>{ 4xz//G5&nW:(>ALPe'6Oz̃{ȴlK)fi25\\KݢaEQdf0؂Z-ߦ,iy}^",L_!jfG#ʲ\dNpy’kO]*OJ Khub1S"~~QDz~ڷ\yyl}$\@}c>3bC8aKQDlzg<P>SpZKC-#~{d;\+Ev\N۾B2pl,ɥ쁘H6vF["eu-:0# :yöꬮĨ/!kk'ܧ*:{!Y|qk Tƅ\D+ɘle1s3E1;6NjO"]aD"ɍwx;:/w]}=>*_gk|\@69̋6/8Ũ:wfl7޻LmwԱ 7PAvU麦q |\uϓgp3b>]bK *!:AjғZmMԣ(J|Fey@g1rHō`A;e=8+ؒ)sX^r7njΚ:׎b a8 *d'4K2G=,>.Uf*x$f{hMj€47՛egue$dzk( NXb]F?'P wTpZH7!#'_WG픶 Bܣ*ŷJ=y-cJSsdQmp #oE:MlM!=o:AZ/֒KBb!G* w6Dᆳ"(E|4!d2vzJjc~ݑf_gYvg~#~uOG]6UVEw 7e.CܠỆEZԀˀwn/ۢ9jVfMBa;؎q DQ P%eFB욪0qa.B&K8A8dMkQ$R vLk[N oa|Q^UE1u }s4;iVr\*-3o, 6lF (CoT9V{S9. Vz<9okIQ߽J"cr<Àp6}'yFTax֣Y YbΙ-W#R]E~/v<_9APAFwތ85=M,NP[RAl23wpj\HI ۜ|50-ϓ!+ǒ7zNm%cxqھbHYڅx4/Mtj>1jeIivPe)8.(NU^ڠusȂ{$qyM\I~L%\aM+n>r27ޱڊI)$LV(]ŌzmT=>_3Ry- fGR _/$XH_d愲ط5^Xr`g8JE|:oQ^w XSVøpԷRJW#2s<k,/jC=ԷMqϛx51S@[M!npHN\eV(H 1T`}+ BX:Z5E)++ ӗZӒIi]\}ibwCGŪnlfXL\{c'jjKC s iM,ۿ^OF)#1"<\2Bi8F )Mm>k=~\ˆ.ekd1y%<{dqYV5Ĕ/3-c6$ :,<ߩAR_'ɍ".=xϖ/1{Qw;8Υ]sݽ5L&{ͫb8۝]ud%#}SLe cۉx\yW(GYcў~e{$U>"bVYa>dמ=)}071Ϯq@h*9-/δKL;s/nY}S{H^:qn6љw 9k]2L)KO[]g'dSlu br-cF5Nr3"lqĦ(;Vr}Nw J]+>'\Df˄*|$x~&4`mBldm H·G !$vdv|~8%LawNj,.z& p.2vb {LpwgDi%cgm#Zj?![VխQ'?k<YRHc2RSg1D1 .z> @mE9[aŭazTb+ڈYE&D%4b|UdUTdE#U|-3dq$"CqߕLȨ#!Ոc|hoI׫ _l3~|M7;U#QyH]"㏙5yDx?E {Ƭ@ ]*ZQ =EST[0_cIFG&O9E|׶/`m5!g Ut+NqV4^YQ<; ^+%8a&ruQ\B ;*͓^!5 uH&^T*#*Tv}^ucdi8@%)^_uGX9^XQ:W鼤$GjX̣z,`,m:tg<&IbbϏxu l}l~؆Y'2g\:Ss{S ' KO Ktd٬tU,ǀzq<_/:R"8N&oʪ*:Ӱ@C&$<M.ƺ6+9806g0#ǥɳ~Vy۽iB{-9ySn!+j[Dc~rH DDsO mdO~N$fQwv!_{I~Bo=Y3U;.e(Z-Ѽ& mMހ$R\^/о,G5J(EV#lBI X% }pYX2o%#}>Ʈl"d g7uT:'d2km䰰iRBTuLOē"K:\DbJ<;3P^uʜ41?mv9t=\ڮˊP/.Ixߔ8Ift (zƻPv0UYmp"I#f坩sħ0N Dr*RbvSE-ΌHI-2o?׽|-zTطfU49G-<9*+gLD/\[vugAbX]G}'_4Jn{Q'A~d!Kg'6硄z@5}]r2B !qB =$3ẕ,75(c <-AN73il4:-0/\Z5[K((Mkle{ޅ/Gc &G^2E{c"GkDsdŽX(W=R^R_HOָvݗ4JpWQ:H)cmM?u8ћrxW_XBT3 48%NDgK)t!bj2 ag8 i~WdLxRqoU:q3Ucm<Gi"(׹+sڱ.h158JLQ:gGv'pgUn'jâXɺ[yYrA8?ˮ[;Z=KXՍgc:TlZNr{F-\68P7KSI@v>dp9]ik+'Avb3g8j f]"\r0;b:bVYze qpV)AL@N1xmdO)uB5]s]+/gDůi[wgD[.EklhOM׿&M#ekߔEER{dO{< ~pW`(JQ@KM6/Qgzl۰s;d"i96u?ԩ Ke#KuG5Ql\DB$e<Cn&yu>?O@{=(Dl蟗$l̯v).}ɅL{d#"ߪNo1r4qcFENޅIq|4sڻU6؈t"v tTuf(帄Sǥ(O"e["B{g߯*p*G|HxE@*0{^vad ֌L|!?DҜE' %fIu'c}\ɟ'2krP+sY~a v4_}% 6O\IM#q9' *!k\^.ŵx1ٓvRlM O!1H`DDWmNj5n(:jG5EDG4:V K4ڨ8M=?KrvM3-M;V0(y-r Ss-}GS6p}9V!'ȆSo?l9/mȬ$G~bjK;;c.-,0y}:X3g#mM7ޅ& ACYZ޴92`}1gW$]{W[MBbx,+d0!j1Gln(NGzM+SS(J8n"; 4 x/d(jV&O;T¥> J̥TI3Q5INA?XIEVnXEb~}t؂L,)/2_WdH5[; pozY-w,JzM@"CI5~13z0/oBY[!}v(@d$?V\9pD)zsre8ۥuՔ@%>ȶA:DABk=EL8YTkbiزg$c#,*q6e ShǕk\~Q>N9QRa_B*\i^/'C;$*J? l^&85+: gsm1kԹGj.95K.>4ÍԷfC&C%ST[swL0\(JBr0RtZYꐝҲlY:6n 7eE{LQ!Č{88vJ!.ˉUF~5@8 <?(DuZZעPʌt˪Z  CJj!+͜L;@[N¥S,1swU'p3g|Ip^}fpہk$˥hqsJ㧋F8ǽG3O]1Mh4r g.7'-r Y8HLK#Z-rhN׃u-ӔbuV#c%h^H,]ٍBطEҶIr3mF 'D#o_9xJJP#BH'N5ZN: YVuy]f0 ULNDގNMR;Jf.Q\+䘓j* 8;6,i#ј&"oޔ4snׄ' ?s闙{m[$lx;t6jJxJ2%$sBkIC%?g9Dn {h|T:}u;CG:T$Ǹ̺!u.}0&|iuXǓP-U7)D"$ -TUghAaˡ$T162*$J^57iwitHEuΣUEѐr+KIy9ߔΑ@FVE\>L\9LzH܊0ud%}Jg]DL>]ף:ne*m¡ “A|bٞ\fs^6I13\㘵?ril昁}_Ң{g""9v^ #WU|"Yv//*FAqQX^WY+a!$qL\W.{t#Lp~~4 ʳЭ"S+:۾* xey"@o̪,#dzEqיЩ4/U᧾)3=t+֞45 m z7@$Yt4bSO 7>P?i8z'Oe)|WDb)roN@kXI_ߜڸ[]N )q`*mӮ3Ns%8e5N/wpe'ҼR2C, $W 685t:!P}t\dļ,.T/Q)$5NNeiI4N 0AV rah$I5ޢX[גOQj2uR]2 DNz*Wx$yH4jD+a.?oF9yio8-C0u=$3JpiSґ:ɤ̾$PP9Ow>Xe݀+ٔGFZf)Gf <>]~T﹵UBȪD!}'tˢhOÝ}PHAyyAp;.xaK+ΦK)a{l%Ȝ$ycT_vbZ qqwsz$2łMfK:2|.ʈBa"G{.RL#dB uETj$ۥm,ܻ]ԀQ#7/ft}d-A5W0?8VO*]5UVpū.Z= e : ?dzʜlq["կj˕]RҐHݍ(3O:Lo[$Nyi; Kg3J%F!_s{ O1iܗ`Z2#W/0Dk,R7.:pԓOZ᧞: Lɓa *@< "vt=JXΣi Z_#is6@|yqv w"`f c|Gܸ;#H5et4EvFP+|CٲYZw?Kݕʺa1q^gQHRxɳ&t1oE&~'1HZ']kFm$J^/Y -cb)O7 H%x{{$9EƄ,\լ-y^4DYº{ LhcqΒ8USig24B௹*Fo'>gal1[msmzwE){GL%ekizUY B.sRQ->~$z0ͶqÍKj~P&8MA4˨Qd\^9ffua[78HaO$y>$FX*'np|EREZp)Zǭ1GA̧$8E'EeTFVr|Ţ3_ 8:ב́O{Mxˑ8Dd3,tT-*I'-{gyuWBj=,T*sp;JWEC{ zK(VA(aHr!eOן.Hn$I`>~ؙ.f;0܇G$}'Zg7df`***]PpV![Lq{WQ"GAϧT-5? dKl=_N'1arj$])S`Cg__%{g5NkWoYx2TK/WyLIF۫X{ ,̦&`U4v_ 3g[h]`eQkFעuk 0IXqeDiƥS(]sz  ]gټiYƴms: rS2P1 Ә[jM~fo`\7q,Xo׈R0Arj{aT}e 9_^:~d4kXx'\/_6ϗ ?6ŏ'xlٜm ,&׵ mǥ;NJP9ܐCn[ң1n{.)ϲ)4M`*+7IuWa8.ƴVX萍GM;UunœX>3#ч5&TgJd"Ѻ[u-\ r-YQ!,aS5XbR]Nat]k].B-娯ЌsjKӅaN su팉cWq3矶k1fV@ S09cRyl-;zy+U%Wl Og ڠ[hv'ͅڢ Y6Xg֒Q-֛w[^8-b'COs@f\zMm"Q"q`N5Y"]- tƽ\.ynEW+}n\FG? -ߖ͟_fF`:l^RGlƞ{ua~9}׼&'qPFt4S xf+)}/&e2qi20d7**B+^obt+8ȡ s@{<ܔ? SJaiH15I(R4ܨ C(*D/QHe='@^vw6>~hi!ش(fNeihU=dң7pQPϺ^}5~}av嬆6-ې玨_]^ǥunN82.NP7e ^sJy\Pd2kErPY]a՜w'tR0l->t&T0KdVm"d_2 a U.9:F[MϺ &[? B*b=#wabi~q'9lBg셲фb[%0x?aO=c붯7Mcw/x^ݱ6y\%5]ͬǪq'皬uì=h<\/^h7O*x2]cavuֽ|xe=]޷E N0.^f]@{ۥԱ邒'J\(?*UWK -vF;Qe݌>d騟e)K?Հ]5NAgeo[^&,`"gEaݮky\㚟ZH N`iϱD%ԫ^FWWm`_bXWK"˄iKKpNr;ʹ!CsDi&6'帢N_J٪FЫˬC9VwEr7Xh+EmzIgQށNwQO? LY7m'Ʌ1 e/="`3BK05g 5qe-4 T^֗o1Wwy|g{:!,t71TzV~f|O:Jgu7jf^KlNZ3T-t3UYWhWDx޳.rpY@A`j: Y7`dhy˟=_s摖Ӽifk ÅNT2ƕmKFyy{XO+alYuߋS0RY;OWtx箷?A1NJ1L7>!a&(7sY{<'PU"<ƘJ?_˸~28Yޢ['/>=DžƷ]6{tywYvM`ۤ3q$ʨocyHٔ[Ovz6kI΅b3}u}fa~a(1ނm+wfp/ Nf2 mG0 DU6Yʩ7BwGYԳ5M~\d›N ,ȲSAoq˵4|VuƬ>-)yzƑnyRV>Kj r쿷.cpRաyQ/KZqѳ~ϯwyl\bQ'_RhnS,CNfrkq{lm V[īi)a]e:4j%47QRfo'nl5i=en3c.RckNn?mJc.,_SQQ1vlOu]n0(wb7ӏYǾ9l솱_洎p|#g<p[VLLޠz6YҬW6@s5O>$1?SMB-tH%MGSq׫@MOܼρ٣Bn{LU ^ \yd[)U/o >!_m؞KMm̬[En9EZk|^ bWa<󗶴z}R᧨EXP-nՓW|g |A<* nRZM[3S’h9eʿ5Pc6k~ y>|y%RPٺq}XvyDSJ7u@bCkMq 9Ϧ5_ vd2jG K*3SUFDy=}9{lc0w7tk6~"JݻQEPY:q7uY`@WZ. ([t^s3 k7VbM V55Y~,YZhA@iAi٭j\8t[РN*F;gwW ҧkl9_KghC@ 6U&l۩vťt:.z]RthQ¼]Rd qY6&5nr ^.m/i^#Ns0 +~THӱƞ#MFĵem[Y6:^2TI/%{h82j^H\9bnL8Uy^;ZFQbE{ϔyi^y۩6N袿~s@~8IMMˁ6.~6 ne齘W.w˰2bEK7)=@l7_`fC}Lj6{]c[9:9mx#c菫MQ-%DQA@ԍSUU1nxj֕q0#d)Ue X^YKM~ c4̯64 ѧaIMR:hYw.g 68̝@;M#[gBoBa' = Mƞɗ0cEC*Ԕӧ +qVn,X]'9/?Y"UI]۹viue=֒y7=SZ/~ur~uw"OA." 4!=K(,a(kyTSæ?o^ אoWKW]'ǀZ5Ӵ >Gn]hn=Omєʎ9[4̒>ĊTƪChThHp avqos=GP0݊xz=|p?ͦro( =bb9OV01, s8hEҘ4'ߢT*Gy6zbOW }WӮV[h8gȚ;MM™aYN 4A|n&Ӡ/ʚhDY!gs ۗ?O*+`짐'Énlsu⡜Cue%G IFU霛Blvr^_:OtvҖsQmnIն7< nfxt㚛K\  KoQP%u.rkrқYnCN<\eQlHF̙zJ;^n^Ĝ)|nd:&"b9UVniy~P/SFq'1 u1^4ߢɖV9ˮ*ںi޹I|sƱ/zJ~cՆ)v3ǐ85[ʙ'\P#uE6vTfzkzm'<ǒÃ\N(8>K 0FoR52Yf >)Utŀ:Bn01}U~J0"i决5!*=*O $[?+ _BYX\4A@0oȳ`䂬v؅t^xޅWҰ#c9I__ek:%?H4ڏ U>"~zM˖4Cg$:|ZF9d?L7Ex2ٻ ;l֙v&/F4o)$ 4U*M;[CiӷqPГbZLuk%$rߙA0پ{J yuNUbB]87|ۧ0*OybMW=(r#ڄllms;NXE'nmtSiVg!+vxTOs xeF}y=WPmKW&(v SĔJF&=B.pdUe"N[ֻjso'maxO*dcJVk#CD%8J/BK[ )GFBnB]6Av*f;4عn<שp7y”KbՔ|^Q5p&I~Ũfonn`9R%Xܲ:o4/,:77w v7!,lruLLV5T{!aQKXPH9E[( B:.x2f1 LiO)_ɳ/u2ig/+r=~W66Dѯa T"W)ή}z0Oߏ^ڍWz :2ͷ~hXԹ̑ciG ւ8=U8wZ:?T?KpxC!Zdnްv|I\A sS0-?ߘM@?-IüPFbV*mTޒBQV<[ZQt,8'g*":En_R7"KT[#AJ16x~q*>Nz KdqŊ2MW|]܉rR Ň{M)]T7Ȅ{R~Њk]l܎f[kn&hmۖ9eh$I}^poEaP ' B_(T+z~3l*x45&2Wdk^ Ć JL:W)RelUePyxɲSQ~Lڐq|n8%}ַ=C5}w￾__yf? ůײogD_>` J8 imtߎ]^r7I2}(۔v)>0ϴ.LNq_eӣܾ\n€ >Iz!:*Ӌ9L|]ĥmM#؍<&~*iH`Bg~n -e\VasX|x K .6.n\UIAeM e7./Gd$XM$h~VXD`E Uڹ-u:xTǽ2iGTAF/ghiB$ޤyߖwDzo嚎mO/`5 P7ԻB9~˛]sӷ籪]%YC L&7݊::9__VjPd%78N?~ZjͼcNkۇƬ-+ڬ픭cME*$iM"DZ3~qNTrgء97H2E|C$2fJ#=ezJ*jǥIvVf*Q[$ 13wIE2MW.ҹ8Ulڮ)2(ۊJ"VD[ѯx>nf=q~$xi:MwcA]e(P~u(OD٪̼|>۶.vSv~(4RX5Q-`@2 eׄkWe[(Iet0̭ÖyfTD(5DUh栈 D[[ԷIqMʔhAFb]AX1mskMCP7doVo?^m/[c|fx!/SU6̲T{%kmV1^]1;3Z'L>#ԚgDxSovz.L]slu\an6*3 =$)Q9Q=WuHd^(# DuZ<ļ-SAVhNMOwNJã:1}D6 =U!~h#P[/%J `ŲԅrBA?{-Nܪk߸K[pN\3^]'9p9(I%o$hECj{13]X(HG914κcjrtmo5dJٗdXV0"Kim<^7ڼLԙ\?=! /(p];}f6^+ۻ-!X%q%Othu W_Ƨ?M|K Z}Svmm'=W^%zZOBOڡI OY+[\c!]{19P,ax.f]:}\0#&u~/߯#(MNܺ净rhƳׁyNP4*4Ll!Dqh#UVfgPmk\xxΥ *~Nީ^0MKB MD蛫W\ 7cIM Zld4uFFUzeJf̙ìh6nR ra$f;.%bR)YXACLL@mhN!3g<,kxXk'\*<$\e崾ȬˉVusUfZ[0&gCN'O nbΦ~tͭ1>էj4`'H;kv17Oo_sa W˄mAζqG7 Gd~C732;Lo퐘*JΝgos]Q($2xANZRhjC0,+vjLmɶ[nLk_A$`EJɷP',Xrc9>ix[:urp7MDii'NAX`uFj6B鸄!CtT5Ô 'uy[ _4.=Trrtۥ1\ZxަzUTʘm8ًL.L's}EJgVZ@iEI~:aq'piBVWenn9J$uL 9iTXF Pv`sv JːvY|YNc|+D$qHr'a7/r8 UwY?ՙQ:+s\An mRAewpqm{hFdpcGIQۄ rLC?6n萮P~ج4S-C1v~/O#=8l"liUF׉H@@sOgl w8Lg9I!Nxa:? Sce-*{GϵRUy@[ǁՙ.yMWAsznܞrQ{uݖ #sO{w 2/b3ϑdNƁn$f:؉S4D)-'__d'L3Sq< o$\Ǫ/s-EAa1rk]\$a詂iy0voֻ-.~PdZ*ƾ\(h'AKl#b]"A@;!-Hz<4G&Vݲ!,]?ǂ鿢"FYp!cʖʭzʬ7~0qҙ B:vyEs\NH _MtϨ2҉ c(&2K:VQ,hٱZ\u.)Zxy3L1Xot4g ￟:-z*%m 뺨n[oi;VCc{ڮ,-5dMk=[V6ęDخ<a)oﶳg=]?+[X'Zke6;g'`,t]}TQ9bwwff>2+*a`W5Rgۛ>yZW4TdA1OKl-:fh q9,g<:{ó{oH9'w󶉇ŷ֍bM~]TT;v, l0SWmfp'm͍.3Zŧ~YS*CR)Uh]Au/ö__}]ecF|Dm+.Pb<_kl߯mc6ǗKY=Vfk5}]M|~d!ˎn[mE?4UuseӽM%6ߡ.vu$GF_Lr1fKd*eGf 4h9~-"w;uLKeì;gƶb Q؟~z{e܃k_{2!>|~tAId }9'35ƙpk"/ynTbF C&L^ֈ51`]$[ p-`._qN9ψFk7ONH]tTմUkMYUZI) [\k2Flbl-n cؓQdD޹n ꚏS,|dmV@k/+W&UTH%?jeF—魋N5'Fu㞴݈\Nw:X k͡sCchֳeءoa_r$^=F{~4{Pkʢ*Ѽ99-=|gt}y5JLBlmY[_P4_g7䮚?|rJ'y 4AR2TJC{Stg~}·_DXBf-gqsNm{U`'U]1EQ%FלFP!V_-Dq*; %A֍eOKAkLmQ[ԚWІSgW>1@sU7ԯ24$Zkγ-z;z # ^?uLuÔ훟k,5?3?Niaͪ}Vɰsz^⤰M7*Sqӻ: [hnnX>T7uN= Ocm9+TALGW"srן Ջi4PWjwm Erb]8$[^\~vk@C7*2V+4{d {p}Q(c^Q7vSBd\|1k*NJC_ OPeٱqOzAVk5r5KF~%]4-c[FaC^y+eU5v0豪άf$N-m{\@yn&nS+影0r~6nS`3U3G!6+Tߠ'~)_ /\m}frl[34ӌk^:8욷S_AhD8ZYœ liP]noԴJDѠBoiUJQY`uv: f|_L/,gR^)7/J&dQ DR+mj*hIUWJ2knmPXy ".JjtCbhGkŢ X2֬W[jTI)1oyB*2sQrK~!_+'q/c6BRuxSժd(q/)ҷO0gSIU մ`^l~PK5 -LqOb-vm7243+ h :չאָٍ7@ 13 oݠo61CClWtrJ]-Ĝwo#~ь?P~=Bo"=my /g`dD,`<3OQJ S}xXˏwb^cPyLNץqZ8βrhmPC Ty w"'ֆ"FqǑe2emK6G[s89fԹlJw-Nu\}~L Xksz:Mj%w$>%6xXތ.E2{Dc0AH즾 3ߏ*hM1͌aWr!AXJ5dǝlWraFϭhYr'pvR X݂l{9ͤ5՞(ȑ-2)({ O#lMUm =}5"A:q͖R)U4U~ϓ bYu_ ze˕KdWvDBԤ5 ">zE0wzAS~jU}4+ۯX":bgׯW篳Z=WVvϓ_\oy<mkǃ?12EQzEevݢSf&sia 4/d唑tW@6%uBNP#pI̼ q%) I+3ݞ"X%_atF%M~/2'2ض}=vRSf:PX5:iÛWQmEa,s۟hG~YVK $@sy^b$lxBMd .*B}d.mW9Tɿii*U:ӻZ6aAV_?.2mIh(s$2E>9;ivSחq|\^x yQk ~CukO[ 6 XEcvE.wq/r9^CO)GnS`î_^wv©FR^곰Rȣ{1ϗ̮^E ^ 8͓BG :T GgPX湣ߥaR'y^g{ޫ)?5˹9Î׺/lS ,qMC?)4CحT,A[mDno-Lm0bKr\5t!Ǎ'=q׹~~S!((^Aح]FZe3؎d!K K[)x U~*zP(W ^7a<\UM3`7(&pGNT)+MաS&GG9BdY'ItO$uદG( 'ELXڄTUϸ "fݳ:7o&Ո mƚ}D(|$&BP @q?۔ 끹Yh/!6{*e/k>]*V,Td)}{f!aabroR~_-@۲SzώW]!\)a_3ji-t]r'=plD,=+|}?ci]NZJZo7t@¸? qފsaG:|e5{QV O?fϽDnga*~I@ΩGDw{aXT>FaQ![YgRm3m#5>j#tU=LCv?{Xo\ Ls4XE{XDnR oL>}u^P`Em&elHЌ*238ՓIEWeٔg, G,˲"DrHm[ve}ytWyU}E&YṲt)EA2 \Ǒ5N~,U>SvSڷ>fB ٴɋ(Rq̦UuR^۲}mBc}\ҟ6>l!?[5|l2KZt;ۥEn:_;?"O Jܭi.&$ P.>#cf/8n==jg‰:*ҳ" vx~?ޓqkd'!k[a [֙# uut_j mJg]i~4Rj'^x)-Fnhi"zsQIM7?1+7ʑfjZI Hu\O1[$Gݛ,yګ/<9]I"l)G#u].YPUOuv TSKP*Xuݠ8򏛒wLJ#Yp\x8ͨ7ԈYse[iM 2F)3oYV"}Pm<>~o"9LL[/!T"֎m VhW~㱎ϭsd^X1cwZnl xIv 8 >,VUW鮚am'p &UVeT'4F!=ɫi4Z12iuOޣGDuKU~nH3Ibzʒh t~1eD\ZSsEx 5c(e::#T_qΩ O:fIwNM.Uas$ : שI\yMb1 K*qrrY1Ҫ}!Җ^ٿ3')Ip.^8 tv T5USDt[AsK07U"yclF߫ (STM467~55sfӓ}<&oW;ά$(6cTpp6ac9bۻh-񣧥JU|zKÎa"]K[-&o̥[ofw߷H*yPTf(ٖblE}M'nȬ/[V=um~Tv1 -!h RyW4EÕBr0>[.UDq0 UqI֊TxaK]s.&Ժ`َ`}IWln;oCݘ: ybc^%fD RzW WD؄\x̆6qȼ$26M(;~ bY DZ~-.#9Y(bnF6]tDɞEYh~ښcZs݈1PlQF[U4Q\ES5_54} 5/%xLXW *x&^9OnKBM4cO_7NUSS_q꺿.[B**SDw@Tz۽>l] 0g~]Ǔ¤( t׋͸<|k~/ܽ]r&<::0Ϗd}GFr@AԈ \TýWJᅫIs}~JXQU)|#V57y{ݤl5Q%MJvr]̛4g0Ap]&«l U qi@:sY>NKSr%J:v & v袬*լP5YWknMgw\= (WiR w! cH *FN UힽצՇܾ nw#֠ŝA0Peg3+'5O^_nrmTH36U!pڠt[?[EQf-UfB¨Qh+Tl(ZT}_V#n[# fa9A>T~{Oƈk+AԴjpimؼW3V{ןG0اl?گ5z=(^`yZ-R)$rhUWsXUxMB`)3k'- uP51JRLCf́1s-ҴףaM}?O[֯'\xIDATk8-B_0$L֤0#2㚗&%u~ߪJjIa۩4eh9$Pa@g̿2gLS[E8PK g`2)j:eƩ ܍t>t~}y 0P8m9BG*u~}^p\M v7 Qл_F`e|KSAAmQ?u Q~̣봿zz%_Ijϊ@(eU&˾Q)6ֺֻ2@{["8y na^%Ob"KU-euUy1 V%+nDOw\@7dNJfbDHn~>8m~Xk4%eɔK(S ݴ=e!a%E4?jb>h==p#0Xohs:E7a6Пɝ%B|g<̝>__:kxm@$;G?|5/a7^jxz_{Sk>M5zH/d[hLbz&ɓe*@Dэ/ 6⯦}d Asq7}ZaZ>E.ei\n3I=2U^ 3e@t[X$q!PHܪ>ovݲ#Gmk<~m g[U5 H[vsHF5{=v\OS<1@ҍ8o3؝"+?OˌOݎU/4Äe]FpZW%,Mķbex|y5BF}Q>ivTY:; $02_Ҡ&pRC.[ַfyx;}pN:PQ9Ms씻osNh)oqwhV@|`YTHQgO t 4OBnܴdMo8 nAR:-6BSp#eM:*F6 R3k^Sxg]Fgdg _]s6ryW =" Lʨp̛:Zn2*a٣jm}LW ͜<_oWaw:M1\і8X4 |rQṕ?js=.m>>sS{W f  ݔQ(T-+tmv\ܯr&<,t.Yfrt6]kMk뚿X0!/a(eH<9gdA(ZVUwW(7-xX ܥYtzZ=e~]^#^ˌ-S? qL$?l|  436L"]B 4S$Xsds-/~ zWrT1C;H՜ԕ;jf[u2bZ%8N$6cE4:cX3;^Bu#RYz0= ՜ՓWeʴZ O? 6H- H0? Ks15kB{?3S"c 4c1GCepZO֢l8rԁP/@bn.k_7ČzԵkrs,&c '?u`b8m5 0of H`; *6Uaiiλ2I 0G#ajza+_NQ=CcvzO1'c^|1 _/kݻͲxn(R&s<~ z2ڸ^jJ6 # x<Ԭ =Et F3+H*R~;eٗlP~l>F=忕QuL8GGaڮG^h#{t؍RduN.?.wC45ld8ցu]:3%p"AٜUQSk2 aZU)O6g*% 7|o4K1߃[ִ:wjuתTcIud)XM[H(tC 1w*kyd΋"yI;tyACȺZ*{ t+T).\oxj\Ά\3 lEןm̞{ U΍ksx`^c*30}ycnO L#?.P*{_se`5ԎC;TېݢyB1 f㯒dŚq\LW[>}:}毯_"aXB옍鯹^׺k2\Uxy4{v 'S7o_YxFK;UVR{8W~2:XFtJᬩQ<abSゃPux's 7XI?n[{fQ9]v-D=ՇmiH]=ҙ+FHTd8G?5ԕhY2 `g7A*"\s ~kӥYm'ilD^րo;e&6"SWmĴSf s^10~4 >(`V&Z5K$Q: IySZ NAL͢{N7WQϓ*(~?@{ %{l&F0gzin[$2ޑRO{PA%YÇ_[ |U{wFM 7w"v!ټkO%1W el~jQ ҤF:bőig:/mtVz/*&Q/;Nu'};/|1Ge=ыZpF+}tz]蓳׵% v>)Ldv~`[~1jq/Uv0x@hd*E8Au,^xU:YZe]e^C;xlj-_~u`lGZMZ`S,k֌iөW)_;&yn >姼 L唥>{A^aČh '"R)m_`tcEЭTҴJ&1q> 6~6S_KBo̒{bZ4D קqq=5I]T[tn]&NXREi'Gh #)yhֹhŷe`Q3/`mVU:ªקY&]kN@k5.L5 [oK t0H6c}dꏵ:wNue}]V˒@MW&.kkލBOC7InU.PYTSnrAa$A_YNŮ0Ž觺j#tjX4؀ezQ(c~p #3%kZ9>pH/ZDI~&gXwVǟ%Z=~=f>C*s%1,ƍ㸈N5n#M)0SYqŵ';ЏӁ9^L,0+1Ȕ}x#xBzfai&hA~ \%o}~`dd티еX@K"3"Ys<34.k\?s;m,8.9;S ,fIJ\^'z6&Tg F=J6@qG%S;LJ)֮.7n)to°eǒgwUQ&a9_ҳv:5Y|D#Tf%ޜaU>rrmCq>8ɲ+u"ԟCYGG:} V[[`x^ +н؁Yf$i֩ih.rPyYiȃ?7rGFqG{cʶQ]Eb1:KBWG[̺uH<9!yݔTW.qȂCPC:w.4BmP@qV;E(vk6XVQ=vUxV: N5=ӆ[McGЀ7j~u7x4\-6*ǰ̽-0@X+$LPҁz[YO|/}*]: E▢dqR8qm3n8wC~s69Y͢뢬xUt72ܜћ0;d`g&Fvj=ώ>ߪ:>kO{c昙w* jd6u V(@V0$,N(15̯XgxoG0t3Q5Q _mH`dhBQY Mm](C%2+}3ݦdw!;h[So>6+)oϥzQL>κM'h1wqLC7Rb~kݬ/enQe}6H`5R)[x t:<52FQu[\Bq[ͮ}K(? Ѧ=ov[Wn/=;~ڳYU!ZKiZ(dk*tME6[@no\w1a+_{SOƛ7$ ~֥g9>b,&F3X!LѼ^{`rcZTlbmGPD3HoL 6foeF[MxNkzrJ3GxoşAOlPsa͂DhI-ƺmY#⇟ZU M!ӷ Y3GhsߥNÄ|? j:=sc;/wVKtz豍mki< E c:ӓm@q;j|Mdls[t 0ye;pcj<'Oaux=+n!LPNM <).7fz:M]1Aذ|FéCr|c "KM>7AeB 0( .mbEnggǔ:CP8"= )g(d)qW]XL«GC)[AUW d@$kY,2G;L;,}=Kiԟ[{ozyK;+Uz;q0T"bZ|}݈VT6Lo;lCD`,T]*[`qKcSə29u;T0m(̠AWfrEҹ8Ϫcv6X-Oyjќgz`"HaJF/7»\d;<6x[ 6rX׼ tZf\vv瞜;oqi9lgpP-5P T׵S5<3TSD {a iw=evܽw3\pn\_h9K0dwΘ&i2i+xeژ5Aé;ȡj6BA}MH\G \٨':ukvf6{ۛüόKE+Ce8[EWЬpGN5WWB>Q'TcQmmQmdՖi'V{?+ZX^|ia*v%8h㗊 Zv2fgNχ}R T/ǭTsI@gm0Ǝ_uX^zZ۩~_鲖f[Q1u|cFCt= a t':8JH" f@nՌKnce(`L߱+1AamV x^ UU$p)wۙ{-i3xUz\z^3m' (ƽMuLĵ'jt)F+x1B;'/PctYB5YQ&/e-Riuj Ș^_֋aˋRݳP ^V?';^R5 iPBL$B&I 4(?.E /Cg+._(ȟٓ3߫B!0PFIVzϪ+ϬG'GVlSx?Ԧ]BNr:1v dXZ2d9 XS_]?{]mьˮt ]|kv[Fs &0yŠUr1}M%M7m{kZ=P+_Y:=}0%MrKM@4,#ڦ@ НBjJ}ݎy<ş= sG3'#П#ҩBbdTLYs48Xsx]#/x]{˥hצXaUH@0g/rmx]jf%MﭱZ '*ܰXeN3o.ܰkk7 w?_/n^ \-8;wwo-}-#Ca04" "uO35Qi)KvA6& !̀1tv0G4+l4חV|M+"T>.[#ygzՂ'+ЈI|;h"Y16 j"nkV3NL'Y[x5i?>n UXP`Rwa@S3V9Y^>)z&ԓQ/mҸntkU!,4a0m?Qu>_՟Ofny~?6F73kW=3]›L퐆ґꑢ;x&>h3#!e,GP9d 3T"36ja\TQSVav׸-`j#Zݏ"y弎 Ɛkba.) *QIae-ׅp4@436fOESLV~ W/~ 'M\r8Io݌VԚ=XPTEqy5{޼؀0lEmrMm;?Uc %I a`$ b|m|+L>M"݋.)a K!m˒(#_%N 0@$ vPg*L9]-\F=>_Zay^`2 MA8'00eWȡOTjTCd(̩r V(dbmΙ5}RtN:.bNK Be^z t1Ȯ0 zX/p JFd27m0z]Pz"0s^i]4@Re@3Fg`QmɷzދFby|S〝(M֏((3W„7aVuR;ޖ(ú<(Otu\ַgb-Wߚ[4qi1}ͳ3q[z%5E2Re-գyN !c yGXZ/8nvE7KƱSMK?Ja#q7km<(5jl;" "\c8tӼ]`toRLגI7X[-kg-X~־~=\yB6w@pͣ4p4'JGxcJqɘș1L֛AGQèsHe' gM+7 b@`n/e9X>+~abxd})Zj5]3:\!2QEmij|pFJZq0"W>QP:3v6P(4`Sy)ST1[,,֪LO`{l;+p/]R VkMjvjH~L&~όoc>l߇y`W#|TR 0u섭0!]tXS2>(j]!f9]N+O])n.|&qvb.hÄfܡiG5{sv*  x;TEi8X5')9nRbP('aI/ړ^Pj;֍;ʶ:uM҇1q-2ϯkA0W-ΟTʓ9oU[5ޱªs(UX|[~Q3zꡳS)v5W|J쐘0gaXbPf,ﻮ_Y$qnFɆ3CJKHyPUz'`4^wI#B3ZզXO@*2$JAz{ӐE"׎^G1Wla=n9pqLbdQ=ڼ}ք"qU (g^?c-J"azrVkY.'-`4S D՝޲pmc|Skܚy7!G'RlM,uGTMs,+ܼ X*i߯}IJ~4:autz]d,"L.h%KZsvͯi9}HTQOѤRQ`ٻ,a!wlebiCxD_}m_@}^׸qR#lT>Z悳e6k{~}v 3$GX\NGB =^iؕkse^'fu: $a y7-Gj'zc!ي\8{KlQAfΗI{Օbb c9A`9^{܋<Dz*wOٯ6]=,HZu*)hM[)# pky[㹥9ڪv[f/;W אjW(+OORB(і16ӟM2}+nlYxF!.w-m8gWЂ(XǰJ8?а=GЕ͔j'Y3,F :Ϫ)^RKNAKUM߳4!+*6%D`:m9fc8F`vgE._l]%ynfW`PBL k|9ZgKi}:bl҆3$M{4!bE&X SjV o|<*,:+3yIBM U<&=B֦||bϬJ믿U*,OXW7HjZ*M.9- V~t?CvqPԥ]q*bQv[U}_fO?>N0 1ڞ-Bd:휠"sNsQFǰ~j`C]=BC+"ϣ2pmFaeAe;` %]PKZ#'GaQgrğaa˰-y'Myg Ɉpz9(c =>[7`[lhR%ŒkK2 X x(d4-˸i|0{)„e)}ϝ}P+ 2t]VnȾw͕#@F?"p7'U\JYu;KS'OzÉ42o횇&' ƪL:*q_^+`TXI L-Yov6i;??Xǀ\>͏[͞bTʲ\Q}Pg\Y^17H;8{ |>M["ҥ)V16R״+I@Ojhz^W''twN0I~Qۥ{]P-WX5g#n X*VX4zUlqݞT0kCժxL;M2T͎o] xnYg/}90$u{e^} D_R 04HƦaԦ O<4kJUq LQepK'^Mkѿm-.}c\)b9+ZMZG 㜜6<Ff,I_qb bG˱h4 %\\,؈y.ʭ*[]hK#F:#GU2q`Fj;dv:5CteTmao?,[B$K֕} 'ZvLuDR}rռ :`"˾l+*z^U+p6-쉦嘻=%u?U6N\3S?K4)ARB!9L0e1Fa~^* &k6O+["swg}fz\4<{]kNN \Ēu'|XƇ XV׼l?LT&ԗY)ҏF;j*I,,oټP /έ2D,3*czVCÀqW lĿ.15CS^BFmbGz:a,댁 O {,hPLv' p%t}e1uaf2=SZ_?5ba캵"'+(&DBT)c%ZpgPXJ[ 2'GzNvV [/c8Ҍ؎ߣ&/ 4 涿ö ;s"Nu K+,GY Δzbd55L)fk.ph[= ;7p h3>a_0sh C}GxXe6_H?_+?{jX_NeAݸ Xg4͋~l5az&yLZOl_b]8#ߵKEvfWjnǍNyXT&_*ח{IB/YU?T_f/RٗN_:xHu 圅%lVTu|"ж;l|{Bد)&(UhQCx.Į--!rh|@{e1Jm^<ǩ%b\+.e-:2Q; vѓrh;wMׁ뀔}Ͷ1:X64e(Bu} )u H`Dz0D ev_Tڹ0zPn0t8_kSU:>Ep K(:<Oԣo]DS=|hfJHT8v/)L3@E?-XPjzRAV0nX $LؾuT>/^'Rtm\0&oNW BjC 8l˧~eBCOkZ\Ckޕuu=1ɲ$>;>qyq*Ugp,Lzg"IɺߠN;mxݪ~L@9 [ե,՗y)@qm^kAh4ŲsN#gӼ!Uό;Lal[BYJm DܱErۢ>C@<4JAV`=wOtn&KX!e@Re`+F8om 2:y*0ȴ=8\Z=/M|Y5uEG %{tBw:xM`Zy@yA N͊`g'w |IѷNO~ݺXfLt{RF슼"/so2k_!UH;Φ;4x̄%Wd1j;:syxA$hqm87&7EAGA5 _ 1<uW F0Ϩ6nvOUt8_l/.WNWԝ mH&NJ/ ׫;Jw?Z2NHe4S 6'IМ+$q5bO EEȼ AXUAL& NZ%?W4=XO ZU ƒCO:<>,x )o$dQ-սnS Hen6K5Ԙh|]M4/69U4EnU^ mCĬn0ջRhx3LCۺ|T 6a}U]hBX_@Kyxup7c"c}JBS^.$E}V su+n1\Ĩ=m̰6;,K ,$B :8z'ߛ:c$:B򶪸4Ʋ4n[ݩK[yYPfXY[(Laڰ`9v޶pS^<,t|FEv7Jo68B0ǜa5?M=rd)=ުrx6iuW+V xeK{8Luu0F^ne'[н̺k*˦yutH eQY1HSofyAf:*!T*M?WuϪ UxK{Ę2; z3qi\g3^L/o{'-Wb8CJRVm8]\eY.:#~ ۮdc4Jm3kk{ZVNov3FL~+z[{w( F:yLrN~Cq 9bI1} ]} >ԘA<]zkŅo^pa$P$UD q=( Tq7#vZ~c^w|X6x zK0 ''v T֘/wqFƪB zK@P!IY2V׏5ܢ(q 4>HD!mgNU]H/\#YA˩t-z-Go9J˙՗n0͙ Rp Sj5ͺ3q י9"6wƸoPU)A ):\$lj܊7 qp'N8$/ I*Wt?l| khZ*L ^{|4>d*shOi`=@m!\]߮}S&zkvboV7_"fAÀ}_zbnd*ٶm;tF4ZmX̌q/Rp]TUi 9 ۣ:{c^F3cɘ}w}0mR\kgb=,Tʂ>xsA NnUZkDA53ve!N¢1@tӸiAC"\: hY}nM~#3Gh&EY8oL]:->0byL(ј26RC$gx}sb%u`Օf QVu+Jb|k5f~e*ecğ/dfZVD50?hgxUR=mxZS10jJ(Ǒ Z #ns㦾LZsao0:yfk+u =8/fm 鮯et)^ Ql69Sq,y}u_*Ҳ/?5[b*b 1"Xl2:ym.>#Da$.hGnқ2{dÂx[t5zE: ԏsͲ]<~7 06 ňRPm}ZY`P8RԣJNUXҁRDpI*j`W-8mæw2?Ġ4*z-&ƕjr߆CS5PsSW\Y-v@oiߪ /q&?t`6fy1;i_f'Z/K}FN'/ N{]ݔFY9{yxe3 ;U&eK[N\zHtߖSltz(;Mz+]e[ǹn!tf^6ONS2a~2 : pc<7_GooU2T8`jg&nV8UWD$t&UԔҶt> ak3aWt1M7L*Gz<XUhGUTEi*塺ZU,*WCEDٸ gyȆ2+Q<n]U8-TJzkR\Uʀg YSL5;B1 B/(nAQi{+{Bn0`f.5(קK΀Tb_vFsv緟?3n9~D%c-^vinpd2T\V/{DO>pSBHq\@Co4az|>6 &m&@;QzZarZ>Qn{=t'39-2^XJPǎ-5XsYڏmLs݌Y4+jàM?W7MǦ2l&w#v+ Oe^h㤇)'@c5eSsF}]K)/Ӧ<8К']0jاm:3d}iCQ:ݲ(UAݎ3%}ƑAM:o^/KN,|}і%gu eؼ-uV$ 1VҞJrлlǂ/ΎnMuS2ZiꣻP6%sGKk$S,/mXY&tZ uCX.3ɍuvYG\e̓[V-0|׹UH1TT@A#KjM=UW!g|f2e$ձK{8Mp膰svvoW 7ԍ9Qq( |[ `FG&wŹ pǍDf`YQpח):7<02y.fX$ikw􋶳W&NmGGtK8~>AΑ?p_Ӳv%7+AsYj^bdHAJ?L!V *P(Vo%8#ޟ2a30ւ}̃N~A>n1\f/mb;bG|gLma.2EHoQ]̖w#RŜg[2=xy)jTЫQg')|#{kx쓷*ӾԑW0W<;vɴN8{8vs''R7mlWSZo+ZM=턵+VJ[D(6!}IUa3lq_n~s7 epXd~)yUz&Q d5;)3KfJW67dGKGaNYR#oUQRט-;@4p32\q>n7Di1Xb.%*TK[k]eEC Ih-0b5 GVhI{'7|NZЎ_b5xkώ ΢s C*;/Ei@oBOG@V]snyz3Rb?mx\Y+KkvBu_?{ByF?FDG P>պ{kuiPh-5q>0O?'EdoKƻn~wFsɕ,O]o#fxS@"B'"',4CG~|rc0yf"uF$ͳD;ŽF12DҴKMei鏗Ց֓E}2s./ye۷z"&C,E-B&DTȹ橿=D(fEf@޻J 6Xp^ zy@6ga֮TnGASCh!RV.=)\ (PAXMPi[lvn`=}05o~\*wOS8$L }%֑5W(mm+n ԌHXԂv$'psh]#yOk*\dw0̙?xb8YwKKFgo.׋QjsFs>m"sfc?t) CEmUh \\PǨ?KoJi섛-]s否k2xFˣE$9WGf7y>.:bMIccʭ뱺oR ~4%,4=,+ :_uJW_,6Э|&7z SK7}PG0u?OSh^1J@Im*~Pl0B2 f),!ɻ^:U#l2UύkU;E{js0M@AC) xI m[%S9'ۃ= }ssl-2bZS{1qKw2p` !8ƞ#.3Q̼{B\^a~B ߆Ֆc ֡(>̶=&ݿһɈa]&\m3(aB]fKs sZ]=bk!t=tqTʠu;IbIs?ڶ(d`=$>fWm~ ݴ? -. N*dİ([+>7cx*քF՟M%ނ m&<{w!oe6L\T:.^,;dA't9뙼_|֭npS -? KR EN]Ba<**SI*]ĸaҁĕ2o n#v#uYRBPC#LL,sC&>Bq &[ܣ΍_y_<^J[f(ʺt~B'{4C^|}9n'~RMm\1n SPэZ\SVZ7ĶN}օF0-pcifhwu FުqCt"0m8' ]yڬ3qrCAއKW֗M|@#7{^Ͽ .c:zT*]!f.A->/*J%{h\m"vzgv]t*YX!Cxr+}Imuҡ[doS".g% 걺dg8 XV/$SmXhl`@mr_z|84juS~= 2j[a]ӋR؊go/^l[C"qQYxEgaOu<khI^YmWC'z1kŇǪ?ףokG#fZU< 1k U/[gP̹ͪWoٖo|mNC;hYPfU ʆM0 !1Xn4_q[gR1shq7fK2 k}a9mIPiDQX>ASJv։VA`Lu΋ |N"[_z@%1SȸB6cHUԛ2 "Wo2gS}X~S 0IrLO; M3 4tQBYU߸S)FZ5f$ukI5 ES6}:Rz{AHжQ m0 5p`yaZBИtɧXo/o]!Rcw+(M.9?g3 щy͹Y8BԨ->2ѨY!_G NN%T!05uB:5 E R2E@HBH&G,3)z:7c?t!}oF˚_ϕbƈ yjz{t~)hBlDᎣ7޲d5R6CIZD6+(К2&Fvz0OH^,8i; ieYi$̌Ni]z y3*7U1p>MuNocǫ~4v1H総8 X6uZ 9 *{ĨzJ[:G|O~]뼛SyQ$LgK| u^Cɔ}o4WH_nD^[]=6 )/[(]V?w©./;fx|kT&X6H6U(M53 0\ K<> 7 9V´Cd8IT")ݒ,eq 3kYquDK!GS#qqQyco\= w1` m |X(gw0\qgͅ^k-ժ32 ̾;SJm3B I2j: *jvBur R̢tYeIX) i7,g*) UtAY&[Y#2+ؘuJӱf~>HJSKAI 7D:êNs/issjmhu54!jaZ쪲K5Y[Gsk)ѫKr9^ћMyry(c@}C^IV$ckZa ˅ =:ĸ4̯醮P?N)8An~SJc *tU_IaٴLjfz9 t,;aݽ,jsV2|HKRX +zuW+DAL?>45u- ViMy@mޟcM߿֦-X' K4ƁG 5aKP J؇lUu+버E"k%CǢNubjvcD٪|SV߃8^9{cQ_:T#EcEyĈ7:6 6̬:숊Û u~vӍu;o3lccͶQ rG5Ԇ2`Po:%yG8]ktZO:ASֆ( &d1G/ 25աU[;0a׉GS_;*&XmlUzJql[i}d R1sԠhax=^!ZOM|O":ƥnqLS1=̉xALXlJ9<,mIxE$N3c@i!(vS񐮷v?4--07b#L 6fQ*Vdtn,)]6٫r]s춉{6~/p~@ԼN`, Uַ#WD1AU&/{M!A<.0VVŕ֏ee?j}ӏ Cm;NΛCMQ-u,&uuN=M8ϯ}y,}|~FF#YAد)o|*^S"4UHwU))WͬLwH٘iSI9/U\ig R'@j2nT4)XU;8_m4cokC1 yog@+r6&bOen*n;KZ*pMTl(|oΧW7znos~n`^yEuk E 8*)^ ϝk[~xs&JxycL*{ũ7_= B0/PB`#ðޭ y()YҮVz/eVkCJ=$Vϒ[^)WUQB "3M+7Ǯ ]s+NhkR&a_gu{VH R/dIح6f'okAΰ[:<Qwll|խmמ]o#},u[TĪF{[W,vЂi6B*- yͫ{hЦ{GyM$ z:J vzqd>vy!@k4~l 'lqڑ$ٙ./1gؕ@kmZHZ6T; :n۶]u- VpƬXx-iCO cTކfhc<$7-ҩV'_%>,3TUqލ7e)p3-dODH{r$:6Ͼ$"#zA}愂©}Um9m Mb-EaH÷l/z_.{Mvj\~>2}{IM`Z7nyx汉UcXqܗSPCQTBvXC*E겉e`һ+5?ev#:c߯ciCb5Ft .XPm-+-مPbi@WT{M%ax-:٧rG2xxR70HL.S$,ZSx' 1yI)$DLb&m;*E/)W}vHq ։/1pDK_uqYgaXvr2qJҲyLv67$] &6:=?_?_7^ }"#$ {*tV5F1Lt_z &y0_\9̿>cu+t&͘e w%LY7MGJ p'ꅲe r1*favʻf{84v{[<'Jd2t_ʹn wUuDQ5gQ-/y!`Ͼ٦鋏ON2&]+)kyLC T#gîjLbw{~im}zVi@£P+ݹnԐ5۬v769q{GJSuzX>-ՠ:>uK1t`jaeݰ?V~`5X~ >SِnYd:aa~.1|.=f;ƳWsr-~`Yzb~C 19fD@Cwrt*$ӂ}| ?~{Qh?j珓ngMU9O>H%iTat(z70=mIm/`p\ .LmLwnu ?>-xa\#4ƳIxI6Xawt(w4;n]#PLឆ#S.Fe{v8ӰNϤTB p{gT0؀tǭki:)=مj89m0{No@xu#WH"0p}*=ΙRr\8hyu0c 2nNi]TѶ -3ڟmԊIaͷ{gh֪nVfӚ>6 4w@3 93 ;3HB&J|1 }{~@]W664`>̽tfiNU7ұ@Zl΂NKΦltwTI6糫~3!0TC@f: yw . 4cK &OYA4t!㾽Pl",A`r~]p@9TQ6 $ RI6l~JsY>%[Mn݄7Qa{ph~֠\-*b7*qY?Ҏ@(g&fs]6+޺6a9Lq $/*uZ Q:aoƘ9fD>7= xsMҲlz AX/*T>&#ws#3BidǷL@ 6&![֘`R|߹y5UMpkujQ~+~uAeKlIxS.vDCneӐ73{7gp5s,n+nȨO>9j$*JWOTov'(=v῵c7reͧ:A?xMM%#ka#TϷj\:b r,IѪo*b8֣;LPϡntb5mܦ0eӊBx7+^׎ISXJKvs=2`u9 LrF^؎{m4# ^ɗ0-_wn3H[Dԉ!`?};=ܿ]k[Oѕhx#,LC'Q~Fd Rt, K`',oR|}]8UYnup:{4U;0ƶ A0 eY T]3?u ;)oxZE?[7'vn3LX<ɓTMN$z[ =l4vyq^2u. =P?Oti:q_a#?_7%"ϯ'fs5:oan*IÒb w %tT毫8ڞ['Vxn^/{BHZ&0Q? 6?ƣߖNd`sj1o1] UX+(BkVقݛ:]܊Ey;ڶ! +Q-.-v:}z< _(Llα#sZ2;W\}7ja6+"\?V7~˔\.R{{) %@/Iyf{HQAw4Tt0"s5s9@dbE]Z Oj$-6<)@P6AI ]:H>Yq?]@3ylA=Zu:+l}k^ h8UB0yRqΤJ ߛ!lu;Khbԁ@V@ v_<̊H^\l7݀nTQĿcZ^6fIIR7SjH#6e5U窖?뤛zQ;V5{uoeJAom0/zk|z!d ~Mצ9e΍G1Hھ3SC78sJ/__cARd]g^=L~kG2`Ce6gY}P ߞo."~CS%wqYM: 7>EN/$7֙$1R&-86{t@R}D*dFZ8& >$5 6BY8|rnc(_oƩdr¼LZ_M7$6<Buku&88IcGH(E[4Y٨Q_7XHzx SJЍ讹hIoZ%۰>iYm|{~rO^556T BxGd]Q `I 9v闁?t'zހ73o3{{ dӪ\һ WhU ANbՋr8jn Y*CM&Lrv0t-\ڦ rֹ  .e]E9UՁ#z_Ep6+@/a R> upIym'c5B8nj! i/t4ju=^ۮj33%cdhuf 3+(PXiazCz%ƀ4w.YI¨t H]+򸇩P!Ui>3&UoRT2˂ާAv?MJ5IV(OǦU:U%2 `u4:o&btgkZnanȍհ b Xu $ox j݁&T9wȄ:@<ZervtZU4NyPz z6* aOױ#Cm\ XTwy6=Փysd"[ѮʊNf@12˫bt\z5py!o eO1d4n^g7EXũɨRPO}#HLnQ;ՃSۀN-m}=Iӻ.@Z]w5Ӏ Әn|E 2#|O|Pz*ѺR}69JH75 Jx'|-Iz-4yW&dƝ3ƥfY|z5p7bnV 4P4e,Wgm7 LY {wn#Z 5rU`2rmKe;UiQ#|=p\LOGޢ&J䡦 E="~,{ aN{]ר A!&|Fd,BNkp븟 !uRqof]'T܏a^XvUO Hi9Pδ~5n6r`tAZ@)$OZIMv*:eoHQf8FI㯤4<7aˢdio) ܹ~ NtOJE1?!g9ardg]tzycQN84ڼaUΠL-vC#Fg4| \tkau:L!0KS )q-6ΕRc&*eq[BC1f(՜>{[BiѤcM* L DvR7 u!Ϝ/ȱ,l]$WwV(>D+ٸ=Tv][#^WԯGv[xLɩhP%שުrwK.lE:y0n5|&U9MSk.? Zp^4 MҴJ;+WZn24`9eKWnY0}>(gZn`Ͳ^'Tf䠑uނ7>Duݵ?S{[bi!!ml^B2umô-׬VӳjZ34O^K DնW&DgC*eB_a>iZ7J3eX tLʥ溊ik$`_~_VE:[}2{YY|nȞcPl5m3</^׾IŗMY0*Lo5FĶ]l`;ԝ5Zdb~MgX߾[P0 mrMQMFl}WT*XXEw!rpt?[p'dShcץ!PZa؀fL,tSij{k* Ӥs[`$|yoaR@nh|WMN$YN5U7MPt)w Qކ#m0;OشAfQG*l__fqZQ O~“<#n> :goH/X=8ΤSp:YcCo:GKUtmد# 2<~hFa9WA=RH몥3#0 oevB,:5N[[yWːľ<VIf?Z"B5t~8*U88hif@'rF Y5xj\ j_I+Tq5&p]T ֣C V0mglM! azd-` t%%twc$YuqH[ʯjEwdu^DDozVo}ʽAh8T4Nu~&Uzt/s= q=ءRrEb:44%w}:4 _wV'} {M 25l=R MI^v!hc2lyxALldޚ޶vom9J Ҿe_Q3kN[^7&*6f{.Р)z2 3|ڎ{]}0%mķJY5w75gx$РrbI1bFNi}keoTfGWT;4nGl߮c%~ !&X9^PMZʠƲ/.e*Y;l P2c>m |DjV娞7I&kj,WzI{^_cJ*箐 }̕L]4f4.ߒI;֣0Є}VEP]0רLpLTN/+V}85$Zh48:WgAƬ903E1U֥CBEC "ILyrsHEj mlǒ:\?}i #0rbr7>;C. 6ZˎA\g,~GJ_&#cXFp\0l bvߙl!0̙|W^v0i*E>wEMm:/h'_ v uURQz1W>BHo''I?޲2ft:Yt~UJ(5y'A5u|ż6C̘aq#TLz#9sk[3S-d* \Ѭ$AIXk Pa6(+UώUiA=27@V1j,V2`Ф7l Pt{R]W2!jHӰ⯥dR!X\($X: AL=c2MC`mUf|2{&0fNyD8Fy8];h4#e߼?gT< tfgGj{+w9wM }1lHӧ[NQ3 ᇴPvoBM_OWZ]Ä^t/O/ΛaPU!C *Xu@+S~ҢˡMs0n8y) 5FD{g#< U^̼J(.a?#7p ENwܐߔI0̍zj;{a s5#Hٛg_޷Y7t|ѡe[@><#h}eXk(4[euLFHC{UǩSMj&6{mF> Q ;Gp9NV?@gjc"M1BS5 VӐ&ocv5Z6n\J0]Y/C 9wի򼩣+zn?Te$M)6$> \xևbn&|Nh́o2 03g[ݶaA&Q}rцX- 6%]4%?kFt\r@Yc˦7TfAf ! prߌIzw5 ٱصZ:=HBwX33d5dZ׸>~M/iȊB Iuvo8@a5M5(. =P*}ccG8QEԭ*ViS5T ϵeNC?*~:Lj&(A]R뉧5<'EW*xf'ss {7ԕVA'IUfu'R3M{޿hƚnU/x*&gF}n'ߋqCMz$dJ3jMx=`lER.f 8cV~\/f܉ڐKzIGcn KILKFqnhfǍc})kP>]%myYiSe2teVk=0KeAQ]_F] ;PIZUiʶۏCɺˣI*Ia'P}|q> (yzKši˪2msOm`Z?@;n[hcL]#Fw~K#$Z+Ȯ9>+6#C_=0KL7YޅjҼg׍(&/A-"Po)[0&27*ZW=bh gUpc+I BmZYЩ_G:M[UBsCG`-(l2NLo5xG4:x֢,DEh&Ue=z-]jTg@=ܙ5V(d, #6W;#9| jC*N+bb`u}3.a0Fߡk`6@2r S5 tUvOOrPmf:`[\8=z|'ܲv700{?4 2dRWJ0z;nVXۀDO*;4+KPo]m=s}ŁP?#?Xstc^P(N._]`nkkkPĻLocZNކ^l~:jYV(xV% L:\XjX JMVRkT&=$ZVCGIMFײ4aJI .+KPt)+k.ERUuL 2rZ#|1XnmS%f6Qwe)KcCi&+B+3ǠUZ6 hYV@Pxsb/-O0H>wef>|QCU{6R)66ugWv"1g8Ü@Sٸ;GvW:qqTm?p>jf4zc빏HkRZrzY h\1Zluu`)۵ثoN)Y8 -d+H!̃ORDwz)]1,uw#i98:vP)WVUjۢj*AaA/UT[OLk"@7lMupupP {IS|qTΣL '}œӤ&pOk *j*9 օqp/׍rOs<8\jNFӓ/]Eaʓk Yɼ6sML ,wg!w*1hkК6D'Ł3C9}x<10& 3>] Ud}Lh|//ݠRѣXI7~ٞ~G4-Đ_OAd]ցf4"PRTv V԰$flP!Z}']gEqnRyVf3ݘaI@r+J^S6=[!,*!(3s}LӖm{~ i g4fS?7<1B,] Y]XǾgnZ8T􂾎߿2B0Nvg'Tgp!1X g[`,@c4FHM垐ɧj%X9#?8My|t䣢i-"u^w7dM0Nɞî$X,]7I\t~bGʾS%J0X?LsJ:vAoRZcQ¼l#pשa᯺X|}Ƨ?Sn*KDL):ӷ "=ſU~Rl7̜DN>ot?gzbZKqկ.Owp UA}^FeΜinʫGD2/&!9oʎ?#)Lr-t̀1dz0ͩ^ZT^~5*;rFp'a' Mp2]q 1kh7.*kCf^w}3݆.zi({Mr<`W T-6&נ 1} 4qq03aK=Bjԗ[Gyo ~ ]*~4Cam]VV\zZDi%,9uKƱ|4SړJᔡ$v'NQWkc2qt*]+LaمEL$,_KBEh\LMWw~\Ҷo\r?x/tUrJy0?:NA*4~y'b V(}KO2ut,h(^5cQP~u k#Ub9VhJٜM؈9פo8me^f/brolfĴߖ0ƨEdLӋa}+T#a(/uKԤw"-;C'Cp゗7)ݾ1+Q`~{/kc.&)qL _=nU׏(˵HYq"eё V-P?pm[Ä_>yS^q4yQʏ.݆0u\|"kʞ~LG;U_SW;ݥBm,Ns?6#N3/Ӷ:HbjXe52>)d÷STaMf7+ }e=.f* ,¬8Ea̚@<Ҩ.yW)yɶI&]Lg^lLWQc\v: Ln* v=*pOmspEXO瀘|.%8.šEKݍq1^(j[SfUߍջinODɾ Sp L%i*t <_5y:iN;qġ<1jPM5Byф0/Ϣa6;xP1iw`|:qN#/^yo ֏=FgE bTd%s< F@pLO.T, ?6,I 3pYPE;m ͷ!39Ub m6"t)GllҰ_ԫ^t7Hg:|)ݧ"cc99?4Pr K* !ԙa~UB]L FMCzcٙT97E y^@lAT*:4H]4e;3:q.{,A*U_UI \דr1#pS؂ךy>l8| ^Rű"n@u3a2&+uEZbs .Xʽv? XsHTU?z=)H?(B_ףCݙŠߌ*"i "0T.ɩҖY ,?-ˤV˭A|!46{c͉^F~r61 9~TYf8=BNRQ7j-WˎC vR"`T||zqRgMk2bnaY׿Zl Ue*ёIj@dyM-/ar5jLuG_'QBHo=Pu2$fU3zv{puRNScmi\٫`AG>zC+GĤG|m}4[f]+(C^W&4!( NM98hnZwr{6BݩXXQ4-S,s/SjRoAB06-z3<Ưc9[-RfY:\Ճ$s |(q:]3VЇ=[E;l{:6[ϊN|:MĩPO .9a<r)^Z?A0-5lKϚ^Rԕ$ͤA7s+?߯9?צ%0Gq>d%u+4BpNյ7()QHѹ6]JdJc'zQ߬%򀂡նa!ؓ 70y^e܃&4s&/jh=EdS,k#E*ӹ)wzp ޶YC2PDKJ2&^Ci4o>#ZV9)ԻAvibV|M}"Eaxͺ3̏5\Ÿⶰn]jX,|r 1iw~;内BI 3u+yX:{CIJs R5;*Kިr5AπJ1_a7+%J|Q$A.M> R2\>=7~V7UYӌ|reN._q 7BЇqެFv-FUv(.ʬ sy4̖d5]v}"tM"SU|WaR; -ڼ.Ue]J.I[_kVft !Y Wt(&}d]`ruNةۚ<zc݉ҏ'aQm6EI2Y:!%w;Ż`U8FY?z{Os&keá<zMݾnoh4NISu sD1x|SuP|Izzh6ٲԻ?g4KBޅ &]vڲk5sR4M MPWUn-"Z:n6ӒToCW=Ѽ"|bF Mc }űe{\x'7D` 4Nj~ZQU0_aU,uZTB}|x Ke +h?< ĝ03aXq0iTfzUgK̢k^$.F󸶤lSg;Ԑw4$л5jm)CaIAmޫ[ր=2Jo0S1 PeRS t9(=zdbRlbykg:p{r7 nnr֯iS'~Uyˡx"~(=sƒeFG+];ŀv&{P٢\}T9PcϦW[ty?4Πf4;l_gy/ ;$NjZYA WSNko|λ6_COtbmD;aԳKEd~=:FN0ԉ 5P ]ϑ‹7"8gv͜1v= zHH:*U3n'uviTo-v=~*L"ʅB_(L ?T.◌]2I$n`n[P%_ESsl4Le2m5x'B(VD^>h˧oV]>TwHyͲUX" PNFg>b֘[Oj'nVXݯ*3$-R:\PhA=4xh) V0mr]LkJUyt[c6VB\QVKїYocSӀ KRD~ӣYI~;!k.Pӝc"Ȃ(RWѸE;j0h@ͷ}4nb^EFWwmnU(ǚ'utIM;$kh%N<)$cb:wJX s54+LJ5ny\U7]^)?G&6f!w]1)b g~(JG^x $S ]$gt%8y4i_t/ Pvn^*U'm0;Q^\R_nub0LyĻīꆴ7(E4S.7ck `^WkpOո'Tۚ3+D \<=қCޙlh[v^8a[ϰ1M Z^732ic]˘Ut푸/V7ڲ]-3]m~MeY?68-3;PA~U /m?qTՅicv{p-HLVn:myL1{@i qd)'EnO*|eJ#3!QѸLwnNJ iц qZT-LQ;[px[@W _-}bYU*luzokƗJBubK=ܿNkwn2װ egsLS?}ڀq 5~tVsժOFU紝_VmYx*σ)=e)\7^֎=ȓ-d&JzJWzHYKQ2UJL{~ܣ̍yg|e.ef Ԕꟍ% !Lzp &Q̀ـ ZyRU: ՆEA Vm?1TKPy8 Ƽσk04j(UίR,x%vMakv0뙌`_fXi .A T ju87JoR18 ȶTX(,C ! *ְVa8mNsf(UzsݢMھGݵinׇFQb1Pgt ij:qfPD!@-&GEt/$Lp$;؊t*t!uy^VG:j R]KdK* a:'dl'е*w\2V[a"}[n< TMx~1q۶~m䕱N~8GE.Ks tqjo`v[`h2%vSVXse=4UC7г.ɠ:UUﲿ2VX]ҁ"*&݀CK۩5t,CFfa[V9i3 ,˷O Ց;WMaEP/ߞ$e60&z-ء{9@lbva׽agp!]X>ŏa[ߜ +j7m7CݖeE,e>AehAzXIMwle̐0nwh6ě#v"q4Cl]y!DݢcKZwߦF(upIB-2)F=ᦟⴁfdԶh癰ay[qCAsYy0n(g ¼1+9R I Ж07mr)9vǹ7i}0AI/&?5炛Xf݉bNa[İQB=xfs,(C?n0lɧÿƷkkKMm埗FȒ8_9DUL$*l\Yup68!09Y48] ߴ$D.3OrP)̋ fc|b}PP 6S:?͇Xj.*|NF9ؓo&ivbj^u)s\Bg.~~]'{޸9X}5'bj8柩z~/{.'qB`]94: nkB kQDCآ W5RZ{nYզ]蒀L0 IXe7.HG׸C0.~k* F`.S6FZ1J6AqEc7u8T1R!hy *egPGϋTfc Yzs6u-EUJdSa?V7Bo-p! '0].oLmx=VW] ipo@p烖4#єIIz*[ognn- ڄY3ὐ P*{ip,]hmJ}_Pm7*j0}9kUXm)r7Y#[U[E 8k7o|1:; "fA=˚lX7{`mحf![6ԶyJN:Xt7HGpfFj9ujZ!dì 0FpQjF1J=]\GGѩjIqV6-`=f|_\2"eͬ,i9O zRh730IcSĵK4#5_M`~LpPv^C+3#[("oP:͢H)(S cW6HAa!ڗif.;mteԊ+ޫQɮU%QAGO/twoܙѨBn>Erd}Z, EJ%pBP0 OWZ[!IZl81,\e-&o s[ Ye8)i^T߯R~&::O71waF R瓏v!Uh|o>ۤ _؛g}OtvXSey{6靧`(ku M/738 de;\LPcll~jN@yIҤcoz.JYZ߯1mu괬|ӆܾ^xk*M 1ĝw:tE?nĪ=z^MĎ*d\TYR7I@ ]=dF[%H+4Ԩel; Xy Z$U-C(>,*kQT! +:f^8+Y_MHA* qn\MfŧB嫔1.NrJHXa$S uH/A(cAЭfqUݧ#1偟DqG2Z;YCU` s`U ,0_ j^]fZMɵ& 22^{ NG0]J&p"aYNWɱ6*L7M5oBf a΄NW[zD6E]&8Ae0dlyU-ӍMz8R܇A4D cnĂ5iQjU5Hl!|Zaqdt ds~Y8M#5) -ԀBoPdro^/{3J߁dqMd'+##9p k [$2'r5Ou'l׮wi=z)_ B@ydv:݃KF7L v?m1F"<UA b[5>[(ћ8^^m+T0)ˮq?ͱ*køF8 K?=H e urWI޺ֺJp T\0W/%W.co*8tXg,Dwlnku0Sj s s$!!{dk]MLc<0Mب;[X.WmăC =܌7v WNuZaF2iw. w+5jYAԙtSnfyu*}뤨>aq~1&IM*UpN+{9"̣(5(LvOAu=Ͳ7%Ki:ͥZkOk" g~a'MP0F7$Tpf!5UVY2I8 aw}uiG2l&A稻;a g`^22-VcІ sJtj }4$.Ƶ`Q3< ENr''a+E+6;%SA<5H:"<Zu&53De# PD_| lQ*r `ۢiȪ_h4"Dma^]N.)5o(YPmN>1PfTq]D3Z{l"]U{}Rtf\LYyQDu ߤ]t6Aƺ"1 q'@l 7lؙHe9<)` 2!B*˼ÈęS6ƦhPuv3J3*kaiB\8ۗdtmdUf/Ϭ*-`8z0^1[Hqԩlu#|}o:iEd`+z e'V?R}7TfN!5:ŠgTre2CK!ġ78Nw"I2sS%6.W+:)1tGU2pxWء2W Y^w/CPC G}7XMrma%7YRD`=Рl'xZNHSI"Pv)OJCS&'3 ک*\L]Ȋ{ ߢĝoF9Sqqy̪ѹbfs0Pe:8Yͱj]942m+. OAZaM e6We;ܽ 2Mjwùj*6Ɩ@X.s`yqXGݳ , 8ӎlgq44TAYX+WJ3 }P ~=4sJE.G GqڍChUͪ|펦Z*wUf,-7%Z49¡1 x=Q*J+鍹*κ4Mi}d@wͩ_m7Ŋg"^I (t,TfGGH_7J_w@ ]mS&͙BS8o^5.>E>]UfO $ErØ 2/(lC-T.E^~2 "+[4[톿'cx;KHzg]2UUiYg '&6dqIaFOI0yYOgf8 Q 1*!Y½sx[E|y(FwN9a>hyj+E&j4*R[~yVGE,wroN]Tŵj#ޡW Y47O0YFM~e֍2AOg n9f[eܴi#s1ka>j7뼙5k7pa1WE T݈ȟUX;?q@_Y' s88DuzW=ѽAſ 41\Wr~!XD& X%bZ-*Q7VIMXȴvu !;E+e\f1x!em 1E)Z q?[dg =v dv > |7[tauy{X,re찧+u.|g& Ԏ ,6T֩7*=ߦ<_gy;mưM=XlƪSm)|߃{3-+7Fce 1~trHP]fJpmcB_2#lٹ);mAirjuѫ\"U - F2raޤNs 8u#ROYZV91 Lw\ E'D"3qSbbS4C^>TW`31 Z7M PF׊`Њ&r+㓁_sg5Kcfӝ Gc&kcMSreԬO0UHbae`,n1 % I;1ry,dVh i̙+ě|na^0-ki~gU('зo鏮)87V>vF@[ vGfEg$wz<8,a@nAiN2w߆&x蓸fus5F.Ml᳘\4ȷMaب 4&nDnv2$\GVJSoYػ |) }#0 %8(.^]gFiNk5&S2&\ϑqd }$hbU3emlj3x7Y YF,nN/e\((2MЭ[ 7~ f2f jaJA7,^#i|T$$,-!D*pZzލh3g۔ Zw@|ƯW^S|lf~zpqO&inAl<%̄WhNDA$sBc/r`avZr 2t Q[mYW15ylq~)ok~ OJӅs6բ{7[wOM 4~q&L7Dtnje6Al \]JF&}Ym/_fҗC>+tgDi |dmTf_TYDZj׷_(&诔,ޕzg> ]^P^N8zcx#O3DWς=WuBoG7SSg\5,xusmumzAP qvV5>+x 26 u nY^ SU6ۮP5BB/ϜL [ᣠGe1 V$cȦP%Ac tcS },epX";}'7E*CvB WF2soOo sjK3[{t:|qO8 d6'5 Ak֧ﺴ6_\oک,h!XtsPhF5+7:{6{eϩ)<qЏ GR*`m@@_ قjuiϐZe`d6vU.])S-2 `(Vwc]li+ s[uGV@ bF#OфT(94pK1ӎ T+ <7v0`? !A:?EXʈc5(0Ţç![b*Kuub^4dcew`7V5hylfOv/:  ۱yeN[-˵bgxhfCG#fϤb3sq1Y3XPPՐ3@o65VG>r(Uj Be|/T\FΊ^VxBo; g] 7׽F֚-G[D>xtuԳoB̓䠫B]a/rNb/SgV!10iO*/o0G uz^']YY_65KJdeQ >6PEF!lޢ{R]\1Յ >!̏iz?L|=9SŇk^`]!7192No}[ggE3|=v4<? lat`h+>ZuR4e 8x؛0ܟs/{4q8\ZX If'{B `奨,Q{`(HҐu.䪝Nԉ7ϑp"syJu#ֺ╍tIr<ŗE&pQl*baRuPF&^|\s2S/䩮^! ؜I/Q ^/qm_ibZIz6V?ڐ,U[\]Y!94%WU, q[t1bϢN%i&@==oKRyL~_M2Q0;>LXzOI_>HmJdy,Ѭp1"LOH6PB-RE)#t*}cO>*%Ea }< @{Ow=ט?Bey-z3˰DDLuJmld[M7Q$Y; >-C'lBۛpt=YC]t{}磓yvWn kWf[՗gPlS7agp~_;K"jjphrjauLcGaEU>-6CjP,LVt%*^$:VC LOr+Xh ,IGMS>WQN-E_U6&3{5X@& @AZ)73mgZ9X!5C7Ij>sr'0?/`:ހ,1]2NٍYi|ǵ^mSN/]mq=־57!M *d (DڴQ\Lz(#MO"BA.AM O6X.cs*Z J47x^--˶B#Uu ky|>᠙wuMV(>uD ?l {k[/V հY(~W>l51!|z7Fa pX&ڞ-K_G4,jbr %*t-[>=ϪP渭: ʎD+i^C-_{W*}uS#2 >A~=44ಓ隋Q(yj bPB*-w:  znx; LZ~VgЛ̌v@*)ˇr_(K(\TGg`uVPcÐ҃5F[VqY5DdQ4\DΔ9։wTSѪDgWn\UL5n>sV7 ^$q5Lٯ&*\ZTuTZȾ aBHUꋣ.]]J<0uӺ/]2FUXO"CL{O3PM6E<)qjhiS(uCD=L8H~XjF0` }]'u8F¼5wSW; r%zW=ݛl8jhJ[DV-O5Id(cP5N4M>  ؏띨XD`-+G <  f`35R~N0!2)tԻ%xmpd[`%L2A DϢ',=VL3m6BVm3c} }]RUV kj~)kW)P\|n`PdH1UEX< ŁAĈ3P*% )hVLJ$TNzj|d Zx~m;`-]_n` _a7&4N>22J#>Q8w9,(o+(|@-* giGYtŵF\?TeAfϜRE($ݼks+%R\\&D#8Q{}r%`w„X]M|zpƪ/AUw;Ca?LIpWC <@Pm>t2Xy%d݈ʋuJ=`"V(:y[PanQ^(pځz !0!PU5k4f n3Q0^$!x*zRSfrD@qW ódgĽܠ@dya'мb"g7rIvBkH;69NӢ+̩#IAؙ/Riʔmq=K\*Da;(͂Qyޘ]U_ق-V=<&@~jߟUO.R%&U}-|;OcvUG?.zz aW]X 4Q\3O}H5Cl(݌ {?1K̉'loS犱j×:zr WC결 ?<. q^݄mD]]]D^@3UUTt֏)aGFZum t%לޜŠRz۩o%^ m?Q},~S @oz)B/Q5N(1ÙB]/Y7 9C!A N3 0 srNP$Ȍ=䟇a0Ϛ@tKVHkۇfZBz-#T9Jc׷ALR&l>(*˪^1 :%F/vj A>*_!.Ke2ue]a ‹*|Mcv-0UbL!~U\BׯbZAeQBӁ]C­Yy8(qITiMIb0fB;j;lU՟Ѓku6xcZo}cSl_kU΍c'X$~Q_WgΖ}?Y^8vӗ飌`^$JhKDޑ^l;G'toٶXiE4^s39ll׋WЂ˄ μg>O f= }.=(Mu7v{9O&r|²v5 EtZ0䠏aɿz=4FiXq/Hb5+5-rEr 0}kQ$ĩ| M8dzf& UD)SxLVwUmJ$BTk6zI+LV3<[40Im-ڮAkđ'eneǻ<&,`/,̗@L)ȦPdSuTCEZ+?6k3=PK#:vS>F8La^6 ]i;C/RS8;_{+ \fD 3Xꩨ*#]˶<cr0g ,x+mìE-wa$Ɔз ,¼ۼ80ϸB0>zHL) `[V.yUTŅ&2!t ygrq1^m R?T£ri\&<8]kqԉDe+t JQˉ#=Yg X 8ŏ4DԢcUuP*rC*ku(&۠NTE SPU@]0Y(¿5K|Wl#cta>/'6{L[χ㪓0v0xNitE;ۣ :YHmC:7z4%P< ,-KӺugfy[~0S!3`wƌӉ4za5 "Vw;8@[akIA$If&ʐ08KF^Ռtԥf5%;@*Y:-]bM0Q^|l+Q>xOE51=->9 -D}pQ1>Z;= yeYj?-<->v+IDATԇJϺ}[yvx2q5a vH8f*#}A:u}^qCnʢBGDv;ߠԷehy !Q*?.4J㰉X`C~Eø ЍfH)Tltݏǹae,Sďa'`)eygҧVR」cp]Vg -&i 6i1kz9:\ʼn:sh(txOo'kg6t9ZLy!=TV?z82: "m|&cU>ݜ0g瀑`uBH]y۶܂\-7#^aGr\:1{` 0FZYl| vc8ÜLV@d@!K}-'0%ibS UwS2Zsbtc{Ҧx);o<7u@:7LH3eHRHz~LDR^D&#XW!LsD̾F>>xJU]"]z0m:0$뽳5ֶ=6+V6:AD]{֠Ϡ\ɬh|ZVI,Gn !d+`Sn 90agF[bx}<( 7j$uF';O}fޔ r&\Ww_0qBmQD!&пnX"ގ,l}ҘgM@['ęK@அ@-߿ͽDJLUZaEzU<|_c >[_d0ݥNb=ok9:Բ07:"٘=""H'ao);o=~|L8^(J~Fo7[Z 5Al5Yw݀ ? n+b§0-Q;e0SVoQկ&8UQ0wlTFӥ6d >{4Ev*\Q.,ܳ`_˷r)hu6Nܔ־JQ؛-K3u@kaAZB֎>f&y^e/{;f !uf 5yxe\Sv(p4H̱1p-ЖB9N \V}f#a+u;#Fa׼ξ_:c]8s_ Ӫhe(#_Tk)htQ3c m̀tG jee¥J\~@w_G6s% gE[^ YtfpC 3bvrD5VU]];0w~hyR&ȯ52鬆G݂cӛUxz5ך};ZEoH4[l_WmFҙȸ҂kh`\aldgslM܆>T׎=: JOf_߶g` "bBW/U3*sug:RyX-L;:j$v{a>@̭wxͣr.io憬P{a/3((̇eX*(\^[6 9 !7ް 2! piޚpK4C m{k5o:Lx "IjV]C!uMU֏%W~?xݞzuf}*F_KdQ0U=c83p'21QMtkVMV-k?( V[㺟TWlLP]^u`noodzÞL 7뫶k}6p'!J7Qau:<{5rs;gim:xhKqn4 fH%s Vͦ؃p8XZF[bu=!7V׾RRZ~6g6LɆU1Ѻg|F_sM4YYsR4DE 6D8*~ ߣPPMbkOimxHxh @o@4^A796O`?iL}p861HG{0@Hfޟ>yEnE; D׍Q!Q7JpFygqpM> || Ÿb]?WwE;y7-.1B1CX[;EfuM 17iҟf yXC#>eӝSo+S;d@K0o3Hw o:h@f9s|f}os]Y_nMĄٔ292@PXٔ϶յ\lTѳ:GR™ʼ-Oj.OA׻npnA4t Z#rd#g=! ▻q&8a5I5Jz0vgoMf v'#+Kqרedܭ/0$kMR]YQ+(j|m9/2FˢE@OI? lf׌TkIBBzXf"F%+H&R6lOǻ7/ 8a_c3 QVI5(jC3jSe(qW1"%AKgTt4mt9tlDu9Z2o3 (r=ПawMe_E%l; s5[|eOw(;ƶw쑧)M[8X*?F5i|4xcN]UK&2)h=j?G#\DkWMP9$SZ1pZށvXsg&Ta>s}n9sE"v[,in6scrw1S.)8G /z sزe j`-x-窰HkLh\4)_z|T.K7:k IkdPu;(峪]GTivɃKi:q%]Yyŕo|#lΰA;NG;:4@B6C,z~`TfVv$W!xљj?qn g>r<7ZcU[gіT݃A/O9ԘA)z2]ٵ)΋~cUj I<@i+PE W@sx }LD`@(^5=[j,a_ΈvF7lCkDm Π6 ã(Ёm:,`48cH\5Om;ظA5m7b6P̢8O⢊Uʼn! mwg;/kydI֜H8 57qNP}!> ݈w0}MnyE=̆ ,E Q)Fpod*+uxaZcc[ %úJk֙ /Η{"yBDj&/ j&ɨ?/q5Nj /ZSvCC" ~6jk6~Q^kP8nߊvC~ϯﯯ@$2}gzGYL*az7X0Mn\F 2 OSR{ TI3SBO3@DJa=+7]Yuzh#` /^飾p: 5Nv;]tijſe8܀*mUCUMsPHҕu`LªbkJbN $܄;)*PݔXg!n*wgzDsI>C"o0x\{*V@_! *`|^#&I-hI.0.QҪt&M_Pz46yd0l~^86Em`(W&fidQ˦}ܘʆYO Bz'$x,JvBu?6殐 pU]gqhM1 ti9z\c;})qB#ܨ!g3eBT/uf^dL/uY+M=CՁt,sz2eU=0<߆Lj?h;{feC~/1Jnήg *!Ӻ+O\9Ll ,8U<8PTX6Vł~%8-ban:<Z::yצ $|5GYz"JTZփb_ڏVٺưͳIݻT9ӫ9~׏Pc}ߦ9\5vX̹q1y =9M0RKa66p@8j":V;Qޝ'u@ނ{E[*i\䧎)Ul)U yT4)Tg6^nL㷷j>JqG+q/\FLRxJȹt uE}zG1c9,e;oA9L|썄pKP u3-+ԷHY$аmX _7_8me fHqOOz $y\p0?mg HD] %} W S^ôh̺ξJ Sk_aSgǢ̌ˠQ@ A D@\7_![M >(=(3pv;a!kW. w$Lcm~~E±1Q[cB) ct+}Mr5ְW*睊#i&<6ZW/?fS%lWeV-rAE)ȂEbC; ~t ഼g.ayMI[QV0>|:s:#Ҿ r;uۻ1ok2 Lpp},iӞ)~,ȯ-aͰ0/3l!ozgO?0<_wʷsp xY:o Ey /\`e2g6 z:}b֎f80Y ZI胹 .rLsWbcLc7ViaAA2+cpP]O|[d4E< XusnUL\͢$؀9U?XkV]z)F~pKoLFUEd(MI WwFtO&'_lgi:SϨ5}|LM4*uQF8Ruud<,{sPX ZeE^'D85FsɊ?ʒ-[_uoZAl ٶM-J$ }t߻](M(Udlp~Y5;VI$لmuKPj~%2(,ǵJWz^9lC#2[1_c'}%J6#dz@B pX@U?}eoO;]G=jDpKow: "Mg킾j+bb.;a sdMML m12j3arJo#ֳx#d0Vm'l{[zR Pɪ/q=a쪦p)kA2H.O]SÃ䎱9$d8҅G&QWKذti jL6-3L5X홧%W\1D QXulc8[ >`Άiky?INj9L]j] tAoW;ml+3x^V&f@ͮ[\Sҧ ("L<5(!,h_7GOп2iAdlLoi>z]xxvA+e |΀@Z=y/QK_ubY5c*]e=f4NPfO(/kQV,v9qĹU 5Gƒw3QQx|֥KDZ'Nw7a:}NRՔ{f{+DıHẍa0Un\vʑۉxgcߦ"K%hmI<-anLrՕga҄`k;CĀU.4a;7}ɼ 0 C}Vˮcĥ2]qO/OsVV}i1ަ>-ɻk 6À>E{QWXe+1MȺx:]Ѯki/J9))Cڂkz 8QkG.AT mAMz4A`p2Y[t$yt*ÁZ(FiU-t^Z:s1=\MWVBBKFs|N͍~k߼۶U+n+=%jdj$lukQOE S)7NH[**$0a\ 9zf\H]JR,ܘُ ][dEE;[q ӝyѰ3XW~8~ wD>_4=[q^6MXfK-XT[OrE]I %]bn+u J]Md-.79.'D ^j08<Ӵ~5tmI  UAKc0KjH]Ib*ګéDt=Lг(2}X~Gx+˙S`Ku=,kan[dx`esܗ¤Rj@L,v-Ͼ>o}c (pkɏϛ@ua!mQf_'woI64N@~D)E@jQ9{.;a,'vm0w;7i=ٽ"3( ;ͱ 86.Dy*-~! ?"4ISS'4N /'<_SuI"&&kr]Y7mFVw;UcbQ}#K$RZ:@euan;oYl#8ujJ)+ ߫IE5 ?1N]]CLY gi1uZF{`ۯIuM;DbywVX^b0e+ e8&|v'S׭0 5.5_+o[m x(|[RZۥ7Ei0uq>vGx1wpTc71"\҃$+fix}:x뜧Jxu{`ZT|B(a3~?OB6Y)FEp~ϼsAEw_hS0e:?'.(e@>w۹+.4/eV6VZ[ZctܴrVn$I( u*]L+o?:ʊe"[xvSz-&ݛ ;TlB}koE߅b\PxnJ;a2F=j2hkD`/>0\Qn;xW(qzG{ݢx$ol$kao9e]ooxG5ЩP)n>Cv|l/ݢ1~{nOA`rsbȧahѱ٨!60 YbO̯}YܭM9.R1jX5h=EzY!VGy kk4WJt)MS7TWҚ> 7iyE0Ǐ.1l&4-eXa58ر:jy$íDHmvUNqK[ 3+cl j8stgۍF~֎uUbbU7A͉%,j.!'|hPL*#w>/c?lg =KV^kgqc.UbqBgch-BmA G0.g;4b̩e!ƳYWD|~qxiqt0IRv*:bt2o7z4Og-51<۟ˮzWT~^o~w4ᙿMS$Z."*ȱa> F}B1ʃǗٖnPj\,5zc#ցxۀio3;Aw[߮E\.f,&.eum+u%yͮ9qH(ofmw]uc0GGM:zU$\wQMi_/p#X9տЌp<_*P_vw Nڛ\ '`oOHLhko}oSMױWJG5BVwsvz*'2LSA_g3!حRdZ`T&e^kkC-&Yڜݵ#&_igrmb7v:<uSqޞ(_}7MoE87r L3+}V[$ ⭫ض~'vJf?rpXD+pcxq/7ͷ n^3sL2F46B,+N1X\F?"uڈD YᫀC$-N`Fng{v#umX{*rsoDwo\{g1Tc)/RF^n%By-_G+s@4mSq\'`-2K}ukھO~ˏ.-*'R]"ʭ ΆUi_A;<T+vN\h;8EOS"vHf͟ zeoWE;>3X| E0[SFRrt"@i,DYpO'>x۱ d/7Y3[Ҩqfzy,ε1b݆$Uf [vXt^,D(:W_ʳNg? Iŗ kb?uf%N?qHnla!OLyq=M%C0/ǷYtȱ`TV Jj]nbvE0A=a^’o,?MCW:Oҷsi`;|Gj{£nKy+S4Xn5ʸn%Y 4"QΒ9E8rֹIq}摵i9KQaCw+/ugm|1V?. NdǞ Uo9ujhC[?w"zayy,SQܪLYu^OsUz SѭMüp[Ek9/( x/EG(NkFDdZ߁t|@#;zFŢ3&KmXbe<̥<`dxN r-)$RvnQz`{ }g`.۵}7m<ԦѬX-+ćn${UYpˊA\#s h]D5BPP-\^Ǻ=C2u P)w67XΥ*گ:R_c?|Di}9ڡV8}z0c0uwHey{Y4]nl9KM: 2k?=n Y &՟wZwgIHmBS 3AXGtWmWfcma tf,$!Q0ImQn?%fݟo=[%u*O (z )wv݁+OӶg/jȍ:-R6,մzEHU`+_uWAȨͯ۲c nǑ#U֜ll EEuB# J@' n9NvxʊpW;s xy0Oi!%Ƿ<5 ч|CG=?`^l[ElV iB3M~3Y'b +`gail5.nl0h&IzS_l ְL,ni%ZXê8Gpm.? Zm{]Dߜ|<΅S -6T:{,\쨵$+Ovoo3 Tbv㽸-Kv1vΜkJ7~MsfH|zL g0)zRJ51ПX ?c] #9b[_'%26vvٓo. h\LĤ+˃8O[2 ȩT|L?Z&dLieX7QY7TS|*Tc~.H9x}}~maBrYc|i'x` Nvj.xySs~c/CvQSJ;壚Jo7JaVc6h&QM5kҞMx4=2״8Z~8 v 2SZ&:A~KX^3?M@ie VH噬K(~gMpuάg]9B0ĝ 5LjHYEfPxB_ E%k=UȋX &B-b0 2˙N 7#V^p\`G* (?cϮU&.iAg?G&bZ _ZW.3 u|#C]hyA2k j˽TLǃ7gUsKw֛q uC0 _%Gߪ:+E Uіg89 y﫛sC>jI "K)풂x3N䃝pV%mV zEa&fq|Bq7iO|z.~AΜXf-0Jy-ʹLPCM(TVNAu\nN\&N  & P3F#1K>{~.߄Ya硓u6#I PQo9!;Lgjx7A^$ eNhV ʞ&JiETId,-Drv*~EȎwr?ƚ|ӎ\3y)xRqD[I{32 k PN~U|X6oyu=i hR S>4}a^h_4Rh-ܓX]̖xlOҰXɊ ps8VR#FHȮ/;h=ee}VWRP 1,]_O1EҼYhb>b<*_cZAR35`BÎ?^T\ ϒAV) }h%]DB֋oOᥙ'fXszByfsVUs~R s#\*>ʪp|nI=?~?:&ȹ#<Ɋ*Gvaå:v;kPi>d\?^?jnaJZ|[mKROy{E+ܼ ev[RysL C{/7\⛩H{bP9ݿRK"Uǚ(JJGA13pOM3-oe \vBqҵ}5?帢j>hi-IJIK֫ir$ZL[#t!{)ip9>Hr'6EFTc[;ӂkɤvG3oqbnQ%T+ҽ-M~l19:ݚ¼)8C8".IіL.RlOmXx`MG#NyR GβC56O8:mJlڶ}}WD~KEv[ػJFP 1fJ~H,9`M joj0C9JBZ,՝5SvBju1s5rʺE􆐴[j2'xD z\ߩoV-\*@WC?a8rȬ/զug CH4s=~F׬/* !f.捵KQ t^)t }b>Υ:ǁEj KhۭV$'RiG1;gX?APJaӻ9O`@hH瀀IQr]3G[KIqG>:>׽$,ld68Y,{R ϮvM>{#"Z+c^* V$hr|EGlGjvY@`b!b5Z!ڳ1*Oٳ&B e𬵿!l(g+ G@2;mP/oq?cs@  ls# k̭iKƶr'2vq?dQs'dϟwa2:]d͜J"ٕ IpG!37Z_Tv\X%ʆrRyns˛UX;) ;q*[g[=]ugǓ}wCvXJ yTe|Q\^=Qa`lFGKR_}XB8Da~6a$Nٴ!7@%n]˸9N/.Gt]^ iGnxݧ;6o`عPBR `( a6iK1ӈ7m~j26 Yj W8эxVgέˋ0n-6;'IՅ]ώSع~YH9svWˍnB+",K_j/{6%<ka92Q+r\-b*@@[2qRB`eӾ>|<~} @ƾЗߝw+ر/|?<7.a?amjc=zHMߴ {Y<<cݥJ MqepB^]›n,Βn+ޣY*? nA /ז)Ui)[FޗCяk6lݟYh?%7/2FqQ[:*p%$z\R͒$Xc;%Kaq0?uOqwO#39tvJ\Ew.~:*շb qMX^+\X~1ml^"6<˛6Hg1#,򦪲ƹTJq#{FsbS#EuPeY]ݧ.Q[Q0].~aaD6>:j ` aZe 7 ˭FcGQQMjM!eŻ="%z˲M/aR_?~N[m]ZY{>e8,k= ޟ'da ͥ q9[]`߫o;+_ ]g.޿(2F 2T |* [&~5p2=!\庲̌ UZΗodEf ǻM޴Ŵ?pzb\&Ys%&9rʺs4Ш~HotM lz78^&Vb 'C~BdPN1KV!ă9jNoX,eJp-4Jy?jqoF)",6:oBI6DŇOIE .n9>ݞ<|zԆIZpURH A7}Znm,x j_Qk尵il飱CS]8\ΨMQ 0ei5l@q6`Js(wC НbL~4]ĨǢ+`/o<>^BOסG=IHiE}}Ľ6muvKs4rh|qbYF>d?,zj>>njEϛFq%kLY^hGryykEq / рXȉtwkwV&y_0q5kv=)*=cס0pWTᕢ1m v\knV\~[_A@F:dƨq`=|%ACK$D{@u>f gwHoFGOHq&WIo}05-;#c?Jz삷}K{m}.\ ؓV h27=N2[ remL\۝ A˸K78] 7{zo}5o@<_+8i{TdA5{ۉK|8,[ƗJa#iB×8kcTu 6 ZBz\Q0׼גAbv#}45R`>l}74ع-EQf7#[@Gj'[#qZkxw]i 1 3*6fq5ۍVBޛM0v@縷Kajlwtq8@҉xeB a^Hɾ沟jo-}?0wW_OA[yi|=]s Hh1%!(n0WӊJ[TD}B W[5Ktyag-W{+碗ӸR'߫4i 匑_ sQ@d]b vy[q9R͟Ag;a͔glYt|P"NO݄'smɧ [{ Gih9YRNqRpeea(oQ|\+#RMs:˫ ٥o3(_`4q)F~j/NO]"7ja^Xw!ZŮxfvn]h*F Ȓn R#5_mzB;B{TC&}D쮶KI_K7L(7UܢʒZATF7QZjc닌sU@b=b ='/d#^O-$~g^Vu`Ŭe;eV%i~;Jrx[=DVH3h@.QꭔNC2utQ@)RXK~\zi+:k2g#_X6-sG$ Srzb CӐa>{,E[%$iM,aaEKb 2.rrm(1O*0vYjkĊRPEtųr,Z-jjp9Mw"`=픂ЂTb?tcW2{Y7|!t6.vuFE)6.KIh'ɪ -&{52/REDM!Mq Ca6c7L7~]Ƴцo, ݙRs@u'Q y\@r w֒22otR˱BNP3H ȢAF~vk˾p܁lN^•4\B = EkOPˏK.WVܷt`oStpH05p؎ V3@7ɥ+tn+Fxƍ %4.~9)6bc>x9ዩx+3ޚ*.J ɮy)ɍ**aV rծ>EqBf-rBμSXb#- x`XiɺM,֎ZTFu=!ݙU >zp̓ET]P݊i;OP-Aph`0b].N6Ʃh*Ktv$+`I$8t]Qw"aب\jmc;T؃)kPc(aE(&v+%W5!!q!_y؅+\V}}R˙E9^p8%Hެ)q̾$!Q˅ȫK)ӗ'|ZcƮc{qca(,I~sh !`ř;{!CnO5 8"koyw+c#v2/XdL@)bʪz({JBYZq866jjsUE&Lm#a'iç5K)P^7/ߦ"`<2ghZ}`i(- 7"Ś4}>{ۂ;*y__w߯qȓAZn,+.!#G--OFl2K8f55&5q俿|2%=0,ŁyO  ܥ_K% 1(Y)%|<-{ gcu:izFpcUz[sQ.z}a#QDZ`(œUg-/.[x[75ze٦UPQX, mcy_Zn#*jo5ؕ5U H`,q=8-+DG|E"39 ;$W̜Q- nXhG C!!gиIԍ9:t(u 8AMvє)Vŷ]~[6Z^w)-N tಶ/sr9hV mp|z0!o- c xFHsz5zv'lxnjʱO=24 1;QYGa(svl={<\%Wqf`=FDʹnNeDo\!@1Y s7е(@-.:j m%=%q0\:^qZ_߬6}opXNSw9I%)}يݥIcϸ͢tdHB*% )f& g\%~OE߿`8alw3w,KOƢ`w~uyoD9aD5$Z5%<CBnu8yu4< ˩- / 2FeXd'%ݤ|V놼{-TEz5oDYKrjBLN/y%}.&tQbf1]X#ڷ]*ic=Vu^D5>|l!]~gkfO`H{+Ê|'2 @=4IGC q-11!ڇy>M#݇M'V%a\h߅n1E> *DV!};/h ¸= xE4uJ#\/p;%ei\iG&! ݅n8$m7vP[c~+[8Ӷ=g-V's>ߜ0ͭH 1%6C|OcFˋaha[ ev 6n~]gK▜+.3 a\.57M>܏y`VRcn+R?#) ,JYJ+maWN)?%˪eN֜WEF-4,uسPP(v3]UVJ~#1be}%մk7L(gu2Ɍ]^n">F$^tL:oY3Q{ oJtժhNk[hsc]^!sƸI}XvZ&W q9{Q][ `&|b)ͭ(Ղdmqw_Oz}r:vXJc| L#ƮFpF-#'?>ʞ}fY^7Ґ$ vhYs%>$MkXi"17R M|y 'FQw|gQxA|<9c12+4u>f7{3mfG%ώg<1-v8#p](&}œtnB 4 "=V( jQCs`d:$~UJig{b 1r2e)-:75Nn>.Yb{sU3}#2¼>?0t@|2w$0g`7Jqr#ۅt,vUXBk+VoD)/QI6/+gq{H1e]G(Xxln2H N<;'o]s]0dׄlYTcf9,>~hn#['Gpz2vK<@sQ >;E {Y&X KZ/sY}a*g)K>.(E ) !qvJ-WZ^25mump)᷆ejN%IfrD^>h'-2\Moպ䤮5ۜEI=̍բ'&[\WĩqׇJl® e"Qﺳht5buμ}Η<ˣeXGX1j5V@,&:M_,u#B&;<,h8.CEklܖwr.fU< ꣼02+hһͼPlZuU jy'%R,#uN +꺾@ae`)|DhaYzO2d so}wkb{2U-6챃>XNӱ7. kV[U!c)h90;eX^v=}@݅Z6:ü"ӌ|s#o6"7wN+ZžEN.j%F~bMV4svˠLA뫛0>#q@g0v;-yY4Ndc{+cb:mv:m"ezv7عP_+_]j},86VxVqr,UZE\u!;}EfD+30MI]&uZ-Vԁ>č׾=g ̮Gե7Z+2˛*șJtg;{siq뒯$ n?([69y1#@L֥fn:" _ZYSW^!EBH0v lB*Yxy8v7pӭu}%?L4<7z~ uv-!rجF獀j9L3ߊd<IoB*.rRޖc>>W˹`<ٕB=&crWḢ14~hovzUDY;L# JYY9 C{WYnߺ$KB.r 4W׍e8dakV], !m.&<(0ÿ\^pR*BfHx):qM^]id¼LMgd 9Gpd{´z{IvEk/ǡewݭ {?f #/Wm<}3̠Z&ʮ%mְGSyM@} ӌWG2M=`9M= ZmeB{X >ZԤ5M!)#`.[_ "YE›Ū5[v*2;bـcMm}WNo&O[cuU:y#8{ʀ6.Qʁ8ÜkiV:4XclQY+<~$OX6Y兌J.P||TC)+4iG`⎻sf3 'kubSGA/WTl%E68t{K+ez! (J[+6]`iHMFyj x+T J`@Y ̏ºg8dxR!r53@:6I0_{ BԫZlU#~''>a S+s z 󬒤GtA.ۿ0|ۋ)H<(?oBق&l+.xYE>JԴ,d4֮ySɡJIz0#Ră;HJsczdNӥ" ۡi⩩y22:])ay@营'HcrůY\fҫZƼ qdCF2{[˔;>Q^4{׎J.4"^]A\\s.$v8ĭ۠8'ؠH(֌G:0CςyC6ZYV]x#,O뷁F|B0!hy8b:?%1F9u۳`M2/M `Љ2-lЎ+ #KUҜ1YV sXONb 5ֵ&儫0?]K&N0N9z6 ggݞ[FH{_9NVWyXl7'o: b :Ӳ)”DE=4+ם kŸ5Ơ3q c};&ڷ*':u|Ϲve2/j;$q W4RgXM<+G|ۇ%wrTRs:v2ƙC;3,-T] *˄Xo}+bc1v@N2 u=Y[^0] e8+wU< =Ff\vqSRrem];o5 W8"{ ל/@ɥeK_aj!Rx RiD?ǷVg (ۮ+M:~3L?~=V5HM'{ZUsgͬc])w?NÅ,$Jf<@Y@,,S6Ke6{Vra'a8aP[ZK cWzEɸ161VS\L ٵ b㨈3:UզP(b fW KF`fH b/)i˿H_$8dLd$BEGLu"g lo:tL"<^[y:2 ~I/ 1[`n{SKp=8&I&0a>,V\ᅩ}?k$|sitNOXyұĨ~(a^H͊:v88}0jkܧi<&L<蚎j{jd5n?~V+O쮤x6b>oLQf9i0?NC"],(J%4B9ɼ?>O1<=9 ټejk/Ugwԉ\[H9J2}uV>k,ۆ^薳/i`&ؙRĚgkQH8yK {8IZE;=$ܓ`hzwA ։œ2 мځ[|lnF3=)Zxjjr^z!O2ZrE+3 s՝X֩{{멀 y<3,,iABҭC3w'~l:Ky}X]e:oM`j̭Z~='7ozh=gx,jVdX+ ڗ}EW,kl04muY\jUC0W8dM M0B̚#wn._~Ͽ! Si:.> /dM.yRUMW^?\4{(3fOuQ 06bƼvBYՄ+qȮ1A{#Co0n?.X!y8 }9ᱻ@U V,i} V"KK.{VXw//e_۽r+9 |H NBm-ؿ̋5vY4 Ӯr-@Cx}{|N,ۅ]qsaj"ez!ʧMY~;5V䥯Jꑦlr!tzB(#m)}*$RɯSs PDҚ27HUmE2wfM`~-JwBIDATǩ0r5QĒ\n/Onކl _;<8>i+?R{L\^x|WJa"ZGҧѭ&Rn3XWl;0Tdh+Ⱥ&w> p e*8/)7SG5X4ZHw X4fұ(%X iZ ZG= 5@:{-?9q[,2y]Ya0B+ֲٙv|&Es(;h;, Z^q9J1SRdN" [s tg̬Qok_o&#>F[յ㲼_߭찁h:ٮkN*y?wxn֖v0 r#i_9JU夀|- {rWKxfS:IK󜔔OdpR>mz秺!!="PԣW]>uOV,َ ~UKl*RaDyF:l7Jy+6$@PУZgboX|QR0_`d|1OX8\Te˥ݸ0\]zc6\Cy-;W;"Yk6R,u)K^g]NAa$0l!k[xbķS:wz1$~3PIJy"{+f~oԌnYnjGtt .jK}LsMq2}[aum>X+]yRcuEaO AOئ~oPlψXA?Y)o-QqEЭ23Ν ]Ҏ$hӬ?]Ҧ /AŪ.Jc.Rte dթy/ى 9FGxKRҷt)dCb/J)%M (avQ[ݣpޔ(ٴ"[Xq'E>J,TR殌K\8SP RA.FYAc&eկ.*֑l;ދA!.<{V7XG> B-ڬ}YO\[ 7Cz-Wm;l4q7Fe[jxD7Ϝen"ξyP ;[>.4Q\!x%MG&uq.Rרs;]Cy\e){!{X|G!uhڥ[!\s! ,:sC-Ḑk7}=TշTGPSS< TpEjn8fc'ʫlyI(-NU-k4jaB-Q*n9.kEĕYKM¼CsKҤ5 f%m ǾSaj.8 ]v/o7@IA.˰9RBRbGU|a,YeI*Ia-{^&yZE>k%y=swkk\ũꪼʜiz:u"\6Y6Qa6 +|,sk:@?kϨk9oMyu@ɽ@ӌdR\l C⌳YY{R E2kb멀 NRRPm9iw ~1a:E*>VS;HӇ 1.4)im~K[%d B]+E!q=GWDP;IZˏ]c?>ra!nO??*(zjg{@Qom\(. Q>ࡨMVFbkuͦGzd2es0sTI-z{20[*qk4 K,]ъ漳,Θ M?; > luE3H:4E ~©>됤+G!e ܪ:'VMN+e}h]p2=DgK< KkW+sά=2bbu.,&󜰫UGLY5t*s{sg1B>k;L_ Iz2RG bC B J#:`u%ye";]6ۇ 'T{0ʁbH^r\"ܠg].;uQ K~eR!g ioSOfRIklN'ue;__O;qϛJkO 6V{Iżp4~jh2Cᦡ;| >>a5`9楚 M!rmakm9|p}* Dr]U-l6380)y)JWfoykJuXMR6j3u!7$ vX!5 IfB`'j-fǕFDo 2;®. :5(:X2gjKak"Vu&PfߑnTϯsMe ްC}|MLT q=-f#e+;:ac̮cVɹ^#Gl9ΥLlbB#;K~nu>9l4/Yą@՚xХmcON 1] r78j|헆zX8~Uai@.@0|l$y4\`2=v+LbA?{>}חI6HKsjζIH!Vm[FdJޱVRьok[{2ZNʧ)YhNFA _ S[7(XDJa(~yPa'qarnIW$at'(|v@MbgD4BYӸOzK_o'dg9fO*hy)$ىbqòaF!f}EW  ]R:zo~ʅEYlhׯ=(DaZ;ۆ0%"`af2Cb!eh(MIZFr2Ki?ԛ_rN"4-xhASh*K3X DnB /RJ?SrA ZAղivKڷ̉#=x|w\le O> MEӗIźӚ1UJKզ̯Rx-ixo3y#Uw릏 " :uvɂ,*RM= `27fd`1o e["71H~~ONc& VU%̱R[KUMmѢC (NZT{>^lŎ tZ_P7[} )͕!ѴJXBZyN2ql(r%[ȉB# ͋3|Qsĺt'D\i;pٍnK5Γ>n =#Xoew+C~„:&XL:89SHK|œrbJ>撟G\lڦ֬ aN# /(7#ĜqZYl{r#Ņz+Xk2I:N_'Åq;T++0pa~RZXiRRZpLs;Wq7)8Ƥ C[?)iz֩"׃aiΛ8մT:O+_ܙK#?wľV VGt/xF_)# x2hGhl#e28ühq`VΧ5&҆"DV|N e;\i\>%snxALW^' {qZ4+M#5{nۣ7fli`i<?1,$ !H~CR&UWa*YOpIѼNG2{ A1p!,]gYnuc }[+# :W')`3Nօν>)1]`96ޓE7oSZf8Ζ 2{>~}= {q/aOdu&cm9E1QK02.gws+x[jqu-;1UuVu1pDmtIz jCX]5XƬ>y%5p Gʀ/@״sFzPgCt{gs-G8{)iY8e }МҭB0g?ƺ;IlڭXT<)zj"KwJBa_X:Ӝ s}qT6亂-<"̲tnLx*K0eY+Hn(c.SfF2v}ת]{;RS.w~X2!e ='u,L|pxK{69 I@Ac?(l" r$7o<-q*I@PW:wv¼,.R>>,f_qbH+Vh"``kE~5k_NbAY|ӣZa:ר12I$u`u]mVӏ^wN)>EմgVGlFq:N[/E{Fۧ<7]0=Ld$}CۧMhF{N3S,Qxc:[uюTRwS)bˌ2E8o@szǟ\-w91ia]$ʯ4lYOL0rP@1(bXO`ce im0ı]x0s+˪[EňZ#.om0=?i Xa'Э/VD&hsU8 (a|.@3o'M̧̟,&5I~ kKG,BF-yUbC.2vtF+27g6VWk':r^( eNkMqf1yV]i95e^p|hm%b ,8\hmÐA7؎AY&f^%G;~i8s$NܖZ@罼r?&s)Jj: >M""Ї"h0ow5X#.'+j?%&c x+k.[*ao+Vneꖹ^ZfZ7L]J|nލsc rRӭ*:qsq ֽ]vET[SeSpޠա[)Ѽ?gKRCboJ'=^XUm lִ_Xiֶ]̍`Bm =NʯugI4Y<<[_|?:%G8^19z6CؑI#`$΅ ҫ4|;~67fW백?s8pz2Ymh-}vĿYy $}߹Yu,t^҇ԯCs b.vڳ+5U\4R8,؂XuvDйǘ,?^ z=0*5KȬG:ږiv[ 콵4`2`jdOO"?wۙӲh}qBBN#9;z\Frv⒲q:J̾.Z0tIvL{URf3~Ů`W8-BB{fn֎8A`&|%GTcG*chj62dHGԨQB=}v]V>,ϯ_?B@5Jӡ;V]mҸ=}޵r{\σ\6ya58kZQhw;{bv_Va5YJNKqۖ7{Y:iJj9$ʻ$#*Y=rU x#UO&N0kF}%z(X3X ±[+JE3Kl{{WYzSڷ=fzfTDQheZFGlֱ*V[[L{Uk{;i ;G90Q4tJ1ju-^+͐0nu?'K Ii֌Z24i =^yk &Ov+iySMsy#'HN)߇hD{jgcpW%&`$?-]/+ipd pB I;YvvA=V!dmDl(9rQ=/w)0U >N5銏~-b0hy831 L8j #8s6^-vtb\aDU1\q)#ުZ;JָEM=_;D<61{)o[֚8 3`l˵:rǿXy[EL4sS DP+fbU^]~@+]G@ami0#i5KX审U[%cwHS%V |}+L'Y`w-ϼ?ۤU}~^+r"0n;ܔY#iw"`%sYU7 / 7`F*M ,€Z\4Xj=Gyq,vs]Ui} knr&MUHQkaOY^޴W.mǯ*,X޸þf {E2Ϯ*y| 'm?Y ҙ`vz~j]ϟci$UÔ&;Ym= j]uu()XufeUО׽>Kݢ/:|GEZaCy_߇f/r%cǑr߿~J'Xv,>\u?jcCIuBL1T>sof}zPZkQ mc1|$ yFUMþ9O.xUMf]:WSt8xUh2Zxpy:pHN0+$sWVbul4F-FYKyvI 'q@)-Y B(vOr3R(o(Hax,ٺٜ t<ث%o/*s0%F8p0_e$\*H v6Ff c=ݺ2jFk~Nj,?SԹEh:S:$E>ީ:ML0=uZ7E@ g#Kv7t>Ejw,I:;bf㋚a5y nM:KSl:9 K u|ud{V!8''On3Y C>)`2Q箮yzC =@;1ra Paº~&ֹ4s[{DGu+['>{Q4VVnGa/ާJAi)cZ cL/AfAGTʥ=zo?j{lQSEY5 >i'%+ⴭk0@NbVpR'V,4@~|9(U2gXoC:g@YhY CZs< e&~8\Ji=H9Uó;&c[ VWXig MJqr.G p,0̈́|da΢]VH/@O^&,R2(> :Q,X#m8hW'i14f ˱uI_] *xoEO7 XZoۓQen/GqW+bFgeyߠNP,3I\ãȈe >dӯDwǵ 4!qZ[v?C11o7 SMAo'Jbvd؁<[7^GǓjݎ&5 k&*2ټJcvӫ3͗a@2k _VXMoIao`tCV.`y|{o6Dh+9Bw=  JĘUD ͍t|"Ԯ <#.zv/;%f? cq?LYP (8lu|슬X0~O1;uϊ7 $paS @t;sܥ8]C'M $W"RZ?NL{ϯ/ vALE'{Rk_N]n#[=;;b,#f<`/BvyW nET 404x*ɻcC:؜#Ng `„Hh({YuVw7`(r.O{,tif1e=KEYMߎV_ 7Ti̷,&gv!uY<=˩3aF?nvݗ7SKƪWb;M+{ױ]QdoIaޓPC)HJ\WL `el 6p-Ќu53m=;^N` Dc(:OF?ksWWCS<,]5HB܊ޱqUm}.N{Nj-(7?g'etJweu5̞b YK,Rkz ba ,9Hj- `d#Jv9hXuw۴zW:+58MnӬ̱QX})¡3](Ad Fۧ(Y)tuhv7FCuANjj_ʊmSOcqF-UOUtuc,kmV=͸u$GY݂mו~dugN߲?$xzÆj%2**%/QV(L'Yaj$\bڕɂEVñĦV`dw&nUyZ<$q.y}DyH5>H :W(oY͝yZ9 ZQ;څYVzjY.Н-& )VH0T9%W eE$1AIkV5=qk,tfEMfѶcRRYW6z cgtua-&~ROvm}SpcNqD0LM ԇiPIajjҸ)6*OK uhĂVcUx$èd+ b8X= z vϭTU쁵n*W~OIR ?޶LhMS2奏&||LfE֐m'c ?NŶOs6C7?_wg,%%XU /7.e8tEn a\`żv_ >KÐCg7CPv>Ar*d!O&}3 ZnY9@[. ތ"o C)IpOOвUYYXt06y"Ub}.2ĹTz.#``"G%ExNi0.hI\EV3co(N =%Qh;̽ 08[KIJ8J ͧG`L1[5V*)kZzYOZb8[QVxM y*Y-Qu~s"g'iVq^H]' 򐿶ždq ,̳RaIρb3 Y[vc#Mn#QUiEٯ7z|6q'w'oqY`>[ Ogioa.Q_ȈqK(N]2~8jD @7MUybӗvRrjTT㋚sh>naE 6ָ}@ BK`khQa%-{ <9n]3dȣpygUX/K]t60z_x0x(Ҕ*I"5Tl&iIۋу5Um 6b0Tmp [Va28!)g5ڎNRPoݵr^b5{Fv h0d/[I b7uQ>vo;bL x'g+l4v3 73UمGkM 2&Kt]5RT*9 6VYbRR2a.TQ𛓸r}a~"33]pg˄¯*\d8nu?_J7/7 .AUGz/fB[A oIO(Z܏zVH|}Q˿`l3Vl'lX I<بr{Qk(Yn ݉Lr2OlaFv'}gY=j_&{qC&Yjhp<(T`{YC3@yT2ͺ)]Rُbj@ @Rn9󩟺8ұvNN (v\s<E)NZe0NҜJwfKwǖ1tۣ"wihd[Kӊ=D?+f-_Hy\Ni[H"EvUq.tfil-ϥ0Z+K̶Jv{ՈNd8B.CwmlaBf:o8ܲx!Ī>@ڏk Nn4oz뾜to0<Ҡ!2NSZ0:=q/]Ǭe`3%?|!w<\$-hQJo=\x7ryQV'g Hkeq,,.J+}52ߗU4ҡ/Rk'ul9<@$AB#)똊OTT[y"1KNϩG2$nR-rSZjoVI¼̲s_N]EEhuc{'76oZEص vkzFEW){1}b-uKjWH kj!׋^`Ak?g.jurU\y}\v+Vk0EPH鸿>cnubS6s~pC7OTMʪ,gpz떱\Rk9tejcNϹSKQTkB!. }V%]'A:H؎-QF5 BBR[GYfK^;:ZZ%D$uveOgU h]*H%#KO-[3ɗ0Hx4; κ񞋛gkp}Ui3+ dt=,uÌ3!.vˮs}Q 0^1Qo_l D]d\M6誢.80fQř}+]=/#=],s^I,K[-\}{X*zЭ5QJ l_𬾺|* pז|^%bsV |<|GsFu$szdC@-7W?9C{:=VL JN2d-,ʲGp> (!uZQY2hHx'neRXމ 2vҴ?[Zn8 5N}f+8,n2),&VzBߟ/ϵ+R\v$I{<ʢ$`Ŭ*k>z{V<~鯋͔Ǭlm}fG`yGbf\wG ̇\ȾhW [waVanLi\$zDZ& nNstŭCg-]Tk ntȖ}UVLb2$Kݬ3_ڽkCƢ14Vau ΩESLClvuL[]籴mc:㪼b$+YR<@dd`l[n yg:q+$,n/AUMPW`xUPtLc\9=lW<%ЈVtDi}|~=/ uHBPh5R;IB;*l`dٸ6F2w{OoV6ES=AW$7f\삞6wP`huy3YV8qOEW' K+f6L)KdEX2z%R< Iu_X-FG݅`N{{=]jϯ}^_vJ_!ؗ"tMe)H`if/`lnUaAW9vcRՖivɝ,G[k:1]5? %7KBY=^/0|cG-)[@;LݪHMkJUS5eU"a%]\U+/OFf%|Š";[Y_Eu<ӵ?Db.$rIf [b,Z w"¤l޻T |]z!FĹ[6ҒCZY'~kh7NbYjjbe)p ܽ"鱭ix.F-}_'VϞ. o+;y .279o.*`K[<3< cNxgmGVBl/{m-sĈ< U[FA}{\_ca5$W#2Nݬ,Vܓb5w}"Iצ+[[!eCOI 0bF8ĭ/k\sOx|~VghjQ_o:rsRs^pMUՙuFȖ>S;kSxK 0W;ݕbdWJRX>vP;UBac%.BsD\\ެEM턲+!>?e ƙT܂Z3gv4#noÛ~32pA>UnQ1Aq#kNEݦx{דUۛip/5MT4)YrНFav =P,,&v`9NL&S 4PT9qhTF2޶oߞ.hq|p1EW>u}ՐOiib Y -e^u¾ *מC{ qJ&YSdvSj^]a6EVq=V׬"jBb~j 4Ff "hʕ aw}>E_es uu{- AS]E^<n!Z\"rmS%eZ̡:_*"^o7{xD/ d_)m$J14,ꚼ5)rnQXC!m1 ϚpRʄlPa*^xi MvJOps $#pC`X\\y+oV\Ľ=>s4,_G~eB[|,kdIՕ7,AN*wPAq["GEi*@|Jsv;)YOZo]vJ,Au AvYy'c&ȠbP/ s5UCupkk&ˤ秚)K|Gob_+ʗןR1e$Q~uB:- WWC#09ެTz МBι@ Hw*~/>$fߞ1qE3#S)܁i\`ymI8f]ޓ"ȺG?(SJW_(<$+Чشj-HMWA{: 7ެ(@4E]X[y^*ʙV[kh5{톈OakƊt! t sjYE7qF1gZ5WMŶ /A+f_LIQ@o2s1df1uǏgʯQ TVo_nTߝXXs22TngqO,D3ACug٨ȂCkm%m ,J>BWu놲!ɻ2){ cT RRX;1\3v, t{*Q,2d HQP=_yh}H V>w-҃"x8j;Iw^]ٓ>_LН'_(Omvf-o\u9#y Mc ܎NIqeGZquvgť%6 I8jM@hvRHѪy<^:¼ΪN繙:B2\0"TYޓ;\uSOlƺv!1ňiJ&9Tn#P@M[6Sȳ!i<ҩ5GSVib ,T^՗kiuYJ.."Bj[fAD>L>:/Aj?FL,^#?eQp --cnuJ?!V VZ@Cu\Uyw[; s7\[gKxRߠ7K8yR>>f}y=B:Gpo wl.Ak` @7w\"AUt$8 YϣB$*{Mr5q 5ʥښ>>Qe`܏魎)v4VJi$1g2nu nPhwO}mY޲u.ǰ>#j΄>Vp {u0Ę߱'Nmd~Z|^74JyPH~zlӅYnVuQ)AFOk+wwarqy5ZM.`جL󦚐bжNe9-4r_H)>CiĸFSt-5Oog6I$MP,!8 ,&֒V߁a$CKo~0?f=qvκZi-[2=qݲguU;X;cce /_  ҴJe|i Ԁu1+zjȪ4f,%4:|T4?q\+yV1Ko<){1A\Q[? 3?ň^p'm7Y+o) [ݼH&q$Ɗ ?|NԵkf^*h<5yKK?z2c uaFsR2F\",D3#=OEFy> t- (8Bpkgz(5Յb,q':;+7}tbu`(=9҈V#h Z_˶Xv?UoRGOaJVQQSDZ>m?_XawNʄa\gY 8|g%J7?4(wځR)/e|[UEuǷ_w_&1(. mZ`55ho~dw+pI׈8vu=}`'ﭥ:ie1rg;ۜsܲY 뛖&i-(aoAYu[>q)djXNn/ Zf7F՘I&'#e3O[v+ J. DŽ ZU!g7uZkw!6UYBY#e)]5,fKHҾLyu[ƕC3qDIfWg/rPr"9yb%Bb C$ 0rN(K s*v2Uǩ9%rvD0X\Px|Q4b^ Oi*PdnX E{gpi|niFZcuxLna< }vZ gac |~  2s*3БD6h[Y0vy,v2a5Ss@D:nUrزezuw5:)nDkיdUrʫ)&iԲ\gl+V8I^˴LdSITݚ5BNuw\/k1` ^Л!~v/^)ll-3pfs {wծA io8g N7kݒEX"ںOZFˬN:+j220-jPXG0v4BMH `|FS~-iBK5P.k (ǡ7{]wE1dkOPJng:I:|$ =H[ID 9 AqMe ?*$ cbLր+U*ZX @)3%%q]nE O4űehV'̉ᗣpTﯓdIPexuӥ^ !$>Ɯs}=9䗂n*!a 98/%^u1 }gnn-!͎u~rtH O:nq"esP Y?ː%Z^~FJ2A9Pp >H}[4Ae"kT[Y5 6 mWjAz֓5L)qI+l@0 j=xώTpMn:N]++N2f $-YncGhuͭ3(*sV6CfQb)QMGp}Lny Hط1مj E*yjvFW\K9 Sn$iEs0?MmVֵo_4N4m}z(ETi?/D>dUŵik>;:K~%6Km|ʸV̎]*̴JdBӾM3]&UZ55* G]v%[$KNv5+G#H9J9F9[#’cz4Wh!~_ 5so._2W8hS"$e*7S@~vh89:w2favr+qM>;qpAjjDu]_.Utt8M3!.n4yzZGtK8)A $,.3O{aIa?WÈ:ĻAtZKiiEp={:} v Ӑp:`Ay=k`B\Ըv]ʨQ+eɬY!i"iuzuREE5Fdce6M=8DN/LhburT_󼙥 . ϛEh-QFj-t#S@rp@z;UÎ%փy731Q:)zR:3퀇<㧾ю_]N,CG?]J8НA냻X0"ՄO)ƒk MPIlzIyl e[rK l?Y>EGwm=jZk>unŵ83*=udY.9՟pkUYPo`Xdp?g%yПNnL̽f&6’ Y`m'^qfWǯGiu_)S! VZMaP06outFټ0HdD]-qJ/'x]dN#G)Jߟw'/ߌ5v5EZmYKe5j+ nd1ZЖe{D+Kփhl'#/ǾG(! Cڵy?+]e{} ޯ;1grMn{d^ hUv:.ł$i,.ShPq]ҹʻ ;(Su(W]en1K~`n8b&0Z^2;0YqbRegQq C>uvF>rĴ b=NԾb^LNض>Pj|s&]4zkꋥO_Va'Z0uK7)[^Ƿǧp߾ʌ|{lO +۫A'; ^ת즭 ,q $ Һ,x&]]i\)4A,28*VZLs7kIemr4s~gtCGׯ׃mٖ.eIJ~{}0ifĕx֯^mO掹]P1{ǠHOj; r(3 2ԱÞ*E2$2 Aq<"+!&Xe*8rQG)g:s`!-?$>] ̦}(BH$gLCbEUCuqwqѽ]S/hngЪakZD0r_as pXkiDdXDpg%r{5J[m*V ~}WmPJ[S;AmUJV0@#ZRm^E0s[p\ ^a9:Ŏ7ώc;<矓ݗKp5oޅQرpb|Ӗܑm.(K jGD-OcS$mi[̷4(z2b7򿳮^Ujm?yEiET֙4:)͎,!?iJ+phnYeSDbLJAE6"lu@n {Pu0ffMdJa5OAX?L׼ķ7i +wZŷ+˘۝륷Wr84BODB=q(g/kA-X)\FcW8]Dyrvr q^Sۅꐌd3%U@!e%ҩ˜۝&]s)Z=(3ZvMh' \`[a34ٻtbA\uQL ӫ׼e})fR%)4]uUyW.Ł5Cd~ %΅l/{_dL󱻈ѣŬK*`EeYG1:BOeWwL -#v;\ I". 9pMAZB4~;Af I0#Q/3 :q iL I(MՌcL ynש4t?u }kahEMBS z[FxW`"H@eV农@W]7;49vD1+,Z-8mV`ø^ּʄq#"MZ.,yPSξi6xX#Za5O@be}|_VK| o2%. j{UU:ݸ?$Q>!KNmx֎ ,}K$tl Aiyg\O !/a+67C@[فvifʡf5zppa9Ԝ(Y]e%|"c7'O+@g7[At3}c^KPFe=wϓDs ei 4+Nwz+xߟN:W Ŵﯗ9q,P-$xsڶJ >/ڢK—Ap:Y=m50D 9|BV 7zl'kAdPxo۪=Şa~wUUMUv-hW,r5tQ3:ımc^*Nn dxdQ cGD[yJ|ց8ޖNQ4. eDL [ڊB~h&^n*^ ,K)!5"*ݔ Ȳgl] O=% ەrFmy)!+W`5ق43yhƔk~ZCu,ܻOH:W-3he>4>+%d&{H"UNn:5 klCRB|;mOD|e^(%{µ'^wpU!j KIrQÁaFmK:5OMp*i +lXȘY||0>N@U86cYdAv6zrKK3'Uv HjDDܯy-Ua~{{'ka(\*o]{t{뀭40Z6ٯd بFPBZ`ߺV ~ast4ʽ׵k8G?{N۽[/l~n0hSȚ%@g$)5,Ւ`)d}a,wgU|@Pr{f:1*#a}V)˗iv~ϣh7g:YK .y*,[8;Rvdv+ʻoFr2PJJlF)Mc]O^1he{in| hgcߋGa4PVGgHzGIP&:*??,ed-Yy{mv-'(7+޲` X()wFHHj>LwMZ8P[EkJIgՃw`.FK} *ZB})y|vB9n 5 N[0oR ZDrV{}SLܾ1ߗ< b~tC+馠= IИiԈB gk՝CRIq_Y>[벇߻ϼV$v액SNmyeqLq$Ofâzke-=Vo A\rDpٰ5ҊŢ%i(Ťt փ5O`@5~+Qv4h}Y-O&;I~HۄzRAZ; {(v4cizЄ;X*;":h?!NK4,/qw{]!VrU] :YA>5q&hnjSg}_ 4Ţ(QUm`&Zh#ȼ]Jzu}5!J4qTe1->`V<9dŃ{}Q 57xn%;Fs^̭AYTK5-_Qi>Ѐ;XPlOZ*Pֺ @Zv8XT/Ot `N g4͜yy=ǎi肐g+ةNco/N=G7awUFW_΋y/Q)#(T)6|Mk&ڠY%!L2AY :wΐ B1JJ طָ@b壏lM5;Hc|x*-H# YŨz7q}MP>;q|.FiI!p 9hRʅT%Y}-9 $˸DgZ ijA)z/Ʋ4u| WW`]׸F:C̑u$'UyKxU#wU%!C3u HuGbqӵ+j":VAҊ6l^ 4׼gU~# &8Zਜ਼6q@ibʯyk|vfIP9lKeKje9e==(c-<߸h2"s ˹W9n3HkSd`x&TNIׂɵaő le)Ɛ-f: )C]Lé&pQQB@<]a֨fU%l4t:c /Jdv^sYlghU8yeUR@d\gdCh'k}MQzWzu܃Eϱoays0\W"~c09ϖAݼo?n߇y]E7'wT/Kn Ɇ#LQ_쾇>JzѤT_KRڭ+be"JxkGiAl!)(T_s9,e҄{sz/)8 YH|loub+FϢ #@${'.d׬kY^5fb6LrHm; 8'eY<=}aX&l.#=]-&u }dkGVܗ坻ܿ~BŎB?LI\*>xt`QmekvJ|tˎ|\s؛|˜+& 6;CRwT;:|3D_d<5Y` 0xQl~;l.u+k-%q:\j*Y!v~X7*\x_c*U,๵ڥ˭#r5y%H4Z9,r36uM">TW&k[DL6 IpQRhC(tR Nh]-]p0zhe}9}P $ ig`ۑI5]~~##:#Qe~\Drg:-QQ68a Ŷ6 Os$}9!5VfC YR wJ+wD ϯ-t?({@3 "ϡ筒zߜgձ?>,WfΫ>)9B(~=}• @h[;'*`N|֣̈́j\!f&KgʁaFYh|۞L{NӞ '2K%'3~=_;$4h|}?__*50YoD0cBo[v5ufO?fI9jwDJOivx[DTBv0PiZdG }pkɎQ[ml؏T٣גvƯy5OkDw^8Y]{vL)lfIDAT\TjDIϓ!YcG0υK<8R"10#۲hnr0 ⚷PݘuQC#C+$L4^A bjJj%r9Ye Ѫlw'MuZCoVzNkKeоT's(\J;QzH2V\Tc@"_:4sZ'_ͪۯLA&1e=>>vzk/ťɳ=n[`'\#I9"{YIy,;aȡ kTPE!ȒP|M14}-Fze;d5hth!,-I3.4Y.e'CuJeþ'Xjf];=m7j([/r#ܖ[Lz˓Y7m־ja[o^N! v{aɷ!XV4qs?J$v )U§FL֭mD ]@B_ULTJ>ᔑHb#k)(E=ɾꑨ\WtE#c1{yv~J kIJҜ5]~T){!E?j: NZ-Y&LKg:Pur5{}Q*g(x#rUfhq”uV&kب,/jomJApVX8ܵXfp [YW49,PCqL- B I)]]K.]sCDj6Bj t.o0 4;]Ė5dYݸܶa:/w/%$ڋ 4$X 44>J]׿~[ֺY<-`g6TXcS(myEb*蒻痈즪knU7ocvcR>Ɨð gYlZaO{yzŹmF=:E>Sid/g$l_Kr:Hۂfu+XI~ŧ(8 $+}pU`v @ Ў[[J<<í 􃍽7G|wH0X{C8x  drɕnl% ͈KdvWSWkF?nEy0(5Q-םz QX/!5ۏ`.wV5XHEI56 5t^SI&rkwb-# Y1 ڏĪO¾RgI-l*\T -X+e&cYF/DɃd>_e9ddz{~Xm^j/F"[ ?nn,pv8j`_HZfS}>?pJ=?tPlY5WKT\!E;\Kk.*1KQ&&[[SҽJ3ښskka_}Q1op9gTN-G}KK;.ne&,\7ۧN foݸU/5 .4Y=nz7Y^o|M6.ݚ~>b&x_dnfF;\Co\,0G +go"F,S⻩B;RGߐd3yFجvsȤ-gn-\PhuuK9VM%R L| Vh >(qyd!.4- "ˉC,Jq²NkMnzXB_F{Q7%۴8X#GL.8_K+HP-4Â׉?_A{бf)mY' "xtnV!Td2ڜCw'V5BiZ&W{Cky!oBnGgngoftdG_xܡ - Ǚ= ;&5GH r߻5oƳ*˧KO<~{==֕ݬ:ۮ76ڕfz~;c\UE_2nD2~jq@k.iv,ɓfY׼@qA|k<=Шe1 ҩi.*߰LuOZ{ ofǀ$aDm>ېiVTY^ps6dq++P6IJg/~;>Ą+5 ̎dY@וּ֡WvN+FLzlACh|}뗽Ovo/V8 6?d ى\ yȺM]+=V SWItu;0r1Ny? J>.q㔧8˯ ;e+j325*qՔ&̌"g EY~7f'"QF T6g ?+ʺy8.4/+h^*x0(]5ZOtդg@38Xޛx}7fi͙[ccW^3uP/%iI快 m\z9V:Uy[`(Lzxmq j'rIܪgl900k\Mbԇ`M7d 0R 2k ,}K9}tQ104Xֻ_8Ps *hAdx|tT}pd'O ]ٖ?hd?&MGcyz}SC.YgZUyZ J3{TOoWYq8[WM]CQ7ftՃ8׍NHu3ǤF0Jy[vR}$1s#%8OT}!Yk:z9Ɗ*v`'[PU.Z/~͋lGwn>R^F\g8u#Ac-ذCz{VxN֊֩'.dd (wgv0g4 z5w}yd`D"v d7߽ pqUˆ&K-|Y Eeg?uv*Ʈ @!s}鸸<؍^.WX'v"c-Jg5º\_ˢ*꽨e>ů3ΪCkGNK3?UP&RZ({ q ۶ ʀA)1QOvVHt}}sbC:9,ٺf b1ᾃrQy"ւ+"5yiy{;RO7 v8eqd\ͯ߯mhcmPYESjU֔m <k5̶.Qs]MkV|68z\Lպi)Z_euBE$&璧Qte}0),DQkؤ\w9\yu:M7dG9ڍ8I$pR:Vreq8tC/ >'>OR]?R܊a@9r?((ÂjNջcmOH`'?dwr5}e3?~}_#u!grwp*L LV8ؽAy p"`񓅏@'?泏lc~[V'Iq;7G[r%m ?ϭWŗ]4ELi b#E;׵i|[mQꃬk{qbokD6Udz- M3|"b1'd؟Mmlj+TY6 [)$-T[oߖ_EKT]rzznӸ`T0_z-},` ͏R`z42z/=ϝL[r84 U\b]Ķ\p!k?,j,bvxkM=Xz~&nI٣`"fDIp4,zyq %3(,'Nupdc?oP@t*NB4ׯSg790n vv{˭Yp0(oA -a<ɁQn~Шq!߾>5 ۙiHK*͓,襺Uay3k/.w&uhfaD6\>p͂?Hvy=Y ܚ=+.{'fiõY&GoaiꬼmgՎ=x3)2]`/:*mkJ54g(F5t̺L+Hh\h't,*kqܭTfcoOԌ0~ۉ`u~q2=9H%IX\ɾJvt pY}Y'O[\ŗ.h^ A7w+ҋf1ĥi Kyd:W%A2F^~.61яqZb0ì$nh'햻M#6܁~ 찘N)4"~-XE6c>qedj4hyߜvx=Q\XEL10u.4%$~ 9VzY΢]%hҊ۷4jL 1#ExS< [EwӮ90FT5{Lm-X~sǣCWYDJbPr =!9LںhFc Ҩ)ek QL;*sg4&+pƃl~;#~woN&ۿ^ZL)vbJ ufr&c)T1Y|-t}soz|5mxeYY5"&E]t-k,)]={8 oEri`o oseZ#TY@ ~D|湯рY-ob~h#Xz$^) *ֺ%z- R(Yb[-6d+r#GPg1D魵 a|a4L Ől "}K{Q`a7bzE5A-crAu`Q.'v\oo<M1)>pHW_caͼc t|6d[թ}?CXyG2WIf9P5fhՈ}Sv],aIx-'d'"T]-xJml2Bt:!nv.N+X?::+QWl-,B<\mz{kW+XS}줈K^C-}ijf?/[k3VOXJHv e/o xhUM6Ff2ZKi^z`zBJhaYL值 BFY1s6ӈdu׷yid|}n -܍^Ul3akq-ZڣS̎-JPnO0+&ų,kʳ ,Pe. %`ogܻmf8=hֲcFǷOɴ(sSa'M2#v߬ ff8֚ma.k}X/).eW{AY62H= Tg#uC@utBbfm^I\._{V,iוylU VM Qo/@ `}naf8X+Ch8>;&, c;9^E-f4hV2Y c~xO '~X^S]Ef)8,b'J+q!JH{Wo0|Ŵ Jw|prd_JSz}Y^.%K}]I2rw#oJm6 7Fp(k~TwKqGMɑtVSX8sŽ!c,V<C\]Ilt+~XPӄqF} ,扌EUqmjjf,iǎ" T")0n,DxcTZŽk~m7lo77T=+V 6ޟ-V".MQ/P{ܢka/3KR-qu4' ykJ~5MS%=yXv?1t:}J_G\@ "JT"YYyY,~u%RH%xTҞn׉u8a' @Wv{ Bf*-Y.֩fod>\?L딜NmF>ĝ!{[prک w/{&"q\X?+$w]"YpzF;9s]4~}ܦnXr+׏(B8ξZq}3{0GG*aDӷŘn䬪~n[T\_+[YHڕix~O\'@}k.qg:3ɥuΩTtʙ7dp</+鏕j}*&MUA%'^XPpw3&-KSQ.c rxYpî_##c;K68c,Ѡh^V !"~ܝ@NE^ci5:X<Rݏa:棰M X .C#+.T޸^kW%d U}u5Tf-JjC^amzZpqL3T,Yݝkƚy[ddwTaϊ!ZҫY 5NIѴ_k;e.Tݛ3'vD?z޿DqQ1-D|[-ᔌ¤ %ԊN~ E2!{*rh1<e >Wo2fKwMVDJC:Gm=so)yr-&W! jV;j]yA)U…=$0-/_{ 9t%tp)_ o/Lv~FlG|h+p `l&[o-Z]T=%v?,c9> 9xg$L >Z݈" `v\Db(}^Z.2kA`NIDsפ?/qDEr9őH"cm%.]5K}]qc0Tu ]\5c5msFFY:H pxc?(`٤E/iRkv:E,'mk=Q oFN0Mn:a{4 _<:d(>si\Qc#Yo]%nqJG >O6UiȻߥ}>= ||>u)&FIfk[بӎaY^ j ?lҙ tx4Z*p2w ZLv w`'Ȟ< Yց&VW$ʜ龡R@`'FM?;Q1}@*~sjO8:ciEAf&DWLM sg&v*87~ |?+ֻcե]q5_ 8G/x}4CD;2lTw5VlE _tItKb|m n8nV^O9K*"d] a3T_;,cIq;+ DY o ѳi2wv RjפO{VenZboֺY׬mqK++D%.av+,z`b%I!4ں|Vcmy#+K>>' / QMɸU8 L{dkGY<12%!f%ZhyOt#ʝA+Fl먳F M?;}rǨ~z e}ႅ#v G]-OW)*ŹP-ϻI.sLA'ʤ_syMb.>dl9n}_Q|DBoUV7y >6itv?ðw^ Pj4m=hyOmV p\Ǔһ=B[%/ /&+ov\ulmk k7n-RLςq?9}}AH&ڟl-R0a T&E ~XQ2<D!hК^>bi( hώQS{(̍G` -`7(H%c$Tsvpoeushr8Z7Dh _!qR8Rqܬ~L [1x?\sߟKbY^<=͉K;J VPq,jK.#CN.ZD- @P*anއ#Pd.`]Q6Vc'yV8Tt5BA߱W.o0Z`i #혺{$kLa2L*Kr}_kkƬҊTfLv,bR (^ԃ8{Dd6ף/r^"Ks 8ȌMVU#7w: ʋfy@х{82V:W[ 6jl"X!NiR5v=N$: Ȱ@nJ},{ǐ]M,w]M_Wk^&o5wU?qaJ ^h$1KӉ 0OZpl vw$QU8kXΓ8w[6eW`slʦCNf]sւP|ݽд .Kh}i&by pD:w΅L_z93}Aa9xvtJ*Leʂ e=(Oְ*q-d T׬%8.K3%r" u$I󍪝 qű|DHd)%$ZZ^Khʴ*JnܼTHٮd50YK,U49%\EJA>wS۾ETrFǐ$5 :m 'mXO(  |&-1an//#S`!,HkCG~#7nd9\+N&_eͷC~i*:n[+saj/*z@D!d݉Esfkj^^;|1Ӝ؎Rllժ 6р (yE .q/[[[8s$,} t/'FNt6G/][9naX@X6osCuboҪ|9TAt6*ŚLA3/Ҝy=aȞtf\NǑ[GK֞?Hx%lE7I[gscbM:mqïxÊRhc$uGIw2:ҍQûi 7fƭF4RJmj'D Z  xXM~[]ڶ>J62peMG BH}¨ :pƾʛeȣ.g@ X iKQr)V~fFTNC;;01Z!vPC# b9͠k8;wޟ] qi1kM _%2f? 1ydNG>!v*nnZt{J|ʯW;ieWRΚ ~.}z~Biq7LfqC 7`Z^?["C#iW j){zD\)CH@$lf Dbo`LZ%hPwF CC(!{"?lfdch*u}\anWx4 c~%u?ˏ86LZ:iME 6'vkZ6~ e.9s n]kq%*{6ew. ʙL+dٸ8F+[YKUXai6l7UCt80s{Q{ #V/y\ʖVw/0n y[}&ِɉ:rn.kh@mQKa D&Lc#ўk+v~( ;8/[k^]iG`3"^썻_42gzYT=^.af.YaXYxTbUH@r﫴FWTg7KsΡ:&/geOGHrS1l+&Mկ:A uJ |?+EE7|Xt % ޚP4AE"x dHAZ|jZSAfft(kG֖_RYx!C? < !օV$Ze.aA(l2bqeyQ-J$fA;Ctr'~̓a{[EOd5H\Q`%lEPEUtsv?%,ODe={$2{k~fjlcwe{|@Pg Kjs;D5de?VV eF>1Q=Bj(M%?{M;£j%=s܂bNHE7hFvӊZtr{ ug#vrSG*~`I[!cL̑yS.Eu]+њׇxeNS*zu#OiPHz$xPvǵS{V7$s''1V}$ ٗĆN1Y1|N AGuvϷxv 1MUٕ/JKEåڕuoX㼌.{|7ֽڴoi ]21p +RMb=ۜke-eJ!KvWJj?זҥ"$ H.[&DZR67D4 5D 8.-FU5JyH|@HUpj<ù|šTtGKy[D;ty ı)mXys$z@( Q:Y Jǘ| uG]Q?/uv =^O6hex?9z@?xSCcD\'nr&kzWb3^^G^(3lZ{v^s,hzM2!'}I>U0V}KehA0Ͼ~ۋ(:T 5jc!vo3-nET8g6c^.M6R|h,=_'ѷ+NPVWh]-(1 ZyeèYhrEmIV@"ފPz f-kvϽ0"bZO־ ߡ2LᵪJ-b1$5ƙ,`̄f[`kVTץXt ]Rc9umد\ôFiHJNvy6-ڵA$c<@a'F\;Tq[GGMlc ߎalͩ+'Az:9hMǧeJu],&F4EժW]DU%v@n{c=ed~5=>֚eyd Eq8Dn51}tVkq>ˊṰ[XZ(#`L $^>쒴ed9G2'N̖z/\HGIYGKmv<Gz tzh֮LivoUCYGifަudIIr {񛀋z,e˭lH(NB`>,jL?Dñ bOn1o-b`pάeцh0AEN4#d% R>X{;S>PDOk˵Q#A|A9t}EDpY\u%dx%77:.WTS1ڎ_J?0w%RniEm%jd5vH?Kq "*&4 +qLb>PbZg`=ֵoQhaWG>K{UKurQB{oG6%ص|@\7*Vq_.%~tv[@mw[!"u1B` Sfq12UꚘ+G;tiRp!2}^u 3%?bi^%eif<W((v`9QJUxVWt5 ݷ0 TH3#4u'juaNMUMQxxuyNt-~-DZ݂G=-dozY'IsP`: )}i/B>h^YSòAx{--)١`gSU"Y9o?tVv0$ڑfsFk2t_eG ,M7kZ.S,J@MS.IVJ%zw72ٺ3Km'xJH}=M;\EĞ,b&$N Mݫ#}ۯ7 Ilwx- @ TX`ZMCVkKXFɓ9=*NuAR:k"ܠahT#M@BEtVz E w .5n-im+-z rngh"a4UGK5vRXZi/i;1Zk ܪb o>vQ H>^ev\O…pٓTK2VI+ ,o0? f7\!vT ed> g15`9G(טW75mƺ83F X? K3LLArEгP~^i1ۍz A+vhu~++@ Jww%24sjCYN6vS:Mp,嗷 FK/̺Zc hBFJ 'vt0 [" \?cFUVK*pRRPx!mmyI8Qcly*9P5t]Hx;$jd +r-FW¤ɾJ_<>_X)l6=,MVYl8j+Ӟd;3V%XBv+8w4"]z8I: ΎK߼]@`XL SWC//^HI붹~=èz'a Ե-WsGje睠>??7rGزΦ)l6 {ͺwkݟ@׮*Wi΄=d^K lpraX,*ٻ8";eL-j׿nnښ.+Yc &PBcK^4dw5axhƎEdYY3ЌF<< Vdž:>;tLCG f $D' R@sy{$C RZN5^IWf,R`dQtE~'˅O2b|m-jVɈ3G11d;ble$} ԙv}AJm\zfNdr{2S1ܧLw 2g-~p\\%fqŬ[~, ~h,Vh-YZ[geK:NI'`>NͶnNZAvMvnܫgRŦUGٍZ~Sc鲱/T<(WGwB?ГJ UBO* (hzE{ap*%7 ׼"}ׯ_Wj,ʌ ͽ @Gzg7䈆VA%ם•FNp`MyhrHovL?MgJ.a{Xd:u^l' .o R^uHgRW/ёFmv;i զFb"z-R8,rudgեҊUሳL2EȜ„}㤮A QW=a%o: ǜ7[xIeKZ[7sDqR3$Y$2l75ǝڢkݥa*Iyù΢0ӑiY]=w ެ2?N?ohi1 "G,OJi ]hVRX,ҸE%@,9 n7`>0Zk .vvi,O.Q3o뮽RY q_GFXUi\Y$nOS[Ya=z<iZ* vjy94@* uagfPK8RC, T@״%$@O8Jq^c:ԩkEk@TZ3^}"ʲ l4 [YDDa2aHjynqO{W1-_aOS(Mz@vX|Jc>ir{my2+wf]?:ڢQpr+kP_epf6%Mq C,0 }?Qa$i/bDLfAa[) g YDixaDݬ`une#bYt,VTw;HUu9B. *[ ,IGPݏۍ&2ǥߜtȍXyjp!G#u-AΥ%p:Ȁ3imie:RgY Ǣq_0v(THt 9#3si \",7x+Pb:I6b-}9{($Q>cI۟X_ ,3G<jւУ唺 k6\ީed=B>+A5&du^-To3#dq^^8ڻ!|!E?afn04@5uFaC-@r{rHțL] (l'*l- }=vx`ל3CE0:2 ]6/Wnv /mu-Zo_Sx׫H N:9c@(eJ 6@6aE>nVH^ef`!@7E 2ʱ c9/& Z* Gj2m4\A9HxIuy'(Iv)&xGGbmi<%?fDz j-2}l]b`1jThd\e"$uKmT˵b&St ;_ҧ/"9GntKq ۙZr}AH[)w}I*:x5];Wi_8nתc.j81e(;٬ZN %Myoչ%/1ǢcϺFKɳ2}eqkU6I$k~o$4fZnhH΃%{O' ZeuɇC:̲p DpTg\ };xՕ%`\Wxd(S7X_mBE޼o. inQO!k2]Ni$)N3k@m`yvp~bqLJ<[b$SނT<{f5qV0  97PX @0N{q߳[Uc2݉T%"j=݁Zk[ hZ07v7ɛ՚e_!rnͺRh2X +La)\ܢvO\ *Ok CcEOWSZbZ S2亇my@^3|E*dݧ9B A; *K0H F?LUsi kqkcws)#dHh+l:uNEm$裰 E hMեL*w8YӆYf/oB)hZڗApei2Ev,Fwnvqr!Q$j 00bN l a%+a5dqkqg: V$ؾ+٣=/ uR(@~<N-A23I|;raK )?ޮq4A_f`BR{W4z/Uc| [ Hs"މ}$*raDoyP [ؤXKW]R/7SmVqsIy_P/18|TN^/ueSlrںoiE% Ä.>3УgW*G EGkcDKE[õ]3s "f2 7PɅh\w WƢllFLf\%;vpdcE8n6HiP0'HO-\؋9 ʻ]˸POsmKY[GJb%,V\- Vv͘^[_jawcݹsj+αLW 0oP7UvO 7P㙵΅ۆ8QnVE9(޽8F?bKN5Xg Uo]iJ,Vjɲ%톙LMc)4BjɅz7ZYu"$8hkۭLI z?E&'T/7}\fr[3}V?aS!=PM'Q.6vfcH5ofvu j"Ս;`b޾ #,yOM6gEPzڐ*ϼ?2;|>L/C$q֘<"v\E݀*o-/ =N=OE5+98yP\o҈J2PIf=sɯ9"L*Cįy3fרӸ RFw9QGªvPǴ5;r+hidق8ɏg\s#س#H0#~j +D"K BDRbYA[y_c'x$qo|qeNk-뮗^]ӯ>cﱭ蟯cdHiK`GC.Z/E׌\]}=RY]j[h˲"|b#-޸׾Bei-˩%еkhCknMZ׃vԉEMRC#"{}0N4ImoaTgwfpE{,Œ5U#I>4W;3If|YxcT*nɷ:moZ{R6}3dVRdǼzY/0u_;/Z;o#ů<CߊuDY!OjH} {(*.n`ˠ Qk[|wl䑆 _ \wo|Y[]փ]ڹ7r ^W,ZU<ԚI#8M%A_H:V"N\lD'M8lA1~#W<.cO\/XAV$wTDF*>5m\VZvB/7Bh\=Kd5/*Vt" C<FџIεz),Kr ;;аm'(IRTJ%kdn 1ޤjkQņxg6 Qߡij@챯xNm`,ZD }8YO \kҒ뻯)>z&n*uYenՄwz Ӆa[_VR&5msS 5R* xU~5{< Ot ,Gdox4A# ~43DEKs'q$]ONS^>&֮,{'\-!u7t孆j+ Y&Q'"ܠV`i Ѣ/k7f{ pՁ:(N)G譕F^?W,eɸ1zLLI:yAvU`i&Zʺ`?Aɤ6o kbD(yKT8 CjҮ9). i5(Bq!9Hq- q|3 6iaO0>c:K1Ϊa>_Na;Vn]_4тʨ NU&dwi&i%5C*P浥J: )tkxG܍iYm'M{v,l-T v|.Q=._0˳ Vb~ڹ ڋmuFV2Βyӧɟ*+ު<,*--Q,76⭸rbi%RX/0Qa˖!ZT :j< ,!qW].E=5Te[o_} ?ʯhsnzO2X7(* 5'::T쌽:~?W m@gZcZ@ GT9ە&r+|jclX_ǀ~ . n6nO{4:*k5zCp9S4 !†CC4s̍Nq9?r*E _JcقK?`vR[לmL nBXoq1N?Tp}Q:e_^<rZ| u͒(gzCL$4Nma^=DhriK6H]e,Сf'@d,ɮYD0oܽMc5ӌI5|@ YzgboS>dp¸qvm1jEG+H>yFY0Ѥ/VT&.; G)E; no:hac* j;}y F=rم9M>L"L#H3[%tzxo*5X8[/XSkCb$5]kwDj4@mkʩgؕkO:`r^q `vW 8WƐڷ?oէXzxv(4q]!y2rlem njQNtK9ܷ@q7ڈgy/sfF+ؤMCԲ]kY-ۢCSہnekni5* 7׳~*/hU%N5]hUU$"}qEʲsG5vm1SB>5VkhK׬ uN5ECՓ5ae|zhVb6s!ǭ!"'œdJRtyޢcAbv|z2nbMGf=5aS8EmlArQnB},1ֵ؊̆.`i 7 R/# <ww_~;c+&u׼qtqY_׵I*`9IҿfpeY 1,qLa{~=Bad"D@DQhdAѦv?bk=Eh/Iݕ};_o=%989v욷 [0zb LuZ<\6keID#=eoy'8~+?yǷ)AjT ZK"^6  s?êCfy!Ь[U;MѮP욢[TbM#mχ_}zaV⎻KZ5w[AjYM}8v#f7؋~B׈XgH: .R X="ǔAίN,r5]x>KWzIj5if;X.YfmԒhkqX}i6Y𢡊jtWÞuފtxUWҫE55J"ʑ]3Br7X`Ԧꔩ1y"djtz-۳E"ɻ$T¬ WPKm83dWbɏlݽ^hɠC6l-iLg#6·aaZd|!+u*c#4έ}UJt mzjqiЗѶ;µߒyV =!!괞Wrh`Gםzhڟzܯ%RXj&Ɯŀ>W{Vh !)/]2]bYC:zVfVu3]Ezh`V"vۻoJطڧiUY9 J@kU5 ]s8b- WQ48w5HUž{ժ fCS/0 xTecT'[:=^¶Gp/>q`o-EV-&B$R5-[mkc Ho)"yg{ԛ[;oMgihe[(xaWkcBș~H .y˥Kek2^\PjzWNV38 RD{8CE;,a0uPmVZ գdκzO1Djr*d*'5j8اIelx?Rj;c #`&]Q'\h);qG*m ;[ck:1!jG{zVOCJOn*|pcYoeqX7x@v{wy101KuMlRi=fLCj PjKbLe<EsCeלjY^ JJ*N,ڴyV|Ѝ!oer$0o5wxȹ}anאZH :L^,T72uYdcOĘLO@fveuʨ5 a0[Y@lCߓ"?"i) ,#Ծȥ7[ۍ0֨5,r[eHuv!XT5[PC>t$#ݎL odw%,(-m]::ZwiǶ)0J-H(Ι5-Q6M5o?XqcA4gbF 'Teחk!I]4k{RU߱c׉ zJ;R0w݂ҕ?.8B>BR%y0Y!H"l!G@qNM9PNAB͖}hm<3䲶fC3Z"˼Gٲ|;)0" ]d?sbNe旟c=֓^ [oԼd3Y*PֵzdM pjz;ei\O/e!Bʺ"([Yӝ|O%nX?JM@ztYf0Y8rҽBzff 9#/"-,b$*.RUiҗU튧lh.*q hq:@c}R6K`ؗ>w,W3i(ЦDEtLE]=rtcez,=iec 9빮ȱ?_A-|K~DuP`ŃCc勸/t*ř_M^ NױY߮MdVэD2j6f;0#dU2`.RbLq *K {N&d1UOV,owb']4HB6 Pn&vQH3q\-V@lԎyB ^j\w& )E߻\Q.vT\] ؗ5..A G':X"tO7L,T̲=%tݔڎǰr9Ah-oTqSC[;Ah}BғJK{o./Ijz哇=Sa4.v0ۂ#%hq}cYJXl X3>}L^+o6\[slחE^Wxjcu`{ˤL@T{C?53.7 % oq4>z*0-]Vw9֌2Nي lY8|p5JӨav/}Bg'R!?{g:p~8KCebqЪRFq_ea$j-Uܗ@v0[+&Zk< P3/̵U;Qb-#g SpI]UV"Xn"ib9&DX%lfW.fWLr94hm+`}8=OpiI D崜;*}cE`y[Ռ|""ԷK:cRNs5L$N3¶A:*<Nۿ,wj(9bjM\[ߕF_׿ wPL-Hk` eǜʊ[.D`׮DOslv])[X(I4*EViwívۆU{xȅ.ϥ|ho`kUG$Q]" 60":ʴ>X>Q%揨5!¡D[ŨjF5lvƀ`A?w,:&L[QdmUh][hVKG/̝F]ʒS!{_u,mh| ((rce`fEcUmX,YʁyS;x ^Rd<~Pɳp!oKzϛvcv~ hLVðGG洢y+, mxl+`Z]=O( e&?P;-0VDz4.U``RR0S4YOڔ`= ,j֞&Yp=`< ]1xYӫ xJk*|$}V%Y)h<#vMʶ,vA{C98]g/שJ? I;Ec X?5<#Sg U;BzFg}Ii-]UcXeM^.!Cc?ЧiW{9@{t3f̯eT mH%W5|OYo_ri0&|GRhϚė|Z8j꤭q#c6e< ur4QVXC%t -7d|a7Pv|E^U@6#HV@gȻOcQzEINLXR(:}HCWvgkZ:ϋBX =2觻NLjDJ2*+ d4MhϪ=gKxˀ%ȌhN:Art{i_{܄;-&_ƮK6bGzhE Ãр>zX*gY[.W[Z؟2`ׅ H$k@_2L;s,թ6!'ͩT7#V#c6'A:jcܞO?>6;OqOw8-A8iq;dZW5˅LHS&ڛ:ow*0뎎Ϫd; yΞ;]X0͈ƜƊDv%S7y XY=;>~b&j:-)c&b횳)5Ơi Tړ[nMp׼\o4}6oG!GiW02VV@vOȰU Ӟh]}X׭e˺ғ16Fk.)%R`\_ڮEVzY"*goZcrչuyK)-I8>;f.Q]B{T÷ʍ5cw`_-g~qY}=^8]0 vgDžuW r ^4c"Cf n`vGj> PJ㺈iVkac~sai\1.X~HM @1r?8bi71D<Фi_3ᷖZxqFqC9E*;Ǘ#98M7gFQ |i|q48F#bаPǖᩖ-*NӂVs;^ =푍$fυ2r_sQx[y|υZ?ЛO JTc.r+Cc ٙx+(by(*lP-.2ۨ^KhC>PS[+K+ Sv0Ā<7ip^Sf1&U8Yg9>u$"7Fޤi$0jw,Y9m6GR[ اlX*O NK^v?9P-vKƳ+gJ<+K6]QqDLn{ƐC m[ȢU , BAn#'5q6.z{z^5K/jI`rfhR>5+iƾ|-~U\ﮆ$h)\ }t{no\u&7>!}"Y 5٪G%G2X*jGT!(-nc]hgdI)О{3>]v#B_O@'Se-BNœvv F*fd#'_Z ܬU9/S7ܟ>!N[u1[o^_ϽYзjgI_vL*L֑dأZ?tS ҽXnRopQsSVY&f.kG%bohmх?"7Wg(e,9A .Ӌ=x!2ȥ&L{oUgibۼ8gqZ )Ț74!R@*X1[NRs'֑Q]g*(-(!"ٳd,j{Sgy2UGmγxYD1< y\&vJ.X}v֧~5v۟7WxXvz|# 9VWsxr8BZ4a;mU`qGٲ%maO,Mzn[C[UVHhi!QSۖK/RٷՐ$_Ҹ=&6:c`wvaz.&}T˺&Nۚ3^[ZK5$g/J͚'zyprPk㰸 tVdvJ"B72vAֳ|4N= L\-'u0F-,كݱPIlw8V̀ځa(*$JɭE)yuVlM.6_^ַ/T@->v_8(#J`>ٵ|Zg$Զ}REdԉ` Ssk0ADL0n6 rg\N[ݥ6+vIy؝dĂRvT-]H,k$NT\} ZL s`&Gvߣz}g5-Ay^\j /B9\vz=+/TO:69I=*LQr '?Y' vD'I 2-jYt)BTNYL2Ɇ2_nlG7wb<j˸ScjҎJsx.sR%k M\?~ŕ}o>;U]e 1 M8h~Eu2hrUu1oEKu;EoZ4&uV9g)yZlziv 5g]gx>Q~% B?!tWhD45ȷș : P}S+5_Vᅱ a#d Dzdw]p 4oS1-Lw}΅G5vd^#*ϒ.{]e1 e"e8PZ[ua˾\kE|4Yf")ҤjkʡO9ltimv=zw><*-XjrQ`|8ƖwYހ6n#ҝr1(bό{ee(v" q KMqwu幑~a!y'LM{]$鳺iy|EHfZWM[vU%CbbJR gԆwFA5L 욷}@pޢh"x1-|].4At~cpJ‘\U DJ z!}"?]K3}[{)img?T?@VWlBv5gh ~H,F .-Zk 7[yoyYWySFť歫nE !+73B,z6d1v&\4P/TH*sh?{h\?[ ;6J!7N/, r>uK1kת`" jtXV,m]M5]s |WT͛%S54kCadLG*FpCI%W/dٗT1 -8j&G Y~*΃H0enEt_p[9?om.iN 0ik@io%Թ&Sd-@l\jv)11D˪$:`ge,^lLt *i=s+)AOQHەuS`&=k_z*ұSe/{%als{eTkۨ+rgjVLK 0~LsCb40h"'֤0ք=A_XsS6d^-=E$Xl®ْWOmfߖ%"²9oΓ Ⱥ0l矗 #KarJ30I2y^Ckx_s#bUZYSBıK]$>nZ~ZP 6J)*{3V~R;s* цy}cGr@/7"UHbEwꬳs´Qɭ?vF,\3Wr& 䇮s薴D$+R {~941X켖ȹn?>eH2bڭUf 4^ϲmr5\ZEYDtt'5 yIH}u^Qeay1BΔ#\YJDp@l/l YvBee}<7@Wc`qn'nk*[$mfD@٤(ݩ5%0zNWyͧe"wni5f 9b7`ݩho!P^xͼ)}EMn۴!66\6$GdyXNj.f͗i]5L&.zJ\i3JVVը2SUaf<~?Ƅb4?_ׯrgB\q=^nhueza? RwT_5*aX%hhbU*#1QF|+>T76au}7Pы3ai{n Ärh4`Dp ;zz$L]yz th֠3j>]8K 55$C {/NBj?Rn7q CWilY@xB` A׶M<>[$T-ALx>,<0^+2{y BQ3t 4jƆܨ-6Ii*NEmzlB>5&0TMt&|ɢL 8k ⧺R{3[<踫kM sHZ l K?lZ?0<=Iܗ%iI`2M7=t3Yľ*bkAOC' w14»ӝj󟷱O1-x1^?lZ\iwFV$jL]GS05طV=}uXkq_ NTYCdN2ۀ ;yqȫYۖk-q^:kxnpJduH.0E0ԕ,)U&h7"?PT멃erJ}jУFS0W```-#v }mSWh|&8@"kn(!Lu]soN;8o!y͟wrc@SI~e-]U׽1BAޛTUo,HjLt4vƘ{hA:~ksfRE/ٝ=>kN5S\oGq ovMonC aGoa y̹A9_O%V I\FiˀaСc=db 5~JfC*Y`flHgЀ"6&qCrNvMӻ9j6aB>m2iāq=a8(pLE07J8'{tn2P^?EzuϪeܚ;W|o|+1Uv?<]71Cݱ\MۧvIBm);Og~G vY0̰̾4f je2 ו8'֯R0%W-1dwaB -܄Z35;7rf9}3&[~guV{q#vIRьgRE@ƷK)i"P32/`~Vazv4^1 ?iɡ£,ƭU5hFĮꊤdϣJ]Z,SZ(X[=">c[v<0boR"|;WStHGlY.Un|?Ԍ^:̬顕I>H0]4dz G;޿jW]ay%F`]ye^ؐ k\oѐa,c> V(o9* C .͹Q5X<fje;a 0հ[81[ Em5#7`"rە*. O=K,1҆&‡nΝWߏ-`ÖfPh48g$'oA3u<@k3&s7ᖕ%2+4$8 `udZ᚛%yF<-r`)>Fǚ+5П:3F4fF37U]G_t:RotG=.\/TԔ/0Si˸3Gf%͍PU~g[9V k5!o iuѷgūfŒ*'%l%h9Fo5?=w#?fOgĘl[TY@i~(  CVgSV-sUTE_㸀%`bg7cBMW1tj7'.Yz6juTw&[rk>NRԏ׼ϱlZE]J^f ha&,j,v~|ݸFU͐bJsF/FMvBEqash5ܻVU>ۮT_WQ~U*EG#Z1Rmim(kXþL AHSLz8l҈2 pU{ĂYGIU%#R䪝 iMą6sY^Xt[(erMEyLzm38γ%*)gj!Ss E<.I3Oܹ r1Sנ:v<7R4 x}*TlpYN{lA̖/.KB6v\**0)SǤ$ZXf73ȚoAFht8~i p~tX&a@EܺM}< &DgnDi=J0[7pD>E[#kwwi[~|Ԥ1xdQ٭ z x]lDnwœv5\vAL95:g;F ʈtuD]_tJ!9+p36HiҶp춉۶屒WbE;e-!Z؞R*Ii}w+8.6zPɏ nioՠh6)0MJ`ꟹ'.蚫(c~qf mǻ9~@ :wE=d u e 6|5S2:^ 0ڄM3;R:tͦv{M??&/SϏ_vx}S*4M> tJBLLeoR3+G2qAl?3zE[  z=vZ2]'c0KɇaI`S˖ͫ~fi.CY-MZ"^crw/ʼ(4L~ugGIUh^>.H^nv07*"F =bwq-%fX(amru9Dl5~&J"EMbͨU*#)p,`k +4h^c@rV}ЫP_6o\ʖFQXCj6,nSJC&B C-^O򈣺 ubm{<zs~lAEwcۘhh 4Y0vhCèv:@2e2hu19>y(NShNXaJ{\bw:130]fd߅ןl~IQlc]LoE9pQՍ th~RW>SWj]1ҿݵW^yX@ҍH괟]Ha__J @fE'?1ms#Gy_h:Mqt%_k_~QŃÄST=֦sƁzuE4SYJsq\*~z&::cݣay~?;0Ga-Pөs?@Ʒؗ"3">|^/-T!QMҍx?XLD 4L-?,(UZ Mlj5z+l H!;*9gَ_V'Mt8Bw_C{<컹d)#b|_sqa6F+!{wnS@jL wYFLʡBa`~Qy;P⚙YWܐG*n`R _[@g9G @k`8O1/Xx9ۆ<MB2Ż[W]vݼ^ K/2u1FVm.\쮾OTW|ފ륵ڱm eԌa)9?#Wz5 Ǫn|!>oA)E$DžQeLNŜ^7.śJ#F`@9XFz% mu㦈 ׳k04]tN%Z8n82kϫZ-|Z~GqS7nsza"tȻ*lc p@1kC5Z$ p|r*-H)z(ˋٺUZSD]!WPk7qݔwSa@^H?Lcb5{a\pQ+o<57?vͮyk.Cce-6riUל, Ҍĕ{U7>fP[k*mdr-=9/Y=5^雥9>?u.g7eE6mYn'r:EVʺ͌?FLP"H s'c#4Y<.>1ésR]JzSձ&^v٬u)sUCo Y8 ۔ ߥ-1*U*O0P o2qiջ"?( ̿^PwܟKnz3`V`ۀ=ުHd=ѤT›No_ b.cD-<Aɥ0HxIDU4S(lwUQ|]mCYƝa}S xfeqtgC\6Xag%W%](? .OѾsS%~[ ^{m5y jE3Y3?DY[]&qaA4fOߚhGk^j&A+Obuic&Av1*M͓IXazzmQVXcә@'1^s79)ܟ= _befD-ػ}JCvW2q'qbѕ~Zfk:9ʶD%k*Krmx U,ES%Inf4Wnۖdam4Vͺ=MlScN\igz]֮xa硙ucU"!O)yTD׆Mu7P^oxth% 2Й-|iK0t]"o1QxؠFk~ȶRyNlMBztyZ ET<_qA`sѽ'n9hp qJΕ 0B*AjdX422k~ #5۠ر_oVبC2Sj25ZjnhNܚE_k&{+9ۤYm0Bg˖ WjnPhT͛e| #XEH^ u7E֕ zcq>e6{4#>zfv7~.Iɣ#:@9) Ԭ PFA(% ̺LnIVK fYߛ /D4-4 ĸ? |~_tt%zߓPMK9aFrE[QNPLط<,kTGC2S CR 6(zO&3?*o3_g(jl SR7#/) Nf$fx* ˮj^ v惘 ?tpTyDGWK(a@Aza~J.TlmJTǵ+NUEo nS- ߥq{^^yۈάԲLxC l}Sp,I7h-3!.Fs^ ɎEtV8..ΦÑȅ̓T>먘aذo,6 u"cYT2 qm74J}|1buTϧz2YU:=F3LR7/CʌP)tF!;pBZ{%Rdž׮د[L{WƩ6{{5glcLrBߨ7ۀDmQ`2m# -1;7eV*8Igݧ&(.?RTN7UY'PťnUn*?jwM{KUkczJ 9⾻bHV=*  q<,EPȼ4ARmKus62`1~8UѪ¦9K}nj z\=B;ש*]8@@lcF+untp$9Up1賟jW=cHcof168HQe^e&ž̛Hx[`(" ah "B<5:N4q1Ny#lfjr<}oy[ҩAtE;`qY(:utA~]?ƻG7\sp7rUQhF?7Á 2Ü\s'm f"L19>P ͱюlI6t(`㎣үGy>J\dm5'e; 9( K8؆+ƍ_qxו6%mA?:-zi}6"'{4RSpaj; 43qxrw=^d>̃7]BL)`nxE#>M:c{{C#UnAn[0JWȃWL2_Lp;]ݩ ZރjV'přLo>uةmL(ln/h\ɏ.g){B]:(+i+9QMRЖqyI{?aCMn< cfU:,9$a{cLJv;-J՜<2CFuTKoO4~ֳ\(V8(t" ;H8Qx֤L+R}S^?{ 5}٬/gG|KW#]&RFjh"@N*U(x DyMϮ2qcK޲:˾Z L*Qs1W\, ̇>MgʆLnz#yܰ_:vjyd V>E w`>2Quvʣ8=jTD BFI]dnsDɜ֝,1Tw*\0b^4a,JPGR%? &~ÅYN cs#Ѣ$h&z\#h}V. ^2i[?ot)}=L (/IF}RwL}WgM\ T~4T ))Fk@ΆW_v`mz=^OCOL^pZSWRwf Luֵ< ) IQ:,5t~6e&:/*{e2 6뮔]mch0 *RXGG 4YC\U`pT&mA7\`zaukYg.)AU,טaHm%v@!7| R²hT'I[H,^/egO6ՍV$9 d^Eքюk{i=r+(y[w/,m*q_3YQ6ΧjP7&p& 7u3Fga@t0\u3'Ex<4D1P}] r8~,T^N|OQv^dZ̯wDy {ܮ8:gS=j W¯赏)[ͬ(r\ʖ:D6mW'9_FE3%!㨘:s&n!ҕ@@PUμꁬY5 *nА '2Ky1렎sw:fNIJ@.ԢݭElrWYV@V)RmmT@$Q V гn1ml R oBRpm*8RׅWoE؛1 X j`RƎF2L\O/EU4[KbSj}YGSr,њ1wyXjҪD pSytP穳H1S>) z-Z[E~'7SֲH,N#ӥ`|/"X %v,o9,8=K\iNciUywLE+ o Ej7?Y=.2%`ݱh݉#"-,^=1?h6c5ۃfżB{arQޤƁޝuo R}fjثʭ'a{qb;|ݱJ#(I!,\4؝os3Y4Ӿx!#IsE{_n+S9 rp ͬlX jh#1Q’Tsb`y\؈YGȢV h[ZNq+4ȅsNUk 0HwAj~hWaMo*(s8g9'xػQP0'8}7Pvz!Q$3cBZ!ON  ɕۭĤG3r_8}|[-uuxuG6I6HTn1VA?_bCF*Li'Z*{{Zf咿^ޘaƹ5 r5WG!=s_P鱗?łʘ[nѫ*~9hi(YߤDmܥCgc ]qc9ܸn:|d|h[QyuͱieU{We 59DAQ늶T SI!C3׫^5nm .=-,vƸ}^J3R٩6p&` NǯαFוuX` $]ngRנpUMUb8=3d ڙ3rb7sG`BS;Gګ?eU]]BRtj;i.xGkQ(HRx].u(#OL57,#=:}:lLClH* dm*aU]N9H`Z'#3{.l*=q,|m@3f/ʺp7+9}27XS.Bj]YFk%Y7oU(S<isΗӿn~J_{0Ǭ~@)uo!l:6MT0C6wVuu >: uW 7w0zI"MG!FقU i&pP9d?)+>/I2:OoyTR}YThdRv v}𝮴@gU(4unX*k樗 2Բ kыf@}Rt?Npv }Ӟo"8m`5twGb3ш臕JW:М&4(zusڜ$JqW7`*-EOcq.h[}ZOm %M[ߚʞ,t6 E[W?sX2)Q#c=NP Ң-S[$*M 9E{E 㟯^] *^}*&("eF?@繧nu+84ѦGYSܜ%9{V-SSzRT 0~E_J}a=!Ȭ[1zSR毥쑠J}39-V7jiɠ6Ių:;)7i q,gv"bk0^Yho>zMWEw 7U fq7^+Ud6k+ր: "zY?&i_YQ+ʯiC-'l@1d-gՌeXI%Gaꍨ6}L1)Ie:ut W[2,^ r ?hGcN[2@ݻj˲I2[M,2SӠ, KSD.R*w?9ҝzpE$N'lPakR9Cُ5%vU(?P§/~hWؠjAr9UyD\Ux}=]7m;(bʾfޗ}ߢ y>7IYWMm퇦0-u=B>ӷoPI>?w> tfrf>IX1 m ;SȒ]qb2K:,0 - `<N ^CisDvzS[;!"*>Xj fج /D vف[LϛS)Kb;vsg[DYofhFMs|XgX>Ў~ݴqJ^0c!PN Ѵg,2i=Œ-yGmۀ ժ<5\SX?}T:jh6{ (~C}q\qީ[E $$Rс*_ޕԍ^#[pA$Ibi^\3kDd@3y[w5I,wzZ^-MWXX?v'C*2H% ƮOBsa3krAiȋ P s`y2Xse2K'T^#Bcb5*ihXWnlJ H5e7'ʒ݀uSND xMA_kЛQ)J336TfV2Qrꈏp,vgZ֪(ɫFEQyhH¾-ޭ"KXNaxyR)}7e[l!3B>. fؙ8 x-FwlNq~ kH;xq3;Щ;^k(a =F?ZDK|"t:Xꆛ/c_ύHЍc.Q;Ts0g%1 G6gYYlF]Ӧ<|ZXN  Su`d+"}g7,{cqM3ͺjq|RU@c 8 eZ^|8Q{t;sU)`rn725EFtM|^N{?jVNZߡ{F"b*0 8))g۝_GCB%JWp *}-\zm4ɓKb2QZ;HfմC{ť0t,tk#w-Pt\yGo=!QeZe"m_Se`Wo#=)O>q&f:Su^QMJ ")wZb$B~VOtΩؔ& (*x> M-Ц)PryRalPuV;9gJvx8b CWj F*}Cpzbfx)++Ãs:?=[si@ JJ "Xixt ny=MfQQez^#\ &*C\ 1,Wz?KU,c_h⚼nfU4a10"L_ipfUۂJ+Eso׼.Z4z\R\Zbius_z>BRC¼ZYM9w?_˾SEBJ6~vr9s` $ˆ+8abltNe7mwo5pMCg|Kri\7c}V$ "u=\pE|ON2~yX_xB#7iMF,ǃGM5э}"0FI?\72 LBu#X.->ec>Oj|ԲXQЦ$=Xnfu1ͯJ~fR?n9@@[͛BL΋0Y y9R8tPlȲϴ4 ]Na^Ao3MccAoS.}8MZΌXu"`O51g2_ izZS@8 w3~?(7#(gջ)x[0 Uӵe,Ԩԅ#sB,uǸYl=l*2H臩[{zT<*2D:h]T)顆ucHJ˼+wyJM_ <\>׬ҩ-Ia(Trl.j~_le @qi'Ҧ{Nȯfjݑ9( QxigXC_rpWy>qӺ@(!t:!*TKVK dimQ,Ne,= R_1L4/UG's;V nu7#MkV^-Hӕ@M됨ŵ8oiNj ٧jcS׫glUiq3n&;Ihr,XV{Qy]_HA+&nUun(d6@PZ`Fz_BG)l J'u1)?#dB3`]*MUfaVS(THS!B㓵j yr;F=Pld 2g˨觖s_R?Lkymxctqݔ1`&ml.@ 5{dtP'qjSYdABN (7ՙBDw4wAGgWTlv@C]@ eZuivm!5\@fr/|\k&Ѷ&(dqN=psT٣zɖwfFhj𡚴6)? V){(gZSΏ{G;lϴdREAJZsSYü!8uE? w]Xzp; PIi7r.[?Bn2:t\/7٬S(*unqgpVGw Br+L'7?uƣ&/ZGPٹױ͸+Osv菫Sc'SU?]ۯK۱Hc\{T"N,B"HѸ2fPгqTV=ݑ5z82mU -4E8L۲,s6r=J2!Ljr3&)~>+}0gaɇK|<ՄLEK[6nZC34 LXf(f3j.SclDŽIYd7'G5oՓvcN|(-F N4?Pʁ}$ 5=pU b!Cw/?Ցcl =(z&D&T$3`~`AJoBep__u>7QjZR%`mov&>EDZWݥ/ ,t~Tl1n:aig{n]Nm`Ӥl3炫~Z=Gs捇X>9 Q!7;d˜:F٭VU*Aksm7KT8&f(k#VLz=8E䑭V_ַc$ !Nwߔ ;?bMwmT#Jg*4EK')%yۆձ?iYOZ^٣@|M;,t0n 7u\5U灣l6;97| 0ʻ5r}h)ҧo$zt<vVuL0S0h 9 ¨D75=ڼ8 E^!8# IfZ&wOi`'#w{|Σ{o֨\.7)yf񬊏AdL /[PZG{wzNLj"Ōaك,l8`6LBI\6tߩx3>OPguVN4=-}.BY,S5硪;|X36pǓyBWټ(c6/ؼ c$%&QZSoo%hXn4{'ԏ*U2hUkQ WϖΓ ]>*:3Nn0X]XaP2ܿ~AwFV7VM=+qnvT812X-5Hjqu"St½ A5Kj黬Q g@qVo !]N.F3N/I'7 eWW?\O/Y.M1ҟI;5zvJpsSᛟD\^uWͻl_(f83}+{۲C/n>K&% '5=t6][gEIbw"JRU I^d~ܸ!!Ni6*ۋz$l>WZ'eIkP#孬1f:lDƻ5O !AXx˯VKiY f@̒c:i dBRz^ +QFTU+I4\$M0d{lj{noA Uƕk5}=Ko)V-̷Δ ܗoǼUźLiUyc*Omre]T}:\bgp7rlS6ǴR`7gijHRT e WRo]Hv;Yyv*-R:!)Ǹ0r/jl9s9UQ>Fٯ zN:`))d*#I/yP*A`? 8E{L9GE?},gpdzЂ2f+&e* nC,"oF]0:ab 1L< ͐b5.CI 5@&)G\0 ~h &Ia=ȪmϽ+ay~zb23٬(ҺjvG2M^DI#2BoN2gVTxA{A#В#Ekъ4&4?yi(~$8'X{euW-~76ŧ5R W*8yPX-\ C?[rb#֬#2SbyK 4ӨȭC TAH̃4+Fڭʼn,͏na+Mfhh5 ~~#?YFcm]Լ4FY*q"i4ֺSC<84u. HzEt"44C!NDp(UJF5Go>vR[ tWFq\X SP72 nuI[V\HE:Hwg:O9\̪Tp`,|8o&8ErC0e(SLfc˳1Eߎ`JLrpK9]%ӷrى ˣ}q ztʯT*3fXC s}u۱!0#|S `;WB &RQ|@ɛ[8ccB2"^AwP!_7 l{Oi Bꭿo̧i1-P!?kWATT M׼{{-sgXMNI)Q{K/Dx_hU0Kf‡LV}"lFA/`1R#)pE3君PڼMZB-h&X{ @-]j]u7*!^ !aG3OMld P6,<#֨ә^~f z{P!6pti;!w_$fuk& ֞U p䋾JW D> = ,0M?Ad'yu#^I@F4ˡ8!:tnMΦѡ4fr|Tq}(Qau{W#^bPȸ)~I/TZ[`frMI`T,mu !)}(e-.{ )]6qQDN?&cP{Gdj*ٙ]-A;EI/k0F@cLaCh( IQ%:M=٢pêb@9l]&{{~5g oD?gi~l 2T 'd3e͏~ Y%RN}gwIIV ,⊛}rW.B9zF^ ڨ(.76hzcC WMLϟEV_"ć3RSeYʒV.ks-VJ~ i=*wmTmzToYYuP@e;e[]ᚺ}PMCZEnuk.χNTʽcx"$Cwԅկ>UC?qw#jNJkM=Z_HSZE':a֛ mȘu`- h@ExJʼwN +fBa٩]j&WdP j&F\.,NE M]nf D'*9E}\ Y=]ܺᄒ|g45G|!H QDCeAm&AKl߯չknu:<^si#믧iBom{ _'QfBq7]ҙ<4_FkAa&ܝ__"^{YPģ*0Nڇ~~=qk_ DV0ULiUWNY |'8VGf7i>L~E6U_M-??d~{o2 Ӯa Uzmh*@f`TS+~V=]6Y6+1KcvQuc 8t:Z!㯍C we:>e9P:K@dSJ~*?\W,>uNF7#<\Q?Du7 Q D#(C<W cVG>STW3ڈ3чVbʹQ /h2o9Tҷ}^Y6Ycߠz)g8),ZsP ]jMFfQ:R: M.a/ϱWpU|I} TeP%U _{ԫ:3E?2=?W'%$d-q5w57bFl OIϮ} vB75̻IMz+R\W&Lp Ua  0ejlSD [ Z"#~¾^% 3z*K:ʷty^&vYqڡjD#̾MM&-,3^*zuzV?ofm?b2jՁ8 SW' V Q1ȭhP!_7W uNJG+quFj-13}MD2m킞@*n̢fӜ.ʼ@t^iReI4g؏-&R 8"cap6k̪&Cw^7c c6fs%ɚ&D@D)&O#3sENso i}3[}PҺ4')Vtddª̩<}$\)b\S='Hc^Kt9y]o{̭[9z~M.Ϻj'?RϲK겎: ѽÆyt}r^Է)n5S|=aQCwP?a8a_oSw?}Wwq@)z}^Q7괫 \[I-A핁wT׍%|c4:rQ)W1t*+UWDw(k捁uvیj d5̳EB7RU.vC:%?~ʲ*ԫ)Y ŵZZr;o(`ÊW QQm^ *T#owY#JayCE[m52׿6F]k_ QnvZs?xkԓ M҉FŤrx7*5',<\7?F+* 3tӃ2f׼TVfqsr7z<kjP5;- z ?AS(*y[CZ݌4XɏKNl0<?~%`h%kTܚn`6x#ԇ >g?,/}_B3 ksRz[_k߫ 2p>kzVMvJydE**KƼG lJ n﷯Gq ĄUf@zmyc&ZǰL5 $x br \g2ݚz*Z}pp[vUni>G80zZ7yDsD<j"Lky6O,>~6yeS(,,m+qaxne0?@sp}t}g]rj|WV_~&T]ݮY#_p7H ʨn<^we?2r4TYL((RΗ&ϊ>+ge#z>w:Z:wpӴ=31,SQxPpv58V-\?Aη`UdrG1N }dk_+&u&cZX=FغS 7UQ7+NT+CF6I>#o5hF-Ye5Fo y%|_u^HQLo0!*o+KJϗ^]c^-]E \>^O?-##Qls?=l-uDW1X L  <;Rna[P 04V#!Go 0]O=!TL77cUA(( %Л:7yCd %6=yCgUn F`jA !A:`(:۶0cg19CMb_!:>/ǫ hv6IC7uՇh9Oxաg؍~_l"l!g{q7q-6dyMVgBq+?M?mk8`82P-0*myW [a&t}}N򤄗TPP9sޝv(^OOfZԀ4T-hNTJE]6z\_* v\s Q?|tZU&Z*깅ij {")l#mcaM#/`R[0sze[}Cszj\uփ*~Tv ]yզUŗ~B K[c]1w1]E!wj9IbŞu&jư>[|cC:zMC'׼3Z,k lQ u{N#6ɭ'W"2eI#P¸^٩)UW8h3ʀz=zT㗗{>.?Yk7 gix @Y<00AXeD(ŽcܧW^)' ʹF-)f| ) A25 ?ֱtFRuXDGCITFb|wC e*uZGחdu3ZtQc U~$qo%S ݙZHg1"65Oa9#iV<-DAWښAtҚf#hf]MUҪJץʹ]i9KmH>wVN|x SDp)|} X%s#+q۩D%S4;n.h~taF>w.木J?\da?<1Xe'nRpzTuYa:&Je|#XBw?ޔ>ky5K.pQ/5qeR؇᡾Xqs@!/ TRf*2q}0'驼ivƐQǏp^B/`q%嚢*(xFhYW7NVLs;?Z'/|dO xr]**(>Pa>E??.=}TZYoé7=C'g.3̺ؔ{D\ߠSκ(/@7b3FݍNﻩ|$jz=%"/[ CMdLpA鹍ҚF=Ğp3\UX>c%˒58X5:ﳊ #cvֹEwR,->-44~y,^/TlT:^S_FX%*7-&ʧWgt~ {az\J_wھ= T8njiy *vZܳWUmW^:07*GiVpb1u.(!kk Dv5${C}GKEnifx *@CGڪTRm#ۙ*n"|n)d<*1<~mhuuA2|fʧ,diWARi^Dxb-mc Su(iZ^SS^6qeWm>L8J?קbh#h(t}LI"Ln_#fUgM gQ M R@ +Kt +zۆgYכ`Cߦme= +՞\U*(O>N]Wq Xc`{k>8/PiUm%)Rע@pX'jǏ&-k'ʋд\ڎ oLv5EZ+7X6+%C~mϯ|ߨ0̺n!9nԨzi(\4oy|qEᷭMKtr>Po׶cjcs e7(YI=eY Dym7/amiԜ"ZF%$%r(Q DmX[!gf~MV_J՟i(xΌ`r4ȭQ|eخHN9?*2$kx37jKT!=ô"k~7,+S"fVEk%2s1zvYa?86,zM ZJH4-uuzmӷV@Gܩ۲&a^{G:Z'E1@{2!:˩ktxy2n:D}a<5oRH[N,Rt4fզ"p͈ qݢ'b߶nӑM ,Wc Q¤zNU]֘VbDnLiY++LhvC8QCAȳ+kOQzdy :;B_hx{l9i"Y?ߙ.՗jlC<"_SyXϺkDf *_oo@v)ͤ[S;{&W IunT0P6|jN#;a4Ek"?:|e@uQ+{h~ Ѕ{r+1cP$T7x+*g "+ax_?okᣎ<|ix^ fuF4/ÖaU :#FF#ځϚmk#܆Ѓ!K4Bխ=#Y^mt1aD#lʘ"C8&O?u)ţ_4 nb1):@ۖm 6' TNnuk7&\[Xq"hSڭJMVHۨ+f ۃ_kkC6rG~kJXhDp? n.!sTWy{GC%7 w)R,KvΥM4(>m-jfO볈9[4b̺>_ZcTTRE} en{K 2F0|Qh30Ljzd/2\*įt Nak |^AwwSq2Cw4ZQ('_vqK=׼v:3wNAW$b;u^_ʔLa%3$"|1Iα0)Bx)nܢXv>:#2?|3S:Ep.rCoE15 ?6/JUm(4E\шU uWkLCu?;a,;:h&U`jaWe%Q5WW|$K n2ͯ"c`4Pi401q;N, ^ BR-jRE.o_'T<Q|cz>~5wSs쪟*)z_ kNsE9)ˇ^L3R xDT{ xZe8tOC%,>,MA(fW'o^!9 ˠb욃^G{Syz%%nd5]S==w?VMԺmux/Ԩ7s^kRoҏ[ݙH~:B_l>8ثWJKaU)fLJ!KDϹe)oͰ(5dnE :LU1TfCv.ۣBZn?["Uc4chHlP$`Qcġ7~S3:^\8gs^ꢖ=Uz8}Zn>V塼d@I܎#|avCDr IS*U*)2/&!RgtR*Uڛ2bJ. M{11{Tzŋ4'Ո1N kBWizn\/NEc0\6!޺\Mjbgw7S Uٕ^ZgeQi"K&|v j%!847CXUcG瀴[Yq QYTn^;0~/WW#[Nƍ֦ KvK2F.?ow:x1BaRe{õn5sni6 %gu,V2%7%p[Q +oaգBΙ"x'̙kOdW [n=`bjz ħf p؍Nk >u@f3$jV>FUȐ@zΧ`~2Ic7ۥ\ =f~3nt=4v<첪Xcg9@b#cg3g:8>;dh(zKE]?!  }'`ehE|ܖE܀9ÞtPT@Xx Nw 0@w_zx63cD5![mlҺݭ0os5SI7hbVJ/5liK6gMTwJtD;vXyaKb6+ԲMVGma䍩n=M5rYsk]P;ۥAq{}k|׷Oߝ͸ٷޯz~{>B]d)NyCzf1j rZ1Ki~|A5׋N 't_DjL^";t%HGV,K5T64UW}_$1U܄ 3{,n/.zhu)tM5NT9/:r; c ƲC#zN/saκBG2Ԙ:ق df/gòn{Wީڍ ˱(Ms|e3v]Ӿʂ%Na PgIzX@4Tpχ: Kw=dOvvPCծyZo +L;5LXzu#"!HV]cW̉PY"O4QFM6Y+? 386ZF WlDyTT#7Ge i tZIg*$a=^g*cErq nڟNl?DC昤ߍ0''\qDGߪDiax^P]r:ul6:("t*jT1.5Չlz7*Uዮؤ:VU CpYmGVfXE'[aX &<\/RT-]PE0I]~E}k;=~=]xSHiecZvУ5cZ}ho7~Qj`D=Za #ޣ7g>e:0 LtxEiTe؉7_ϗZi6t/@|s-l{56]s[mxmE7PQAAZi6Q, 3k6CnB,BRљO?MGj==ZRpڈh^!2fhK5Dz{?]xhh4W^djf3/E/k!:0<~f\*Z wLHeƢE152Dmmڢ5O)M,d u~+GtYo5LGD`d)*OVoy3X<6{ۆ~ъ/?aQy60Ժi6HWE_zTz+uP׏:BT u揧JOsa֛~lzmެ~T[^+j-Wv=꤭P*mR ݎBOlbu GoS+U2X%sv+Fڨ BaRU6xZo7[ eMFW1{LW 側Tꄫ>i:zE5X;鐺`@7~GXlϕXq}~Upu3U5Ti 'dA1>욶4+萵.,:ę'ȸ nQrV0s'fds3r:XP0iGu7頫\\@_Qě闒q<ح8Cz@}3p$CE)`5CzU놨`Uk3Yl2'rrC nO\aA!^٪M7<%1u!cKK_@FU2#(1{>t:Tކ˦Ӂj_ XѤBW3OvJyKݏ13*/\:<;0] G5(4`y|sRꞻUQ33"MU39JW-άʫya֊ò/6X`( :eXXx~㯭Ǩ["PAȻUAq|z/fXDKgw+!,H:_RHeY g'7Vu^T?<7:=Udlsg4沼˳|clXU#؍TR"-="ѨPRyBvO߂^0[+_^(|k[mn9*,yB#^fW`rUӳPZ{(+s38{ =.΄mђMvFc/vS5+oZJw',%ժQ^z+]_Q8ݭu2Czt̠aۮIңm c[R<FJ Z*Hj"Tm(PN_h Z}D`.]; fhװ:<% {/"Tql[Y}&WϒY'R5~r=;YZ0YGVG }{xP>>Ndg]ܚ؏umܧ<v0\Ҧ[UU.k]7c9DLW4.*bڧ&jȇ%xVġ{|ֳުͩaa.u|7iir+9l% 5U׶ SuMKS 8j:'q1/4p߯o*L= ,%Ҍ_y3NM,fO%GcRHBeZ[+\JK{QM„Yw곟YplQO>*)k73 GJ}&tf)QD+Z1?7 Z:`}y VOa}oq{xQT5SQ^cfZqILE*2CUwP&-Œ4u݂ G_8o4)*I2G7n닲)^A"FK>ݗPDe^]jx ^T(@6c-4-Pt&M#jK+4Ѓ1Z\Pxji_Qnڣyw?|H]TS`v3XWPG|5`Tӂ&E} _iǢ/hz&Bx_L6cRU˴ .foPa@wHu/pNXYEtJf0~ ,Ubb]kU.5BO\s_j –VUf7ѪL44uvقj:|4cz歷U)-SM\5]!Ã5UQ+#aER9zLez-wM}ׯ3Tp+ Nuz;;]/FHyZ&efM]^_ȟ.M.k 54%AQz6ccveݗE)VE,rd`Ek᪲ȭBdtL=Lмlp?`!q o䇾rG56 ѕo/j) PŠZ`S[tq]b˲MYo'Uеl!G<Foqt_sR1ǂ3{\Mf]g?[$堘 &E-h3N_Z@,Vi8XLjM\aTnp96)ڠ>ܿU+TVΚRKd:"XFaHZe膝ȅ߆h/^-8T #R3>aZUWS3\]s"ԃdn(z1s`-r6\Ǣ3׼6uV@ö~dT0eg֭͏YUv;96*Ƙ=o;j6SMn!Re55i5궯]ؠxVuɊuc1>q cqd*3wdgTS  JbXisF:Y[sN|U9=1WkYM9;0i$]o*ձPֻ MΑ2kS+KE=Ո-&~UraΪL5hF@աwE36 ڣUyv1t}wKбdC{85rL{ۅL̲[+-6&OFց] kchhB*w_/uMNGkP|xM<c|al)`^4}@5 UqUՀnxbq?Wݴ-bޜ峰J6|Tьv: *t]mҶN#]ЍhY͝"ThO|&Q¶/KbŮ7MwQN27({GW~c%hPgQv?TD:g|ƶ~EXLtFZ:zUl}92 e(eZtӼ͙igp#!oJ,"85;μG<12Uzj2aX5ZɍC*쨨7_txoF o !.@fzys%V 3xUÂ)^#a316d~y)hIGIbtUYښEI|8!2wuxÂRU ꤙ)Wĩ@R9xN;~]3~A5Y?:-u ϋ~ӯGpoCWN6 Ɉ8wiF&L7B$~SڻҠX唕YSSHQFf|@y).FPrA;ߍyl{gXg]Bq})?յ?JUAQ`G̓kڎfQ&[l|m2յ9ZntZC l4L[@GXcsŸGѸ̂ 5?+d.EV1q q]k{bbcxS̲}0?<˴ۏ߁85oEWG55ɪRnؔcu[];n!U]sg(W]{9:Bfv[=b+UR&!^eyܽ`b܊/ޤ<oUC}qgP*TcՋ)>=4U&<\QW:e5ǺcQu#LKlAw +i3"e4,Xl3F.I|zLnz}7G;:խ {4YM89oL51i~:ǡZ(`AnU]V`;N2lnUz?kPؔ{Sf^;ˋqT}MEgayƶ]U nl^},2g_Hq;ϢLTedx»FeHKa;p74jۗ7\uvP-o:u:ۆbB1ι4gn´ȚX0;:n&$!jksaofE[Tڬd7("Dx͊6t}MIwч)O)xQÜU>ƹNiԩ%-̪[Yu)ۤ_:\*Әj"G#l- U*c5z|)>+J< t0LS״/_ X{}~ݏoxw)\r j:o%fW 2,VP޿;g~뺺sPP˂]p alQЊ]ZqqGB?vCrꞦ{*AYGig"ĢJ0&PҠ-?s7֙Lh uCYR9VɺV|)J_-F5橛_Í) {:a~7V4KnW_>6᪻D#+)VTŢSmj:eL)D5€ yY_[:_~?P c0^w9n[P |(\U~ :u[%( RA663QS%_ƩAgQm6)xbV<%rGVX__ dsnw]퀟oǁ5р5UP{vSYpeZS^v}iwW>s;hj&xA9 QYǚS3RyrI9]H e$E~7-—z Sz:kյfUIdU:K32WʟyUvťf*"FV&w5|x~fPe5cT߶%MF\*b +.KlB8a^mʲIvvyN h{q06MyΛzT들*bRU_g\k˨#s[ @^m_ۨ4qQ.|1xs@ v u:OM@EMH!njJM窫HAB'S9-hqnezf%D,\es6l#k쩢K\O&Qhy5-uoR_TeYvjp9­WӡG׍Xۯ5z<e3F'gz;mCO4Cv|㡘 0JS6cE:1@xT$k3sHGe-1EU88&Q)njt*"o &,S"矷.Gj(uҚ|7o&ʶ[0s*Kur WcwI4]LFz<-0MCV ^}y,!bA%l*6ZSG4;n;+F:6Lن@8UT?#4]?Nѫ44qe^j2uRD#.Qc&]wFԳMo\JP\G0hGXgXT4Kt>!j`-<:^--PEDW9QͳρK(.͡9xy~ߏti|=5u]4)SqTؐ%/ҳ$3_5qqщܗeP &$`*=46ss"5"UVՓ9kreiߺt8qD?.KUyp5}7!1No]3Aք(7qS?I^m5@0m3*mڂYU,C<:.tH9S}Xꚤ2bz%锌n 1|Xun[V(2j\]ߥM&mͯE0 ":?c}\UMdPu6`tzMM'b>h>5OmT]|}Fw5n|ݘ dXTHxj.s}YDWT'-o0qqPlMJjR1aZ撚f%ADzeEzǮmX%UHp>ɬ6<8u8^ԭ|0GKE)@/!OZ!^SS߄^c;"'__kY6gj\G+yںͭ h*"# tuPT;fzNbr?ʭ7]&PA񯫛kvVUh [ DVD`'6*n UרUmK&u0gFP\|-C TC:`H1/;FUfjc>=H́ %%*0a/)Y&X!aքF'ޡz k$F#sSRfEY٥!ծSݐ\OcFbݔm`K( ׂ 0-S2;kJ P7Mb~1=ҶSh>}⚗);&f uV.L3]1?˂:YU n{ lס%L@+ "RN*/P`^k50:+P~4ypw V'CNŪMSulCp=Vet<7.cfIQlW|~:H?׆ݔ$94*ooewMod)hM?:\Ȇfj貏B}0PdLx`V^c߾1gc1 8-xE&ȷ4嵞w(+؍Бd\ĞV s i(۾DT\t0 +AUY&P*g h)0לQ#DzJ`$+c^^=ŦNR-h UuH6-,Q̯j/zGX xv_*j#u7i&5(?4mؤJ쌭Aʊz3ie1˶TTKϏ"(:9x[ec:,vc#WRV+7:}S7-^ۉG/O/04kI6*;領Gpk k>76'KްOUXBh~>|!HD_y"4z, [[M 8RsJuvh7_tiv5;;uƻlcѰtmT}^+ޕ.kd8Qz T59a!=zZ]^mn_"eb69h7B5p8-Rbf9UMFAVY7TC5~ƱF`i:(\z!٥~lJ! -?tɷኹlO_s܎:<[ӇmMѮ[l죄. $E--`#fIQ,lM$4)=|]Il@l&԰} ${o6F5uVϽI1>?mk/ØZ`>/n= t;R%efxf%:8g~a@ʼn3׏ziQafZC>։_\Dta߃_ ֭tcX{ʢɂ%sX*/?{vaKL}ZeƗKZshјKolꦧf~+kCv~bkɤ  -لZ:i:Y޿Vt_$R~lE2M^8TO8t'3OfĴ5.r|`cC4n5uUz*KJ5{{ӑ-TUuf&|}}Py|ܼмNؿL0 %4Ҫt=S9\9a"Yi"̞cgc_:Y_0~~~nLƏ;IJyuKU_G`ц8_/إ5׬YugpA^_-C;PW.>M- !<˛~%Ѵ~M}?ghZN8h̼t{%^U3Xm4pcu;%i=kAIH3}9HOzМzA8~LmT.(Ufy [g:QUG>h]7ƸM@&M)4X1~0淪5qдaƭ <3eTQOJSӉu&T]lZ_YPfWs]Z5c4Z}ٰ@-QS,lݥE=5 2Bg43kX盁1{]EqTT w0+BBDz+'7}ee}(|ai+PJnZű^z fM9AüF{cmBp:B*(Km`L8*M>z VdMB^W?[0+ƗNfhc7Cq2k,jI+x@u֣ާ4yH,C8ۿGUkjַM#CokT~'̽u;poLY"K_8@đڮ8#`UijP4s7)vApea<x7ڮ\MPbmp%q0 9NV (Xŕ[y~p{б 2L sWs)$*rL2?#V`Ԉ+SqZmmrDWd9ꎱIp(W#U=6}zyTw{TTMc,w/1z(뢌ZIaZ )~RP9  /g3U!y]Wu趫XEUFz[I?WA1ݼ1/VWK3%e?B# ʗen $߫_-/\.ȹjPh (9Ĭ< 2Ϸ]+cgt`ƺ*\oH`/PR=LK?@,3>̭a]= $2x=0:Ӿ(z i\n K H:5SEFUF c&ZOlRq7;nۮ*Lkptq3*{Z@tO{)*OJ/ daQS7"5{8c^hs/tPS8O! H.n>ָxzWvuJ1L8J\l,tums Ñ1Jw* Q+wV)LJtC.7 9%k7 5֏8a!b[} Mm0+G8*8J㊷:JbQd6ng n,zynʼn &5տڒf$NzU_fЍErV'Uȴ됦Jt<k3U M4oﺡxʃ2K!ҹ-Ufu:Љ"ee/(f"4D΄\%Uۛx]9;rWɤK,: Q| #:baE8(,pS]/S^CNEX*Ym<ؽ[~? cn[LH>4}&gi 4Fs`1=W6tq=pF B LPq+X,1oW(X@AQnǽ5SaZপCb39DtS5KAV\oSͼƉ''Cc+kvLT;*@L~?emeyPܺ?Rظ/ᐶa6iony^CتfTQWh8Кh YDIhy59Cخ˹3vɹq`kwSa eݚq0FKm@S{rl&E~]c$CtD}SA ;SdmsIqt]]/~ P7hojӊIbmSd*akР*(KL3[軬!jD+96hjjƈ~"ll*hqml.Xs:攣YE &2{]YA{Swv_8_[?pCSN/읭a&Pڌ/|~w ly}>]w__#Ȋ7KyG塪 A7_<:jfo`İ=wI+(MsHM9 ߍbó{ખ:Ň3?z-`ȈzlFTxtoYUbZY0VL‚gPlʛ gAJSotԸmPPl6 3z޶ G&Aȵ2zSQXsbX#Kߵw} p1˦l#AS{ALu/uk6yh6l6ƭP8&6Q7hS0Z͵82cGbqQZTcP+jbECJ) ݂ RXѾE79Vn6XPZܦ^c:"5|Yo8\.2[Y#{`BoQFl_1 ZykO3ێ+8@p ZܡO{d9ٺLPi6~}.t\se&>>Y-ͪ-+%4|]שKk0Ժ6-}YY* 20&y=zX1WU]| &hfi΃5fsL4^PuLDaO g%{,wq}6!#wc^A@lFP~?ӡBG&L*,G;o7Λ3w@sOWX( J6 ER>9v3_i9:\+E4=}4hrU& JQLf `Bҩ $k;52Z6WQXB}~ЩFLj c:Aͱ2LTLt~x\x4#JT4MRAFh^~oϮ~~WWPI_j==s)me~}y\Ps`Ei&PoQ0)X>먓=suUy~e]C_Xcv[K< 6G-ڔ,m/67f G?hGtߏnns{_j H+F_s6"7 z W&09tXn(,A$ӷ=8>Dw!k/7\o./JÕ *tt0t/}r=LQ f^mmM71qZQh xi]\N~v~ܗc* qS=jl=klpMih20uS:&m3ӑyLoFח.vn6AYm𤃹OٽҋD]imt3%NFe8}2%hѤ-OKiv{_+OM)FFWQ 8הt`ރزi?7wݧ6}nJ06'Q)UIڼ~`zpI16=~RMR.n@vF C : ! D?~C80Ns1wy≯W_ׇ93%׶V^eXBϭ&ߘ?|Dc ܗiPD44Č}͓ar<žBƮ$5*]Q_D!UgI4W*+[5*QUbt * k@=5ykzl}mn[C|=:!;tHֹe;(8'`0KJ JJ {4 t-ALŘz t6RRe6Q@+7}uͻ^ VO 3\&6t`d:Vu 6mc'5^5usaFϴ]gvc! wz>is^=,_0uX(5dp{( Q1YF:V:nOz~oϯו\$o$swʻ&EXӪm`p,lt< YWZֱ[x|ܖ~GSmql}ݍgĊk5tcQ4"zoba erP0sD]N n[Ǧy_T}&"$R)l} &iziQl-"#°)i+eWn?_oھP«Ura`NX(td4IX!Ԙ1AGk=t*1Ip@nyzx+jSWWXTtMyivb= e6C:P@+[92aC^׼Fjm >:>.lS(X$mfޢ?jX=g !ԍxM-3]skK `z+ dN +$o9 1MGNˈɩM5@Z% #9t8Q̭xB_"M9b\%aOU)tHu)Mv/L`du[c- N ZHgBT18w>45$j1/6e{d}bkܟFAҥFO٪&]/3@o֌=qo_F-1mkxKRT<^I05gm7؋BɕL9 KqDaȒ+**GIr5/~79p:U/'^[Xz 8cך!88_`64 0ٻҴtCl?ld|!\7 dоA;7Wa]=!p^n[n2e 4Vyx6y_f>XvGlޫIMeIf2m+A!BRJ_࠮Ѫ7 -o,i&U!11bWc1U,J.^!q:iacA{{3Рjf96&]f".6MqB# Ȯdo>*]A+U(b2c\w\ }g:ĕhTfE\_FcTTe0{S%4(5<ѩx5:#vdYOA\%DY{Tp0v%6Ij@1nx+#OdRCs_Y>W!4Q5.jFgfjv<5~a5~Qo.u$#5 <ܥY}rwJجOvkNPV֘$4WS7׼y1b-D{Vތ8#c `>YP"oW`; , צӻuyUi.v%C@\lGlMol UJq v6>*M@zya[SY}tNUwuލq~>i>ٿsfK uFom:sڙW\\/6(q&Lt*6QIg0:ݲB{ך-^C?Xޅ9OPB_ZmN0} uW4# XZ ԔS[ Nɛi>V4yuIDAT|TdzUD żÄ/m|VC/.2Uo;+A`7콹q9m# Ԕ.:{(\uP$6+>>UHS!7K[_ P…!;++:0PΆ:V]' FǏnqʘ5 =o֊6 )p4CymR0v7.1Z^!jKF^@kaOEU/ąT0UGFElauބrͲ߮ ,EOzEZ8}LuZ͂~t~!BZ%3׬#OfQy޷IAjbGbsSp%ۺs4wVN Uݢ2ptmn{/he &jnj5>@=|7 m"3CԵ-[2##7kYsϔvMndg6o /̾z%M[c7?ۣ4uyMlW6%Dt44s\W\_{`e:&f9ʂNb'=SS.xl5(ھ*8C-0vT&q ]a.`^z^o%,Q$C\gbEɽRUun`wiqM%.5 oP= EYlqs[H˹.WY\i!J5>Kmn{Ź*ϱnud>AR1Y"u-T@ ]NaրEﱴ#av`wkkak²ڡÂ}Wl\iXvK޴I>&BS M)Uk̦/e%M]ܔW W˿x 1v^F3UR~aH1I[i[gz1ҁkɥ"v&=aowc d0 (bEt{ %4BɠETumb ̞y͘5-U~+7鳽 jk'1qgboa2z\nm@4PLiEXe#%*7cG|>uەO:nuQһTU⬋X=@ '"fIC-G_y\9CNdds%i;Tⷡ8heF@=xv;FK0aV( 1p;<5n F)^u6 2j ]]E5e-`gHK*ur@W1Ynƌ6/~Q^֑diGX˯|>pͼo2rcVjgs|Ţylk&M6 ^mtcnfL[itә8˦GhuF=~pV@ DlrBZ==3<*/ !zB^F/AebZ?TDհkQ̆>0 T?LJ퍅ٖINߴNVhzt`mGU5#ߎCUAP<0 cK}Kը-錖WlbV+mpd 7Hs*ﷹ尲ˮ"@܆932@}G٬ % h,K9v f̟!qYt!|SwL4s]TvkUOg>Zxy懞dXSs; a7bKε(:S'idzmBEc5(,,‡#\|+ &UP̈ @3tw6"iLM=66ָB$*Ƣh%Ft0}sar,Rm^}Չ㹋1i0eA]\J)> cOHG9q yRԎr` bcTqc(f3!@^{꬯YNE! +>4vqWt^*&Ԧy\]n\n 1!lQMb3?qV O?^?$CB݄3vq!J ;M&kg-FΤ,th? VB's`T7Lr:ukf; )96։ (1q0,A՚٘.uYkf~A-ye: !bebQmiMpQ¥ jĘuzXo7FRh1bNB`Ywv^4xR[DZF:뮨`4N#)oA:~ H*$WCXƆ uBn~EaUgSAz~پ5TiEƦ^`O@ekR,~10n JU?x `f=v[qs|tmm/O _'D86Za::]Bs1mRCr 0]i l4;,ӗ_> _׊{#~yFg r-mxŷ-u1`@L/9—e`@Lz.ͱh^րCh ۝6Gϗl0=zD* Wc3b;\sdMf:4K e^DZ,y%~tdot-V3A|:z:txn^lѩʁ\H&k|'W)SQdl8}2&: nKl b/Z 3!閅,0Cv-t(.vi+}>n]wg=4aj<r‚ŹͳHI̾KZqڵ`CFzv*] вJU"~S/C7Ƹ p wDWYA+ `]ܶ3 ۖPj=NܱǬoc-$3GrFTVM~UHRYfHT"i"Vi 8N̜LvbR\Uhh)gYN6y{~fCd:빏QyN@7|@f3 ysJ$E_2Rc %9'%-IY* jlva+>6Sű]sFGܿӓ$M2o ܴhvp\:}Jm%עeӭf7uKoJ(TngcϜT :R6 8U˴f*`/Wԡ.I7VBHzE}ĝK0ge:HMLs5&mUW³-8/(>>s?m?BGP6a/'@s}V\CQ%.nD;*]؏%.gߴ'n2 T9b{%u"٦ jݶKGQF@ܲ͊d: vۅ`߷>7dæ/{ g&*r>նzmmZ*an^HYLmldᄓߠ}R&kE4 f">Stf43պ):qƫ桒+›MVBUIQ1EH]g>ֲ1,k{ Pu9`;ڽ2A`r^:sKlDd&Dc9&4WXטhW}Ϲ뤋j޸MYnH:^.|> g,jhCiW̚š8t|C% 6` ^9Eɍ=hۅf`ƕ6`T`5)B61ӄJ蔖iUl\乎JY!HV'&m̪.rw!0-[ ;YCN^ Qk#Jh\{6mYuJUU{hcψE1H*`EޗN+>CM/0X ma ǺoԁUWPBg,xn]$(J*lڅUzAo}J[" a`c]y7ť _u󜬿Nk4e3316 &ciܛE^"yhM~@)B}};~<ܫ*n=ZSapl}65,e6(ؙ7R&qoZ\Td+/dA)ݘ<9dBm%wZ Y0W=˯<{qC6NZZZ(|.t(<uHA쩐pm)hn6S$Ep udHwhЌOYGڦ]riz7nti&*IvǘmLOeIYioR~M %R9)ju&})>/2)X|.oMI w}@^].K9mGoEePCVY]HAS( :k CjU.kxLGYz^ x/Ē}_Pg^GO2d-TDPܩjkߺdE_lS5>oret(8 >OAq:}Ӣn4H&e{PfT~*Js'8ؖzýQeqWS?>icOQKz6&.آLO]m3C$ yZ[:{Y9o[Ia5qZt84 + ʉ :%V *V~M-KRa,"[{1JKE0t '%ׇڌKi{eo\{F]yxz6WPy#g1I)M;!K;:]i^?{=Sn?iS&l74 q9QzBhVp0q>64~i$hJWeOQY۸ZMh.xIZR[֙iz(_8њ6u;cp4na?=8akZक़yz,f-ݣU 73X"̎8z#ih{K=h뵿a`յh?RXFܺzzk׎m*t͗N˶u{U<6;y0p/%\MZt&H:X>E1l*m0mC;gÔUi_+jl0E1Ы] TveҦb:)ZXDei”3#"@>gtk:{b*Ɯn k9t 튩i k(f%_[0Knw9Ƃ? }Qf:旫^#at@SUecA荚QջTWsO) "ïsPuZ6ɻjY M4K^q?k)f֣-0{s]nz.%YBw.,'s|T_XNЙY[<2; fUTu> OFg}seT(P_k/#j5SOMS]/(0YQfcr+= Vx=6~f5n rAAלa -)*AO$#$ $U*'P?N'dzG*R'ߛP4a m;,ŲH3cֺ?p?@}<[h1VKiS׵qejX.@I1ًj.C`m.͊ Ns1<7[3j J:i0_CoO2[Y`>+/Kl3yFҌ])YbyA|gE[$nX_DHn9JnBs͛NNa< ()G[+ގ:Bxzѳ':dzU8T4U``Z}ͅKSYuc}ݭSq恦3vpe:  ShiRA(w{"Mc ;sUʧp{Z"NXqw/`ѯKΎ*5J)ͧLE3^2 ;|P(& BkQp>~U>mq*IK9|ya'TY#7&}(iM~B +Egx \{\/&}M@NclNj3:!Z gѫ{UzvudPg1iU٢4T2|?+]Y12SA>諸3QeΛ؎ H` ʞK0D tQƴ Q0qgf({YYI1#gylg`8֟CN_UD{CB|GBT 2=y^1vQJv٘cm Gh(bF@TPVΪS6abj!=ŪԜ:BIHH7hWCnK mVqajTYe0Q!ηS׭i>Vیl+t6뼝'ޝ"QـW`Vy@=0d?us/-@_Bk>iT\9pՕqUAW#* !6;?nztLvYw{gI{zבN]mϨBп7p! 3 cN&D}(ކ2Z4 AF'I+d-SydUOai8*zt-[Q_U@ 8PWs Tv_ߞ۶&~Fz)›76q`g gMfӡRS]^OB=*uGđӪWl1c䅜u7;XnȕR0NÔ_B,+?;Q515 $v&G}O[N/!(i]]3-_+DQ9UO{]H'd'~ "2[BX_Dxq-yrjS :Wx_GP(l{XOD8\9H !ln󈚅hk ;-Zi=Pp/}5K@+=Ƭ( ''gX4iJuW|MX7KH [4GC@]-3uCoJ{hPUև?3}a֚q݂8T"ār PM ( 2) QY!?uU@ϠX%9jݢm.G~DE2?{eǾ<瀲Dn?ǖcl矇y.u0#oVrцk{\Qela[0gK{<&mdu*DAV"`,36SNcY/зxZ_c%(0hJkbRu3ca8>2ŦO{|ƇcZJ=~ìl-3sm3vҽw{̲e߈@iOރلFCmr#`0\x UxrBzZ~ιxؕ(51rAVtB3fOay7q̫:w:þ6P RьA_>3R9T Fs=OAZ7 !7%dhl/trQḡ45P(-S7=Tb3,^GwgԣJ̛91*TYE뒲r_Iuqesѫ ξjx'Cy_fHhh?v.ű[FsZ d ގ+K[t#,BgI6̀ц>ֳ8q◦Oi~~}l ._ztbl&? %{RVWH> "(/עΒļNrcx/0왈͎S%TZ:- yű6'( 3F#G1* $?nz\<$*ooUؚ-WMWv5P*xPbYz*36+Ԑv#gc]Oj2zJ^ku|< {.w\upxͲw:|g75:u=T@z;sPqUZ=?foi 8bD ܧQ xk> ~* cf w#_kvϝNAXȲ3H'[> }1\pBz"uJAgVD]UAB0)bOp`xΈ_xXgmu[9l7l_%<|hU(T%4P;fۏƶ_5ᵷFIЧQv$p~*@7 |Io\5E2&(>+^UcQNWnfY,/B ϺeCvbM&M=+]ktXcѓqx,l\F^NeS1QBmeҮ 2#&] YrԬYSCp/*8guz md]MpT%؇Z?47`VR8}w:[I!~_ (v*JmZ~bA퍟]ci+qQ34#Ǔ(٨k ˈIȠ?3-\sga 1ʮMNQLLÑ@aK4L"9%.=J-F Щz& /T\szf"f%ZF ='ًQQ6T^Y݁3 +mmZ/[0`#dةknN}Ky22hy ]6jZs$]oӋDTEC{m\ϯE rg5uGm- a;,ͭE1?aN#2jLA'tf&ktiL ֛by-{Uկ4 <ƕ.E86=,]=2r׾7iEw!aHKϘ>bY^&t/4B4B :wm ="&l0:wU.n0qefLΛY a*zzصμ;84]Qz6܇bhüA/$Իe! _ }/%3]azieu֑ˌ. +io2l1m$U_c]Q6uߎUƹ;OxU2U§p@*}:^cCplGP駫 ߮ #ܬ_'-ǝNDЃ/p٨]+joʐ v7KAz3":$hMu%}?87l;uIUM*0V$LBbS{]# (uTաR uNJTXEi'.9c3o3,)O6nF1I?./7t*3#nREϳ풼F/".RIS?"|!m}<wb)_%11ٙ6922ŮYˬ0z3(r֚g:*ɇ&KY3Vh6(ƞFHJt , rBN Q{Rx>@Q@oEQ6G-8W5wvUPi'mr65itTZZ/I"х:`DPͅ|v?Kqb$t{l "otuZ t}~nJ٭ۢ·\ncm$.o$~mJO[>kB )sn+^Vͧ>뷸EcѥƸr+ezL2BIۭ̍ Ϙ*dkHerILP)"`کiR=:i]_Y^,JJ;E-©Yۣ*)tTY$%E;K%E˸G5*/݁yWm4kQ?vowvW#SV_ BenŧǺf~g-qm!4юI!2TL4):K{f -Nj(QקȇEXzO y/t pu)Pg%bQ Cgd<3{ޢԻv'ehPhwItvI4)BokaO]")etƘS3!WYwC0BY03Vi`H=&[QG;7O/ވ/>I7~Ͳ˥Fo9QzP;c6#QJHl|b} M\_̕jM9T"C-/qlLQwe:,'F7gT17)P6\2<z@M9oq3->nUv(*(dhkНFI~DF #lU݇y">,d )MS[ITmw7ٸdo{ȓ`Bk`u=v57xaF!t(Vy3¿A.Tv= ̟#mmjBf427cXŝymF5&r0+j_C !CW6]rhzk6тTTB \ers=Q6W 8妢1%X=cPB_y^/7dY7̽mڂggUsK󝇀`mt&ļD c"1UAKP/|,i6#AѼLv^vi f&79iICse.Zqyq#k=xΒjLF˺J(az/gfݮ}C+y[1Eg8}VqPJbo5i9 SPZOe_rCBqv}S]vgQ;H)O1agմ׾ǖqse6+(fxWW: d)H;qF -/sLDICx$j[hH_Bk9c<ܙ&B_7Jw~ŞϿy졖M϶}&V᧖ #JU-?v*e<5-#^DhnM ;="'FQ\l?ŹܮxEukKJVJ1bRLtϕ~R/}>bWu850o"9wݱ Ǿk68­oc {=%f eG&˯JXA"}w>UԗڙD+D }Xk NI]N=fݬ",}\َ(`z.p;KDg9[J~:D{!? ?|onyB.xPP9؍?S (Ry* D61#ۄP-,@AI]hMeUꓣKLJ}oީ"t@6UّVSQLT(yl$1<3W72EĤN3wgK@]J4_P>ӦWMO|嬸a }T SVW~Ө8!ӳ@T)T\uRFˠOt#t_.ykzdIB; KoVk-]V8D5"ֿAiuG/WDcQySVrȑ?OLC >hPuwx \`zzBkzH{)Һ NТ_KMֽꎁ6;,7tW nE[_o6|y:M74޳If|0yBZI&.QϢdrX 3od>TBOy64 yN'f5[9JeBԪhɐ,f8;5^}BƻNuҮ/Yš/RF:y^6DPB x1JX^`R/!)Uɵfy?Q(gi)KkIę\W/XPYlGԙߊܵؿRn먨G1D*q\M̤?n-|:nE@jU].uSj/뾳;k_ b%I-PJ:S2GP/r5jƮ9u* ΍e?5Xr17YBܔw\)m3&.W'm@ ?|dNc s~N (SRUGg+`9u3?nĦ3Tg켳ڏ sã*pā)vk-˲ﳴ/l'?V&:ҕS`R>ჩ+?#vTG0i e5;cZFn~;hLO00cϢv'&1"0ʋ'RaFאZm[(F!ecpi"׾6Cs|{kSA|4KQP7bdn”0 僪Sͤ{)r={ڮc#nV9.y}nZʀ@dL?x?8}<,Z*Ϗσ~qDŽÅg/Xjɥ͸,|CE}U:K_;\4c:S9Cȏ(!Fׂo__UWg_eeQ1X@PVu;پf-?!W]`i\)x9 4|S)([׽}v4W >6_W) l$Uu`2lFRߚ޿DW辒l/^߼A"֘ ՑS)BU5n4TdE;)L jWݎ^Q{`t e΄+Cd̈DKY']/ w ,_VXV qKE)LȦS%C~>a}~}cfw0njIܭL]ts,u*կݵW]FTM+>V,:yÿĉ@CTf>}L`Kj/S-#԰j?-y09\Oؐǜzޣjg*5g: ̳҄BP3c qP)ۂ. L_=a\Q/+8]6S ~uqY65 m&Ec7)#a|%&-q_.gAOB2{&:XIȰu8?OtbH)pT7c_6Iݼi'-$ )_Pv㛡nY5fXjj쵿NbSǿ-Z#uNIbnSiW+os}~c=|i*ˠ˘tmzч&=)Bl0ʮd^];: 9 1 GMb>||J :LwmXW|Agj_[_bTW?#G!ub|(E*gWj(¶_Y CNU;v5| 6PMgGӽw4\(Pnt>&&ޏ['}^+BLo7߾+~s}Ϳ[p=W? G@! WUV9R{BD>Mן0̑m`x ?xCeYZBBhLvi<[֟i6̎fMs{^<$ym+/ƞC"bDžKd\WUهhꇱ,P@ḓƶҹ*U[@*Lzkik\Ul\}֧VRc6ehihnT3d]=}׏:ZMП|=h\!fJc'| `JJiHB2Aa쑠ПQ*J鳠RvФu ePSt{C%lp*o|;oz4UmUS4[pz}x3]4;ևVmV|8HXqЇ`qY/lσCwp½-spJ>r+[\P3"H.xZf}q|= g2J/d+7h"6F'gAU'fF-aubMoϟ=zVzBl0oD{;bX](#4FMя%)lSg9&TʀTȇ{תl<MR x¸>MYP-pYP>zWZ?r?t臺`e\~==ޥw뺪T:} -Ah嵊Je;2,,&* Pè7gȡ]ө\BrDwcK6z8N5z>W S=\$U]B,+5u@ԻC3.TVY)C>6&йI LR|CS8N~lkf[) sYTC3J'[k]:}VMtJ(F>\ 9U[̈́;!Yק֫V8@N-Zh3Rw1 .۾L:%Q2V_~-d!szng X ipGt-=8j6*14U1ǹ3qˊw[Zv>4[5<2.\gq5M/iST@FnY <9<sQ::qjV]ou@|-F!RmǗ4:avOaӈAx*:%2I4N`\QkeS+lu=}W?s NUE]—B%ӣ=J3‡.Ί̅Zsfwfӌ@@Te嵜dYvV"Ա,mNЮڃCYIHmzO璩qV 2*3}_j~ysM4L_\ d73$-} Ǟ05s(vJII mr41d.50M߿c^ixD.d}e|2au0rUkR&z[8n]TUW-.uRi8;E}]|wQ'Iy l3n>yzaC~Ȣ}T:>>Ÿ\L7- II%gW鲌`ZݙZ;%`\\^/F6e*g6&ˬDXU -ݴ^}f͊n#fm NWy+y;Vد.Qߞ(dnvSu_Bbxn(pWj&!Xɯ_DDr7z]H; ̾0t|̂n &veř+y7;P`%ͪ2$ح Np^74(e 0yO&͘PVͶ_ybjtoZRxfDWVuko/X+rVݽ+n casnUfOyp({^.v.J:=%]Kv\37vN3ŪaviJ~;AwHTu̖EdL-(U"tTlA9$qvJO6qϸZf@|1]u\K<|~ޗKڸ.gSʷi;$ `⍇ZӖINϔkMO])ק>pc咳`____3qu>\ځnF' &ȤSF%ּۊm̦qUgK8PT[ڏ> ~N:־wnrә-UFJ A#)a5\W7¾ j3]!ZY`8BvzX8d(U\`/M}]JgI^ϽB;z4&ܑ:N3"3S6oU)>Y WP<e% CQ6U}dXu;"zc6ϭks,T Hkh},>B0%^5S-X9- KdW"P&e^ eT׸Θ 5uV J(˫ZbJ/ԡ^_I]^Z̳94d~ sNO]۞~]f ݄Q7 ~BeAk}[0D$r^fzS*J6 bQǭ_ӜB/TumqFY\ ^՜CڇZ`zz~~{y> }u_܊Ha[pJ!X2bdT. '7=\&>5DC&q{A͘뚳k~ہZ )k .&Ǧf`F,L+T.֍g5>VaLw2 _p-w)SԲeszM (Uù&U}L%r&[;|Ru+<NX)}-˜%M_%axUO=cXH:[gslW@wJuIׂ]fJ{J_mTuu+ srbQyI _qK&qOv-By6 KWDNjz{mCki5|fv ՈBA<7s:IZUz! [9`7"U!{{!BL1>`< *f" [5״lwڼ(A-3վhƈʢWvǥbl"ޜ=Ǟu+|_* 6u\?€Dř@blޫNKz¹򹒬H<6RvK~3AQD:bOqo:$_#>/+'qO]h|(.TZQdfnʺ^ } UNR;v(Gy\O"*- ` W`7 s.Y'. <)XƆ@?$JƠ;5fc>΂BOm旔'ɡ¨Z!ݨO5wońiѵYwh?kY/Ag;/P#¿TEB/C2O1mpi!z7Y#:"r< ]y1'RrIfct~QiVHT8HxtC{ K {~oxRۏj<BF pя:Lw[V SBL*:Ki[&,bM(̪|17/RqPnrײ>A*a-AecĶ`5PM㋲oδ1%<V-J _su??,lBɉ_ϯyT"qt3]"6M1vfiLYu͹?vіtZe8 '~+|]C~W5]`^ +k2-QA0ma-j*\̱{v͵ͶQ[h#8p4ug@U[/2UEsSf)$54mXB5f0G_ /hԾ)g6!OzpDe̓+Uxsǂ-2y VYgʵI((JyC4|}T~?Fuv%;ʱ ۠P.¾>Gm[_sg6yh+Ǎ8ձ o0bQzF9 PUWS/:R}U9vS{Wb;Jx^UmG1_MYQ&8ЌY3[@kWж*sS,pTFKִm@̈́D^s E*$~3Y7tJ.+fyw:k_"kӈ-"[y)|.H6`8Y$*/1 Cn?^k dd:"<(#V7ԈK"{f=ԉM0坠MH@Q8FR˷zFGw%?#_*cjQ'qLNg };o~=! 8mP"صp(n)T$a0P$*o!251j`M+ƔY:V X_To zn_ ~dޘU멷y N!@u $bX ڿyi ͡}lH_`N]]Iu7T-m_OAgff;rÆ;o~, nc37cgګt#\`]XMrm]?T=͹Ag hrV-t̏jQ텀 2ԬRD;v٦D޼f3Hς P$?1-aAHZ,ˀ=w_xsfЭ*._Pc9$ahT `5ף~nNzF~iECD k乊/g?U9VABO ]Cɍ\цd/gNyA)U__X vͿ·(GH@&+ݾː|'0)5J> ]sr+kH{E3WOfű)g0~@H^T j5j卺@t2hl*hB̸ P,1*:B`$]I˺#W(|ER*ZABbr&0d b.ue N݂lOoHN]oP5%UJ.Xiޒ="|nOoݙ=b9cypg n=mQ)霹ޣ#}oew]Ϻ2Yc~<Qsæ[ E#x#uBkzH5Ux?`Cr{Hg@ƒ-](Qhg"D5f(K' }zul:&|݁Wt-?[00{ɺ1)֙B jQS:Y^XP*Pn`Tٱ*͹{ߖUez$h+,醘Ow +vJ]t 4o^P|v6XB2uz~)pw?`oP}Ls˗9~3**jΒm> &D8 )BN,W4돑uC]0cpUꉤұnõJ. J 1ku0v? ; mIY:˷xmyerMFA鼮tٻVI&t˨YBQ.i@f8Љ&2n5fޢ~=؇z|߿Y~ޕH_'ug=Ͱ|*Y8?>8?o;R?~lFfa & zA)85G* wae#@patfLhM~;a)͞x#l6#b`t7s2bY]rcwJu^c}ݭ*$g>@W/=, EiPk4 Ml( -T6igV0-;UhCT& I5Um|ujg`.z8z9TUJWUt Wy :Qa@g+A֣$19jMS}w#*7;1DEl:N6]v!{뒂{%49lK/2FSG^'Cc[HXa 7 AŻ7,RۺcM)끎]`@&:qMU:'GlMy~qj"|60K%?E֏Ɯ<6رB^Jh߲vI0ҝRlak6_B 7}S#Qw^eET7+(_'\=fxQ Fz`PB4ӘVn4t_Z[U WWp>JLGAף9Y[]~G3Ͽ :7Q%٧(BʈsK`K5yQ_qu쪳_;ņ-`u9=^5u^LCf$in5>'(V;Jd UXs(Gɛi*y~tLpa bcWH00 l_x~i 4[3K!NuBVeݫg`6Y)}4Ĺ@3;{PP e ٨N`]`#(.gÐdf~l/k+%xaî&l^.p6HAHMF߱ރjemӅ&) ?GuM2L FoUH3,HP#8HhzށA _TKG%Ar(q/Zs2:zOuTy[`HOԍ[s E(yΑ}6C|s]5/^;*Sݘ֗B;7(uq8,:m»=M> UU&f)ndh}c 5+)d_^ _e/1MXwhQ%*ȦٕUdSg / ߡ6pޕKQBS^6U¬# C&K:-au4k)r_ONwDb9#*@NxT6/ڒ} imA}x͏wdEX0L3M(XWC) cӦXΤ9:3p;KFQ!I((F 6d@ d=3Lj\tNϿ9PǪ$: "òW]\:fFOgLJK^u oK(z{žTwdIu ;6u7FٟPT3?lGk]W a9?6 nw;ro u98[``,Oxu<::Q|XeZ7Htj;f\㾖*>帉7(wC'`tۑWe&C@/E1dy"|MٖbV8> ,-e+)6&hhT|Ҿ*3Kz1.܈<e$SJt^AΟYmc[\֠ c"njތAMXK{cNXůu)knҟۚb*4Y&PpTmkm¨~5OA>yoˏ)ַI?mbֹ Ms5cNخmʷGUjVk ՜fY`\]g|X̓&<2|`lV֤ l")2axTKcdb6ݿ7ZG?i1.׿|lL?o1Zg; ~+c:Ox}$vfW_<=RX8ٟMLPVuS\5n_,CGӋP&1\9FkWn~fۭ-vzڇjU5jC 5)#[>37y:y6y+hT22lUk]soe4RE Ԅ,E#`*Bo"S\QyhխR`(Sm6!4QE϶¼86ޛ4kmoxɿ%^$ӵCvktɥU׹vUd3ҩm:O:e)Zj]/о -TPfk/9|v'*J@ Z g :^Pm]O fņ =D8ۗRUE"jR#c0Og4l ?F 4gLe62q0e1$P3X]-?LZt3}va2`Y_?=v"ᾤ϶d/_o=I<5eCM Հ6ɻn8F".8 p§3R6Yt\fHєFe76~D ͣyֆΪ ߷onE4= nbhe> 9+1j 'oo&qae-|%̯7%tl}@u8@cj znm]s6^-{Ex a =8eW=ܬ~bM脵Ot-&Ff$ח.קbq۸Qm/lT\ꅅ e6Ґ|}:42aEZ#O a*~nR('oBf.k,e]i/,G*:,~C}5l5#S3WC['&Y`7ee_Y6)R; Kk][$m&ʕ5,x&$ g .ͧpcw= 5Ҭs er-GmmE" ~寉r$UIB$xu6E1؁4 p@ Y8٫oTX*?fjqPjPTi16NH\6a}2{EJ` S0z2gia3TO A"MOy? QUE9!teˊ*:6ش|xڸ,a,;nGr@CX_%b iOkצ>W\|}|Haz&~Z#xƆUoD7}Vy藯/Ts~>χoƍPshތ>iPu;vHe f>aYh. qL6..2ٲ76b w&7+'ZY%|OR F} ~ޛU̯y0']Dٛp(6vNU@M4 CA[g{ޥJ_eKK`Yt+bZy$+UB0[]nb. < lbz|0ְ{o:o.NA?@-DZX|]טˡVݪJqB؟'e~i/v}~^ jv\D%\ Byk񌮫:$rdG>6e[|0͹qXΊjܤαhT5(sGH)T5B5)K^qm4AK+Kt*!!*nwYYz@Yʑ8*{V23%6Ho?@ u]Һ??VCy*Ĵ[ada` )V:6:KP~p^5 Ο" 4P]-k1%I]ueXE/@[TxkRuy] ^NnA/%ꭩ)kg Ӷ2&eRb}Ϳ1Q5ҝН_!V"i#z.S6}=w>OrI29sm42lUl1QcZ8B=< dW]!AƼl)M8 ɣKnW('lywį~?Ma?/ɍ/9mF{AxTGwzEOӴ^}skCv|#rm04F }N*o5?~:v oۯ*?>Ԝߩ5)uw]:v7.,{_jKe^F=l~  QW]ְ$dM4DȘ6?N- Qk 9\\cO4&s:.oG[~LqؖІr: ŊBpT:$i71ߊ_-YjcLͼ[)ಫlbjOI`KsdSR`@%Ɉ Vı7 oIN5[Q->~o FXqW\vۚ' oq;|_cN 6eX%n*w?F o>BdK!nlLbM6% /e޻mޟkz:@|-^m^O0JP[&ľ+Y3M(WNͬi"wh-D0e pHkߣ)JYo4pǦcA}';rMƄEy D߿kQ ߝ^=ye8{S?Pl:XOTnX1owuc/D-hXs yd ~[1̮0|<އ5yY&9F:@N $[(o##[eiy :ĕfW_@\V6h-CukS"-AнU0W YHن $Kuv=,K9<]5kA&@9넳3G-{,l% ^m@ʫCl1p{k&_<\skg%7X e3ㄨyX邴{G.$L5_Ӝ[߶Wu_vW&zyǯF6eA&| }65cZ[֣NL_P*VTٛ>BMy3j?#WmC||_HgA{5^qD`95^s돗`knd}|_sVTQFmSC~1%:迯9^%U"{0+Wq\iDe\25IeqDU*0! ;u5עlR?}4%R2,;c'͵hK`8 X8@ӰѪl5GFכ l?A<|᭪:^L$c BGw 5'ӓѿsjl eQydQ|_7%+[Swѳob]i/ JRuYR5zz?7h 5gK,mwA`ǧk. (L|N^pYt{,ܻ钄=%B/2"MoB]-uTV]AkoYVAA;桬X~v#Bk/W ڗ?/WgC0N~vONAtۉJʾ = OCa3)0- r zZQDDjMTʢM.]?af"#ڐ9xu@pOBr:D2:Q@Ϸo ES/Wyvv^n/;j$$1ehέ[ 4:4graӎj s#6ڊ4Q[l7ѽGi QE}r'9=[+/[]$7Ae*I&ÀW]hД(.X@;y^zAI @F3"$ M69=.R]kfDF޳ñ {<֦31`DHÙ=":5@DXqe316w/H\"@ݝXG~"*HDp5k#bj˺H%F[ꡲ|qfXJ)1,E"""Xpt+Y0wg.n "4M)" J)7wIDT,ָ̻1N]/PMt>=z uv@w'd@DFP57t`F! ZEj^n @`f.`Si]y:@벮r}ɫ2s)^DrunQUm#w%0wEZL^=^D",4ún"2M"n:u]uϿZeA FZkkM};5@faSX33sh`GDwwR ú Øy(F"6DT0ԖסL֨{Wam2FY0,"6\+ !"Qi<].enLȀF׭O9 J)\Df̜̤^\ PND27$Q7R y61`c Vt|u]x}nfcq<Uu." HR O~& l( a7k)("-S@>^*m^zu\kFVWDt7wLخA;I=bV9`LM !.RǺyNS /FD۶RnhX0s9"1" YX!B"x #IM1T!` !H H"0;u{ DZe=_w $Dfbf|E[ E#R)YC w_D` CuB"bf3/?Y6lܮ",L(\=̔/~fv@"D" wD$ p`" "߿#e"CCtjXLӴ7DBWLCu jiyo[||/,x[o"' UBBRާ*1/K03꺮,(̔Yj p7elf̌DfM jcYm3LhĂfn>BUk"u۾"۶Ҿ_/_^^qY?u.{˿˿콷6C(TDTo˭0 "nRT^EuSaUۤjLr\e&F9"PXGdbB w#d)Ṿy/}Z4TsfRp)̒!r-`˲A^j9 jmq]62`cw޽{Yc]W^߮7wr{CJmR*#mY- $f@U @Bjn<#ok"Q)0G'$b6,XT"""C;L1a tpDİY@`mhf}hyx6ÓGDVjH" d^ó`Z!QD)rqs̛q)O<?"+&H{Y\# TZ ;26FV\F 9vTaa}D;rmϻ DhLfE10fAG y@@3#`"}1̗;DHfzC$g eID3$JC@ D y۶0t a`.>ƨ2R˻ojZ&<Ç?'kϧi^~7~۷0ϳa>34M]?>>R Fv+AaF`p$BD@Tuh.ˍK%ZzSWwχj)._ʢ[c Pd[ڧo^8OLn,Lj6M9U)9#1%8cf^eVZ˯j)maB!9L&ׯ_ˇmY {_u@pac4x8&qZΏ^=}+5N}1 Zv;γ ,ֹLMffM pC*B̵\T:#UJ΅dK}D2TE${m3q U8MC #@+%=)+p\L<32mc0<2S]o~8"oY|~mPg0sB t3>>>-N,\"G*"14͌a}ۖ BMK)t7D8u[p!„dYֶI˵N۶%JM*:! y`)RE q) fV3{}:ƶZm `Z6/ˆL&a[_;3} "# 5Hm8 `4lEDX f.3E>y[e-P"&>mӔS4O{ nڷػ{  {  @_ZX^QdBDZ̃@"LZ("Rked ۊFĂI(2sݖkZt#712%JLYk@Bp̋GDFND!;GDd>Oy bYMr9b>3s",Pm]n~? M積m+U&\10}Y!2v'1ʾpޘ 8R/qӫX,v s'$*$~Gl1AJ!']6|CDLa.Լ@8pΘpV+1@7UAZ""+omB6&Etۀk55@rhZkE@.D,LD",!yn "PւHf^dDCթv:=iUU"͛\1.z+W"N4@܎ce1FMi4bQk֍Y󄁮΄Skзe]nC90neZ^/:OmO^_<ir3Bc۶uL`y:x^_lT{6DUDH(Tokz 7` @ܵ5 Yڻ:?=n۶ܖRK>WL FVhnK `뭈PCy}*m<>U)"jm[kYz`]j Hai+ %Z҄ # !uҡD%Qs-۶RfSf.(^DXJkMeYVˋ۶1z#(Ց3D) p#<)}tfu]pZ)amyNdDDwMvIbHOn7r<@[T X192U&"n^Jq+3C`D z>V"rDzjmoa 0-<>UkCs4ytpRJ,eKۨegܖetBt05Yb #W?ݴb "a@ 1Z+P#,Ef Fd LDyFBE$8"-0ADTDի< @= y1,!@$Y( LfMǶKĥԝ(X-60$6[Wa]G^nHHBLJ1 q>BaAu၅? \0ͷ D^ݬH\zg?76̐(7~8ڼ/?Os堡CGΓH_yޞg _=Z_3Uz+Vɉ/cVOӱ0>$&LP8B]mkQ5(RAh_Z/K[_TTfVSm4Z06>}ӣ-܎Kȵ m[opi:B#Z-Xa!G "qZ|nnV ZAD *2vҘ q>a>|@RJK}QvYL$!\`iO)c5g*n/}R܆J)MUnb`j]ӦyHӃ[̇#<3 "`ZˎH2t2B<|]dG]$sCB#"1I]aIJD]-Ye(ocF|{ucbdCD"R[MjM."m[WBDUaaqRHZCYv⪚T?HRhw @0;G'lj a sՈTZQb;ɺq7w%$@He%$'\1t-DD! uSg}nyM>r{ZӾ*9χ"zV )Xv"ry0mt25 ۺ%uELx<,˭CM{Ƣjy4qVk#B]\~7p+$zj.LE8" T.˝0 0QMa]uY ΆcBR>ZXH> \+n1O Z \mľTp[W&>JDR,JxnfKR*Ksj+E߶ nR`m-W?Om۾yG)TD6 ɺܐ X?Ek}2ě$\%wo6ȶZ z;3ȲmD[4M?ZGVp^@0@d ZFg.{R",Tug"H%8JiH\81js̥ AúmmRDfJD:b &uٳtZ|koy!㺭\D vJ#a>FKԖD'AHBriɩ11JyXXfAbLN]DG 2D3srk-NTp"sc%5r,qTTD|C @;&yV]R>|p KE8;dG`!<gD03}!AI`ɫD"r-+ @y*TSS[  wImgSۈ>l۲,RrO,.݆ǧ'sc)cCX-Y(S(Z"B@$P-7]Mxǯ1G1o۲ݻGRJ䠇Dy(r%xR^>|x:z:=)=|7?p)cuZP%m Dz|+`kkZ]]nWOfq[kyiYSjXjz[{jZj R HzF_#E\-ӡBU v0}Q~^,\tRHH[!\jmEtdb8Bnf; M<eY[ r[Yj3)RH1 )5!HDڈ0"i|f*j34mZv]|yR,QXdmlGJfulNk Ԧk/BHoc]*,DI]u>?}LFxRr)D,\݃LGؘwb)uN,pRkSMRRNny %#T{p]BR !|G3yz$]JMP @&%W SLIrID6Yw.$M Ò HfsOQBJ#΀Hz&m쎭Rjɛ@Qv:[;!R!|vykkADD|9j޷;ͦVka&",0{a-y6!kqd80kkuYF/e]7BU%KȺmM1o:j; بC6ujM{܀yG6a8"B:)F4m[m[w1FRk3|%Ii:̇"e,0# rm[G \髧|8Ok_ud޶mjU5iojZ׿$뺎UI0Q)%G8[-5%u\|lOۺa>;ZnÓAOCҦy Mb:>DsRj@P0s&D&$].ZK|._}"Ne]wիGჇRF VF}䁉MẮm|j+@a۶m<=<<[!in>RX-e CUXpps 1<fu] #ڵWZz:?<=|O}Dk|6 ?>˺TvwJyQ]1CҤEDe[7AWjKs0Ot'_~eW=N}T?\iucm[k|<?$4b=\Щ;NxD(|ӥw%Tr[£։ GwrL ZsFomaϿ~Nv{zzp8˦Cՙ I)j,D鴮vChm~xx.D*>#"bȺۺVq+3N8Mںl}b^}r./DmQ֤P+"U$2!nn2vmp6PK` I0sbsfrteR-dGIHP220"fa$UBԖ'Tx8zHYv:x)1jcX)ϕ&@ d̜G8QS:.aCZCx'3!rN y(} [Hvܾ2#30Uec('~"0Im saa&.l]LR6ͦNm>ha}ݮ͈eDm}Vc&piu}-fёO;h=.@޷eY )r}&1ַ^KYץHI 1ẁr1deCxcq"HqIáff뵕r(r{k;?|<#Q0n}Pf6H꺻>` A2V[mDDjmjT X€P3 //ϗK/k߈j>*'?HW^_.-i/C qj!z L9VHk5n=9 Vv[͌Lj8:1sfv&PmjLq"0s==,(ވ†[W`Ð9h==vdQF,"u7!cK!ڭҗ({l9$ "0wD2p,mB`xkB̼k<0Zkfm\’IJ)M1`>BHbr-Z5Dc685 "pwT)"1D~]dԈp8K;_l2}Z+HmIS]1 bP7SzY>{}CNR XJ K)ۺ6T<"6ubcxa~WoMB"Y=41't:m;zzSSk=o9s;e۶vW]ģs΁@:KɿyBpug&ibyFG(zy4kd.lUXr-R N"m6Kۡ۶Zi2_ypIjb&@V+"*$ <m upHzBU*ОmO25JA:|MhXjAFj1;WZ2n@ ܦ=n*\ݻD#K"DH{ZtJNe)0燇O?fHyjZ.ry1э_x<3 s1G, Noi'R#HE*8@yf,13-j+ Q)Xtt5kU!I@thr)˙k}DDd@@7cy^MZfcͲtɦV nfaʈ!sV t")T9_?s)-]k0۶?$:j6iC^c]KȄfM!+1 I)9_!b˟ai%yw'ʜa &@RdW.2bMs <" "D}F}>L>|7o>1}YZkZm)EDh"ٶ-.y?;3+ 浔ctC5B m(;33;~, xx>_/߾PW˸Ago:r>{^ݖe]uݶmg5KpkMDT4MiwRK)I`0\{ mb1Lm̈Ç!L6jv8LVwkWEjVdJM{H)Lzy&u[ 1qE|k#ϝ><< u92Jm[ Zkɵ<$ dҜ-9_vp[;t|z":!ؒr}[y>X8̇0m1D8@DEh R/ęu:r)L(@Q >,=Mt3  $植-@ޥaL =Dj4[ӭ-ܖuE<N,%!{G"J6} 0pW`aFȈ\nV {xk2H5aC;S-nK }nID @P$%f60;&  ‹cgw/db4wb*R<$8ɿZ߼__Շͽ Q:DRS{W ZR<a $eɲEMYpRK iH}ÄiRӕN"ƶv>!Dlվ0!v> L8V swf#8E2ΣB4 ,Xj\Ì~[~~2l.RT:Oԩ6K_I[u݂p[Gw"Sȶ1Yx#Ӷn̅Dn"CȺmkjuaL4_|z}o6#ckӇu[ڛ7jPJK pH0 JRr;_Q /cy8ULc2Tۡ i6=<<>\JU R z~}e+P<+Gqh,`.7l$+$ :` IS1`$WSsϴc @P2~W~MMy\.ԪYvwC DPUD:OޮrŻP-<,ZTUSun:Nĉ"YQ lh$!k/xd}I O zDHQ5O@9U:X%i6$R:YDbyaqc2;DS8k#u[eeYIU ۔OZ]5K}mG?rcIaZ,ZK$PM}ctԝ8unf!,{6"Zkn,&aMN8̳6H14]5f 3~ 'MHE"+""yF\Y8u `}m>fنDJ)fR;{Rj)sBhMI轧3Hk#0 0{3{0Ou}Q.R2\.)8Nt:T6օ%WK.|z< ͛<Zt>=Ç4t:Dr3$8}\^D4=r"PZγMc;.Syr>=p8gիWC{Zi2t4zd9!<{ *(*=S G 4zG $2Lѻ6|]RK[n̷uU>ғ2 BD0M{"s5IbZ.7sxxPyTwE\HxRoۧOn/"ur{חp8-u(1ݍ"Y$i@DX̽*քez?Ud(\mqaq>?u)Mpl}*@ ,`kaj4,(Χx8V^?UzTՆŐf/i ʔy\ qDz$·=5In\ 9'&ԐMUG;iIy=x8fc(#A*s\$nm:+bf*sc!;ZkXjC^ńP#03b?<<濛y$LRdw{Zk&{!t!b }KZ7ux!00܊.߅ODZ2Ҿ$tjMZj]J^.ϦJHr$8&!usc}1 NG"дȼI$DaLai$䍈<޻Hٶݻw_}^MVƺ DVW݆eJ$91q0K=SВT(B8ϲMj8an+#ZmY$h) e׿):x~eY گOLҮOn?o .TQ̞[-q\T{`-³p0c,VF,Hid+aD4ɺQ&0\))t k9\LG"0H}0@GRF)B S#4s(H922 n$I?U1n-?FVRGBI:J)4c: Hkmo}ݖ.~_[b.PY뺺kkM5Ha64 Fc]<'<rg[^䘈y>2/.N81Mm1u"Լضռ{h3s-U%܅ayGkc)E!@t1 .1FTS{{>Ep!Wf6T#Wu%02P& =5C?~տ $-pwBp8j^`B8sUH\h0l:T3 qwEtDLӴ JI~AiiIP 4#px~ ;9[y|YB;#ܘv033RԳ)=w3p=htH s6)zQOs4qsWw pA$B֚GPaz0gi3qC,IHO%=j_$J!BsII>2L>*24]]6)λs&[ 0G??z}hcY~@6u=0CEzHj2S0IMdOpX J'.L\== kxC|Xbju̢\_;!,̭se\ o#|:Јyo:u};ϙ˓FCi"~Cz0nfi~߬@.uFDaq=.g1t['RwGB 2uUS3n#:OԢG7l­f(BH̴(* ;Nm;uOLjherU+4-ۚ.x<~c?淿W?x\u]XE%S;i'wEDt^E3 CmfV [7!Bq3>0PMuu^] m,ZJ'?nkZ \>\_.a _^^M,WS}Sp}mQt>_/,t^2P2zni _֥$6uD( ֖8 s't$"3ֶM{/4뮒aR+a.34I0-Z-H$WL#Rhgc"[7sRy_vB Ͽݥcd! 2I#W0)xPzzJ23+ .mӛa ˶ݴ5"G{dÝx_~?;0r‰F9LǸCA?BLj_DZmC#p!I rK⻥Lis8Y)ݿ?c,b"r>?|];sU^)U4^gpw=LKlҘY2j+D\y iT0KC$D=[*Md\]߰1'Fp7Dci0wFLn~Q%p^wԕh=I v# Pj#\qsLwkbwӮo3 ADQb"Nu],YڛZaK?wgĚjmRzT*!.޾} Q~o_6x>dc [_u[o:)uӘmJ•Ka!\x<Hr\S;'aC;QI&)r]Mb(S՟pHT(#,#>qe1 -8܅YRk."azϜCNW]J@):TC  F2A _`L|10bYn͈[ے3N[b0W« O@Zm[;.,7L[0I}nKI|VK)46F),E PUG2l}jD(Q|)+>fB`!vc0D4/k)e`Sʹyy-{ Gr98ȈkK"ԉRZYdPmcqW$u]YRĘ}С}+5fE_H|8ԎtI_jݕԦ^_W˺>޼+9o[LIv)9 l0ѥ YEg4.;C4[Lխ֩뺐gB66MܴݮC-m\$[yF Du:"b;f+:iwA|Z"@tpp1"g?@Jڐ1Ac<>>ZcDÃ<0ɟK=WD=v :M&:iq>/LueƤ9I)[6RyG({x1zڽ2RJJ }}Vj{G]ǻwe){&xt7ѝiD4 LJG@(XX)%sIX{(B(U)).Բ;j3j-ҤlZi}n#|z8^^·1Ɵc)ܮkZ1W_ŏ*1.޿O6=>O>Ɵn۶"ܒXVKmin^[;!A>qv($dSZsVs+\Hn0* ֈXXj)x}2t9a~k_7`''j:Sg܂@ͲHu[_Pu, ~xm6vanKf{;0"9W1"uۚ;lU#{#"QA | D sS3 Ӱy$-8Nղq)qoc0ޕ;(34S@iژjNJ*4:ۉAk xOmR"1p>_W_|зHVU;n0{ȡh2q2|fvI$3척 3gxq 6aĐ/~rNH 8MpLsM)i!hv0~{ߝÇۺ&jEܾy2U "tnwka"z<_>|xwLv*m/J-Re3Dp廷+?/|\~W~.??|Y/ʩe]{߀T eY";bO~ s'! ÔD <=<ban3f˺J)Tr:Ͻw3O$oo~6-ϊoM|}yaq6c5W鰓 wu )@#кo||:G1HJ!SyCw <\'Nպ9y!.}1P~Fnt(!PNw)WfUk-bul۶ѳЌt\& ӱ>S8g~BjL7fnӤcLneq!@q͓fr^Rn&R `ĥIRҦfO~ Թ6h81F`Oӌ$%VKy<0u]z|8-5RG̵-zϧ__Wwôwer}qyݮ K)&,\Jಬskq<.KD v$p\JV2uY<e~<TBD<,ן~"LE K!>Bp:Ja3]EmJ3:[/:F6 c>HuqE`eZZF^֭(l[6W^G50M_-Rz ;<4/; snSٕ Ҫ3gROa %I`/%5F; @*$0^ {0l}t`&b3\*RKWŵ^ln#\[>f"R6P"ۑ!dc 0nV[ۧ$uN':FR<}`">|i"{|܋{8r?.(0,}IٙWGVHD1zi$;x:N.yr2n69mܣ">Z?ӱm5­w- ^pmrj% Wo_G??OvFM;*sݗLJjWu]U!iNMnu!B3߶Ͽq>p@D@,~*ܙ1Ft:i: 뺺6UNq#ZWS}'Z}yynm^/J+r0s]n~:Tkm],L6OU}xx}3e):t]ml-)ܬMGwDTJKkt[5"ND9um:!??R,k1R#"m1D cl1FdS)LR =sEcHNĝСHyjaQ&8V/}o߾ Rx]Lf=5\DdR=v wχ= FqP8OEz=97 YJ)0`! pGFF (G$"{Jރ3N*) LPU+Fi9\yD]x\pz@@`"^J+|뗾t\MDRzzw8Pwmj#s鉖hNeR޼yIL\yk)i= W߉+F ߧL[Hz]FC2r~ADRu (Rͼ6j RKo늎j˺x1UCڇRK)˵0en"E8ϟ}tP&.i DsjWd-`Y ^/Rd_뺭chFAxmU1~M=eo6MS=wZL!r&m5 m۶RH$"Ӳ^Ç"iݶT[i-jncn~8u)23Tk6z@L6z^/Sθ;M8d&pphn g@'|{\cёIPZ1fj:zMDv#g,g?HݐXD. I$4"tȤ}1{ͩb*ǬqxK$,zc<4=q 6X7|Ip8YDd<9BƄ[C$tKѾudzc aoi: ;sĄj7/-xnk&G$Y,dַ)ݣx`'3֕[k'ZRKmc 󶉑^{Z&ve] IJN3k-1I}z|~8YZ_~5ԉ~^r"uD|֪ϖ\Tz2{$&jBϟ_^ˎh '&#̇j GAjtKk~ S]2b}l(=7Iîx?]D;= A̡12iA#AH!V3ӴBN}ctiU]jI}$Q6nz^?ӫؖq1Ӿ<x:?>zwoK˺zm]sAZ{+S3"yZPURt:Ϫ~[%}`ʺEL`O ȶ@J)M]x f^/]t})Rkr6n7Dv|1@PUovn 2M__i)e]^Z}CĸF9N@` ͌p͎$Vib}0Θ6uQ[N8.W(tu`z݉G K-uf?}CpfB@U|5_z$,u?z~0̳ū-3֮ޑaqVmP$PBL1F\k4Hh ҙp8Ę6 3Sk.%j"XIEbHCʗ̑{WsJ1rAELkySZՔ3^ qBSZj;@4M;Etl3C&Zk"$fB "}@[kn!,˒juYk=_<`]L^. ۊ7bfH$;xELlS< 1@f[K!vSVxJq#!8Pot~wom8al=U>>>K+|Ǿv18<>ۉHֲzRkǡBD˲8/YUkm! Z׌ZbӼxGbC ՐV}||SO!RՈR{+mFN֚yjk{ͧǏ۶Cj 9% ,*iDDcٖ.8Vki!Ժx3DN_/CzlǏVu$a }7h..˂]jԒt/ZKx2 9 )VzW7yqI:Q\C%īЙv i]v3Gպ`a̬kiYRV7&U5%BU10F^1HlRh>*$&3`o "s}?} bm)Zːs5ݎd']fջEzSq{5SQ 1eƪx2ګ!K̡8b#i+ЈG41s[7@fUwܳ1w [ۈk)c*D@!Kc0R `Wk!#@U[ `3RapF)A4Ak1\kM(PJyׯ_xy|GȜS~SU. "(Bb Bwzh@ حr!E/9.q~ϗe6C9Oxg9 R45C9c ij+SDu%Dr0j "bLCmZmi]׮jO|6Vd#RUbPΔC/]jo]Z y`)G?\sJz1.=uliW0!Zo`Lp n'e0L`H!ZD!q^BH#&ʀ@hlD!&Qm1lV8\.BCNC~9eV$i[-uN9޶Z[b,u!֛˶#$7w>Z*S,RLØwDcܡKGFx{B140B#b֮1%rVK!9"yt{'8ECjv<,ҼODTu"=@8! 5=^oZZȉC !H"=Dg`U^4 c`ZTk?L7`W۰H3Ǟ{6hJ8Z7S%"0uz`lﴍj.$"TP3fB+jT:!#]35m]zqY肍C[k۶JDײeYyhWJ̙Nu/^)H@?}׎CJ*Snu+hxcD2|ϸ d3y苨Hif1!S ׭4i)&U{EjtIp] 0Cm} ٷTpO+Q L-0(9+= @@D&{K= {VKB80OrV.bKDM̺JU1FQiIm!E1!|/8Mm32[sRiDĹIT'c GF"a8 h%jv[AcGKK03whya1ZA3iwa9,r:T "H.qG6ET8pb.4"J9 yek͗aDRt|*3G'zOZ{llAD@sQp@t(1a8d[n.۲c0H4Rh,2#umM!QDtͻ7hknŤJ1s-4@m*[KizwiȹwqXk BИC&&ur*DBbۓ:mm͎Ӑmݼq) Y aJ1s_1q8H!l aw.Ždktvv/UsyᆁCJڀt~k{o"7oۃ)y`]WS*&`}}i{wa ؽM{ b@iǵ۽2ؿR;j{+M(ňЕ kUE10c)%R֛M:`vQ?"V? {m`R52WO x;3SH* b4\h88yv]7#^uB! ]jk۶z3Bcd ҅)&v庮0ZnN!01X)Ĕ1EHwmJw:s8:bLÐ[/)r?LܵńWAx25kpVZ{UDJ !V(1G0c CB8)?O.0^!Kۓofp5^CVT~ s򓝈v'S`m.^ JZ4o5?"[L`h*33wZkO9h<1 c`ڙtHf *&@!8ewk=0].E3[)g^9mTة2mK=³Օٿמī\[[{CĀU?ne_N>0tiIR:ӫ/^|JXERJr Tu jJ!uSd2b]0p)1n7ww)lΏU"2[C{iá>䉀e@x- '=bFRq&&MZ9!&ty˼"J@[Dr<_rN~sPf~xS9&@2?!G֪m2N!"0L#.!rb:jSn˲뿞K\z>?kmWwxX=}rF`%"y3 tכoD]^c*Ğ}0@8eǑb{So%p~zb&\ ѡL{672Q]=_ i:oɕRE5m\NuT}[v֚߹XpkRѫ*JLPf/abb!5}kǃzg?3Ҳ\RN1w~2L'??/\.fz8K뀠#1SL9x^KU QGԭ/]3t9?q6 c/չq4P lHj ]变|4֚"!Qq<0TفY!|s<u 1z]ku8L0TQ2 ,Diu'z5;ah眤7"<1dt?T ؚ֭HuYq" ;NA;etcp]z@8AU}ghnF`0T-VKü^r1Z4H7QA809B(&[]nD|{{H9a+OOB EjL>pM8u@"cJ1brwe t}vWjZKݪ6@݊.~Z6S)bQr8Z{֥ХǘDŋ{zrW!V͛D Zk"r{{s޶R vVנ(ļASmJ)1&"ji8ڙ 8PֻLM#0.DT]. ar@K7MA}ױxRr֚N@d6#j-%4H6@iDZ%u1 R`! ) V"iW CL!D3K0.C7ǣt|Wл4vmZJ5dUGx<<}S{?Әi) 1& fh];E>"@fQj0t2 (F&SPQLkөf! xJ.8L/}[K?$x0gH9sEPeb 6ՐqhK)Z q@Km zS|YgC)2 V9֘tiab9}W1؊a:8RILt:.^{cӡCb\3뺐̚4ĀJoURrH sTDjc{"Ed6t@.5[)LDz) A..9a;4@Hvg4atiKWvbИxIDAT3!0Ո8je(Mӑ9kXB1Um qLbV[biino$̵l2Z/ Cm] !)QS!2ĔW' ژ+*v/*CTQ0PGwmM)p@ }/=dNB߉ShS ͳ.ӧUDax](˺BJ0l[1mȃj7Ho~v8`:JBď?|}70t.#R-7@{WMh1EtĘA~|DPs`xY&u))Ƭb)i8ZLIa7GA: p@Ȅh9=p4"aHi9k&njN38c 1ޜn}VHF8rkbKYLLB1? suiCfёFM/)1OHj"a LC923@0s8{ZhrLJ&8Lu+mu]m+nXK݆ ś{sh8<>=xkZ_VֽT<ʫ) ;n1rv]5億t4޴l[-y9=Z[9qDNnە:g!tU"k tgC1Hxk9."mf4W/Zk[){!.+WbL)cU&J)^\:ދgCRS:Y%!xݼcܭշw`"ɘ&KyzH XT5GD!e1))A8GNJ;-7vk"rmYZ'.!"L: SΈtr\tp 3Ws<|(~Wo77i-}}!rV)q,ޅ!E@ ޽xtzvH!q#IqPB[눔1PP3Rد""AHcp*#^-প`R3@p]z=X?LԺ&kwє cȁ)$n_V{můrr$twoU@ `65iM9bJVa0H[)Tk]ŧ3o~6}aAAfCH̋k;]A%!*f@B1Mi..[L#KGxx-0l#OӴ'+gqDB 54 㼮DR\Y;[)SiW/(Kџ'4 1``Zu[n[*M1Qb HEmoTG>#R#4R) *rL8lZ׺-j84ִu`n[7=Ox) bo0ixBٱb*LèzUWbǔ$rXixhWbSj$GLLo#$" 1Ĩ ~)$Wb`US3RB];*iǑU0 Ԏ4N@1f"q@=>Rq^{Qcm}C.onoq;Ĕ5jEnC)[-ńD{q,hȌ"A% {۝lک90B@.">=>~npC!lrJo^Dy^1t{w5[x0[ohWb2u]|D8M `J)ԚH CL_yl\4vΞ#;yתoqսks=]kMH47Ǜe].bN$Rʽf&Q3eYZk8֥˛eYcL9<0!WVyyA&`lȐ'B=pzCl<a87r魶Bֈ9@ѬRU/^0@땯qVp8y<$@nq  >WUwy+t ^@*y1!֐ADmet2`jfb"tDsSOǗ*a8܆}vLbf ֛y_תr>_ND}cIWVuB0te+rT㦻ńllOOOu.;Vl-ɱjC59B"Bbvc}o0(c fpwɼ?|Ϋg[o^tw70V<_P< r>|u΃vM1{~i| αH<ծ=4v/`ƁLTUJ) YaR~jtsá+p/_}իB)( { S@R!n`9 3got@)A)]BHsRkT!,BM:?>>JmHj !<P ^*/yzK2W|߻1vnFD\K^hWVqD-C 1֭F^x4T< !%*hJ:L[-.&i:JWTz1 `ٻOG5#{ iS\URJ77_}MTD՛Nj 9~! _>J[Z{<G?~Oǯ߼x[KYKSV~`77cJQUm!խ5GLԻ)%sXS%?h۩K-߁)f8N9K\NKblT)1#@!RDDETT"Nmv1a< FUcJ].2ǭ:|~vd"bcݫUe_l]A4WHTdP]6[r\lj1zO&p콚ٺmhb\|p H(ҧa\Zމ)ގl[-!ŜO,᷿mMr !!\ZKJG?~{@yŴPiÇOjcC"Cݪ!ǵjʳ̴K#!%".Zy8>==խ "12bt8&${m\<ݽ|9qqqxzj^8Cra)rʈԤU`B4{v:I|Ώ^~_Wh}thHctts77ҡVyz)%qg`ۛ[U-dl/~Ǔs0c8NP-ֲ1s4Mf ґLUmŠff 3Me*J`z-ں*g 1sĐj`;)[J,!<`:L Qz Sd_R>}RޥMͶ4 i;?e;E2`˲l86Q=DTTi'}Q)REMS8Nev_i9Z%ȄvR1UUa{ǵd@Mnn),r<϶M8Ecʄyn(S_jm-w@~DpG 4 yT b1×/_"]hb˕|sϜjw14 7眜sf%&Su0v9?t_vo$V/CdaqYJix:_T5GUNCʇi {!Bdf)%ou͈Wֻ%ɅNR&ۻu+D D< ><"d|m.{SJN ϖU{ 0g?o֥4$fJ|9Ccy+9.|嗀:#_ywYQzxx?Y/0|||x{̥ 4Ml91h]tKkއip p~U,dgX˵M9 9O!1Qޫyԝ«e[,c0[.oZktn rnn~'."߼xZZƉhDAe&Pv Mx8c a`ZWB@2pwQ4Ebq8P'n!.J(JjO~`&51jʙvb k;7zCz+_w5aVB!1"NOEtq^W^}6Yמ1<ܜCQ2ѻwV))}QK?~ivi[L!]'"Zkm)g!8(2{ I0H)Ÿ.k T3CHj`F5yu{)i@DSw.bkLi>+vr7-"S-$cT7 9aH)m[m[ʺ֭V9"~FuYXTtȱM8f8 ZzH!|k_rpzufh[yNF9{\֔C˶hiZݤTkZ%&jQ<4 8uQ!Hǂi hlJ RʪБ@C֫IôAU]hbn]+i#湨h_my]K`N:z{ Qv~{AT{`Fέ1K3?=]bLj g?+]0 ano~j4E#mJ)*.l/6v!Scn]_xZ{:_ReZYΏ?||xw}ߦot"OǘxHy(>!jo"B~+t8L5Y @#sH)qYj%b{ş|˲DjZ1JJ:Xgҹю^fD DPMv!~8i\n~9ZVt87IyYoJK@U1b 4÷f1zTE:"V.cC鹂C03NR^ ޛ\gŞ1p7gSFLl bFZS&!#j)eqTDEoov "Z ܴ&ti<<|HAUմ6çOe+0o7oS!$]2/"CJO,"pGys #rV֭n~ :r8.0N򎙥8We p<ޘ4^uu[\%vgG-8'VTw8`J9sN) ϛ;/.l`K)~mRjS y!5wmۦiK!mi+`U{CB7 {ejLH_e[ƇWnѐ8x!B|{wĢ9 /svJzki_THL11l[qJR5?_,p9նl7_}b@ @뽫QAqpC>lwٛ7oÏ~_g??o囷.ijWngӐ\(1pj%AѰjSL4rԍ+ۺ;K)nPwrq)7"2~n( |1؛|xnv&ܯf Z"33 朘ڶm8l(^u7.f۶;+3Vؚ ȁ} J^\VS6א9hx- xzǻ_W ؄EUwvAĔ_붽{~0պ=?0BjNQDco"眈X*&).8:T91W{+eCyYWqV5E@aj?"+А%[kHc r̗˥z:RÇO˼[ CNҫZTSs1@Bp>wwwΒUo[q݋g_} wJF@U ;r3dwyo{>ܟ6.:3R40ǐIA "N#aH) 9Vk88H1ioZat8ܞnn>=~rlo}po CM֢&mHFr8 <׀V b;q/De$/At3cނD{uG6նx$ Q! m?USZUe[ @NCL֪b)&$'zS8MSx<[b.Jz+m[ORJW@VO4݋J'q @D}s@M'bX3x6aX:o|E˿/oW>{:n#a|aS˼|?Bz)},Z5aY֘C0b8Dbj39z̾@o]G$~צPh4"riTkSbiH1G}OO6By<m /^lsνwBrn=]ty0lK%pX˶q apQJѵ簒GE44It ?{E1@g'w@JCJ)Ǜ 3} r)<3, s@_槧C1x>?= lwwweFƵmb ^|"w^]W)zMz_)rjZ vfѵVk9a9ETNHwx88U-[I9$i"9>|Tv<Vs,9'$UߋޥnNwC>NWJgoVTm֘93{nHcB`;St PE`R9ps:|||0_Bx'_/yY?yy/! M|C!eYbT}fJ@׿|y?Ju0noJk 1ӄfԺ޽0qau[d'7 c{(03p@!!'&쭉H sc'k9 |wyZMnM}w__ꗿMz c (қH 14sAeqGaX%t9_wá6b"1%inܼz%[)MPcR@b n_)zv.#~s}O3yb] b ZVpg"LVtZ4@0o3GZ߽}՛V[)N>Bϗo&aʺnoz2­|׿ud*yufuv5)aC1ۻ}O7w&ǧ!a>VS"fbc0i 3yS qD ntr8۷||!Բ{1c35(ƄFSV_}mD'uug14x\mbm)QJ9 HWZ^[6wx> AEGnnU`f!_urJUbYUN~&uo4x}|n3b_yOj^೛/g 5RHٶ/S|]8xe#½ƚ D GLղRF46 !pEvܱw=%xsFھ+r!(H VkZ8p-z!q\:Nww?/"_׵ DZ>x8~׏ׯak)F_)绻e|/r~z:yssϏp"#՛c{:4ʷ_L6ha- R $]Rv8>{>'Ov1X5la4DF0< S BbR_번Tb`.fNt:>hF S㱵&ضRڕ*1F#6tss{>? 9oAHqۻ;U.@ALsu]L T6Br/녽OUzﶷһ2.[@ $䷔e]zLC`2(۶nb#]9 mS,qjV˗˲21Y / !BD"qu[u!ry,k_S.^Fa1H)^3>{~ S*[џb777> ?5kի7̱ڻ àj_NAUEڶ?P{Nx1^ K'b]u{`>yƘ\!@o͍Spn2́΃jJe|0M2_T#Av00!^kH\J%"j" P5P-@`()ALkFW d*#։)GU1I$ "zM{LCq"LU@(XKuct3uA]M ho~7ç'G?{/0 qȷwӻu].11Ibm-꺬Øz+kY~&Pe?iSxDeUu!F$8f MCZ,Dڤl&BE8"@1&L)3Eo8!^ĺ{KNkf`I_sޖ6IR}MȨ@04 Q&r>?EZ$zkk b!┆r.j 0ZtFDQ@B [@$na;Z~ؙ488t/vI";/8x\;{k1!箚rV!{9x㑜4& jқ ji"8쭮]ZΣIEC.r=L<_b¶m###RIz)R˥EJ@ )0v waKm1}bj 1r i[)~5}oM)6H)Bme.n*җ18孖l~ۖGmwi8y[I|>HkպBZBbֺAz [ݶ%Ǵ-%<?OMm\Z) D>IuC({yY m֛ZJNņ*(ֶRZDw\݀1&ףkp-:"3_9e)Bk0z)x\fjkE(Dt;o^y8L˜Sb²1rL֚RDd=Z?}4M!Vz+&Dyv2ӳ̍:UUѫrcpoIC"roz1K $^VMBj]e^ԐBom]9Qo޼y||"9qu] 4;HD]z; oZg]/${_P9Njwkڤ;R^C䔲 Х:[,p@ DlEēRm[OG5wh0|WDLy#CNC5 i:K`rZ֭~:le5TBbp1ݷ]zz+aN۔_¸CcLLvT5"Nya8#9gb3Rٯb-ptV4U-쪝t댎D(j4[(/^5iOp̤͑撼/ݝ# @Lcz È@CT$%+AM1cAĽuLm4;Rע"wRJ<\jj90,pRVۼ\>=}ޞN/xNe&/_%OOty?Oe9oyׯ^}j{y{~zX i~2`89PJQ!) q< ?_?p>q =g; 2fS L?uSv!_yCuuz]|Fv1)4meװԲREn!fZ{Kp8='bRsqYb띘u1ښo|{zs9)q;Ϻ`]zihG2b]T{|~?쳇O;oooevԥ탘RܛԽ Ui>#A[mׯZzoy;ޜR+!C1Ƙi_ҊytTV˺,4wk/½)m\L!+UWޯR 2QBHe[Krnb,㓪odmhYz;!b I'M"oZ99FP&4U.QgF3)vf>N x/;"9K*" jQwo)19DT<>2LJqȭ۵:8Zݷ(OOObPRCcm+pkdǘc]4Ɛs3#@ 3S `bQ ?VqJrPB)yӤ۩YRyNww`Qt[4#RJkmSq6N/v >0T L45K)u `!ƺ{fjҥAo"^G;a͐ p`b0j)ۻgQ1e !DZ^9GhR8 ! c^ץ'/go!}Vaq8?=3WIp8o>|Yt>2_O6ú,қy?7>{շ_=~Y޿<CW!0>~1!rկhՙ;KJic+IS_AkU {h7bϮ$G<D]3o $`^[Dtl9R*0 u1#G SN1VJ0dQËׯϗ 1Zk/m)֘8D^̀t~31fƀ?>)'/ / ]|"N$R a_j?==QwOO?>}Pk}1|>]S*!;dQg{YURg WtLo^/BL)gcu]w6oaYȹPka)B`1qSJ{k[ku!y۶r9"cDDUq^K)x^kCƅ0ti:18WŘT6iqq.# D5.6i'gx9 u9/]ε,hn˧oZiOOOd7ޔV7r|>ؐ4M҅B䜓H`O?ڗZp,Ɯ(c1@y8!˭T~C,l~} s0Ӥr=<5Wk尗azr?϶?3cN9crJHff8va㲮|5 äHy\޶MLK)xD˲lߩ„*rD1r$X791 aI}?.k$ٯX%>BZHTgJEpA RΗK`;mR9朻4 ``D;]]\A9{wn!4FNp$ >|0bq SJm;#WSuBkMnȏ~_~eSse΁u~|z -_}".ŋWDzjp<Ɗ^i}Cɕk6_.sinv8?=

    /iiSFVmʹn0&v{sR_R_/?:g@C #p3so ! "ZӺΪr^T0!Z2!M'NKo3V<{̀\s1;50]e^Z貭c?~ce<4jO;ňk'0 iʩ~9x:jk Җ1w @ŗbctxL.j';1@NcرBT3Qgv&I_(֛IO)D8;ReD"K1RC@L3%dS1Tb 1rYK=Ĭ"T2ʀb,ki7c΃t=y]OiYr2ЇLJW/ݿ{{SYf/^{S{xx&23UQT)v"kYq!0"ZNC )ɯyf!Uc sT8~8N$˲ews!˲;@|||L)N3|t:3OXUICR4}pwZO~x<>={z}L,ǔ -Bv<[<ϥDx}}OME"6QE|sq_[.V@9x 襵2 03;uUh`A11;g])0nf9g&|_~[ 1ٲ7 Sf:ZGAM[1"L̤2S$Z:$Rh^NnȹˆkNqYN1j[Ni%ooo#qom#QM9IDBN7E*B-EtCƀ ÐovoeNPʩSYN$W_oOWWZ qi-ᡔCmk+ҫ6Q0Z9rT@@1 i>z9wr[Y{M)CֶvMv9/ qc  y 1)0 abR 0gy)?<ooNq~" {6nS)Za81q+´K[ȔbM– =BP5nZbÙhbjrR@Vq,R:ͧ|7)'ҩHJ:/q>)(CzalETn?Oi(Ro"ݐk)Ӳ-(aOOD!GcDjm{>S !on` S5Q@H؊߮S]sO k'BvzfZ cJvZNC6ckH[)Dx}BۺF[)Q @[׀uWBEN_}UzU#=<C8;Uyv{믎2 p B7xwϻpzuNS@Cm=Ơ*u[Kz)BE㻷_?{o۷yҐ00(`ET=ޅ9x>I^j_; ,|| LCji`bs[U򗘘 rJN.G3#JZ":\Bp8Ԯzz?ǧs]CxBDvOTanW08fiR{ota_kA 1q.uL]dߋi[MzMeZJwzYfwte!Z ϔ3"v2I!EDԘRJm1]<l:on7~}E዁cW!Q![Ս[v4M:7%"JA\Z[;{Yi5/Vֲ0ʺ?<Onf( [8NWW7^}4~wwyVQkMpu Zz: CnMѮ2n$h U8Ɲ[^)ҍ`0갵ji::cА@AC*Mĸ0Y{q~u]< *z9TМkg3Gv*j_>r~38mṶ7$4 4 w<2t- p޾#VKBx||5QM |@rZ{)JkUMiO1Ra4K7obO]VmAڤRjiELaҤ.8ᾖ<W<<tN&ƽ|fEL& C֤ۛ̆3Qݗ~Db *Jg&:Қbz͋g/0)"Pƛk!Xץ bwTK9>=fg7ҕKY{+!ZVb6@)pssn=!@0ԋ8ro$q1T4PX7&M ƴu;Ɣ(8MZy8LN[繷˺6Fȁ8.k/#oU ` }0$ x{9t˺H ) e@ \οx1I9{?y 21!HS.Ჟ*뺆xۣ @re]bf ڌi뺚Y=( 4CmJ[C Rt^4RJ)LNKy0?= Lc~?'WN~-aHyee]SJRc)!ǻ0SL1PruuژZ0 ɕ#vȈ=Zץ`"ջ!9Ug/m6*u^5>MȪηTAj&Ą~Br/Ĝq!bbckm]KJCSwW뺼[w81ôyW#"ň|I ]qR]bW)3yҹ%zL 8!EfeYWW_}x?iw%)k;0^SL2D4Sf !i-k)3^x աV)k9=="bjWii#DUo'{4odW 4;g nt>olJR!y-1XPL˲hK]4CyT'ŵ֗e5ӛZt*^MLc R"h$,n@tZRέ5PPW݊M=lZ%)=bs] 9Z< v@)w㣪hٳ[S$.H,b9UM[b)ws;I ĥeYE9m0?g;Dp_~xx[v7)DHEe7jCq_BZ=1ƸE%|kCvG> Ł< Yopx"lMRb'9fjLxwww{TdN9>;8NUQhwƌ1 9ZުW7|8\SL~"* qq#GDDUmlXI@&s&5fEba]VDp&g8V i%yƍׇ^ CJKS6Bqqq6i^CJ@.16Ŵm̈#s4(2oqޗę"]#qpcR^ui,sAN)$1<nݻgkƐ2@;1iFfv"Xt15@+kaLpY#CB+s53Ai"q(.l`n,x@91?ILƆf,0&1]-H8;\!Z!u뜒MӔ׮qFiBYn:Ѽ5jۡj5r*)& ѳX>UE?ǻ6x󷋏>zkn^xVls 0/󐳿D0% $Mi>齕ZNOG&լP5J"š[U.踎\:g&\S eC)"n+0_ɟ>KuO" p`뺄ȪK!h1D .DBX!ŘChf~90J$`~?=3y܍< }bxz:nH)=-Nb ?eT@r*l)kBeRfKJ ENX L|wޙN*b v-">,v;3]QMGH0)l.`@:zETdG׆[npmǧao!a&`!GWdo)95{9śȱbnr=d8{x[ |'C.ͯ(uݛ+M,bL<#⋗/yk1AjbN7G6<j-څ0'x?ypoʲ̧t>Ïg?˗/iOOOO2r*k1؜ϭuDUjE:1ٌk-TՀx<c)!1"ֽ-_ιYr[ŐD䡀Hv,2/@лLiۙ1<<;<ًWWBHɛۛ)Aom%t{89># qLH(quefU] F8",s@ƩVfn_p |;vyȟG?Ze0FfUze-YEDūn_ZYe8*چCӣp *~IH`Ӌ\"#ϫ׾Sh~(I1!T@y<S޾;ǡֲO\pY3K!\uԹZ]jCS0%@3>B !ᮖr}낞&һƟݠDL0Cʹ֥3ܹnnE {ZUu]W{y̅0|6H8c P[ykՔ22qw.~|k# #1S qZkR.ڜVk#3sjg'Nv'd+S9ZH@tD|ZCڊjK&p:=yϟju_-ʂ9=bpPb!j|1/^~0MWw[Dc|0M/O ֘RӞR/>DN)J~w7o@LG?ݟ4|w5PK}oD.֫E7~Kֺ7z7{o 1셋 aT1o4p"{no~5a篾|9Qjr^M .i" UF\8c}ǔv7ݦ!:u3|"O gǽvߊ'ǹ 1i ODݼ.44 [UDֵ,95)e ۈ:T%]BwiatqH>UqX!nw'%LdRԇN+)*3mNIPlG3C*fC] D DdgϞOZJm9%")_g!Y1DږrimcN)CC?BZ뺮9gO.3nFzy~iQ^1/ubnzXuȣ/<ޠrdB&"kmTJsLqYim޻O\꽯eݦa90{a='9aOOW^Ed>ևt77]g Jk)臟<>>əH@t:>}B 3U齮1&3_ڼeNl߁Ћ-S#TS߀z/i[LԚpw` [) (8X\&U]jkB@.,1{"!VиHEK8 q^WD)s\UòngD)"a=ĐRQ &b=C4,]WS !Ouóyhk1rD'n >"T;",Q(uPKq@u))U)W 5m=3 hr떏N۽BHn@M͈CFf$?}8'^kݚAD!D@D56$AD{nnXlZkBL:K/ɬi̱f*iiS띘ީDL {ED%kEB[#Z(bWhػĘcR%f)SZji%3K+Ĵ3U#NLd8qgO\K ):)7k)kC!nH|ۻ#q1Qm,` )rUTk)@$*h8MnYYٴB襁Z`469"QȘT cL9\.2Cf&_/Z)>VQr6Zݎ"Aإ AwQi'O՛ǿ;?>[?x\ՇΧ_|5B1M)a?G[ݻwݗ/_ٛ/S}9=.R(DCwLĊ(y`h(+i7n&8r4%m{pG<|gj unMDFPi&vvw*|{am31T):u]WK_j9Ck LRJ*̈sݾz.*KQUT98Lȭ7 H,nCa pUa0&}^GDYowZKLiS18Le^" bبAmTJ?{=aL4Ͽf*l:Oӯ~/_~Ki˲̭~h(\%&1')\ꁊȄ^kQuΟ6KߨCDP'WѸލn}DuVv!W]^r8%zmW04C,һvƍHLWWWXEEQԺ{SDz홙Co⿺sODT C12'@jnH3'l]}BYT?x)7M!dYׇb20WRo-sĴ8QQCr̭֜s뭖C 1`]\c!GvNsַJE$F8 1("B@")ps{;ФR *Rz0<ѫW/Ok˿g_|/^q_9{o޽=ͧ0?|~qouix>=󇷷˲gUk{{֖e!"5eK7UЋIHS;$/1)y`cyO0 cf903m,i"}~gsM$ Y0s)3cO'KRJU9T>p:.`STS~o||Szf ]"VgZJ_~}> x:u2 004dS}i盛îe93@3"o_I :>aBvPں.Z0Cֵl.qϘ.NTUC16x$d"B9=3sPEzs'\V(Εb܆;6zEDؓkTwq9?``R^@{ڥxASi0\_B-%`t:0 9dS0вK@D"Kvͺ~U9s4汷YdXb wK`U,+ރL1:\%:=<ō#uHq֕SS@z0Y2"1` \DbȦ8s[v1Vw4d_Gͤ;DA\#ޛֲ)))g2.><=>R>>>)#j"/ZyY>fPJS7)^zǟv?o?7>7.}O4-/!aoՋ/Jя>Usn?1x]z*`Օma6(4i ̶ TW@[qC\HfD,]]E@YZ9*Є YÐ[M)9qaAqd[C'0}ޓnPzZ{CDZ^z0Si޾Yy21w <{ū^}-jLaiTuu^b|||:?{v.'0?<>Ӽ*'@|<Uz-4X׎D֒kv>7CV ={?M2M$#N V6 E׭p?m6cݫ9wzhffB֥tZYZWikYMe8/'s\V)d3袦(uiHhM:!j AĜX{vKФXMzu͗ɸrzキT/6MIc=mƊ獈}<_,B!U)yιrN\p}sR{]eԗL,6u#TD~xiȵVƵDu^N0>?xu<>ղZ~?O?wߨe}e>&54N~&D${k@8MB\"(F4!"]! Ruy43mzl |oLcy3 6 +`U.zme{ZJUk;![zlLxR2ak 5jBhHML̘؍ĪơG604S!+Dh{kt\&B1%UZ38^!6"ڤs8+>" nU%f$e9z"] &>/Q}gf.NRk-9RJW1y@o|uYQK̠"Ha߫<'fOO]$@WWo)eF>ce]?sk7_a/uݧ}O)U{O_~e rs}wݻ7Liw>>//տ|_z_|_ş9nR:NܼRQ36d ȳ}zS]{,;ՎEi"Bf!ߤ#^yt-S1C!F@Hn]34<.Rc(MT/#"iՔD$]O?r&myYūƔ8x1jH!ݽ{njӣrTGe^tOիLJ[Н$#gni2&'A j-WD`b1C )|v-]tؙKq/@2f=@L/.6w,T/\ ѦwQh&[ ҪTu}N㮴~:l#.B Lc"KZJ^kJ alO5@wj4)_! >OQvpjn~f 0B$$킨9Z v;hku]4蕵  t|ZK-}C@@c=\Ϟ=skZSRg1D86+L"ŜpRK?Ko>Mu1Eŋ4Qܐ{I_&ճgl]a;u^NW_{s__8[n}vrz'__aNO}9 1?K]U:ݺ.Di! 5$"8ϧ^jǔOf& |9S9F&3@w7XU#b6?@Hj~YLzm$?oZv_ ;k0LiZZLQMqHRF !0kHճ[9}[-6,- T"JWhHTײJ'O0[5D$)ښ4V(UlD\@,nrJmk .+Z)")^]M7< ii.RVR)2ig9t<Pjy**RZnoo[k(JtZ!`Jg8ĔF̤׼ZT <+ !sz(]&g`D4Pg\!nj4$\"yj0 n5*O #!Z8~wX50ϡ4/WoߞNs2 (Tjv!iTi Bj1*SPRR bL)2޷>pl {(oCDO+ f6 clޏ@͌c<_glw d@24Aߣn-)"FL17:O kHzjhF1i͏.[Řq7xy3O5[uS(!]A`#EC4Ӱ{|xJ1{sw/˲v;L@RiRz]wm>=\Zny{5/^|勗R|j{뻻/?o_lϾaG5E30ÞB)#qm*u !bB|, @]vW_G4P3U$PGz7H/D!/ܱ`Ի";_L+ʜ_ǭ}߉fǭWq0!YQΗK# *CЍ)!~ 0 T 17Bэf)g@˲b{lҙCkLc`R˲io/*jcq)tQ'>l9 <yfZ8/<=$J1B퍘6zgCLL+=RD;svdW9s0r! Q:\i u;&'$wzԺ^xj/^Ⱥ<7QϏ, 0" ,P!ZI147y `qOckzusb'ч~ L;^?ɟɟ03}'8Rb~/\Gck_~_<ߵ6?~{ڻG;[.ŗ_2Xg<޺G<B&bG"C0 W&{4i?Z"h~\@-d)f3ŜR6|ujô륭ӛ/8ȧG唟|xf-'ն; ݸKԮ!<W}0M\z V,}<.KSյ%Q0MhWQ15$>#*k  T-=Oi͐υBCS3(l`x$COmHh]@Ps aq臟ȔMNcŘwiQg4V0TQ3ŜwI)3Ji((ZƐTZ"&#R8PP$!<"J l#i>Ŝ沆xK$R0Fe< 4^(0{Cp%,eBScbl9aZf>3(*fTyL-Oп !mTIXaA8D|,Yk% a^<]iiR!Qjҁ) y !9oZTDfL7 l߼yZw` JWȀ\CL!wQEՎK0 Nc?O??/~~㿡b_2L<< ӏ7~<{z[p5O.zz?͟ٿj]bL1*Pٳ/[+77e> )Y^00x/BD1We D88&ta$ E޽{&݉fK)KﵖM3-F{Q2R9JgT Wm. rNJ瀭0CbTD0 ym1"! CSxW)V<8M1J4Юz0R]Vk.EDviH޶VC o޾!@5uׯ^ײiIOOh}Yf͛e}Bz<cJϞϧDcBG>PZT_=<0D3Χ6 Ji !VU:pc|y˺t:yN%;JKy~P䣔޻!vnO?۝@1,DBpK (vb:};] \J{xx1ĪnMC/0zG b:ԕ_V_t*֥m[ZnkyC˲ 4펧SkqYnRJfnַ78?w7_Wo߾acJqa~_VZ͛W/Z7O~O;t<=}>:Z))Bi+ puՋw831u ^(hmC@8n\0ELԟIcN;﹜/[Nt"8DrUys^@--q"J` &F`>=H* C)e>Ho>agunkxu֥u)ev 'o~qeE4MDZ3Umm[!jY:=c&pثnJ㴿f"뭾!ۯ[YhI[ K-u'Đڞ>S5ڸz0/>'f 6NtUKUt8L[hfgy34QzJ8/3w SĖ!,g=FÍD^ئcH- 9lM`z7ZLbjb+ )j{O[-,IMn<`r9K#*Xs)`B@l 0ϟC ZKc4']˼RLd; ~y>MӴ 1 MC a^f.3 t1ˈT݇yVDsYtE`npV:^ y| )qIP@r +3:6e٪v^3eUi^!u%@5L@Ja^t{6 Ce}z:OM᧿ַ՛/˻w_}j7ZI)_y_|w.t:>Vo?c "믾?</?~[o_MO~ԌB^?1p:UW_~>#"ZxURx:bF γ7K02^hq8 Wk(bQHDqGu-HP P)fj*7i]Kmu]k+>E%h;b,vU,.hj"{4˲R`]z JDh? 9===)D`~a{w_No>]ʲ'Ujf9 ܛ<~wwwgׇb]O+#e2 Qu-0PHl*q=(M:] Cڻ? Td[V:s;29kWR ن9{ 8]{ǪBvzfY 8R̠| q\"uO/(ͱK3Z MDW@y'y8ǧ'oq]F"adRy0s8.r:1I_n 1/|&t9|J/3{, *DtQfoc*N!D_"΋t&Dğ2Et{Y'S.ⱂ!$U5s3; UMQXJUPa&CNpw}]aM1a۷o_ݻuY7_ϥu=Ϳ?2tMZKϰ}RfBnoJ__Oo~g߽{f]u9}o$0e OC(J}Ϟ}wW'f/TbRC54*-]Ǎ9 H 4躮WWWn/y@CÚ!{|'" /tcHTzohK|5`*^"J@1&DiS~uJwc1tsFJb(j#)^2b7EU'?t*eI5X[3UMcHk]R|k顔:Ɯۺ:@aW7UiTsp rC&5 <pM&6E37̭<]&imuC^^6]K@C3U76pc1b~wqD^c!c Dwf&f'WCQ6mtf6m("&qw0V2`K-Ho RDi߫jD5CgxȉbHbpPKz\gn`Y=/`b-vƵ1MT i8H )ytIq)Ɣ<2Xs)/^nx3u`kzKijSjMTks1 {wwwoOa\׿o޼}|x8>=n{|?b~]5FD 9x s1Uzk՟a wY4j~o'$qA-?⋯WWi}:\<`涾,9ml2Cd3E:whj.QE}뭘)9ЗX [@TՔٳiW)F!af&Zqu57a5^51S/_e-_쫯ַ>|||5OӳJ2vv5jqH3"##x]E_4/|1t "jDؤ"p몕m&2&S~CG[ Y)k;M!y1ptlޛ:AU 2 qȬf˲xzQ:yǝ_`w3 TTE6c4, z՚<ϋSyb AtF)ݻ7D "MZc^׵JȢZj< #0O|:6ջwowwo`A#c+%8Mj'뛛ZKe]BD f1kY=b$zCDSxݺsdN9燇Rf`қoL)|b"/[뮷!`")"#2 %c` LŴ9h#eftN0f s&W0~~x赦1ƴK0$?Qcv Wk@r<><h(e]y0"f4 /|y}}E{-:M2^\v[HF&PY{뭡!!&xD|xOf>aD̐T @3?C05 jQ̺H(:b1q̱FTSzohDjD(ĜqXץF⋻quid(p\2@}_J !FZsn뽗Z5Dډ88/˪)8z¸h[%"}i|{8ƔziABBvVy !R SeT^[>>><==u@L=]k;Ӏ)0d$NƘy 0Nu7#`j `)$Bj2rgt)`.koooyݪ9U$^YTX U'IFH1P;B`8Z;!.eɳeJ1F !]HD]L|J1`Z^Ã@y0ǔTzYSJ]!z)eUuYJYP1vqy=Y+zo kY݆ETy$4unmW. 6#Bl9D˒ݻLTRJtX>^Z 4ωAk9B,@^9# 0iR*MkRʺKBRj-*c x9묦D>_RJ2vRg/ ɕy." 3d]FhzoWݲ,!09į>ͻ4 e]RWW11$B{9^fF"rZ[ B-̽븬|[2M&m,(uoD 8RNw14M'608|`[]v<TO!#v0pT rsV|fBucLV[L@@\l>Zۜ"3Q뼢NM9bK) 90 /x| 4 ZqOCJG1a]giR[뽨0jm= i. ZƔEtYuɤBiv^VS.W7eYD pvþj!Ʊ@;6ս fL@)0 k7+EKm)E/yM@Mٿ)McRp^:NSE3 wSop};}_yEOaw*]$Z{ CӲeH1F<.1#iH+n^Đu kgBRD=u @jEPUlØLB !UcNq  3መtA"!Ԉ( UwADG(uipފH[ED{U41ܚӴڻ552FݸK{mcZ{'2/C\sNiPƵ4QELqYK:+b4#bJ]6wQq 3F݅͹-KT ѐW]]ԻR(;㜈xCQaۖg!CHһ` g/y!8x3agjqpXZN!bLTj1X 1ld F#Q %0uF/=fjm`  }S(6B3mÐ01 ;EEZ3iv$Ӱ34S|zBs|l`hd%gbf!$fN1Ywgm6z XZuAú.ƴ[ūF'D @ (4_j^D95lhw*Cq):ЪiDaY|_}ujVSC$/z]H,~-YiCŭNzGj[,ou%YR(lHH?+ٻ oꗭ ޺;wF#c΃#I#ں k3ں`eSwO`qLՁ<ͥ>p\֊CaYB@33a$pXkyjøgϞ=<==1;™kwVg/bL< 1FD{gtlDιwG*ɷVc;{ȹK~z֟C@1 L`mͬj81,7Y"Z˺.8 v1}lSs?!YN)b8Z|!Z[JI Sjm77ϞS?C_|n?RynCkcL)2XDR]aqՖC$m&CaX.c`BsβD:>=>g MLLTs9?_,ϯf寋:ޣ`?=s>8W4[dM{;jC]/l5Q 9b>ǣ3BT'. *қRVwM˾ wTz1VOfϨ-mƔ隈\Y~juPou<<ם~I}:LQl^7Ss:DDf`p]9V` —# .UB`)g9e!uqemIK)KcvdD]{PJ 쭧ELB)Ck]{teynZ3/3-$"S95q!O`w =.1ɶ-^! ^D %x~`ίԪ*\|_H(No^Ö%f9Oы&B@L`J@~7 `Z^=#4'y;F#zKTiڰYT44ӉrN)U-f1nS13;pRQÔivU:QLl\k+YC[E'1G ^V5W/cj3& 2!u_`b)+9RN:rPǍ'49dҝ}޷Z+Hڥ1|mսYŏa|.Izo@&V{ﭛlmʀ ]bHѶCv@]`jͷo@H]:"ZJ61k_1k+Hg$͘W/,5߹J){~U5L11@sJ׌R߸m o웝G|7Tƕ3!VZV1F|||+VK`}JDBkiæ)Zn{Yu-u"O7VfҮ,{< UBˍ|,(g3vaK)R%b$qLc {h< g&I/NUSh޿v bv3yTUә@LQz 18%fh7Viҫ_n 0>)!:.7[K1):s)eG eu- +L[on)VMfnWNk]w9eOOO(vkRrki5ppsZՌ "sKɘy8SʪZzlq<67aB!瘽K1vWBK3?UU`.NqRe*v0e'Yg!މBD Sm޸t.쐽 :mLuH)""!5 7e_hE@.G\q_V T6+ "깡J(two}4!vO+cTDE#ӿn[*g!Tw),ÀrJ)( 1E=h+=p!n3o 11(y"k@=Ճ"Wbkrr m!d[jcyC׆h]U2+rIzWqk7ygULY ϲIMC Մ RkjSFoVT\жFzWSqi yb U~.Sئ5ހ9Hg{ wx>v'6[ΛiڙboF2q y|H*'V(kdXKbu[["h===h efYfqߞuAzt!f&.w˺r.R}!] EBjL!@10Z=~֎H9 `h2Xa?0QHC̾ qton=x@ܰMbp\/- .5?6Mġxnc1-FѽZuϯ >:|a[ҹqiF8}|4athU)HQ!HF$Zi֬\<wy76>;x+[4ߙaWv;woz|e> 'lvUuDL)!Xk qP =7H)Ewm*mn8[.!FDC-O/HZEe@}Dk#!e>]0i #h.|0 A-F"@&Cyri7޻^z|8[oU 3!Ԁb 4zX,y.[`!n+QT$P.GPߠ0Cd]մÙ G %TQقy6iُ-7HK]'℈pnDH*mzM5p浄pé̼oBJ)H1aڥ!Z4V7MonnNyIu_neWӎeZQs !R~ͿaL)v{݆8Rѿ̞^MgVi!?F̼z`Kt B6Gr:QZSa7ZT%7[Lr%IwB{SJ=yY7:Y QD]m8u!n Uqw3Z ̛GVM[oWQKY! òΥ,)h]q{m 6Vng$w֛njR`u/ޝCBW58YybN簷лo;n9<zﲮ+jz$Cy&뺮+3_r7<zp7sgSjߖ}Js7CH3 TbJ)Re!M> S+z [s ,NDDUs璎db)uƤ^LMG`358db9Yg@ubrO \Ku׏hWi! ֹ y*BM;j p93S]/u.:E†R; ܄S)WǣRrLN4x@Lܻ\5 x[eFlh]Ye ;Ӑ!pzcL~z2S!mȞ KJùq\ZW CL 4M)ESaRJm42/q=^cȲ*MelW&8HS&Mjs[|0Nem8ZTeHCNYUwDD0 ޢVb10s1!zԜ.oVWR?߼y|z@SY,4N/ 8:P4/SrRtE%8zz:D!qpr`'Q!M}Sv# ?adI\ be~ʪnt@C +[E̮p(h23u73U53,!--Qu7SS=zh(`fHuLȓChnk P U"fxXjG6|xjk)u=.-zo;gf7K,SNiZU63yi{u|eo-fGPK?r-e ڭGpiAB"uE$X8"I""YX29]Yj$\ѴZ8;睉 v!| {LAiaRkM̻){.OGdww:=ι$IZ<ѮC¦PUw o8^6јC(vZZ+_~u7flj^$Ҡ͋E_a/z}j؊ZU-ˊJ2ok-g//~_Ps 檪6٨pgw3!ݞBo^UVkuu&""؀x,f^ʞv=}YW:9 eat?؇ *3BV3&GI!as46y>Nz I 8T2IcRciiuJCu =%f.|O#O eB(m']Hy{qNOOO&lĻOAPmxlͼ^.W"2{ˎbtfF?yMzѵq?/~ƣ^ ItsF!" 1([l ?Dz7LU}}} HzzzvjГ%kʫjY zSe`c /% ZLOż3;0  z9uȴḲN#f ֫PŇ~#1SwD9ؒ/5A&"b9"VwY֋X/Zk`ebGojiIyYiզȒU":0HXi.(')J]$tf&j_95ǃ}N{5X$Mpihp?щ/En]]ݐPdxry31gnOwwgiiVi ~H CR/Lt8gd%%"I[׿ /WUM4y3ozYP!bz<뫻oV&oiIQC w=^}Kzb!1fl\K),IM nRz}:ax(>)-`9hQE~~pru,:C3z,9"CǗhLr\Z%] Vmf[]f D)Y֨慈f;s2wS]y9̽3Wjk-p^#sTUaȝle \BdF!TqXL>*,.s?4Wݕ(A JTw}""6h'ig[kɗ@\rh@\I1SQ 8 uwz4Pmy:KI JKkA9~wwf,|mU)Dx{b v<ЁEp8>9< IA CI?̴m5(%M%0(Efք! ݣ[:*D$2& ZuYJE"Lwצ4ǃ L6'"ՔBgIZG-\ED m"` bw ܉t :\"ݐ/ 4E,nSwUM)wxy~(9qɽeςC'õj^Wa֪b6) k~Sdm|4qW#hGu[v^"#LcM)Vɦn (c `̻xtр<*`:zkƗVi]ȑGU DPF_Vk)QiC-*0Uu]GUK4O/} ;jj9ׯLh1eBLwXUmMs1ERTʾuul7xpYק'fkH".-==װpdm}/%llw?Qٴ{i!7Y0݂F`(%Ҳ,*a*''h0 Q49?-e1еO)-I\x?ҭF?NpB"=;b xENSK5vĺ{%*0ѠIYPz/u{!q"Nd 66 }^1|z D:NBHv>۾+\{DB%ʾǀ,+VwbBjRNLIUXM9qwWә P룭@`$zk4ڥ LnŒȦ@O>f㑓O?4WH) Itbc`xYDWU7mn*>Gjq]{b86x"9C3IQB!ޣ:"VHUC;S k 䃕b  ׂ5؄cEzOC[knhC<ժމ\Uk-dfڌ B\C1"~l۾풨=MFZ5Zj L`eXDi)ʻZӓ s^Z̝!\PXǃ$媵2v#!BmeYr15[.u{kD)fzznʄୖ=DHԚZ./㾽6kVZɒht_dƦ-RJ,I 0SK(D}3L$.߆=4Ć 1,4R$DLQ uHpͺ@AXjҴFG=pC<42}" 5_Z$*L BYmNfPUKU K|_c9e1Z%7Ch9Ibnt]͛29Y.<@K=5!&avwh$6ې7r!FjǗ;X{!rjfMDTt8HKr `}@Cf5t%'avnls  I!~%$Qmj-W]RZYd0 7}47ֽ'뺤t>9m9rM0c 稵3_ccG^̌"ggnC kZ v^ w:x,ޔIB"D"C0ĞO<{t͌Pz6M)E[2xP嵬 tӌ}y#"m@NkkjCaP5yoDO^RJ}/ﯯ_}J8/85$#1GpXoU'AhP@Vۤ䜯^Zjnz(#Y)%E˲<@cep,O"LO&HEABSS i(ixΌ\>#9[a;m]z(jTؚ*+h8TTtϋD$Bսcb N5grG(x ]<@rgbk ae.!w7* p@ 9>$h5NT9e'!Et< 1p߁90f r`" 7mVhcbF*+}ڐ63B4f;s=N(iJ1M$8̶?6w{@x}6MtS1`-fБb{-ԩ0zCbٷGg8`4$Fj #7F0,*̄µGUӐ6!jS^B};"ZDNK!|m?G$~jlcإFņ3]wtͩݽc؆:= P[q3&!$@DD^.Lu膯5.`Cu]RcAg13AhY9t\j h܂ώggӶm-:`Wlnfֺyx6JD|USJ^PLQ>u.8Ho/;nv`c&`=0Gd'"U wMp$C\bWdv+3u+^8bW и^xЍ%zXH[m=t c 6"" ͤvK|TɠjnRx4AqZ^Fnsst "R}F3nG? 'T=,AS8I<VCh33sg6z !5+!8Ys~c|>ٹ,n`Tgh T^0.64/b-IkICq36A0SG=@>|*GFC*yI67Bˏ+C 0Y[@1fh;t3tY)w.lbA 1))弬+ E3317 nmZO*~˵@BZJ)[PqFօ`s\JaB`13lejn}X)}Gt_ZmE[Ā" E),{H)mzn7-83Al1P{S 3Tu˶AUs`༩VJ8f{m{gH4B7FCg\ 5썎nߐ˿qYm2眷mh}{#al2 ^6Nk\s\|$YOFW@,irJk$DCHacԆ.$sC3\Z!-$#i)DO%BO'j#,pwWĜrN)@bȠSJ{+@k-l\ZP^ S!Wc>~xiaJف̭%te0$I8J0[4ڔLD=9vsH`@@񯆌 I?EWw(Ңޅ99`(O nA L $H>& 9<@F9 qkͷs,9!ex~~QmuL ݝn痗g6pMk!gYHO㗡4˅K[U@2dm*!PZs_|^/)eW t:pI2v}߷eYȥh(PkMH0$$!w -/"ӓg:7H't=z xBt׼t.R 1eAʘud T-v +ȓc9D6ޱW>џ{g΍0_ CN8"ܼYJÉ\v.}!|`镂똛 CKZjEe1ѻ$ǘ b((h0;$g8(jj}h fB QVLD_|RwtFYPDxdv 8 FàH 1+J)<_4'"H<#paɿx6x}Zc}qZ!LJ'|(ݍD2 ~@L975O* pɋ}~c,D"H1Oǀ,"?ܻUT+'0mDc&$J,DTk\.0e"dzn-˚r^uY@Wr"Ew\_}+3+23'}Ps'RvUEr"HI/SkqIشMiRZ a|h{."Fk^[mj̵Dk R{ g6AŹlfu8~9Ů? qǿzO}\/___*29[j>J &3](iƎ+`NԥIT9S"2@3̡w:^ BDZ'|/Qyxǵ~jS/L'ǮhU0.Dk-􏿿n>+x7N"p AD"6bG4Ե3& dd x"|r:tjZŻi8G'9췑57ZѰ15 G@D׉ѿy @-‹'> 1}V1pAB}߂q^hT;| zޝozCvwCuZl~@trM ! ֘hl\.Rkkc/e%PRJFRBUUvz1L+DoeLxX?{m%.&Ώ ֐)ֺw)q8Ihqw(>^w>6-DւT[ Թi88!D#LHQ<; -(/(|(GnCƙbr?'t?ޝ0%Ԕ9Y`0[iRPSmV;zQHW;j9g6֙'z(tuѦX@yYM:22ZIʥhʴo;1iS֚2cW&P!qf6LݍMcވY(163AI;s:J $<^=,4B  E~^*۶?Ppc9TUj^"8 f{?D*--Gb,>F" Y >diZ457#9 6с#"!1!V{=kӜ6WGʬT$|x(OH1L wj"0)Q氮kZ;<֪=(@,eoٺ.&K S:SΙn\!9asLˊbE!-iYm߷r. UddK$PjI9%Zo)I';@į_PjC7pY/SdWZx;u-I"G$\kmXRuկ~vw7#Zwh#.|p/Ds5y=gI{myOߌ,r#щ6?^|)y'?dw 2%B>ܠ45 [/}۾nx$QfNdo8 ւ[69>A?I/zöe/"D8ZgßJ+LsZji͢ygPDC&R\J[zWJgWnES89S$٪3A[DRJ&fP[k۶O,-W3p8չ{ O-3ӓRjJiY.euF>wbJqv{\[%JRӧOqHe4$b#߇P@o$H9t`ch #ad=t,%SRmM[TZn݁5%6WP>zzz᧼,̛7:/;03B$'Bv0cDXDu\m z̔[D/'2aYB6dI\#M/r'& #{O(O|#^mg?ިм `¶m!k/md1'RݜѠ 8fL(W$&N@Bq^VX9Z5Dtd&գl1`&ijؕ-dÉ]ȒcL;L:%HXPӜelDnOOO8~\q}~.yY"mpm )'y& #8%>\}1Ç8ZskBtvǶ0I5Z7EyH-uyi#H hY|OݭIJxzsJb?h=EѼ|G?YMMt7{mȪ=Zya`ח3ǔ]B)f:ˆdn}/Lj6 )4c>dfKS":2NV"wa z?@/·[Pb& er{y 0"t>??o_%YCRIR!:QJUU2+#MBzGACgId-M9d(Οc T|xqR.Bޛ>_ݕ&|z  t8z] !"ɒ`Ι#e_)PfηSPA*RѵA9"p$C$)#eɒ%p&J$L18+O֚^A)"F>_TkZ[Ψ0R-Dqm߆ =uMU50L ok;8+D_ "E Wjf֊'ax ggUѭMt'#BNRjUD |ӫ ռpF$yRBNjfc2Kƫ,Kb5 #淯~9;&~x ̝B,"@_# }Db8=1>[v^J1i %-5+e7R(p`x*Ճ̌,6sGGsmZV:!b SN41 ?UylQ缼U՘˾a8RZSeYSJ޽gLzfҧCcɻ5@P0fkzsPцȔoLkt^Ä2u й;e34kpv7wƄg~Z0W>f;)8֕\CKn CG2eӨ0HN qPxG *poqf㘎@ &Ńأ]5|scprDĮKl][OƄ漮 c,D tEYZeͷg3KIZRv&OZ{lwP $'mĹdSR0d"җ^`04TuVKHTPdB~ bxkԔBRU{u.(- @ hZ|Ѽ?Q hMq\+ !46t!ڠDw|Ν1,<#t.AY zʌL̦=^Z ˲*Ӛs^/HZ#o5ln)F‚J)唳ZC bAd `;ȇ/{`=zZMr?3wGGUEo~YuYb9`JyWqo│Q̡ljMUywb1>Tjj5+D $h`#7d1誦㓺Rٷ$-TK(tN?0?|ӏ?].ׯ_>7?S)z[UopRJk5^}mL'GE{1RRJ' { y2w'Fv,CK\պGf7 Kyb>9c;]Xz SR^t*PZ 20ǧQ ?4a}pw&r:@H"`NzIT;% &,;HdYr-jq ¸ N"YER:ؐR{캝p!5WfK:fȀqژQoaQ(NpӒ[ӼR*1!1Zk :߀m7 7Nߞ 7:.I=Oԝx,r/ `!')#x6i WB_>W@:cǛѾZ!5mff},}ۣi]>~TkUqfnnM"B HGF"af`<%< &akJ) ]z9-yE$1s۾)IJI5}}}uR^L[VfBtf1P}<?9`T:C" xJ)*3VRkj%brJYThєRn_~5BĜsmuR{I8y}u>G ,ԇ42*=2gBF2+IA3[E".'0CH ^6MZp=cAIJ"o]RޡZ% $p63pa b&dTWv%&Ppu A60 !%N-fCJ-%ZKtY'/<2#1xLֽ:81hA>n{kM"UL$q)IϠqԋ;S|&/,yGbh 7BnO 8qiGb MpqL>RV,}kmw`;\/ܴJ5uuY}ǟ⼬nֶ;v"z "r6eY v(!J/ Y$\rn5-Ĩ=: 0[m9Jix%%%mѭ,5'BfV f^31a̚6FZVRY8IfpuGTCV!wAߠvXaR^KSS|bjQ[厀MRcT3SW˲fRrhf)'o.DXk '),hRmN!:Ae5iLvTgdiRu@fг؇L,,YhAdO;X(;籟 %DXmӹZ4/b9FXݕ$!C hҸ;sZuc c +>LýClx4W<,9yXR0 Wp;Ƿՙ|3ฤ-Fgr^-q:KX:׏DoDApTJ;'Q5~FB$z<.?,__9$˺rf}$9xZlM[;)'W%/m~Y/,BD "21dKHDݶQF+ˆ]CT/GX-z}fm:g!tޗ\cak潒i{%ZddS!u9ef!}{9Hlң݀hʈ.0,cüt:kZ2Wdz=Fc{ T|EHA4K-Z 01sYEC*~ 8D){ ̈;(ZU 9wcz7z[f6$!z{jj"{ew3M%\Ck)C3=HC80Vb$XJ &G7Ub(,kSž<߈{( H5"fZŇ\SG<8bd~=r9ej|Cb n#bM?I4POBCuE2>nбsa!ҦF}dy|C&&nF#PfFu8Ə>| <oG  qQwq]Ins^ yMkH fA"Cv8h>u~Mg2u 2!Bo#wl%R˄(s}zcf'ɡe" A@w5G wz'bXxȈݽk1L)z|t./ ~kv>k("Q"D_!-ѾAdf5Ⱜ 6SӘ؛ÜסF \k5k'3Цs7 "Zi?I˲\VDV3AÎs2;b ^ i!2W;֦W5!\.?xVX^__S=.l@Հ\c66PJǔ21q5%@0hM5.s=)35r(ci]$uY#Arݠt9@0⬍S|ԝ^St9zG23P"^P PkNތxV "Qd۹sCw 26TKm8;CY|>fh#;gng b"բX,u{f!PzPޚrZ#+"۶EmeFkZQƐXwOQE{0јS-˜#j#?7}0?iX%V iCHBpkE"qjX t{M}>\]| >O1CC> ƲBCں|3{Ȩ%/] |Ld\[sc"3Ea"\nҚ;^DĵHR3U 'zqmۃ9%f&&M29@mmYfZҢ۾_%:A7?m^@UM+"n2Nb4>7&Ip=.KikЍ y"#Ǥ31 ``7ᣩ- ,4PXߠ3 }R1ɔg7:Ni8= !m+x!|B! #(L ]c2p(Eˎأ;:[@T&!/ܾѡ'FbNIz.땘i6d$cۑy].;wSw8 BX6oRow> wmp?]ASJó <eDHΰQ(x7 mU;9u0Nf>Ɲ=4Wu)Emvr%ducI\ 8!q<#,ƀz3wr=OlhD`B $4ޚF"%"I!MXjfjm^TT&СCÉ #djm373.(48gH43soF'1"b GG0 ?%cUG-?;\G&fÏ pv=̉LPrxwtA:O~ܮ7`\ 6 ,6,Uh(5JЧ;df>qfI<@=l˘Cb)ˢeauX0ŚrYmrKYqk*=Q$;x#>ũ9n D NV61&C j"~G X96tx)9GxW.Шs>w;z,<,zu]gNPtu0$faa 2wjHh)sHvxxW?f9V%^T&T35h`:nf 64315Z/ZJܖeuZJӶ=z޷ BݖΩęrUt߉C M[g"/+9A _x/e]Vk=бx3YQu R&D̒ǹL"Ð (w {sWt| @>ӯ9 ^DGX86G ! 0zbNaNTA?Fs1@1w # ѐEbj`TgK.k㐈{P"1%p4 9ɀL${)ɒߛ֦,,X20V=??o=DTúaZG0ѐaF:ƈFwz`/1{c"=D3*X//ϮF3Bdh~򺏚֪sgj^p˃3("&~@oyC|#|Ê9s99=0C,}3-ÜRBf3mVN,^}󛞲}*ЦxNE)+O?\kuRʾ5UHJf)QZ~Ln3kږ%rb3=-)gIfLm$vSPK]? „Hj 2E&Y^^K-8˵_r5C?eIU )IZʉOÐ3䡓伀 H^o0.K,1ppa PO)圙S .371 m36oN5GD?RC jo2mdc/wgH qn7@49gs2a:3,RΣܶkݽPSJP۞׵5%&k-2EZ3,=luj>#e@@6HCĜZ HYlږ%'4fjZM[1afxK0>OzUɱtñD`xA[+`u-sOk <ǠY"c7qD]7CL9IG@,f:`H.s6w5Ibom4ȪM@Nt8#]/$3mNnjN6걾%wur{Z(aдS9R?|xpZr@7#5^{k- e"wÇHO <(?,ZBr,iP($KK˺RyJ+%X///͈x߶%/U"N)۶9/hH('I_>q'@vWWd^ژW`fjőռ.KD؜G9ʠ@\*j!gѤ {H!6c$<ë+xʌ.4|p.<; $b3_C jN#yAZD5!tkURe\mAmM5р"^j47'Jyu D,ɎDz `wab,uz#SIO)F*9ZLmd 0G*_8uYm: 3;ZGÍ$jk.. c+"c$)O303 ZkHjw \q̞nϒHJ$1PjYו];ܴUGE?=={J>r]l("U-fK$==?VQϞ(:=///۶].>~(΂KBtݠ眾~E9rvTPDB3z6G|CM3iPRIDAT΢!2ˑc ZHQL$f[FLiLߴL 7Ρskdn$ Rԣ)%NZ5>,LCV "WD3ZCm'[plקOx" cD+ ՚y ӣ܎s:QX`Pk-Ɲ20D] z% Ӿ,ݿ~SN]P9„GRm/m.ǁ&ѭ<ŏVk=Xf~pR-&oq)ԊpăPJ E,1p$)2QbQF!}1>Rv>u3@!N)3K}͵T1 ܡ5MLmY(jiHt6fx%ZKYT[thZUOFS@(ػ pi{u>$A4yyკoGmeߋ##S)M\.㑗<֚期m3m C>NQA7AQhf锒8PJI$|xYAD뫹>??Y/e/mw:}/u86DK:vsHsǗqw>WχϠ aodBDDdOQ&/tYrXW2k9̒RrCX5>β,DDHu#Umvwub9D<8-70jI`A ;"2%lBQÒB~cN!I|^֔R%pke]*)'pO9Ycb3P'6?\g7j B|HI^h^i'^4w:jH&+ڰ=qY  ˺"TKI9wvĥH^v8x`q @tr/TUR޶.8v>`T߮Z[ wWQ"ċ+3'+cY$Ir,˚DmFD˲n~&1AӅtZ]+P2,(|mɣRe/BbMo5v~q]Sޢ7f\.-I2 "⃲5XY!R܌' RﵴÇ( jx@aAԛp}&Qͥ;%PԱt?m89L|Auޅ ZЧ@#߳F~a0;ة39q^mY rCmU"dBh/˕/~x~P)(Ʊ,MDRN$Rj^X͛*\cojSm\+R_'EqP3%Fy;O]1D䧟~FDԐc0 :"1 90#@N)q!ncӎM5#iw oਦEx 0(D>!vS@&s$0;Z)5]%%"#}_׋HRBfš* H5/$uRfУpBD`OQje {n#< rD /"YWe# X(̫OZةK AB8$FIId%/yY?}?헯?_\-j3g٦n۽8]?=}HǕwawd G&z+8yxw-.#I?~x h^y{{'u9QRV'nݛضPZ!!(*ܦjZ%ƣMUk޵) .9uœ F^"9;`T䐇sj&Zk̏YA2fMNufB$$W4WkZkyaɟɿ!"7ׯfr%^m];! 187==}$xh23v~ Q]i{qb,IjZnAl{r朷mR'" S21ؙo}FSf /G~$M\̝xctr]I#aHHabVR2u]Zkv:kK)`vӈ(f`kAkݺ;vZzoLuxPy~uVÌhK44{f͢0DԺqǹLfsB;dKe+뺖OuoRsFmbڥ޵"^31٨L'vZGGh]NVÞ0q!Z )Q;Rʺ^xϏ5JӶ"ru]V=/Z{^q }+ejCLD1bGmJAL),n<(qӁºGۚFv4fF)%G\{xR"|C6|173z{$í oQ GSS`槧Eko3LTSҦ>|_zj޺"N@Gȴb5aVUVhn;nm$< 縜nu;+TH$-ˢj,IXFJC\{_ibAaA8E29Q-E?Rh>>Bїe 6wEu讈ȓ=Zk]+DGf'(0}+4 So- s>5& g.16ox5Y]狽;Rk-%6# Ik5E "$H L{ٗ"RK \5`JKV5 xԽՊH(o UB˲tW85k=KUnO?0&֒s޷gC 2 T9­,[[J??VwzYzKJ3 \՘˺~eYnOy=mǎ?Rczz/f  RZ,{m{ty fwgvsp: r 8w\3EfIfsRQ86uo ".yuXK!Rkݶm1%& 4LFv{޶RJq6C`QGL}-8խp8ԁqptl#V"T[ $g;XΒo˒C/i^?;iLN+1+ Sb`r"ZO77U  K-1w^5c8S7Y!PkV۔;wo3 w:ԻBGCCwDP`w ݏbKaE9P>P9=oVY'o"65,#m:8YZkrT]D('֚0-Ut5$lE:Pܐ8%N!dMb nĔ`Ū걻Up,RkeKmdC $GNv{."PbF=/y4maVD{Ͳh)Ů "Խ ɲ///Qwu͙?ɡ{&d0۴1_H5fETA[ŬZgumZeYZӐ/jcI^o/צ W`B&VtI9jӚRZ]RFO{ixInmx_lV1ߊ~_{ w1Wmn1b ~<919_Hҙ9*st>D~$C4}@v 18X7PπJÊk A2ԝY̼>9OD|Y/U3Wf IK$bAskUG`jч@2 p05ܛ=Tm01!2#!+5mnD7q['U1s@~I/`XʉoJ%wnYyFl{T۵I›Sz0x`F<̠GvpH9#3Ť;ҙgy?/ث3טAj|=q7B#ps$ 3?^9ƧsНKbRj3cؘ#{9/iYTM圗Y8%I)o{#A,|(9=^_u)ӗ_?|,//^__ ]SRض@1J{&A˞bfIfuĜ33cۅeywTb魨vK p%ZLfښz?}QJ)_~)CsPS׹X4NSJFv>;3@$:?ćRE:¿CNݦuXywQ 3L><18Bx@*M1fz_3N)0iWnB jUU:Ymo-&'phmYSc=Za#:u2cUDÇ_ikA6Q-Pm?1!! s0.p ('4_mXpDO=>v|\vͼOs@-v(Nc{Y¢|8hÁ OPy;3!KG !SIOOO&cauGD!":x\ %wgIsBUEE 6%R4X9g&@ď}}n/7׿?w%RbꦥDQ ~yLIrεT"Zx0SS b3Wս$19;NLEbafB۾ZV$2Ճm1#lGׯ˅[=4uٶ 4OaY7 >~P':x,-i9՛+yάy*y0|9pʓ sX9{ |Dȇmy<߻D Dn}q(@DN>woc$ 0Xqg#2[NnkvNkhQ]!s^ԩq3O˪ PЙMb̍Ki^DՒMI$0 z: λhf'盟G>M{|ňw _)vӛ#~) LP'Ga9_&”q]K^6;pcQ5'ۨTLrߩͭ> OsE)fjMk3/ JaRv4>۲,H7mǏw"yVݴ1# aG2^e4:sN)}xy?wNj!EڍVdDXN9 Ź&[)KѾNz#ڶu!"bU]g9"`(zU3I(趫~ o-sy))1Ĺ؝o3Ax&)::JdfN)6YN>7rOOu2MYpd**8aC^jL)%aJ{NAXĈE.w%W= 7S;zqдEIH@mfȺh{uGY0MWFcB|,Vo3;"ժ-1{eN- qyUx~VϟeQXٯ_dLޕPzgx$ # sNi#UuY ܬ5K"1)e xSU]%nꦔf~Zz58@bmIjoq9Hp#0)75 1zx>$Fߛ9FMcpy85 Q,w#RQl`C81"PtB df#Ư4^qxQBF66d QM<-%Tw %MHd RB_ٔ ӥjSU\;:]55#vOUw̻a~7 cΘIy ߥ';pGHݹ:eMSԄFL8) ZZM'D8u#jANAOw>=[g`i9kSa *$Nk\/S*r߷%/\1 2RkR~㕈k.tmӾA2Ssr2/#vٓ@dYּ2ra$睦9˶\˒}Cu]̼r[VaY GݠJBU4r-S qOTM)~~6^J 8+H<ƎFDꚈZ)4]8]8ݶE$ Hppo 7kd+4HiI֖%ĦEU1\IA8U?!<ۅx%awxᡕ參 Zح2-uAl'TO`̅| ;?;}vޡl#BY"39:;Ny0GlX%QYc m2ʸ3%"nR[f* ^9p8  e5S Vپn^[[֒re7ZKU "~z}YZZ#'qvպGW7xe!B[[S5e,1BT-e1u]ZѲmC8W{Z ) DGrY.)%&//m q+Zf BdڴU,LDS]׵̾~U-%=fgj7u]Dxu#b-42_6Ɩ9~>D55u惈V4aGЪ͖8Oo=a@XQ_=d$F$:sNa!S kmUFK=V>;Qakӈ!l%-%ˇR.%$S muX$DحK9dU=p׆ZCa,Y/yR!ىuLr7s?o)yG 9DmFMWg zM~pTRf<-|MI<#3wErY.Ap׌4z] aF91o(A9Tpĥ)IՊH@DO?_. a HœMi<$pZTܣSR"rJbw3 Z$5٥98$O>| (V~ݷ{RpI)kK)L90q9ˇ/6 " Zzƽ 88mpbLws}Gۛao3#N sNHoX:xjW#:q+ɛ 1ɲ,qݡ$B!dB&m1ژC4X픚{TB;'chFGfs"%1{y 2XӒoA׎zx={B^;rg-Lܗe]j#&U9K6UpIzzVreGI䮭6'b8LpjNw=Kb:r``a9[Еf;~c:E9s\> !:6'ikw$?1-Ai-1yݕS( y蠳DIA:?F!#*p 10މuDո957'U ]Q`dJ"ɣEF"Hȉk+BĄuۓ$5 $bjl)Ir65\Wd˂$4Xc̻̒yH;9E$~^J"rڊjt01_֋rACbj_l۫jZ,+1 8p0HV Z굔F, QDAk5, |`CݚDn#D ӧOqT{rY)\G 9㏭5rTV[E (:#X_LakAFGíW̱W3)6_N|ǹ=5w=5'c5ӸcЉg<b]2{Z Q=WwD-;eCmN9sFI'RJ)$ 0`N; 2}yS ;9k^ 8j*fR󋈸) hUD\eNx075{P 'x'p!N0ouDv}z= NsM|DٲTt+o 0؝tT,8lpTEKʱG\i5RZ̼˕S5MT qIiC[5!" ُ?BUD\UM ^9Ň Pv9eYCvnj+%\JeD*JڴjS벺$,fӯ~^bgB~'LTE7 ̄^[ )i JZfh5;˂`F?qInaŎ+ s_էԗ9aMDjFHqIsݎ@:hiPBN+Ɣ  0# 5WC3jeCH{?!!GP30ptP( 4C鏯KSaSWMC4jMlra} ®x!$1Yf|}Gݞj$;<Ɖ@IH=#chF||~5ROzO_wK#缄2y>' >:x:ҽ[9m0'#׉})hnj)-D2bvs$v@ HXj9× pLr^/XZK9[M8R˚N]U㩊㱩E&K}2"m][;*9pa5%j2UkSueɑ"-nNV$Ru+xݮOO_^} 1_~ #@U%.n1 `*ٌfo{r \M{LG:3"2 b!&9%Ffiߜ_qPl.`B~ŨkǸicM"<[sQ8M:&7T<ǾKO);!XE0x7L{r ᜜mڬJ̃=r{͇`GB);>p ~w7Pfiil~YWUe*M[b @PJr_5ݶGOh 9yqI{mof8bxm/LmJ0}߿=TprD;g(󈲷,RL ?n]f'b'dI%,DRUeƔr_i/;Bg_@r7u{yy1V6b#$fLϷ'U&3$B lsw=S^pÇ`S8`-`YV0M`vWK9Zض gu?GHKεV5S ,fY06w%=A0΅磄oa:ȝ<_y]N_[œty\3@qC M%↓s->l[}8Z zo6h0xdΈHG:q"fG$>Sۣ}NsP^M'"iM(r°l")iq,|^?}J)Nn31K5rZ i!``m,_|Z;XނGND@o 7ܘw 8N8fo3w9oezh ҲdզbN#lovftǶ?z`bFD `4ύ"BZ+x' cJYׯ_eYq݂4fP5e!s.ZjQuɉ]"Ĥiz#cjsaD|Zx4M]MR'^Vl+ 6ab±#T5d/cղ_$/R2V_xF*ªz̜YR^b "Ake3s07c}e5DЊR[Yg\41C".1 owym5աw[Kb}e[OReka]&tùG? EŬIH-y }Q)swVT -U̳C7\@/觎,^.:f%[ܼfqtt L0f0(q߶ 6Ddj9^_>|df5{}}-$',ӖzA$9-Tr.?E3g\9Ý]pkw:aD 9R÷͑qPlБ0<{޺U ٭]zm 8 sb " ,focSb>XӲIiX4%D &5}z~Bm۞n/Dsne.Wfw{zNV"5S-5h]r㱵Hz"}/µ^ZGI9ژyYx^#t`Aw+΂*aRG2脨6A1AZEZ B'] ok6`3POgOq4c'Oۥrz%l7eS ?* 0DRKtAX)%3#05G53*$bf cLxW!!ܪ!,{)u`q7M)zLuuP}:1/)0z?Hd]˄Cqn + O fڐ"c2.'uYYrv03mW7S\.SBt׭VJ)yY!-ѐ?X>iB [X&zpG rNm?/)r>H~qIF35.]>A:A^^|N@D˲kf$9NjDA qLJ!2 IJ 8AɵeI=Nf*"&JFw^ԜOy@,Pma{ݚ6߶MRz~~]FyGZq$i/5e* ֶ}[TkqSb/"Tm-c);%˾)ɺf1%g7%Tk!y>r{LR($9!'q{GG2}TEgw gǾwVk mCxwwp? &": ;gBζXh2F#FH1bw l{uAxϥ5-NqT6,** My(8 Dx<‚S~)5'P0\7$kjf덐[crk*LRʫEw珟_vda, 1~'rն,:PʫEvݶ⦄jVe5P4İ95jz[uȖ /[k Eİ>~, Si/5pѐ;x4 /FUDK"{@s20%HԪ)(`#IJH^.!qV xw/a$Ia="gݳ. zHQ0H@鏕F$%3^>3]EGT,=ӝw]L[R]Y "K!!!o¤VKݶ+a%uAږ#2, ̾\ˋhۡh 3)k]7"Qǩ,Dn<cȽ8:'=Dc!aamTJ%d4H`` +$ya !393"p_)vBhZV9{˳&լA0RAsO ;vfH DT "iyw<^gEˊdQm}+En"YԥGk{ӭ;Bԥ ^۾ǀ`(#x0&r'^YӍ9M2H ԛ,5,~pJ0ӥ,kē۠ hfJ[pEx9WSYsO|qz0W~Q޾FVkϡ=&KnJKD8whH ,q|.6Tw@YUsSm<arp8̴w,Ve P :uo4`߰ Re͆C5s@sݶmEXLU ]RcGE]gZKy^j9Y B_?ryy FK)///m7"qw"֦esF*kYBڑ&Hq\NA;k OqӠPwp}l`Je1heu>w7sGlHwez<1Yd]ZXRZk6|_?%a5}eV]>|kګ2$yGRƴOu}r} ,DjX& *!roa7%z-+F\dɆ!%>/ȡ{}p9+,c`Dʀ7M)mp ,g7|7M2?+^N;l͜/)= na]|kS  G)=< Z`51YlL]=B\ D *,# -"ZRԒ\\of.,%gWS&$-wk-xsO;\H[AD=JwS]jf ݹZ]1 R.+Qg=1ܾ,_m1VqJ0skmY.u}X׋4EF[_1r.GTR{:@u `"ZS锊ׂ-Q"wψBG; m5!:?+a8Y6Bqa1"K5~  g D6DdL~G[O VL[kiK$ᎀTcbٶd"̡%ǽ󉰋'ztoRfO8TIcoLq& L^,B(fHeà ~׶Ge44 q&.R]V)%UHvK"5cR+sPmL)N9 29L|t4CfbADs)Y4ݩ|yKuzO 'O<_e&}T66frhЛ6i'P|:~H*KMkSIHb@0d&,ڒI.HH)$;TY2Msgb$wJ Iz9#1 3 7!!"ޞz=έ;_$-ZOGk|_dp~CʟoߓXT h]׺'bULˆDjJ8( !BI5c@6ݛD,{.UF˺k۶"v) =W`$:|޳5ʣZ q䴦ԴiwLC#H9~`-ٷluE|HZ73mDR }߈zyF+£g?eэ٬ ־́lp"J 5.2*#Ff4+uw3[մK5Xj^/ᑣrp!",r۷&nHћ8.nc@j- 0Jjmkj`U "YviE b!$&R2~/K=6ӽᔇB9Huwflm"oo?~}{oKZFsJ"Tz7$Q<,O[#r!"bV̖IZ!0fP!,ӹwju^c`C7mS'SI8Ɇ\.R Sp3SfE@}RJ)KoEJPW9#qU/7|lsJӎ͙WIʶOf|yxG$‰Ye K003o}6WKU07wB74kU"a|WFm͑̑J)J~ HOOFLt07gp'=)~n2gI78DtFvKh#a濪J]岾5Ȟ,. ,2\+3" K].jpy0S7'Siq=O\e۷mEbbok}yyf掀>{r:, u)ŁC" 2')<ٮ`6No=P;Adhb u$SwdL}5 fkC{g,!"W_7 0@˲^kb-uܳ5Io>??nZ.Dg~Oj\ɞtUcؽvhS=M-m*3 姺3Ҳ,cf^.w Z%SLU5) @D6FN9 smQJu@(zDz^^j 3ۊuU䞺;Fdmtƣ*Jc:p32S{.&Gf}=X1Lqgb<l=-u"ozJf7lfD`"%WJffmDLq.˾7row5[7@uۋe^@B0}ADhyOTi 2"$v9.9擄oԟ}mk0Ama3^Y,_ߟ ~@",R.z.k7kO}(R;>zl ck6j]n\oRdaFΓHl; \H> XFHIx`NRkRdR^egUgI LMTfL'n{KbvǏr$mc)k@;HNs97UbP550$ F 33!\:=yGon@(uZ=@[A"=>)L-<8m̐ BD ؑ ÏLU!)jEv oiJQ0if۝0.5W P bdgE BWY ILOH9۟ Dތ7o+¡HPa t) @6"@G;"Tvr IG~{ O˺{k8&hÃfEPX>} YH\_> fN.`XMm#bKzKDHxU;,Twط!ԽYDpa@2z@O>24Ժ*3U^J}}8驥ϟ?;___7H+7˲* 쭙%l7텈 뮵[kfnѭ2&=1O({e"\,΀=ڢ$ˬeo(F$a6ؕ3pt 1`7 KM?3!)%[uS52Ho=p5d  pd}S13 mZ ps05Sa\Xf4\Amk)MH $!FLL "Қ%*#F.ث%!(Ût'.&Ue] I aѵ5EfL&l,E<~$"= L.q6e""Ԉϩ#eh&\Oyʛj3_=3v)9@j+{o2Q/i|&2C/"H{$z߷Z;\.뾷*;"kNqR]=‘kmjp{~Il43R0߷{}:\ҡ" '@Nh]?-[0ģ\`r͹ 1,=<<`2폏ﻩ]Wo~ݖTwZp'EG/"dͬ<^D^Zs3!YZj{&bXQQe˩ض0s1sI.mU#RvE8Dh _ycIOm׿;s2R4WC/v҆#Y6Z1ҪЭ l'־S`Tt9x&""ck[j' zBDݦBՏG>3,EdDGKPhf1ءªMs2A.,8cSFGBtZr\.IFIxar>e%-~d|οwjVI@FmWAX:3|?^6?w^|c?|26 vDd?%(!g)m<vۙIf M93TiTm,5}xz ",:FUIr>R@xme{.gʆ;1liC(ȡ:6h«3dz+jUrNl|ӧO$c1mk~vDS {'pXM5cn,,PkІ,$a@M DdzV'Ōہq:4O,$xM+q E}v˼G7棧1GR̔3~<N%1Uu74:ϋSf׽2\zyNAJ&5v"R!0 u1H D#yh0 |g?f("jȂu퍐m #B}|a%N埌}tʏ5w@`Tx1|}Oh~2ܟό&5snԈdPDŽnF,朘_D3^ܣ"=VUBKm/ˢf) ~f.pK~L{B )DfanfͶERB&J" `32Z-SG’i#Ew 0'D\$믿NnvݖZH,+_.F\~1bQx-< ٵE#9vM=-jVYd&J0W\Aˊ N)25K"2Mʾz= M%/<2 x~~([\hd󜘩'#D$q嘀UN>sO qqϞa>Fb]_^??|/<<<`oi+g+#[PrQfŊ$h1BRDD*+cqyyf<琷#ĘyݶM=+St}Z!K` d2־ zx \f1@fpț:fO!s2^et┚RY !F)<8ngʦKbѣ KaG0$r(̼$SMoZݾkxm׶#F4EֶR "AR ,fywDn,g_s߶PSLzd% #v>Ɋ@,+568Csu۶P+!岬nD mkOOO_!A.fR }זG0SyR$@J)IR3QI%qUtw 1^Gu7~~fn78 d}d:{KN?߄AM|@Ce璨G!%F+"kjVh0}bw7pnVHI\}JWW3@d7P3Djf:ιÀeN󟘤fc1FՇ sJDTؽS8pَy7 `Ρpl'u͍kX%?#r`wD@KL<{WgO8fHsgb\&ff@r:0p JWkؑ0A+Lp6Df`$_@v]O o`$)GAs$kKTLYF"w}xv۶HMtJ$Y.Lq=T$"@h @@79v*al;YLYZpJ}>`ĻO۾YSlv]Bh!s 9|cX猈apObcUq셙%K~ :VR&Wq6X23pHQƲugKRO'*= g,޼S))ݻgW.2Frg=XWJjfP);b~mO[WSK{8"??>q{yAJi} 1^,ԪFGT޷v}QUk)\dFf,#cef-)HE9XXo`ZUH s+Ee}N۾ԅK˲M}ce]uRuo@2(XB晸4!0') S7Qb,sRZ#(std3j%`"fʌ,4HKq3͑f"NGrF7 st)C*x(Rm))+D4n>]]>7:o`"Sz۽+GDJ`R"͍.!'=P%'Xy[;y "˲ 7@ d@ fxK)"]m3t[SQXۉp)7E6UbfDm z>xz@m &h0s4HO_ZS?xMo}&k^8.rFSZ!9FJHPxPl~,yvȉ{k"oȹ2ނpu]\B! )/ÿǂʌ@PJf\j R<!T O4jK!BA{$8^n#e]jnL(3 >,pg9_cnF)h/ly!xݲ{ƮZ*!Kbqp 3[k)"H`S]X܁V;|*%Ha*4$RVM7~.zu=s>12s,>Uh~S4euY |Lf9qB!wc& !CH:l̉(Mfܳ%;CD0Ps&QEJ ХݬIDu8y-2nABNH\$q(륮,Bb-Wp #ZHwim6bT!f-^3pqUG$NZ®. z)"q` HW FSU*Sg ُԘv}(92v ddiž&r \Ab$ATɘ9 J1Ug?\L558Gϥ3cԄe쮃JHvrLjȗ_D*!ֲD9GC ^.NQFW'k N p ]#.m#y`7!̘§} ]hH5Q7!OoL6iG ON=hrS9uxߨHv қ,401Λi]0/9~4ȃȴ^֧wn{'.XgAt~Nl1*ͼ]Rsg^b]eYDIsݓ1Nt{[) `Հ@(9KCF>cPeko|HmsUoR4)iMT^m~; axl@޿Iek&j ztN~T99P@$?O?lx#≠UkfQ_QLOT;uYV)5"zڞYwyK,@3c$꒱f`{{M{S'8O-.IT57"SZ(ѕAd1;TDDtT 9j Ẻ; 2Zr׶aFT'iK*\#(+$0CJ8ȼTpד$_ ve9vT^=+yo~h}B/e+>߼*{0F;<",MӓnFA v\eLپ&# \sJӮ\D𾿴v'dGD`&aVBȸVShʙӶmwQu¶7@:/Niک (""F( T>!Ñ2Q hLcG½y1FDqRJg p&"@Xf/|'M][F կX}ߝϓd$DA4hBύ-96N` Ln9 O~l p BzCGrߗr|, #Yĵ(H)/0t,w'hfr,t&4I<<=O{kû^<"C`s}} sپ">xz N1 IDr My}df}kZZJ)< ,aL) lРʵ.Kjp#S8Y6[ͼ;,Ǔ:F1A0va}]q2sӰt&T=:h'i/7x5U-x|h 4sOb-aI 㛌ݛ޸df:EPay衷n˺`f0 Dx?o,eYDvK`VDĿ^>^/iRd7v?fAkRf&BRM[,fUf[0K zx..3{ږ9[ҩpEYttDc֥aNЦaq]0Rg'Զ0{kMU5L=O}3)|L? kd?ټFD ;G؃o #{D qY?ϟֈ)+#, Sy_GJ;j-VPf5of3回{8ΐNxi2f{;]S`|ND|B4js{o`ס}&8S6}R8}9@JQD(f6H }#aAt7m/ vK(ɶi[#"D4#FY>[gn 1"^CNٺKmMͭIo%O(3"֠"eiMm])"&..E<B Z UM (ZJSE")ؙD:#ΰޟ q guJ_cN#dRόJDu-ef/kTˊFg|UDDXjNҺ.,,,Y3 ;n5(]'Ùew,z[kTdYZ좎t4vw9@D6a3YʃACe@piU ̓R}';.R [S}s"Ow\)Yd^{ҷU iZ D,fr%o;yxFP񥪺i6zf<(m_O)ex/U;<|yA\̹+~;I% '1쇯GD踌w즺CÏ\Vs*jtJ>PfͦږbF ײ, a^ 4bv緗{2K,}g]q7N:m۝0EK)s&q,n,5_]t6p;6)4 ,7HL@DT p@*P꒕1Al 02uh8tQ /?˳C! Ȍw"A"2Nkf}4$/ < KB 4K ^3lpU LG8g 3{kXmsw!޶t*RKi֓EHμ „8U3)]U:j0Cܷ-^H0ًJZN!8p Da1[k?ݛXJA<>4UIٖt",+a)XTq̋ڗ#iJhKDtFC! j"s d4"Re!ĊDEG%uC[B07Rc)~LiCz\jYzYv_: U嗢T7!WDq*^E$ 8&0hY)F,5K~~Gm{<4!1|C-O84lP fMuჵU5(YS> mGst24t/ڹkz!ZWIu?=5Y;gѝT$;Fԧb\1 &%+/m;RS+x;Z$Pw% U:kw_Hzm{Q\Ynma&X= 3{r_b=Xn@u4x|R3?}}xjV=^5 ÃH}8.7G)i ]t۷Tnׇ>9,J8e\p5F"j-G{\.Hm0!*"/RR/ӧ")2Q>̝uL#eq}N}gé1 I`z#"FUZ]ݐ GľyK)T[MM2h0ihး%<mst~z}#bz "M}xx0ԘLg1yن>;[f+8#Y謜_W{3d;i%~ arR09K=#lBon}RPfQax8DKKED< ,%rU><ϟ *5_@"{YjB%2~xNMȮ-=ISelRyOH,:if[xhB*DL` 1 $Vj!K)6NTF J #L&0A'w8FRM?|{8ߘI0U',[hAS,^< o=2v˲}/0"DmۻޞJ^jaFz{#  joLdjNLM{g)3"09%T! Hꦣ:̔郙ҧ E ry݇0\J𗗗6ff"%"}G,̘R{SX+E׵mwDLvn"z͜"_4lS54TA,/}o1"0OϠS l%A'ic-L9|)ysSMRa.lqh!̒45vZ!0" HmkEx1owX7(R1MNTOrջ#'n8 6}Pmoaӕ AJU/"rR@D.1LZD橘Śۘ AQ@tXDW=uEջs3Tk Sy;J gw1鏟{&5;韎۹-ן2#ˊMKtp C|oWH(Ο8/~=Mf?LIDiL>qԟD77>8ݷ0ײR ɳr lu2iz-Hp*~;(!@CúveT2瀃Ir2LHDl˅!DdvM."jTn/_DT!Dm I2L\(5k5l1kZa1>N`'c$/z䔉D\$]_o=N[UypTqg꘩6!qHxh/Jz#F`δDT zv8Po~ "zWāŌy{v9X7$5u7(=5GRJw3Zm k)a`v]ץZ"YÅ'b)jMEC@sQmx@\6D|z.0#DHѳuTsDH`ylMbj)"9ɰu]/'u!㲮ܚ#}q׶iҵԵ{jX zxFԧ*4w JKqg@^Y,@ _kb*쀈8}Ҿfؚl^~d@=8VG툀J HLN88Tb-!2w \?Vϛx '&X(MQZE7E" @Z*"ZSO?!ȗ[ver.˻>W'PI~Dx)`NDJgNPӞx`BuM:$$$\"9}v1x?ȤcdjLܛHګc8{6'1w.9Ocj,jzJީ9¼lޞy;Gq5f`{ܽ_~""w҃ XDr,*nO׿Z7.l޿R/LRJxU exxQwMD_Hɖ:n섮@Md9wFG8I8 05 "C@8nI&: WёݼXX, Lm/ſW򈽵 43RGIw fھ[$`"b(=ZSdN{С3{{,iH'soBj@Pgۏ.p s)cksڛ"6ip5(=G11{qJG!UzJG% lf.f{+3}Oھ1 zkTbtϾTMUZ8dh=|҅f1H(j)!ޢOB"2w w Kb<x_tBY_>0 ?Dž37|9$9„^ /O8_OWӉ22&EIw]h Kѷ@WTZk˾m4u]=.O?vcƎBǧ֔6tp5OkTo/UXPP$G[(Liq빟'0LXz  %F>1IHNt#FUʝ#ՆL::!ə"m;mV%kn1׎`:sy 6%# Izte6WS\̩?5wwah#=isLcz|hp&R}g4y.X@RM(#ww%2 su4GN93u8~K۲8im{Jl@.^Gԣ#{KYa]8r.̪6# 9Sl Fb,¹G>"; t8a*t*C n8R`2!Sf-~IAoo* at(3E;LD 8#BepN}͜M(2[`{a| $6#:@@. S*f֝7K=:nC*)+"ZE8mq#J)|۶][nۆL۾˺g̚iER( 1Ig'b "%W r ħ%zO>pzh >c&!S1dd:P["<]":l"SNcUC.gSi {ʫ2;F*QL9vupt;fwEx0 "RUuv9Ͷ{ Sxr5&YG_yV$)ZeID tړw/&JYj5պ̙{<<R̳a[|4MNm'J,OK"v]zykg.Qr~|Ra)؇,%})ݓ_,i0FK;U?+i6_q×{f*h2m H1DD`ue3hӧ-ծ[0 8ZX`̦DBZϣ!(KRJlTS K4I!vT[ۗe"jfFbvԠĤDY33#5N23xX2$ReLųA $  2F0"]JO5c;IK0Q"mZJ|tB@5SfRSuCDu3lڮf,]J9IF|\X'=3~HV~e/ґFkfwS/q;&\F}^^^x&"UnLhᨘ'P s^TgD)Z90\ YdL6fhvBd)BkjVKISP:z&p72I OC/0fvWV~eCwfXJ1y#曻;w^ "0 L)T2<ި8RxW yasAD.8hٳBd:/#8䘨Gp5Pr&h j 5DƏw~S"S\}mĺQsm"J!3/u4R݈XњFk;wYG ADboHqY=̘! 2xeYԐՌd  WB!Yyh>]ñH9 ބ@)$0HF ^UmÈJajz^ Sn!magʵ{(2u&M|(m.Kq&JE8I!uMㄱ1CIDoFyJ `8eatt"#c1Ssw=,v.%qlxMt? ;i KqtAsaG!q3p HxyV `1}y βF踻ޜɰ;~^am3LDrFZ5!v+K=& f֦x>k֏ w0%(AOVF8iΜ]=+3R9%؈83PL&D~c/=&c:#CuY7S"Rv!R0-к*Sd8.(0xAN2"вQ3gs/ę/o{K[J&f"o5UM lH$)bO7SD"镣E1JYN8T0@B~*u3s!2(MХ`F%KireGz:Jy%c^< !`)D`)o $/G4 rBwz4omWѫԃtS7Z-5瘄#,:'B9aD`z@ n~'r`%0&< QGZ|d_>cO(ofoyuPZ"B 98Roo;,̐9=,?]pAskaNBfR51"lnCtpب=skt1p/jAPg%V,|[ d:?F!Q! EwM~.FkZP߼G7 x@\,RC|^#pV$rO`s],cP:ǁug}ǧZmq8 B)ER?26Mp>ć>&H0<3*ߵե"$kaPm#>chƩ~d ua3< a)9"&ח4<ӝGdzL$@KGZ 94ԿXjjD9,"%wSEdB173#BBD" 1uY>|,..$%0m;@CDmUd<3ɮ_f] .,>ёa:otsdqDnƌ Y\J%V.n{k[r&ͻb>Rv5a\9Ko 1$;/˶^"L'W?=3 S)%n4,&@E@2Y$Eodғ9H#I2ԫr ូPj yY dM:,F;!,v/cWa/ 8,;&?!|pG`0 1)˝,^ևٷvwivqNš5K' 3I.D$5<%]IGf2r?sFL^Tg&UE΁oF= Dw=) t ڝ,L!F7| fѼi昋 :J~cd7H$ z{GDsN`VA+3\D4z͠mahåH5scޘf335H&Ƚ3{j)@Khͷ?K[Z.?o~~3K!uRӘ@pJ _@t᳼\wY1/iB#"2}~}faݍ,C3#ymDIDJH#>WL@HUa@9m|#c>-|x7ZfG!Io#{O^gg`Ap Mƒ FcGD& qLʴ\1J1ZL&1pTO\ 0#akTH ;#x;tw)h@NR?s^>>o?xx|zw>ݷT)uYBek]Koa0ZI:nm/R]"4kT"<wGv}z3U۶[߰ hbW}<.+w1͚i*Jڭʥ$TӨ5*: (C`DmH§חpx8݈/NU볡BGpc*EDJL #3Ǡ;cb@O-Aj=s}utP(A?C1Kg^4K`?aֆJn*i6`˲aQ0YZ6K>~><msۧ<}3hm}=B|v̒G.".B"bpD"GT*,B(PD^D!2!5A*OьXvOF.Mbxz!O"5Fs7p̜i)Żg/b ykM["*ʾP.ښdiZV1ڵ!b);ȺԳ9 L"e׉dNU$Г+>o7YN{-r ROѬw:%&n-ws[ 'bTqhk6 :o fvHu,Wav߷ϟ>ÏsGXgې&Kg RJFCJ%^;Y K#+"rȳW_y)c%8:DD:OiS9]ׇVLJfh|G*=iُ<ϥeXKS _g3KtHNo\n6|(IYM;!)ZPe)݇R9SIC^RB@ VRXԱ*}k[~aXZ׿/>}e]uog|rRԲ IyzZ۵mZ:=3Q{x׵STfH)9.L̼hM>!-u7fH}"1==D8:ʹ!Q)R k򳀨KfQ9 Rxڞn :9釦3"/gz?faf36O5ט[FvfYMn7M箁E4*B tI/"^pe]߿fpi>S$}DaTw0d}r5d)sh#sv~AqM8%O J@Vws4"" KcjC IJ\2aQ=#:"K,_nw^kpm~?0fLJ&~y?==m~we{k^}}RK:ҝk)"E )>>Ee33A<^ȉ 7צnێ.nnM)۳ff\2EQ_/^jM ۦf٥ 6H 4mI8t?t*]zΛ HY]ێh3ZNmF p$3 CZD9ln#'Na{o_I7}02zZQj&\ i__>~޶{R9 _7H^`DDsjBu|#"?1wq}~ě`}n28~~_?yw1稀:ϿzM%A8:Nn " BOFf3DtG,g ]{Eńq -1RG1=w GDylZ[KΉZei^ǧO\?~DuumwXJYewjSMU%Yd8;󳺅ԢnaD}R@N= mۖLȗ9# sfP9Bs 4@Cr0n{`4z $MB6"cXy$ִ`3qet4Z/&Qǐ,)13&$iv }I!NyBDzW ܐ=pc ̝h@ĔWX1aѧW"" 'V&>@;d]qYiJ; | t<у9#"[Ic뀇7"u]/_?pҀ8o b9ijh 0nfW %q#gdz?M0L+ȡ9c{}O@~65%;$ąs!$T\|{ϟU fo LM5o6yӣ'rϟ[EDLZSBR7evC  q ˲; =1 )L]x*s `vmপ}[ו[Cdf"p /1-2s{sSRv&39,DScuJl ñka ΦZ5e8bFi &hY$jtb  沼^.6~{p.Mn;fDt 1YEߵG!|fĜrO"@J 20tơ* GND\tF9M9aTŌrꃈ,y $r -&DLMlCLI[Pd=/Θs.N  Eo s)@?7mVaϟzz͇w/Mm]Nxhy#:'E !Q8nޅͶg`R)i %5~rtxuw`E\% y K&r_H# -e_* #fX$2Q)3yoGyRr1E@v"?" z lo$ ȡ p #.s u !(EdvKEw_} Oww?|wl煡owuş`uvfҶi?"ضASv/QS?~E!Ca $Je)3yh -Iv,ҞP+!.pAm{6kmC"#||znxYW.-@icxSgu\]*趑Эm; %Y#TM%a 4) Gk.7d2p$F3 %{vZZ:jnzڹمH@VK}+A' pE]Dw۩NWPdY.'mm'FbNkMlp/b*Q @h#"Q6 ;~ uQ A#yωCTeW|/~_~iYֺ{ A~(5婈DOTƺž۶%UBD{qP0 DD1mwwBĵ.v+=1Qvӓ6%"mz_/"OfeY{߷}^U*9eۛ3rl)gD6DCfO䗗"^*RLԓuژǀXk! ɚ%R6v) 1܇T YT?ʜ6 Rstw7kD$O-077/~X5%BҶymCQU冃[: Rkg}N鈈D2}j]i]7E km\.4c*9,Dޚ0riQkT~YO>===R.eb?w#fzn]/RE-<%Qn>s*fa7u"a;q˄dݱX9$.| Q Pp:H&'̣+4TDŽ}OYG+J 5wp ؾm5h̏wr__5ۏ $JG1'Hvoۦm7sT$NȮBXSe Ӯ,kaT<2k48<y"䘚Y2 "{nkO޿ܶZ"T߽.LW_yaQM4=2m`v0DJ J+D^[K)QDY$,׆fu%JumÀ̊HZSն7B"}ߗZ?}|YZ*%(Y#m#_/O,̎Кm " sCP^ũ&rY3g݃#ߑlU=̌pu5K tg.#R"0d0 ' }UD";G{?ϜlkCm""`]N>聃%o-Qi$|Nb{W@2/ϝ7?ߋ,3+83Sk9Bm%<(X}Ƣ\#&fʜ5uha67v?=ۄ\s;7 ~_74<Ήמ~3bJoHS%ҷ݃H89n?Qdf^9y3fwܮ̌ܓ% 4|c5:ID4R&}z}0 oeÇwOT[RQs3phKDt3 !`d&znPj7'f#}߶LfI\g"F,hf 3o^R[[ZHjڴJ}~~\ofY"}/U@ǶZjD~淿ӗH?Çw^>[)_^mg"&]9cG 8gee2$^F'޴l8LVCjON=7Q;iӳ}CDISiQӠ*U;Y >ckvM8#P19޳B&"B'rH "7f; w&)òTa)K}>n[ʄ=& $^+ DH " e02J߱yB9f Q{_" .$ɺCc,mz|R_hZ$ן>}ǫWO==nwb\nԕ\JE@IJ[DM춘:֘y]RY[KzUFo Kv>,, ̶"Rk]pO?|~}OC]?!PI~'~o'"<]׺V)/օ-3a!!|ʏ0a襤jKy'(!v,Dݭݩ-3md:? ul Gk=0e!FTYgcOؿ69$YD[ꚞN/G(\7p6E(ngy3#9Ȭ٨+Y0SS=zwp$e%@Nr^fID D7,4MLt\OnYiZmop8 |^.?|( ɺV"&eYʿͯ??t:#19VΗEu$%uYo[u%<jxנtP8T~[@m7#Fod=F 򔹫Ȏc`jqVuTA쇟zˈFVt Iն)cf-vwC޼yCjEJD490S$|LQG;K@`p[}%nT܎ 4[kاFĥ$zyyզ̡[5Pc!Q.cj~aBL04$MtWqy]-eI2oPXyx(מ0f Xpg`rt07uL5𗗳W__Z.,rVӜz<Ԗ+!I͛`9u]DS4TuFSbaHht,h h[KhVox<'??ͯ򿮭\օZܠ&`[Pȼ[J`uJsXDFؚ)a8Ҍǿ Hk㘇m4 w{ݠo$"%}$% up %S)P1dB(L1McMJs8x?= !"/=z@!L m&S3A( UDݒ6Ki&R7蹛ٳ;r]+0j>.LoZDt8TL54s)et1tՃ}2Wnpؒ?T>v~#M Hq؞(918,ylE;[`S͊}Az{JUMkqc Ȩ`|! LR8kZUy+%,oޞ__iYe]Sέb.KΓR{Zmb7Q,lX4DLō)v!o.kk1w#2kB<\KYxݍ<r:zPpieYEO93qNO"%mjkt8/6/M[g `"4G@ &A w <:nj䦵=|ś[862.ƼaD9g뾦6>_: 6r|ݘ4^9PӴ ;$%"b@dӸᯯہ]pN#pa~]]׮\1LH+ o+yԘ(!6r! kZw'i_?Ŀ\ͫhȌrGt ǫp3|x<-SNϧSN||O=$˭;@,2=>dڕBhSyJ\pvY3DB܇޻KYa@;")%yABBvtFbd`OM5:{{';yq>D!cD e-܈Xrȍ4a`a-S%G@() sjbg03G B]!8m)k-pE+ RS q7oϯQ]벮Z|Bf6ӔR9tw؆wcr4m3+n[nc6|"#!ojЅa뵪ahߴޛK1=ᛷNDi;ih]o)p=pyri8$U uWzX{]hB`7"ea91s΍_iRu"K)jm/?P({%Yݛc7R Q᦬?"_m]ec-{sk=)T1OO?Oߗk)F1^z-{[Xg~˝wA=1? a+LiA.W6py ïݣ<I2 AWdd>>L}PC[+tm)G#v7J7""ǿ UJGaq 473BNdW-jOo~ӟ}ӟN?Qk-)%s)Y~;u@,!˜s&"0;·uz4z01{?*|ol;1Y"vV AaAw}zx)3 C-͒Zg8;Lt:~ӟᇥuWע,iJKY)3^%Bmi5X5*oD-VlS2{,26#$'Щnhӻ @g&xUjqgA%䱌ȭH MPRfVK1ˋ˩nCBcE(TԷn_@4cp eGU=Ͳ,׺3C|F21u ob;=&Dn%ȸEH3]HFnƮ2{yJI$;8oC v^˧O?ϯ80>.8$÷{ }O+ \Ʒ/F~;}x}-0T`XX 63r3K 0NAoІP~]110tP˼Mcpg` bI *!%Dc3 .:mzpzQJ3!5mn,y~z0u^>r^9 py#g7sDpBCm$ nDL;*HDЇ|YUk)Z #{Vk)O(Ti6I/׵$\i84BdѬ ֚mr+}!HXm`N}1 w\(D' .KōsGf+R=MX(!{$=hH{$4@SIr<kS]׭(۱[c&9NoNOj3,6E9Ok-9|~]EkCPU箂6w' 8>a,pS>܆3bb43{+7 " G?/~1Q}Hap#dy%8.RK=`Lakd#@^.tr]߇-z[k,_C&$ޭ"mgsX13oD4k7[d'$f*;qŽ2Kj0}&J7!ʠF{OSJԸ3@P6>! P-Á^[;/r-.Ĵ\fۧS], @hxYtPQ&;\G,X35\YfΒ 'բE%) <,D.̳ò/]3R$ YO.zYn=0D+5[3hAV"xlqFŽxt Jog|4:5 uR۹­؍}q|o 0Auw9ƂSZzNêK))$[%rqLA'"4?3]GHI7GsspIk%&&.+:xY%jZʯ'`nX]pLj,[aH ps\;eG% "lB Esg$Oׇ4݃f`CM0k~}-}ե_n:4p. uR|'qͧSEiYL-Yt7 u'EiLԞŕ Jw1<f #5 7ʙ堮 L8A|W뻷oM$5u]dտRں.i,"VhX(! {k#F g$:r Zs98@Rצv]u]%󫂝/OTJ9bZian$uA4.ORv$ 훷PjV#Z  6#:R57& ,`w n6r#ڶмIoy" ;mKdco]~6,B \. C_lKءP'TJ5pohgdQ5Dg)9gFݓT@@廾KqbShc_"̈pRqi:+d#``Qy4j)[^,''5p8[p[3]ޥ޷>Q]L$ QmA0 _m,xZA'sj!11`";;"ys+3fjC)Tf:pңv=`7۵|]+tzye-_t:R5ͧ&ZZsUz=$۠89y{1hDX: TUZWj]'gd,jjyY _KP_i.jK"Or]߾{{] jNV1J-s[ ؁慍;ktP~!bFPUn40l7}Np_d?aO曜s|Ĉ("̈df)N1jDwoL,I3,R站ȗG?uv9(!#A]VM۔i3kmj-n @[ AD3ws@sdhÇ+5n`+rm#ض Lvde ^+$F]m)5S뿥BC3γA"D4Ӧ)j5'A0O9fy>rJym u.C&b ̄Yk$J= Awg|~ 8'#Y~k2lVymI V1qluQ{| "NnK /R.{Į"12Fbb>P QS<(4MNU5ޛ0Q). HHyrܚ)ili(LTk$& TeZiJy.ʪn/ui4ꔧR&DKY_@E:̬bfn;,iOq0t&:p$aaDDZmچa"9UF,9e74,j)4Mצ C00Hph~yo54$fo[٠d˴f{>jxys؉7硞&N`Mu$ J@e|knm;3ǀ("֞߼EIS)IZYjIĎOb ^_Z';E<ۄZ'8ާ:pm)8aNjԽzw}]Cf;efw8[p= HH~;;Gʂ(!!]Ϭ%07 L "tÝ_+ɒ1y ]]#+10.3t90uYM[Z 0MYJY `gHz&Ŭudt#`kfMK-rV|YDz~~~i̕5yO޽p^ Ne)p" ˍQJuu$p(y_ ݀iP зpNp$$x9Nֲ,,غyo[|So+z~4'qy:CAD20^;)s5d:Nf7!t#867>OԒIԍBw__ ]=7ftvOc4uϒnRHJS@ؚ;5Ⱦ0܀\L ǵUj 0*iTjMAX=~Q] p(,3ޛlmofj+`O ܴ`oawy2FLqBo~ 2xad^0 /gDB6ƌ aHSCӧdl[2:4t6FܻႮ S3!t#5"(MQʹUf_7XQ .GÖѡY20PL$T6LZk(3 9|?9[,Q;)Y}]R4񄀄"s7HBykSwd#`7}HWJ v-^5[Ly@^|uE߽>h](nMD =5c FawV;!2qwD޾#cJ`j*"eYx[V18MC`uqRpi]MC@@v;>*ٯ3ǔ3aO i巫8N_T7~+/W O)$J,#B& Sc%o3eLeJc u˃mD4tWsmMu&2|l}hh vx]Sн[kH v]A. k!4s|݉bjD60ou]|,zoۺ5QHj@4xz]˪KY-a&fd&ReYuYu1k)Ich4Co65y2m쾦1MoDAl= |?_x֟^h{F ",/¾ 0F&Ѝf9 Mfj'#!1Ost<׋k"T4q H[.^ q6$d 8h 'N3S k=T FLQ?~ÀUc2РI?3fM84q:܆)Ldtӿa7υr__-WǸ^EϨ nG0 Ǹ76g"'Cp.W*[COD`b04@$`A!B,&Bz`Lj("NӜ6ė?|V[XpQWti>"@[mj%UuRZ)zUmzd{,jsdw5US̖jmI: 0]GfVrWz}=Rʂ2I9I"DbZZ:!!iL[[& GD ~n #net3  -q;VVXG2>50R7%&$ yf 蚌‽U@Lo%H Q&s#cA˅`rD"I$N nmU@Z5c}MsQtgSSmVk$ZkŬ5k뺘i8ಒ;p9`'G>ϞrmH$LLkq}l}~5U8'ͭGfJ{ xڮI/]P嶑 sNZQ91Ah pU@24UWeZǬL;#n.ҶX;iyn= @[uJ(Ǎ0pa) u3R/~˟oߘzMsnT?ݑ *Hb=܌QQ#gvFX#r 7_+BP"pC}n;X}`it9oY?΂GC{"WS72u$!K}doMivZ[x7|Ej0Z&QoDF1y]nBy‡I~GeH0Rڪ!ssocbJ">@W`mcK8DĻu%9qmf_ѾHoL =CVwP 3;̠wX=捸D|DSFyΒd<etZC܂SSCDÑ|HCϲ+woɠinAp Lf76I]^>y/O.___SʓHWaeJijVU+3/StZK+!zœt|H"0攨= ԓS" u5ͭ6m [mncsu] x<.ˢuaׂDx^߼y>ylUEF5#FkX՚a6iNp^ܽ23~mMe<FcoF%BgpH=En#sW#-vDBWp} mi EbW݂= ?o~]6m݂ɑ`p-\_ϯuyy}Ĕ6!E+B=:B(бӅFFybijydQ,]#M#Qpnu $>S!и'njo>w@-/bx =l2w<[ODD<ԔI9ys }G*,YDX [s3C`UO ڡ: Ҫ6 DRJġG]Arz:9skI eM竖eĒ$yJVe=NOl?__>匮ük+| JP?n.C794s3uu"RRԎLDYRqQlfItjKo:jJiXk!ॖ^Ԛ5Bl0MsmM$_R鴮kmw5f&Z/JHK]H oxD)}%"?VSTnٟF[Gkm|uCmg}0[X&껵=&g;!ow4/s} MERe-,p<}.L?kh6n]q#̀oW̸d8ԫ:pZdcj.㻞C{;w.se݌vz6Swwl20,3__^Ɨ'.o!lV^5{YgKE(OKzA@f@"`T-VD8"Pw[o"bX"F4{64:M sFq x-[16bĩ˧)Q-+?y*D@PSYDTZ`:Gb+ Z[e&[nBOk&[3ui@{`#oʲGI6@?û}yyEWN)0缔z\9gCca]{ Ow#`E)u#|1'2meK`=(62"%‘ a7;"aBot{Ndpgr>dRjH'kYB T %FЫ ·8ĈC98f;#6&N#m'2ȾF(#nSawe|qxx;}o_f2{֟?<Lw5#1npMnK?~D-'}NEH܄Ӕ[5"Z[-iʏ%𳫹!1 #rDVClmKfIj u, >7?.kO~O'yέ=y#5?==kmUo3B-D`} |] 2kha>ڃ?eMBrV M)ǎUP/H)i0-n+3Lׅ%M4v///__$TCt<7c_sOϒ֮}fx] ̖7Ӟ!vX}wN7a vot8&l;IHܧ}{ڇ9Ӷ*W@ "S _pbFijQ!6~Ѡ#4q&[TDh&IDQBDqTn(9GGv7!;Ng2m>c8[~qS`Od).P&*}{og3j㏶O IsoaX\d ꉆul'tw@vwB" yZ?Þ$qf ]3àlC`M7$GJHB<(ӃC߱ Oϯ/Dh"mOe].uww2Uw *tmLpꦪM) u=oLnj)%nO=sJ.ׂrpUmzh`Z~_kYrzzu}:=wx880k,r]^/˲rExˀwc>. Z[7 a;@cqlS@$ȡEΎUdž+!yvw"N94m`La[D-9Oڏ:F҈9XHH X(9$9"qX"!:"SIo޾-UEMSBP+DܬA\g4m 6琉ue99Ze _aWet-Zj&L ټY'a96B@bVXSUf r+eY͔EK.;Ϛ 42m\l!6[NڡWnxdnoBړ۽YƃVInݘa&Xjjk)EPJ)Jf֏Rm)sIX33F"o"2e<̔X{~w6=$ rJɴv>NcdQݮ{c7NE|XtO/bwoW‘'YLv}6gUD1iGl lհ.Rz j9M. L겮ܡWNYCt%ҘB X洪<>|xGnue֚'4Y-, fYK[C30 ZA+ủ55OU!nn!г3n_" j4 ZY{C CYWp?31Qx8sRJN)%d)'WiV,^Ze*TUSD39z]뵩Xm9;nn̦ "ԺhێmG&{"KFЕ<:py|=&9+FC<i5̮xSٍd"bޥ6,a}4;0O3@@RK)e_:!TzZk9GMkl{;{6&~:%#jyGĔ$%b6oӪVm((}D)ynu*n1Ŝ4Ko/~m5SB#jsBE6BdDpi2$2vfI#VDȘD@kK)qBLL }bq U$bYK i @@Ќƒܕ"}\ZQmVKbL oxO}y=|:tj9ϟ>WD̮r=[uum"4fN,IDrԴ)V֋k#Ah SJ땻S Vۆ)"~JꦮvaXX)Rʇ1v}Γ;( ޵[K׵킩]dOyiŬFPo:—!HW"jgOa K 3$I8Fq$Lw[<$JuY0Ϡj1fRr OcYKFAt~Lj,iL@t1:>>!ݎ}orT5TܽF5gCQJN}7:،fn6"5ҊM_qຕMn#QO|=DBE[7|:\"! kmE?>N`j9T?}:/ 3!>_.n ˲|&DOΗYknaN:cbxg#Fḕ#8=;fLDjf&;-F6Owr|jحA{X0։旃H3WM0i$ h~ f`#!Tx %h4$'$njSQ[9H%!a$PϢitNZ܎ Z d-k!”ՙI H"}S˘0s$x`J <##"j ~i1BSZUWkpz-GfaB5r·ܪ9[)!gɵT͛iʇy7o?Ѵj&U}=W\`&I$RZĒJY0r^NSt fJ)huI }6t;5 :Z 7apce:DKf:dlK/6Cvg6v~Cn}ld;}P7mߌ0SgH3k31 jm("n:PJc(=8Μi"p48Ǻ%ٱ$v$aD|xRJZ@}G֐~ ?~u{Tg,~/8aa]jɌ ް B0WCoZ= B쀾i탻cqWj K+n G4^l< PRZut<ݙ%UG& P'<%&!@p0A^},)=(RZ{t:۲ؕ) nV[%iRMS6VkʙeqsLe9e;,aFy{[8` a^%B#z~d[ duGo˱|V(aF}00p1=꭮ݖ4M)Vkj;G_XըLHvx&Us79MXm9e[|NwzCigG9uvuu;e! 5eA5w~Gv_щ* Wo,sxܺۜnybw!|wl3e dfaNJD,A!tZ7F F8iQOGZYi35kBgI˲,zE$z__N~X.~{#x<Ʋy:r///`5Yd.O#|8#~~y157Ky:x\!OB%6k#O=RuNqom &(ŖR}>|hU߽kT3Č;`v{(U*B-v+;q4n]mlCiܽsh{pg 1QNiʉ MV4m6Wi?^.ҊVT5Da'˅CrI4n: uAUC!;3A %֚jQ{Ji|ޥA "<3k#"/ϟ~ܬ:_u~Q w$w]& +> GWӠH'Ba hF/#cg#8Qq@)bf:`Gg`fwnA7al<?<ϵ31j( iXF29FAZ:gSŒޔ )׺Fɂ ZUiކŘӴ}RmmYWIy?p2sih[:A9=)g&)i'DTr=4MSQ ԉ'IDIXAUOSU[fpwޢͺ_7 -|oA❢-Zǁoo.3 2{u#Z+D7D?_#nLIUCsXJI)e)iʲ~j0#K`XD72$,443ѻ%;u7wHC@T! 8u];>t;1-<=^~4v|v5ho+b6~#G(aFCYipo0Y^[Nn*nG #fn$(ɃCdVsNSuz̈)f r"!V܅9O1b*UpGI9\h]JQBdS07"0ɜ9 [(@$ >Y-l;m|d#2%2 cp#d"  v`lϑay Eit'G}LVEa$d72J=wvIJYJ(5ZS&:n`DnUuM}[QA(s޼ys:z2x8`AJv >>>woju{}ݷ#G9lx_\9UG1ۿ[ H۸b]\4AQ5dr b2R0jkZkfpvEu`QUwYQ8Ȱ]xM6.B0uj(vv]ս-z@{FR yW_1)xǫ@m<w/{ ;F g!C,Dp>eJHSJkNTmՠo@L %VQwɮ)Iڢ6a._ELR"pB`BsmMc9K3Y8,zxO' I7`aGmm[ixX?d|~)6zg#3md}s 1\y/S-+ݺy''0AC^lZHe-nu̘E{BK88>}518m3)?I|wz싷a69ҽ peI7݂؟12w! 1 ;+"! K"N C)FDܜZ%1*Q^!1K!7>JNLo3ӔZmQj!AWkMx8Ґhj#bsw,vG+Ǔ* @rJU Όt855sϮ$$`޵ Z(cFbIH-$JLN- j mh}wBZ7?BYx_j' x<"^ZMddn|8<zND))dqduFkr>_׫K-dB̭霧V[kf)gPӲNq՘L7`z"رJs(x堇lh~sq87ftڥC61ʘo{WNZF;{+7вA߃pw6)=;7xͭ,R ζP ;pP0A 銆C2"Q#?QضGc-tw%7o/y8wĞ?|ݸ-=rNHȄ߉ˆEC@ZS@T [muښ唈`][~W]Cp-w7$sgVջ#:j[לsZ 99*I Rݚ'@dI}X ͡ 4O/i>VZTM++!K29L\z z%ᵔϯ5$ݷN`)e9uns/ 5ՆDnv8jY:Cy"E3sL]tZ#‡ #33%&A=.ؾmN] QN kqc"n+ }- sG_wdcv倷~O[4t.u"~CUQՆwc| a+ }71|wݎV1h޽W"W$߄*0 /N#8vf)!Mi>>He]TKf`j]%` t'!?/$zE0L RRi^j+eSu8450e"BऴVսOL]D9D$ꭿsScI!K>8HBrUmV3c#!:I.yڀs>vss' ].d2;% :8Y M)xw~}=/^\.u]SSǏǏ s,")# yZQ:eYR̬>},7g$"Z-%C)k rNfLKYҴVjmm[Sm "<7, }H17#=w,oW+-1V,6e%o=dԣA;͈o2oÇFq []r{H9V.zp';Cuy?9K?!07q?rHsW+?ǹ߈w}mOG(ќ)!Gރ;Ǭt~{ކ5@4@b#88쎭vm$r谬WA !LYn7͚FI[=)g":N֜ckVӬm "njZc 9sD1% 8tslДčOh0͊ ?jyup{LK0k}=OSVjnT\["2#u4ZjIK&3+몪P,ZZ__?#3^ߜNsoY.ښir̗x<"SaW{~z[z~Z2g8 >dwy""gv3U ,K3}=$fLQ24Ma\Ȼt[]lf]?4pZDnmz| [ƨm>l8H6VaXS58C)dmoحiub{Q(`pc܉(;XFTѐz;6'>nD¨էngp >:H=8% Hj.Q2fDs aYVZRDpp3r B XLM)!rJsm(FWU`3$]km5t1;jcb>,kkN)MPVbh[.I0Ei(D}uaIӜNɽS"ZsήV7m̌)$)#amצ5P uOSZ4fȔZk!N'sWPbz>&o!i\lY 'YugWHOIQiRrRJsVUZ[^*0]Kk~<?5$dž`.)RלeVt Yf+vHZV5sW6SR!aPׁRֈD>HQ(=1o!df)ZYj_e:8 H5H1T)dpq`a=&: wvwx}p;:t+x;FEdWIw{uDĻW,vpp!{ɷH6cF^QsݐێycBuɎj'Ӂ(M9Y; mb=-Q|g6N]8kfR0S:#݊ѱlf&@Sһw~(Ht8ik)emx8/4χZJpꯈxYxt]9OY[G_^_ ,l`(LM5fAK-AD߈!&_|>RVq]@_ʺR"S7o/O?IGrʇ'16T͛ZPmZ]UV7I$&ͭFKFL=qvٛ }Tg5Sh\g$9)ص,OO0 \9O>ky,~y)5T:͇eY6zEҖ uZCsʵVm֖sZ[SJý1¼ AD޼y#PbZ[)pE44'`ɏ?O\[=Y G )h#mxw0zG}RD  M umeqAq$B&I 1~+چth3R8pMo|w/sjfS{Q9_|9'R+x:E;aVs:˂Lavre.~[(5tY~2hrʉQDsZ t=euӜVwSj=חO/kGj %x/tr&$]@[7wՐwz33b '̓b7,)7oK)M7qʾM9j(4O@IoH6v]@[ſ&s^l{~ztyEpS3G!LQyce@CL~NBG@f yK s# Zn]o]ٿW2guiyuvc-vsثvhĄ") KC94eG7Uo"r.ais{ !C l B0ֶ6"`OCG55͈[]jCY0vlUlͬ6C)MC< iwAMy\A9ZO`# xV7FT3Ŭ4ͦ&(DH|VJ TlM#.RLx]y>d)ebΧbkj[Zq4%u+Zu%(k;Qrvf6$r:y"z^ZZJq=_.Ma:8hSuwXZܹ,fI\w/៛r}4~_]Q^xkMD߼yHr-ew ^> "%0JR)0KZK`tƬt:yАSJ)`"IS:Et<s0 n_L[7bM8qGfT"hj@?W äMCa {Ld3{nG]EVp_9<#[2g@D[cw-E-g K'&|coqS`s-QιR Q75\֢A y^3 w^ AKSj2|F3wn-SN΀>gm/ A %?PŭyNEil0m,)"O=nIUadJx,D@G ˄2Jn XZU 4C`g(ё19 S^s8t1 '3wNL5HRf#t`k LY w5ԘCr)"Dm^kn-N 4kiL)8JJ$ZRG̒rΪ)"or3&2U "tjD &(:/c<ԣcHZwOZ#@o=>}~Ԫ6kI۷@,O粮۷j]>==N$9-^C&`T3NۧO?nmhw X&$1$L̐jԕK)z^1ƣzj~y `muY)t|o=RZm!|\K٫ꠢS0M7EB#=4Ǐ/,?>T0n5|=p8qXoF Z+~8jլ&Ru5Gn1i'}] 7cqr #@P{1ݺ182v$m掰˔^p\zrΡ~h6.̈3PyĸCP X1p01Y޴<RZھ7K[@Y0@7!!"C%eGTs5$$ykcC;a$DiM#SoB2窺\A\ V";O)*1 &ɈN@ềM 3pgO)Nݚjj0OΜD4;ດs­za/!Bmz]sܔIk!lyJl1}I(TLc3}0{RyV.ppV3#NijZrQ5y^4|&ꮗJ UΉ/kf??ϗ+:t8\-F%S`MRB@P!J)絮B@%ĉݝINǧt8Szyuz]Zi9u]A׿uAMSJk)+y SEa9CRNX<;3G͛WE4Z/˲^Wln,Ӊ<}rVbJD޿^KYpC^4X8_ ]e<wZ[9Mӻw/4wG.Gp~/&Е/ft{DFnIx3U1w# ܣoc> aAHI' ~H!y_Ɯ?fm5m,s ZfFW s7U2# kmcL TSB`7fNtDBoR;4ije`?Kr,XҮ Jhqu$eYPP $gG -$Ӝg--a^+!5|KnJ‚щB)4 ^ !fLiJsj2scIձCWj]ɰwPDdhJ ]pΓ5s5'pci5uug 3PȮBqyRrεk j#L)?|x.sqrp)\ZI՚+i 8?|2-$+ԋ. Sm5NemeYU67gG˥yCJ)93)Or.ZU[CCrL?/_.//Dy*a$z1I~_E{>п- #%1Z 2#{kLy9LjZ#NR*|8|x6穮5Ig580/x<fjZu2;- {@lnD=Bu]G{Feލ-q\l$_CÇ&mAlmV z#S]fduDXU~x l.8P`3֚rp.:LDsPWuoښ4(YDb#kixJY`N)T#2 "NI̼֪SN˲h@Y zdNC`t}滰o~?}HD,ZgsT3A$CaQF-$ê ` 1WG(9xh+h1e734$č[)OIm ݯ""S:Z/ZkilsέԷo4֞GNRK1WQ3w:ab 4'o,f&S"cnm%͇bE Zd'V 27ӵ`JVDx].^[+Uu"w"pSrו.k]MsL |L͢Zwޙ1c g`-*!ɵ"uݲ#DY̵,>i]t:Ou ]}-M?k%I1]#v̛[eU5h40Ur@> ().2AccWtWuU.޳E*#-pde᫚꧟~_ix_DBgX9`PS!?AXDF'/18]vew2*F17K )P=M-o>>w9:L6^VC۽ZNm,DWA[_)DP3Q4Z+$B 1P㪂I-u5"UDϿh!q}+x2ScPk='1|s04\KDBΠvn"K.zo2:FEDv#3 e.hY8V\ r"r}? 36UUqXt\m~w]tg @G1x,Bpi1FPsE¾ۯzuy:>̱5Q'cJZ=I8q9h1ƾSV}#}d )%Br7P{k{󤦄H&VOU+<" PyJ)A 1jA3Ĕb*:O#{||8#-#8:nB8N!u͍qM%jaSnm7#(}?v;Xb0xZŨZ#EjYAK@Q=qjА ʻݾu}c_Ԁՠ+(1>T.RTL\-dH18޴016CjV~q8α]Ǐ0 Qjw/~~g\s-/0L)]?CHӜ *RI6[f"tA}mdxX"pU(2=wHU)*.i*V YH̐<Ϲa˥!UCp9up@DnD~Zס:I`"N8碠nP 2 CD ԗZj-)R NCYTcRki*"SKo߼e>/ͷs? d :M]J_})*?R$8KH *ay׿'`e|C7!r-(aA?ܤEU)vqrV:Kz.BfqR%hKrs.[cdRA';/ŘSRt{11P%|a&Uy~~4c("h28 AM 6ye[-PW[UdH+ "omb׶+ d\K䤍M1Vͼ˥e=.h&˟N6j~ӌeYd43wp<UoUd'<l3`뻔B`HN 湄K]/f]~c`UcL$S*2M2MyVBr.UBu`57WNis1Sb.ծonGBQ614EjʄhA]b!ZCu*N}Wj9t D%0ԩllJ[Al眳2WiAv)U]?|?|xus1Nӯ7`anncH(b:T)u.D)Z37lH:"EUk@Q!3*}߯s.]߫0@s,rp^kQ0ǎC4su0ݫ "t{7dO?1c1[|Rۘ9g5 TLT`!ԬRb.SA*@UsR`yB`B%iS@f/͐Q)GEWA2 6ȡj1"eCS _OaS @(t11+(j@bPA59.H̔RYTՓHOU4 hj<)s(H8sۇby)9fVW!pWvFbn1qꭨٞEۇɵ/Ԣ{]xRY(Tݷ!oÒ{2ʓ[ $e[t 4}!/Sxl*:wӉk\D0.UۤjBDBB@'LD%r !ڱ=q"RWᅭA-Y8yJgVku5|<-p__1S{EVhMDM *[ G>S0DF8jJ(jWcJh*ݸIU++du$[i;bJg m_7*6U/ݔ74Z94_rfcByj}5R9Ͼ?8"nS{d"})z^2S:UQ/Pn?#q臾8y[S .U L8B[uzQuK j:,RLn;@9WTS{W]t_Kiu~wnةh-LR5Wl.cjFs&B{?K-)9ZyiG89Ͼf6|UnWWO6bD3^YMy&ɵedck,:T]78g UGI9bnbX#j[HBf)мa;sVՁ uo~ V%bv U@<ζ6+A`6qvT1ޛ]ե!ԄŸɟ;bzۛR TfBj3s1!J7t~\U:9˄.:mֽ;H6VTlH V˥j-W_~Ǐ8ݔ6ZLZfAk} \ j*'?Xժ,roguy3c>{: qإ,~3}ADek4]_$N"`123H"T"L.PPUz"Zj>1Nv} lrM0rȀ}ɐX"՛B$O=(2՟|?=> ӽwC,ǒq1fSGDDa_{ip3M+|) c(TZHT,>@P@")u!$f={Uj-Rsk/64&]O?O4ϙ,E\}EYn0r;7˶|]b.{{q)^V[%|3H5ƌ<}xڜ- [ B5W j`i6/aiUGZw"^G,c)Nro@-!p[nZ/N4RRJ-Ϗ!]C,.34"0Z L˜U5R&0ef')3Q BV4ʁcbSWW7n<"]yRf{tW4}ɵO󜳀a K.TVkZ NDinVid[x/a[o~ ᳳsftbK\^p;2[eŬ`l=;K]#{#d'Q3_.6xRT@@䮊LSi4stev=6:H$Ko q-}_ Ǐ H6SX/pCDD5L} xRιOp;0H]yTYaUUDH:YQ*0PJ1Z !]Rj)u1Z"2s|B@樀)$f*80tCS^2zf2׿yx|V|)(;o-=d)F3`*zZ׷F??<:F:O5=?=ڻ7aIu7#\"֢"J)a⋯F?˯f7<\uRb }Ga?g'}ݜp R]ՠUDT޽ |8<@~mJ//bJPK>"HHql3'PT|_xLoqSl1Qq;,"ІTԀ8vww+V7A)phjޔnHi!9w]@lAdiHp8}Ls.]h ]IyTrf&3uE#3U\8lٖw\}.5JJZR]?B0O?sZ.ZqQ,,B]zYp_cS! KU"Wh Dm)y;=IJj'18c׷7OOc;ʹ^ 9_>\_|/~o9?4l̳4;y?ݛz ®aW%yc~9MCҥUk䬧.ͭT~)tCH, <یQoUM}Ç?>??yv}闿ey~~]]ӿO1!6[Mt1:6Ng Jkw>\;|81-ٌ~8|Vjns|hxY,]?/uUY)gOW!/Z~ 3} [X{Ix~v6Y[ 04G]~i@ 1Tk13ъҼxdLnpDbIcLɀDj??ULIU|x,R l Z 1t}s?.݉\RT;R*EL0b\KჁyH|H!~7إoތ"9aT_a :ײ H2UTfvU_'TV}/ċbb Ԭgf_ TL}D*"H }5Dv?kPnEhsLgyd4ǾH{V̘C\x2'ߜ]X^m|‰#\8mZWSYhK]Ete>}l2\Ap{DTQ BssѤAB$չT 73 1Imr;$EK`!pD4&sͶ>>A)bu"5Lԩ"yJ)Tcp4xFV^EUs5E3"BC`q&gWH Lr1]&1+c0%D@EA06y|IDWv]ι,*91cJH !) ELJasq?VC88 @"0lƷwoRj2R߿?ws?1~js*}x' :Sb]44ZRs?)nǡc>Z+Vy<1yRAH`xADu)4MfXlE\3tBzP,Psɀbb$ C4W'9Kk CRb EXDN"k6-$Q g{L1Дs{^`&lUZkZ. Cp O٪WhF$LA'POI0-<9ut0baT^ Z/&ͼ#o6y |&?E_@,Qnۇ4u)nB;bx~?Ow7_~՟ş?8?曻ۻ?}T>7ϳ TG 80\s-KVRPRkuU RN;:x< W̼:1;̺+ HyBZ5@%p?QP1$1-Oð1 ]}=3kN s8oZh~/nUu8")gdlCeo` Dkڲ7 <+bӄ`mTsb$UCdyޑQosC.3y.KWkYIxF]L@*l qtA ga: 49a).})r!)R2*x[Bqv %a2gpQ_ z8_ ܠeվ0sSٵQؾE/By}_`i2setP[V^D`p{  ?(G-2)_/ǮgKkc\,\D:.GM/ q֥FL]m0X D a/TQ@LԜTy`c8de#dfr2q.0SJab=ȅM˞"t M5-TkB1fCRy^[%8`  ,Þ*rJ>z[.>zLD"5t+=8kQJ&SA"5P0eƘ9Ƙ~;18/_ij[9Q?Mھq@O= fpr"ѥe@2]_MW -s==Vb.g*]%[Xq[/?)%k"YO.oo\ ^\ۼ< @tqW޳R+մJsvR랮~7|ǟ|dPAbtb%t#FMwlXDBC'_3 !91.u]y^3&.2Wn\nw}uM)Cv~x>~W?w^ DOHȈIjSJ"%ń*b`.d FZK.%*T-wYh뛛i*9#2ٞ6"zٴmj7D@)#B_suU̟@M[%$|%D# 1ڜJBۿ?|?cq1F]Eo Cu62.HDI& 9^-Q`)hl0xd5f@T=;0_kEGDWϼ"h vn.o.Pe/:$[rv7sd&VqR3e6wX@i6|f Vs1,/NOY2\v_Y;AUyfPlE>3 zI> !J1F@XfF@Q"1V'xh[P DB 4-~tCW-_J,K:C\k]Z".:!yMsDc a[b:率7hfK!D3ͮ]s9G 4UC4 4B޿JfR|_~||n_]_<=@MϿ/~_/_~ߏ3Grw}|Pv}7OxLi2̟p6ԮN!"RJ8<)y1UA(REϘ= Y{t}ԘYE^VJ{Jj!ߴb6'mTLnŴkb,R(DVS'[`a<4D*%ں;= g '^ Kʴ5H3m>ak4N%-//BûTOi3Ĝ*1Fں\smpwg-cb 2e+Wp.VWrK6^ !bEDSERX^1{Ѹ86DJ5GEy0^(J2xzP"?= O[Rï='"FC&&U JC5FS5A-ZRrE*rJD,ͥ5زԐ2UјGLUJ%. 8 (<He&T!^h.SH!XkI~})tL1:v'?_ZonƯwa?<ǩLLru7iTAHr)i].%D11"VfZ{A-<"!f"2@ijb21#i. ~8=>>2'xkjk ,t,5k 8@TR>#=>~)j8A-%N<'O&B(S#s#c+uYZf^ueF,#WP_Y|@k&k*Ə>7:)hM#^ĽTol0l5Ir! FAEKƘ(fܘ-vAz$g*^-}&lt|Iλ/e@aݵm,KQveM^* eoݭBdDtxRKs7,UDk"G~Ӌ5UkOC舐I9 3"VJāiy 8xT_S,4]&0DK-V\HNTbj^by=b Ntp 6"LHh}ߕ9Co?~~""ݐR*2\ߥ]_hZTaYr)0/hF@vd:8:<nTSZq2BL8N__R "z(1p= V&Bl5 İEL^̹f!f9Df,9}H]́8$g?Eĩfv`ҥrgWYpֆJH"!ˬ?uݪ,SCJ7%bЉ%@ӵ|B l>l51\ƊOVC6s̞3t㖈 hLY \Kf$1B 薁)rqz}?e ]$D,Uthn!!-Ln @HU"R'֙d8(`LAvzN)5p|x|xx4pKɫN)}׏O0"Ҕ.v^XpPⷉߣmaLr0\sipjq N(q~?{ŔW CLɊa k}W"}w磂(Q4%NQ DH `ы. !\ `̓߅`3<ْ0Jm=  ,k7&Fxo늰4ՉOf@'[ )jϺH<6hyg(lt [65qFz8FT8RO}!B-ZD(NDaAֻnLK Ɉ@UsREi0LW, {8D443*KyKdR`kM-0;UT-6*ݻ }kFxSg1q1Ƭi̡$Bf )SΣS ʁT Jix$bC1mԘB!DĠ B{Ds)޽~˿]眝'wÇ{f1nߥ$UWw5)<9cfoj&j?jZUbK3@qbsu/3#P]̤`UyI])zrB4"13@RJ)5ur7&W +,Jy1rt2*i])wKZD)Ƹ:3w8/}s*ui)- -*;Zk&%捲 S!`35ko1jRaw% _o>;4N_~EK.뛛ww~}pS:<޽{7t8s%rL!<jK.8sNL!h_<\:"u֪DCpQ>&D sh04UEܗ?plV\Zkuۦ55q3[eB**$`;u"tx><]wϏfv}}?.n4•:DdPm4JGr+6. 3z2B̼h2} D(c!CD" L.?_~kw<5^|ă&m4 >{Taκq;{fHE,?#zmKlfxI}C[v|NN;Y jdӞq!G63'OpBwnb918 ۮ'(X͍cd]i1\C@®c|?\wx{lmI)~WXGnw[ b 0B 1;>pR4OPE% lA301,HDmUh?ܜŘ c@Wo 諯+ Ija#uzaK7/??~@t{{WJy#? } 4{5yoc]? n'@zx~9pUb`T.AxkH۸!"D dc/au=#@`~ z?ݗ_{ß?1y۷D?{1~ޅ_O{|~*0 aWJg5sVMXrabd>TlRkS!L \݆H(I6!wZ R|b,Kɉ2q bRE G<8wVOykPTk֪t]"{_D\`,mRUJ 7`WyG>VT07^u11C1n{xx1\\?<ܿz}hf*wW~&bW֊LVSb20䑵  45:#"3R10X],kU ]ZLLv8wU#]LI(65HB,md}SJTjBmfjMd W&9fMN K'itB}1S̴0cNS p2Ri^VvR7hQ_ <)kQH L Cj)ǧ'$zfVXL1UwX$hF>yD(j53b@࠯*1CL-D1uRgZcRD0Rk(> l!^x=UfdƋfh%yѰ8%#p\xxipw'_w/?LeլWw)DBbwp<\"iufnw9_]z%3sۗ*9??Ej&*|D?l<sn:wp{u4u|49Rs!r 8h{TWyc@Lj EfԪdCƾ\"sF@b*8Ԓ]Cb hF9P 7BH)R MMdQiYz8`RJ]ߥSiժ*D0 T#RM-B1D2C ÛkmcـaOrJq:.ʌmD; -t%\.rRK5/ .֌eʦ/?r5j_)oha_PlgZYGՖ|/aRxi/SwZ;_~ o߷7$ҋ upc&sOuYlЕ&UnڜBhjnL ۢΌoQ63DFBjD.wDZl⨫]eZ3S֋];^/OZ|9'"qTj@CL7|K!<~ǷoLëW~{fu4MjD4ʫybC=>=o?/?~"JO)uOyQT9`)su1)P˼힞kկ Ag "qƔR,e]f!Zk@t 1H!qiEkXf#)$DMՈ9PW|R@sa-e~_j-,0ޘY\ B\$uÔC!Ib=0 - 3f_Bo.B܆*8KgQ֦C&+`*h\؆~?IWckpyVckMy};ekKxڲ]gdߩ$Ff \ F(2lX43OqUb&j}4J^9إZ댂pi3C-0&"ļAi84=<<~o"&GN/q]jɻxO8&Zgeۘ pqt""v]x||x~ L)W?|H֊?ǚ%:H= Ӈ?`5W7Tq)E!L//?|SKhZ,~3<aID@]q-iRJ.E DjJ1&B@)cUXd{IDAT5M1EJ%"L#&&g{+ JѰO)bA3 b^tRͬmđnԾxAnf]}%*ԴтyWX>4dDT5[<~z?5/)cv^1:tAi)04z.\브}"`Ak| -O$gu [!- .0s$lO\KW3UBs{pq.E;`$3@Q\;BΨ@s`QEĚim&%iƒ C,"|BNH1b0b>KID"CLA90Ue3#W_}wOqU%E^ -RL}ժb@$"GaŵćBYKy>OO&o~ׯpLE_qn R8MLBRL9zjNrQI><2s ʁyaTiby 10MTT$T*Ԫ!@RC]BVjQ1/2t=!C ]O@!J@‡LJE x Ī:5WTuYmaRL1F)7RĪSUL 3iR|uͯ,䐈 jVG| O-ڤiEpCfi< qg')ԈM{Xo3*&|*o;OFϠ`υeex/慒x6~o ,XKQ <-Xn֡md~ŀEg7]*z␁8#(1Uk0%x|> B 'Usة4}!J Qj !*f@ tQkie / /$QU!$8T뻚gf~><GDߖRf|j5sv]ͳ33JLMʌW-F9竫f8 :Mer`$z+EOv(e>yk O}שz~mZtsw+RϾchVU9Rnnn~"%iG~E$LPa]UUQf 4Γ;,B f/,WHˋQjuk|^>/ɣS@I͑]UN],o^>6|thkԅ77([mED&i ~TS1XLɇJ8Yy30 *CPU0O 2ĆNְZ !] >R 5 C`Z 2ZR k*"^=?y6'3 Lt}wCץ]׿)& "bJ(o~vb~Bbvtw?`~x7|iSߧg-}x=Ma}`d73e1낸p(9w]֣+vC)cG0 Jqs!uEKYMbgi]8, "Ef4pEK1ǣ4 =2*4D'׵1EwNC"Q1`ᥪ˿3A^DC mq :֩_ef&!BJE gb䷁n}W`exo䉖lVk'f\&0~RG;ˠ_mRO~v jvl ؾSͫ/"̟1K'`[ɷ̖#"_S|.@OoV5@Dheu@F)+Ԅ lsG]϶TL,.,b+vNS_|d8"B h]U%v>L!԰PVvy [)w^!4 h.KiJ)Ŕ̰ĉfBv4噈wץf08GR|<>wO,Lf~Arw}&]*xswi<>u]f?`@ Kd .FLm*_3<=+\y5]e<_?Z")*kȜl#COD# DC]B׈N\Dgl2 g?-/7K)p*=}?6>bC&vkk0vmXN=sMOiۺוyu+uupUUDj`W(xcf^Ik'ygDSJΤ2~cg^R!"S "7hn Lb#BQDjا13aycJ󜻮C[6]/ULuZ|W3Pk bLfv5}{3Ёhٻ}SJχQ 󐺧..8v# SS@$ $bsN)yHPPȪs(0J̈́(Gt7+ BɰXH12!VAK\ @sEEN۶c*`Rvԫ_}y|zvgLr";J&!hl}5OItLJD"Ws>H}>ZKɷqKӇ\JR gokMj)L Hw|̜"D~}upq nHE!4Āb n~ysظ$D$tTB%Up!}?a51J\:RI\_tèQ hۻiTS@L {UZ,zki8+V?>ƫU@?-@vym<-D Z7ݻ+͂qjM LA|Hx-^O֨>ЊDeo?zQd z|6/Mm/? ]^nǖz]J35"@W"͕O َ.I֤}Hێ#6J,a@Bit Q7f(Ocb 1RJ w!J`f"E"e@}KU|𕈘)RQ7\V+ZLaQ&rGZB+XTJ)5h[81no߾y38SIj5yct{{=IMnnLi*KfZ1j;<~R*xH-R:=pN6wzls b53^TL1"fb\sEg}ŃS`vICdZa L(h)Lu@[n=]|<J!X03]>lm bKj튫H IG](/KJ2=hR>EDXr(ȶv.YǤOyNnڤED} '#mLl—~cY#}O!載pV&¯xl ^jBIŮb@/ -Ch'h<_iΏkC_-10Uw<=V0*PfndZE^3ʩQ3LZ10/z߈!FSLg \DUL LlVho !n\KZ!*<Zj-_RkcdVZSLBt8>!AB)]x<>!\MKzVj)F&HT+ :4OĘK"χy<8"RUL)EdR)g1A Stsp_2\ k-*YVp쑚2ªQL]DTm )qAy$aPmUE_|ЇZ LV%DMӁyy%-7vVr3WEt9dW;5pcSO/ "آ u !- 9 {\ >f_+~CyT\<>?O7+}Ё3!D\)KQ`7P[qRCٌM` J{sZLEڢ .jh(lky 'GﺮTA`ClH!{IT\ |ʎb|B\뺽AE5e#\ 0 =kT/Or1OӴ'dFkR0 A7]|2]A t1h?$pp|ԚU%nƁCw"|?~ꫯre>'"a:|x0>PE9ϢRkNԧK!y.ﴔҘgE{(k)j)Fd!r." DVQ6!n[:E &hU`@H80@r}}sf>쯮= is| nv&f5dRb P\*H@kBl[]޼{ 2ٚ5/gZ'|LA@{Sk|e2Kc˿EИ9ōvŁ}2omS8_L۷LENf~^lr!h:DK[N)|ys!9gx{q/"<[NDh́WBO65]UUc"1!S;H[B1֜T}::vɬ3K@U[|P | Y !Y'M)nwP:_94m4'rxw%dUPJɻJͿqfyѝA4<>Mc|<88n!@-z 1a?wbDM|1+%Qz0dA0pO>@m@oZ4p9 T*cbbdjy]EZi!DH>RJ%DD- gӠ9 Oh43IX8-4$B*4@ F6cu.\H)#fꖇ΅0\zÿW"q˼**W77e.qz~~@ !F0XX*oKxݠU *@H0U\C3(.F!HŴ( f&`TT*(1%bdb@F2%3ӥwͿ1/%XXN^ 9 "Vùj'[c"SKz8 ]|[#V a;Y2y?FpÄJ!q 'KVP-Y'вf}"0~"SYG7|1#eLg['׉߲-3!uEԋf2$lrhGl:L Ff 0 j^5*i&˩_{IKFZH>:{)Z 9{Z9eUc3Uj6^u۟xzHM@U39 $"朙úx@Ufʮx8UQ1)15=HZkgUu9cL `y+3e9qwww?p.p{}wNRχy<,nnnCLRnP1O j`8#qx8>RVYP)ƾ"8KLf j.u]삂ɥ\ ~8 !TU84 <)6FyfbnU"a`'5syLyv;l Qcd UT%X(9LS^0yzN|Oe'QliYorSSmU1Z5( 3c_']?IWl[+mS8ظ(fv)ئۧ[zHb{><&D_}iAln ZTZg`2SyZU$pPnU`bJL.("aDZUdv]ug0*bjb j컪z<IL݋bKqC\ M(+uZKYLkږÝMp_iZs)x'QZ|S.0l8vM4nv{-!0N=F%:i/dOR!?!2Uu_#ESFQk!O='ua ~'UQ#'b'8Ab&8KHL*DTkMsTCLo<&VL*! QD|p՗[K;U $ʹ"Qd12Dr- ,ʦy6sz;<τp{w3 }vKVD r$̀ZAkv2͟ !a 1)j,jsw&Ӝ'p8P%<LLLkFdj5w 4#@QK!L qbȨ!d)hM(1E_}O!QǻjM`9u7(xj*0@,m#Db"dSJ j.];T9P"zs-!|;.y F! іƞH2 U \YjVPe?뙓 eB$0-,stʷ-|Xhs"sgOǺmARQl/O.[L 4n &ɬ)s1/la/B,jI 85(PTqRT|/AmgRcw11gn݃DtuuUkED1z22gh~WKs.fD"fnN]$~ͬ!̌OOO"9}?lfW+ԔKn ci8Јenb"*d5&"PQB0"v}r(T8w\3Jץp8>?59{HkW꺽yuu?~=7? P& !T 9gǠk.^ȅ(ybj""w T=ʤ9ߥEa9ӣX#kS{$>6φi)"\bL!nͫ{CHwU_s$4u6+蹅x! Ɇi{<׶Oj]3Vk-âL+Ґ* Z fkB-^wWPm:)[omMtًɨJg:}|5^&qڃ^DSpd @yuZfgZ[ʹE'$ Yi`1{mՖxK$j~|!@ ,ckm#'3WӺ% as4UvDEM85e.žK%RRQ K%2`Dhbm`fDd]s"%.w}5`} ]-z{f@fj"*/J\ʘ.:1]{)eq_SBR9s){0\Pņ RT3]_ ] v}%Y~bbUyfww7WOS@R.bD!jDCS$׆4j4T"uI{7'S R@<ū"'%yo"3w~1"$ݰsXnMփ`(q-̟6<4급KǏWUaYYPswS%Zz~:^ r>I`z79Se̽rN_~6o:Powɬq}",77!9ǀBD *NtW{R\sZIbRs.#:VV,  usO1d'6DX>jH4N#9KUS<QMM\IU|Jkg`w=I̡b]קT԰ͻGKsF&FO<% q|g߿.ig}"WUI6L)Kc 7f&s`!SQERPA \nys.7_O)!8C`A7^ZwjDC?ի~ Vk11Sf.h׿ȒdybyGdGUWz{W,!JZ7~׈"(@ Rvw33ӯ73nu]&.nf*S)e:x.KSmf|9y'lLdfM;{g0sY$?,Reo­ff1d%3wpx P'=.m>qZCofD?}=9o\FJu8VaB 1T>lJ9q=2y"4;.c=6x|Y;Xb?ֶ6Sn3ex2,+N됡\Ϭw49Ͽ$<Au]ȁ4E2Rof,+psSw5O垌mO|icİb>4B&PW?7LL7mow}2Ӷo?}$)(Dҷomݚe]8α<ք"q]*ShnɇiDɁCdu (q5%kꦪ "RHJ)LGRz ѠFyb(j!s?F3x5=ꌽ幟0D t3$$=x!k1uV_ Ӯ(J4~|B%8l'W[M\RɊ8 T+AL|m?;[|'rk=E罵;R\RIDj)uZc@a, !=̝QU Pz(#Hdu [#8 ҂&bמR29'd io߀ï9o#Y)k{ KJ="D@ПLEA>c7IxY]F57QY̲+6Z3UdE0Q'*4<G#1 ް`FAJ!H~qq2SQ̀w#QZ!h׏W{0/h7ufY`3(@If1_0Ո(x{R&ۉ8QoDbaDt fփH4 I>!enp= Ӡ}GZh qw{eiۂ(75ms_kmAQF@D䡪J,{eYr~: u L5jZܜݔE}sw5PDlj,Dt,Oj(ETi{seM-H@ ~|,f˲,z<{Rw?˲HYDݷ 0/Ke"oSko;)ru)[o-EU; \O@߷(t{k{kL[Rk"ˆW0O#9C Ey3٣Z3$"RU,d~ f]5Y ;iL3>)H#`J <HF&"JR Bז۳R<*4ֽa'0HlwpD>VV)%P#3Lމh]uZ ;N"Hx.. DR T++A4biA,eY#-DjZ,7$b@($Gj6nj c/91/L4uDLSe>\|'}O}WXHzW{-„Y oLPb‚d]EhY޷zSPt^oקL-YDD ,23DG}.GaXh5`fS%Zk߷R*!q{CRK 2S2Kn"WZjg.,9!ϚͥD mPD\R1wHY{0#a{Wb$NP XY6f31xSJtiNUvw!K+A;9a.n'mN8 d""ӔֺxX pXϵDA9O][*qjfISfy",HsҙCg |*9l{ D"j}Far(Td9/=M.bD 11'`}`dH-ywU$baD쪈馛xqd~D}o(Cl"Ҿ5K!b#?_o6Zrr-K8p"noj) HB> LDTHݮk۷Z*֟߹{)u>(Rcnﻻ__o5)ĥmumeT:1{xkDZ"JE)~'*[V@4}% Wxe q)HmxxQ8sH8.x]b)-_/; HXfĿ>^8ʼnmy*FNN{aaj:%O% ?fp|ZHiH>2u՞[l3n)E"Fq$!` }1!}AM@U$HSs8VcDF22b毯tkF"Z%Hw{sM=oJeFY,]Q& ?zY/[RUp*oU2&aL݃D(~z^zz3#c{kj)E{1/#3C{G"7u[k\xTyE.e5e,bBJ YMvACLRJz(FF].Lnݷ r$faf(RX'NT-@bVvjUsrwm=zkݾo Er^zH"LLD:h>"ՃDqC"1œWZޢrߑhL(C"%ZDAL˲k@ݍSΑ{fDTZJ1 䮹g'H{=,rN?>e˥޶f¬!vpAp@X"E55-5 eu7Own]5}x' z_g?w^>"LzN2Pmї.ץVsr6ێKB"0Z1#BJ!fse]vH@@v5 ٠0I-> qYu]ݝ0="z#2KzMN1 cɤq$b03?ʺj"oT);0gzv~XDg~}pCWfZ#PF%mַ ~bm̏ևʛcD>|_><]5I0|!̋ipEs(ٺL-[O0:ccxO{pW{F oyh`RJ8 wﺪP qfCܭ!qx wl8d,L,H,NDB3Kj2$@"wRjuR>|("e!$z]{۴w]ԌY5#nc=% huSS ,,JR B///eQ f,죓iiޔz߄Ė2A=Ҹ*EUrl|Y jϟ?}z9]&KY jgnLO[7I)<'>1>_.eo֬6a {vyCb'/8ǎ?_q>kJ~[? ?23S_36h@ȟBu]U=Sg&>Lɞ $;RZrHo nv\~/Un//rj!vS Yx`t‘hN>R3b)Hz+D[Cϟ>v p)Dtg"e)Ak=w۾fGiK]1O8qry GD}ߙvJ+ cv9r1P@3ٔf0k#DZOκIѧiq[Dw"Adj㜝Qk> y78ҏO}s`u;Ht㞄E)%{;&ᎉ@dɘ3"Dt !I !!zAח;M1173aZr82A(2)mRj"#`EA`˨ڐ9ܥri#o[f짘EF!pFnZEJb+O77-mUzk0PDAOc2W$_~ Ld5_^o^DvU j 3 ?{["m},jzY/7&mۮ˶"e{Φva(ܼ~?3R$ivDj^WmaH~kKvUA4ص~1f K<#I&p3\ !+ȆSwI475H!שVP=c"l!5@)cGLĩH7?Z(]τrzʏClT }dm3qτ<)@d"ZIe)u]4U@R;Uèǁ v}zm׿.wUL;l ypS3k ;!@J@@̭u1dwOPDBH½"@PH5w&>] [ |)݀pY3j׮к?r 1EMJ-;2shݻ*Po )˺<'Rr}F*j,/)D6^\S[F@ma-njy]uսRJ_'L?{zzU \ o'B=o_oպS\ Uu::&JJU&0wduZԶa._^.v@07{GzYY}wӀHWezY.% ۆc2R2ZϪX ")1fQ"Mi Fw5Ġr`GC'aaa9=") &4U'}^| ME`0LF8%9{-EK)r 04Xn]U3 3(FkPk a#H,Kk}[-Ll`fE #Ĉ@) '[ͼ r}FbH VEM͔2+UDDAΚ < 񜼉.vh߶f"u&{o[[tS]}bDH yD&(=~}~B+Ysn]K)7f|{r) I8Y*R*mۅ8XRVaf)ҵ'P,4G]U{#qή6!G}~yO\ {Phߴ3O' i0=A{ţ $c4lv#`2s>0Ud\s3=ZҮq$'"б V7W^<M>7B>DkȄ? =P=Wy(!i5WKt(G"D[Nfd1T`O3@3@ӎH^"߽DS38N"9j- a+`  uL8"s֑6s5 /X.UXkfܡ4@J]Z!RD 5}>'ήmئ"Rk)n!FDNUA,ko{A@( !<]Or=)k3y2^~EfUz0릚vg"\.ffwCƽNB{kli]f#! EH)",hRJYZ&ZG{o$y7+i- vR*xEu755Jgq&ɅCˇc]fNg11D "e:['1\a(Q@1lԐ/[[BAgEH{ ʬɧ_"![gx6rӏYU`ܤ،bW_M0x2G 4ޙ dVaUD3 td4ڄQ{^v{ l$"=0uDp2&o'M*=Y롥#ɜ%g:[v"r1ƒ=\`|:fH BN] k*|k;lriҿFh㲢|$MOdsMcDl<}C6YdG h0pR 9@!EyGhR)H\R_T@{QJE!a׎0ܴ3c)ey g=zx!9?o/֗0җ"Yl5rD*C PJu q 29 6}\2ͬEK]$ṑxHs[fpx}k}НZdK956#P2v =p",$Lr ˹Z[73@̘z mLv5-XDC>ΈDTe]*0>C!UvRmyYQZ?~XdaąO`Y֯?%~{]ץ8 >*7uf6=<as$)W铨>̧zcxALӄH$6r Ba3s3*;# L#͵8eH Rm < `6s#{^kd N=ysXtm MԛkEC18?<U1NaoȰxrN4?/C{@)EͥRWB17K}GyFxż F$RTp"y=3"G#׿}/֚iY E=B˵<a.X꺮k~!bI"~zzvs$|Z譇۲`1n}g[ӭ'tR[|ZϟԼTYֵ07ݭIHQ|kf&,9c~X3chDD240n$=f^je3S}۾#Qx4j&KUk 7!l C@)r>k:z8÷1'|$(/~c> 3qآ8[泔ә۞{`iGt\'#z1iMIvdR-DgdfַHD@։\! a̸2CnĘ $6}@%̅RJ-Hۿ5J ke9$d ÜbMd."Rj]kSE@ÑܔU-#a-Ÿ_7`u3wp8-4|4C>}*m AH%z^W& Zʾmf^J)-DǷ掟#I "K$Y{RJ))n魘K!Ʊ7]j//qͅ%p\K"$=E=iY׺_,??z]/@("& $_.J?Oe7w>۶!ba:-;<o$D% f^It7ag{?Q+ŦF\>f) 1 P5=ͧR7Ԓ7|*$/(_1~0_̶Ԛ}wJQO&o2U<[ӛ}hq{l#:} <݅e@6HU#ggo.קD`nRXK$[psHRjX@ 08Wa#]1y@UI1 fE~1cm2_IJ}cc"T43@ /hg@UD қffoj;HIJ( kNm 1LXjYmy7+Emc˺l~rwFb""2ّy &͇{ 3RR~ò\DJ0/kzGl$vW퉆-u@`!t=.Khr}ܼ֚&w"r{~}FD^> ? o}se7՞G~j)6 8-!+USR2b4XM0ޘL~`Lx_CC{DLkxecr' %#^$$OS#鞌T#<;r9?</@?y}iX㟪C"Tu3-FLY|:R|̵:F?B ;:rg?ٖ@bT7"II4MMJfcw-E6Q31s$!1$$CD%jϴ$&W/JQx#bC͹Iu|kfe<1'|ǫ͒=m@XXWB&j@LUp>TYO̝0 L1-IY #JYh 3Ti C|h$PE!:8j-{60 oH wϿˏdH26B]n)A.R3vDl,픊t]3$f˺_\^o/DT{DЬC0yo{kTR, RZfya0E9?@3l`cq(I9͂"i npP9wwA&iK)GD/ 23.Kf0HȈօkRoۭku nkC%iD֘gwm{p1@Fl4 ?JV:"ZRY Q߬S˧#'dQ.v?'  " f|a̩L8wy^.VQ"uY/nK@d:R^Nc㎸;#hL"O?ƏgeLb"؉" Cy/c $qn@VI3;v~-H߱@>oEX8յH}oͬ RY<rѶuh͐K[~D4Zk@# 0,0;y(>NjBŘ"X\Ww/"yaAލ9Un}s͖ۡa1à ${j=ԚQLAD(ƴޢִZkm+#PD5mڮ5ˁ ef$f뮽z @DiK $RjIJÍf\NS*w0΋[GY|zI%&3jOOOin7!nO"2%#M;˿rk;)9톈֗K7_00<8d Z[KJR908Ga Z %HGyx{4K3AW'"x  |y3zIH2lK6f-ǡ!*RsvwfY&zxcDB@}CUdCoBtq2,ϥ|W|2o.L=F21D3>Ï14 ".uU5"fuHS ֌E -‰ [o*Tk%,Pld4Hè/ ̝YsRU9Π$AC0 PUұVmcMq+"Hyj!є"k$R#@Z)%3_9fm !~o/Z߷É.\AX1ia vn T04$w.yng͉q6|ε?_t~_8~| O.}pbn륔Rr^KjyM,ܥ1* Ts[8p~8J)CLI6yvI)|4J[@&'M# 7'm/x,cGu999;XrM"]αg2{TԽEZUKO̝ep!xNaf /~\Dm{[8th؏{E|ޡ7 >;Og{Ʀx3RqI=r_dzy}S3}ۑ>ZKr\LCWk |Y[KUL??D`L8"ưwqn ]wbBtHL ֽRrI30CAM-nhouYe齿{amTRJ;H7sX"izKFHkֈ 00QNz8k?.vM{v B $l}'d3)ٷeT B4S00=LGJs'yzS %ݕ .= L{D<m[k"Z<ǼVk/i1mL u] eAe]^_^ ?_7f gج׽mf\~d<~U& X>lF60%va Pײ0zyj#Ծ a$F*]gS{LvH6 p5@> @n,Krnw@*X#)E[,Bn{N?e,]jue B\.u]CM#O0꒡#1{?p)RNB{ ѵL?t3p0/ A] }@+hzOhYV&vd/޻Ԣ624D(8sdH Jm7$fa|bPlʵ=y&9BjTDoKEq`ڴ)tT#~ݷ_듹!! bZ ,^jkLLBG5C  &k.O3|veY̥TD63`rfIsD pD!{k,ZT%I/mĠj'~RGk?&22(*W+1qr_EM;K!&*\!9@]eK{Vhc#sӿ|_-8LCpEď@& v,|Qf& Wrz:%}!>568t/Gh&sIVUeg.2]?,Ydn¥JgB*!7ӖYc V8otit:\cW@f)Rq.R aCR.ӟz>Ev#Қk{ZLzNH)S "^߽rR30ʱy8K|;̤p%4[˜5#)Ąfͦoxw2fdr {,˲o{)%ee^{連"yM{:3zf'jo~`HD[Oz1"lY}Ow,u1k)"p> FK@§wfmq"RmouUE @pI>- |c=R]n@pBf>T6]ʹ0u(Ecf+拴71;qq篺.Z[oRJreytch׼*S #ٺ>m~qY~QxȨu8)IK"#Gc䝘T)uYj:B5 }"uyjJdy :dT8`ϓUq%}8>0K[>_SAW@p7 ".m;Dt{l̺0. <["cxxx wFEjQ p8K'.M_mvٶN_wfƺ.\z}"Zۻf=== .Zܶ[_^_*""l*kL-7B(L\r<;m;-r]c%2|a=@"i.M[f^33 ;x$XS@?QfS]j,bT\e:MDB\RIkXk?|wmV3N7s3ĭT$U}Yh] }o;ղpUeb@~\.t JFldHy^8ӽg4v{zzZKk{ Ǽ<<~\+?^2(ouD\ouYHkanGszE0E4=p;͏r&xNiuE3D27m^/a 6;t$N3P 3m/? &ΥχxQP r^5Hr}l ind?#( KR˺F"˥ 9akCz1r9>8\R%E.L$RDJ- x/1[T5Bd~/?p`7[͵TRiXrGxz]afpM{?罷 K)*Df#e" bY7uU/ȞiG}JNAZ q:kDK,}o.Rj  ~{n]5<קmn۾7M8;M0ȅνjQm ѣ,"ZP(8lYhQ!(G|Frn 2dMj8 DTd>0RJRvߖe#L¹#"-˲m% yq*u u XQW~Dz؊GI/g{n*"]̐IKAQ8e0sЌD s1ȱgq?Cǎ2*h2jr~vTD"F2ao 8gKXxMӜ~Q~yEF4#t:BY,8Ӎp8eQMyz)jYmKhkDUșQd>D4āys `H),Rj`"OܛLHLʲ\.E?.$Lj͈Zh'@D[/L6SU;"v~ֺo{,j"UgaR91v+XljRf̺YTS>NYRRpǮOi3jjHsHd^Zp %TBRKٶr|)ch\غ ,%uk܃=v}Q['LסtsLڸs[KgĔz @"݇%˪cX,uBX/)k98Y0&C<T}6!@#6R;pu%#LR1%[@rĹ=ƯڗL}3W>}@"~gDG"N٣dc8` $Slxby?Ixy ܽz8^[@d= q c ]-uؓ  dM>i a9 w6 Ge#}`XrmD_.D%wCv\21p\"FZT1r~Ne' FL 0"V|ӟt%omc.nmg" *~߻.KH aΌjZvpK)]}AD2MmL4LHOm>d+j]bF9y;!79SY;QUNCU˺vUHktW L#\k{2 ܥEDp$w"X6'R'ğ{Ok.;:Z;Bi ^9:2ѧO̬-u5eY(1D\K͖m]/DD>Ɇȁ)%5Ekg;2u]~?Gq&s/axJ GEMaj?V\8Y.בZ7|ϭo7Vk^RM{of.R`4=^r9IǦc>8 *I5zk~ч')CK3fSC@:O$IDATON=AZϝӂR{88< ͧ|ΓHAavKתTs?—R}+ ۹|kf5 tvY؅2rtf >%$ EJ].Izs{=\^v%!΂}rjE"\J<]bo—uݶr޶ ,R83&N ]@7%rYd]zRʺ^@F>٨c+Img;4L}W<13#xwD*sf.K][/K\OT~ׯG7f* )CC?Yhតue]}swG(޶{ȱ @icHpɔھy݌\6m}Csd~o3dLy0A¨uR`aM,1&2 ryQY<{rDЮr&"D H`s4?Ixc a#ġy'Űb3<(Wn~P#G 3rXЍ<t37{)K-5,e57//?m7Lˡ H[v{Y*feڴH" ) ơBJ/p7a1JD覽\­wfoKRѴAk:P]!nPJ n/0ޛv{| DРu<{O~ޓٗq H:]E$s=:sb^cDŽAm۶-mۈhwD\JEϟ?o&",5(D O_Kh.Z X=^0 F}Hp\}]=o۶^.T &nC.0G&U LrѮօ5A=ppaP P͘.%q,fjZt/RsQ㱯; oNOt(0?sN`K1V441vm\sq?Y@ҽ(m4CҞcl?v'@@#uE:D=DΖXc9Y@&9 CJ7;T}ey`>o'q*U)K?cɆ)`.Sqj1FBE. 6E Ṋb@?QӧO*)s޻1fJ'@I~Hà!pppË- f. &>{޿]trws7-NnaZX23vZ[;zg@".1Ą,LZN@R֧g,+_>}nf[L q)3 Tk]Wt Z jd.$Xkޕ)aR;0pJ״p"\/+5M nSM&K& FsK0K?p&BL,}EjEvR- ,\ÑQH]ep~{Mg&hmtR&ELyHJ-P>i4 tȀ$̅\O>oq]@nfYU&aƳ/#C Msl9, [tS8%0={i`"=̜I~}klV۾ʌ1I2WN?sb.4't<%Aߌ3ϫ0#B2!Y\.flr3Kg2ѱ=CQ%ߞAd/ayF9NQQfy?wC8c8;p>!a)9ۜ/:L9Z-"131iIqsKaNNaܮ7ӸAiGtsc=PV6bLu,uo.ۖNN(1id84>^5t5xd {2ծMpk79?0Wd tA<~Ot7R,+}ŰA^c"dz}hV@)mbV} js ]uЫ&m3CFy-,k)K].ٻQ0C{\b s~>mF۶91YWb^J":# 0}/륖zNOKofUϳxxܦHIEf1x \S))'l{9 EqO^\?|nG!i;> :CfO6J:2_Ox%*_^T9NqvG}`lX 9t\^]ȏCB8FLHhfH?/}6>jcxRŦk{;&9&٪XR|ᱥe x TDp4mn!$nI0Aa D#jmZݍ-s]3  l齳HRr)IpnLA)haY4Kx]JuWOQd"DaшId!@)bfKƺ驷ݴwBWCĄ0 SSp4O'8 z}_˒{O5Ϧe57+#23&ꭵg%"@u 󼚧RjXi7wP$3-qRXMr݇Mف`9q$1fĩ)<8G!ʑZ x2neM ʰ"r@-! ͺ,)bqDe]j)̆6!Eh;z5I@qJ<Έn܇EmO$ &v^2 y8^\ N|U& K∿`/LErZ>#Dx۶ȤfvW503Q88:1MR=,pӧm8Ei"7 #0Q9'νQF'G\\#ڟUo+;@pps}[302ft!1B,.(,ER꥔ 02M53+ 0ܼ]rC 0¬# aɸ^.)&7/^_>~{]%l>%NIiᰐ&ҩTę. MCgnR))Eʌ>|RBDfȤǠާNu&?Gd{ɃnH {l7r u@FJ/eka^aPR\F5+jHM۝ [0dΗƒ R+˕0.kJꈨ x,4ӿz]/]JMcԅDdY.O1a&7@ZǩzNlJy,ȿUk6 0CD$ňɡ< IP.5mw8K\ ͛Mq G5eSD4($9Lyu(Qs-'LV Ź8%j@"v[W›_4oٹ:Y~ڹ3l7!0E+IfɒjT2S_ZuxY 1(e(1Oc<qe 4"T$ƀ@0Y#׿v[֪?jv9&L(Lzm&L֗*TΣ;ڬ^'8LR%BB@Tn{{[o۾a.ܰPg)o9fF]@#>!0g>QL7,ώ|j$+j)Dn ČZRj?&5mŽ`juY݇Y1JVKLH H0Ru]T}"usޔB`R @}ᜣH+<(,ty`J:)lr:c9<~.oZ2-SHRƔ)D֑nHhn] u1oL7|d&eqAsWzCT?:wl8G~ 2N[_GbƣX~~o6`D 8FI&wuMp&5A0y$H<)tRBVdp~պ 3qagJdfsG! "RӦjEpyc8{N~}c_ jK]>|RzSUE$j]3'SJe Fպi:DZ2Av'{aq '* + ԚRO3\/O&2qq8,K9^G9ʢPK}~zDwdzꏀ7D<‡J#?}K)[#,MMgzW<1ֺ۾Xʘ7vp X~1(\D. 63|-߷2KL8ivX{e^Kw0޵~b*jtH4.`D4KQZV:$N@2I:FPn ”)BBS҄ x ߎ7!˺lzAI$M"xX{^1F-LP{Hdi]̽o{>?[ۡϟRý"Z3w !P,"pR1*F@om!a,,in&S^i"IC3RYauS3%1z"Qq&Ar^̦ NɎiffvGA 5 : /Cc].j HnC7,RJ-" ry}}}ӬOK7۷;")3ΐz=n\.N("nn'$'[MOUJ@/wϷ q=L҅?@mw="/"D<G-=N$r ^/M[%)a"Y F3 Ѻ^McTC HY.p ʄƌaH&\_׮]ME}A)1:b՞-0F&=,#RGUyw7=MTt&PK~-R6mޙD>7 ]Ǩky8 0X 2}IpjIUd"̒L33tF*AZ= 3ө iY}B=ncv\U{m[?#1mK⭵7"IƨVn ||s@IL0bf-}~`8gm‚筠4)|@vo ݣao Ha%D?5s?rI~Z?|ynvXqnϿhtM0? t1<3:Z<\G"b0RbR\,7痗> [Reoz]I]_>}y~6p9l;F3 3 UyW@R7}|]/%"e-jg@ !Et8ϙIս9 ɼYJIeTfHkiO{o{0{D aBd6z{"rf'h|sZQ uP!u-e]w~u`K9YC\ s5"m, fwEف |_ˌz \.'k]܌ dไLfeJ̦,nv@H?U䉁#}{`:0Y/Jsg0AäL xfyOs+}bԜA3 t2MF(iSyyz,Ydg(_H8FjC sl _v0";Z 𬡳>DR*#{.:lū3HH죭T"2Iʷ0Afq".)ه1>Z꺮}e)Ͽ>}Z"D6RRs4=rrFNޛH!aI\jj"8z%K]DJ<:'4OϚeI3AL3ss[efmAA`0 4i>pHp~/pP|i!)]]YUjɪ̼9f|P3ssx$]Ήp7SS[|<49gMOdyvfbRTi ;ҵiPBl^H)M~Z%^zRr/o=>bSJ Ki)Q բ걠 ꖧN ږ=Fu3P"RJ"ETt>..R9[y:=dxYU/˹ւ·~S} 6 Uz`m֞6L рoѰVljN`hq* ZNS2 h޽$F.U|ȼW'vX>\-~7PnFY4:-z㋑c*꙽iOHP?U] 7V>.ay}v*uƫ Q3tBl +34Ny3ymx(μR 4) H6"өpH"77뺖Rb ޽)߿Z 45nnOx,^Qdj1R9V^))y M*)\ EZrͥiJɥZ\|FV/ut䇔lyv#@(h_^-3s5v4Gr \:D0[*ޞnjx1kv`5Ĭ9ExoUjUJ:k`,Կad;Я ҃Z#>|gܖ䦺DL?f5'V0aHZ5DG\zRJs.ND%Ƙk*``ls'4h:/k3}ۧ 3sym[R*; 2#WB@` bRPbv Zy08ȹ7rFnC[s5䑤C`6܅YٸY *^mr#!qoG#rc[ߑT˫7VGI%L⃋eߑq}mg)%VUp) 瞧6=$C[=}ղr,;ؠ7 Q7vRJhmm9RJʯ*U?ϳ+s-"B&!ET85*R*HyhLJb\G8}:8l{ k3Nje7"Ǭ7:.TcN)6|jBDdn a;ǵԯLfD҇dzpԎߍ! uH6. Ͻn>;gfܯեn#u}cøH?f-b!  p<L]Yy8:d!"gի7.R\Y"HofZJecma S .b.ӔD$T f/1%H> ꃣSZ5vo&WI[Xj."[cG"C *Ĝk1}˛ء˴"U%m5% !"C}-d4)FylgTL)w=ºӋ( IRض\Q`\.y+D]+ck,";# @?Z'G眗e)RE5=I޽fcB&+*fS)ƦxSp. K"4TƲi aY֠(^Ųk{zesv֦X34dq˺:աGW5Z]#!yspMunRs^x{h<BXq j?IZm?wFn_8k4wno;.Ѣ.R&G.7`7Tk[l;nFhF؛1= fp:݈)C@#0!"3 !QC0\˲ij6lh`DyRjJLl>?y"gBZeg7L1!XMћ"LsdTd$ .!:9u!32C’%p&j<*"5+5c3"!5)4i86j1DH!!R@fKR՛dJ h;RT5.hf;AdFc8o^yEt"| w$l 6GG\\+ (#1WDJ.H-DPi?94v -D&RU\ڰscڈ`mKzt8…V)LiRR31GhXE94MGSUA j֘uYgoY%V3p+?& mדV07H,.~_Sj5CMJiZ%\pzhU!z ܟ hER:ӱxaw Pخh4p2q <[u'(583|E$PP b~ i}f#C*Y<((EU*ge C"ALU[2kd"BJKqyqrs۔a>{:i61F\J)Ee{#A4)Η˹ւ>{A|t+]LR|c40`2+꪿ه:0kin"Xb񜅙H ^ccԡU"iCP_8ܝ'b8Uh1RJ)*sVj$<9380!4M`$b|^vePGqI5W1pǘb^W Ԫ.M1lWuiaXnܕ1P_-AȻCB";xcjo'>vºJQ~p-1F<> ಬi"޾ ‘ݩ4jQH!u-D'&>ߕPF3/zqccfr,W$¦  U!NӔ҄U+d?h]s.1ܵ]hif70ko߾-%Jk>Ϲ,āLRj{z-E8-Cq)eY31V蒊)i`18ˇ}R<;RּH)>)`7%B$6 (Jv3BZB ́89AMВ#4}_BQ Fe<3!0nq{^z5jF؞]D^p5"&+V:Rc%x\cӲd$G af8>X[VG׵Ϳ_=+,SENfZ\"Qذ5e4 v!5sMcJ='<6;>8]Zʺ//Z8+=DDj"뺊3htr1WnڳV)7ӟɟN:PJΥ:ޯD:Pvy:9\B.)"7kuVηU10k+fm@FcL*>L]WR~H8 $6,:{[ppW@ҕ~ct "m,}ҽn[]fi/KΈbJ@O^V Pg qAFqgvc8HO:\ZPP D鰦cD_)p4Kb)\ p,FAr]2X"fGpGB냎Ym0k]Nv|ܷxb֮ex]nPD(@!Fj-"B TPVm}##^s1noo߼ys7`oCԌS i@nLjSyX{b7[#G1ɯ}a#louu<4N "qH|pV>DBT&oF{`9/IJ\,hEj)ׯkk@L)9r6Sxiι_uI! U #º^|nR4| jmjH4ϳCުeϩD2.u[kadx do5zcg8ٜfJ@HؐVeS-Nlh ?{Dd!j6܎4 E&hCgC w-u^9ht7<CdDMӱ]{opZ&᳴[RЙHA"R4(=k8Zs)Np\z܋T'bh=NE & ڨ~4=Ćq3byrELcBl(`$JN \ǎ[po%]"6#3^') B &m7E qj.y*@zk1"ڿo Dw{k7J)_r to<}0.l Z+!mćA}V|wBOW׳F]:n媙ک@q;̌c.=6R\z&9@*u>%b ޾MS4cJTqm MFbS6x9JB#Qn࠳6O/; 1$qA\D1B`F@LM к)%UkgM7x ^,[fh$6?[>кo= Ag;sj=C"b?n=xt~i5F68\{?}G<*Zgq20(ds"0RJ^0R**~*RKV7Z2i}s;:g.Rɣ-~sZ^o;`(wɟKp !+bp"&jPJE,ƈ(qѭGqF,*9g~+U9Nr'R.zHS xnǣ5__^ǵ=x;nwC;pG .һ;GRa>6V=5{a:M{29$"%ϟ?_!enUOj/_UBL?o޽{sFfƁWu@)qBHDRsͦ)=Nhj,Vӗ^A{;YGڶNA$RJ301<~ov !x:_FH%LܲZ ׊6Ƃ]b[.<⚯4-Cxo-(VB[nvcIJN3cASKإ\Sk ۃWzU qJ@;Is!!"sp8JReN5UHR20q o߽*ZE8M֜W'-ʬq-ZB EbΥ)~szB"8@3 Rz 6U6"S$Y* 9]=B`njZaR+z"N>GcS?Px9$ix[@͹gf!D☻F"VC7|=GZc4uYBt 4MemWjL٘o,ѕ5]9\ՍX;"Zd Ǜ Z"Cj.mhvw'R*JL\\J.NSrEIRwws~WEV$4/ 6bGbLEJHI bJ@P.b*k.!@|HR'%kAB`z SLZS2@U3%熆c )ƥ.@S'EňsSe " -;XT*V1j"L),XKGJR2"DjDc"fB{3J =-DEUiDcrܙC:A\[ǬJtz/00$Se~ 7}2DS{<.PϩU?TKs=Tk-PH XK\.dĐ²,0MSRkD.RDj6l Ʈ"O@j59U2p JFΊU hD@hLlǫFl*PD|fJhfլZ`S HA *xsCTR+1ZAJ9`Xsv?裏ݽinx]YҨM汱Ipa@nKܱH-k۹[;‘/Ζ'?`]2uFȭc6;R0)a=:oy1/8S)f jPZ+LSBÚ3D~?|E@CyͯrřH5Y< 7ZVS  Tj5{A9y:J1&5|-}gl0wt;DDf2n J3f1N).yZDLHJVUUĔ\88ROiO8baUԶiɽ7ff$ՂV@@A䍏}ߡ]k~Jj6sqY}im|ki- "TY3a՛`v= >\.iݚgo[u3ľОiT8gO>ӞGCky+wm `.e q9=UaǏGU6q|_xK bfE]n0϶$#&<gv܅AZ#7 jD@.>jH@!E׸ıLֲu^>8a8F]a[5?Qvy΅l! DDM UjMWCX%'"Z2>zݛǏaAkYzsZ]w0"1y-O\90S)j15/UK)C,%?:: z\#"L|8)Lm4L[5b;aPorںfU)͇4EG֢m|8@՘\.g kZN ġi7ՐnWq=Na]|A(]-ahDoSn`ŤND%[W;k# 5:y4x<91 x3Ӄb5,oOA6o>W4nrOӼ:,̴GZ6RZ=,|騛.ƿF15Vgc{lcf'Pc ћS޽{k1\|~敔B(ye0D{Gww|<sĔ0w4A e ]N眍5}_K^ nn 6]M~BRg|w\]FTRf {Va#ǰpϊ=M "u]eճcr 3ju?ݲk͠]\9NX͓Z YD4Vje)M,x,)n`؁{^ޅ=goVj\[(՜ﵳVєB)tBRS IjɦH歾j.:1 on(k-)NiJ%}$Z"~8 H!0HDH}ѿ6 %4IjSkgmS!!.*Dt"k3qr*\}h#c3}_́!QCf,ǚ:u_Zu斧|ކeBnzJy$sbqb`錮5>A=[~7OchNPPh8JڴN@r*UpP,;090Rʚ<ϹVUSRin5RĞ0v+ vσ6}|ow 5!1@>GjfkUF KQ8S̮2}/+OhUdq3oBs"Swwue\*<*=HUp84j-93Sm "u])Ul9mlV;KJn!Gfo#5v_}踴=Z_ JڼW 1l xԔbAU=vx")N8Ĝ Hܽ&jR9Z;b@G9wq LTD #Rab&$RTa>J1@QMZϥќp !~\xoרWԊ5Ed ` ܫmwSk<}4ϳԂf.HndjFxT\Ck]rEr3kts VB:5B|k^EZt<߿Ma#V)i1^Ο!*')X +C:0L0PT+ăr0HyGv:BqK!R*4Qbeg09Q=fpc&VO=Wqw`3i6 $p*xu̓7t^.lUiK)۷mhRڹTBe9\.nfmlO;cB&.~~?_|ww8RJZ MY8l#6!Tqc*܃0ն}glC}S͇c)!rS`p8+Skd}-CO߿=\}FvM83$F9|ݚ"*B:Us~ȔfT:c^ۺ.yj@݀H2M)" _ʬ3j5/CEbf5a]D霦*u].8ŠZW؎1h~SLEX9M"M(5h\ < !Ug{C a[in@)KD`*;q^ac\~3Oi`JD!&_$ԖSGrSV7zkmoEzcAq{_"9 9t5uQ3 1iO'Zۻ ܤ)V0[LMJ N׸x_6?x j[Os>dA@uFv+WWFiB|(ºfU )uXQ fZӧO/3qj$āҙauw <~aҘ5~ "2ncʇw/(ټ`Hc- i\!_;RIef txqRvèʥPVD#”"B@!ĨW*!P}eJ16 \%2\ѥ^1@e{)G7[zQo)%v?Z+r0ZZOU}֋noo#Ӂ @JIuE8LVAbd",֖>8024裼FLdHaH̑N\5 *zåu튂iDeAG:5f;gnGGҝT:=R.FRQSѩfL$UEA 7wfbI NnO7f+0;˷ dh.3߯b'JlI%y#X b Aj@[99鍈t>}lQKMS!CWtsr=Ӌ4K)T܃cyJ<: %H=J @ Gd ݟ(4"LCͣG XZki"-n##.ݙwAtcnJ#tDg:Αmi鰆񀈤,*h8D!F̀.3dy/D1?EuIۼT[ij)>w<mr{s3u_}eZJ^!x:U5P7>.$q>L['SNse' y%Pdm֫kht5ycF#&?wB>D_WU6}kرZuب5;y[QkD>Uu3L{!$ڃIkC HJ^Y!4)9]ԈDt8ۤȘ1~Pߔ O ] yW^"btهBaJ{y8Z~xR5|¡od4{~@s| 04sˑ{) tv*{vwIo_ܴݨl]W"Kϐ⺮r>ήxZs>9VxxDͮway\w3A3Pw sSZLEԵ#}iBQխ`諰 4Q9wV)%6'ztR x<_B5g hKE/@d6>e0F2XU_Sk<zL޴u'c^\@ }B;DxzG!<&Es vKm$OMqm9B:匎;(a .4O PH{>HtskW/*4rYLE"Qk^T77!&9fБRגU*ML>!K^]2O!H!F5,U)Nl}Tph@r`> c[nu ǏF')%S,-99>0 Ppz? Z!\5#l#ϴ,{A& 'u@j8;j wP5)%RJI):+nmc\edC73S.cT (4֞ʦ`fJ"zfۇx!z|N Tol>g=p6EkRRgĘbrwG1Ti9_ U> ԏ CFXߏx2Ӧ*y8m MʪW.Z8m>)oq=` s0Gx'351_fNGGm`B 3e #" $K- ^!'~z9j-ozLD<#6M4c039ɬ\Wb=#*RQ\J 1nN%R55%&$3&%UZ 2H5y>Ni>n!Ol?/u TQS0Ǣ"euu]iÜHA$AjLKYԴJ%Z !y֒Ǔ,!1sSAUqYUcNT7)r M(2,9On!D JL ڸ8f*mE<ɃDR7)T$TҪ;C!sq|Fj!r)U Rno _E0IA]ի.ro!ړ̌0L5XFb5pasmn1&ČTp,"7777f04#0ĮIn΋$p>c3z%S=*f= fBX]< F5 DU$)x-)B䀈Uby۰-Dkw&Q˓mgvܯ˃B_=tb=a@].DCư T˿ciٵ(]1&1Y2eYe,W۷oc˺ZnU$T׏D$V60K=5"VRҠ(M_&Wm^~%Dꎀϧ[@R^o|R:<`RD#׵̇C9SG hXkN1&vpY>$ V"2M+F*}TqJU&BBCp;\٠MaW' ϭt[uඈhZz8e'O^y` &yH! 5޷S "sJ1N'`p]n_dCeU%̤6Ox.?sm5(8">&9+uw&F U;qsn]Xh%bs4Sx`+Ldbͱ u>5㎕׺f&D!\Kw0RiB '73!D]1 hjp7cvWbxhg=oi0Db_kol<}]wIa؂z0_|:uVuhX90~󚙀)u7W !t} )M1xvS2Ҥ*ZG7Kɀ:<'O$77sHik^ltQغ,)K͹noK4ݩ )}W/WGr ́R3-jbMAp"dt:Xy>8q D %0ȅNi1A {@{gE;` o'ǖ+Bւ&jh}zkZPVJqoM*j=%a+B6I33{Gcc|%޹S,Ni&bR+yղ*qz?KUv؃뛻Zqږ{/0IE7'm_IMWD >MzolP8}~DKfFq>?v!b EcH&_>1F%@H~AqݪB777k)І?hzJV1"e9pS%gx30y|8|yӧe_ss⋟ݿ~`+4',˚(N~]љfƔZJ^n6PTT]#gs&nj Ht]3W 8pG&ܾl̘TW4("1&"6o?S0.r#M#kqځe9Rlˆ|>&SO" R!k kd})qKG'n`m:Qim9z{AZf`; i 6kl./0t ׭]H6`Kjcy>dzq)xf PeGSx^88WE9i<$G碹8.z#-/CU.hs6&o[G>o#71L6XSF5+_Vj6!u@㘘"f^ƖܥDD3;O)ؤ̻G 5Ss'D|Mڈ^l#OWdҏ1CZ'{ݲ:F_kV_︄ [PRscRQؘ:GxET>PZt bN zy6ȕx| tNn6nApmQ4y|~EMQu]sP m "^FG|r xTækZs{'@>@LV3,!°!rp׼RSJDRA'5UTt:,gR9Mǃy>|RŐ94S)?pg|Ǐ/~_~!FZGϞ}%杖}_ ?O]_*0M|8ynOC.p8>x^uɪT3u!"C(ѻ|#|t\MM=IԬJV {2.ofQDs`ݲߚyu6}fTRDUIJ-ئU}Q#q۞f}j W mUS*TG")[3![mKu~mt“?.lBKT?&ݚids0:;!M@@ N2qk*HedDv|F]^GKQjDJMxpK5_b T4Ɛs ;n_F_~۷oU?Ӌ/B ayO{7YK)ZrO1woH&Z FPڄ2C`$@PJW!0](U$,R1DRrF !ɩdW-0)p*ŵt+iZT#iYz֠dLET)PsQUi-U1@y-1!)4bǛ@'|"gvM drwe"BPvsx np k%Kc}}<# *֌ʼnIG DˏaUJ x_u3#amƍtJG B`i&J]ʂ@DAͽ8 BCsOƄj̠pm񑺠gl7 9ɋ2UMd"1 qp02"2T`&2cZF &w3lԏ΋鹷znHy:68. . 拕QmOAj3~rJ(FFD1>,*21JҺ\\|"4MHs)j ZBDb1j.Q5q??|BD㲞ww)?oޝ˺xG|,oe믾W= tɫ˗VsŤEDjZMخ#ΰyْ*!x baTds s0_;]ݥa% ]D$bw XyG6}BP jeiJve齪O^ո%7o53)TQw v͞f.W#V}I1?қY> eSU–eհUn]՟bǴd~ʊJG eZ؃}yط4ubhh[e,&i Vuf;hb>=Uff8EhSOgMK?Qǐ\df1'RrΎg} `| ""MIΙ9&3eU.HҰcYbH>p},qի/^t^O><g7"7_7j7e k-^VWylEX/igguM]]\Tէ,t>7MDql{n@1m15-5bҎFV@*$"T9 fch}?v)\ M&۰l+l`  8tix얍㱁5ty&/`ntX] ON7oވXm1lGD0M=M>WfM̳4iBZk5˝o<)%U8Dj=ת)'O(ҫWݿo$ ~s/?}GO]r)>裏Dʺ"~~^Uh!0?}Tj!SYUUȃEbc!!j ]Nr^#43gѿ`SRnIn*7D5Z"b&E@)N̥2IvtOU<u#Ӝ/44g`(e޳z8Lfu#LԪBmflH`;h OpXfnb-[`ju}lz1]:DT+!+WZEAD';&"(1xb&=ֳ)/h,2~eUGp bj}:\фΗO2n}P''>9X^[F{P Z#MVjc\` (Q#3ZsD4Ms˽vlRJ9ZUUcj8_3{VCUQt<x:qt9/Ӕ.糈NG7i~ϿK_|E)壏?˿WTz<9g"47=y ޼~+ԪҖY;D4ITcVХKjTfJjݴ٠*#* 1SWkra/1;f^ʥ*vfh&=܆bƎ݆(:Sc{10?~ɓ'dmRQ]O\Sa|- A]k.sh {6S5}NeGp5֖6w$VrWk{p qw?;()R1IDAT$0hNyDHa3c̺Zc+\}1FUpbٓ[QDˁoq Z\hus3/NwsoWiʱq&'4Gx!VYޯFZ2>a#ɖh<.*B6b[(g2X <{ ơ<|Dt:JJ!0,/2DC0Yp8NU#R(Et:Ӕs,w'~7毿:粖|\?{||ߛR<_|tz9ݽyry{{MմH#v֯!|8,缟 y(YhnSiKoX(Jr SLf,RӔDTTHv92c̡5m}ŐHLGmRZ\KV9WOPE7sH)s]=P$t ,] mtmjs؟>>+`l<_Rj͹Ahnp+b/oޣ:`S=v8Z fN`< ``1 %{lZ1)hJ Ļ[G>F UCTqB{^^kSuƍUM!hk@VZksrli2Bpנ_/ơOXCt+nj637` L@o3BbmJF7vxqw12a>j퇤Ef"-oU2HT}݈4'f!9Kx\+RעHnDRDRtVClL4v2u]J)a䓏?gO?w?8}E9'<R /߄/~EYt]r8Jf)N5!R@ ;vpf϶>(*کUT+Djs^:J:L^ͣu]HBa^sJipeQUx j cDv[` TՇh EfdYw.6MԪ*nF50B`ΏDĔbh1cul* q!R 6/;>~ iWJKbh$gvTUM"}E#SަHxBD)Zֺ7뀆WEa-o0~GAw}[( 3kTK`k@"H&Z|cgjtEu>eWxArй{7D$5>گj뻆֦F*6\~QO^ĩ#d@jC%T3R+bpS.K) P_ ͠b"JC0rD|LGGFh9ycy]߽7"f45d6\<Ǜy 1s@kf<zS7U\uٳgo޼*?ܽ+ϾW Ǜ[1p^EEXD ˲\}}eJ\Jq/l?0{ڸS5MQͿi*EO7\.gf~4giL4M|TQq!Dj* EU}=#Vja"`)4)' Vњhy~\P :n\Z\#]GDLxdC!-"Ň6X&MB.g5L`x޻7"̓ !ts_HH 6w;<&3bb88MY_DRZ+됣yeFLsYj>BPfVK`e⥭1ft^)n9;n9"t(D 1Dif∶2m2%@Lԟ>WU*+zwW̩b=cn}1ӎdڌM]ޝVê&n`f"LV9)GkT@\22N|0r8 {~r1ۉdwk`~݂G2E}#rB4ZSCmMNZ EÁ;oPCwgxo} #k|i pvĺqJNw6j6@R%0@Lx(="Ft ˥^X'/8cMU[U py> 5r\tyTUUL܆wy&d2Os|>DGR^~ 3l-s>oo׿o/ݻ~]fzo\q_ׯ^`绷/^|}QSx#jZƍ՞1rYzb"RFr&IszSU1AdNq!`m谈 qp=5hZzɬօP ]E8lx0DM1ܓ2W"l&*T1"Mbd+HK!%555spL9HdGtV궷UUZ 7BzC?pS5$ ރlݾSU H [ 5y>̇EBǥq LxsDܣ}U "ZoAB/xveW=n!WuϸN;Tpʆ9-h3!cM -ك*?ޯR<{}= Bk-)$p n"lMZ7Zbnb<Z@]ދ=#SZrgf3]svx6NJi!Ϟ޽{͛5_o߾{xoݿ?ݗprY.~zͫ/_z8www4r/eE-u=߿}:l7v]ڙeu^R. .="}p6#5ɎaMc UdJW# : Q@i& ݃T#kR"B )p9 Uq=3UJM|R\ M v:(S)M3D0Cޏ7ܴ H:W1#l3P:^ǘ*QD$P8Mܡ4+.5"/K}fAp'P4uNIRbJ)t0Ze]7uǷ,|1Fu2<wٯjhs&u)eJxun#T k-λR-*A68;1y;;r is\jEBm`dzbQ͵z|><^#" 2r`@pZQGU dM|_j}]ݝUsD}|_Et?m,n<Ȍ@?[^bMj6co\^ logD}k"6k4 unnʲ(ARӎ:imWu:Ÿ nG߱%a$?j[KnnZOIS/ST՜KsU8DbgϞeuɻ/{,r\.bDaYs!NS.G}W/| vaYJonoorwwݛu]k)Mo޼E4ɋjAP0)*EAoTiAQDVFX$jX4Ԓk'N>E#wfqf 9XJ>CMF3ؐi1t=h5#ͺ,COLb8$˺uET5q_p9u Ԏ.WF'`@3s0 t Xe\cs}[]Y]'۶9(av]afNEDn` ݃ s@? ͋44ǘ@Jhb*[1Og\lWY/`s}>q|6{}v}{q'_+a0kAD$ vYDEz А}ܐ fNR8W"2Rbi_7Nq ؓRwz.|TUIGau 4A t<}ΝHk˱ iƘVt|J)_}Rʪ*>*!fDnNtx٧}C)|Iּ>{㯿ǟ|g}fj7ӏWӟD ̖|8|:M ֲ\JF@jbs%tph %f?Bmc{4EYN# 7P]Z{ GXKb$&SSW $:C[4ªRt!·qU'U˪|n}LTs^!br:MKǀ9g}$뒵qzY۳Hb7|04Oo7[ Rc=.!ny\ݏq YYk{Ŭ҃,@eA=T]*2toAF{@Huu{澿]og}X/^5(1x*WDGv80"+r^|Y֧[kr68z^nvbwcD(t sK)%p1:ilYe]b |֒KQH<447޽;1F\kqC.oWD|<=z釟|O\>O~Xr,[_|>~/Ͽf,.)UԘjEl],!Bb;]їWC|k# |H YF'cͭA,| =D,JQQ6#`VJ.4?hSCpm`Ǧƥ&C1z]kBLSZ0ܝ* rH~ 3l$7o_y_zb ĊjܑS?}}6>Hi#N"gĚU r^m=#*R9$̥"Pjr1$R I <8"u,5Uᵦ;Cl#ZVS%4"Zk>]5=zA n8]Emb'tdOz0x#&p8P"0@MU0 Lܝ7|i>5k*bUV`DntR@]z\d:ʖ}q0aW`C-}Ϧ\B}ta"*0ir1D@aRizr1eYKDkΙy1!BJ)fΧt~/Wjϟ?7ۿ@|2L?w߼f)_FZrۚ*p.졊jmp&1ZE*`ۜ 3iD$j %€˜2`1s'.=' OLStLSKS첦?~PUdؤHDBbSJ! Rb?۷oywz$&-28:DdC p{p 2 Еc뾯?ƔU[\c|F%T{psSBBZJlZb-ilDo8nk-j-5"ZEMBuROeWjly#Ό_:ݚׂ[5c̘܃԰JRcU1ݝ?MTj2L2(Z|ȹ mjZJPVqUUD4ckΫUABfs\wT0%&Kq\ZFc0RK) 4!yBť}AL4j onn9G'e6TD84i]%p<-~Yq:<{p'ϟ\~W7xܯ<~'}O'߿}rs8Lя??2ucۛrQ~j1M11A"fu* &mqլ;rjU-V#48gf]̚n8"T@M04 ĦF.UYHisZ-UBwgD^hyL8s0" BLD z*ȹܔJ-Uy2S20v Hݞ6EY-ъ+$jC\:Z5\JCĢ K|F`>nJQhfk4-M<[!Tةk6NkuPSb](Yۧ?[9 pQ~Ji?v٭G:X~&ۻ5GZ]yK;FZf-q * Jn[WuGeG (hFĖoУk"Rt 9j8gBSU+;թ qǛ@+^i)2֏+ll"nl}:U%n˲zbb q]<Ϟ|2lY7o2Z !ׄBjz®r:W?ˏ?矞nn?yGWիWGcx)|嗿o?_}`FZE"d7=8-0'{o[e'D՞Dru}_O=%/L]52<`7Nm~&4"2mfUK:nSfG#"1Df:g"*DZfYhlDDE)D_ELTAK Wn|'@/yTwտ&&ܞF|X}!u=Ƌw ܶFݿ? \=/FbAq $it=jI߶BARKEnVcS:KtVh8jD#P)ٵ-E vEF ِW7"d$ H2j *ɋ833m=8P wz6m$9,b檺+ݝyoAuU~/TtYΪ:M"UpW;cqG/|\nEk0yw'fӧO~Ջ?tyVńSw!JDb<%4Rk!CkVP:36|aLjW{ia" Ww>3T`"D* H,ˠm) v_EU#Xh1sɅLbA=[+Vw.;2 6`/b0{%-#茓ûM7"` 6fdo74 8A) <ֳ~/ɸI틂5XS};ǵ|:^aLsBdNƭhYXDF'Ǵ#:m:4 |N44&BPS%7idbDn4aM6qbj2Umt#u 1"w)bj[j;jH.9RR2a@0޼{Wxe攒HAD3Yk!fjvhӔB Ek:8+3˹|>~_|q b1~oݻR`^.c ; "1nP}?80P]m ʶ ީ>!Asք#΍T[&iq ._amF&ib43$6" 6K8$ !MuJ5:A#䘁ԪM i7SNG p$p Hi8Bo},?uȃ;Qd>w`ŏwmN8~>u5ٯwQ]: A4<(c/(}yu\WnZM>L&=Z -̑$#?6mny?}lI0"ι73ݯ{3 p@F/4HfG AL$!Z2s"]#ɬ=CiUeΉhuGf x*˜qF\9hMm F4߹- 1#yX&ucĊ3|I[֪]{/K]j 3=!4"A Cm/UD~񇧧O~釶o?ӏ_?Ç/?],s7XO|>pke9F;s1M)B:.㆙I_,'5F.~`-Zؠ|Uo#1l&` @PkD,˲,(")r?aO,c07IQDdWA(7 y~~$\܎+|\f$pl=kCW$7L J{ɡUP8~Pe_ǂ !Cu|3t#aFf&3`6yC73s hdNW]k"EYa\nAкqC.e9&2xG6僁⩧(GF(;.@Іެl5g?fΑ><ܯozdC0M},qkmoΌHպ_KwW0mۥmWDCw)%v}~bD5u1吙 .!2:Ox40cm%Bs4ϙKcxM<Ƹ% vJqF0HOuÍ$t4wf^׳j75łqsf60RhDCf"`ƽa! ͓c;?M p=>7Y@i@l!n|1V㟓v<f>6u_;$/6 ?kϵc j ?:`2GQh8T )ƃfts[;K*"]9}.!UbRH8ġ#C qub`a4\V_MČL,UJ *f9O۾K) Zfj""R\DZWw\ey<3riE7]ư\kezL{d=w|>~]/oΦ7{?ip-޵MߨޚE}í$]U5Nn1}_P4=Cg\ӑxmy 0BКe q}233RLqK]~*1eY2vU67rRJ1QZ +4DA 8rpDG"4P P!3rjMO=^ ^4tx<UHasD ]mA"I3s"U)}~~19=~^!_w00Ot5VfB>ad8[瘘:ե;ob9j@r&Jn.r=j2&3fD d w7r0 "mSGmn lG ȧtS$JE݃nn݌Ec~k-Rʺ6os)̗*"޽!󕙹FQ[)A ,u2p?7w즗R~m[>|hryڶDC]^Қ"¾o-df]b5Fo:5)>^n6 涄r,fx?E*L\KMs?fXAK&0@H<:~j6ҍ:&v11 _J)FCȎcIwpzq@q2侏vP.D=r|' $!⎦ \qRcRֶ; iCStӶwLX3 IUuR`* nΦj<@" 0 2 bHG&ȂeBB.X[&7uTx#b岮m "x^O5ݙ UJQu7ooo}{oz^Ͻu)UjvuUmKoR ?O>Gv~E0p։hڗdQ6Ix5&% w}ҵ=B ZC67]jqZjǔE%<H9Oa!]/K+[Q XcX[ /!XNA:tT 6~݊3u$Gl"R-k;:woUh]_v4@WtVT.A17iΙiު}zLr)հo33#b3$Lh\Y|O!A̭eYc$RD RJ=51" n/Rc s:Aku[uk1AeoVx>Ík8?'Xd uЏFyIZoWͺcq5"j_Toߞq\ #irs@ $ eh. ޒX)nKp֚yInƟI[AF)?R`Փ =t:p6𦽵ֵGP_@]zW"_>ۺ.zlەΧ{hەeYTM׽Z뽝N+"~zPJeH4Pǜ`ۉ[inX:[a)k/^e߯s_*󟚽!7Ax%| 3q@rkc~/^Jldɩ# fX$, S`A0P3Q*$o8WKYuU @<.o+ƻKWJc>*wOY#xlL{ 1ǐ>at3Mvݶ@}:`,u]Y R6"LuxYDJdf<"1bg{9sELA9<::u FW=8в3~#².{kU#vz Xt{ciQrr 0_W |ymE'9^7Pqjsz_Y%w!;=OrPg#Ao6,kw'w_5վfimKd&g8jD8RG? ${So3{~~"yֈ%)Ϧ4DhNDN):w>ٺ̄HOOO?tI^.>??/ \|!Sx^ECAckMs-ep~P*EF1A >:aw+`/M2`*0E4' phqs=IȦZe=Ut <#nk=)~^ԑ" (Bt3wBìؘ,|<^f0/0^? csC4"_,2^}6Gq)Q S4A x_4OWKfurh{"_/Wwg0o$AB !<8J=N`_1v0!S_5tybx"XSDRbyĀv>zos}]^p]\x I^J㏗˥B5DXe]ϵмff`.˲o+(1N I D1$:fd1#@bqoE/4ݺ_t~d&Rc޷Lq m.ri0G}7H8S?DG]~@Y~n L5?UcߝͿztȠDY*7oƙ8ܭ/ƈlѥ@wpl "zNrm@4qE('٧oؕZ([SuoWQ˝jݬse$lڅJ37v2ަq׺?w}?̈18i͉+Gj@ Zo |m{)e]޻nf!εmzjwfZh b)u;u Tseo޼Oӿ8zkwWmwwwOwwwDswt3O?$/vrYY<%*~ =9"  ?:s>{9sdc = c,ȤUU;"C w3,YvX%"ޏ B#IYWyߚ8|T4NGM 瓻Zj,>|mWwd"&~ݭa@Kf˲\}w3=UQF>E|4W9`")݋@9!mckӼnеKHc#OcYmؒ;a#?t=7ogJdA"^ _u<&;fQ$f S ho`FO6D: pX .&.AfC$EE^!-1H˨"HDrw ^T%l 14[ .\&;.u]jﻻƙ> hh`IHKEH۾;81ﺟ;fD7DE[j绻߿}x~7YЂz}vҊ aAUEf$ c"iqP1s>Eݭ D 潛R1)4;4Έ ds3p`G ,п.;15-ˢ̵#ޮ4ƺE#":pȂXh6mBԇl2Y@33 sE>(>•sӋnd ޼; 1сպR .U{~tBCx yGFw&L˨f3!16sEF WLy{XѰWD-[ǰR/w)q8sNg4j_>=N')k?HA{lտBZgE"$}"3 g03FH*Dwn֧~~8huhm OHz#{14/`=/TYšS㛴mb$Is@&cqfNØ)tpZ X(Hƛq ioqO'?bB6T 4njo#u@Zj&LF s*!ZJ`Qjw[ޮ"aRJLR@7ݛށkZYakABֶ֔EJS|}z>NTǏ۶],rpܕ+"Jf ]zP"f ; DRbhf!` 00%` pT@^C@;Z #4 q"eW# 0N;ucn WfB#ARYuQ"bU-j7!A&wg(> ]Xj]UӖc=/GFaЁ {'33jS23x `Lq n43,X|Ô#%c"o-GXT hL^y]xyYO:3"b?>/>>o`8Sƙg2pM38N,ևf D;tHPK[km)}LH a`1]fH 4_6b!rTHtƤ1LtAD4Ñ;X]j܁XLz6;k]e]ꢚ! їeAAw)1xP}^"{B3eYw|yj-۶E DdaFHL ق~Tl43baqSBޙ6 I#oPچtdùi:7E'Ιo#D$" {~m$lG#}Bq&Z'>vk}بf 8F~EԭE_ 1g2)<J-ѰJ {@tEi5sCβ9MefBh@1 q`c I8Ȗ>SGٱ{l ό5_y=ȓϧw?BbkFn>hzbEr4=7~T7tt".0FȞ 8]"sC"ȲoD<8 TK0%@c8!08"PB=%P MݢCD' m90ZQ YjkcJs#\E'C),L6KwUMG7H]j*P/}[1^|xs}D}Y}# Dǚ"GEi CX5S34B4;pqYZYB F }Ő.OǡApO *㛯 cgs!CLoqv <`ڣq4ˋp\`/ch"۾D@ftO[~0 ͳ$Ë,'qnt z+6! Izi3W̫H @TQ9 #b  c&u?33]"o" ] Ԣɛ}vS_sr/~d/bI8 O]Mmp3 ٭D XwCB$ёsCH{UL.RR ' h='P&`1o􌆉8 IsZwlxK fӅmNDA$<~l3 JRsɩ*!JWw"^wM9(x]К,j~:ŵi}y(12 |yZ8x0HI2< #1!S y49j`$, OzZ뺴ץC+5L,&1@@)}1bEmnnP/nkfd)lv R˘SB qդPm 뽳A=rd!@寛ӂϼŢ]efB}IDSCT;&: 4rDNYǦ8YvԫGJrE9" -ŕO%2QdpҖhDc@d)LLi4xCoNTfBLS`"]&YK_i]/_C~)"o;2'GG0>bճq(~1GV_qf'1AT:c8b03,2GQ1R5w:%ӐhW_| 08fջj]X}k̡f1:xz{67c'h!,u ٧8`6t\|@ $`V  ":mjd6o.ѐcUfO#ftq}/!b`X0qV-J"sCwwo]{뽖4f6!6}.>wl"4vO9~a @kmY\.+@ѷ# 00-:+w". 3spNˢuԒ8T tN~xk^}tKDa <GٸML$Dȋ 0w̔H!FNO>v30\bB$@}߷mP:!vl^ Cb ?sV^."|[3}8`2MbXp_Z%oF1 }_u?k^^M_1VZ!mm[)e߻ȢZƩIvGb`yJlI>AHL̴G/vRQ7h1:'4u]rjoݭżXEcEJjHRJZ|

    ] =head1 DESCRIPTION Starting from fvwm-2.5.x versions there is a built-in support for creating fvwm modules in Perl. This B utility provides help services for the Fvwm Perl library. =head1 OPTIONS B<--help> show the help and exit B<--version> show the version and exit B<--man> or B [ I ] show manual page just like man(1) B<--cat> or B [ I ] show manual page in plain text B<--raw> or B [ I ] generate output in man format (not human readable) B<--dir> or B print perllib directory without a trailing end of line =head1 USAGE Use this in the fvwm modules written in Perl: use lib `fvwm-perllib dir`; Introduction to the Fvwm Perl library: % fvwm-perllib man Manual page for the C class: % fvwm-perllib man FVWM::Module Standard options: % fvwm-perllib --help % fvwm-perllib --version =head1 AUTHORS Mikhael Goikhman . =head1 COPYING The script is distributed by the same terms as fvwm itself. See GNU General Public License for details. =head1 BUGS No known bugs. Report bugs to fvwm-bug@fvwm.org. =cut # *************************************************************************** fvwm-2.6.7/bin/Makefile.am0000644000175700017570000000527713001417131012252 00000000000000## Process this file with automake to create Makefile.in bin_PROGRAMS = fvwm-root fvwm_root_SOURCE= fvwm-root.c fvwm_root_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a bin_SCRIPTS = fvwm-config fvwm-bug fvwm-perllib \ fvwm-convert-2.6 \ fvwm-menu-xlock fvwm-menu-directory \ fvwm-menu-desktop fvwm-menu-headlines man_MANS = \ fvwm-root.1 fvwm-config.1 fvwm-bug.1 fvwm-perllib.1 \ fvwm-convert-2.6.1 \ fvwm-menu-xlock.1 fvwm-menu-directory.1 \ fvwm-menu-desktop.1 fvwm-menu-headlines.1 LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm $(xpm_LIBS) $(Xcursor_LIBS) \ $(X_PRE_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) $(Xrender_LIBS) \ $(Xcursor_LIBS) $(png_LIBS) $(rsvg_LIBS) $(Xinerama_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(X_CFLAGS) $(png_CFLAGS) \ $(rsvg_CFLAGS) $(Xinerama_CFLAGS) configdir = @FVWM_DATADIR@ config_DATA = fvwm-menu-desktop-config.fpl EXTRA_DIST = fvwm-menu-desktop-config.fpl $(man_MANS) ## The long generation for *.1 is to make both pod2man and 'make -j' happy. _fvwm-menu-xlock.1: fvwm-menu-xlock @TMP=tmp-$$$$ NAME=fvwm-menu-xlock && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) _fvwm-menu-directory.1: fvwm-menu-directory @TMP=tmp-$$$$ NAME=fvwm-menu-directory && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) _fvwm-menu-headlines.1: fvwm-menu-headlines @TMP=tmp-$$$$ NAME=fvwm-menu-headlines && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) _fvwm-perllib.1: fvwm-perllib @TMP=tmp-$$$$ NAME=fvwm-perllib && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) regenerate: \ _fvwm-menu-xlock.1 _fvwm-menu-directory.1 _fvwm-menu-headlines.1 \ _fvwm-perllib.1 ## Create compatibility symlinks if available install-exec-local: @rm -f $(DESTDIR)$(bindir)/xpmroot @$(LN_S) fvwm-root $(DESTDIR)$(bindir)/xpmroot || \ echo "Minor warning: $(bindir)/xpmroot symlink was not created" install-data-local: @rm -f $(DESTDIR)$(mandir)/man1/xpmroot.1 @$(LN_S) fvwm-root.1 $(DESTDIR)$(mandir)/man1/xpmroot.1 || \ echo "Minor warning: $(mandir)/man1/xpmroot.1 symlink was not created" CLEANFILES = $(bin_SCRIPTS) $(bin_PROGRAMS) fvwm-2.6.7/bin/fvwm-convert-2.6.in0000644000175700017570000003421312673746443013527 00000000000000#!@PERL@ # -*-perl-*- # Convert .fvwm2rc from 2.4.x format to 2.6.x format. # # Original author: Thomas Adam Dec. 2009 # # 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 use strict; use Cwd; use File::Basename; use Getopt::Long; # Global array for all our converted lines. my @converted_lines = (); # Global softref for addtofunc continuations. my $last_func_ref; my %converted_funcs = (); # Global for additional files... my @additional_files = (); # GetOpts my $follow_read = ''; my $process_read = 0; # Convert conditional command syntax correctly. sub __convert_conditionals { my( $cond ) = @_; my( $line ) = $cond->[-1]; my $condition_cmds = qr/(all|current|direction|next|none|prev|pick|thiswindow|windowid)/; # Take the last component. We no longer care for "[*]" as conditional # command parameters. But we shouldn't really put another conditional # in its place, so we'll just remove it. $line =~ s/\[\*\]//; # And convert over Next [$1] syntax. $line =~ s/$condition_cmds\s*\[(.*?)\]/\($1\)/io; $line = "$1 ". join( ', ', split( /[^,](\s+)[^,]/, $2 ) ) . " $3" if $line =~ /$condition_cmds\s*(\(.*?\))(.*)/io; $cond->[-1] = $line; } # Process the files specified and output them to a destination file. sub process_files { my( $files ) = @_; no strict "refs"; foreach my $f ( @$files ) { my( $s, $d ) = @$f; my $cwd_path = getcwd(); warn "Following: Read $s...\n" if $process_read; if( !defined $d or $d eq '' ) { my $fbasename = basename( $s ); $d = "$cwd_path/$fbasename.converted"; } if( -e $d ) { die "Destination file: $d exists\n"; } open( my $in_file, '<', $s ) or die "Unable to open source file: $!\n"; while( <$in_file> ) { chomp; # We have to handle continuation lines here, such as: # # Style foo !Bar, !Baz, \ # NoSomethingElse if( /\\\s*$/ ) { $_ .= <$in_file>; redo; } dispatch_line($_); } write_out_file($d); @converted_lines = (); %converted_funcs = (); } } # Convert style syntax over where applicable. sub convert_styles { my( $line ) = @_; my @converted; # At the very least, we can cheat and just negate everything. Whilst it # isn't deprecated yet, it will be -- so it won't hurt to do it here. # Split the line out first of all, between the "Style foo" part, and the # actual styles being applied. my( @style_parts ) = ($line =~ /^(style\s+\"??[\w+*?]\"??)(.*)$/i); # Convert the second part over. foreach( split( /\s*,\s*/, $style_parts[1] ) ) { # There is no !PPosition style, but there is !UsePPosition s/(?:No)(.*)/\!$1/ unless /nopposition/i; s/nopposition/!UsePPosition/i; push @converted, $_; } push @converted_lines, $style_parts[0] . join(', ', @converted); } # Buckshot approach at turning fvwmthemes into colorsets. Can't really do # much more than this, but at least gives the user something to go on. sub convert_fvwmtheme { my( $line ) = @_; $line =~ s/^\*fvwmtheme\s*:?//i; $line = undef if $line =~ /modulesynchronous.*?fvwmtheme/i; push @converted_lines, $line; } # Comment out the modulepath line -- grr. sub handle_modulepath { my( $line ) = @_; push( @converted_lines, "# Commented out by fvwm-convert-2.6: $line" ); } # This should have happened in the fvwm-2.4 convert script, but handle it # here anyway. sub convert_windowshadesteps { my( $line ) = @_; $line =~ /(\d+)p?/ ? $line = "Style * WindowShadeSteps $1" : $line = "Style * " . $line; push( @converted_lines, $line ); } sub convert_edge_resistance { my( $line ) = @_; # This gets converted into two parts. One is the EdgeResistance # command, the other is a style line. # # We could only ever have had two numbers as arguments to # EdgeResistance. my( $edge_res_arg, $move_res_arg ) = ( $line =~ /edgeresistance\s*(\d+)\s*(\d+)/i ); push( @converted_lines, qq| EdgeResistance $edge_res_arg Style * EdgeMoveResistance $move_res_arg| ); } sub convert_snapattraction { my( $line ) = @_; push( @converted_lines, "Style * " . $line ); } sub convert_key_mouse_bindings { my( $line ) = @_; my @components = split( /(\s+)/, $line, 5 ); # Also, conditional commands should now be separated with commas and not # whitespace, so try and fix these up where we can. It's not the # intention we'll catch them all, but at least try and do so based on # where they're likely to be used. __convert_conditionals(\@components); push( @converted_lines, join '', @components ); } sub handle_continuation { no strict "refs"; # Yes, yes... my( $line ) = @_; if( !defined $last_func_ref || $last_func_ref eq '' ) { my @func_parts = split( /(\+\s*\"?(?:i|c|d|h|m)\"?\s*)/i, $line, 2 ); __convert_conditionals(\@func_parts); push( @converted_lines, join '', @func_parts ); return; } eval { &{$last_func_ref}($line) }; warn "$@\n" if $@; } sub handle_read_file { my( $line ) = @_; my @read_parts = split( /\s+/, $line ); push( @converted_lines, $line ); # Crudely try and work out if the file is readable, and if it is add it # to the list of further files to convert. # # This won't handle having to interpolate out any env vars set via # SetEnv, or worse yet, outside of FVWM's environment. The user will # just have to run this script on that file manually. my $fname = $read_parts[1]; return unless defined $fname and $fname ne ''; if( -e $fname ) { push( @additional_files, [$fname] ); # We're done. return; } # If we have this: # # Read foo # # Or this: # # Read $./foo # # Then we assume FVWM_USERDIR ("$HOME/.fvwm/"), and if that file can't # be found there, try CWD, and if that fails we just give up. # Canonicalise the starting point by removing "$." -- we can guess what # it ought to be replaced with. $fname =~ s/^\$\.\/?//; if( -e "$ENV{FVWM_USERDIR}/$fname" ) { push( @additional_files, ["$ENV{FVWM_USERDIR}/$fname"] ); return; } if( -e "$ENV{HOME}/.fvwm/$fname" ) { push( @additional_files, ["$ENV{HOME}/.fvwm/$fname"] ); return; } my $cwd_path = getcwd(); if( -e "$cwd_path/$fname" ) { push( @additional_files, [$fname] ); return; } warn "Unable to follow: $line\n"; } sub check_func_definition { my( $line ) = @_; if( $line !~ /^addtofunc\s+(?:start|init|restart)function.*/i ) { $last_func_ref = ''; } # Then we have a standard function line in the form: # # + I SomeCommand # # Ensure we run it all through __convert_conditionals() my @func_parts = split( /(\s+)/, $line, 4 ); __convert_conditionals( \@func_parts ); push( @converted_lines, join '', @func_parts ); } sub convert_initfunc { my( $line ) = @_; $last_func_ref = "convert_initfunc"; if( $line =~ /addtofunc\s+initfunction\s+\"??[icmhd]{1}\"??\s+.*/i || $line =~ /addtofunc\s+initfunction\s*/i ) { $line =~ s/addtofunc\s+initfunction\s*//i; } $line =~ s/^\s*\+//; return if !defined $line || $line eq ''; # What we need to do now is convert this from: # # + I Foo # # to: # # + I Test (Init) Foo my @func_cmd = split( /\s+/, $line, 3 ); unshift( @func_cmd, '' ) unless @func_cmd > 2; # Remove any quotes around the action type --- they're not needed # anymore. $func_cmd[1] =~ s/\"//g; $func_cmd[1] .= q| Test (Init) |; # Run the command through the conditional function to ensure we # handle those correctly. __convert_conditionals( \@func_cmd ); push( @{ $converted_funcs{initfunction} }, join ' ', @func_cmd ); } sub convert_restartfunc { my( $line ) = @_; $last_func_ref = "convert_restartfunc"; # We treat this exactly like startfunction. if( $line =~ /addtofunc\s+restartfunction\s+\"??[icmhd]{1}\"??\s+.*/i ) { # Split this string. We can throw away the "AddToFunc" part as this # is irrelevant. But we want the following result: # ( 'I', 'Some Command' ) $line =~ s/addtofunc\s+restartfunction\s*//i; } $line =~ s/addtofunc\s+restartfunction\s*//i; return if $line eq ''; # Remove the continuation prefix as we can add this in when writing out # the function definitions later. $line =~ s/^\s*\+//; my @func_cmd = split( /\s+/, $line, 2 ); $func_cmd[1] =~ s/\"//g; # Run the command through the conditional function to ensure we # handle those correctly. __convert_conditionals( \@func_cmd ); push( @{ $converted_funcs{startfunction} }, join ' ', @func_cmd ); } sub convert_startfunc { my( $line ) = @_; $last_func_ref = "convert_startfunc"; # Now, it's possible that we have something like this: # # AddToFunc StartFunction I Some Command # # Extract the command part, add it to the hash for our functions, and # flag the fact we're dealing with StartFunction at this point for any # continuation lines (+ I Foo) since we can't determine the context of # them without such a thing. if( $line =~ /addtofunc\s+startfunction\s+\"??[icmhd]{1}\"??\s+.*/i ) { # Split this string. We can throw away the "AddToFunc" part as this # is irrelevant. But we want the following result: # ( 'I', 'Some Command' ) $line =~ s/addtofunc\s+startfunction\s*//i; } $line =~ s/addtofunc\s+startfunction\s*//i; # Remove the continuation prefix as we can add this in when writing out # the function definitions later. $line =~ s/^\s*\+//; return if !defined $line || $line eq ''; my @func_cmd = split( /\s+/, $line, 2 ); $func_cmd[1] =~ s/\"//g; # Run the command through the conditional function to ensure we # handle those correctly. __convert_conditionals( \@func_cmd ); push( @{ $converted_funcs{startfunction} }, join ' ', @func_cmd ); } sub write_out_file { my( $dest_file ) = @_; open( my $f, '>', $dest_file ) or die "Couldn't open $dest_file: $!\n"; # If we had any continuation lines, preserve them as best we can. @converted_lines = map { join "\\\n", split /\\/, $_ } @converted_lines; print $f join( "\n", @converted_lines ); # Write out the functions. if( defined $converted_funcs{initfunction} or defined $converted_funcs{startfunction} ) { print $f qq|\n\nDestroyFunc StartFunction\nAddToFunc StartFunction\n|; # Put the Init stuff before anything else. for( @{ $converted_funcs{initfunction} }, @{ $converted_funcs{startfunction } } ) { print $f "+ $_\n"; } } close( $f ); } sub dispatch_line { my( $line ) = @_; if( $line =~ /^style/i ) { convert_styles($line); } elsif( $line =~ /^\s*\*fvwmtheme:??/i ) { convert_fvwmtheme($line); } elsif( $line =~ /^\s*modulepath\s*/i ) { handle_modulepath( $line ); } elsif( $line =~ /^\s*windowshadesteps.*/i ) { convert_windowshadesteps($line); } elsif( $line =~ /^\s*module(?:synchronous)?.*?fvwmtheme$/i ) { convert_fvwmtheme($line); } elsif( $line =~ /^\s*edgeresistance\s*\d+\s*\d+/i ) { convert_edge_resistance($line); } elsif( $line =~ /^\s*key|mouse/i ) { convert_key_mouse_bindings($line); } elsif( $line =~ /^\s*snap(?:attraction|grid)/i ) { convert_snapattraction( $line ); } elsif( $line =~ /^\s*addtofunc\s+initfunction/i ) { convert_initfunc( $line ); } elsif( $line =~ /^\s*addtofunc\s+startfunction.*/i ) { convert_startfunc( $line ); } elsif( $line =~ /^\s*addtofunc\s+restartfunction/i ) { convert_restartfunc( $line ); } elsif( $line =~ /^\s*addtofunc\s+\w+.*/i ) { check_func_definition( $line ); } elsif( $line =~ /^\s*\+\s*\"??[ichmd]{1}\s*\"??\s+.*/i ) { handle_continuation( $line ); } elsif( $line =~ /^\s*read\s*[\/\w]+/i ) { handle_read_file( $line ); } else { # Could be a comment, or a continuation, or simply something we # don't need to convert. As far as continuation lines are # concerned, these are kept in order just by pushing them onto the # array --- but converting continuation lines is tricky since we'd # need to determine the context of the continuation. I can't be # bothered. push( @converted_lines, $_ ); } } sub usage { print "fvwm-convert-2.6 [-f] [-h] source-file destination-file\n"; exit; } GetOptions( "help|h" => \&usage, "follow-read|f" => \$follow_read, ) || usage(); # But we still require @ARGV to be populated with our filenames. usage() unless( @ARGV > 0 and @ARGV <=2 ); my @files = [@ARGV]; process_files( \@files ); if( @additional_files && !$follow_read ) { print "The following files were detected, but not processed:\n\n", join("\n", @$_ ) for @additional_files; print "\n"; } # Only do this is we've been asked. if( @additional_files && $follow_read ) { $process_read = 1; process_files( \@additional_files ); } fvwm-2.6.7/bin/fvwm-menu-xlock.in0000644000175700017570000001716112673746443013631 00000000000000#!@PERL@ # Copyright (c) 1999-2009 Mikhael Goikhman # # 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 # Filter this script to pod2man to get a man page: # pod2man -c "Fvwm Utilities" fvwm-menu-xlock | nroff -man | less -e use Getopt::Long; my $version = "@VERSION@"; my $name = 'XLockMenu'; my $title = 'XLock Modes'; my $itemf = '%n\t(%d)'; # may contain %n, %d, %D. my $icont = ''; my $iconi = ''; my $wm_icons = 0; my $special_first = 0; GetOptions( "help|h|?" => \&show_help, "version|V" => \&show_version, "name=s" => \$name, "title=s" => \$title, "item=s" => \$itemf, "icon-title=s" => \$icont, "icon-item=s" => \$iconi, "wm-icons" => \$wm_icons, "special-first" => \$special_first, ) || wrong_usage(); if ($wm_icons) { $icont ||= ""; $iconi ||= "menu/lock.xpm"; } my $icont_str = $icont ? "%$icont%" : ""; my $iconi_str = $iconi ? "%$iconi%" : ""; my $params = @ARGV ? ' ' . join(' ', @ARGV) : ''; my $lines1 = ""; # non-special mode lines my $lines2 = ""; # special mode lines my $start = 0; my $special = 0; $itemf =~ s/\\t/\t/g; open(XL, "xlock -display NONE -help 2>&1 |") || die "Exec echo 'Could not run xlock'\n"; print "DestroyMenu $name\n"; print "AddToMenu $name \"$icont_str$title\" Title\n"; while () { chomp; /where mode is one of:/ && do { $start = 1; next; }; if ($start && $_) { my ($misc, $name, $dsc) = split(/\s+/, $_, 3); next if $name =~ /^-/; my $dsc2 = $dsc =~ /^Shows (.*)$/ ? $1 : $dsc; my $item_str = $itemf; $item_str =~ s/\\t/\t/g; &expand_width_specifier(\$item_str, 'n', $name); &expand_width_specifier(\$item_str, 'd', $dsc); &expand_width_specifier(\$item_str, 'D', $dsc2); $special = 1 if !$special && $name eq 'blank'; ($special ? $lines2 : $lines1) .= qq(+ "$iconi_str$item_str" Exec xlock$params -mode $name\n); } } close XL; print $special_first ? qq($lines2+ "" Nop\n$lines1) : qq($lines1+ "" Nop\n$lines2); exit(0); # --------------------------------------------------------------------------- # Substitutes all %N1*N2x in $name by properly stripped and justified $value. sub expand_width_specifier (\$$$) { my ($name, $char, $value) = @_; $$name =~ s/%(-?\d+)?(\*(-?)(\d+))?$char/ my $value = !$2 || $4 <= 3 || $4 > length($value) ? $value : $3 ? "..." . substr($value, -$4 + 3, $4 - 3) : substr($value, 0, $4 - 3) . "..."; $1? sprintf("%$1s", $value): $value; /ge; } sub show_help { print "A small perl script which builds xlock menu for fvwm.\n\n"; print "Usage: $0 [OPTIONS] [-- XLOCK-OPTIONS]\n"; print "Options:\n"; print "\t--help show this help and exit\n"; print "\t--version show the version and exit\n"; print "\t--name=NAME menu name, default is '$name'\n"; print "\t--title=NAME menu title, default is '$title'\n"; print "\t--item=NAME menu item format, default is '$itemf'\n"; print "\t--icon-title=XPM menu title icon, default is no\n"; print "\t--icon-item=XPM menu item icon, default is no\n"; print "\t--wm-icons define icon names to use with wm-icons\n"; print "\t--special-first put special modes first\n"; print "Short options are ok if not ambiguous: -h, -t.\n"; print "\nSome useful xlock(1) options, 'xlock -h' for more:\n"; print "\t-delay usecs delay between batches of animations\n"; print "\t-nolock screensaver, don't lock the display\n"; print "\t-inwindow run in window as opposite to -inroot\n"; print "\t-sound turn on sound if enabled\n"; print "\t-nice level decrease the process priority (0 .. 19)\n"; exit 0; } sub show_version { print "$version\n"; exit 0; } sub wrong_usage { print STDERR "Try '$0 --help' for more information.\n"; exit -1; } __END__ # --------------------------------------------------------------------------- =head1 NAME fvwm-menu-xlock - builds xlock menu definition for fvwm =head1 SYNOPSIS B [ B<--help>|B<-h>|B<-?> ] [ B<--version>|B<-V> ] [ B<--name>|B<-n> name ] [ B<--title>|B<-t> title ] [ B<--item> format ] [ B<--icon-title> icon ] [ B<--icon-item> icon ] [ B<--special-first>|B<-s> ] [ -- xlock params ] =head1 DESCRIPTION A simple perl script which parses xlock's output to build an fvwm menu definition of all xlock's modes. =head1 OPTIONS =over 4 =item B<--help> show the help and exit =item B<--version> show the version and exit =item B<--name> name define menu name in the following argument. Default is "XLockMenu" =item B<--title> title define menu title in the following argument. Default is "XLock Modes". =item B<--item> format define menu item format in the following argument, default is '%n\t(%d)'. TAB can be specified as '\t', but in .fvwm2rc you should specify a double backslash or a real TAB. Format specifiers: %n - mode name %d - mode description %D - mode description without "Shows " prefix if any These specifiers can receive an optional integer size, positive for right adjusted string or negative for left adjusted, example: %8x; and optional *num or *-num, which means to leave only the first or last (if minus) num of chars, the num must be greater than 3, since the striped part is replaced with "...", example: %*30x. Both can be combined: %-10*-20x, this instructs to get only the 20 last characters, but if the length is less then 10 - to fill with up to 10 spaces on the right. =item B<--icon-title> icon =item B<--icon-item> icon define menu icon for title and regular item accordingly. Default is no menu icons (equivalent to an empty icon argument). =item B<--wm-icons> define icon names suitable for use with wm-icons package. Currently this is equivalent to: --icon-title '' --icon-item menu/lock.xpm. =item B<--special-first> instructs to include special modes (usually black, bomb and random) first. =back Option parameters can be specified either using '=' or in the next argument. Short options are ok if not ambiguous: -h, -t; but be careful with short options, what is now unambiguous, can became ambiguous in the next versions. Additional arguments (after B<-->) will be passed to xlock. Please see the B(1) man page for the xlock options. =head1 USAGE Add these lines to your fvwm configuration file: PipeRead 'fvwm-menu-xlock --name MenuSSaver --title "Screensaver" \ --icon-item mini-bball.xpm --special-first -- -nice 19 -nolock' PipeRead 'fvwm-menu-xlock --name MenuSLock --title "Lock Screen" \ --icon-item mini-rball.xpm --special-first -- -nice 19' AddToMenu "Utilities" "Screensaver%mini-monitor.xpm%" Popup MenuSSaver AddToMenu "Utilities" "Screenlock%mini-lock.xpm%" Popup MenuSLock =head1 AUTHORS Charles K. Hines , initial version. Mikhael Goikhman , from 24 Feb 1999. =head1 COPYING The script is distributed by the same terms as fvwm itself. See GNU General Public License for details. =head1 BUGS Depends on the output of xlock. Will produce an empty menu if the structure of the output is changed. Report bugs to fvwm-bug@fvwm.org. =cut # *************************************************************************** fvwm-2.6.7/bin/Makefile.in0000644000175700017570000007566513010103322012265 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = fvwm-root$(EXEEXT) subdir = bin DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/fvwm-bug.1.in $(srcdir)/fvwm-config.1.in \ $(srcdir)/fvwm-convert-2.6.1.in \ $(srcdir)/fvwm-menu-desktop.1.in $(srcdir)/fvwm-root.1.in \ $(srcdir)/fvwm-config.in $(srcdir)/fvwm-bug.in \ $(srcdir)/fvwm-perllib.in $(srcdir)/fvwm-menu-xlock.in \ $(srcdir)/fvwm-menu-directory.in \ $(srcdir)/fvwm-menu-desktop.in \ $(srcdir)/fvwm-menu-headlines.in $(srcdir)/fvwm-convert-2.6.in \ $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = fvwm-bug.1 fvwm-config.1 fvwm-convert-2.6.1 \ fvwm-menu-desktop.1 fvwm-root.1 fvwm-config fvwm-bug \ fvwm-perllib fvwm-menu-xlock fvwm-menu-directory \ fvwm-menu-desktop fvwm-menu-headlines fvwm-convert-2.6 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(configdir)" PROGRAMS = $(bin_PROGRAMS) fvwm_root_SOURCES = fvwm-root.c fvwm_root_OBJECTS = fvwm-root.$(OBJEXT) fvwm_root_LDADD = $(LDADD) am__DEPENDENCIES_1 = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } SCRIPTS = $(bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = fvwm-root.c DIST_SOURCES = fvwm-root.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ fvwm_root_SOURCE = fvwm-root.c fvwm_root_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a bin_SCRIPTS = fvwm-config fvwm-bug fvwm-perllib \ fvwm-convert-2.6 \ fvwm-menu-xlock fvwm-menu-directory \ fvwm-menu-desktop fvwm-menu-headlines man_MANS = \ fvwm-root.1 fvwm-config.1 fvwm-bug.1 fvwm-perllib.1 \ fvwm-convert-2.6.1 \ fvwm-menu-xlock.1 fvwm-menu-directory.1 \ fvwm-menu-desktop.1 fvwm-menu-headlines.1 LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm $(xpm_LIBS) $(Xcursor_LIBS) \ $(X_PRE_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) $(Xrender_LIBS) \ $(Xcursor_LIBS) $(png_LIBS) $(rsvg_LIBS) $(Xinerama_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(X_CFLAGS) $(png_CFLAGS) \ $(rsvg_CFLAGS) $(Xinerama_CFLAGS) configdir = @FVWM_DATADIR@ config_DATA = fvwm-menu-desktop-config.fpl EXTRA_DIST = fvwm-menu-desktop-config.fpl $(man_MANS) CLEANFILES = $(bin_SCRIPTS) $(bin_PROGRAMS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign bin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): fvwm-bug.1: $(top_builddir)/config.status $(srcdir)/fvwm-bug.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-config.1: $(top_builddir)/config.status $(srcdir)/fvwm-config.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-convert-2.6.1: $(top_builddir)/config.status $(srcdir)/fvwm-convert-2.6.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-menu-desktop.1: $(top_builddir)/config.status $(srcdir)/fvwm-menu-desktop.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-root.1: $(top_builddir)/config.status $(srcdir)/fvwm-root.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-config: $(top_builddir)/config.status $(srcdir)/fvwm-config.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-bug: $(top_builddir)/config.status $(srcdir)/fvwm-bug.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-perllib: $(top_builddir)/config.status $(srcdir)/fvwm-perllib.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-menu-xlock: $(top_builddir)/config.status $(srcdir)/fvwm-menu-xlock.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-menu-directory: $(top_builddir)/config.status $(srcdir)/fvwm-menu-directory.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-menu-desktop: $(top_builddir)/config.status $(srcdir)/fvwm-menu-desktop.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-menu-headlines: $(top_builddir)/config.status $(srcdir)/fvwm-menu-headlines.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fvwm-convert-2.6: $(top_builddir)/config.status $(srcdir)/fvwm-convert-2.6.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) fvwm-root$(EXEEXT): $(fvwm_root_OBJECTS) $(fvwm_root_DEPENDENCIES) $(EXTRA_fvwm_root_DEPENDENCIES) @rm -f fvwm-root$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fvwm_root_OBJECTS) $(fvwm_root_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fvwm-root.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-data-local install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS \ install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-configDATA uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-binSCRIPTS \ install-configDATA install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-configDATA uninstall-man uninstall-man1 _fvwm-menu-xlock.1: fvwm-menu-xlock @TMP=tmp-$$$$ NAME=fvwm-menu-xlock && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) _fvwm-menu-directory.1: fvwm-menu-directory @TMP=tmp-$$$$ NAME=fvwm-menu-directory && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) _fvwm-menu-headlines.1: fvwm-menu-headlines @TMP=tmp-$$$$ NAME=fvwm-menu-headlines && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) _fvwm-perllib.1: fvwm-perllib @TMP=tmp-$$$$ NAME=fvwm-perllib && (\ mkdir $$TMP && \ cp $$NAME.in $$TMP/$$NAME && \ pod2man --center "Fvwm Utilities" --release "@VERSION@@VERSIONINFO@" \ --name $$NAME $$TMP/$$NAME >$$TMP/$$NAME.1 && \ mv $$TMP/$$NAME.1 .; \ rm -rf $$TMP) regenerate: \ _fvwm-menu-xlock.1 _fvwm-menu-directory.1 _fvwm-menu-headlines.1 \ _fvwm-perllib.1 install-exec-local: @rm -f $(DESTDIR)$(bindir)/xpmroot @$(LN_S) fvwm-root $(DESTDIR)$(bindir)/xpmroot || \ echo "Minor warning: $(bindir)/xpmroot symlink was not created" install-data-local: @rm -f $(DESTDIR)$(mandir)/man1/xpmroot.1 @$(LN_S) fvwm-root.1 $(DESTDIR)$(mandir)/man1/xpmroot.1 || \ echo "Minor warning: $(mandir)/man1/xpmroot.1 symlink was not created" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/bin/fvwm-bug.in0000644000175700017570000001056612673746443012326 00000000000000#!/bin/sh - # # fvwm-bug - create a bug report and mail it to the bug address # - adapted from equivalent `bashbug' script # # The bug address could depend on the release status of fvwm. Currently # it doesn't. # # 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 PACKAGE="@PACKAGE@" VERSION="@VERSION@" script=`basename $0` address="" while test $# -gt 0; do case "$1" in --help|-help|-h|-\?) cat <&2 "Unrecognized option $1 specified." echo >&2 "Run '$0 --help' to get the usage." exit 1 ;; *) if test x"$address" != x; then echo >&2 "You may specify only one address." echo >&2 "Run '$0 --help' to get the usage." exit 1 fi address="$1" ;; esac shift done PATH=/bin:/usr/bin:/usr/local/bin:$PATH export PATH : ${EDITOR:=vi} TEMP=`mktemp -q "${TMPDIR:-/tmp}/fvwm-bug.XXXXXX"` # Figure out how to echo a string without a trailing newline N=`echo 'hi there\c'` case "$N" in *c) n=-n c= ;; *) n= c='\c' ;; esac trap 'rm -f $TEMP $TEMP.x; exit 1' 1 2 3 13 15 trap 'rm -f $TEMP $TEMP.x' 0 # Who is mail from? : ${USER:=${LOGNAME:-`whoami`}} # Who is mail to? if test x"$address" = x; then LOCAL=@LOCAL_BUGADDR@ WORKERS=fvwm-workers@fvwm.org if test "$LOCAL"; then echo "Do you want to send the report to the local maintainer <$LOCAL>," echo "the fvwm workers <$WORKERS>, or both?" echo $n "Send report to (l)ocal, (w)orkers, (b)oth? " $c read ans case "$ans" in l*|L*) BUGADDR=$LOCAL;; f*|F*|w*|W*) BUGADDR=$WORKERS;; b*|B*) BUGADDR=$LOCAL,$WORKERS;; *) echo "[Defaulting to LOCAL]"; BUGADDR=$LOCAL;; esac fi else BUGADDR=$address fi UN= if (uname) >/dev/null 2>&1; then UN=`uname -a` fi if [ -f /usr/lib/sendmail ] ; then RMAIL="/usr/lib/sendmail" elif [ -f /usr/sbin/sendmail ] ; then RMAIL="/usr/sbin/sendmail" else RMAIL=rmail fi prefix=@prefix@ exec_prefix=@exec_prefix@ datarootdir=@datarootdir@ datadir=@datadir@ libexecdir=@libexecdir@ : ${FVWM_USERDIR:=unset} FVWM_DATADIR=@FVWM_DATADIR@ FVWM_MODULEDIR=@FVWM_MODULEDIR@ cat > $TEMP <> $HOME/dead.fvwm-bug echo "$0: mail failed: report saved in $HOME/dead.fvwm-bug" >&2 } exit 0 fvwm-2.6.7/bin/fvwm-menu-desktop.1.in0000644000175700017570000003617013006057357014310 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .ta .3i .6i .9i 1.2i 1.5i 1.8i .TH fvwm-menu-desktop 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME fvwm-menu-desktop \- Reads XDG menu files and creates Fvwm menus .SH SYNOPSIS fvwm-menu-desktop [ \fB\-\-help\fR|\fB\-h\fR ] [ \fB\-\-version\fR ] [ \fB\-\-install\-prefix\fR \fIDIR\fR ] [ \fB\-\-desktop\fR \fINAME\fR ] [ \fB\-\-menu\-type\fR \fINAME\fR ] [ \fB\-\-theme\fR \fINAME\fR ] [ \fB\-\-with\-titles\fR|\fB\-w\fR ] [ \fB\-\-without\-titles\fR ] [ \fB\-\-enable\-mini\-icons\fR ] [ \fB\-\-size\fR|\fB\-s\fR \fINUM\fR ] [ \fB\-\-mini\-icon\-dir\fR \fIDIR\fR ] [ \fB\-\-app\-icon\fR \fINAME\fR ] [ \fB\-\-dir\-icon\fR \fINAME\fR ] [ \fB\-\-title\fR|\fB\-t\fR \fINAME\fR ] [ \fB\-\-insert\-in\-menu\fR \fINAME\fR ] [ \fB\-\-get\-menus\fR \fIall\fR|\fIdesktop\fR ] [ \fB\-\-set\-menus\fR \fImenu_paths\fR ] [ \fB\-\-all\-menus\fR ] [ \fB\-\-include\-items\fR \fINAME\fR ] [ \fB\-\-regen\-cmd\fR \fICMD\fR ] [ \fB\-\-dynamic\fR ] [ \fB\-\-verbose\fR|\fB\-v\fR ] .SH DESCRIPTION This is a python script which parses XDG menus definitions to build corresponding fvwm menus. This script depends on python-xdg to run. .SH OPTIONS .IP "Main Options" .IP "\fB\-\-help\fR" Show the help and exit. .IP "\fB\-\-version\fR" Show the version and exit. .IP "\fB\-\-get\-menus\fR \fIall\fR|\fIdesktop\fR" Prints a space separated list of full menu paths found on the system. \fIall\fR will print all menus found on the system except empty ones. \fIdesktop\fR will print the menu(s) that would be generated by the script. No menu generation is done. .IP "\fB\-\-desktop\fR \fINAME\fR" Optional parameter to set the \fINAME\fR of the desktop XDG .menu file(s) to use. This option will override any default menus set via \fBFvwmForm-XDGMenu-Config\fR and cause the script to find menus in which \fINAME\fR is a part of the file name. Possible names are: \fIgnome\fR, \fIkde\fR, \fIxfce\fR, \fIlxde\fR, \fIdebian\fR, etc. This option can be used in conjunction with \fB\-\-menu\-type\fR to control which .menu file(s) are used. .IP "\fB\-\-menu\-type\fR \fINAME\fR" Optional parameter to set the \fINAME\fR of the XDG menu type to use. This option will override any default menus set via \fBFvwmForm-XDGMenu-Config\fR and cause the script to find menus in which \fINAME\fR is a part of the file name. Possible \fINAME\fR types could be: \fIapplications\fR, \fIsettings\fR, \fIpreferences\fR, etc. When used in conjunction with \fB\-\-desktop\fR, only menus whose file name matches '*destkop*menutype*' are found. If no menus are found, the script exits with an error. .IP "\fB\-\-all\-menus\fR" This option will build all menus found on the system. If used in conjunction with \fB\-\-desktop\fR or \fB\-\-menu\-type\fR this will build all menus matching those settings. .IP "\fB\-\-install-prefix\fR \fIDIR\fR" Optional parameter to override the standard locations for XDG menu definitions. Tells \fBfvwm-menu-desktop\fR to look in \fIDIR\fR for .menu files instead of the standard locations /etc/xdg/menus (and $HOME/.config/menus if it exists). .IP "\fB\-\-with\-titles\fR|\fB\-w\fR" If this option is set menus are generated with titles. This is the default. This option can be used to override the \fBFvwmForm-XDGMenu-Config\fR default setting. .IP "\fB\-\-without\-titles\fR" If this option is set menus are generated without titles. The default is to generate with titles. .IP "\fB\-\-title\fR|\fB\-t\fR \fINAME\fR " Option to define the menu title \fINAME\fR of the top menu used by Fvwm's \fBMenu\fR or \fBPopup\fR commands. Default is "XDGMenu". .IP "\fB\-\-include\-items\fR \fINAME\fR " This option controls if the additional menu items 'Regenerate' and 'Configure' are included in the top level menu. \fINAME\fR can be one of \fIregen\fR, \fIconfig\fR, \fIboth\fR, or \fInone\fR. The default is \fIboth\fR. .IP "\fB\-\-regen\-cmd\fR \fICMD\fR " This option sets the fvwm command \fICMD\fR that is run when the menu item \'Regenerate' is selected. The default is "PipeRead `fvwm-menu-desktop`". .IP "\fB\-\-dynamic\fR " This option is to be used with creating dynamic menus using \fBDynamicPopUpAction\fR and \fBDynamicPopDownAction\fR. This adds a 'recreate' to the \fBDestroyMenu\fR command on the top level menu so those actions are not Destroyed when the menu is regenerated. .IP "\fB\-\-insert\-in\-menu\fR \fINAME\fR" Option to insert generated menu(s) \fBIN\fR a menu \fINAME\fR (its top title). This option makes it so the top level menu is not Destroyed and the items are added to the end. Note menus regenerated with this option will append the menu items at the end of the existing menu. Each time the menu is regenerated new menu items appear giving a growing menu of duplicate items. You have to regenerate the whole menu via a function or restart fvwm. See \fBEXAMPLES\fR below for some solutions. .IP "\fB\-\-set\-menus\fR \fImenu_paths\fR" Generates all menus listed in a space separated list of full menu paths. This option overrides any defaults and \fB\-\-desktop\fR|\fB\-\-menu\-type\fR settings. .IP "\fB\-\-verbose\fR" Enables additional information printouts on STDERR. .IP "Icons Options" By default, fvwm-menu-desktop builds menus without mini\-icons. To enable mini\-icons use the following options. If ImageMagick is installed on the system, the script will resize and copy the icons to $FVWM_USERDIR/.icons. This can take awhile. You should be prepared to wait the first time you generate the icons. Once the icons have been generated the script should run faster. If it is still to slow using icons, see \fBEXAMPLES\fR for ways to limit how often the menu is generated to speed things up. .IP "\fB\-\-enable\-mini\-icons\fR" This option enables mini\-icons in the menus. If set, 24x24 mini-icons are used. If the specified icon isn't that size it will be converted if \fBImageMagick\fR is installed and saved in $HOME/.fvwm/icons or to the directory specified with \-\-mini\-icon\-dir option. Otherwise no icon appears in the menu for that entry. With most distributions, all the menu entries will have mini-icons appropriate to the application. .IP "\fB\-\-theme\fR \fINAME\fR" Defines the used icon theme. Default is \fIgnome\fR but all others found in /usr/share/icons could be used except the \fIhicolor\fR theme because it's the default fallback theme if no icon is found. .IP "\fB\-\-size\fR|\fB\-s\fR \fINUM\fR" If \-\-enable\-mini\-icons is used the \fIsize\fR of the icons can changed with this parameter. Default is 24. .IP "\fB\-\-mini\-icon\-dir\fR \fIDIR\fR" When the right size mini-icon isn't available, fvwm-menu-desktop creates icons with the right size in $HOME/.fvwm/icons. If you don't want to use the default directory, $HOME/.fvwm/icons, use this option to specify a different folder. .IP "\fB\-\-app\-icon\fR \fINAME\fR" Sets the default application icon if no others are found. Default is \'gnome-applications'. .IP "\fB\-\-dir\-icon\fR \fINAME\fR" Sets the default directory icon if no others are found. Default is \'gnome-fs-directory'. .SH USAGE \fBfvwm-menu-desktop\fR outputs XDG .menu files in the syntax of fvwm menus. When \fBfvwm-menu-desktop\fR is run with no options, it will load defaults from the \fBFvwmForm-XDGMenu-Config\fR file (see below) then search your system for suitable menu file(s). To see which menus are available on your system run: .RS .EX fvwm-menu-desktop --get-menus all .EE .RE If no menus are found you may not have any installed on your system. By default menus are stored as *.menu files in /etc/xdg/menus, $HOME/.config/menus or the location set in $XDG_MENU_PREFIX. You can use \fB\-\-install\-prefix\fR to specify another location search for menus. Though a combination of command line options and the \fBFvwmForm-XDGMenu-Config\fR settings, \fBfvwm-menu-desktop\fR can generate any combination of the menus found. To get a list of what menu(s) would be generated use the \fB--get-menus\fR \fIdesktop\fR option. The following will list all menus generated if \fBfvwm-menu-desktop\fR was run with no options. .RS .EX fvwm-menu-desktop --get-menus desktop .EE .RE \fBfvwm-menu-desktop\fR determines which menu(s) to generate as follows .RS If no config file is found, all menus will be weighted and the script will generate the best (highest weight) menu found. If a config file is found (and override options are not used) the script will generate all menus selected in \fBFvwmForm-XDGMenu-Config\fR. \fB--desktop\fR, \fB--menu-type\fR, \fB--set-menus\fR and \fB--all-menus\fR will override any menus selected in \fBFvwmForm-XDGMenu-Config\fR. \fB--desktop\fR and \fB--menu-type\fR will only include menus whose name matches '*desktop*menutype*'. If used with \fB--all-menus\fR, all matching menus are generated. If used without \fB--all-menus\fR, only the highest weighted menu is generated. \fB--set-menus\fR generates menus from the list of full path menu file names. \fB--all-menus\fR by itself will generate all menus found. .RE By default \fBfvwm-menu-desktop\fR will generate a menu whose top level name is "XDGMenu". To tell fvwm to read the output of \fBfvwm-menu-desktop\fR to create the menu XDGMenu add the following to your fvwm config file: .RS .EX PipeRead 'fvwm-menu-desktop' .EE .RE \fBWarning:\fR Depending on the options used this command may be slow and fvwm will pause until this command is complete. See \fBEXAMPLES\fR below for more details and possible workarounds. Once the menu is generated you can open the menu by using the command "Menu XDGMenu". You can also include this in the MenuFvwmRoot menu by: .RS .EX AddToMenu MenuFvwmRoot "XDG Menu" Popup XDGMenu .EE .RE \fBfvwm-menu-desktop\fR can be configured though both command line options and a \fBFvwmForm\fR GUI to customize the menu(s) that get generated. .SH GUI \fBFvwmForm-XDGMenu-Config\fR is a \fBFvwmForm\fR interface that can be used to configure the defaults for \fBfvwm-menu-desktop\fR. You can access this from the "Configure" item in the top level menu that is generated or run the following from within \fBFvwmConsole\fR .RS .EX Module FvwmPerl -l fvwm-menu-desktop-config.fpl .EE .RE This form can be used to select which menu(s) get generated by default along with setting many (but not all) of the available options. When you click "Save Settings" the form will write a config file located at $FVWM_USERDIR/.FvwmForm-XDGMenu-Config that \fBfvwm-menu-desktop\fR will parse for defaults when run. See the help inside of \fBFvwmForm-XDGMenu-Config\fR for more information. .SH EXAMPLES There are many ways to setup when fvwm runs \fBfvwm-menu-desktop\fR to generate the menu. One method is to just generate the menu when fvwm loads and then use the GUI config tool to change any options. To do this you only need to add the following to the fvwm config file: .RS .EX AddToMenu MenuFvwmRoot "XDG Menu" Popup XDGMenu PipeRead 'fvwm-menu-desktop' .EE .RE The menu is created once when fvwm loads. Since menu creation can sometimes be slow, this could cause fvwm to take longer to load than one wants. The menu is only generated when fvwm starts. If software is installed or removed you will have to select the 'Regenerate' option to rebuild the menu. One way to speed things up is to save the menu in a file and only generate the menu when 'Regenerate' is selected. To do this use \fB--regen-cmd\fR to call a custom function and write the menu to a file using a command like .RS .EX fvwm-menu-desktop --regen-cmd XDGRegen > $FVWM_USERDIR/.XDGMenu .EE .RE Then add the following to the fvwm config file to define the function XDGRegen. The second to last line will generate the menu if the menu file doesn't exist when fvwm starts. .RS .EX DestroyFunc XDGRegen AddToFunc XDGRegen + I PipeRead 'fvwm-menu-desktop --regen-cmd XDGRegen > \\ $[FVWM_USERDIR]/.XDGMenu; echo "Nop"' + I Read $[FVWM_USERDIR]/.XDGMenu Test (!f $[FVWM_USERDIR]/.XDGMenu) XDGRegen Read $[FVWM_USERDIR]/.XDGMenu .EE .RE Besides creating a top level menu, \fBfvwm-menu-desktop\fR can insert the menu into an existing menu using the \fB--insert-in-menu\fR option. For example one could create the menu MenuFvwmRoot and include the XDG items at the end. .RS .EX DestroyMenu MenuFvwmRoot AddToMenu MenuFvwmRoot "Fvwm" Title + "Item1" Action1 ... + "ItemN" ActionN + "" Nop PipeRead 'fvwm-menu-desktop --insert-in-menu MenuFvwmRoot' .EE .RE In this case the menu items are inserted at the end of the MenuFvwmRoot menu. If no items are in the menu, this menu becomes MenuFvwmRoot. The problem here is, that you have to restart fvwm or rebuild the whole menu to Regenerate it because menu items cannot be removed. To do this you could use a function like .RS .EX DestroyFunc XDGRegen AddToFunc XDGRegen + I DestroyMenu MenuFvwmRoot + I AddToMenu MenuFvwmRoot "Fvwm" Title + I AddToMenu MenuFvwmRoot "Item1" Action1 ... + I AddToMenu MenuFvwmRoot "ItemN" ActionN + I AddToMenu MenuFvwmRoot "" Nop + I PipeRead 'fvwm-menu-desktop --insert-in-menu MenuFvwmRoot \\ --regen-cmd XDGRegen' .EE .RE Fvwm can also create menus dynamically by using \fBDynamicPopUpAction\fR and/or \fBDynamicPopDownAction\fR. These commands when used with a Menu will run a Function when the menu is opened. For example one could create the menu XDGMenu when it is opened using .RS .EX AddToMenu XDGMenu "XDGMenu" Title + DynamicPopUpAction PipeRead 'fvwm-menu-desktop' .EE .RE This will create the menu when it is opened. One issue here is it will only create the menu the first time it is opened, and you still have to Regenerate the menu to see any changes. To create the menu each time it is open used the \fB--dynamic\fR option .RS .EX AddToMenu XDGMenu "XDGMenu" Title + DynamicPopUpAction PipeRead 'fvwm-menu-desktop \\ --dynamic --include-items config' + DynamicPopDownAction DestroyMenu recreate XDGMenu .EE .RE This will now Destroy the menu when it closed so it can be rebuilt the next time it is opened. The recreate flag doesn't completely destroy the menu keeping the DynamicPopUpAction and DynamicPopDownAction actions. The \fB--dynamic\fR flag includes the recreate option in the generated menus. To insert a menu into MenuFvwmRoot and still be dynamic you need to use a function that generates the whole menu. For example .RS .EX DestroyFunc GenRootMenu AddToFunc GenRootMenu + I DestroyMenu recreate MenuFvwmRoot + I AddToMenu MenuFvwmRoot "Fvwm" Title + I AddToMenu MenuFvwmRoot "Item1" Action1 ... + I AddToMenu MenuFvwmRoot "ItemN" ActionN + I AddToMenu MenuFvwmRoot "" Nop + PipeRead `fvwm-menu-desktop --insert-in-menu MenuFvwmRoot \\ --include-items config` AddToMenu MenuFvwmRoot "Fvwm" Title + DynamicPopUpAction GenRootMenu + DynamicPopDownAction DestroyMenu recreate MenuFvwmRoot .EE .RE .SH BUGS The whole process of creating menus from files is slow. Otherwise report bugs to the fvwm-workers mailing list . .SH AUTHORS This script is based on fvwm-xdg-menu.py written by Piotr Zielinski (http://www.cl.cam.ac.uk/~pz215/) who assigned Licence: GPL 2 Date: 03.12.2005. The script was reworked to replace the existing fvwm-menu-desktop perl script by the fvwm-workers. .SH COPYING The script is distributed by the same terms as fvwm itself. See GNU General Public License for details. fvwm-2.6.7/bin/fvwm-bug.10000644000175700017570000000273713010101137012024 00000000000000.\" @(#)fvwm-2.6.7 06 November 2016 .TH fvwm-bug 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .SH NAME fvwm-bug \- report a bug in fvwm .SH SYNOPSIS \fBfvwm-bug\fP [\fI--help\fP] [\fI--version\fP] [\fIaddress\fP] .SH DESCRIPTION .B fvwm-bug is a shell script to help the user compose and mail bug reports concerning fvwm in a standard format. .B fvwm-bug invokes the editor specified by the environment variable .SM .B EDITOR on a temporary copy of the bug report format outline. The user must fill in the appropriate fields and exit the editor. .B fvwm-bug then mails the completed report to the local fvwm maintainer, the fvwm workers list \fIfvwm-workers@fvwm.org\fP, or \fIaddress\fP. If the report cannot be mailed, it is saved in the file \fIdead.fvwm-bug\fP in the invoking user's home directory. .PP The bug report format outline consists of several sections. The first section provides information about the machine, operating system, the fvwm version, and the compilation environment. The second section should be filled in with a description of the bug. The third section should be a description of how to reproduce the bug. The optional fourth section is for a proposed fix. Fixes are encouraged. .SH ENVIRONMENT .B fvwm-bug will utilize the following environment variables if they exist: .TP .B EDITOR Specifies the preferred editor. If .SM .B EDITOR is not set, .B fvwm-bug defaults to .BR emacs . .TP .B HOME Directory in which the failed bug report is saved if the mail fails. fvwm-2.6.7/bin/fvwm-menu-headlines.10000644000175700017570000003444712673746443014205 00000000000000.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.02) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "fvwm-menu-headlines 1" .TH fvwm-menu-headlines 1 "2009-03-22" "2.5.28 (from cvs)" "Fvwm Utilities" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" fvwm\-menu\-headlines \- builds headlines menu definition for fvwm .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBfvwm-menu-headlines\fR [ \fB\-\-help\fR|\fB\-h\fR|\fB\-?\fR ] [ \fB\-\-version\fR|\fB\-V\fR ] [ \fB\-\-info\fR [site] ] [ \fB\-\-site\fR|\fB\-s\fR site ] [ \fB\-\-name\fR|\fB\-n\fR name ] [ \fB\-\-title\fR|\fB\-t\fR title ] [ \fB\-\-item\fR item ] [ \fB\-\-exec\fR|\fB\-e\fR exec-command ] [ \fB\-\-command\fR|\fB\-e\fR fvwm-command ] [ \fB\-\-icon\-title\fR icon ] [ \fB\-\-icon\-item\fR icon ] [ \fB\-\-icon\-home\fR icon ] [ \fB\-\-icon\-error\fR icon ] [ \fB\-\-wm\-icons\fR ] [ \fB\-\-frontpage\fR [where] ] [ \fB\-\-proxy\fR|\fB\-p\fR host:port ] [ \fB\-\-file\fR [file] ] [ \fB\-\-fake\fR [file] ] [ \fB\-\-timeout\fR seconds ] .SH "DESCRIPTION" .IX Header "DESCRIPTION" This configurable perl script builds an fvwm menu definition for headlines of popular news web sites: FreshMeat, Slashdot, LinuxToday, DaemonNews, GNOME-News, KDE-News, RootPrompt, LinuxFr, ThinkGeek, \s-1CNN\s0, \s-1BBC\s0 and more. .PP It is possible to specify a customized menu item format, change a command (usually launching a browser) and add menu icons (there is a support for the wm-icons package). .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-\-help\fR" 4 .IX Item "--help" show the help and exit .IP "\fB\-\-version\fR" 4 .IX Item "--version" show the version and exit .IP "\fB\-\-info\fR [site]" 4 .IX Item "--info [site]" if site name is given print the site specific info, otherwise print all site names .IP "\fB\-\-site\fR site" 4 .IX Item "--site site" defile a web site, headlines of which to show, this option also can be used together with \-\-help to get new defaults. Default site: freshmeat. .IP "\fB\-\-name\fR name" 4 .IX Item "--name name" define menu name (default is \*(L"MenuHeadlinesFreshmeat\*(R") .IP "\fB\-\-title\fR title" 4 .IX Item "--title title" define menu title (default is \*(L"Freshmeat Headlines\*(R"). .IP "\fB\-\-item\fR label-format" 4 .IX Item "--item label-format" .PD 0 .IP "\fB\-\-exec\fR command-format" 4 .IX Item "--exec command-format" .PD define format for menu item or command (what is shown and what is executed when the item is chosen). Default label is '%h\et%[(%Y\-%m\-%d \f(CW%H:\fR%M)]'. \s-1TAB\s0 can be specified as '\et', but in .fvwm2rc you should specify a double backslash or a real \s-1TAB\s0. .Sp Format specifiers for a headline format: .Sp .Vb 11 \& %h \- headline \& %u \- url \& %d \- date in the native format (that site backend supplied) \& %[strftime\-argument\-string] \- date/time, see strftime(3) \& the date/time is represented according to the local time; \& date and/or time fields that can\*(Aqt be guessed are stripped \& Example: %[|%d %B %Y| %H:%M %S] \& If site supplied only date \- this becomes %[|%d %B %Y|], \& if site supplied no date \- this becomes an empty string. \& %{name} \- site specific named value, like %{comments} \& %(text) \- arbitrary text, good for escaping or aligning .Ve .Sp These specifiers can receive an optional integer size, positive for right adjusted string or negative for left adjusted, example: \f(CW%8x\fR; and optional *num or *\-num, which means to leave only the first or last (if minus) num of chars, the num must be greater than 3, since the striped part is replaced with \*(L"...\*(R", example: %*30x. Both can be combined: %\-10*\-20x, this instructs to get only the 20 last characters, but if the length is less then 10 \- to fill with up to 10 spaces on the right. .Sp Example: .Sp .Vb 1 \& \-\-exec "iceweasel \-remote \*(AqopenURL(%u, new\-window)\*(Aq || iceweasel \*(Aq%u\*(Aq" .Ve .IP "\fB\-\-command\fR command-format" 4 .IX Item "--command command-format" like \fB\-\-exec\fR above, but enables to specify any fvwm command, for example, \*(L"Function FuncFvwmShowURL '%u'\*(R" not only Exec. .Sp In fact, \-\-exec=\*(L"mozilla '%u'\*(R" is equivalent to \-\-command=\*(L"Exec mozilla '%u'\*(R" .IP "\fB\-\-icon\-title\fR icon" 4 .IX Item "--icon-title icon" .PD 0 .IP "\fB\-\-icon\-item\fR icon" 4 .IX Item "--icon-item icon" .IP "\fB\-\-icon\-home\fR icon" 4 .IX Item "--icon-home icon" .IP "\fB\-\-icon\-error\fR icon" 4 .IX Item "--icon-error icon" .PD define menu icon for title, regular item, frontpage item and error item respectively. Default is no menu icons (equivalent to an empty icon argument). .IP "\fB\-\-wm\-icons\fR" 4 .IX Item "--wm-icons" define icon names suitable for use with wm-icons package. Currently this is equivalent to: \-\-icon\-title '' \-\-icon\-item menu/information.xpm \-\-icon\-home menu/home.xpm \-\-icon\-error menu/choice\-no.xpm. .IP "\fB\-\-frontpage\fR [where]" 4 .IX Item "--frontpage [where]" add the site frontpage item to the menu. Optional value can be used to specify where this item will be placed in the menu \- 'top' or 't', 'bottom' or 'b'. .IP "\fB\-\-proxy\fR host[:port]" 4 .IX Item "--proxy host[:port]" define a proxy to use. Example: \-\-proxy proxy.inter.net:3128 .IP "\fB\-\-file\fR [file]" 4 .IX Item "--file [file]" write the menu output to specified file. If no filename is given with this option (or empty filename), the default filename \s-1WORK_HOME/SITE\s0.menu is used. Without this option or with '\-' filename, the menu output is written to standard output. .IP "\fB\-\-fake\fR [file]" 4 .IX Item "--fake [file]" don't connect to the host using \s-1HTTP\s0 protocol, instead, read from \s-1WORK_HOME/SITE\s0.in file. The following reads input from freshmeat.in (downloaded http://freshmeat.net/backend/recentnews.txt) and saves output to segfault.menu (both files are in \s-1WORK_HOME\s0): fvwm-menu-headlines \-\-site freshmeat \-\-fake \-\-file .IP "\fB\-\-timeout\fR seconds" 4 .IX Item "--timeout seconds" limit a line reading from a socket to this timeout, the default timeout is 20 seconds. .PP \&\s-1WORK_HOME\s0 of this script is ~/.fvwm/.fvwm\-menu\-headlines. It is created if needed. .PP Option parameters can be specified either using '=' or in the next argument. Short options are ok if not ambiguous: \f(CW\*(C`\-h\*(C'\fR, \f(CW\*(C`\-t\*(C'\fR; but be careful with short options, what is now unambiguous, can become ambiguous in the next versions. .SH "USAGE" .IX Header "USAGE" 1. One of the ways to use this script is to define a crontab entry to run the script every hour or so for every monitored site: .PP .Vb 3 \& 0,30 * * * * fvwm\-menu\-headlines \-\-file \-\-site freshmeat \& 1,31 * * * * fvwm\-menu\-headlines \-\-file \-\-site linuxtoday \& 2,32 * * * * fvwm\-menu\-headlines \-\-file \-\-site slashdot .Ve .PP Then add these lines to your fvwm configuration file: .PP .Vb 3 \& DestroyFunc FuncFvwmMenuHeadlines \& AddToFunc FuncFvwmMenuHeadlines \& + I Read "$HOME/.fvwm/.fvwm\-menu\-headlines/$0.menu" \& \& DestroyMenu MenuHeadlines \& AddToMenu MenuHeadlines "Headlines" Title \& + MissingSubmenuFunction FuncFvwmMenuHeadlines \& + "FreshMeat" Popup freshmeat \& + "LinuxToday" Popup linuxtoday \& + "Slashdot" Popup slashdot .Ve .PP 2. Another way to use this script (only if you have fast network/proxy) is to run it every time you want to open your Headlines submenus. (Note, the submenu that is once created is not reloaded, use \*(L"Reset all\*(R".) .PP In this case your fvwm configuration lines could be: .PP .Vb 4 \& DestroyFunc FuncFvwmMenuHeadlines \& AddToFunc FuncFvwmMenuHeadlines \& + I PipeRead "fvwm\-menu\-headlines \-\-site $0" \& #+ I Schedule 900000 DestroyMenu $0 # reset generated menu in 15 minutes \& \& DestroyMenu MenuHeadlines \& AddToMenu MenuHeadlines "Headlines" Title \& + MissingSubmenuFunction FuncFvwmMenuHeadlines \& + "FreshMeat" Popup freshmeat \& + "Slashdot" Popup slashdot \& + "LinuxToday" Popup linuxtoday \& + "GNOME News" Popup gnome\-news \& + "KDE News" Popup kde\-news \& + "" Nop \& + "Reset all" FuncResetHeadlines \& \& DestroyFunc FuncResetHeadlines \& AddToFunc FuncResetHeadlines \& + I DestroyMenu freshmeat \& + I DestroyMenu linuxtoday \& + I DestroyMenu slashdot \& + I DestroyMenu gnome\-news \& + I DestroyMenu kde\-news .Ve .PP And finally, add \*(L"Popup MenuHeadlines\*(R" somewhere. .PP 3. Here is a usual usage. Use FvwmConsole or FvwmCommand to run fvwm commands from a shell script. Every time you want headlines from some site, execute (give any additional options if you want): .PP .Vb 3 \& PipeRead "fvwm\-menu\-headlines \-\-site newsforge \-\-name MenuHeadlinesNewsForge" \& # this may take several seconds, you may use: BusyCursor Read true \& Popup MenuHeadlinesNewsForge .Ve .SH "HOW TO ADD SITE HEADLINES" .IX Header "HOW TO ADD SITE HEADLINES" It is possible to add user defined site headlines without touching the script itself. Put your perl extensions to the file WORK_HOME/extension.pl. For each site add something similar to: .PP .Vb 8 \& $site_info\->{\*(Aqmyslashdot\*(Aq} = { \& \*(Aqname\*(Aq => "MySlashdot", \& \*(Aqhost\*(Aq => "myslashdot.org", \& \*(Aqpath\*(Aq => "/myslashdot.xml", \& \*(Aqfunc\*(Aq => \e&process_my_slashdot, \& # the following string is only used in \-\-info \& \*(Aqflds\*(Aq => \*(Aqtime, title, department, topic, author, url\*(Aq, \& }; \& \& sub process_my_slashdot () { \& return process_xml( \& \*(Aqstory\*(Aq, \& # mandatory \*(Aqh\*(Aq, \*(Aqu\*(Aq and \*(Aqd\*(Aq aliases or undef \& { \*(Aqh\*(Aq => \*(Aqtitle\*(Aq, \*(Aqu\*(Aq => \*(Aqurl\*(Aq, \*(Aqd\*(Aq => \*(Aqtime\*(Aq }, \& sub ($) { # convert \*(Aqd\*(Aq string to (y, m, d, H, M, S) \& $_[0] =~ /(\ed+)\-(\ed+)\-(\ed+) (\ed+):(\ed+):(\ed+)/; \& ($1, ($2 || 0) \- 1, $3, $4, $5, $6); \& }, +0, # timezone offset; already in UTC \& ); \& } \& \& 1; .Ve .SH "AUTHORS" .IX Header "AUTHORS" This script is inspired by WMHeadlines v1.3 by: .PP .Vb 2 \& Jeff Meininger \& (http://rive.boxybutgood.com/WMHeadlines/). .Ve .PP Reimplemented for fvwm and heavily enhanced by: .PP .Vb 1 \& Mikhael Goikhman , 16 Dec 1999. .Ve .SH "COPYING" .IX Header "COPYING" The script is distributed by the same terms as fvwm itself. See \s-1GNU\s0 General Public License for details. .SH "BUGS" .IX Header "BUGS" I try to keep all supported site info up to date, but sites often go down, change their backend formats, change their httpd responses, just stop to post news and so on; the script in the latest cvs may be more up to date. .PP The headline times may be off by one hour or more, since the time is displayed for your local time zone, and the time zone of the original time in the site backend output is often guessed (sometimes incorrectly); similarly it is guessed whether to apply the daylight saving correction. .PP Report bugs to fvwm\-bug@fvwm.org. fvwm-2.6.7/bin/fvwm-root.c0000644000175700017570000001677012773467231012347 00000000000000/* -*-c-*- */ /* * This is an all new program to set the root window to an Xpm pixmap. * Copyright 1993, Rob Nation * You may use this file for anything you want, as long as the copyright * is kept intact. No guarantees of any sort are made in any way regarding * this program or anything related to it. */ #include "config.h" #include #include #include #include #include "libs/fvwmlib.h" #include "libs/Picture.h" #include "libs/Graphics.h" #include "libs/Fsvg.h" int save_colors = 0; Display *dpy; int screen; Window root; char *display_name = NULL; Pixmap rootImage = None; Bool NoDither = False; Bool Dither = False; Bool NoColorLimit = False; int opt_color_limit = -1; Bool use_our_color_limit = False; void usage(int verbose) { FILE *output = verbose ? stdout : stderr; fprintf( output, "fvwm-root version %s with support for: XBM" #ifdef XPM ", XPM" #endif #ifdef HAVE_PNG ", PNG" #endif #ifdef HAVE_RSVG ", SVG" #endif "\n", VERSION); fprintf(output, "\nUsage: fvwm-root [ options ] file\n"); if (verbose) { fprintf(output, "Options:\n" "\t--dither\n" "\t--no-dither\n" "\t--retain-pixmap\n" "\t--no-retain-pixmap\n" "\t--color-limit l\n" "\t--no-color-limit\n" "\t--dummy\n" "\t--no-dummy\n" "\t--help\n" "\t--version\n"); } } int SetRootWindow(char *tline) { Pixmap shapeMask = None, temp_pix = None, alpha = None; int w, h; int depth; int nalloc_pixels = 0; Pixel *alloc_pixels = NULL; char *file_path; FvwmPictureAttributes fpa; if (use_our_color_limit) { PictureColorLimitOption colorLimitop = {-1, -1, -1, -1, -1}; colorLimitop.color_limit = opt_color_limit; PictureInitCMapRoot( dpy, !NoColorLimit, &colorLimitop, True, True); } else { /* this use the default visual (not the fvwm one) as * getenv("FVWM_VISUALID") is NULL in any case. But this use * the same color limit than fvwm. * This is "broken" when fvwm use depth <= 8 and a private * color map (i.e., fvwm is started with the -visual{ID} * option), because when fvwm use a private color map the * default color limit is 244. There is no way to know here if * getenv("FVWM_VISUALID") !=NULL. * So, in this unfortunate case the user should use the * --color-limit option */ PictureInitCMap(dpy); } flib_init_graphics(dpy); /* try built-in image path first, but not before pwd */ PictureSetImagePath(".:+"); file_path = PictureFindImageFile(tline, NULL, R_OK); if (file_path == NULL) { file_path = tline; } fpa.mask = FPAM_NO_ALLOC_PIXELS | FPAM_NO_ALPHA; if (Pdepth <= 8 && !NoDither) { fpa.mask |= FPAM_DITHER; } else if (Pdepth <= 16 && Dither) { fpa.mask |= FPAM_DITHER; } if (NoColorLimit) { fpa.mask |= FPAM_NO_COLOR_LIMIT; } if (!PImageLoadPixmapFromFile( dpy, root, file_path, &temp_pix, &shapeMask, &alpha, &w, &h, &depth, &nalloc_pixels, &alloc_pixels, 0, fpa)) { fprintf( stderr, "[fvwm-root] failed to load image file '%s'\n", tline); return -1; } if (depth == Pdepth) { rootImage = temp_pix; } else { XGCValues gcv; GC gc; gcv.background= WhitePixel(dpy, screen); gcv.foreground= BlackPixel(dpy, screen); gc = fvwmlib_XCreateGC( dpy, root, GCForeground | GCBackground, &gcv); rootImage = XCreatePixmap(dpy, root, w, h, Pdepth); XCopyPlane(dpy, temp_pix, rootImage, gc, 0, 0, w, h, 0, 0, 1); XFreePixmap(dpy, temp_pix); XFreeGC(dpy, gc); } XSetWindowBackgroundPixmap(dpy, root, rootImage); save_colors = 1; XClearWindow(dpy, root); return 0; } int main(int argc, char **argv) { Atom prop = None; Atom e_prop = None; Atom m_prop = None; Atom type; int format; unsigned long length, after; unsigned char *data; int i = 1; Bool e_killed = False; Bool Dummy = False; Bool RetainPixmap = False; if (argc < 2) { usage(0); fprintf(stderr, "Nothing to do, try again.\n"); exit(1); } dpy = XOpenDisplay(display_name); if (!dpy) { fprintf( stderr, "fvwm-root: unable to open display '%s'\n", XDisplayName (display_name)); exit(2); } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); for (i = 1; i < argc - 1; i++) { if ( strcasecmp(argv[i], "-r") == 0 || strcasecmp(argv[i], "--retain-pixmap") == 0) { RetainPixmap = True; } else if ( strcasecmp(argv[i], "--no-retain-pixmap") == 0) { RetainPixmap = False; } else if ( strcasecmp(argv[i], "-d") == 0 || strcasecmp(argv[i], "--dummy") == 0) { Dummy = True; } else if ( strcasecmp(argv[i], "--no-dummy") == 0) { Dummy = False; } else if ( strcasecmp(argv[i], "--dither") == 0) { Dither = True; } else if ( strcasecmp(argv[i], "--no-dither") == 0) { NoDither = True; } else if ( strcasecmp(argv[i], "--color-limit") == 0) { use_our_color_limit = True; if (i+1 < argc) { i++; opt_color_limit = atoi(argv[i]); } } else if ( strcasecmp(argv[i], "--no-color-limit") == 0) { NoColorLimit = True; } else if ( strcasecmp(argv[i], "-h") == 0 || strcasecmp(argv[i], "-?") == 0 || strcasecmp(argv[i], "--help") == 0) { usage(1); exit(0); } else if ( strcasecmp(argv[i], "-V") == 0 || strcasecmp(argv[i], "--version") == 0) { fprintf(stdout, "%s\n", VERSION); exit(0); } else { fprintf( stderr, "fvwm-root: unknown option '%s'\n", argv[i]); fprintf( stderr, "Run '%s --help' to get the usage.\n", argv[0]); exit(1); } } if ( Dummy || strcasecmp(argv[argc-1], "-d") == 0 || strcasecmp(argv[argc-1], "--dummy") == 0) { Dummy = True; } else if ( strcasecmp(argv[argc-1], "-h") == 0 || strcasecmp(argv[argc-1], "-?") == 0 || strcasecmp(argv[argc-1], "--help") == 0) { usage(1); exit(0); } else if ( strcasecmp(argv[argc-1], "-V") == 0 || strcasecmp(argv[argc-1], "--version") == 0) { fprintf(stdout, "%s\n", VERSION); exit(0); } else { int rc; rc = SetRootWindow(argv[argc-1]); if (rc == -1) { exit(1); } } prop = XInternAtom(dpy, "_XSETROOT_ID", False); (void)XGetWindowProperty( dpy, root, prop, 0L, 1L, True, AnyPropertyType, &type, &format, &length, &after, &data); if (type == XA_PIXMAP && format == 32 && length == 1 && after == 0 && data != NULL && (Pixmap)(*(long *)data) != None) { XKillClient(dpy, *((Pixmap *)data)); } if (data != NULL) XFree(data); e_prop = XInternAtom(dpy, "ESETROOT_PMAP_ID", False); (void)XGetWindowProperty( dpy, root, e_prop, 0L, 1L, True, AnyPropertyType, &type, &format, &length, &after, &data); if (type == XA_PIXMAP && format == 32 && length == 1 && after == 0 && data != NULL && (Pixmap)(*(long *)data) != None) { e_killed = True; XKillClient(dpy, *((Pixmap *)data)); } if (e_killed && !Dummy) { m_prop = XInternAtom(dpy, "_XROOTPMAP_ID", False); XDeleteProperty(dpy, root, m_prop); } if (RetainPixmap && !Dummy) { long prop; prop = rootImage; if (data != NULL) XFree(data); XSetCloseDownMode(dpy, RetainPermanent); if (e_prop == None) e_prop = XInternAtom(dpy, "ESETROOT_PMAP_ID", False); if (m_prop == None) m_prop = XInternAtom(dpy, "_XROOTPMAP_ID", False); XChangeProperty( dpy, root, e_prop, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &prop, 1); XChangeProperty( dpy, root, m_prop, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &prop, 1); } else { long dp = (long)None; if (prop == None) prop = XInternAtom(dpy, "_XSETROOT_ID", False); XChangeProperty( dpy, root, prop, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &dp, 1); } XCloseDisplay(dpy); return 0; } fvwm-2.6.7/bin/fvwm-convert-2.6.1.in0000644000175700017570000000710712673746443013670 00000000000000.\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH fvwm-convert-2.6 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .SH NAME fvwm-convert-2.6 \- convert fvwm 2.4.x configuration file to fvwm 2.6 style .SH SYNOPSIS .B fvwm-convert-2.6 .RI [ --follow-read | -f ] .RI [ --help | -h ] .RI source .RI [ dest ] .SH OPTIONS The following options are supported: .IP "\fB\-\-help\fR | \fB\-h\fR" Prints a usage message to the screen. .IP "\fB\-\-follow\-read\fR | \fB\-f\fR" Follows files found along with the .B Read command. .SH DESCRIPTION .B fvwm-convert-2.6 converts an fvwm 2.4.x configuration file into a fvwm 2.6 file with compatible syntax. It is not suitable to convert older 2.x configuration files. Please use .B fvwm-convert-2.2 to convert these to the 2.2.x format first, and then if necessary .B fvwm-convert-2.4 .PP By default, .B fvwm-convert-2.6 won't look for a given config file. This must be specified as the first parameter to .B fvwm-convert-2.6. Different source and destination files may be given. If the destination file already exists, this program exits. If no destination file is given, then the filename is the same name as the source file with the suffix ".converted" added. Without an absolute path given as the destination path to the destination file, the program will create the destination file in the CWD. .PP .B fvwm-convert-2.6 makes the following changes: .TP 4 .B Style lines In fvwm 2.4, most style options could be negated from their counterparts using NoFoo -- fvwm-convert-2.6 corrects this by now using !Foo. .TP 4 .B ModulePath In fvwm 2.4 and beyond, the ModulePath is compiled into fvwm. .B fvwm-convert-2.6 comments out any ModulePath commands it finds. If you are using your own modules, (not the ones that come with fvwm), you will have to fix your configuration file after using .BR fvwm-convert-2.6 . .TP 4 .B Conditional command syntax In fvwm 2.4, the conditional command options were whitespace-separated -- they should now be comma-separated instead. In addition, the older syntax to Next and Prev of using [*] to denote all windows has been removed entirely. Both these checks and conversions are done on function commands, key/mouse bindings. .TP 4 .B WindowShadeSteps In fvwm 2.4, the WindowShadeSteps command is replaced by the WindowShadeSteps Style option. .B fvwm-convert-2.6 makes this change. .TP 4 .B FvwmTheme In fvwm 2.6, the FvwmTheme module is replaced by a series of Colorset commands. Whilst .B fvwm-convert-2.6 will try and make this change, it is still recommended that this is checked after conversion. .TP 4 .B EdgeResistance In fvwm 2.6, the EdgeResistance command is has been split to include an additional style option for EdgeMoveResistance. .B fvwm-convert-2.6 makes any changes necessary. .TP 4 .B StartFunction / RestartFunction / InitFunction In fvwm 2.6, the need for using InitFunction and/or RestartFunction is redundant when StartFunction is read at both of these times. .B fvwm-convert-2.6 attempts to convert this. .TP 4 .B Read If .B -f or .B --follow-read is given, any files .B fvwm-convert-2.6 can detect and open will be converted automatically, else a list of files that can be followed are printed to the screen. .TP 4 .SH BUGS .I InitFunction and .I RestartFunction and hence .I StartFunction are printed at the end of the files -- this slight reordering might put some comments before in an odd spot. When converting over FvwmTheme lines, the colorset definitions might well be broken, but these cannot easily be converted. Bug reports can be sent to the fvwm-workers mailing list (see the .IR FAQ ). .SH AUTHOR Thomas Adam fvwm-2.6.7/bin/fvwm-menu-headlines.in0000644000175700017570000010372112673746443014443 00000000000000#!@PERL@ # Copyright (c) 1999-2009 Mikhael Goikhman # # 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 # Filter this script to pod2man to get a man page: # pod2man -c "Fvwm Utilities" fvwm-menu-headlines | nroff -man | less -e require 5.002; use strict; use vars qw($site_info @smonths @lmonths %smonth_hash %lmonth_hash); use vars qw($entity_map $error_menu_content); use Getopt::Long; use Socket; use POSIX qw(strftime); use Time::Local; my $version = "@VERSION@"; local $site_info = { 'freshmeat' => { 'name' => "FreshMeat", 'host' => "freshmeat.net", 'path' => "/backend/recentnews.txt", 'func' => \&process_freshmeat, 'flds' => 'headline, date, url', }, 'slashdot' => { 'name' => "Slashdot", 'host' => "slashdot.org", 'path' => "/slashdot.xml", 'func' => \&process_slashdot, 'flds' => 'title, url, time, author, department, topic, comments, section, image', }, 'linuxtoday' => { 'name' => "LinuxToday", 'host' => "linuxtoday.com", 'path' => "/lthead.txt", 'func' => \&process_linuxtoday, 'flds' => 'headline, url, date', }, 'old-segfault' => { 'name' => "Old-Segfault (empty now)", 'host' => "segfault.org", 'path' => "/stories.txt", 'func' => \&process_segfault, 'flds' => 'headline, url, date, author_name, author_email, type', }, 'old-appwatch' => { 'name' => "Old-AppWatch (closed by ZDNet)", 'host' => "www.appwatch.com", 'path' => "/appwatch.rdf", 'func' => \&process_poor_rdf, 'flds' => 'title, link, description', }, 'old-linuxapps' => { 'name' => "Old-LinuxApps (moved/closed)", 'host' => "www.linuxapps.com-closed", 'path' => "/backend/linux_basic.txt", 'func' => undef, 'flds' => 'headline, date, url', }, 'old-justlinux' => { 'name' => "Old-JustLinux (no headlines?)", 'host' => "www.justlinux.com", 'path' => "/backend/discussion.rdf", 'func' => \&process_poor_rdf, 'flds' => 'title, link', }, 'daemonnews' => { 'name' => "DaemonNews", 'host' => "daily.daemonnews.org", 'path' => "/ddn.rdf.php3", 'func' => \&process_poor_rdf, 'flds' => 'title, link', }, # this is now called FootNotes or GNOME Desktop News, was news.gnome.org 'gnome-news' => { 'name' => "GNOME-News", 'host' => "www.gnomedesktop.org", 'path' => "/backend.php", 'func' => \&process_poor_rdf, 'flds' => 'title, link', }, 'kde-news' => { 'name' => "KDE-News", 'host' => "news.kde.org", 'path' => "/rdf", 'func' => \&process_kde_news, 'flds' => 'title, link', }, 'old-freekde' => { 'name' => "Old-FreeKDE (taken off?)", 'host' => "freekde.org", 'path' => "/freekdeorg.rdf", 'func' => \&process_freekde, 'flds' => 'title, link', }, 'rootprompt' => { 'name' => "RootPrompt", 'host' => "rootprompt.org", 'path' => "/rss/", 'func' => \&process_rootprompt, 'flds' => 'title, link, description', }, 'newsforge' => { 'name' => "NewsForge", 'host' => "www.newsforge.com", 'path' => "/newsforge.xml", 'func' => \&process_slashdot, 'flds' => 'title, url, time, author, department, topic, comments, section, image', }, 'kuro5hin' => { 'name' => "Kuro5hin", 'host' => "www.kuro5hin.org", 'path' => "/backend.rdf", 'func' => \&process_kuro5hin, 'flds' => 'title, link, description', }, 'bbspot' => { 'name' => "BBSpot", 'host' => "bbspot.com", 'path' => "/bbspot.rdf", 'func' => \&process_poor_rdf, 'flds' => 'title, link', }, 'linuxfr' => { 'name' => "LinuxFr", 'host' => "linuxfr.org", # 'path' => "/short.php3", 'path' => "/backend.rss", 'func' => \&process_linuxfr, # 'flds' => 'headline, url, author_name, author_email, type', 'flds' => 'title, link', }, 'thinkgeek' => { 'name' => "ThinkGeek", 'host' => "www.thinkgeek.com", 'path' => "/thinkgeek.rdf", 'func' => \&process_poor_rdf, 'flds' => 'title, link', }, 'cnn' => { 'name' => "CNN", 'host' => "www.cnn.com", 'path' => "/desktop/content.html", 'func' => \&process_cnn, 'flds' => 'headline, url', }, # to be removed 'bbc-world' => { 'name' => "BBC-World (obsolete)", 'host' => "news.bbc.co.uk", 'path' => "/low/english/world/default.stm", 'func' => \&process_old_bbc, 'flds' => 'headline, url, abstract', }, # to be removed 'bbc-scitech' => { 'name' => "BBC-SciTech (obsolete)", 'host' => "news.bbc.co.uk", 'path' => "/low/english/sci/tech/default.stm", 'func' => \&process_old_bbc, 'flds' => 'headline, url, abstract', }, 'bbc' => { 'name' => "BBC", 'host' => "news.bbc.co.uk", 'host0' => "tickers.bbc.co.uk", 'path' => "/tickerdata/story2.dat", 'func' => \&process_bcc, 'flds' => 'story, headline, url', }, }; # Site specific parsers may use these constants to convert month to unix time. local @smonths = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); local @lmonths = qw(January February March April May June July August September October November December); local (%smonth_hash, %lmonth_hash) = (); foreach (0 .. 11) { $smonth_hash{$smonths[$_]} = $_; $lmonth_hash{$lmonths[$_]} = $_; } my $TIMEFIELDS_DATE_TIME = 1; my $TIMEFIELDS_ONLY_DATE = 2; my $TIMEFIELDS_NONE = 3; my $home = $ENV{'HOME'} || '/tmp'; my $fvwm_user_dir = $ENV{'FVWM_USERDIR'} || "$home/.fvwm"; $fvwm_user_dir = $home unless -d $fvwm_user_dir; my $work_home = "$fvwm_user_dir/.fvwm-menu-headlines"; require "$work_home/extension.pl" if -r "$work_home/extension.pl"; my $info = undef; my $default_site = 'freshmeat'; my $site = undef; my $name = undef; my $title = undef; my $itemf = '%h\t%[(%Y-%m-%d %H:%M)]'; my $execf = q(firefox '%u'); my $commf = undef; my $icont = ''; my $iconi = ''; my $iconh = ''; my $icone = ''; my $wm_icons = 0; my $proxy = undef; my $port = 80; my $frontpage = undef; my @time = localtime(); my $menu_filename = undef; my $fake_filename = undef; my $timeout = 20; my $endl = "\r\n"; # this is preferable for http sockets to "\n" GetOptions( "help|h|?" => \&show_help, "version|V" => \&show_version, "info:s" => \$info, "site=s" => \$site, "name=s" => \$name, "title=s" => \$title, "item=s" => \$itemf, "exec=s" => \$execf, "command=s" => \$commf, "icon-title=s" => \$icont, "icon-item=s" => \$iconi, "icon-home=s" => \$iconh, "icon-error=s" => \$icone, "wm-icons" => \$wm_icons, "proxy=s" => \$proxy, "frontpage:s" => \$frontpage, "file:s" => \$menu_filename, "fake:s" => \$fake_filename, "timeout=i" => \$timeout, ) || wrong_usage(); wrong_usage() if @ARGV; if (defined $info) { if ($info) { my $_info = $site_info->{lc($info)}; die "Unsupported site '$info'; try --info.\n" unless $_info; my $host0 = $_info->{'host0'} || $_info->{'host'}; print "Site Name:\n\t$_info->{'name'}\n", "Home Page:\n\thttp://$_info->{'host'}/\n", "Headlines:\n\thttp://$host0$_info->{'path'}\n", "Headline fields:\n\t$_info->{'flds'}\n"; } else { print "All supported sites:\n\t", join(", ", &get_all_site_names()), "\n\nSpecify a site name after --info to get a site headlines info.\n"; } exit(0); } $site ||= $default_site; $site = lc($site); die "Unsupported site '$site'; try --info.\n" unless exists $site_info->{$site}; #$name ||= "MenuHeadlines$site_info->{$site}->{'name'}"; $name ||= $site; $title ||= "$site_info->{$site}->{'name'} Headlines"; my $site_name = $site_info->{$site}->{'name'}; my $site_host = $site_info->{$site}->{'host'}; my $site_path = $site_info->{$site}->{'path'}; my $site_func = $site_info->{$site}->{'func'}; $commf ||= "Exec $execf"; $title =~ s/\\t/\t/g; $itemf =~ s/\\t/\t/g; $commf =~ s/\\t/\t/g; if ($wm_icons) { $icont ||= ""; $iconi ||= "menu/information.xpm"; $iconh ||= "menu/home.xpm"; $icone ||= "menu/choice-no.xpm"; } my $icont_str = $icont ? "%$icont%" : ""; my $iconi_str = $iconi ? "%$iconi%" : ""; my $iconh_str = $iconh ? "%$iconh%" : ""; my $icone_str = $icone ? "%$icone%" : ""; if (defined $proxy && $proxy =~ /^(.+):(\d+)$/) { $proxy = $1; $port = $2; } # Three cases: # 1) no --file option or value '-' specified (STDOUT is used) # 2) no or empty menu file in --file specified (the default name is used) # 3) non-empty menu file specified (use it) $menu_filename = undef if defined $menu_filename && $menu_filename eq '-'; if ($menu_filename) { $menu_filename =~ s:^~(/|$):$home$1:; $menu_filename =~ m:^(.+)/[^/]+$:; $work_home = $1 || "."; } elsif (defined $menu_filename) { $menu_filename = "$work_home/$site.menu"; } my $content = ""; $content .= qq(DestroyMenu $name\n); $content .= qq(AddToMenu $name "$icont_str$title" Title\n); local $error_menu_content = $content; my $frontpage_entry = ""; if (defined $frontpage) { my $cmd = &expand_all_width_specifiers($commf, {'u' => "http://$site_host/"}); $frontpage_entry = qq(+ "$iconh_str$site_name Frontpage" $cmd\n); $error_menu_content .= qq($frontpage_entry\n+ "" Nop\n); } $error_menu_content .= "+ `$icone_str` DestroyMenu $name\n"; if (defined $frontpage && $frontpage !~ /^b/) { $content .= qq($frontpage_entry\n+ "" Nop\n); } unless (defined $fake_filename) { $site_host = $site_info->{$site}->{'host0'} if defined $site_info->{$site}->{'host0'}; my $redirect_depth = 0; HTTP_CONNECTION: my $host = $proxy || $site_host; my $iaddr = inet_aton($host) || &die_net("Can't resolve host $host"); my $paddr = sockaddr_in($port, $iaddr); my $proto = getprotobyname('tcp'); local $SIG{ALRM} = sub { die "timeout\n"; }; alarm($timeout); eval { socket(SOCK, PF_INET, SOCK_STREAM, $proto) && connect(SOCK, $paddr) } || &die_net("Can't connect host $host"); alarm(0); select(SOCK); $| = 1; select(STDOUT); # do http request my $http_headers = "$endl" . "Host: $site_host$endl" . "Connection: close$endl" . "User-Agent: fvwm-menu-headlines/$version$endl" . "Pragma: no-cache$endl" . "$endl"; if (defined $proxy) { print SOCK "GET http://$site_host$site_path HTTP/1.1$http_headers"; } else { print SOCK "GET $site_path HTTP/1.1$http_headers"; } unless (read_line() =~ m{HTTP/1\.\d (\d+) \w+}) { &die_net("Invalid HTTP response from http://$site_host$site_path", 0); } my $status = $1; if ($status =~ /^301|302$/ && ++$redirect_depth < 5) { # redirection while (1) { my $line = read_line(); $line =~ s/[\n\r]+$//s; last unless $line; if ($line =~ m{Location: http://([^/]+)(/.*)}i) { $site_host = $1; $site_path = $2; goto HTTP_CONNECTION; } } } &die_net("Unexpected HTTP response $status from http://$site_host$site_path", 0) unless $status eq "200"; # skip http response headers while (read_line() !~ /^\r?\n?$/s) {} } else { if ($fake_filename) { $fake_filename =~ s:^~(/|$):$home$1:; } else { $fake_filename = "$work_home/$site.in"; } open(SOCK, "<$fake_filename") || &die_sys("Can't open $fake_filename"); } my $entries = &$site_func; close(SOCK) || &die_net("Error closing socket"); foreach (@$entries) { my $text = &expand_all_width_specifiers($itemf, $_); my $comm = &expand_all_width_specifiers($commf, $_); $text =~ s/"/\\"/g; $content .= qq(+ "$iconi_str$text" $comm\n); } if (defined $frontpage && $frontpage =~ /^b/) { $content .= qq(+ "" Nop\n$frontpage_entry); } if (defined $menu_filename) { unless (-d $work_home) { mkdir($work_home, 0775) || &die_sys("Can't create $work_home"); } open(MENU_FILE, ">$menu_filename") || &die_sys("Can't open $menu_filename"); print MENU_FILE $content; close(MENU_FILE) || &die_sys("Can't close $menu_filename"); } else { print $content; } exit(); # --------------------------------------------------------------------------- sub read_line { local $SIG{ALRM} = sub { die "timeout\n"; }; alarm($timeout); my $line = eval { }; if ($@) { &die_net("Timeout of $timeout seconds reached") if $@ eq "timeout\n"; &die_net($@); } alarm(0); print STDERR $line if $ENV{"DEBUG_DUMP_RESPONSE"}; return $line; } sub read_all_lines { local $SIG{ALRM} = sub { die "timeout\n"; }; alarm($timeout * 2); my $lines = eval { join('', ) }; if ($@) { &die_net("Timeout of $timeout seconds reached") if $@ eq "timeout\n"; &die_net($@); } alarm(0); print STDERR $lines if $ENV{"DEBUG_DUMP_RESPONSE"}; return $lines; } # make unix time from year (2001 or 101), mon (0..11), day, hour, min, sec sub make_time { # ($$$$$$$) my ($h_offset, $year, $mon, $day, $hour, $min, $sec) = @_; $h_offset ||= 0; my $type = $TIMEFIELDS_DATE_TIME; unless (defined $hour || defined $min) { unless ($year || $day) { $type = $TIMEFIELDS_NONE; return [ 0, $type ]; } else { $type = $TIMEFIELDS_ONLY_DATE; } } $year = 1973 unless $year && $year > 0; # it's my year :-) $mon = 0 unless $mon && $mon > 0 && $mon <= 11; $day = 1 unless $day && $day > 0 && $day <= 31; $hour = 12 unless $hour && $hour >= 0 && $hour < 24; $min = 0 unless $min && $min >= 0 && $min < 60; $sec = 0 unless $sec && $sec >= 0 && $sec < 60; return [ timegm($sec, $min, $hour, $day, $mon, $year) - $h_offset * 60 * 60, $type ]; } sub set_entry_aliases_and_time ($$$$) { my $entry = shift; my $aliases = shift; my $time_func = shift; my $h_offset = shift; my ($alias, $orig); while (($alias, $orig) = each %$aliases) { $entry->{$alias} = !$orig ? "" : ref($orig) eq 'CODE' ? &{$orig}($entry) : $entry->{$orig}; $entry->{$alias} = "" unless defined $entry->{$alias}; } $entry->{'_'} = make_time($h_offset, &{$time_func}($entry->{'d'})); } BEGIN { $entity_map = { 'gt' => '>', 'lt' => '<', 'quot' => '"', 'amp' => '&', }; } sub process_xml ($$$$) { my $entry_tag = shift; my $aliases = shift; my $time_func = shift; my $h_offset = shift; my @entries = (); my $doc = read_all_lines(); ENTRY: foreach ($doc =~ m!<$entry_tag\b[^>]*>(.*?)!sg) { s/&quot;/"/g; # fix buggy html in some backends # replace ' with single quote and " with double quote s/&(?:(\w+)|#(\d{2,})|#x([\da-fA-F]{2,4}));/ $1 ? $entity_map->{$1} || "{$1}" : chr($2 || hex($3)) /ge; my $entry = {}; foreach (m!(<.*?>.*?)!sg) { m!<(.*?)>\s*(.*?)\s*!s; # ignore incorect fields or throw error? next unless $1 && $2 && $3; next if $1 ne $3; $entry->{$1} = $2; } set_entry_aliases_and_time($entry, $aliases, $time_func, $h_offset); push @entries, $entry; } return \@entries; } sub process_text ($$$$) { my $fields = shift; my $aliases = shift; my $time_func = shift; my $h_offset = shift; my @entries = (); ENTRY: while (1) { my $entry = {}; foreach (@$fields) { my $line = read_line(); last ENTRY unless defined $line; next if $_ eq '_ignore_'; chomp($line); $line =~ s/"/\\"/g; # $line =~ s/<.*?>//g; # $line =~ s/&\w{1,5}?;/ /g; $entry->{$_} = $line; } set_entry_aliases_and_time($entry, $aliases, $time_func, $h_offset); push @entries, $entry; } return \@entries; } sub process_slashdot () { return process_xml( 'story', { 'h' => 'title', 'u' => 'url', 'd' => 'time' }, sub ($) { $_[0] =~ /(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/; ($1, ($2 || 0) - 1, $3, $4, $5, $6); }, +0, ); } sub process_freshmeat () { return process_text( [ qw( headline date url ) ], { 'h' => 'headline', 'u' => 'url', 'd' => 'date' }, sub ($) { $_[0] =~ /^(?:\w+, )?(\w+) (\d+)\w* (\d+),? (\d+):(\d+)/; ($3, $lmonth_hash{$1}, $2, $4, $5, 0); }, -5 + (abs((localtime())[4] - 5.5) < 3), ); } sub process_linuxtoday () { my $line; while ($line = read_line()) { last if $line =~ /linuxtoday.com/; # skip the text note last if $line =~ /&&/ and read_line() x 3; # if it was replaced } return process_text( [ qw( _ignore_ headline url date ) ], { 'h' => 'headline', 'u' => 'url', 'd' => 'date' }, sub ($) { $_[0] =~ /(\w+) (\d+), (\d+), (\d+):(\d+):(\d+)/; ($3, $smonth_hash{$1}, $2, $4, $5, $6); }, +0, ); } sub process_segfault () { my $line; while ($line = read_line()) { last if $line =~ /^%%/; # skip the text note } return process_text( [ qw( headline url date author_name author_email type _ignore_ ) ], { 'h' => 'headline', 'u' => 'url', 'd' => 'date' }, sub ($) { $_[0] =~ /(\d+) (\w+) (\d+):(\d+):(\d+) (\d+)/; ($6, $smonth_hash{$2}, $1, $3, $4, $5); }, -8 + (abs((localtime())[4] - 5.5) < 3), ); } sub process_poor_rdf () { return process_xml( 'item', { 'h' => 'title', 'u' => 'link', 'd' => undef }, sub ($) { # this site's rdf does not supply the time, how weird... #(gmtime())[5,4,3,2,1,0]; () }, +0, ); } sub process_linuxapps_old () { return process_text( [ qw( headline date url ) ], { 'h' => 'headline', 'u' => 'url', 'd' => 'date' }, sub ($) { $_[0] =~ /(\w+) (\d+) (\d+):(\d+):(\d+) \w+ (\d+)/; ($6, $smonth_hash{$1}, $2, $3, $4, $5); }, -5, ); } sub process_kde_news () { my $link_to_time = sub ($) { $_[0]->{'link'} =~ m|/(\d+)/?$|; $1; }; return process_xml( 'item', { 'h' => 'title', 'u' => 'link', 'd' => $link_to_time }, sub ($) { (gmtime($_[0]))[5,4,3,2,1,0]; }, +0, ); } sub process_freekde () { my $link_to_date = sub ($) { $_[0]->{'link'} =~ m|/(\d\d/\d\d/\d\d)/|; $1 ? "20$1" : ''; }; return process_xml( 'item', { 'h' => 'title', 'u' => 'link', 'd' => $link_to_date }, sub ($) { $_[0] =~ m|(\d+)/(\d+)/(\d+)|; ($1, ($2 || 0) - 1, $3); }, +0, ); } sub process_rootprompt () { my $title_stripped = sub ($) { $_[0]->{'title'} =~ /(.*) \([^\(\)]+\)$/ ? $1 : $_[0]->{'title'}; }; my $title_to_date = sub ($) { $_[0]->{'title'} =~ / \((\d+ \w{3} \d{4})\)$/; $1; }; return process_xml( 'item', { 'h' => $title_stripped, 'u' => 'link', 'd' => $title_to_date }, sub ($) { $_[0] =~ /(\d+) (\w+) (\d+)/; ($3, $smonth_hash{$2}, $1); }, +0, ); } sub process_kuro5hin () { my $link_to_date = sub ($) { $_[0]->{'link'} =~ m|/(\d\d\d\d/\d{1,2}/\d{1,2})/|; $1; }; return process_xml( 'item', { 'h' => 'title', 'u' => 'link', 'd' => $link_to_date }, sub ($) { $_[0] =~ m|(\d+)/(\d+)/(\d+)|; ($1, ($2 || 0) - 1, $3); }, +0, ); } sub process_linuxfr () { my $link_to_date = sub ($) { $_[0]->{'link'} =~ m|/(\d\d\d\d/\d\d/\d\d)/|; $1; }; my $hack_for_url = sub ($) { # hack for mozilla -remote openURL my $u = $_[0]->{'link'}; $u =~ s|,|\%2c|g; $u; }; return process_xml( 'item', { 'h' => 'title', 'u' => $hack_for_url, 'd' => $link_to_date }, sub ($) { $_[0] =~ m|(\d+)/(\d+)/(\d+)|; ($1, ($2 || 0) - 1, $3); }, +0, ); } sub process_linuxfr_old () { my $link_to_date = sub ($) { $_[0]->{'url'} =~ m|/(\d\d\d\d/\d\d/\d\d)/|; $1; }; my $hack_for_url = sub ($) { # hack for mozilla -remote openURL my $u = $_[0]->{'url'}; $u =~ s|,|\%2c|g; $u; }; my $line; while ($line = read_line()) { last if $line =~ /^%%/; # skip the text note } return process_text( [ qw( headline url author_name author_email type _ignore_ ) ], { 'h' => 'headline', 'u' => $hack_for_url, 'd' => $link_to_date }, sub ($) { $_[0] =~ m|(\d+)/(\d+)/(\d+)|; ($1, ($2 || 0) - 1, $3); }, +0, ); } sub process_cnn () { my $contents = read_all_lines(); my @entries = (); my $link_to_date = sub ($) { $_[0]->{'url'} =~ m|/(\d\d\d\d).*?(/\d\d/\d\d)/|; "$1$2"; }; $contents =~ s{(.*?)}{ my $entry = {}; $entry->{'url'} = "http://www.cnn.com$1"; $entry->{'headline'} = $2; set_entry_aliases_and_time( $entry, { 'h' => 'headline', 'u' => 'url', 'd' => $link_to_date }, sub ($) { $_[0] =~ m|(\d+)/(\d+)/(\d+)| ? ($1, ($2 || 0) - 1, $3) : (); }, -5, ); push @entries, $entry; "" }sige; return \@entries; } sub process_old_bbc () { my $contents = read_all_lines(); $contents =~ s!\r\n...\r\n!!sg; # they insert this randomly! $contents =~ s!\s*<(br|/h3|h3|span[^>]*|/span|img [^>]+)>[ \t\r]*\n?!!sig; my @entries = (); $contents =~ s{\s+\s*([^\s][^<]+?)\s*\s*([^<]+?)\s*(?:\n|
    {'headline'} = $2; $entry->{'abstract'} = $3; $path =~ s|^(/\d+)?/low/|$1/hi/|; $entry->{'url'} = "http://news.bbc.co.uk$path"; set_entry_aliases_and_time( $entry, { 'h' => 'headline', 'u' => 'url', 'd' => undef }, sub ($) { (); # no time... }, +0, ); push @entries, $entry; "" }sige; return \@entries; } sub process_bcc () { read_all_lines() =~ /STORY 1\nHEADLINE Last update at (\d+:\d+)\nURL \n(.*)$/s; my ($time, $contents) = ($1, $2); die_net("Parse error. Did BBC site change format?", "") unless defined $time; my @entries = (); $contents =~ s{STORY (\d+)\nHEADLINE (.*?)\nURL (.*?)\n}{ my $entry = {}; my $date = undef; $entry->{'story'} = $1; my $headline = $2; my $url = $3; if ($headline =~ /^(.+?) (\d+ \w+ \d+)$/) { $headline = $1; $date = $2 . " $time"; } $entry->{'headline'} = $headline; $url =~ s|^(http://.*?/).*/-/(.*)$|$1$2|; $url = "http://news.bbc.co.uk/" if $url eq ""; $entry->{'url'} = $url; $entry->{'date'} = $date; set_entry_aliases_and_time( $entry, { 'h' => 'headline', 'u' => 'url', 'd' => 'date' }, sub ($) { return () unless defined $_[0] && $_[0] =~ /^(\d+) (\w+) (\d+) (\d+):(\d+)/; ($3, $lmonth_hash{$2}, $1, $4, $5); }, +0, ); push @entries, $entry; "" }sige; return \@entries; } # --------------------------------------------------------------------------- sub die_sys ($) { my $msg = shift; $msg = "$0: $msg: [$!]\n"; print STDERR $msg # # be quiet in non interactive shells? # if ($ENV{'SHLVL'} || 0) == 1 || defined($ENV{'PS1'}) ; exit(-1); } sub die_net ($;$) { my $msg = shift; my $check_network_msg = @_ ? "" : "; check network connection"; #die_sys($msg); $error_menu_content =~ s//$msg$check_network_msg/; print $error_menu_content; exit(-1); } # like strftime, but gets unix time, instead of sec/min/hour/day/mon/year. sub format_time ($$) { my ($fmt, $time_pair) = @_; $time_pair = [] unless ref($time_pair) eq 'ARRAY'; my ($time, $type) = @$time_pair; $time ||= time(); $type ||= $TIMEFIELDS_NONE; if ($type == $TIMEFIELDS_NONE) { return ""; } elsif ($type == $TIMEFIELDS_ONLY_DATE) { $fmt =~ s/[:\. -]?%[HIklMprSTX][:\. -]?//g; $fmt =~ s/%c/%a %b %d %Z %Y/g; } return strftime($fmt, localtime($time)); } # Substitutes all %N1*N2x in $name by properly stripped and justified $values. # $name example: %[%d %b %y %H:%M], %*-7(some text), %-32*30h, %{url}. # $values is a hash of named values to substitute. sub expand_all_width_specifiers ($$) { my ($name, $values) = @_; $name =~ s/%(-?\d+)?(\*(-?)(\d+))?(\w|{\w+}|\(.*?\)|\[.*?\])/ my $tag = substr($5, 0, 1); my $arg = length($5) == 1 ? $5 : substr($5, 1, -1); my $value = $tag eq '(' ? $arg : $tag eq '[' ? format_time($arg, $values->{'_'}) : $values->{$arg}; $value = "(%$5 is not defined)" unless defined $value; $value = !$2 || $4 <= 3 || $4 > length($value) ? $value : $3? "..." . substr($value, -$4 + 3, $4 - 3): substr($value, 0, $4 - 3) . "..."; $1 ? sprintf("%$1s", $value) : $value; /ge; return $name; } sub get_all_site_names () { return sort map { $site_info->{$_}->{'name'} } keys %$site_info; } sub show_help { $site ||= $default_site; #$name ||= "MenuHeadlines$site_info->{$site}->{'name'}"; $name ||= $site; $title ||= "$site_info->{$site}->{'name'} Headlines"; print "A perl script which builds headlines menu for fvwm.\n"; print "Supported sites: ", join(', ', get_all_site_names()), "\n\n"; print "Usage: $0 [OPTIONS]\n"; print "Options:\n"; print "\t--help show this help and exit\n"; print "\t--version show the version and exit\n"; print "\t--info=[NAME] information about a site\n"; print "\t--site=NAME headlines site, default is $site\n"; print "\t--name=NAME menu name, default is '$name'\n"; print "\t--title=NAME menu title, default is '$title'\n"; print "\t--item=FORMAT menu item format, default is '$itemf'\n"; print "\t--exec=FORMAT exec command, default is {$execf}\n"; print "\t--command=FORMAT fvwm command, default is no\n"; print "\t--icon-title=XPM menu title icon, default is no\n"; print "\t--icon-item=XPM menu item icon, default is no\n"; print "\t--icon-home=XPM menu home icon, default is no\n"; print "\t--icon-error=XPM menu error icon, default is no\n"; print "\t--wm-icons define icon names to use with wm-icons\n"; print "\t--frontpage[=V] show frontpage item; values: top, bottom\n"; print "\t--proxy=host[:port] specify proxy host and port (80)\n"; print "\t--file[=FILE] menu file, default is $work_home/$site.menu\n"; print "\t--fake[=FILE] don't connect, read input from file\n"; print "\t--timeout=SECS timeout for a line reading from a socket\n"; print "Short options are ok if not ambiguous: -h, -t.\n"; exit 0; } sub show_version { print "$version\n"; exit 0; } sub wrong_usage { print STDERR "Try '$0 --help' for more information.\n"; exit -1; } __END__ # --------------------------------------------------------------------------- =head1 NAME fvwm-menu-headlines - builds headlines menu definition for fvwm =head1 SYNOPSIS B [ B<--help>|B<-h>|B<-?> ] [ B<--version>|B<-V> ] [ B<--info> [site] ] [ B<--site>|B<-s> site ] [ B<--name>|B<-n> name ] [ B<--title>|B<-t> title ] [ B<--item> item ] [ B<--exec>|B<-e> exec-command ] [ B<--command>|B<-e> fvwm-command ] [ B<--icon-title> icon ] [ B<--icon-item> icon ] [ B<--icon-home> icon ] [ B<--icon-error> icon ] [ B<--wm-icons> ] [ B<--frontpage> [where] ] [ B<--proxy>|B<-p> host:port ] [ B<--file> [file] ] [ B<--fake> [file] ] [ B<--timeout> seconds ] =head1 DESCRIPTION This configurable perl script builds an fvwm menu definition for headlines of popular news web sites: FreshMeat, Slashdot, LinuxToday, DaemonNews, GNOME-News, KDE-News, RootPrompt, LinuxFr, ThinkGeek, CNN, BBC and more. It is possible to specify a customized menu item format, change a command (usually launching a browser) and add menu icons (there is a support for the wm-icons package). =head1 OPTIONS =over 4 =item B<--help> show the help and exit =item B<--version> show the version and exit =item B<--info> [site] if site name is given print the site specific info, otherwise print all site names =item B<--site> site defile a web site, headlines of which to show, this option also can be used together with --help to get new defaults. Default site: freshmeat. =item B<--name> name define menu name (default is "MenuHeadlinesFreshmeat") =item B<--title> title define menu title (default is "Freshmeat Headlines"). =item B<--item> label-format =item B<--exec> command-format define format for menu item or command (what is shown and what is executed when the item is chosen). Default label is '%h\t%[(%Y-%m-%d %H:%M)]'. TAB can be specified as '\t', but in .fvwm2rc you should specify a double backslash or a real TAB. Format specifiers for a headline format: %h - headline %u - url %d - date in the native format (that site backend supplied) %[strftime-argument-string] - date/time, see strftime(3) the date/time is represented according to the local time; date and/or time fields that can't be guessed are stripped Example: %[|%d %B %Y| %H:%M %S] If site supplied only date - this becomes %[|%d %B %Y|], if site supplied no date - this becomes an empty string. %{name} - site specific named value, like %{comments} %(text) - arbitrary text, good for escaping or aligning These specifiers can receive an optional integer size, positive for right adjusted string or negative for left adjusted, example: %8x; and optional *num or *-num, which means to leave only the first or last (if minus) num of chars, the num must be greater than 3, since the striped part is replaced with "...", example: %*30x. Both can be combined: %-10*-20x, this instructs to get only the 20 last characters, but if the length is less then 10 - to fill with up to 10 spaces on the right. Example: --exec "iceweasel -remote 'openURL(%u, new-window)' || iceweasel '%u'" =item B<--command> command-format like B<--exec> above, but enables to specify any fvwm command, for example, "Function FuncFvwmShowURL '%u'" not only Exec. In fact, --exec="mozilla '%u'" is equivalent to --command="Exec mozilla '%u'" =item B<--icon-title> icon =item B<--icon-item> icon =item B<--icon-home> icon =item B<--icon-error> icon define menu icon for title, regular item, frontpage item and error item respectively. Default is no menu icons (equivalent to an empty icon argument). =item B<--wm-icons> define icon names suitable for use with wm-icons package. Currently this is equivalent to: --icon-title '' --icon-item menu/information.xpm --icon-home menu/home.xpm --icon-error menu/choice-no.xpm. =item B<--frontpage> [where] add the site frontpage item to the menu. Optional value can be used to specify where this item will be placed in the menu - 'top' or 't', 'bottom' or 'b'. =item B<--proxy> host[:port] define a proxy to use. Example: --proxy proxy.inter.net:3128 =item B<--file> [file] write the menu output to specified file. If no filename is given with this option (or empty filename), the default filename WORK_HOME/SITE.menu is used. Without this option or with '-' filename, the menu output is written to standard output. =item B<--fake> [file] don't connect to the host using HTTP protocol, instead, read from WORK_HOME/SITE.in file. The following reads input from freshmeat.in (downloaded http://freshmeat.net/backend/recentnews.txt) and saves output to segfault.menu (both files are in WORK_HOME): fvwm-menu-headlines --site freshmeat --fake --file =item B<--timeout> seconds limit a line reading from a socket to this timeout, the default timeout is 20 seconds. =back WORK_HOME of this script is ~/.fvwm/.fvwm-menu-headlines. It is created if needed. Option parameters can be specified either using '=' or in the next argument. Short options are ok if not ambiguous: C<-h>, C<-t>; but be careful with short options, what is now unambiguous, can become ambiguous in the next versions. =head1 USAGE 1. One of the ways to use this script is to define a crontab entry to run the script every hour or so for every monitored site: 0,30 * * * * fvwm-menu-headlines --file --site freshmeat 1,31 * * * * fvwm-menu-headlines --file --site linuxtoday 2,32 * * * * fvwm-menu-headlines --file --site slashdot Then add these lines to your fvwm configuration file: DestroyFunc FuncFvwmMenuHeadlines AddToFunc FuncFvwmMenuHeadlines + I Read "$HOME/.fvwm/.fvwm-menu-headlines/$0.menu" DestroyMenu MenuHeadlines AddToMenu MenuHeadlines "Headlines" Title + MissingSubmenuFunction FuncFvwmMenuHeadlines + "FreshMeat" Popup freshmeat + "LinuxToday" Popup linuxtoday + "Slashdot" Popup slashdot 2. Another way to use this script (only if you have fast network/proxy) is to run it every time you want to open your Headlines submenus. (Note, the submenu that is once created is not reloaded, use "Reset all".) In this case your fvwm configuration lines could be: DestroyFunc FuncFvwmMenuHeadlines AddToFunc FuncFvwmMenuHeadlines + I PipeRead "fvwm-menu-headlines --site $0" #+ I Schedule 900000 DestroyMenu $0 # reset generated menu in 15 minutes DestroyMenu MenuHeadlines AddToMenu MenuHeadlines "Headlines" Title + MissingSubmenuFunction FuncFvwmMenuHeadlines + "FreshMeat" Popup freshmeat + "Slashdot" Popup slashdot + "LinuxToday" Popup linuxtoday + "GNOME News" Popup gnome-news + "KDE News" Popup kde-news + "" Nop + "Reset all" FuncResetHeadlines DestroyFunc FuncResetHeadlines AddToFunc FuncResetHeadlines + I DestroyMenu freshmeat + I DestroyMenu linuxtoday + I DestroyMenu slashdot + I DestroyMenu gnome-news + I DestroyMenu kde-news And finally, add "Popup MenuHeadlines" somewhere. 3. Here is a usual usage. Use FvwmConsole or FvwmCommand to run fvwm commands from a shell script. Every time you want headlines from some site, execute (give any additional options if you want): PipeRead "fvwm-menu-headlines --site newsforge --name MenuHeadlinesNewsForge" # this may take several seconds, you may use: BusyCursor Read true Popup MenuHeadlinesNewsForge =head1 HOW TO ADD SITE HEADLINES It is possible to add user defined site headlines without touching the script itself. Put your perl extensions to the file WORK_HOME/extension.pl. For each site add something similar to: $site_info->{'myslashdot'} = { 'name' => "MySlashdot", 'host' => "myslashdot.org", 'path' => "/myslashdot.xml", 'func' => \&process_my_slashdot, # the following string is only used in --info 'flds' => 'time, title, department, topic, author, url', }; sub process_my_slashdot () { return process_xml( 'story', # mandatory 'h', 'u' and 'd' aliases or undef { 'h' => 'title', 'u' => 'url', 'd' => 'time' }, sub ($) { # convert 'd' string to (y, m, d, H, M, S) $_[0] =~ /(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/; ($1, ($2 || 0) - 1, $3, $4, $5, $6); }, +0, # timezone offset; already in UTC ); } 1; =head1 AUTHORS This script is inspired by WMHeadlines v1.3 by: Jeff Meininger (http://rive.boxybutgood.com/WMHeadlines/). Reimplemented for fvwm and heavily enhanced by: Mikhael Goikhman , 16 Dec 1999. =head1 COPYING The script is distributed by the same terms as fvwm itself. See GNU General Public License for details. =head1 BUGS I try to keep all supported site info up to date, but sites often go down, change their backend formats, change their httpd responses, just stop to post news and so on; the script in the latest cvs may be more up to date. The headline times may be off by one hour or more, since the time is displayed for your local time zone, and the time zone of the original time in the site backend output is often guessed (sometimes incorrectly); similarly it is guessed whether to apply the daylight saving correction. Report bugs to fvwm-bug@fvwm.org. =cut # =========================================================================== fvwm-2.6.7/bin/fvwm-config.1.in0000644000175700017570000000611112673746443013144 00000000000000.\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .ta .3i .6i .9i 1.2i 1.5i 1.8i .TH fvwm-config 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME fvwm-config \- query an existing fvwm installation .SH SYNOPSIS .B fvwm-config .RI [ --help ] .RI [ --version ] .RI [ --info ] .RI [ --prefix ] .RI [ --exec-prefix ] .RI [ --bindir ] .RI [ --datadir ] .RI [ --libexecdir ] .RI [ --sysconfdir ] .RI [ --mandir ] .RI [ --localedir ] .RI [ --fvwm-moduledir ] .RI [ --fvwm-datadir ] .RI [ --fvwm-perllibdir ] .RI [ --default-imagepath ] .RI [ --default-userdir ] .RI [ --fvwm-exe ] .RI [ --supports ] .RI [ --supports- ] .SH DESCRIPTION .B fvwm-config is a shell script that provides an information about the fvwm version, installation directories, built-in paths and supported features. .SH OPTIONS .B fvwm-config prints to the standard output in all options. Both short and long GNU-like option names may be used. .TP .B -h --help -? prints the short usage .TP .B -v --version -V prints the version .TP .B -i --info prints the full info page .TP .B -P --prefix prints the installation prefix .TP .B -E --exec-prefix prints the installation exec-prefix .TP .B -B --bindir prints the installation bindir .TP .B -D --datadir prints the installation datadir .TP .B -L --libexecdir prints the installation libexecdir .TP .B -S --sysconfdir prints the installation sysconfdir .TP .B -M --mandir prints the installation mandir .TP .B -O --localedir prints the installation localedir .TP .B -m --fvwm-moduledir prints FVWM_MODULEDIR, where the modules are installed .TP .B -d --fvwm-datadir prints FVWM_DATADIR, where the system wide configs are installed .TP .B -p --fvwm-perllibdir prints FVWM_PERLLIBDIR, where the perl library is installed .TP .B -I --default-imagepath prints the built-in ImagePath .TP .B -U --default-userdir prints the default FVWM_USERDIR, note: $HOME is not expanded .TP .B -e --fvwm-exe prints the fvwm executable name (in bindir) .TP .B -s --supports lists all supported features, one per line .TP .BI --supports- prints nothing, returns: 0 if the .I is supported, 100 if not, 200 if unknown. All or supported feature names may be found using .IR --info " or " --supports respectively. .TP .SH USAGE Here are some real life usages. Checks for xft support: .EX if fvwm-config --supports-xft; then echo 1; else echo 0; fi .EE .I fvwm-themes package checks for the correct .I fvwm version installed using: .EX fvwm-config --version .EE and tries to use the same installation directories: .EX fvwm-config --bindir --mandir --fvwm-datadir .EE A way to find the full path to the fvwm executable: .EX echo `fvwm-config --bindir`/`fvwm-config --fvwm-exe` .EE A way to start modules in perl: .EX use lib `fvwm-config -p | tr -d '\n'`; use FVWM::Module; .EE For a more human readable output, try: .EX fvwm-config --info .EE .SH COPYING .B fvwm-config is a part of fvwm package and distributed by the same terms, see GNU GPL. .SH AUTHOR Mikhael Goikhman fvwm-2.6.7/bin/fvwm-bug.1.in0000644000175700017570000000274612673746443012466 00000000000000.\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH fvwm-bug 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .SH NAME fvwm-bug \- report a bug in fvwm .SH SYNOPSIS \fBfvwm-bug\fP [\fI--help\fP] [\fI--version\fP] [\fIaddress\fP] .SH DESCRIPTION .B fvwm-bug is a shell script to help the user compose and mail bug reports concerning fvwm in a standard format. .B fvwm-bug invokes the editor specified by the environment variable .SM .B EDITOR on a temporary copy of the bug report format outline. The user must fill in the appropriate fields and exit the editor. .B fvwm-bug then mails the completed report to the local fvwm maintainer, the fvwm workers list \fIfvwm-workers@fvwm.org\fP, or \fIaddress\fP. If the report cannot be mailed, it is saved in the file \fIdead.fvwm-bug\fP in the invoking user's home directory. .PP The bug report format outline consists of several sections. The first section provides information about the machine, operating system, the fvwm version, and the compilation environment. The second section should be filled in with a description of the bug. The third section should be a description of how to reproduce the bug. The optional fourth section is for a proposed fix. Fixes are encouraged. .SH ENVIRONMENT .B fvwm-bug will utilize the following environment variables if they exist: .TP .B EDITOR Specifies the preferred editor. If .SM .B EDITOR is not set, .B fvwm-bug defaults to .BR emacs . .TP .B HOME Directory in which the failed bug report is saved if the mail fails. fvwm-2.6.7/bin/fvwm-menu-directory.10000644000175700017570000003631712673746443014253 00000000000000.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.02) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "fvwm-menu-directory 1" .TH fvwm-menu-directory 1 "2009-03-22" "2.5.28 (from cvs)" "Fvwm Utilities" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" fvwm\-menu\-directory \- builds a directory browsing menu for fvwm .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBfvwm-menu-directory\fR [ \fB\-\-help\fR|\fB\-h\fR|\fB\-?\fR ] [ \fB\-\-version\fR|\fB\-V\fR ] [ \fB\-\-name\fR|\fB\-na\fR \s-1NAME\s0 ] [ \fB\-\-title\fR|\fB\-t\fR \s-1NAME\s0 ] [ \fB\-\-item\fR|\fB\-it\fR \s-1NAME\s0 ] [ \fB\-\-icon\-title\fR|\fB\-icon\-t\fR \s-1XPM\s0 ] [ \fB\-\-icon\-dir\fR|\fB\-icon\-d\fR \s-1XPM\s0 ] [ \fB\-\-icon\-file\fR|\fB\-icon\-f\fR \s-1XPM\s0 ] [ \fB\-\-icon\-app\fR|\fB\-icon\-a\fR \s-1XPM\s0 ] [ \fB\-\-wm\-icons\fR ] [ \fB\-\-dir\fR|\fB\-d\fR \s-1NAME\s0 ] [ \fB\-\-order\fR|\fB\-o\fR \s-1NUM\s0 ] [ \fB\-\-[no]all\fR|\fB\-a\fR ] [ \fB\-\-[no]links\fR|\fB\-l\fR ] [ \fB\-\-xterm\fR|\fB\-x\fR \s-1CMD\s0 ] [ \fB\-\-exec\-title\fR|\fB\-exec\-t\fR \s-1CMD\s0 ] [ \fB\-\-exec\-file\fR|\fB\-exec\-f\fR \s-1CMD\s0 ] [ \fB\-\-exec\-app\fR|\fB\-exec\-a\fR [\s-1CMD\s0] ] [ \fB\-\-command\-title\fR|\fB\-command\-t\fR \s-1CMD\s0 ] [ \fB\-\-command\-file\fR|\fB\-command\-f\fR \s-1CMD\s0 ] [ \fB\-\-command\-app\fR|\fB\-command\-a\fR \s-1CMD\s0 ] [ \fB\-\-[no]reuse\fR|\fB\-r\fR ] [ \fB\-\-[no]check\-subdirs\fR|\fB\-ch\fR ] [ \fB\-\-special\-dirs\fR|\fB\-s\fR [\s-1VALUE\s0] ] [ \fB\-\-[no]memory\-for\-speed\fR|\fB\-mem\fR ] [ \fB\-\-menu\-style\fR|\fB\-men\fR \s-1NAME\s0 ] [ \fB\-\-func\-name\fR|\fB\-f\fR \s-1NAME\s0 ] .SH "DESCRIPTION" .IX Header "DESCRIPTION" A perl script which provides an output to read in with PipeRead to build an fvwm menu containing a directory listing. Almost everything can be configured. .SH "HINTS" .IX Header "HINTS" The title item with its own attached action is usually added to the menu. This may be used to define an action for the directory for which the menu is built, such as starting a terminal in this directory (the default). However, this may annoy some users. To disable the title action use \fB\-\-command\-title\fR "", to remove the title completely use \fB\-\-title\fR "". .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-\-help\fR" 4 .IX Item "--help" show the usage and exit .IP "\fB\-\-version\fR" 4 .IX Item "--version" show version and exit .IP "\fB\-\-name\fR name" 4 .IX Item "--name name" menu name, used only with \-\-reuse, default is MenuBrowser .IP "\fB\-\-title\fR title" 4 .IX Item "--title title" menu title format, default is '%*\-40p' \- last 40 characters of the current full path. \s-1TAB\s0 can be specified as '\et', but in .fvwm2rc you should specify a double backslash or a real \s-1TAB\s0. .Sp Format specifiers: \f(CW%d\fR \- the current directory name \f(CW%p\fR \- the current directory full path .Sp These specifiers can receive an optional integer size, positive for right adjusted string or negative for left adjusted, example: \f(CW%8x\fR; and optional *num or *\-num, which means to leave only the first or last (if minus) num of chars, the num must be greater than 3, since the striped part is replaced with \*(L"...\*(R", example: %*30x. Both can be combined: %\-10*\-20x, this instructs to get only the 20 last characters, but if the length is less then 10 \- to fill with up to 10 spaces on the right. .IP "\fB\-\-item\fR format" 4 .IX Item "--item format" menu item format, default is '%n'. \s-1TAB\s0 and width modifiers for \f(CW%n\fR, \f(CW%N\fR and \f(CW%s\fR can be specified as described in \fB\-\-title\fR above. Note, specifying a non default format slows the script. .Sp Format specifiers: .Sp .Vb 7 \& %n \- file/dir name (without the path) \& %N \- file/dir name (full with the path) \& %d \- file/dir date (yyyy\-mm\-dd HH:MM:SS) \& %D \- file/dir date (yyyy\-mm\-dd) \& %s \- file/dir size (in bytes) \& %t \- file/dir type (File|Dir |Link|Sock|Blck|Char|Pipe) \& %T \- file/dir type (F|D|L|S|B|C|P) .Ve .Sp Example: \-\-title '%*\-40p\etDate, Type\etSize' \-\-item '%*40n\et%d \f(CW%t\fR\et%s' .IP "\fB\-\-icon\-title\fR icon" 4 .IX Item "--icon-title icon" menu title icon, default is none .IP "\fB\-\-icon\-dir\fR icon" 4 .IX Item "--icon-dir icon" menu dir icon, default is none .IP "\fB\-\-icon\-file\fR icon" 4 .IX Item "--icon-file icon" menu file icon, default is none .IP "\fB\-\-icon\-app\fR icon" 4 .IX Item "--icon-app icon" menu application icon, default is none .IP "\fB\-\-wm\-icons\fR" 4 .IX Item "--wm-icons" define icon names suitable for use with wm-icons package. Currently this is equivalent to: \-\-icon\-title menu/folder\-open.xpm \-\-icon\-item menu/file.xpm \-\-icon\-dir menu/folder.xpm \-\-icon\-app menu/utility.xpm. .IP "\fB\-\-dir\fR dir" 4 .IX Item "--dir dir" starting dir, default is ${\s-1HOME\-\s0.} .IP "\fB\-\-order\fR number" 4 .IX Item "--order number" in the range (\-6 .. 6), default is 5: .Sp .Vb 3 \& 1 \- do not sort, 2 \- dirs first, 3 \- files first \& 4 \- sort by name, 5 \- dirs first, 6 \- files first \& Negative number represents reverse order. .Ve .IP "\fB\-\-[no]all\fR" 4 .IX Item "--[no]all" show hidden files, like in 'ls \-A', default is \-\-noall .IP "\fB\-\-[no]links\fR" 4 .IX Item "--[no]links" follow linked directories, default is \-\-nolinks .IP "\fB\-\-xterm\fR command" 4 .IX Item "--xterm command" X terminal call, default is 'xterm \-e' .IP "\fB\-\-exec\-title\fR command" 4 .IX Item "--exec-title command" an fvwm Exec command on directory title (usually the shell), default is ${SHELL\-/bin/sh}. '\-' means no Exec command, i.e. Nop. If the command is not started with '^' X terminal call is prepended. The command is started in the currently browsed directory. .IP "\fB\-\-exec\-file\fR command" 4 .IX Item "--exec-file command" an fvwm Exec command on regular files, default is ${EDITOR\-vi}. '\-' means no Exec command, i.e. Nop. If the command is not started with '^' X terminal call is prepended. The actual file name is appended to the command. .IP "\fB\-\-exec\-app\fR [command]" 4 .IX Item "--exec-app [command]" an fvwm Exec command on +x files, default is '\-', which means the same command as on regular files. If no command is given, it is assumed to be empty \- simply run the +x file. If the command is not started with '^' X terminal call is prepended. The actual file name is appended to the command. .IP "\fB\-\-command\-title\fR command" 4 .IX Item "--command-title command" an fvwm command to execute on title. If this option is not given (or command is '\-'), the \f(CW\*(C`\-\-exec\-title\*(C'\fR is used instead. In the command, \f(CW%d\fR is substituted with the full directory path. .Sp In fact, \fI\-\-exec\-title=tcsh\fR is equivalent to \fI\-\-command\-title='Exec cd \*(L"%d\*(R"; xterm \-e tcsh'\fR .Sp The empty value disables the title action. .IP "\fB\-\-command\-file\fR command" 4 .IX Item "--command-file command" an fvwm command to execute on regular files. If this option is not given (or command is '\-'), the \f(CW\*(C`\-\-exec\-file\*(C'\fR is used instead. In the command, \f(CW%f\fR is substituted with the full file path. .Sp In fact, \-\-exec\-file=vi is equivalent to \-\-command\-file='Exec xterm \-e vi \*(L"%f\*(R"' .IP "\fB\-\-command\-app\fR command" 4 .IX Item "--command-app command" an fvwm command to execute on +x files. If this option is not given (or command is '\-'), the \f(CW\*(C`\-\-command\-app\*(C'\fR is used instead. In the command, \f(CW%f\fR is substituted with the full file path. .Sp In fact, \-\-exec\-app=^exec is equivalent to \-\-command\-app='Exec exec \*(L"%f\*(R"' .IP "\fB\-\-[no]reuse\fR" 4 .IX Item "--[no]reuse" no pop-up menus, reuse the same menu, default is \-\-noreuse. When you specify this option the Menu action is used, not Popup. Also, the \-\-name parameter is not ignored, and \-\-dir parameter is ignored if there is ~/.fvwm/.fvwm\-menu\-directory.dir file. This file is only created or used with this option specified, it is the only solution for the current fvwm menu state. .IP "\fB\-\-[no]check\-subdirs\fR" 4 .IX Item "--[no]check-subdirs" check all subdirs for having execute (+x) permission and replace \*(L"Popup\*(R"/\*(L"Menu\*(R" command with \*(L"Nop\*(R" for these without permissions. This has a visual effect of disabling popup triangle in the subdirectory item. The default is \-\-nocheck\-subdirs, because: 1) enabling this slows a bit the script, 2) with this option enabled, if no icons used and no dir/file separate sorting used there is no way to know that the item is directory and not file. .IP "\fB\-\-special\-dirs\fR value" 4 .IX Item "--special-dirs value" add .. or ~ or / special directories according to given optional value. Without with option these directories are not added. Default value if not specified is \*(L"1,2\*(R". The value is comma separated ordered special directory indexes, where 1 is parent directory, 2 is home directory, 3 is root directory. If minus is prepended to the value, special directories are added at the bottom of menu instead of top. Value \*(L"0\*(R" or any bad value is equivalent to non-specifying this option at all. .IP "\fB\-\-[no]memory\-for\-speed\fR" 4 .IX Item "--[no]memory-for-speed" use speed optimization, i.e. use previously created directory menus without destroying it when closed, default is \-\-nomemory\-for\-speed .Sp .Vb 2 \& Warning: speed optimization takes up a lot of memory \& that is never free\*(Aqd again while fvwm is running. .Ve .IP "\fB\-\-menu\-style\fR name" 4 .IX Item "--menu-style name" assign MenuStyle name to the menus .IP "\fB\-\-func\-name\fR name" 4 .IX Item "--func-name name" overwrite the default MissingSubmenuFunction name that is \*(L"FuncFvwmMenuDirectory\*(R" .PP Option parameters can be specified either using '=' or in the next argument. Short options are ok if not ambiguous: \f(CW\*(C`\-a\*(C'\fR, \f(CW\*(C`\-x\*(C'\fR, \f(CW\*(C`\-icon\-f\*(C'\fR; but be careful with short options, what is now unambiguous, can become ambiguous in the next versions. .SH "USAGE" .IX Header "USAGE" Put this into your fvwm configuration file to invoke the script: .PP .Vb 2 \& AddToFunc FuncFvwmMenuDirectory \& + I PipeRead "fvwm\-menu\-directory \-d \*(Aq$0\*(Aq" .Ve .PP More complex example: .PP .Vb 4 \& # AddToFunc FuncFvwmMenuDirectory \& # + I PipeRead "fvwm\-menu\-directory \-d \*(Aq$0\*(Aq \-x \*(AqEterm \-g 80x40 \-e\*(Aq \e\e \& \-a \-l \-o 6 \-\-exec\-app \-\-exec\-title \*(Aqtcsh \-l\*(Aq \-\-exec\-file \*(Aqvim \-R\*(Aq \e\e \& \-t \*(AqGo to: %d\*(Aq \-\-wm\-icons" .Ve .PP And put this in the menu from which you want to pop-up the directory menus: .PP .Vb 3 \& AddToMenu SomeMenu MissingSubmenuFunction FuncFvwmMenuDirectory \& + "Home Directory" Popup $[HOME] \& + "Httpd Directory" Popup /home/httpd .Ve .PP Note: please use absolute path names. .PP It is a good idea to set the menu pop-up delay to something positive and enable busy cursor .PP .Vb 2 \& MenuStyle * PopupDelayed, PopupDelay 200 \& BusyCursor DynamicMenu True .Ve .PP in your configuration file when using this script for better results. .PP Another interesting usage (\f(CW\*(C`\-\-reuse\*(C'\fR or \f(CW\*(C`\-r\*(C'\fR is mandatary for this): .PP .Vb 4 \& AddToMenu Browser \& + DynamicPopupAction PipeRead \e\e \& "fvwm\-menu\-directory \-r \-na Browser \-d / \-s" \& AddToMenu SomeMenu "My Browser" Menu Browser .Ve .PP Here the \f(CW\*(C`\-\-dir\*(C'\fR parameter (starting directory) is ignored if there is ~/.fvwm/.fvwm\-menu\-directory.dir file, which you can delete. .SH "AUTHORS" .IX Header "AUTHORS" Inspired on 1999\-06\-07 by Dominik Vogt . .PP Rewritten on 1999\-08\-05 by Mikhael Goikhman . .SH "COPYING" .IX Header "COPYING" The script is distributed by the same terms as fvwm itself. See \s-1GNU\s0 General Public License for details. .SH "BUGS" .IX Header "BUGS" Report bugs to fvwm\-bug@fvwm.org. fvwm-2.6.7/bin/fvwm-config.in0000644000175700017570000001451012754306001012765 00000000000000#!/bin/sh # Querying fvwm installation. Author: Mikhael Goikhman. # 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 PACKAGE="@PACKAGE@" VERSION="@VERSION@" script=`basename $0` usage() { cat <] return: 0 (yes), 100 (no), 200 (unknown) EOF exit $1 } if test $# -eq 0; then usage 1 1>&2 fi prefix="@prefix@" exec_prefix="@exec_prefix@" bindir="@bindir@" datarootdir="@datarootdir@" datadir="@datadir@" libexecdir="@libexecdir@" sysconfdir="@sysconfdir@" mandir="@mandir@" localedir="@LOCALEDIR@" fvwm_moduledir="@FVWM_MODULEDIR@" fvwm_datadir="@FVWM_DATADIR@" fvwm_perllibdir="@FVWM_PERLLIBDIR@" fvwm_imagepath="@FVWM_IMAGEPATH@" fvwm_userdir='$HOME/.fvwm' fvwm_exe='fvwm' VERSIONINFO="@VERSIONINFO@" release_date="@RELDATENUM@" with_bidi=@with_bidi@ with_gettext=@with_gettext@ with_gdkimlib=@with_gdkimlib@ with_gnomelibs=@with_gnomelibs@ with_iconv=@with_iconv@ with_perllib=@with_perllib@ with_png=@with_png@ with_readline=@with_readline@ with_rplay=@with_rplay@ with_rsvg=@with_rsvg@ with_shape=@with_shape@ with_shm=@with_shm@ with_sm=@with_sm@ with_stroke=@with_stroke@ with_xcursor=@with_xcursor@ with_xinerama=@with_xinerama@ with_xft=@with_xft@ with_xpm=@with_xpm@ with_xrender=@with_xrender@ while test $# -gt 0; do case "$1" in --help|-help|-h|-\?) usage 0 ;; --version|-version|-v|-V) echo "$VERSION" ;; --prefix|-prefix|-P) echo "$prefix" ;; --exec-prefix|-exec-prefix|-E) echo "$exec_prefix" ;; --bindir|-bindir|-B) echo "$bindir" ;; --datarootdir|-datarootdir) echo "$datarootdir" ;; --datadir|-datadir|-D) echo "$datadir" ;; --libexecdir|-libexecdir|-L) echo "$libexecdir" ;; --sysconfdir|-sysconfdir|-S) echo "$sysconfdir" ;; --mandir|-mandir|-M) echo "$mandir" ;; --localedir|-localedir|-O) echo "$localedir" ;; --fvwm-moduledir|-fvwm-moduledir|-m) echo "$fvwm_moduledir" ;; --fvwm-datadir|-fvwm-datadir|-d) echo "$fvwm_datadir" ;; --fvwm-perllibdir|-fvwm-perllibdir|--perllibdir|-perllibdir|-p) echo "$fvwm_perllibdir" ;; --default-imagepath|-default-imagepath|-I) echo "$fvwm_imagepath" ;; --default-userdir|-default-userdir|-U) echo "$fvwm_userdir" ;; --fvwm-exe|-fvwm-exe|-e) echo "$fvwm_exe" ;; --supports|-supports|-s) test "$with_bidi" = "yes" && echo "bidi" test "$with_gettext" = "yes" && echo "gettext" test "$with_gdkimlib" = "yes" && echo "gdk-imlib" test "$with_gnomelibs" = "yes" && echo "gnome-libs" test "$with_iconv" = "yes" && echo "iconv" test "$with_perllib" = "yes" && echo "perllib" test "$with_png" = "yes" && echo "png" test "$with_readline" = "yes" && echo "readline" test "$with_rplay" = "yes" && echo "rplay" test "$with_rsvg" = "yes" && echo "rsvg" test "$with_shape" = "yes" && echo "shape" test "$with_shm" = "yes" && echo "shm" test "$with_sm" = "yes" && echo "sm" test "$with_stroke" = "yes" && echo "stroke" test "$with_xcursor" = "yes" && echo "xcursor" test "$with_xinerama" = "yes" && echo "xinerama" test "$with_xft" = "yes" && echo "xft" test "$with_xpm" = "yes" && echo "xpm" test "$with_xrender" = "yes" && echo "xrender" ;; --supports-*) feature=`echo "$1" | sed 's/^--supports-//'` feature=`echo "$feature" | sed 's/[-_]//g'` with=`eval echo '$'with_"$feature"` test "$with" = "yes" && exit 0 test "$with" = "no" && exit 100 exit 200 ;; --info|-info|-i) echo "Package: $PACKAGE" echo "Version: $VERSION$VERSIONINFO" echo "" echo "Instalation options:" echo " prefix: $prefix" echo " exec-prefix: $exec_prefix" echo " bindir: $bindir" echo " datadir: $datadir" echo " libexecdir: $libexecdir" echo " sysconfdir: $sysconfdir" echo " mandir: $mandir" echo " localedir: $localedir" echo "" echo "Compiled-in paths:" echo " Module directory: $fvwm_moduledir" echo " Data directory: $fvwm_datadir" echo " Perl lib directory: $fvwm_perllibdir" echo " Default ImagePath: $fvwm_imagepath" echo " Default UserDir: $fvwm_userdir" echo "" echo "Support for features:" echo " bidi (bi-directionality): $with_bidi" echo " gettext (Native Lang Support): $with_gettext" echo " perllib (Perl library installed): $with_perllib" echo " iconv (i18n conversions): $with_iconv" echo " png: $with_png" echo " readline: $with_readline" echo " rplay: $with_rplay" echo " shape (shaped windows): $with_shape" echo " shm (shared memory): $with_shm" echo " sm (session management): $with_sm" echo " stroke (mouse gestures): $with_stroke" echo " rsvg (SVG icons and images): $with_rsvg" echo " xcursor (ARGB/animated cursors): $with_xcursor" echo " xinerama (multi-head): $with_xinerama" echo " xft (FreeType anti-alias font): $with_xft" echo " xpm: $with_xpm" echo " xrender (XFree86 Xrender extention): $with_xrender" ;; --is-final|-is-final) test "$is_final" = yes && echo yes test "$is_final" != yes && echo no ;; *) echo >&2 "$script: unknown argument '$1'." echo >&2 "Run '$script --help' to get the usage." exit 1 ;; esac shift done exit 0 fvwm-2.6.7/bin/fvwm-menu-desktop.10000644000175700017570000003616113010101137013660 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .ta .3i .6i .9i 1.2i 1.5i 1.8i .TH fvwm-menu-desktop 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME fvwm-menu-desktop \- Reads XDG menu files and creates Fvwm menus .SH SYNOPSIS fvwm-menu-desktop [ \fB\-\-help\fR|\fB\-h\fR ] [ \fB\-\-version\fR ] [ \fB\-\-install\-prefix\fR \fIDIR\fR ] [ \fB\-\-desktop\fR \fINAME\fR ] [ \fB\-\-menu\-type\fR \fINAME\fR ] [ \fB\-\-theme\fR \fINAME\fR ] [ \fB\-\-with\-titles\fR|\fB\-w\fR ] [ \fB\-\-without\-titles\fR ] [ \fB\-\-enable\-mini\-icons\fR ] [ \fB\-\-size\fR|\fB\-s\fR \fINUM\fR ] [ \fB\-\-mini\-icon\-dir\fR \fIDIR\fR ] [ \fB\-\-app\-icon\fR \fINAME\fR ] [ \fB\-\-dir\-icon\fR \fINAME\fR ] [ \fB\-\-title\fR|\fB\-t\fR \fINAME\fR ] [ \fB\-\-insert\-in\-menu\fR \fINAME\fR ] [ \fB\-\-get\-menus\fR \fIall\fR|\fIdesktop\fR ] [ \fB\-\-set\-menus\fR \fImenu_paths\fR ] [ \fB\-\-all\-menus\fR ] [ \fB\-\-include\-items\fR \fINAME\fR ] [ \fB\-\-regen\-cmd\fR \fICMD\fR ] [ \fB\-\-dynamic\fR ] [ \fB\-\-verbose\fR|\fB\-v\fR ] .SH DESCRIPTION This is a python script which parses XDG menus definitions to build corresponding fvwm menus. This script depends on python-xdg to run. .SH OPTIONS .IP "Main Options" .IP "\fB\-\-help\fR" Show the help and exit. .IP "\fB\-\-version\fR" Show the version and exit. .IP "\fB\-\-get\-menus\fR \fIall\fR|\fIdesktop\fR" Prints a space separated list of full menu paths found on the system. \fIall\fR will print all menus found on the system except empty ones. \fIdesktop\fR will print the menu(s) that would be generated by the script. No menu generation is done. .IP "\fB\-\-desktop\fR \fINAME\fR" Optional parameter to set the \fINAME\fR of the desktop XDG .menu file(s) to use. This option will override any default menus set via \fBFvwmForm-XDGMenu-Config\fR and cause the script to find menus in which \fINAME\fR is a part of the file name. Possible names are: \fIgnome\fR, \fIkde\fR, \fIxfce\fR, \fIlxde\fR, \fIdebian\fR, etc. This option can be used in conjunction with \fB\-\-menu\-type\fR to control which .menu file(s) are used. .IP "\fB\-\-menu\-type\fR \fINAME\fR" Optional parameter to set the \fINAME\fR of the XDG menu type to use. This option will override any default menus set via \fBFvwmForm-XDGMenu-Config\fR and cause the script to find menus in which \fINAME\fR is a part of the file name. Possible \fINAME\fR types could be: \fIapplications\fR, \fIsettings\fR, \fIpreferences\fR, etc. When used in conjunction with \fB\-\-desktop\fR, only menus whose file name matches '*destkop*menutype*' are found. If no menus are found, the script exits with an error. .IP "\fB\-\-all\-menus\fR" This option will build all menus found on the system. If used in conjunction with \fB\-\-desktop\fR or \fB\-\-menu\-type\fR this will build all menus matching those settings. .IP "\fB\-\-install-prefix\fR \fIDIR\fR" Optional parameter to override the standard locations for XDG menu definitions. Tells \fBfvwm-menu-desktop\fR to look in \fIDIR\fR for .menu files instead of the standard locations /etc/xdg/menus (and $HOME/.config/menus if it exists). .IP "\fB\-\-with\-titles\fR|\fB\-w\fR" If this option is set menus are generated with titles. This is the default. This option can be used to override the \fBFvwmForm-XDGMenu-Config\fR default setting. .IP "\fB\-\-without\-titles\fR" If this option is set menus are generated without titles. The default is to generate with titles. .IP "\fB\-\-title\fR|\fB\-t\fR \fINAME\fR " Option to define the menu title \fINAME\fR of the top menu used by Fvwm's \fBMenu\fR or \fBPopup\fR commands. Default is "XDGMenu". .IP "\fB\-\-include\-items\fR \fINAME\fR " This option controls if the additional menu items 'Regenerate' and 'Configure' are included in the top level menu. \fINAME\fR can be one of \fIregen\fR, \fIconfig\fR, \fIboth\fR, or \fInone\fR. The default is \fIboth\fR. .IP "\fB\-\-regen\-cmd\fR \fICMD\fR " This option sets the fvwm command \fICMD\fR that is run when the menu item \'Regenerate' is selected. The default is "PipeRead `fvwm-menu-desktop`". .IP "\fB\-\-dynamic\fR " This option is to be used with creating dynamic menus using \fBDynamicPopUpAction\fR and \fBDynamicPopDownAction\fR. This adds a 'recreate' to the \fBDestroyMenu\fR command on the top level menu so those actions are not Destroyed when the menu is regenerated. .IP "\fB\-\-insert\-in\-menu\fR \fINAME\fR" Option to insert generated menu(s) \fBIN\fR a menu \fINAME\fR (its top title). This option makes it so the top level menu is not Destroyed and the items are added to the end. Note menus regenerated with this option will append the menu items at the end of the existing menu. Each time the menu is regenerated new menu items appear giving a growing menu of duplicate items. You have to regenerate the whole menu via a function or restart fvwm. See \fBEXAMPLES\fR below for some solutions. .IP "\fB\-\-set\-menus\fR \fImenu_paths\fR" Generates all menus listed in a space separated list of full menu paths. This option overrides any defaults and \fB\-\-desktop\fR|\fB\-\-menu\-type\fR settings. .IP "\fB\-\-verbose\fR" Enables additional information printouts on STDERR. .IP "Icons Options" By default, fvwm-menu-desktop builds menus without mini\-icons. To enable mini\-icons use the following options. If ImageMagick is installed on the system, the script will resize and copy the icons to $FVWM_USERDIR/.icons. This can take awhile. You should be prepared to wait the first time you generate the icons. Once the icons have been generated the script should run faster. If it is still to slow using icons, see \fBEXAMPLES\fR for ways to limit how often the menu is generated to speed things up. .IP "\fB\-\-enable\-mini\-icons\fR" This option enables mini\-icons in the menus. If set, 24x24 mini-icons are used. If the specified icon isn't that size it will be converted if \fBImageMagick\fR is installed and saved in $HOME/.fvwm/icons or to the directory specified with \-\-mini\-icon\-dir option. Otherwise no icon appears in the menu for that entry. With most distributions, all the menu entries will have mini-icons appropriate to the application. .IP "\fB\-\-theme\fR \fINAME\fR" Defines the used icon theme. Default is \fIgnome\fR but all others found in /usr/share/icons could be used except the \fIhicolor\fR theme because it's the default fallback theme if no icon is found. .IP "\fB\-\-size\fR|\fB\-s\fR \fINUM\fR" If \-\-enable\-mini\-icons is used the \fIsize\fR of the icons can changed with this parameter. Default is 24. .IP "\fB\-\-mini\-icon\-dir\fR \fIDIR\fR" When the right size mini-icon isn't available, fvwm-menu-desktop creates icons with the right size in $HOME/.fvwm/icons. If you don't want to use the default directory, $HOME/.fvwm/icons, use this option to specify a different folder. .IP "\fB\-\-app\-icon\fR \fINAME\fR" Sets the default application icon if no others are found. Default is \'gnome-applications'. .IP "\fB\-\-dir\-icon\fR \fINAME\fR" Sets the default directory icon if no others are found. Default is \'gnome-fs-directory'. .SH USAGE \fBfvwm-menu-desktop\fR outputs XDG .menu files in the syntax of fvwm menus. When \fBfvwm-menu-desktop\fR is run with no options, it will load defaults from the \fBFvwmForm-XDGMenu-Config\fR file (see below) then search your system for suitable menu file(s). To see which menus are available on your system run: .RS .EX fvwm-menu-desktop --get-menus all .EE .RE If no menus are found you may not have any installed on your system. By default menus are stored as *.menu files in /etc/xdg/menus, $HOME/.config/menus or the location set in $XDG_MENU_PREFIX. You can use \fB\-\-install\-prefix\fR to specify another location search for menus. Though a combination of command line options and the \fBFvwmForm-XDGMenu-Config\fR settings, \fBfvwm-menu-desktop\fR can generate any combination of the menus found. To get a list of what menu(s) would be generated use the \fB--get-menus\fR \fIdesktop\fR option. The following will list all menus generated if \fBfvwm-menu-desktop\fR was run with no options. .RS .EX fvwm-menu-desktop --get-menus desktop .EE .RE \fBfvwm-menu-desktop\fR determines which menu(s) to generate as follows .RS If no config file is found, all menus will be weighted and the script will generate the best (highest weight) menu found. If a config file is found (and override options are not used) the script will generate all menus selected in \fBFvwmForm-XDGMenu-Config\fR. \fB--desktop\fR, \fB--menu-type\fR, \fB--set-menus\fR and \fB--all-menus\fR will override any menus selected in \fBFvwmForm-XDGMenu-Config\fR. \fB--desktop\fR and \fB--menu-type\fR will only include menus whose name matches '*desktop*menutype*'. If used with \fB--all-menus\fR, all matching menus are generated. If used without \fB--all-menus\fR, only the highest weighted menu is generated. \fB--set-menus\fR generates menus from the list of full path menu file names. \fB--all-menus\fR by itself will generate all menus found. .RE By default \fBfvwm-menu-desktop\fR will generate a menu whose top level name is "XDGMenu". To tell fvwm to read the output of \fBfvwm-menu-desktop\fR to create the menu XDGMenu add the following to your fvwm config file: .RS .EX PipeRead 'fvwm-menu-desktop' .EE .RE \fBWarning:\fR Depending on the options used this command may be slow and fvwm will pause until this command is complete. See \fBEXAMPLES\fR below for more details and possible workarounds. Once the menu is generated you can open the menu by using the command "Menu XDGMenu". You can also include this in the MenuFvwmRoot menu by: .RS .EX AddToMenu MenuFvwmRoot "XDG Menu" Popup XDGMenu .EE .RE \fBfvwm-menu-desktop\fR can be configured though both command line options and a \fBFvwmForm\fR GUI to customize the menu(s) that get generated. .SH GUI \fBFvwmForm-XDGMenu-Config\fR is a \fBFvwmForm\fR interface that can be used to configure the defaults for \fBfvwm-menu-desktop\fR. You can access this from the "Configure" item in the top level menu that is generated or run the following from within \fBFvwmConsole\fR .RS .EX Module FvwmPerl -l fvwm-menu-desktop-config.fpl .EE .RE This form can be used to select which menu(s) get generated by default along with setting many (but not all) of the available options. When you click "Save Settings" the form will write a config file located at $FVWM_USERDIR/.FvwmForm-XDGMenu-Config that \fBfvwm-menu-desktop\fR will parse for defaults when run. See the help inside of \fBFvwmForm-XDGMenu-Config\fR for more information. .SH EXAMPLES There are many ways to setup when fvwm runs \fBfvwm-menu-desktop\fR to generate the menu. One method is to just generate the menu when fvwm loads and then use the GUI config tool to change any options. To do this you only need to add the following to the fvwm config file: .RS .EX AddToMenu MenuFvwmRoot "XDG Menu" Popup XDGMenu PipeRead 'fvwm-menu-desktop' .EE .RE The menu is created once when fvwm loads. Since menu creation can sometimes be slow, this could cause fvwm to take longer to load than one wants. The menu is only generated when fvwm starts. If software is installed or removed you will have to select the 'Regenerate' option to rebuild the menu. One way to speed things up is to save the menu in a file and only generate the menu when 'Regenerate' is selected. To do this use \fB--regen-cmd\fR to call a custom function and write the menu to a file using a command like .RS .EX fvwm-menu-desktop --regen-cmd XDGRegen > $FVWM_USERDIR/.XDGMenu .EE .RE Then add the following to the fvwm config file to define the function XDGRegen. The second to last line will generate the menu if the menu file doesn't exist when fvwm starts. .RS .EX DestroyFunc XDGRegen AddToFunc XDGRegen + I PipeRead 'fvwm-menu-desktop --regen-cmd XDGRegen > \\ $[FVWM_USERDIR]/.XDGMenu; echo "Nop"' + I Read $[FVWM_USERDIR]/.XDGMenu Test (!f $[FVWM_USERDIR]/.XDGMenu) XDGRegen Read $[FVWM_USERDIR]/.XDGMenu .EE .RE Besides creating a top level menu, \fBfvwm-menu-desktop\fR can insert the menu into an existing menu using the \fB--insert-in-menu\fR option. For example one could create the menu MenuFvwmRoot and include the XDG items at the end. .RS .EX DestroyMenu MenuFvwmRoot AddToMenu MenuFvwmRoot "Fvwm" Title + "Item1" Action1 ... + "ItemN" ActionN + "" Nop PipeRead 'fvwm-menu-desktop --insert-in-menu MenuFvwmRoot' .EE .RE In this case the menu items are inserted at the end of the MenuFvwmRoot menu. If no items are in the menu, this menu becomes MenuFvwmRoot. The problem here is, that you have to restart fvwm or rebuild the whole menu to Regenerate it because menu items cannot be removed. To do this you could use a function like .RS .EX DestroyFunc XDGRegen AddToFunc XDGRegen + I DestroyMenu MenuFvwmRoot + I AddToMenu MenuFvwmRoot "Fvwm" Title + I AddToMenu MenuFvwmRoot "Item1" Action1 ... + I AddToMenu MenuFvwmRoot "ItemN" ActionN + I AddToMenu MenuFvwmRoot "" Nop + I PipeRead 'fvwm-menu-desktop --insert-in-menu MenuFvwmRoot \\ --regen-cmd XDGRegen' .EE .RE Fvwm can also create menus dynamically by using \fBDynamicPopUpAction\fR and/or \fBDynamicPopDownAction\fR. These commands when used with a Menu will run a Function when the menu is opened. For example one could create the menu XDGMenu when it is opened using .RS .EX AddToMenu XDGMenu "XDGMenu" Title + DynamicPopUpAction PipeRead 'fvwm-menu-desktop' .EE .RE This will create the menu when it is opened. One issue here is it will only create the menu the first time it is opened, and you still have to Regenerate the menu to see any changes. To create the menu each time it is open used the \fB--dynamic\fR option .RS .EX AddToMenu XDGMenu "XDGMenu" Title + DynamicPopUpAction PipeRead 'fvwm-menu-desktop \\ --dynamic --include-items config' + DynamicPopDownAction DestroyMenu recreate XDGMenu .EE .RE This will now Destroy the menu when it closed so it can be rebuilt the next time it is opened. The recreate flag doesn't completely destroy the menu keeping the DynamicPopUpAction and DynamicPopDownAction actions. The \fB--dynamic\fR flag includes the recreate option in the generated menus. To insert a menu into MenuFvwmRoot and still be dynamic you need to use a function that generates the whole menu. For example .RS .EX DestroyFunc GenRootMenu AddToFunc GenRootMenu + I DestroyMenu recreate MenuFvwmRoot + I AddToMenu MenuFvwmRoot "Fvwm" Title + I AddToMenu MenuFvwmRoot "Item1" Action1 ... + I AddToMenu MenuFvwmRoot "ItemN" ActionN + I AddToMenu MenuFvwmRoot "" Nop + PipeRead `fvwm-menu-desktop --insert-in-menu MenuFvwmRoot \\ --include-items config` AddToMenu MenuFvwmRoot "Fvwm" Title + DynamicPopUpAction GenRootMenu + DynamicPopDownAction DestroyMenu recreate MenuFvwmRoot .EE .RE .SH BUGS The whole process of creating menus from files is slow. Otherwise report bugs to the fvwm-workers mailing list . .SH AUTHORS This script is based on fvwm-xdg-menu.py written by Piotr Zielinski (http://www.cl.cam.ac.uk/~pz215/) who assigned Licence: GPL 2 Date: 03.12.2005. The script was reworked to replace the existing fvwm-menu-desktop perl script by the fvwm-workers. .SH COPYING The script is distributed by the same terms as fvwm itself. See GNU General Public License for details. fvwm-2.6.7/bin/fvwm-root.1.in0000644000175700017570000000722012673746443012664 00000000000000'\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH fvwm-root 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME fvwm-root \- Sets the root window of the current X display to image .SH SYNOPSIS .B fvwm-root .RB [ "--retain-pixmap" | "-r" ] .RB [ "--no-retain-pixmap" ] .RB [ "--dummy" | "-d" ] .RB [ "--no-dummy" ] .RB [ "--dither" ] .RB [ "--no-dither" ] .RB [ "--color-limit" .RI [ ncolors "] ]" .RB [ "--no-color-limit" ] .RB [ "--help" | "-h" | "-?" ] .RB [ "--version" | "-V" ] .I image_file .SH DESCRIPTION .I fvwm-root reads the image file specified in the command line and displays it in the root window. The supported image formats are .IR XBM ", " XPM ", " PNG " and " SVG if appropriated libraries are compiled in. SVG rendering options .RB " (as described in the " " ICONS AND IMAGES " section of the main fvwm documentation) can be utilized. .SH OPTIONS These command line options are recognized by fvwm-root: .TP .BR "--retain-pixmap" " | " "-r" Causes fvwm-root to retain and publish the Pixmap with which the background has been set (the ESETROOT_PMAP_ID and _XROOTPMAP_ID properties are used). This is useful for applications which want to use the root Pixmap on the background to simulate transparency (for example, Eterm and Aterm use this method). This option should also be used for the RootTransparent colorset option, refer to the COLORSETS section of fvwm(1). If this option is not used, fvwm-root sets the _XSETROOT_ID property to None, and some programs, like fvwm modules, may use this to update their background if the background is transparent (Transparent colorset). Note, a well behaved program, like fvwm, should listen to both _XSETROOT_ID and _XROOTPMAP_ID property changes and update itself correspondingly. However some programs listen only to one of them, so you should either use this option or not depending on what part is implemented by these programs. You should also use this option to get fast root-transparent menus in fvwm. .TP .BI "--no-retain-pixmap" This is a default. May be useful to explicitly force the default even if "--retain-pixmap" is specified earlier. .TP .BR "--dummy" " | " "-d" Causes fvwm-root NOT to set the background, but to only free a memory associated with the ESETROOT_PMAP_ID property (if any). In any case the _XSETROOT_ID property is set to None. .TP .BI "--no-dummy" This is a default. May be useful to explicitly force the default even if "--dummy" is specified earlier. .TP .BI "--dither" Causes fvwm-root to dither images for "smoother" rendition on displays with color depth of 16 or lower. This the defaut with color depth less or equal to 8. .TP .BI "--no-dither" Causes fvwm-root NOT to dither images. This is the default with color depth greater than 8. .TP .BI "--color-limit " ncolors Causes fvwm-root to limit its color use to .I ncolors (if specified). This option is taken in account only with color depth less or equal to 8 (and a TrueColor or GrayScale visual). The default is to use the same color limit as fvwm. So in normal situation this option is not useful. However, if fvwm use a private colors map, as fvwm-root always use the default colors map you should use this option for limiting colors correctly. If .I ncolors is not specified a default is used. .TP .BI "--no-color-limit" Causes fvwm-root NOT to limit its color use. .TP .BI "--help" Shows a short usage. .TP .BI "--version" Shows a version number. .SH COMPATIBILITY In the past this utility was called .IR xpmroot . This name is still supported as a symlink. .SH BUGS Repeated use of fvwm-root with different xpm pixmaps will use up slots in your color table pretty darn fast. .SH AUTHOR Rob Nation Rewritten and enhanced by fvwm-workers. fvwm-2.6.7/bin/fvwm-menu-directory.in0000644000175700017570000005575412673746443014527 00000000000000#!@PERL@ # Copyright (c) 1999-2009 Mikhael Goikhman # # 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 # Filter this script to pod2man to get a man page: # pod2man -c "Fvwm Utilities" fvwm-menu-directory | nroff -man | less -e # To speed up the script, several optimizations were made: trying to minimize # the number of additional file operations, function calls and includes. #print STDERR "fvwm-menu-directory @ARGV\n"; use strict; use Getopt::Long; my $version = "@VERSION@"; my $name = "MenuBrowser"; # used only with --reuse my $title = "%*-40p"; # may contain specifiers %d, %p. my $itemf = "%n"; # may contain specifiers %n, %t, %T, %d, %D, %s. my $icont = ""; my $icond = ""; my $iconf = ""; my $icona = ""; my $home = $ENV{'HOME'} || '/tmp'; my $dir = $home; my $xterm = "xterm -e"; # the X terminal program to invoke my $exect = $ENV{'SHELL'} || '/bin/sh'; my $execf = $ENV{'EDITOR'} || "vi"; # the command to execute on plain files my $execa = undef; my $commt = undef; my $commf = undef; my $comma = undef; my $all = 0; # whether show hidden files (like in 'ls -A') my $links = 0; # whether follow linked dirs or not my $order = 5; # -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6 my $reuse = 0; # non-popup mode my $wm_icons = 0; my $check_subdirs = 0; # whether check subdirs for +x permissions my $special_dir_val = undef; # which of (.. ~ /) dirs include or none my $memory_for_speed = 0; my $submenu_pos = " item +100 c"; # " menu +0 +0" my $fvwm_user_dir = $ENV{'FVWM_USERDIR'} || "$home/.fvwm"; $fvwm_user_dir = $home unless -d $fvwm_user_dir; my $dir_filename = "$fvwm_user_dir/.fvwm-menu-directory.dir"; my $change_menu_style = ""; my $func_name = "FuncFvwmMenuDirectory"; GetOptions( "help|h|?" => \&show_help, "version|V" => \&show_version, "name=s" => \$name, "title=s" => \$title, "item=s" => \$itemf, "icon-title=s" => \$icont, "icon-dir=s" => \$icond, "icon-file=s" => \$iconf, "icon-app=s" => \$icona, "dir=s" => \$dir, "order=i" => \$order, "all!" => \$all, "links!" => \$links, "xterm=s" => \$xterm, "exec-title=s" => \$exect, "exec-file=s" => \$execf, "exec-app:s" => \$execa, "command-title=s" => \$commt, "command-file=s" => \$commf, "command-app=s" => \$comma, "reuse!" => \$reuse, "wm-icons" => \$wm_icons, "check-subdirs!" => \$check_subdirs, "special-dirs:s" => \$special_dir_val, "memory-for-speed!" => \$memory_for_speed, "menu-style=s" => \$change_menu_style, "func-name=s" => \$func_name, ) || wrong_usage(); wrong_usage() if @ARGV; $name = $dir unless $reuse; $dir =~ s:^~(/|$):$home$1:; chomp($dir = `cat "$dir_filename"`) if $reuse && -f $dir_filename; unless (-d $dir) { # the next line may be commented not to throw error #die "$dir does not exist, exiting.\n"; $dir = $home; } $links || !-l $dir || exit(-1); # exit if linked directories are disabled chdir($dir) || exit(-1); # exit if no execute permission on the directory # expand title &expand_width_specifier(\$title, 'd', (split('/', $dir))[-1] || '/') if $title =~ /%(-?\d+)?(\*-?\d+)?d/; &expand_width_specifier(\$title, 'p', $dir) if $title =~ /%(-?\d+)?(\*-?\d+)?p/; $title =~ s/\\t/\t/g; $itemf =~ s/\\t/\t/g; # item format optimization variables my $itemf_eval = $itemf ne '%f'; # evaluation needed my $itemf_name = undef; my $itemf_stat = undef; # stat() needed my $itemf_date = undef; my $itemf_size = undef; my $itemf_type = undef; if ($itemf_eval) { $itemf_name = $itemf =~ /%(-?\d+)?(\*-?\d+)?[nN]/; $itemf_date = $itemf =~ /%[dD]/; $itemf_size = $itemf =~ /%(-?\d+)?(\*-?\d+)?s/; $itemf_type = $itemf =~ /%[tT]/; $itemf_stat = $itemf_size || $itemf_date || $itemf_size || $itemf_type; } my @type1 = ("Sock", "Link", "File", "Blck", "Dir ", "Char", "Pipe"); my @type2 = ("S", "L", "F", "B", "D", "C", "P"); if ($wm_icons) { $icont ||= "menu/folder-open.xpm"; $icond ||= "menu/folder.xpm"; $iconf ||= "menu/file.xpm"; $icona ||= "menu/utility.xpm"; } my $icont_str = $icont ? "%$icont%" : ""; my $icond_str = $icond ? "%$icond%" : ""; my $iconf_str = $iconf ? "%$iconf%" : ""; my $icona_str = $icona ? "%$icona%" : ""; $exect = undef if defined $exect && $exect eq '-'; $execf = undef if defined $execf && $execf eq '-'; $execa = undef if defined $execa && $execa eq '-'; $exect = $exect =~ /^\^(.*)$/ ? $1 : "$xterm $exect" if defined $exect; $execf = $execf =~ /^\^(.*)$/ ? $1 : "$xterm $execf" if defined $execf; $execa = $execa =~ /^\^(.*)$/ ? $1 : "$xterm $execa" if defined $execa; $commt = undef if defined $commt && $commt eq '-'; $commf = undef if defined $commf && $commf eq '-'; $comma = undef if defined $comma && $comma eq '-'; $commt = defined $exect ? qq(Exec cd "%d"; $exect): "Nop" if !defined $commt; $commf = defined $execf ? qq(Exec $execf "%f"): "Nop" if !defined $commf; $comma = defined $execa ? qq(Exec $execa "%f"): $commf if !defined $comma; # manage special directories if needed my ($special_dir_lines, $special_dir_pos, @special_dirs) = (""); $special_dir_val = "1,2" if defined $special_dir_val && $special_dir_val eq ""; if ($special_dir_val && $special_dir_val =~ /([\d,]+)(-?)/) { @special_dirs = grep(/^[1-3]$/, split(/,+/, $1)); $special_dir_pos = $2 ? -1 : 1; } if (@special_dirs) { my $parent_dir = $dir eq '/' || $dir !~ m!^(.*)/[^\/]+$! ? undef : $1; $parent_dir = '/' if defined $parent_dir && $parent_dir eq ''; my @special_dir_def = ( [ '..' => $parent_dir ], [ '~' => $home ], [ '/' => '/' ], ); foreach (@special_dirs) { $special_dir_lines .= qq(+ "" Nop\n) if $special_dir_lines; $special_dir_lines .= &eval_folder_line(@{$special_dir_def[$_ - 1]}); } } else { $special_dir_pos = 0; } # create file listing opendir(DIR, "."); my @files = readdir(DIR); closedir(DIR); @files = grep /^[^.]/, @files unless $all; my $abs_order = abs($order); # To avoid warnings, '!!' must be added before '-d'. Will this slow things? my $sort_sub = $abs_order == 2 ? sub { -d $b <=> -d $a } : $abs_order == 3 ? sub { -d $a <=> -d $b } : $abs_order == 4 ? sub { $a cmp $b } : $abs_order == 5 ? sub { -d $b <=> -d $a || $a cmp $b } : $abs_order == 6 ? sub { -d $a <=> -d $b || $a cmp $b } : sub { 0 }; @files = sort $sort_sub @files if $abs_order != 1; @files = reverse @files if $order < 0; # dump all menu items and start adding new items my $menu_name = &escape_fvwm_name($name); my $menu_name2 = &escape_menu_name($name); print qq(DestroyMenu recreate "$menu_name"\nAddToMenu "$menu_name2"\n); # destroy the menu after it is popped down print qq(+ DynamicPopDownAction DestroyMenu "$menu_name"\n) unless $memory_for_speed || $reuse; # set the 'missing submenu function' print qq(+ MissingSubmenuFunction $func_name\n) unless $reuse; # add a new title (item and separator, or real Title if no action) my $title_act = $commt; $title_act =~ s/%d/$dir/g; if ($title ne "") { if ($title_act eq "") { print qq(+ "$icont_str$title" Title\n); } else { print qq(+ "$icont_str$title" $title_act\n+ "" Nop\n); } } # add special dirs at the top if needed print qq($special_dir_lines+ "" Nop\n) if $special_dir_pos > 0; # add directory contents foreach (@files) { next if $_ eq '.' or $_ eq '..'; my $file_path = "$dir/$_"; $file_path =~ s|/+|/|g; if (-d) { # it's a directory print &eval_folder_line($_, $file_path); } else { # something else, apply editor to it or run itself my $item_str = $itemf_eval ? &eval_item($_, $file_path) : $_; $item_str = &escape_item_name($item_str); my $is_app = -x && -f; my $icon_str = $is_app && $icona_str ? $icona_str : $iconf_str; my $file_act = $is_app ? $comma : $commf; $file_act =~ s/%f/&escape_file_name($file_path)/ge; print qq(+ "$icon_str$item_str" $file_act\n); } } # add special dirs at the bottom if needed print qq(+ "" Nop\n$special_dir_lines) if $special_dir_pos < 0; # add style: if ($change_menu_style ne "") { print qq(ChangeMenuStyle "$change_menu_style" "$menu_name"\n); } exit(0); # --------------------------------------------------------------------------- sub escape_fvwm_name ($) { my $name = shift; $name =~ s/\\/\\\\/g; $name =~ s/"/\\"/g; $name =~ s/\$/\$\$/g; $name; } sub escape_menu_name ($) { my $name = escape_fvwm_name(shift()); # fvwm is really inconsistent here $name =~ s/\^/^^/g; $name =~ s/@/@@/g; $name; } sub escape_item_name ($) { my $name = escape_fvwm_name(shift()); $name =~ s/%/%%/g; $name =~ s/&/&&/g; $name =~ s/\*/**/g; $name =~ s/\n/ /g; $name; } sub escape_file_name ($) { my $name = shift; $name =~ s/\\/\\\\/g; $name =~ s/"/\\"/g; $name =~ s/\$/\\\$\$/g; $name =~ s/\n/\\\n/g; $name; } sub eval_folder_line ($$) { my ($_name, $dir) = @_; my $item_str = $dir && $itemf_eval ? &eval_item($_name, $dir) : $_name; $item_str = escape_item_name($item_str); my $act = !$dir || $check_subdirs && !-x $dir ? "Nop" : !$reuse ? qq(Popup ") . escape_file_name($dir) . qq("$submenu_pos) : qq(PipeRead 'echo ") . escape_file_name($dir) . qq(" >$dir_filename; ) . qq(echo Menu ") . escape_fvwm_name($name) . qq(" WarpTitle'); return qq(+ "$icond_str$item_str" $act\n); } sub eval_item ($$) { my ($name, $file) = @_; return $name unless $itemf_eval; my $item_str = "$itemf"; if ($itemf_name) { &expand_width_specifier(\$item_str, 'n', $name); &expand_width_specifier(\$item_str, 'N', $file); } return $item_str unless $itemf_stat; # / $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, # \ $size, $atime, $mtime, $ctime, $blksize, $blocks my ($misc1, $misc2, $mode, $misc3, $misc4, $misc5, $misc6, $size, $misc7, $time) = stat($file); if ($itemf_date) { eval 'use POSIX qw(strftime);' unless defined $POSIX::VERSION; my @time = localtime($time); my $date1 = strftime("%Y-%m-%d %H:%M:%S", @time); my $date2 = strftime("%Y-%m-%d", @time); $item_str =~ s/%d/$date1/g; $item_str =~ s/%D/$date2/g; } if ($itemf_size) { &expand_width_specifier(\$item_str, 's', $size); } if ($itemf_type) { my $type; # $type = 2 if ($mode & 0100000); # regular # $type = 4 if ($mode & 0040000); # directory # $type = 0 if ($mode & 0140000); # socket # $type = 1 if ($mode & 0120000); # symlink # $type = 3 if ($mode & 0060000); # block # $type = 5 if ($mode & 0020000); # char-dev # $type = 6 if ($mode & 0010000); # fifo $type = -p _ ? 6 : -c _ ? 5 : -b _ ? 3 : -l $file ? 1 : -S _ ? 0 : -d _ ? 4 : 2; $item_str =~ s/%t/$type1[$type]/g; $item_str =~ s/%T/$type2[$type]/g; } return $item_str; } # Substitutes all %N1*N2x in $name by properly stripped and justified $value. sub expand_width_specifier (\$$$) { my ($name, $char, $value) = @_; $$name =~ s/%(-?\d+)?(\*(-?)(\d+))?$char/ my $value = !$2 || $4 <= 3 || $4 > length($value) ? $value : $3 ? "..." . substr($value, -$4 + 3, $4 - 3) : substr($value, 0, $4 - 3) . "..."; $1 ? sprintf("%$1s", $value) : $value; /ge; } sub show_help { print "A perl script that builds directory listing for fvwm.\n\n"; print "Usage: $0 [OPTIONS]\n"; print "Options:\n"; print "\t--help show this help and exit\n"; print "\t--version show the version and exit\n"; print "\t--name=NAME menu name, default is '$name'\n"; print "\t--title=NAME menu title, default is '$title'\n"; print "\t--item=NAME menu item format, default is '$itemf'\n"; print "\t--icon-title=XPM menu title icon, default is none\n"; print "\t--icon-dir=XPM menu dir icon, default is none\n"; print "\t--icon-file=XPM menu file icon, default is none\n"; print "\t--icon-app=XPM menu +x icon, default is none\n"; print "\t--wm-icons define icon names to use with wm-icons\n"; print "\t--dir=NAME starting dir, default is '$dir'\n"; print "\t--order=NUM NUM (-6 .. 6), default is 5\n"; print "\t\t1 - do not sort, 2 - dirs first, 3 - files first\n"; print "\t\t4 - sort by name, 5 - dirs first, 6 - files first\n"; print "\t\tNegative number represents reverse order.\n"; print "\t--all show hidden files, default is no\n"; print "\t--links follow linked dirs, default is no\n"; print "\t--xterm=CMD xterm call, default is '$xterm'\n"; print "\t--exec-title=CMD title exec command, default is '$exect'\n"; print "\t--exec-file=CMD file exec command, default is '$execf'\n"; print "\t--exec-app[=CMD] +x files exec command, default is '-'\n"; print "\t--command-title=CMD title fvwm command, default is '-'\n"; print "\t--command-file=CMD file fvwm command, default is '-'\n"; print "\t--command-app=CMD +x files fvwm command, default is '-'\n"; print "\t--reuse no popups, reuse the same menu (no)\n"; print "\t--check-subdirs check subdir for +x permission (no)\n"; print "\t--special-dirs[=X] include .. and ~ directories (no)\n"; print "\t--memory-for-speed use speed optimization (no)\n"; print "\t--menu-style=NAME assign specified MenuStyle name to menus\n"; print "Short options are ok if not ambiguous: -a, -icon-f.\n"; exit 0; } sub show_version { print "$version\n"; exit 0; } sub wrong_usage { print STDERR "Try '$0 --help' for more information.\n"; exit -1; } __END__ # --------------------------------------------------------------------------- =head1 NAME fvwm-menu-directory - builds a directory browsing menu for fvwm =head1 SYNOPSIS B [ B<--help>|B<-h>|B<-?> ] [ B<--version>|B<-V> ] [ B<--name>|B<-na> NAME ] [ B<--title>|B<-t> NAME ] [ B<--item>|B<-it> NAME ] [ B<--icon-title>|B<-icon-t> XPM ] [ B<--icon-dir>|B<-icon-d> XPM ] [ B<--icon-file>|B<-icon-f> XPM ] [ B<--icon-app>|B<-icon-a> XPM ] [ B<--wm-icons> ] [ B<--dir>|B<-d> NAME ] [ B<--order>|B<-o> NUM ] [ B<--[no]all>|B<-a> ] [ B<--[no]links>|B<-l> ] [ B<--xterm>|B<-x> CMD ] [ B<--exec-title>|B<-exec-t> CMD ] [ B<--exec-file>|B<-exec-f> CMD ] [ B<--exec-app>|B<-exec-a> [CMD] ] [ B<--command-title>|B<-command-t> CMD ] [ B<--command-file>|B<-command-f> CMD ] [ B<--command-app>|B<-command-a> CMD ] [ B<--[no]reuse>|B<-r> ] [ B<--[no]check-subdirs>|B<-ch> ] [ B<--special-dirs>|B<-s> [VALUE] ] [ B<--[no]memory-for-speed>|B<-mem> ] [ B<--menu-style>|B<-men> NAME ] [ B<--func-name>|B<-f> NAME ] =head1 DESCRIPTION A perl script which provides an output to read in with PipeRead to build an fvwm menu containing a directory listing. Almost everything can be configured. =head1 HINTS The title item with its own attached action is usually added to the menu. This may be used to define an action for the directory for which the menu is built, such as starting a terminal in this directory (the default). However, this may annoy some users. To disable the title action use B<--command-title> "", to remove the title completely use B<--title> "". =head1 OPTIONS =over 4 =item B<--help> show the usage and exit =item B<--version> show version and exit =item B<--name> name menu name, used only with --reuse, default is MenuBrowser =item B<--title> title menu title format, default is '%*-40p' - last 40 characters of the current full path. TAB can be specified as '\t', but in .fvwm2rc you should specify a double backslash or a real TAB. Format specifiers: %d - the current directory name %p - the current directory full path These specifiers can receive an optional integer size, positive for right adjusted string or negative for left adjusted, example: %8x; and optional *num or *-num, which means to leave only the first or last (if minus) num of chars, the num must be greater than 3, since the striped part is replaced with "...", example: %*30x. Both can be combined: %-10*-20x, this instructs to get only the 20 last characters, but if the length is less then 10 - to fill with up to 10 spaces on the right. =item B<--item> format menu item format, default is '%n'. TAB and width modifiers for %n, %N and %s can be specified as described in B<--title> above. Note, specifying a non default format slows the script. Format specifiers: %n - file/dir name (without the path) %N - file/dir name (full with the path) %d - file/dir date (yyyy-mm-dd HH:MM:SS) %D - file/dir date (yyyy-mm-dd) %s - file/dir size (in bytes) %t - file/dir type (File|Dir |Link|Sock|Blck|Char|Pipe) %T - file/dir type (F|D|L|S|B|C|P) Example: --title '%*-40p\tDate, Type\tSize' --item '%*40n\t%d %t\t%s' =item B<--icon-title> icon menu title icon, default is none =item B<--icon-dir> icon menu dir icon, default is none =item B<--icon-file> icon menu file icon, default is none =item B<--icon-app> icon menu application icon, default is none =item B<--wm-icons> define icon names suitable for use with wm-icons package. Currently this is equivalent to: --icon-title menu/folder-open.xpm --icon-item menu/file.xpm --icon-dir menu/folder.xpm --icon-app menu/utility.xpm. =item B<--dir> dir starting dir, default is ${HOME-.} =item B<--order> number in the range (-6 .. 6), default is 5: 1 - do not sort, 2 - dirs first, 3 - files first 4 - sort by name, 5 - dirs first, 6 - files first Negative number represents reverse order. =item B<--[no]all> show hidden files, like in 'ls -A', default is --noall =item B<--[no]links> follow linked directories, default is --nolinks =item B<--xterm> command X terminal call, default is 'xterm -e' =item B<--exec-title> command an fvwm Exec command on directory title (usually the shell), default is ${SHELL-/bin/sh}. '-' means no Exec command, i.e. Nop. If the command is not started with '^' X terminal call is prepended. The command is started in the currently browsed directory. =item B<--exec-file> command an fvwm Exec command on regular files, default is ${EDITOR-vi}. '-' means no Exec command, i.e. Nop. If the command is not started with '^' X terminal call is prepended. The actual file name is appended to the command. =item B<--exec-app> [command] an fvwm Exec command on +x files, default is '-', which means the same command as on regular files. If no command is given, it is assumed to be empty - simply run the +x file. If the command is not started with '^' X terminal call is prepended. The actual file name is appended to the command. =item B<--command-title> command an fvwm command to execute on title. If this option is not given (or command is '-'), the C<--exec-title> is used instead. In the command, %d is substituted with the full directory path. In fact, I<--exec-title=tcsh> is equivalent to I<--command-title='Exec cd "%d"; xterm -e tcsh'> The empty value disables the title action. =item B<--command-file> command an fvwm command to execute on regular files. If this option is not given (or command is '-'), the C<--exec-file> is used instead. In the command, %f is substituted with the full file path. In fact, --exec-file=vi is equivalent to --command-file='Exec xterm -e vi "%f"' =item B<--command-app> command an fvwm command to execute on +x files. If this option is not given (or command is '-'), the C<--command-app> is used instead. In the command, %f is substituted with the full file path. In fact, --exec-app=^exec is equivalent to --command-app='Exec exec "%f"' =item B<--[no]reuse> no pop-up menus, reuse the same menu, default is --noreuse. When you specify this option the Menu action is used, not Popup. Also, the --name parameter is not ignored, and --dir parameter is ignored if there is ~/.fvwm/.fvwm-menu-directory.dir file. This file is only created or used with this option specified, it is the only solution for the current fvwm menu state. =item B<--[no]check-subdirs> check all subdirs for having execute (+x) permission and replace "Popup"/"Menu" command with "Nop" for these without permissions. This has a visual effect of disabling popup triangle in the subdirectory item. The default is --nocheck-subdirs, because: 1) enabling this slows a bit the script, 2) with this option enabled, if no icons used and no dir/file separate sorting used there is no way to know that the item is directory and not file. =item B<--special-dirs> value add .. or ~ or / special directories according to given optional value. Without with option these directories are not added. Default value if not specified is "1,2". The value is comma separated ordered special directory indexes, where 1 is parent directory, 2 is home directory, 3 is root directory. If minus is prepended to the value, special directories are added at the bottom of menu instead of top. Value "0" or any bad value is equivalent to non-specifying this option at all. =item B<--[no]memory-for-speed> use speed optimization, i.e. use previously created directory menus without destroying it when closed, default is --nomemory-for-speed Warning: speed optimization takes up a lot of memory that is never free'd again while fvwm is running. =item B<--menu-style> name assign MenuStyle name to the menus =item B<--func-name> name overwrite the default MissingSubmenuFunction name that is "FuncFvwmMenuDirectory" =back Option parameters can be specified either using '=' or in the next argument. Short options are ok if not ambiguous: C<-a>, C<-x>, C<-icon-f>; but be careful with short options, what is now unambiguous, can become ambiguous in the next versions. =head1 USAGE Put this into your fvwm configuration file to invoke the script: AddToFunc FuncFvwmMenuDirectory + I PipeRead "fvwm-menu-directory -d '$0'" More complex example: # AddToFunc FuncFvwmMenuDirectory # + I PipeRead "fvwm-menu-directory -d '$0' -x 'Eterm -g 80x40 -e' \\ -a -l -o 6 --exec-app --exec-title 'tcsh -l' --exec-file 'vim -R' \\ -t 'Go to: %d' --wm-icons" And put this in the menu from which you want to pop-up the directory menus: AddToMenu SomeMenu MissingSubmenuFunction FuncFvwmMenuDirectory + "Home Directory" Popup $[HOME] + "Httpd Directory" Popup /home/httpd Note: please use absolute path names. It is a good idea to set the menu pop-up delay to something positive and enable busy cursor MenuStyle * PopupDelayed, PopupDelay 200 BusyCursor DynamicMenu True in your configuration file when using this script for better results. Another interesting usage (C<--reuse> or C<-r> is mandatary for this): AddToMenu Browser + DynamicPopupAction PipeRead \\ "fvwm-menu-directory -r -na Browser -d / -s" AddToMenu SomeMenu "My Browser" Menu Browser Here the C<--dir> parameter (starting directory) is ignored if there is ~/.fvwm/.fvwm-menu-directory.dir file, which you can delete. =head1 AUTHORS Inspired on 1999-06-07 by Dominik Vogt . Rewritten on 1999-08-05 by Mikhael Goikhman . =head1 COPYING The script is distributed by the same terms as fvwm itself. See GNU General Public License for details. =head1 BUGS Report bugs to fvwm-bug@fvwm.org. =cut # *************************************************************************** fvwm-2.6.7/bin/fvwm-perllib.10000644000175700017570000001302112673746443012721 00000000000000.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.02) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "fvwm-perllib 1" .TH fvwm-perllib 1 "2009-03-22" "2.5.28 (from cvs)" "Fvwm Utilities" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" fvwm\-perllib \- shows the documentation of the Fvwm Perl library .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBfvwm-perllib\fR [ \fB\-\-help\fR|\fB\-h\fR|\fB\-?\fR ] [ \fB\-\-version\fR|\fB\-v\fR|\fB\-V\fR ] [ \fBman\fR [ \fIPerl::Class\fR ] ] [ \fBcat\fR [ \fIPerl::Class\fR ] ] [ \fBraw\fR [ \fIPerl::Class\fR ] ] [ \fBdir\fR ] .SH "DESCRIPTION" .IX Header "DESCRIPTION" Starting from fvwm\-2.5.x versions there is a built-in support for creating fvwm modules in Perl. This \fBfvwm-perllib\fR utility provides help services for the Fvwm Perl library. .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-\-help\fR show the help and exit .PP \&\fB\-\-version\fR show the version and exit .PP \&\fB\-\-man\fR or \fBman\fR [ \fIPerl::Class\fR ] show manual page just like \fIman\fR\|(1) .PP \&\fB\-\-cat\fR or \fBcat\fR [ \fIPerl::Class\fR ] show manual page in plain text .PP \&\fB\-\-raw\fR or \fBraw\fR [ \fIPerl::Class\fR ] generate output in man format (not human readable) .PP \&\fB\-\-dir\fR or \fBdir\fR print perllib directory without a trailing end of line .SH "USAGE" .IX Header "USAGE" Use this in the fvwm modules written in Perl: .PP .Vb 1 \& use lib \`fvwm\-perllib dir\`; .Ve .PP Introduction to the Fvwm Perl library: .PP .Vb 1 \& % fvwm\-perllib man .Ve .PP Manual page for the \f(CW\*(C`FVWM::Module\*(C'\fR class: .PP .Vb 1 \& % fvwm\-perllib man FVWM::Module .Ve .PP Standard options: .PP .Vb 2 \& % fvwm\-perllib \-\-help \& % fvwm\-perllib \-\-version .Ve .SH "AUTHORS" .IX Header "AUTHORS" Mikhael Goikhman . .SH "COPYING" .IX Header "COPYING" The script is distributed by the same terms as fvwm itself. See \s-1GNU\s0 General Public License for details. .SH "BUGS" .IX Header "BUGS" No known bugs. .PP Report bugs to fvwm\-bug@fvwm.org. fvwm-2.6.7/bin/fvwm-config.10000644000175700017570000000610213010101137012502 00000000000000.\" @(#)fvwm-2.6.7 06 November 2016 .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .ta .3i .6i .9i 1.2i 1.5i 1.8i .TH fvwm-config 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME fvwm-config \- query an existing fvwm installation .SH SYNOPSIS .B fvwm-config .RI [ --help ] .RI [ --version ] .RI [ --info ] .RI [ --prefix ] .RI [ --exec-prefix ] .RI [ --bindir ] .RI [ --datadir ] .RI [ --libexecdir ] .RI [ --sysconfdir ] .RI [ --mandir ] .RI [ --localedir ] .RI [ --fvwm-moduledir ] .RI [ --fvwm-datadir ] .RI [ --fvwm-perllibdir ] .RI [ --default-imagepath ] .RI [ --default-userdir ] .RI [ --fvwm-exe ] .RI [ --supports ] .RI [ --supports- ] .SH DESCRIPTION .B fvwm-config is a shell script that provides an information about the fvwm version, installation directories, built-in paths and supported features. .SH OPTIONS .B fvwm-config prints to the standard output in all options. Both short and long GNU-like option names may be used. .TP .B -h --help -? prints the short usage .TP .B -v --version -V prints the version .TP .B -i --info prints the full info page .TP .B -P --prefix prints the installation prefix .TP .B -E --exec-prefix prints the installation exec-prefix .TP .B -B --bindir prints the installation bindir .TP .B -D --datadir prints the installation datadir .TP .B -L --libexecdir prints the installation libexecdir .TP .B -S --sysconfdir prints the installation sysconfdir .TP .B -M --mandir prints the installation mandir .TP .B -O --localedir prints the installation localedir .TP .B -m --fvwm-moduledir prints FVWM_MODULEDIR, where the modules are installed .TP .B -d --fvwm-datadir prints FVWM_DATADIR, where the system wide configs are installed .TP .B -p --fvwm-perllibdir prints FVWM_PERLLIBDIR, where the perl library is installed .TP .B -I --default-imagepath prints the built-in ImagePath .TP .B -U --default-userdir prints the default FVWM_USERDIR, note: $HOME is not expanded .TP .B -e --fvwm-exe prints the fvwm executable name (in bindir) .TP .B -s --supports lists all supported features, one per line .TP .BI --supports- prints nothing, returns: 0 if the .I is supported, 100 if not, 200 if unknown. All or supported feature names may be found using .IR --info " or " --supports respectively. .TP .SH USAGE Here are some real life usages. Checks for xft support: .EX if fvwm-config --supports-xft; then echo 1; else echo 0; fi .EE .I fvwm-themes package checks for the correct .I fvwm version installed using: .EX fvwm-config --version .EE and tries to use the same installation directories: .EX fvwm-config --bindir --mandir --fvwm-datadir .EE A way to find the full path to the fvwm executable: .EX echo `fvwm-config --bindir`/`fvwm-config --fvwm-exe` .EE A way to start modules in perl: .EX use lib `fvwm-config -p | tr -d '\n'`; use FVWM::Module; .EE For a more human readable output, try: .EX fvwm-config --info .EE .SH COPYING .B fvwm-config is a part of fvwm package and distributed by the same terms, see GNU GPL. .SH AUTHOR Mikhael Goikhman fvwm-2.6.7/bin/fvwm-menu-desktop.in0000644000175700017570000007703113006057357014152 00000000000000#!@PYTHON@ # Modification History # Changed on 26/10/27 by Jaimos Skrietz: # - Renamed default menu to XDGMenu and changed the name of the # FvwmForm to FvwmForm-XDGMenu-Config # - Modified the FvwmForm and added the abilty to load defaults from # the Form's data file. # - Changed default to generate menu titles. Disable with --without-titles # - The top level menu now has two additional items: # 'Regenerate' - Regenerates menu. # 'Configure' - Opens up FvwmForm-XDGMenu-Config. # - Added --regen-cmd "CMD" for a fvwm CMD to use on the Regenerate item. # Default: PipeRead `fvwm-menu-desktop` # - Added --include-items [config|regenerate|both|none] option # to control if the additional items are included in the menu. # - Added --dynamic option to be used with dynamic menus. # - Added --all-menus option to generate all menus and not try to determine # which one is best # - Changed default behavior to include menu titles. # - Added new option --without-titles # Changed on 25/02/14 by Thomas Funk: # - Converting of icons always to png # Changed on 06/10/13 by Thomas Funk: # Some Bugfixes: # - DecodeEncodeErrors in menu names # - no output appears with 'fvwm-menu-desktop --get-menus all|desktop' # - No entry "Regenerate XDG menu(s)" appears with # 'fvwm-menu-desktop --insert-in-menu MenuRoot' # - exchange all tabs with spaces to prevent indention errors # - add two new options: --app-icon --dir-icon # to handle default icons for not available app/dir icons # - fix bug in convert icon routine that background of svg icons are # transparent # Changed on 15/06/13 by Thomas Funk: # support for python-xdg > 0.19. # add gettext localization. # Changed on 10/01/12 by Thomas Funk: # Unicode support. # Changed on 01/26/12 by Dan Espen (dane): # Make compatible with fvwm-menu-desktop. # Restored DestroyMenu, needed for reload menus. # Remove bug, was printing iconpath on converted icons # Replace obsolete optparse, use getopt instead # Change from command line arg for applications.menu # change to using ?$XDG_MENU_PREFIX or theme? fixme # - use "Exec exec" for all commands, remove option. # fixme, fix documentation, FvwmForm-Desktop, usage prompt is wrong # change, mini icons are enabled by default. # there are rescalable icons. # Author: Piotr Zielinski (http://www.cl.cam.ac.uk/~pz215/) # Licence: GPL 2 # Date: 03.12.2005 # This script takes names of menu files conforming to the XDG Desktop # Menu Specification, and outputs their FVWM equivalents to the # standard output. # # http://standards.freedesktop.org/menu-spec/latest/ # This script requires the python-xdg module, which in Debian can be # installed by typing # # apt-get install python-xdg # # On Fedora, python-xdg is installed by default. import sys import getopt import xdg.Menu import xdg.IconTheme import xdg.Locale import os.path import os from xdg.DesktopEntry import * from xdg.BaseDirectory import * import fnmatch import time def main (): description = """ Generate Fvwm Menu from xdg files. Standard output is a series Fvwm commands.""" obs_args=['check-app', 'enable-style', 'enable-tran-style', 'fvwm-icons', 'kde_config', 'mini-icon-path', 'merge-user-menu', 'su_gui', 'utf8', 'wm-icons'] dashed_obs_args=[] for a in obs_args : dashed_obs_args.append('--'+a) obs_parms=['check-icons', 'check-mini-icon', 'destroy-type', 'dir', 'icon-app', 'icon-folder', 'icon-style', 'icon-title', 'icon-toptitle', 'icons-path', 'lang', 'menu-style', 'name', 'png-icons-path', 'submenu-name-prefix', 'time-limit', 'tran-icons-path', 'tran-mini-icons-path', 'type', 'uniconv-exec', 'uniconv', 'xterm'] equaled_obs_parms=[] for a in obs_parms : equaled_obs_parms.append(a+'=') dashed_obs_parms=[] for a in obs_parms : dashed_obs_parms.append('--'+a) try: opts, args = getopt.getopt(sys.argv[1:], "hs:t:vw", ["help", "verbose", "enable-mini-icons", "with-titles", "without-titles", "version", "desktop=", "size=", "theme=", "install-prefix=", "menu-type=", "regen-cmd=", "title=", "get-menus=", "set-menus=", "insert-in-menu=", "mini-icon-dir=", "app-icon=", "dir-icon=", "include-items=", "dynamic", "all-menus"]+obs_args+equaled_obs_parms) except getopt.GetoptError, err: # print help information and exit: print str(err) # will print something like "option -a not recognized" print usage sys.exit(2) global verbose, force, size, current_theme, icon_dir, top, install_prefix, menu_type, menu_list_length global with_titles, menu_entry_count, get_menus, timestamp, set_menus, printmode, insert_in_menu, previous_theme global default_app_icon, default_dir_icon, include_items, config_menus, regen_cmd, dynamic_menu, build_all_menus version = "2.3.3" verbose = False force = False desktop='' size=24 current_theme='gnome' previous_theme='gnome' icon_dir="~/.fvwm/icons" top='XDGMenu' insert_in_menu = False install_prefix = '' menu_type = '' with_titles = True menu_entry_count = 0 menu_list_length = 0 get_menus = '' printmode = True set_menus = [] build_all_menus = False config_menus = [] default_app_icon = "gnome-applications" default_dir_icon = "gnome-fs-directory" include_items = 'both' regen_cmd = 'PipeRead `fvwm-menu-desktop`' dynamic_menu = False # Loads config options from $FVWM_USERDIR/.FvwmForm-XDGMenu-Config if os.path.isfile("%s/.FvwmForm-XDGMenu-Config" % os.environ['FVWM_USERDIR']): fvwmform_config = open("%s/.FvwmForm-XDGMenu-Config" % os.environ['FVWM_USERDIR'], "r") for l in fvwmform_config: o = l.split() if len(o)>2 and o[0] != '#': if o[1][:3] == 'MEN' and o[2] == 'on': config_menus.append(o[1][3:]) if o[1] == 'IconsOn' and o[2] == 'on': force = True elif o[1] == 'Size': size = o[2] elif o[1] == 'TitlesOn' and o[2] == 'on': with_titles = True elif o[1] == 'Theme': current_theme = o[2] elif o[1] == 'Title': top = o[2] elif o[1] == 'InsertInto': top = o[2] insert_in_menu = True elif o[1] == 'Installprefix': install_prefix = o[2] elif o[1] == 'IconDir': icon_dir = o[2] elif o[1] == 'DirIcon': default_dir_icon = o[2] elif o[1] == 'AppIcon': default_app_icon = o[2] elif o[1] == 'IncludeConfig' and o[2] == 'on': include_items = "config" elif o[1] == 'IncludeRegen' and o[2] == 'on': include_items = "regenerate" elif o[1] == 'IncludeBoth' and o[2] == 'on': include_items = "both" elif o[1] == 'IncludeNone' and o[2] == 'on': include_items = "none" fvwmform_config.close() for o, a in opts: if o == "-v": verbose = True elif o in ("-h", "--help") : print usage sys.exit() elif o in ("--version") : print "fvwm-menu-desktop version " + version sys.exit() elif o in ("--enable-mini-icons") : force=True elif o in ("--insert-in-menu") : top=a insert_in_menu = True elif o in ("--desktop") : desktop=a elif o in ("-t", "--title") : top=a elif o in ("--get-menus") : if a == 'all' or a == 'desktop' : get_menus=a printmode = False else : sys.stderr.write( "--get-menus argument must be 'all' or 'desktop' found "+a ) print usage sys.exit(1) elif o in ("-s","--size") : size = int(a) elif o in ("--mini-icon-dir") : icon_dir = a elif o in ("--set-menus") : if a[-1] == ' ': a = a[:-1] set_menus=a.split(' ') elif o in ("--install-prefix") : if a and not os.path.isabs(a): assert False, "install-prefix must be an absolute path" # add trailing slash if not there already if not a[-1] == '/' : # trailing slash a=a + '/' install_prefix = a elif o in ("--theme") : current_theme = a elif o in ("--menu-type") : menu_type = a elif o in ("-w","--with-titles") : with_titles = True elif o in ("-w","--without-titles") : with_titles = False elif o in ("--verbose") : verbose = True elif o in ("--app-icon") : default_app_icon = a elif o in ("--dir-icon") : default_dir_icon = a elif o in ("--include-items") : if a in ("both", "none", "config", "regenerate") : include_items = a else: sys.stderr.write( "--include-items argument must be 'config', 'regenerate', 'both' or 'none' found "+a ) print usage sys.exit(1) elif o in ("--regen-cmd") : regen_cmd = a elif o in ("--dynamic") : dynamic_menu = True elif o in ("--all-menus") : build_all_menus = True elif o in (str(dashed_obs_args+dashed_obs_parms)) : # Ignore sys.stderr.write( "Warning: Arg "+o+" is obsolete and ignored\n" ) else: assert False, "unhandled option" timestamp = time.time() if len(set_menus) == 0: xdg_menu_prefix = ((os.environ['XDG_MENU_PREFIX'] if os.environ.has_key('XDG_MENU_PREFIX') else '')) # First check if no user presettings made if desktop == '': # check if $XDG_MENU_PREFIX is set if not xdg_menu_prefix == '': desktop = xdg_menu_prefix.replace('-', '').lower() vprint("Parameters for creating menu list:") vprint(" XDG_MENU_PREFIX: \'%s\'" %xdg_menu_prefix) vprint(" --install-prefix: \'%s\'" %install_prefix) vprint(" --desktop: \'%s\'" %desktop) vprint(" --menu-type: \'%s\'" %menu_type) vprint("\nStart search ...") menulist, desktop_temp = getmenulist(desktop, menu_type) if not desktop_temp == '': desktop = desktop_temp else: menulist = set_menus vprint(" Menu list: %s\n" %menulist) menu_list_length = len(menulist) if menu_list_length == 0: if not desktop == '': desktop = desktop + '-' sys.stderr.write(install_prefix+desktop+menu_type+".menu not available on this system. Exiting...\n") sys.exit(1) else: # set previous_theme if /.theme exist if os.path.exists(os.path.join(os.path.expanduser(icon_dir), ".theme")): previous_theme = next(open(os.path.join(os.path.expanduser(icon_dir), ".theme"), 'r')).replace('\n', '') vprint(" Previous used theme: %s" %previous_theme) vprint(" Current used theme: %s" %current_theme) parsemenus(menulist, desktop) # write current_theme to /.theme if --enable-mini-icons and printmode is set if printmode and force: fh = open(os.path.join(os.path.expanduser(icon_dir), ".theme"), "w") fh.write(current_theme) fh.close() vprint("\nProcess took " + str(time.time()-timestamp) + " seconds") def getmenulist(desktop, menu_type): menudict = {} config_dirs = [] if not install_prefix == '': config_dirs = [install_prefix] else: config_dirs = xdg_config_dirs # xdg_config_dirs is a built-in list from python-xdg found_menus = 0 for dir in config_dirs: if install_prefix == '': dir = os.path.join(dir, 'menus') # skipping all paths which not available if os.path.exists(dir): filelist = set([]) dir_list = os.listdir(dir) #pattern = '*'+desktop+'*'+menu_type+'*.menu' # Always find all menus pattern = '*.menu' for filename in fnmatch.filter(dir_list, pattern): filelist.add(filename) # the menudict dictionary has a unsorted list (set) for the values. # set is easier to use then a list for removing items menudict[dir] = filelist found_menus += len(filelist) vprint(" found in %s: %s" %(dir, list(filelist))) desktop_dict = {} if not found_menus == 0: all_menus = [] # remove all menus in /etc/xdg/menus if exist in user dir for path in menudict.keys(): if not path == '/etc/xdg/menus': if path == os.path.join(os.getenv("HOME"), '.config/menus'): menudict['/etc/xdg/menus'] = menudict['/etc/xdg/menus'] - menudict[path] #else: # menudict[path] = menudict[path] - menudict['/etc/xdg/menus'] for menu in list(menudict[path]): all_menus.append(path + '/' + menu) if not menudict['/etc/xdg/menus'] == 0: for menu in list(menudict['/etc/xdg/menus']): all_menus.append('/etc/xdg/menus/' + menu) if get_menus == 'all' or (build_all_menus and desktop == '' and menu_type == ''): return all_menus, '' # get menus selected in config file if len(config_menus) > 0: config_menulist = [] for i in config_menus: for j in all_menus: if fnmatch.fnmatch( j, "*%s.menu" % i ): config_menulist.append(j) vprint("\n Selected menus from config file: %s " % list(config_menulist)) # Use config file if --dekstop not set if len(config_menulist) == 0: vprint(" No menus in config found. Using all menus.") elif desktop == '' and menu_type == '': vprint(" Using menus from config file.") return config_menulist, '' else: vprint(" Ignoring menus in config file, due to --desktop or --menu-type.") # filter --desktop and --menu-type options if desktop != '' or menu_type != '': vprint("\n Filtering menus according to --desktop %s and --menu-type %s" % (desktop, menu_type) ) pattern = '*'+desktop+'*'+menu_type+'*' for path in menudict.keys(): for menu in list(menudict[path]): if not fnmatch.fnmatch( menu, pattern ): menudict[path].remove(menu) if menudict[path] == set([]): del menudict[path] if menudict == {}: sys.stderr.write("No menus found matching --desktop %s and --menu-type %s. Exiting...\n" % (desktop, menu_type) ) sys.exit(1) vprint("\n Finding best menu in Menu List: %s" % menudict ) if build_all_menus: all_menus = [] for key in menudict: for i in menudict[key]: all_menus.append(key+'/'+i) return all_menus, '' # sort menus related to desktops and create a weighting vprint("\n DE weighting search: DE => [user menus, system menus, overall]") weight_dict = {} if desktop == '': # first the desktops, then debian (shouldn't appear in others) then others holding # all other non DE menus e.g. tools and at the end the nones without prefixes # If there're other prefixes from other WMs - should be added BEFORE debian DEs = ['gnome', 'kde', 'xfce', 'lxde', 'cinnamon', 'mate', 'debian', 'others', 'none'] else: DEs = [desktop] for de in DEs: menus = set([]) user_menus = 0 system_menus = 0 filled = False for path in menudict.keys(): if de == 'none': pattern = '*' elif de == 'others': pattern = '*-*' else: pattern = '*'+de+'*' # fnmatch.filter returns a list of files the pattern match menu_names = fnmatch.filter(menudict[path], pattern) if not len(menu_names) == 0: filled = True for name in menu_names: menus.add(path+'/'+name) # delete each found DE menu from the actual path. So, the menus will be reduced loop by loop. menudict[path] = menudict[path]-set(menu_names) # count the menus found in the users and systems menu path for later weighting if not path == '/etc/xdg/menus': user_menus = len(menu_names) else: system_menus = len(menu_names) if filled: desktop_dict[de] = menus filled = False # fill the weight dictionary with the counts weight_dict[de] = [user_menus, system_menus, user_menus+system_menus] vprint(" %s => %s" %(de, weight_dict[de])) # get the highest rated desktop highest = 0 de_highest = '' for de in sorted(weight_dict.keys()): de_user = weight_dict[de][0] de_system = weight_dict[de][1] de_total = weight_dict[de][2] higher = False if not de_highest == '': # don't weight 'none' and 'others cause both not DEs if not de == 'none' and not de == 'others': highest_user = weight_dict[de_highest][0] highest_system = weight_dict[de_highest][1] highest_total = weight_dict[de_highest][2] # first compare the total counts if highest < de_total: higher = True elif highest == de_total: # if the totals equal compare the users if highest_user < de_user: higher = True elif highest_user == de_user: # it the users equal compare the system menus if highest_system < de_system: higher = True # if the systems equal the last wins elif highest_system == de_system: higher = True # fixme, should be biunique. -but how? With atime? else: higher = True if higher: highest = de_total de_highest = de if highest == 0 : # no dev environments? de_highest = 'others' # use 'others' vprint( "\n Winner: %s" %de_highest) # Perhaps there're a global menus available which are not in the highest rated list if desktop_dict.has_key('none'): for menu in desktop_dict['none']: name = menu.replace('.menu', '').split('/') # the fnmatch.filter will be used to find NO match because then # the menu is not in the list found = fnmatch.filter(desktop_dict[de_highest], '*'+name[-1]+'*') if found == []: desktop_dict[de_highest].add(menu) # Add 'others' menus to list, because these could be tool menus like yast, etc if desktop_dict.has_key('others'): for menu in desktop_dict['others']: desktop_dict[de_highest].add(menu) if len(desktop_dict) == 0: return [], '' else: return list(desktop_dict[de_highest]), de_highest def vprint(text): if verbose: sys.stderr.write(text+"\n") def printtext(text, encodetext=True): if encodetext: print text.encode("utf-8") else: print text # fix unicode decode problem like # UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position xyz: ordinal not in range(128) def decodetext(text): old_stdout = sys.stdout fnull = open(os.devnull, 'w') sys.stdout = fnull try: new_text = text.encode("utf-8") printtext('%s' % text) except UnicodeDecodeError: try: unicode_text = text.decode("iso-8859-15") text = "%s" % unicode_text new_text = text.encode("iso-8859-15") print new_text except: new_text = None fnull.close() sys.stdout = old_stdout return new_text def geticonfile(icon): iconpath = xdg.IconTheme.getIconPath(icon, size, current_theme, ["png", "xpm", "svg"]) if not iconpath == None: extension = os.path.splitext(iconpath)[1] if not iconpath: return None if not force: return iconpath if iconpath.find("%ix%i" % (size, size)) >= 0: # ugly hack!!! return iconpath if not os.path.isdir(os.path.expanduser(icon_dir)): os.makedirs(os.path.expanduser(icon_dir)) iconfile = os.path.join(os.path.expanduser(icon_dir), "%ix%i-" % (size, size) + os.path.basename(iconpath)) if os.path.exists(iconpath): iconfile = iconfile.replace(extension, '.png') if extension == '.svg': os.system("if test \\( \\( ! -f '%s' \\) -o \\( '%s' -nt '%s' \\) \\) -o \\( '%s' != '%s' \\); then convert -background none '%s' -resize %i '%s' ; fi"% (iconfile, iconpath, iconfile, current_theme, previous_theme, iconpath, size, iconfile)) else: os.system("if test \\( \\( ! -f '%s' \\) -o \\( '%s' -nt '%s' \\) \\) -o \\( '%s' != '%s' \\); then convert '%s' -resize %i '%s' ; fi"% (iconfile, iconpath, iconfile, current_theme, previous_theme, iconpath, size, iconfile)) else: sys.stderr.write("%s not found! Using default icon.\n" % iconpath) return None return iconfile def getdefaulticonfile(command): if command.startswith("Popup"): return geticonfile(default_dir_icon) else: return geticonfile(default_app_icon) def printmenu(name, icon, command): iconfile = '' if force : iconfile = geticonfile(icon) or getdefaulticonfile(command) or icon if not (iconfile == '' or iconfile == None): iconfile = '%'+iconfile+'%' else: sys.stderr.write("%s icon or default icon not found!\n") name = decodetext(name) command = decodetext(command) iconfile = decodetext(iconfile) if not (name == None or command == None or iconfile == None): printtext('+ "%s%s" %s' % (name, iconfile, command), False) else: sys.stderr.write("A menu entry cannot decode! Skipping ...\n") printtext('# Decode Error! Menu entry skipped.') def parsemenus(menulist, desktop): global menu_entry_count if menu_list_length == 1: new_menulist = menulist # user defines only one special menu parsemenu(xdg.Menu.parse(menulist[0]), top) else: # create a top title list top_titles = [] for file in menulist: # extract and split the filename and set first char of each word to capital name_parts = file.replace('.menu', '').split('/')[-1].split('-') name_parts = [name[0].replace(name[0], name[0].upper())+name[1:] for name in name_parts] top_titles.append(' '.join(name_parts)) # create the submenus new_toptitles = [] new_menulist = [] for title, menu in zip(top_titles, menulist): name = 'Fvwm'+title vprint("Create submenu \'%s\' from \'%s\'" %(name, menu)) parsemenu(xdg.Menu.parse(menu), name, title) # remove a menu if no menu entry was created in its sub menus if not menu_entry_count == 0: new_toptitles.append(title) new_menulist.append(menu) menu_entry_count = 0 else: vprint(" Menu is empty - won't be used!") # create the root menu if printmode: if not insert_in_menu: if dynamic_menu: printtext('DestroyMenu recreate "%s"' % top) else: printtext('DestroyMenu "%s"' % top) if with_titles and not insert_in_menu: printtext('AddToMenu "%s" "%s" Title' % (top, top)) else: printtext('AddToMenu "%s"' % top) for title in sorted(new_toptitles): name = 'Fvwm'+title printmenu(title, '', 'Popup "%s"' % name) if include_items != 'none': printtext('+ "" Nop') if include_items in ("both", "regenerate"): printmenu("$[gt.Regenerate]", "system-software-update", regen_cmd ) if include_items in ("both", "config"): printmenu("$[gt.Configure]", "system-software-update", "Module FvwmPerl -l fvwm-menu-desktop-config.fpl" ) if not get_menus == '': printtext('%s' % ' '.join(new_menulist)) def parsemenu(menu, name="", title=""): global menu_entry_count m = re.compile('%[A-Z]?', re.I) # Pattern for %A-Z (meant for %U) if not name : name = menu.getPath() if not title: title = name if printmode: name = decodetext(name) title = decodetext(title) if not (name == None or title == None): if not insert_in_menu or not (insert_in_menu and name == top and menu_list_length == 1): if name == top and dynamic_menu: printtext('DestroyMenu recreate "%s"' % name, False) else: printtext('DestroyMenu "%s"' % name, False) if with_titles: # for insert-in-menu AddToMenu doesn't have a title for top menu # because this will appear then in the other menu if insert_in_menu and name == top and menu_list_length == 1: printtext('AddToMenu "%s"' % name, False) else: printtext('AddToMenu "%s" "%s" Title' % (name, title), False) else: printtext('AddToMenu "%s"' % name, False) else: sys.stderr.write("A menu entry cannot decode! Skipping ...\n") printtext('# Decode Error! Menu entry skipped.') for entry in menu.getEntries(): if isinstance(entry, xdg.Menu.Menu): if printmode: printmenu(entry.getName(), entry.getIcon(), 'Popup "%s"' % entry.getPath()) elif isinstance(entry, xdg.Menu.MenuEntry): if printmode: desktop = DesktopEntry(entry.DesktopEntry.getFileName()) # eliminate '%U' etc behind execute string execProgram = m.sub('', desktop.getExec()) printmenu(desktop.getName(), desktop.getIcon(), "Exec exec " + " " + execProgram) menu_entry_count += 1 else: if printmode: printtext('# not supported: ' + str(entry)) if printmode: # should only appear in a single menu. For more it will insert in parsemenus() when the top menu will built if menu_list_length == 1 and name == top and include_items != 'none': printtext('+ "" Nop') if include_items in ("both", "regenerate"): printmenu("$[gt.Regenerate]", "system-software-update", regen_cmd ) if include_items in ("both", "config"): printmenu("$[gt.Configure]", "system-software-update", "Module FvwmPerl -l fvwm-menu-desktop-config.fpl" ) printtext('') for entry in menu.getEntries(): if isinstance(entry, xdg.Menu.Menu): parsemenu(entry) usage=""" A script which parses xdg menu definitions to build the corresponding fvwm menus. Usage: $0 [OPTIONS] Options: -h, --help show this help and exit. --version show version and exit. --install-prefix DIR install prefix of the desktop menu files. Per default not set. For system wide menus use /etc/xdg/menus/. --desktop NAME use menus that include NAME in the file name: gnome, kde, xfce, lxde, debian, etc. --menu-type NAME use menus that include NAME in the file name: applications, settings, preferences, etc. When used with --desktop only menus whose file name mathces '*desktop*menutype*' are used. --theme NAME icon theme: gnome (default), oxygen, etc. Don't use hicolor. It's the default fallback theme if no icon is found. -w, --with-titles generate menus with titles. Default. --without-titles generate menus without titles. --enable-mini-icons enable mini-icons in menu. -s, --size NUM set size of mini-icons in menu. Default is 24. --mini-icon-dir DIR set directory for mini-icons. Default is ~/.fvwm/icons. --app-icon NAME set default application icon if no others found. Default is 'gnome-applications'. --dir-icon NAME set default directory icon if no others found. Default is 'gnome-fs-directory'. -t, --title NAME menu title of the top menu used by Popup command. Default is XDGMenu. --insert-in-menu NAME generates a menu to place it in the root level of the menu NAME. --get-menus all|desktop prints a space separated list of full menu paths. 'all' is all menus on the system except empty ones. 'desktop' list the menus that would have been generated. No menu generation is done. --set-menus menu_paths expects a space separated list of full menu paths to generate user specified menus. --all-menus generate all menus found. --include-items NAME include additional menu items NAME in top level menu. NAME can be 'config', 'regenerate', 'both' or 'none'. Default both. --regen-cmd ACTION The fvwm ACTION for the 'Regenerate' menu item. Default: 'PipeRead `fvwm-menu-desktop`' --dynamic used with dynamic menus. -v, --verbose run and display debug info on STDERR.""" if __name__ == "__main__": main() # Local Variables: # mode: python # compile-command: "python fvwm-menu-desktop.in --enable-mini-icons --with-titles" # End: fvwm-2.6.7/bin/fvwm-convert-2.6.10000644000175700017570000000710013010101137013217 00000000000000.\" @(#)fvwm-2.6.7 06 November 2016 .TH fvwm-convert-2.6 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .SH NAME fvwm-convert-2.6 \- convert fvwm 2.4.x configuration file to fvwm 2.6 style .SH SYNOPSIS .B fvwm-convert-2.6 .RI [ --follow-read | -f ] .RI [ --help | -h ] .RI source .RI [ dest ] .SH OPTIONS The following options are supported: .IP "\fB\-\-help\fR | \fB\-h\fR" Prints a usage message to the screen. .IP "\fB\-\-follow\-read\fR | \fB\-f\fR" Follows files found along with the .B Read command. .SH DESCRIPTION .B fvwm-convert-2.6 converts an fvwm 2.4.x configuration file into a fvwm 2.6 file with compatible syntax. It is not suitable to convert older 2.x configuration files. Please use .B fvwm-convert-2.2 to convert these to the 2.2.x format first, and then if necessary .B fvwm-convert-2.4 .PP By default, .B fvwm-convert-2.6 won't look for a given config file. This must be specified as the first parameter to .B fvwm-convert-2.6. Different source and destination files may be given. If the destination file already exists, this program exits. If no destination file is given, then the filename is the same name as the source file with the suffix ".converted" added. Without an absolute path given as the destination path to the destination file, the program will create the destination file in the CWD. .PP .B fvwm-convert-2.6 makes the following changes: .TP 4 .B Style lines In fvwm 2.4, most style options could be negated from their counterparts using NoFoo -- fvwm-convert-2.6 corrects this by now using !Foo. .TP 4 .B ModulePath In fvwm 2.4 and beyond, the ModulePath is compiled into fvwm. .B fvwm-convert-2.6 comments out any ModulePath commands it finds. If you are using your own modules, (not the ones that come with fvwm), you will have to fix your configuration file after using .BR fvwm-convert-2.6 . .TP 4 .B Conditional command syntax In fvwm 2.4, the conditional command options were whitespace-separated -- they should now be comma-separated instead. In addition, the older syntax to Next and Prev of using [*] to denote all windows has been removed entirely. Both these checks and conversions are done on function commands, key/mouse bindings. .TP 4 .B WindowShadeSteps In fvwm 2.4, the WindowShadeSteps command is replaced by the WindowShadeSteps Style option. .B fvwm-convert-2.6 makes this change. .TP 4 .B FvwmTheme In fvwm 2.6, the FvwmTheme module is replaced by a series of Colorset commands. Whilst .B fvwm-convert-2.6 will try and make this change, it is still recommended that this is checked after conversion. .TP 4 .B EdgeResistance In fvwm 2.6, the EdgeResistance command is has been split to include an additional style option for EdgeMoveResistance. .B fvwm-convert-2.6 makes any changes necessary. .TP 4 .B StartFunction / RestartFunction / InitFunction In fvwm 2.6, the need for using InitFunction and/or RestartFunction is redundant when StartFunction is read at both of these times. .B fvwm-convert-2.6 attempts to convert this. .TP 4 .B Read If .B -f or .B --follow-read is given, any files .B fvwm-convert-2.6 can detect and open will be converted automatically, else a list of files that can be followed are printed to the screen. .TP 4 .SH BUGS .I InitFunction and .I RestartFunction and hence .I StartFunction are printed at the end of the files -- this slight reordering might put some comments before in an odd spot. When converting over FvwmTheme lines, the colorset definitions might well be broken, but these cannot easily be converted. Bug reports can be sent to the fvwm-workers mailing list (see the .IR FAQ ). .SH AUTHOR Thomas Adam fvwm-2.6.7/bin/fvwm-menu-desktop-config.fpl0000644000175700017570000002650713006057357015572 00000000000000# Uage: Module FvwmPerl -l fvwm-menu-desktop-config.fpl # This script generates an FvwmForm similar to the FvwmForm-Desktop by # Dan Espen but inserts the found xdg menus dynamically into the Form # before processed. # Author: Thomas Funk # Version: 1.4 package MenuConfig; use File::Basename; use strict; use warnings; #open(MSG ,">>/tmp/log.txt") || die "Error $!"; my $modname = 'FvwmForm-XDGMenu-Config'; my $all = `fvwm-menu-desktop --get-menus all`; my $selected = `fvwm-menu-desktop --get-menus desktop`; my @all_filelist = split(/ /,$all); my @selected_filelist = split(/ /,$selected); my %all_menus = (); my %selected__menus = (); my $max_length = 0; foreach my $path (@selected_filelist) { my ($filename, $directories, $suffix) = fileparse($path, qr/\.[^.]*/); push (@{$selected__menus{$directories}}, $filename); } my $i = 1; foreach my $path (@all_filelist) { # qr matched against the end of the $filename. # The matching portion is removed and becomes the $suffix. my ($filename, $directories, $suffix) = fileparse($path, qr/\.[^.]*/); my $name = "MEN" . $filename; push (@{$all_menus{$directories}{$i}}, ($filename, $name, "off")); next if !defined $selected__menus{$directories}; foreach my $hit (@{$selected__menus{$directories}}) { if ($filename eq $hit) { pop (@{$all_menus{$directories}{$i}}); push (@{$all_menus{$directories}{$i}}, "on"); } } $max_length = length($filename) if ($max_length < length($filename)); $i++; } my $fvwmform_commands = " DestroyModuleConfig ${modname}: * *${modname}: Title \"\$[gt.Fvwm XDGMenu Config]\" *${modname}: WarpPointer #*${modname}: Line center #*${modname}: Text \"\$[gt.Fvwm XDGMenu Config]\" #*${modname}: Line *${modname}: Separator *${modname}: Line center *${modname}: Text \"\$[gt.Available Menus]\" *${modname}: Line "; if (scalar keys %all_menus != 0) { foreach my $key (sort( keys %all_menus)) { $fvwmform_commands .= " *${modname}: Line left *${modname}: Text \"\$[gt.Menus in]\" *${modname}: Text \" $key\" *${modname}: Line left *${modname}: Selection meth multiple "; my $m_count = 0; foreach my $count (sort(keys %{$all_menus{$key}})) { my $menu = $all_menus{$key}{$count}; my $newstring = $menu->[0] . ' ' x eval($max_length-length($menu->[0])); $fvwmform_commands .= "*${modname}: Choice $menu->[1] $menu->[1] $menu->[2] \"$newstring\" "; $m_count++; if ($m_count == 4) { $fvwmform_commands .= " *${modname}: Line left *${modname}: Selection meth multiple "; $m_count = 0; } } $fvwmform_commands .= " *${modname}: Line left *${modname}: Text \" \" "; } } else { $fvwmform_commands .= " *${modname}: Line center *${modname}: Text \"\$[gt.No menus found! Check why from within a terminal with]\" *${modname}: Line center *${modname}: Text \"'fvwm-menu-desktop -v'\" *${modname}: Line left *${modname}: Text \" \" "; } $fvwmform_commands .= " *${modname}: Separator *${modname}: Line center *${modname}: Text \"\$[gt.Options]\" *${modname}: Button continue \"\$[gt.Help]\" *${modname}: Command Module FvwmForm FvwmForm-XDGOptionsHelp *${modname}: Line *${modname}: Line Left *${modname}: Text \"\$[gt.Include in Menu? ]\" *${modname}: Selection SelItype single *${modname}: Choice IncludeConfig IncludeConfig off \"\$[gt.Config ]\" *${modname}: Choice IncludeRegen IncludeRegen off \"\$[gt.Regenerate ]\" *${modname}: Choice IncludeBoth IncludeBoth on \"\$[gt.Both ]\" *${modname}: Choice IncludeNone IncludeNone off \"\$[gt.None ]\" *${modname}: Line Left *${modname}: Text \"\$[gt.Use Icons? ]\" *${modname}: Selection SelItype single *${modname}: Choice IconsOn IconsOn off \"\$[gt.Yes ]\" *${modname}: Choice IconsOff IconsOff on \"\$[gt.No ]\" *${modname}: Text \"\$[gt. ]\" *${modname}: Text \"\$[gt.Icon size: ]\" *${modname}: Input Size 2 \"\" *${modname}: Text \"\$[gt. (Default is 24)]\" *${modname}: Line Left *${modname}: Text \"\$[gt.Use Titles? ]\" *${modname}: Selection SelItype single *${modname}: Choice TitlesOn TitlesOn on \"\$[gt.Yes ]\" *${modname}: Choice TitlesOff TitlesOff off \"\$[gt.No ]\" *${modname}: Text \"\$[gt. ]\" *${modname}: Text \"\$[gt.Used Icon theme: ]\" *${modname}: Input Theme 20 \"\" *${modname}: Line left *${modname}: Text \"\$[gt.Directory Icon: ]\" *${modname}: Input DirIcon 20 \"gnome-fs-directory\" *${modname}: Text \"\$[gt. ]\" *${modname}: Text \"\$[gt.Application Icon: ]\" *${modname}: Input AppIcon 20 \"gnome-applications\" *${modname}: Line left *${modname}: Text \"\$[gt.Top Menu Name: ]\" *${modname}: Input Title 20 \"XDGMenu\" *${modname}: Text \"\$[gt. ]\" *${modname}: Text \"\$[gt.Insert Menu Into: ]\" *${modname}: Input InsertInto 20 \"\" *${modname}: Line left *${modname}: Text \"\$[gt.Icon directory: ]\" *${modname}: Input IconDir 30 \"~/.fvwm/icons\" *${modname}: Text \"\$[gt. (Directory for converted icons)]\" *${modname}: Line left *${modname}: Text \"\$[gt.Output path: ]\" *${modname}: Input Path 30 \"\$FVWM_USERDIR/.XDGMenu\" *${modname}: Text \"\$[gt. (Full path to store output)]\" *${modname}: Line left *${modname}: Line *${modname}: Separator *${modname}: Line *${modname}: Line expand *${modname}: Button continue \"\$[gt.Save Menu]\" *${modname}: Command PipeRead 'fvwm-menu-desktop \\ \$(IconsOn\?--enable-mini-icons )\\ \$(Size\?-s \$(Size) )\\ \$(TitlesOn\?--with-titles )\\ \$(TitlesOff\?--without-titles )\\ --include-items \$(IncludeConfig\?config)\\ \$(IncludeRegen\?regenerate)\\ \$(IncludeBoth\?both)\\ \$(IncludeNone\?none) \\ \$(IconDir\?--mini-icon-dir \$(IconDir) )\\ \$(DirIcon\?--dir-icon \$(DirIcon) )\\ \$(AppIcon\?--app-icon \$(AppIcon) )\\ \$(InsertInto\?--insert-in-menu \$(InsertInto) )\\ \$(Title\?--title \$(Title) )\\ \$(Theme\?--theme \$(Theme) )\\ --set-menus \"\\ "; foreach my $key (keys %all_menus) { foreach my $file (keys %{$all_menus{$key}}) { my $menu = $all_menus{$key}{$file}; $fvwmform_commands .= "\$($menu->[1]\?$key$menu->[0].menu )\\\n"; } } $fvwmform_commands .= "\" \$(Path\? > \$(Path)) 2>> ~/.xsession-errors && echo \"Read \$(Path\? \$(Path))\"' *${modname}: Button continue \"\$[gt.Save and Regenerate]\" # Before saving the data, remove any previously saved data: *${modname}: Command DestroyModuleConfig ${modname}Default: * *${modname}: Command !( /bin/echo \\ \"# This file last created by ${modname} on: `/bin/date`.\"; /bin/echo \\ "; foreach my $key (keys %all_menus) { foreach my $count (keys %{$all_menus{$key}}) { my $menu = $all_menus{$key}{$count}; $fvwmform_commands .= " '*${modname}Default: $menu->[1] \$($menu->[1]\?on) ' ; /bin/echo \\ "; } } $fvwmform_commands .= ") > \$FVWM_USERDIR/.${modname} *${modname}: Command !(/bin/echo \\ '*${modname}Default: IncludeConfig\$(IncludeConfig\?on) ' ; /bin/echo \\ '*${modname}Default: IncludeRegen \$(IncludeRegen\?on) ' ; /bin/echo \\ '*${modname}Default: IncludeBoth \$(IncludeBoth\?on) ' ; /bin/echo \\ '*${modname}Default: IncludeNone \$(IncludeNone\?on) ' ; /bin/echo \\ '*${modname}Default: IconsOn \$(IconsOn\?on) ' ; /bin/echo \\ '*${modname}Default: IconsOff \$(IconsOff\?on) ' ; /bin/echo \\ '*${modname}Default: Size \$(Size) ' ; /bin/echo \\ '*${modname}Default: TitlesOn \$(TitlesOn\?on) ' ; /bin/echo \\ '*${modname}Default: TitlesOff \$(TitlesOff\?on) ' ; /bin/echo \\ '*${modname}Default: Theme \$(Theme) ' \\ ) >> \$FVWM_USERDIR/.${modname} *${modname}: Command !(/bin/echo \\ '*${modname}Default: Title \$(Title) ' ; /bin/echo \\ '*${modname}Default: InsertInto \$(InsertInto) ' ; /bin/echo \\ '*${modname}Default: Path \$(Path) ' ; /bin/echo \\ '*${modname}Default: IconDir \$(IconDir) ' ; /bin/echo \\ '*${modname}Default: DirIcon \$(DirIcon) ' ; /bin/echo \\ '*${modname}Default: AppIcon \$(AppIcon) ' \\ ) >> \$FVWM_USERDIR/.${modname} *${modname}: Command PipeRead 'fvwm-menu-desktop' *${modname}: Button continue \"\$[gt.Save]\" # Before saving the data, remove any previously saved data: *${modname}: Command DestroyModuleConfig ${modname}Default: * *${modname}: Command !( /bin/echo \\ \"# This file last created by ${modname} on: `/bin/date`.\"; /bin/echo \\ "; foreach my $key (keys %all_menus) { foreach my $count (keys %{$all_menus{$key}}) { my $menu = $all_menus{$key}{$count}; $fvwmform_commands .= " '*${modname}Default: $menu->[1] \$($menu->[1]\?on) ' ; /bin/echo \\ "; } } $fvwmform_commands .= ") > \$FVWM_USERDIR/.${modname} *${modname}: Command !(/bin/echo \\ '*${modname}Default: IncludeConfig\$(IncludeConfig\?on) ' ; /bin/echo \\ '*${modname}Default: IncludeRegen \$(IncludeRegen\?on) ' ; /bin/echo \\ '*${modname}Default: IncludeBoth \$(IncludeBoth\?on) ' ; /bin/echo \\ '*${modname}Default: IncludeNone \$(IncludeNone\?on) ' ; /bin/echo \\ '*${modname}Default: IconsOn \$(IconsOn\?on) ' ; /bin/echo \\ '*${modname}Default: IconsOff \$(IconsOff\?on) ' ; /bin/echo \\ '*${modname}Default: Size \$(Size) ' ; /bin/echo \\ '*${modname}Default: TitlesOn \$(TitlesOn\?on) ' ; /bin/echo \\ '*${modname}Default: TitlesOff \$(TitlesOff\?on) ' ; /bin/echo \\ '*${modname}Default: Theme \$(Theme) ' \\ ) >> \$FVWM_USERDIR/.${modname} *${modname}: Command !(/bin/echo \\ '*${modname}Default: Title \$(Title) ' ; /bin/echo \\ '*${modname}Default: InsertInto \$(InsertInto) ' ; /bin/echo \\ '*${modname}Default: Path \$(Path) ' ; /bin/echo \\ '*${modname}Default: IconDir \$(IconDir) ' ; /bin/echo \\ '*${modname}Default: DirIcon \$(DirIcon) ' ; /bin/echo \\ '*${modname}Default: AppIcon \$(AppIcon) ' \\ ) >> \$FVWM_USERDIR/.${modname} *${modname}: Button restart \"\$[gt.Reset]\" *${modname}: Command Nop *${modname}: Button continue \"\$[gt.Help]\" *${modname}: Command Module FvwmForm FvwmForm-XDGMenuHelp *${modname}: Button quit \"\$[gt.Close]\" *${modname}: Command Nop # Tell ${modname} to read vars from .${modname}Default file: *${modname}: UseData .${modname} *${modname}Default "; # We are just asked to open a window, give fvwm a chance to do it ::unlock(); $fvwmform_commands =~ s/^\s+//; # trim leading whitespace ::command(qq[ $fvwmform_commands FvwmForm ${modname} ]); #print MSG "$fvwmform_commands\n\n"; #close(MSG); # Local Variables: # mode: perl # End: fvwm-2.6.7/bin/fvwm-menu-xlock.10000644000175700017570000001711612673746443013363 00000000000000.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.02) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "fvwm-menu-xlock 1" .TH fvwm-menu-xlock 1 "2009-03-22" "2.5.28 (from cvs)" "Fvwm Utilities" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" fvwm\-menu\-xlock \- builds xlock menu definition for fvwm .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBfvwm-menu-xlock\fR [ \fB\-\-help\fR|\fB\-h\fR|\fB\-?\fR ] [ \fB\-\-version\fR|\fB\-V\fR ] [ \fB\-\-name\fR|\fB\-n\fR name ] [ \fB\-\-title\fR|\fB\-t\fR title ] [ \fB\-\-item\fR format ] [ \fB\-\-icon\-title\fR icon ] [ \fB\-\-icon\-item\fR icon ] [ \fB\-\-special\-first\fR|\fB\-s\fR ] [ \*(-- xlock params ] .SH "DESCRIPTION" .IX Header "DESCRIPTION" A simple perl script which parses xlock's output to build an fvwm menu definition of all xlock's modes. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-\-help\fR" 4 .IX Item "--help" show the help and exit .IP "\fB\-\-version\fR" 4 .IX Item "--version" show the version and exit .IP "\fB\-\-name\fR name" 4 .IX Item "--name name" define menu name in the following argument. Default is \*(L"XLockMenu\*(R" .IP "\fB\-\-title\fR title" 4 .IX Item "--title title" define menu title in the following argument. Default is \*(L"XLock Modes\*(R". .IP "\fB\-\-item\fR format" 4 .IX Item "--item format" define menu item format in the following argument, default is '%n\et(%d)'. \s-1TAB\s0 can be specified as '\et', but in .fvwm2rc you should specify a double backslash or a real \s-1TAB\s0. .Sp Format specifiers: .Sp .Vb 3 \& %n \- mode name \& %d \- mode description \& %D \- mode description without "Shows " prefix if any .Ve .Sp These specifiers can receive an optional integer size, positive for right adjusted string or negative for left adjusted, example: \f(CW%8x\fR; and optional *num or *\-num, which means to leave only the first or last (if minus) num of chars, the num must be greater than 3, since the striped part is replaced with \*(L"...\*(R", example: %*30x. Both can be combined: %\-10*\-20x, this instructs to get only the 20 last characters, but if the length is less then 10 \- to fill with up to 10 spaces on the right. .IP "\fB\-\-icon\-title\fR icon" 4 .IX Item "--icon-title icon" .PD 0 .IP "\fB\-\-icon\-item\fR icon" 4 .IX Item "--icon-item icon" .PD define menu icon for title and regular item accordingly. Default is no menu icons (equivalent to an empty icon argument). .IP "\fB\-\-wm\-icons\fR" 4 .IX Item "--wm-icons" define icon names suitable for use with wm-icons package. Currently this is equivalent to: \-\-icon\-title '' \-\-icon\-item menu/lock.xpm. .IP "\fB\-\-special\-first\fR" 4 .IX Item "--special-first" instructs to include special modes (usually black, bomb and random) first. .PP Option parameters can be specified either using '=' or in the next argument. Short options are ok if not ambiguous: \-h, \-t; but be careful with short options, what is now unambiguous, can became ambiguous in the next versions. .PP Additional arguments (after \fB\-\-\fR) will be passed to xlock. .PP Please see the \fBxlock\fR(1) man page for the xlock options. .SH "USAGE" .IX Header "USAGE" Add these lines to your fvwm configuration file: .PP .Vb 6 \& PipeRead \*(Aqfvwm\-menu\-xlock \-\-name MenuSSaver \-\-title "Screensaver" \e \& \-\-icon\-item mini\-bball.xpm \-\-special\-first \-\- \-nice 19 \-nolock\*(Aq \& PipeRead \*(Aqfvwm\-menu\-xlock \-\-name MenuSLock \-\-title "Lock Screen" \e \& \-\-icon\-item mini\-rball.xpm \-\-special\-first \-\- \-nice 19\*(Aq \& AddToMenu "Utilities" "Screensaver%mini\-monitor.xpm%" Popup MenuSSaver \& AddToMenu "Utilities" "Screenlock%mini\-lock.xpm%" Popup MenuSLock .Ve .SH "AUTHORS" .IX Header "AUTHORS" Charles K. Hines , initial version. .PP Mikhael Goikhman , from 24 Feb 1999. .SH "COPYING" .IX Header "COPYING" The script is distributed by the same terms as fvwm itself. See \s-1GNU\s0 General Public License for details. .SH "BUGS" .IX Header "BUGS" Depends on the output of xlock. Will produce an empty menu if the structure of the output is changed. .PP Report bugs to fvwm\-bug@fvwm.org. fvwm-2.6.7/bin/fvwm-root.10000644000175700017570000000721113010101137012222 00000000000000'\" t .\" @(#)fvwm-2.6.7 06 November 2016 .TH fvwm-root 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME fvwm-root \- Sets the root window of the current X display to image .SH SYNOPSIS .B fvwm-root .RB [ "--retain-pixmap" | "-r" ] .RB [ "--no-retain-pixmap" ] .RB [ "--dummy" | "-d" ] .RB [ "--no-dummy" ] .RB [ "--dither" ] .RB [ "--no-dither" ] .RB [ "--color-limit" .RI [ ncolors "] ]" .RB [ "--no-color-limit" ] .RB [ "--help" | "-h" | "-?" ] .RB [ "--version" | "-V" ] .I image_file .SH DESCRIPTION .I fvwm-root reads the image file specified in the command line and displays it in the root window. The supported image formats are .IR XBM ", " XPM ", " PNG " and " SVG if appropriated libraries are compiled in. SVG rendering options .RB " (as described in the " " ICONS AND IMAGES " section of the main fvwm documentation) can be utilized. .SH OPTIONS These command line options are recognized by fvwm-root: .TP .BR "--retain-pixmap" " | " "-r" Causes fvwm-root to retain and publish the Pixmap with which the background has been set (the ESETROOT_PMAP_ID and _XROOTPMAP_ID properties are used). This is useful for applications which want to use the root Pixmap on the background to simulate transparency (for example, Eterm and Aterm use this method). This option should also be used for the RootTransparent colorset option, refer to the COLORSETS section of fvwm(1). If this option is not used, fvwm-root sets the _XSETROOT_ID property to None, and some programs, like fvwm modules, may use this to update their background if the background is transparent (Transparent colorset). Note, a well behaved program, like fvwm, should listen to both _XSETROOT_ID and _XROOTPMAP_ID property changes and update itself correspondingly. However some programs listen only to one of them, so you should either use this option or not depending on what part is implemented by these programs. You should also use this option to get fast root-transparent menus in fvwm. .TP .BI "--no-retain-pixmap" This is a default. May be useful to explicitly force the default even if "--retain-pixmap" is specified earlier. .TP .BR "--dummy" " | " "-d" Causes fvwm-root NOT to set the background, but to only free a memory associated with the ESETROOT_PMAP_ID property (if any). In any case the _XSETROOT_ID property is set to None. .TP .BI "--no-dummy" This is a default. May be useful to explicitly force the default even if "--dummy" is specified earlier. .TP .BI "--dither" Causes fvwm-root to dither images for "smoother" rendition on displays with color depth of 16 or lower. This the defaut with color depth less or equal to 8. .TP .BI "--no-dither" Causes fvwm-root NOT to dither images. This is the default with color depth greater than 8. .TP .BI "--color-limit " ncolors Causes fvwm-root to limit its color use to .I ncolors (if specified). This option is taken in account only with color depth less or equal to 8 (and a TrueColor or GrayScale visual). The default is to use the same color limit as fvwm. So in normal situation this option is not useful. However, if fvwm use a private colors map, as fvwm-root always use the default colors map you should use this option for limiting colors correctly. If .I ncolors is not specified a default is used. .TP .BI "--no-color-limit" Causes fvwm-root NOT to limit its color use. .TP .BI "--help" Shows a short usage. .TP .BI "--version" Shows a version number. .SH COMPATIBILITY In the past this utility was called .IR xpmroot . This name is still supported as a symlink. .SH BUGS Repeated use of fvwm-root with different xpm pixmaps will use up slots in your color table pretty darn fast. .SH AUTHOR Rob Nation Rewritten and enhanced by fvwm-workers. fvwm-2.6.7/COPYING0000644000175700017570000004321412673746443010523 00000000000000The entire fvwm distribution is subject to the GNU GENERAL PUBLIC LICENSE (see below). ------------------------------------------------------------------------------- Additional copyrights of the fvwm main module: fvwm is copyright 1988 by Evans and Sutherland Computer Corporation, Salt Lake City, Utah, and 1989 by the Massachusetts Institute of Technology, Cambridge, Massachusetts, all rights reserved. It is also copyright 1993 and 1994 by Robert Nation. 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 names of Evans & Sutherland and M.I.T. not be used in advertising in publicity pertaining to distribution of the software without specific, written prior permission. ROBERT NATION, CHARLES HINES, EVANS & SUTHERLAND, AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR M.I.T. 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. ------------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 fvwm-2.6.7/acinclude.m40000644000175700017570000013213212750325036011642 00000000000000dnl Convenience macros dnl new version of FUNC_SELECT dnl - submitted to autoconf maintainer; expected to appear in next version AC_DEFUN([AC_FUNC_SELECT], [AC_CHECK_FUNCS(select) if test "$ac_cv_func_select" = yes; then AC_CHECK_HEADERS(unistd.h sys/types.h sys/time.h sys/select.h sys/socket.h) AC_MSG_CHECKING([argument types of select()]) AC_CACHE_VAL(ac_cv_type_fd_set_size_t,dnl [AC_CACHE_VAL(ac_cv_type_fd_set,dnl [for ac_cv_type_fd_set in 'fd_set' 'int' 'void'; do for ac_cv_type_fd_set_size_t in 'int' 'size_t' 'unsigned long' 'unsigned'; do for ac_type_timeval in 'struct timeval' 'const struct timeval'; do AC_TRY_COMPILE(dnl [#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif], [extern select ($ac_cv_type_fd_set_size_t, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_type_timeval *);], [ac_found=yes ; break 3],ac_found=no) done done done ])dnl AC_CACHE_VAL ])dnl AC_CACHE_VAL if test "$ac_found" = no; then AC_MSG_ERROR([can not determine argument types]) fi AC_MSG_RESULT([select($ac_cv_type_fd_set_size_t,$ac_cv_type_fd_set *,...)]) AH_TEMPLATE([fd_set_size_t], [Define to the type used in argument 1 `select'. Usually this is an `int'.]) AC_DEFINE_UNQUOTED(fd_set_size_t, $ac_cv_type_fd_set_size_t) ac_cast= if test "$ac_cv_type_fd_set" != fd_set; then # Arguments 2-4 are not fd_set. Some weirdo systems use fd_set type for # FD_SET macros, but insist that you cast the argument to select. I don't # understand why that might be, but it means we cannot define fd_set. AC_EGREP_CPP(dnl changequote(<<,>>)dnl <<(^|[^a-zA-Z_0-9])fd_set[^a-zA-Z_0-9]>>dnl changequote([,]),dnl [#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif],dnl # We found fd_set type in a header, need special cast ac_cast="($ac_cv_type_fd_set *)",dnl # No fd_set type; it is safe to define it AH_TEMPLATE([fd_set], [Define to the type used in arguments 2-4 of `select', if not set by system headers.]) AC_DEFINE_UNQUOTED(fd_set,$ac_cv_type_fd_set)) fi AH_TEMPLATE([SELECT_FD_SET_CAST], [Define a suitable cast for arguments 2-4 of `select'. On most systems, this will be the empty string, as select usually takes pointers to fd_set.]) AC_DEFINE_UNQUOTED(SELECT_FD_SET_CAST,$ac_cast) fi ]) dnl Checking for typedefs, with extra headers dnl pds_CHECK_TYPE(TYPE, DEFAULT, [HEADERS], [comment]) AC_DEFUN([pds_CHECK_TYPE], [AC_REQUIRE([AC_HEADER_STDC])dnl AC_MSG_CHECKING(for $1) AC_CACHE_VAL(ac_cv_type_$1, [AC_EGREP_CPP(dnl changequote(<<,>>)dnl <<(^|[^a-zA-Z_0-9])$1[^a-zA-Z_0-9]>>dnl changequote([,]), [#include #if STDC_HEADERS #include #include #endif $3], ac_cv_type_[$1]=yes, ac_cv_type_[$]1=no)])dnl AC_MSG_RESULT($ac_cv_type_[$1]) if test $ac_cv_type_[$1] = no; then AH_TEMPLATE([$1],[$4]) AC_DEFINE_UNQUOTED($1, $2) fi ]) dnl Configure-time switch with default dnl dnl Each switch defines an --enable-FOO and --disable-FOO option in dnl the resulting configure script. dnl dnl Usage: dnl smr_SWITCH(name, description, default, pos-def, neg-def, dnl pos-def-comment, neg-def-comment) dnl dnl where: dnl dnl name name of switch; generates --enable-name & --disable-name dnl options dnl description help string is set to this prefixed by "enable" or dnl "disable", whichever is the non-default value dnl default either "on" or "off"; specifies default if neither dnl --enable-name nor --disable-name is specified dnl pos-def a symbol to AC_DEFINE if switch is on (optional) dnl neg-def a symbol to AC_DEFINE if switch is off (optional) dnl AC_DEFUN([smr_SWITCH], [ AC_MSG_CHECKING(whether to enable [$2]) AC_ARG_ENABLE( $1, ifelse($3, on, [AC_HELP_STRING([--disable-$1], [disable $2])], [AC_HELP_STRING([--enable-$1], [enable $2])] ), ifelse([$4], , , [AH_TEMPLATE([$4],[$6])]) ifelse([$5], , , [AH_TEMPLATE([$5],[$7])]) [ if test "$enableval" = yes; then AC_MSG_RESULT(yes) ifelse($4, , , [AC_DEFINE($4)]) else AC_MSG_RESULT(no) ifelse($5, , , [AC_DEFINE($5)]) fi ], ifelse($3, on, [ AC_MSG_RESULT(yes) ifelse($4, , , [AC_DEFINE($4)]) ], [ AC_MSG_RESULT(no) ifelse($5, , , [AC_DEFINE($5)])]) ) ]) dnl Allow argument for optional libraries; wraps AC_ARG_WITH, to dnl provide a "--with-foo-library" option in the configure script, where foo dnl is presumed to be a library name. The argument given by the user dnl (i.e. "bar" in ./configure --with-foo-library=bar) may be one of three dnl things: dnl * boolean (no, yes or blank): whether to use library or not dnl * file: assumed to be the name of the library dnl * directory: assumed to *contain* the library dnl dnl The argument is sanity-checked. If all is well, two variables are dnl set: "with_foo" (value is yes, no, or maybe), and "foo_LIBS" (value dnl is either blank, a file, -lfoo, or '-L/some/dir -lfoo'). The idea dnl is: the first tells you whether the library is to be used or not dnl (or the user didn't specify one way or the other) and the second dnl to put on the command line for linking with the library. dnl dnl Usage: dnl smr_ARG_WITHLIB(name, libname, description) dnl dnl name name for --with argument ("foo" for libfoo) dnl libname (optional) actual name of library, dnl if different from name dnl description (optional) used to construct help string dnl AC_DEFUN([smr_ARG_WITHLIB], [ ifelse($2, , smr_lib=[$1], smr_lib=[$2]) AC_ARG_WITH([$1]-library, ifelse($3, , AS_HELP_STRING([--with-$1-library[=PATH]],[use $1 library]), AS_HELP_STRING([--with-$1-library[=PATH]],[use $1 library ($3)])), [ if test "$withval" = yes; then with_[$1]=yes [$1]_LIBS="-l${smr_lib}" elif test "$withval" = no; then with_[$1]=no [$1]_LIBS= else with_[$1]=yes if test -f "$withval"; then [$1]_LIBS=$withval elif test -d "$withval"; then [$1]_LIBS="-L$withval -l${smr_lib}" else AC_MSG_ERROR([--with-$1-library argument must be yes/no, file or directory]) fi fi ], [ with_[$1]=maybe [$1]_LIBS="-l${smr_lib}" ])]) dnl Check if the include files for a library are accessible, and dnl define the variable "name_CFLAGS" with the proper "-I" flag for dnl the compiler. The user has a chance to specify the includes dnl location, using "--with-foo-includes". dnl dnl This should be used *after* smr_ARG_WITHLIB *and* AC_CHECK_LIB are dnl successful. dnl dnl Usage: dnl smr_ARG_WITHINCLUDES(name, header, extra-flags) dnl dnl name library name, MUST same as used with smr_ARG_WITHLIB dnl header a header file required for using the lib dnl extra-flags (optional) flags required when compiling the dnl header, typically more includes; for ex. X_CFLAGS dnl AC_DEFUN([smr_ARG_WITHINCLUDES], [ AC_ARG_WITH([$1]-includes, AS_HELP_STRING([--with-$1-includes=DIR],[set directory for $1 headers]), [ if test -d "$withval"; then [$1]_CFLAGS="-I${withval}" else AC_MSG_ERROR([argument must be a directory]) fi]) dnl We need to put the given include directory into CPPFLAGS temporarily, but dnl then restore CPPFLAGS to its old value. dnl smr_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS ${[$1]_CFLAGS}" ifelse($3, , , CPPFLAGS="$CPPFLAGS [$3]") AC_CHECK_HEADERS($2) CPPFLAGS=$smr_save_CPPFLAGS ]) dnl Probe for an optional library. This macro creates both dnl --with-foo-library and --with-foo-includes options for the configure dnl script. If --with-foo-library is *not* specified, the default is to dnl probe for the library, and use it if found. dnl dnl Usage: dnl smr_CHECK_LIB(name, libname, desc, func, header, x-libs, x-flags) dnl dnl name name for --with options dnl libname (optional) real name of library, if different from dnl above dnl desc (optional) short descr. of library, for help string dnl func function of library, to probe for dnl header (optional) header required for using library dnl x-libs (optional) extra libraries, if needed to link with lib dnl x-flags (optional) extra flags, if needed to include header files dnl AC_DEFUN([smr_CHECK_LIB], [ ifelse($2, , smr_lib=[$1], smr_lib=[$2]) ifelse($5, , , smr_header=[$5]) smr_ARG_WITHLIB($1,$2,$3) if test "$with_$1" != no; then AC_CHECK_LIB(ifelse($2, , $1, $2), $4, smr_havelib=yes, smr_havelib=no; problem_$1=": Can't find working lib$smr_lib", ifelse($6, , ${$1_LIBS}, [${$1_LIBS} $6])) if test "$smr_havelib" = yes -a "$smr_header" != ""; then smr_ARG_WITHINCLUDES($1, $smr_header, $7) smr_safe=`echo "$smr_header" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$ac_cv_header_'$smr_safe`\" != yes"; then smr_havelib=no problem_$1=": Can't find working $smr_header" fi fi if test "$smr_havelib" = yes; then with_$1=yes problem_$1= else $1_LIBS= $1_CFLAGS= with_$1=no fi else problem_$1=": Explicitly disabled" fi]) dnl Defines a boolean variable for config.h depending on a condition. dnl dnl Usage: dnl mg_DEFINE_IF_NOT(c-code, cpp-if-cond, var-name, extra-flags, var-comment) dnl dnl c-code the first code part inside main() dnl cpp-if-cond boolean preprocessor condition dnl var-name this variable will be defined if the given condition is false dnl extra-flags (optional) extra flags for compiling, typically more -I glags dnl dnl Example: dnl mg_DEFINE_IF_NOT([#include ], [defined __USE_BSD], [NON_BSD]) dnl AC_DEFUN([mg_DEFINE_IF_NOT], [ mg_save_CPPFLAGS="$CPPFLAGS" ifelse($4, , , CPPFLAGS="$CPPFLAGS [$4]") AH_TEMPLATE([$3],[$5]) AC_TRY_RUN([ #include int main(int c, char **v) { $1 #if $2 return 0; #else return 1; #endif } ], [:], [AC_DEFINE($3)]) CPPFLAGS="$mg_save_CPPFLAGS" ]) # Check for gdk-imlib AC_DEFUN([AM_PATH_GDK_IMLIB], [dnl dnl Get the cflags and libraries from the imlib-config script dnl AC_ARG_WITH(imlib-prefix,AS_HELP_STRING([--with-imlib-prefix=PFX],[prefix for IMLIB files (optional)]), imlib_prefix="$withval", imlib_prefix="") AC_ARG_WITH(imlib-exec-prefix,AS_HELP_STRING([--with-imlib-exec-prefix=PFX],[exec prefix for IMLIB files (optional)]), imlib_exec_prefix="$withval", imlib_exec_prefix="") AC_ARG_ENABLE(imlibtest,AS_HELP_STRING([--disable-imlibtest],[do not try to compile and run a test IMLIB program]), , enable_imlibtest=yes) if test x$imlib_exec_prefix != x ; then imlib_args="$imlib_args --exec-prefix=$imlib_exec_prefix" if test x${IMLIBCONF+set} != xset ; then IMLIBCONF=$imlib_exec_prefix/bin/imlib-config fi fi if test x$imlib_prefix != x ; then imlib_args="$imlib_args --prefix=$imlib_prefix" if test x${IMLIBCONF+set} != xset ; then IMLIBCONF=$imlib_prefix/bin/imlib-config fi fi AC_PATH_PROG(IMLIBCONF, imlib-config, no) min_imlib_version=ifelse([$1], ,1.8.1,$1) AC_MSG_CHECKING(for GDK IMLIB - version >= $min_imlib_version) no_imlib="" if test "$IMLIBCONF" = "no" ; then no_imlib=yes else GDK_IMLIB_CFLAGS=`$IMLIBCONF $imlibconf_args --cflags-gdk` GDK_IMLIB_LIBS=`$IMLIBCONF $imlibconf_args --libs-gdk` imlib_major_version=`$IMLIBCONF $imlib_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` imlib_minor_version=`$IMLIBCONF $imlib_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` if test "x$enable_imlibtest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $GDK_IMLIB_CFLAGS" LIBS="$LIBS $GDK_IMLIB_LIBS" dnl dnl Now check if the installed IMLIB is sufficiently new. (Also sanity dnl checks the results of imlib-config to some extent dnl rm -f conf.imlibtest AC_TRY_RUN([ #include #include #include /* migo: originally it was GdkImLibColor with incorrect spelling */ GdkImlibImage testimage; int main () { int major, minor; char *tmp_version; system ("touch conf.gdkimlibtest"); /* HP/UX 9 (%@#!) writes to sscanf strings */ tmp_version = g_strdup("$min_imlib_version"); if (sscanf(tmp_version, "%d.%d", &major, &minor) != 2) { printf("%s, bad version string\n", "$min_imlib_version"); exit(1); } if (($imlib_major_version > major) || (($imlib_major_version == major) && ($imlib_minor_version > minor))) { return 0; } else { printf("\n*** 'imlib-config --version' returned %d.%d, but the minimum version\n", $imlib_major_version, $imlib_minor_version); printf("*** of IMLIB required is %d.%d. If imlib-config is correct, then it is\n", major, minor); printf("*** best to upgrade to the required version.\n"); printf("*** If imlib-config was wrong, set the environment variable IMLIBCONF\n"); printf("*** to point to the correct copy of imlib-config, and remove the file\n"); printf("*** config.cache before re-running configure\n"); return 1; } } ],, no_imlib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi fi if test "x$no_imlib" = x ; then AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "$IMLIBCONF" = "no" ; then (echo "*** The imlib-config script installed by IMLIB could not be found" >&5) 2>/dev/null || \ echo "*** The imlib-config script installed by IMLIB could not be found" (echo "*** If IMLIB was installed in PREFIX, make sure PREFIX/bin is in" >&5) 2>/dev/null || \ echo "*** If IMLIB was installed in PREFIX, make sure PREFIX/bin is in" (echo "*** your path, or set the IMLIBCONF environment variable to the" >&5) 2>/dev/null || \ echo "*** your path, or set the IMLIBCONF environment variable to the" (echo "*** full path to imlib-config." >&5) 2>/dev/null || \ echo "*** full path to imlib-config." else if test -f conf.gdkimlibtest ; then : else (echo "*** Could not run IMLIB test program, checking why..." >&5) 2>/dev/null || \ echo "*** Could not run IMLIB test program, checking why..." CFLAGS="$CFLAGS $GDK_IMLIB_CFLAGS" LIBS="$LIBS $GDK_IMLIB_LIBS" AC_TRY_LINK([ #include #include ], [ return 0; ], [ (echo "*** The test program compiled, but did not run. This usually means" >&5) 2>/dev/null || \ echo "*** The test program compiled, but did not run. This usually means" (echo "*** that the run-time linker is not finding IMLIB or finding the wrong" >&5) 2>/dev/null || \ echo "*** that the run-time linker is not finding IMLIB or finding the wrong" (echo "*** version of IMLIB. If it is not finding IMLIB, you'll need to set your" >&5) 2>/dev/null || \ echo "*** version of IMLIB. If it is not finding IMLIB, you'll need to set your" (echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" >&5) 2>/dev/null || \ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" (echo "*** to the installed location Also, make sure you have run ldconfig if that" >&5) 2>/dev/null || \ echo "*** to the installed location Also, make sure you have run ldconfig if that" (echo "*** is required on your system" >&5) 2>/dev/null || \ echo "*** is required on your system" (echo "***" >&5) 2>/dev/null || \ echo "***" (echo "*** If you have an old version installed, it is best to remove it, although" >&5) 2>/dev/null || \ echo "*** If you have an old version installed, it is best to remove it, although" (echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" >&5) 2>/dev/null || \ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], [ (echo "*** The test program failed to compile or link. See the file config.log for the" >&5) 2>/dev/null || \ echo "*** The test program failed to compile or link. See the file config.log for the" (echo "*** exact error that occured. This usually means IMLIB was incorrectly installed" >&5) 2>/dev/null || \ echo "*** exact error that occured. This usually means IMLIB was incorrectly installed" (echo "*** or that you have moved IMLIB since it was installed. In the latter case, you" >&5) 2>/dev/null || \ echo "*** or that you have moved IMLIB since it was installed. In the latter case, you" (echo "*** may want to edit the imlib-config script: $IMLIBCONF" >&5) 2>/dev/null || \ echo "*** may want to edit the imlib-config script: $IMLIBCONF"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi fi GDK_IMLIB_CFLAGS="" GDK_IMLIB_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(GDK_IMLIB_CFLAGS) AC_SUBST(GDK_IMLIB_LIBS) rm -f conf.gdkimlibtest ]) # # check if iconv second argument use const char. # AC_DEFUN([ICONV_SECOND_ARG],[ AC_MSG_CHECKING(check if second arg of iconv is const) AC_TRY_COMPILE([ #include #include extern #if defined(__STDC__) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], use_const=no, use_const=yes) AC_MSG_RESULT($use_const) AH_TEMPLATE([ICONV_ARG_CONST], [define if second arg of iconv use const]) if test "x$use_const" = "xyes"; then AC_DEFINE(ICONV_ARG_CONST, const) else AC_DEFINE(ICONV_ARG_CONST, ) fi ]) # # check for locale_charset if libiconv is used # AC_DEFUN([CHECK_LIBCHARSET],[ AC_MSG_CHECKING(check for libcharset) ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $iconv_CFLAGS" LIBS="$LIBS $iconv_LIBS" AC_TRY_LINK([ #include ], [const char *c; c = locale_charset (); ], r=yes, r=no) AC_MSG_RESULT($r) if test "x$r" = "xyes"; then AC_DEFINE(HAVE_LIBCHARSET) fi CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" ]) #----------------------------------------------------------------------------- # pkg-config dnl dnl AC_DEFUN([AM_CHECK_PKG_CONFIG], [dnl dnl Get the cflags and libraries from the freetype-config script dnl AC_ARG_WITH(pkgconfig-prefix, AS_HELP_STRING([--with-pkgconfig-prefix=PFX],[prefix where pkg-config is installed]), pkgconfig_config_prefix="$withval", pkgconfig_config_prefix="") AC_ARG_WITH(pkgconfig-exec-prefix, AS_HELP_STRING([--with-pkgconfig-exec-prefix=PFX],[exec prefix where pkg-config is installed]), pkgconfig_config_exec_prefix="$withval",pkgconfig_config_exec_prefix="") if test x$pkgconfig_config_exec_prefix != x ; then pkgconfig_config_args="$pkgconfig_config_args --exec-prefix=$pkgconfig_config_exec_prefix" if test x${PKG_CONFIG+set} != xset ; then PKG_CONFIG=$pkgconfig_config_exec_prefix/bin/pkg-config fi fi if test x$pkgconfig_config_prefix != x ; then pkgconfig_config_args="$pkgconfig_config_args --prefix=$pkgconfig_config_prefix" if test x${PKG_CONFIG+set} != xset ; then PKG_CONFIG=$pkgconfig_config_prefix/bin/pkg-config fi fi AC_PATH_PROG(PKG_CONFIG, pkg-config, no) ]) #----------------------------------------------------------------------------- # Configure paths for FreeType2 # Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor dnl AM_CHECK_FT2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for FreeType2, and define FT2_CFLAGS and FT2_LIBS dnl AC_DEFUN([AM_CHECK_FT2], [dnl dnl Get the cflags and libraries from the freetype-config script dnl AC_ARG_WITH(freetype-prefix, AS_HELP_STRING([--with-freetype-prefix=PFX],[prefix where FreeType is installed (for Xft)]), ft_config_prefix="$withval", ft_config_prefix="") AC_ARG_WITH(freetype-exec-prefix, AS_HELP_STRING([--with-freetype-exec-prefix=PFX],[exec prefix where FreeType is installed]), ft_config_exec_prefix="$withval", ft_config_exec_prefix="") AC_ARG_ENABLE(freetypetest, AS_HELP_STRING([--disable-freetypetest],[do not try to compile and run a test FreeType program]), [], enable_fttest=yes) if test x$ft_config_exec_prefix != x ; then ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix" if test x${FT2_CONFIG+set} != xset ; then FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config fi fi if test x$ft_config_prefix != x ; then ft_config_args="$ft_config_args --prefix=$ft_config_prefix" if test x${FT2_CONFIG+set} != xset ; then FT2_CONFIG=$ft_config_prefix/bin/freetype-config fi fi AC_PATH_PROG(FT2_CONFIG, freetype-config, no) min_ft_version=ifelse([$1], ,6.1.0,$1) AC_MSG_CHECKING(for FreeType - version >= $min_ft_version) no_ft="" if test "$FT2_CONFIG" = "no" ; then no_ft=yes else FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags` FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs` ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\3/'` ft_min_major_version=`echo $min_ft_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` ft_min_minor_version=`echo $min_ft_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` ft_min_micro_version=`echo $min_ft_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\3/'` if test "x$enable_fttest" = "xyes" ; then ft_config_is_lt=no if test $ft_config_major_version -lt $ft_min_major_version ; then ft_config_is_lt=yes else if test $ft_config_major_version -eq $ft_min_major_version ; then if test $ft_config_minor_version -lt $ft_min_minor_version ; then ft_config_is_lt=yes else if test $ft_config_minor_version -eq $ft_min_minor_version ; then if test $ft_config_micro_version -lt $ft_min_micro_version ; then ft_config_is_lt=yes fi fi fi fi fi if test "x$ft_config_is_lt" = "xyes" ; then ifelse([$3], , :, [$3]) else ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $FT2_CFLAGS" LIBS="$FT2_LIBS $LIBS" dnl dnl Sanity checks for the results of freetype-config to some extent dnl AC_TRY_RUN([ #include #include FT_FREETYPE_H #include #include int main() { FT_Library library; FT_Error error; error = FT_Init_FreeType(&library); if (error) return 1; else { FT_Done_FreeType(library); return 0; } } ],, no_ft=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi # test $ft_config_version -lt $ft_min_version fi # test "x$enable_fttest" = "xyes" fi # test "$FT2_CONFIG" = "no" if test "x$no_ft" = x ; then AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "$FT2_CONFIG" = "no" ; then echo "*** The freetype-config script installed by FreeType 2 could not be found." echo "*** If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in" echo "*** your path, or set the FT2_CONFIG environment variable to the" echo "*** full path to freetype-config." else echo "*** The FreeType test program failed to run. If your system uses" echo "*** shared libraries and they are installed outside the normal" echo "*** system library path, make sure the variable LD_LIBRARY_PATH" echo "*** (or whatever is appropiate for your system) is correctly set." fi FT2_CFLAGS="" FT2_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(FT2_CFLAGS) AC_SUBST(FT2_LIBS) ]) #----------------------------------------------------------------------------- # Configure paths for fontconfig # Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor # modified by olicha for fontconfig dnl AM_CHECK_FC([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for fontconfig, and define FC_CFLAGS and FC_LIBS dnl AC_DEFUN([AM_CHECK_FC], [dnl dnl Get the cflags and libraries from the fontconfig-config script dnl AC_ARG_WITH(fontconfig-prefix, AS_HELP_STRING([--with-fontconfig-prefix=PFX],[prefix where fontconfig is installed (for Xft2)]), fc_config_prefix="$withval", fc_config_prefix="") AC_ARG_WITH(fontconfig-exec-prefix, AS_HELP_STRING([--with-fontconfig-exec-prefix=PFX],[exec prefix where fontconfig is installed]), fc_config_exec_prefix="$withval", fc_config_exec_prefix="") AC_ARG_ENABLE(fontconfigtest, AS_HELP_STRING([--disable-fontconfigtest],[do not try to compile and run a test fontconfig program]), [], enable_fctest=yes) if test x$fc_config_exec_prefix != x ; then fc_config_args="$fc_config_args --exec-prefix=$fc_config_exec_prefix" if test x${FC_CONFIG+set} != xset ; then FC_CONFIG=$fc_config_exec_prefix/bin/fontconfig-config fi fi if test x$fc_config_prefix != x ; then fc_config_args="$fc_config_args --prefix=$fc_config_prefix" if test x${FC_CONFIG+set} != xset ; then FC_CONFIG=$fc_config_prefix/bin/fontconfig-config fi fi AC_PATH_PROG(FC_CONFIG, fontconfig-config, no) min_fc_version=ifelse([$1], ,1.0.1,$1) AC_MSG_CHECKING(for Fontconfig - version >= $min_fc_version) no_fc="" pkg_config_fontconfig_exists="" if test "$FC_CONFIG" = "no" ; then if test "x$PKG_CONFIG" != "xno" ; then if $PKG_CONFIG --exists 'fontconfig' ; then if $PKG_CONFIG --exists 'fontconfig >= $1' ; then FC_CFLAGS=`$PKG_CONFIG --cflags fontconfig` FC_LIBS=`$PKG_CONFIG --libs fontconfig` else no_fc=yes fc_config_is_lt=yes fi else pkg_config_fontconfig_exists="maybe" no_fc=yes fi else no_fc=yes fi else FC_CFLAGS=`$FC_CONFIG $fc_config_args --cflags` FC_LIBS=`$FC_CONFIG $fc_config_args --libs` fc_config_major_version=`$FC_CONFIG $fc_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` fc_config_minor_version=`$FC_CONFIG $fc_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` fc_config_micro_version=`$FC_CONFIG $fc_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\3/'` fc_min_major_version=`echo $min_fc_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` fc_min_minor_version=`echo $min_fc_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` fc_min_micro_version=`echo $min_fc_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\3/'` fc_config_is_lt=no if test $fc_config_major_version -lt $fc_min_major_version ; then fc_config_is_lt=yes else if test $fc_config_major_version -eq $fc_min_major_version ; then if test $fc_config_minor_version -lt $fc_min_minor_version ; then fc_config_is_lt=yes else if test $fc_config_minor_version -eq $fc_min_minor_version ; then if test $fc_config_micro_version -lt $fc_min_micro_version ; then fc_config_is_lt=yes fi fi fi fi fi if test "x$fc_config_is_lt" = "xyes" ; then no_fc=yes fi fi if test "x$no_fc" = x ; then if test "x$enable_fctest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $FC_CFLAGS $FT2_CFLAGS" LIBS="$FC_LIBS $LIBS $FT2_LIBS" dnl dnl Sanity checks for the results of fontconfig-config/pkg-config to some extent dnl AC_TRY_RUN([ #include #include #include int main() { FcBool result; result = FcInit(); if (result) { return 0; } else { return 1; } } ],, no_fc=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi fi if test "x$no_fc" = x; then AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "x$fc_config_is_lt" = "xyes"; then echo "*** Your Fontconfig package version is < $1" elif test "x$pkg_config_fontconfig_exists" = "xmaybe"; then echo "*** fontconfig was not found in the pkg-config search path." echo "*** either fontconfig is not installed or perhaps you should" echo "*** add the directory containing fontconfig.pc to the " echo "*** PKG_CONFIG_PATH environment variable." elif test "$FC_CONFIG" != "no"; then echo "*** The Fontconfig test program failed to run. If your system uses" echo "*** shared libraries and they are installed outside the normal" echo "*** system library path, make sure the variable LD_LIBRARY_PATH" echo "*** (or whatever is appropiate for your system) is correctly set." fi FC_CFLAGS="" FC_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(FC_CFLAGS) AC_SUBST(FC_LIBS) ]) #----------------------------------------------------------------------------- # Configure paths for xft 2 # Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor # modified by olicha for xft dnl AM_CHECK_XFT([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for xft, and define XFT_CFLAGS and XFT_LIBS dnl AC_DEFUN([AM_CHECK_XFT], [dnl dnl Get the cflags and libraries from the xft-config script dnl AC_ARG_WITH(xft-prefix, AS_HELP_STRING([--with-xft-prefix=PFX],[prefix where Xft2 is installed (optional)]), xft_config_prefix="$withval", xft_config_prefix="") AC_ARG_WITH(xft-exec-prefix, AS_HELP_STRING([--with-xft-exec-prefix=PFX],[exec prefix where Xft2 is installed]), xft_config_exec_prefix="$withval", xft_config_exec_prefix="") AC_ARG_ENABLE(xfttest, AS_HELP_STRING([--disable-xfttest],[do not try to compile and run a test Xft program]), [], enable_xfttest=yes) if test x$xft_config_exec_prefix != x ; then xft_config_args="$xft_config_args --exec-prefix=$xft_config_exec_prefix" if test x${XFT_CONFIG+set} != xset ; then XFT_CONFIG=$xft_config_exec_prefix/bin/xft-config fi fi if test x$xft_config_prefix != x ; then xft_config_args="$xft_config_args --prefix=$xft_config_prefix" if test x${XFT_CONFIG+set} != xset ; then XFT_CONFIG=$xft_config_prefix/bin/xft-config fi fi AC_PATH_PROG(XFT_CONFIG, xft-config, no) min_xft_version=ifelse([$1], ,2.0.0,$1) AC_MSG_CHECKING(for Xft - version >= $min_xft_version) no_xft="" pkg_config_xft_exists="" if test "$XFT_CONFIG" = "no" ; then if test "x$PKG_CONFIG" != "xno" ; then if $PKG_CONFIG --exists 'xft' ; then if $PKG_CONFIG --exists 'xft >= $1' ; then XFT_CFLAGS=`$PKG_CONFIG --cflags xft` XFT_LIBS=`$PKG_CONFIG --libs xft` else no_xft=yes xft_config_is_lt=yes fi else pkg_config_xft_exists="maybe" no_xft=yes fi else no_xft=yes fi else XFT_CFLAGS=`$XFT_CONFIG $xft_config_args --cflags` XFT_LIBS=`$XFT_CONFIG $xft_config_args --libs` xft_config_major_version=`$XFT_CONFIG $xft_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` xft_config_minor_version=`$XFT_CONFIG $xft_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` xft_config_micro_version=`$XFT_CONFIG $xft_config_args --version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\3/'` xft_min_major_version=`echo $min_xft_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\1/'` xft_min_minor_version=`echo $min_xft_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\2/'` xft_min_micro_version=`echo $min_xft_version | \ sed 's/^[[^0-9.]]*\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*$/\3/'` xft_config_is_lt=no if test $xft_config_major_version -lt $xft_min_major_version ; then xft_config_is_lt=yes else if test $xft_config_major_version -eq $xft_min_major_version ; then if test $xft_config_minor_version -lt $xft_min_minor_version ; then xft_config_is_lt=yes else if test $xft_config_minor_version -eq $xft_min_minor_version ; then if test $xft_config_micro_version -lt $xft_min_micro_version ; then xft_config_is_lt=yes fi fi fi fi fi if test "x$xft_config_is_lt" = "xyes" ; then ifelse([$3], , :, [$3]) fi fi if test "x$no_xft" = x ; then if test "x$enable_xfttest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$XFT_CFLAGS $CFLAGS" LIBS="$XFT_LIBS $LIBS" dnl dnl Sanity checks for the results of xft-config/pkg-config to some extent dnl AC_TRY_RUN([ #include #include #include int main() { FcBool result = 1; result = XftInit(NULL); if (result) { return 0; } else { return 1; } } ],, no_xft=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi fi if test "x$no_xft" = x; then AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "x$xft_config_is_lt" = "xyes"; then echo "*** Your xft2 package version is < $1" elif test "x$pkg_config_fontconfig_exists" = "xmaybe" ; then echo "*** xft2 was not found in the pkg-config search path." echo "*** either xft is not installed or perhaps you should" echo "*** add the directory containing xft.pc to the " echo "*** PKG_CONFIG_PATH environment variable." elif test "$XFT_CONFIG" = "no"; then echo "*** The xft-config script installed by Xft 2 could not be found." echo "*** If Xft 2 was installed in PREFIX, make sure PREFIX/bin is in" echo "*** your path, or set the XFT_CONFIG environment variable to the" echo "*** full path to xft-config." else echo "*** The Xft test program failed to run. If your system uses" echo "*** shared libraries and they are installed outside the normal" echo "*** system library path, make sure the variable LD_LIBRARY_PATH" echo "*** (or whatever is appropiate for your system) is correctly set." fi XFT_CFLAGS="" XFT_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(XFT_CFLAGS) AC_SUBST(XFT_LIBS) ]) #----------------------------------------------------------------------------- # gettext stuff from the gettext package # # Authors: Ulrich Drepper , 1996. # modified by the fvwm workers # AC_DEFUN([AM_GNU_FGETTEXT], [ AC_REQUIRE([AM_PO_SUBDIRS])dnl intl_LIBS= intl_CFLAGS= POSUB= found_gettext=yes dnl check for the necessary stuff in the libc dnl the pbs is that we can detect this stuff but in fact the included dnl libintl.h is from gettext dnl Moreover, we do not try to use other implementation, but we may try dnl one day $UNSET ac_cv_header_intl_h $UNSET ac_cv_func_gettext $UNSET ac_cv_func_bindtextdomain $UNSET ac_cv_func_textdomain dnl a "gnu extension" $UNSET ac_cv_func_dgettext #bind_textdomain_codeset AC_CHECK_HEADER(libintl.h, [AC_CHECK_FUNCS(gettext bindtextdomain textdomain dgettext,, found_gettext=no)], found_gettext=no) AC_MSG_CHECKING([for gnu gettext in libc]) if test x"$found_gettext" = "xyes"; then problem_gettext=" (libc)" AC_MSG_RESULT([yes]) AC_MSG_CHECKING(if a simple gettext program link) AC_TRY_LINK([ #include ], [const char *c; c = gettext("foo");], found_gettext=yes;problem_gettext=" (libc)", found_gettext=no) AC_MSG_RESULT($found_gettext) else AC_MSG_RESULT([no]) fi if test x"$found_gettext" = xno; then dnl not found, check for libintl $UNSET ac_cv_header_intl_h $UNSET ac_cv_lib_intl_bindtextdomain $UNSET ac_cv_lib_intl_textdomain $UNSET ac_cv_lib_intl_dgettext smr_CHECK_LIB(intl, intl, for Native Language Support, bindtextdomain, libintl.h) if test x"$intl_LIBS" != x; then no_textdomain=no no_dgettext=no ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" AC_CHECK_LIB(intl, textdomain,, no_textdomain=yes, [$intl_LIBS $iconv_LIBS]) if test "$no_textdomain" != "yes"; then AC_CHECK_LIB(intl, dgettext,, no_dgettext=yes, [$intl_LIBS $iconv_LIBS]) if test "$no_dgettext" != "yes"; then CFLAGS="$CFLAGS $intl_LIBS $iconv_LIBS" LIBS="$LIBS $intl_LIBS $iconv_LIBS" AC_MSG_CHECKING(if a simple gettext program link) AC_TRY_LINK([ #include ], [const char *c; c = gettext("foo");], found_gettext=yes;problem_gettext=" (intl library)", found_gettext=no) AC_MSG_RESULT($found_gettext) fi fi CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi fi if test "$found_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo USE_NLS=yes dnl We need to process the po/ directory. POSUB=po else USE_NLS=no fi dnl Make the po/ variables we use known to autoconf ]) dnl Checks for all prerequisites of the po subdirectory, dnl except for USE_NLS. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.11 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU msgfmt. if test "$GMSGFMT" != ":"; then dnl If it is no GNU msgfmt we define it as : so that the dnl Makefiles still can work. if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` AC_MSG_RESULT( [found $GMSGFMT program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi fi dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po fi AC_PATH_PROG(MSGUNIQ, msguniq, $MSGUNIQ) AC_MSG_CHECKING([for NLS fvwm messages catalogs]) AC_MSG_RESULT([$ALL_LINGUAS]) POFILES= GMOFILES= UPDATEPOFILES= DUMMYPOFILES= for lang in $ALL_LINGUAS; do for dom in $ALL_DOMAINS; do POFILES="$POFILES $dom.$lang.po" GMOFILES="$GMOFILES $dom.$lang.gmo" UPDATEPOFILES="$UPDATEPOFILES $dom.$lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $dom.$lang.nop" done done # CATALOGS depends on both $ac_dir and the user's LINGUAS environment variable. INST_LINGUAS= AC_MSG_CHECKING([for NLS desired catalogs to be installed]) #if test "%UNSET%" != "$LINGUAS"; then # FIXME: How to check if LINGUAS has been *set* to "" if test -n "$LINGUAS"; then AC_MSG_RESULT([$LINGUAS]) else AC_MSG_RESULT([all]) fi AC_MSG_CHECKING([for NLS messages catalogs to be installed]) if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no #if test "%UNSET%" != "$LINGUAS"; then if test -n "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi AC_MSG_RESULT([$INST_LINGUAS]) CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi ]) AC_DEFUN([AM_MKINSTALLDIRS], [ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but $(top_srcdir). dnl Try to locate is. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi ]) # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in ifelse([$5], , $PATH, [$5]); do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) #----------------------------------------------------------------------------- # Safety check for mkstemp # AC_DEFUN([AM_SAFETY_CHECK_MKSTEMP],[ AC_CHECK_FUNCS(mkstemp) has_safety_mkstemp=no AC_MSG_CHECKING(if mkstemp is safe) if test x$ac_cv_func_mkstemp != xno; then AC_TRY_RUN([ #include #include #include int main(void) { char template[128]; char template_orig[128]; int fd; sprintf(template, "configure-mkstemp-test.XXXXXX"); strcpy(template_orig, template); fd = mkstemp(template); if (fd == -1) { /* could not create temp file */ return 1; } if (strcmp(template, template_orig) == 0) { /* mkstemp broken */ return 2; } if (close(fd) != 0) { /* doh! */ return 3; } if (unlink(template)) { return 4; } /* mkstemp works properly */ return 0; } ], [has_safety_mkstemp=yes], [has_safety_mkstemp=no]) fi AH_TEMPLATE([HAVE_SAFETY_MKSTEMP],[Enable the use of mkstemp]) if test x$has_safety_mkstemp = xno; then AC_MSG_RESULT(no, use our mkstemp) else AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SAFETY_MKSTEMP) fi ]) fvwm-2.6.7/fvwm/0000755000175700017570000000000013010103342010466 500000000000000fvwm-2.6.7/fvwm/virtual.h0000644000175700017570000000111012773467231012267 00000000000000/* -*-c-*- */ #ifndef _VIRTUAL_ #define _VIRTUAL_ int HandlePaging( XEvent *pev, int HorWarpSize, int VertWarpSize, int *xl, int *yt, int *delta_x, int *delta_y, Bool Grab, Bool fLoop, Bool do_continue_previous, int delay); void checkPanFrames(void); void raisePanFrames(void); void initPanFrames(void); Bool is_pan_frame(Window w); void MoveViewport(int newx, int newy,Bool); void goto_desk(int desk); void do_move_window_to_desk(FvwmWindow *fw, int desk); Bool get_page_arguments(char *action, int *page_x, int *page_y); char *GetDesktopName(int desk); #endif /* _VIRTUAL_ */ fvwm-2.6.7/fvwm/execcontext.h0000644000175700017570000000525612773467231013151 00000000000000/* -*-c-*- */ #ifndef EXECCONTEXT_H #define EXECCONTEXT_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* Inernal types */ typedef struct { XEvent te; } exec_context_privileged_t; /* Interface types */ typedef enum { EXCT_NULL = '-', EXCT_INIT = 'I', EXCT_RESTART = 'R', EXCT_QUIT = 'Q', EXCT_TORESTART = 'r', EXCT_EVENT ='E', EXCT_MODULE ='M', EXCT_MENULOOP ='m', EXCT_PAGING = 'P', EXCT_SCHEDULE = 'S' } exec_context_type_t; typedef struct { XEvent *etrigger; XEvent *elast; } x_context_t; typedef struct { FvwmWindow *fw; Window w; unsigned long wcontext; } window_context_t; struct fmodule; typedef struct { struct fmodule *module; } module_context_t; typedef struct { exec_context_type_t type; x_context_t x; window_context_t w; module_context_t m; /* for internal use *only*. *Never* acces this from outside! */ exec_context_privileged_t private_data; } exec_context_t; typedef enum { ECC_TYPE = 0x1, ECC_ETRIGGER = 0x2, ECC_FW = 0x4, ECC_W = 0x8, ECC_WCONTEXT = 0x10, ECC_MODULE = 0x20 } exec_context_change_mask_t; typedef struct { exec_context_type_t type; x_context_t x; window_context_t w; module_context_t m; } exec_context_changes_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* Creates a new exec_context from the passed in arguments in malloc'ed memory. * The context must later be destroyed with exc_destroy_context(). * * Args: * ecc * Pointer to a structure which specifies the initial values of the struct * members. * mask * The mask of members in ecc to use. */ const exec_context_t *exc_create_context( exec_context_changes_t *ecc, exec_context_change_mask_t mask); /* Similar to exc_create_context(), but the created context contains only dummy * information. */ const exec_context_t *exc_create_null_context(void); /* Works like exc_create_context(), but initialises all values with the data * from excin. The ecc/mask pair overrides these values. */ const exec_context_t *exc_clone_context( const exec_context_t *excin, exec_context_changes_t *ecc, exec_context_change_mask_t mask); /* Destroys an exec_context structure that was created with * exc_create_context(). */ void exc_destroy_context(const exec_context_t *exc); #endif /* EXECCONTEXT_H */ fvwm-2.6.7/fvwm/focus_policy.c0000644000175700017570000001242512773467231013305 00000000000000/* -*-c-*- */ /* 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 */ /* Note: focus_policy.[ch] is meant to manage structures of type focus_policy_t * only. No code dealing with *any* external data types belongs in here! Put * it in focus.[ch] instead. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "focus_policy.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Initialise focus policy to the system defaults */ void fpol_init_default_fp(focus_policy_t *fp) { memset(fp, 0, sizeof(focus_policy_t)); FPS_FOCUS_ENTER(*fp, DEF_FP_FOCUS_ENTER); FPS_UNFOCUS_LEAVE(*fp, DEF_FP_UNFOCUS_LEAVE); FPS_FOCUS_CLICK_CLIENT(*fp, DEF_FP_FOCUS_CLICK_CLIENT); FPS_FOCUS_CLICK_DECOR(*fp, DEF_FP_FOCUS_CLICK_DECOR); FPS_FOCUS_BY_PROGRAM(*fp, DEF_FP_FOCUS_BY_PROGRAM); FPS_FOCUS_BY_FUNCTION(*fp, DEF_FP_FOCUS_BY_FUNCTION); FPS_WARP_POINTER_ON_FOCUS_FUNC(*fp, DEF_FP_WARP_POINTER_ON_FOCUS_FUNC); FPS_LENIENT(*fp, DEF_FP_LENIENT); FPS_RAISE_FOCUSED_CLIENT_CLICK(*fp, DEF_FP_RAISE_FOCUSED_CLIENT_CLICK); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( *fp, DEF_FP_RAISE_UNFOCUSED_CLIENT_CLICK); FPS_RAISE_FOCUSED_DECOR_CLICK( *fp, DEF_FP_RAISE_FOCUSED_DECOR_CLICK); FPS_RAISE_UNFOCUSED_DECOR_CLICK( *fp, DEF_FP_RAISE_UNFOCUSED_DECOR_CLICK); FPS_RAISE_FOCUSED_ICON_CLICK( *fp, DEF_FP_RAISE_FOCUSED_ICON_CLICK); FPS_RAISE_UNFOCUSED_ICON_CLICK( *fp, DEF_FP_RAISE_UNFOCUSED_ICON_CLICK); FPS_MOUSE_BUTTONS(*fp, DEF_FP_MOUSE_BUTTONS); FPS_MODIFIERS(*fp, DEF_FP_MODIFIERS); FPS_PASS_FOCUS_CLICK(*fp, DEF_FP_PASS_FOCUS_CLICK); FPS_PASS_RAISE_CLICK(*fp, DEF_FP_PASS_RAISE_CLICK); FPS_IGNORE_FOCUS_CLICK_MOTION(*fp, DEF_FP_IGNORE_FOCUS_CLICK_MOTION); FPS_IGNORE_RAISE_CLICK_MOTION(*fp, DEF_FP_IGNORE_RAISE_CLICK_MOTION); FPS_ALLOW_FUNC_FOCUS_CLICK(*fp, DEF_FP_ALLOW_FUNC_FOCUS_CLICK); FPS_ALLOW_FUNC_RAISE_CLICK(*fp, DEF_FP_ALLOW_FUNC_RAISE_CLICK); FPS_GRAB_FOCUS(*fp, DEF_FP_GRAB_FOCUS); FPS_GRAB_FOCUS_TRANSIENT(*fp, DEF_FP_GRAB_FOCUS_TRANSIENT); FPS_OVERRIDE_GRAB_FOCUS(*fp, DEF_FP_OVERRIDE_GRAB_FOCUS); FPS_RELEASE_FOCUS(*fp, DEF_FP_RELEASE_FOCUS); FPS_RELEASE_FOCUS_TRANSIENT(*fp, DEF_FP_RELEASE_FOCUS_TRANSIENT); FPS_OVERRIDE_RELEASE_FOCUS(*fp, DEF_FP_OVERRIDE_RELEASE_FOCUS); FPS_SORT_WINDOWLIST_BY(*fp, DEF_FP_SORT_WINDOWLIST_BY); return; } int fpol_query_allow_set_focus( focus_policy_t *fpol, fpol_set_focus_by_t set_by_mode) { switch (set_by_mode) { case FOCUS_SET_BY_ENTER: return FP_DO_FOCUS_ENTER(*fpol); case FOCUS_SET_BY_CLICK_CLIENT: return FP_DO_FOCUS_CLICK_CLIENT(*fpol); case FOCUS_SET_BY_CLICK_DECOR: return FP_DO_FOCUS_CLICK_DECOR(*fpol); case FOCUS_SET_BY_CLICK_ICON: return FP_DO_FOCUS_CLICK_ICON(*fpol); case FOCUS_SET_BY_PROGRAM: return FP_DO_FOCUS_BY_PROGRAM(*fpol); case FOCUS_SET_BY_FUNCTION: return FP_DO_FOCUS_BY_FUNCTION(*fpol); case FOCUS_SET_FORCE: return 1; } return 0; } int fpol_query_allow_user_focus( focus_policy_t *fpol) { int flag = 0; flag |= FP_DO_FOCUS_ENTER(*fpol); flag |= FP_DO_FOCUS_CLICK_CLIENT(*fpol); flag |= FP_DO_FOCUS_CLICK_DECOR(*fpol); flag |= FP_DO_FOCUS_BY_FUNCTION(*fpol); return !!flag; } int fpol_is_policy_changed( focus_policy_t *fpol) { if (FP_DO_FOCUS_ENTER(*fpol)) { return 1; } if (FP_DO_UNFOCUS_LEAVE(*fpol)) { return 1; } if (FP_DO_FOCUS_CLICK_CLIENT(*fpol)) { return 1; } if (FP_DO_FOCUS_CLICK_DECOR(*fpol)) { return 1; } if (FP_DO_FOCUS_BY_PROGRAM(*fpol)) { return 1; } if (FP_DO_FOCUS_BY_FUNCTION(*fpol)) { return 1; } if (FP_IS_LENIENT(*fpol)) { return 1; } if (FP_DO_RAISE_FOCUSED_CLIENT_CLICK(*fpol)) { return 1; } if (FP_DO_RAISE_UNFOCUSED_CLIENT_CLICK(*fpol)) { return 1; } if (FP_DO_RAISE_FOCUSED_DECOR_CLICK(*fpol)) { return 1; } if (FP_DO_RAISE_UNFOCUSED_DECOR_CLICK(*fpol)) { return 1; } if (FP_USE_MOUSE_BUTTONS(*fpol)) { return 1; } if (FP_USE_MODIFIERS(*fpol)) { return 1; } return 0; } fvwm-2.6.7/fvwm/menudim.c0000644000175700017570000000351612773467231012246 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "menudim.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* * functions dealing with coordinates */ int menudim_middle_x_offset(struct MenuDimensions *mdim) { return MDIM_ITEM_X_OFFSET(*mdim) + MDIM_ITEM_WIDTH(*mdim) / 2; } /* hallo */ fvwm-2.6.7/fvwm/placement.h0000644000175700017570000000172512773467231012565 00000000000000/* -*-c-*- */ #ifndef PLACEMENT_H #define PLACEMENT_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { PLACE_INITIAL, PLACE_AGAIN } placement_mode_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ extern const pl_penalty_struct default_pl_penalty; extern const pl_percent_penalty_struct default_pl_percent_penalty; /* ---------------------------- interface functions ------------------------ */ Bool setup_window_placement( FvwmWindow *fw, window_style *pstyle, rectangle *attr_g, initial_window_options_t *win_opts, placement_mode_t mode); #endif /* PLACEMENT_H */ fvwm-2.6.7/fvwm/infostore.h0000644000175700017570000000166112773467231012624 00000000000000/* -*-c-*- */ #ifndef INFOSTORE_H #define INFOSTORE_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct MetaInfo { char *key; char *value; struct MetaInfo *next; } MetaInfo; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ MetaInfo *new_metainfo(void); void insert_metainfo(char *, char *); char *get_metainfo_value(const char *); int get_metainfo_length(void); MetaInfo *get_metainfo(void); void print_infostore(void); #endif /* INFOSTORE_H */ fvwm-2.6.7/fvwm/conditional.h0000644000175700017570000000173012773467231013114 00000000000000/* -*-c-*- */ #ifndef CONDITIONAL_H #define CONDITIONAL_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* Condition matching routines */ char *CreateFlagString(char *string, char **restptr); void DefaultConditionMask(WindowConditionMask *mask); void CreateConditionMask(char *flags, WindowConditionMask *mask); void FreeConditionMask(WindowConditionMask *mask); Bool MatchesConditionMask(FvwmWindow *fw, WindowConditionMask *mask); #endif /* CONDITIONAL_H */ fvwm-2.6.7/fvwm/ewmh_intern.h0000644000175700017570000001425112773467231013132 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ #ifndef _EWMH_INTERN_ #define _EWMH_INTERN_ /* Extended window manager hints support */ /* #define EWMH_DEBUG */ #ifdef EWMH_DEBUG #include #include #include "ftime.h" #endif typedef struct ewmh_atom { char *name; Atom atom; Atom atom_type; #ifdef __STDC__ int (*action)(FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); #else int (*action)(); #endif } ewmh_atom; typedef enum { EWMH_ATOM_LIST_ALL, EWMH_ATOM_LIST_CLIENT_ROOT, EWMH_ATOM_LIST_CLIENT_WIN, EWMH_ATOM_LIST_WM_STATE, EWMH_ATOM_LIST_ALLOWED_ACTIONS, EWMH_ATOM_LIST_WINDOW_TYPE, EWMH_ATOM_LIST_FIXED_PROPERTY, EWMH_ATOM_LIST_PROPERTY_NOTIFY, EWMH_ATOM_LIST_FVWM_ROOT, EWMH_ATOM_LIST_FVWM_WIN, EWMH_ATOM_LIST_END } ewmh_atom_list_name; typedef struct { ewmh_atom_list_name name; ewmh_atom *list; int size; } ewmh_atom_list; #define NET_WM_STATE_ADD 1 #define NET_WM_STATE_REMOVE 0 #define NET_WM_STATE_TOGGLE 2 #define EWMH_MAXIMIZE_HORIZ 0x1 #define EWMH_MAXIMIZE_VERT 0x2 #define EWMH_MAXIMIZE_FULL 0x3 #define EWMH_MAXIMIZE_REMOVE 0x4 #define EWMH_MAXIMIZE_FULLSCREEN 0x8 typedef enum { _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP, _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM, _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT, _NET_WM_MOVERESIZE_MOVE, _NET_WM_MOVERESIZE_SIZE_KEYBOARD, _NET_WM_MOVERESIZE_MOVE_KEYBOARD } ewmh_move_resize; typedef struct ewmh_info { unsigned NumberOfDesktops; unsigned MaxDesktops; unsigned CurrentNumberOfDesktops; Bool NeedsToCheckDesk; ewmh_strut BaseStrut; } ewmhInfo; extern ewmhInfo ewmhc; ewmh_atom *ewmh_GetEwmhAtomByAtom(Atom atom, ewmh_atom_list_name list_name); void ewmh_ChangeProperty( Window w, const char *atom_name, ewmh_atom_list_name list, unsigned char *data, int length); void ewmh_DeleteProperty( Window w, const char *atom_name, ewmh_atom_list_name list); void *ewmh_AtomGetByName( Window win, const char *atom_name, ewmh_atom_list_name list, int *size); int ewmh_HandleDesktop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_HandleDialog( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_HandleDock( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_HandleMenu( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_HandleNormal( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_HandleToolBar( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_HandleNotification( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); void ewmh_AddToKdeSysTray(FvwmWindow *fw); void ewmh_SetWorkArea(void); void ewmh_ComputeAndSetWorkArea(void); void ewmh_HandleDynamicWorkArea(void); void ewmh_HandleWindowType(FvwmWindow *fw, window_style *style); int ewmh_CurrentDesktop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_DesktopGeometry( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_DesktopViewPort( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_NumberOfDesktops( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_ActiveWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_CloseWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_MoveResizeWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_RestackWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMDesktop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_MoveResize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMState( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateFullScreen( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateHidden( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateMaxHoriz( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateMaxVert( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateModal( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateShaded( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateSkipPager( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateSkipTaskBar( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateStaysOnTop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateStaysOnBottom( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStateSticky( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMIconGeometry( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int ewmh_WMStrut( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsYes( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsClose( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsFullScreen( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsMinimize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsMaximize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsMove( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); Bool ewmh_AllowsResize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); /* ewmh_icon */ int ewmh_WMIcon( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); CARD32 *ewmh_SetWmIconFromPixmap( FvwmWindow *fw, CARD32 *orig_icon, int *orig_size, Bool is_mini_icon); /* debugging */ #ifdef EWMH_DEBUG void EWMH_DLOG(char *msg, ...); #else #endif #endif /* _EWMH_INTERN_ */ fvwm-2.6.7/fvwm/Makefile.am0000644000175700017570000000451113001406606012454 00000000000000## Process this file with automake to create Makefile.in configdir = @FVWM_DATADIR@ bin_PROGRAMS = fvwm EXTRA_DIST = $(config_DATA) config_DATA = ConfigFvwmDefaults ## please keep .c file in largest first order to speed up parallel makes fvwm_SOURCES = \ add_window.h bindings.h borders.h builtins.h colormaps.h colorset.h \ commands.h conditional.h condrc.h cursor.h decorations.h events.h \ eventhandler.h eventmask.h ewmh.h ewmh_intern.h expand.h externs.h \ focus.h functable.h functions.h fvwm.h geometry.h focus_policy.h \ icccm2.h icons.h menubindings.h menudim.h menugeometry.h \ menuitem.h menuroot.h menuparameters.h menus.h menustyle.h misc.h \ modconf.h module_interface.h module_list.h move_resize.h \ placement.h read.h repeat.h execcontext.h schedule.h screen.h \ session.h stack.h style.h update.h virtual.h window_flags.h frame.h \ infostore.h \ \ menus.c style.c borders.c events.c move_resize.c builtins.c \ add_window.c icons.c fvwm.c frame.c placement.c virtual.c \ menustyle.c conditional.c ewmh.c stack.c session.c colorset.c \ functions.c ewmh_events.c geometry.c module_list.c focus.c \ windowlist.c functable.c menuitem.c expand.c module_interface.c \ menubindings.c decorations.c ewmh_icons.c update.c bindings.c misc.c \ cursor.c colormaps.c modconf.c ewmh_conf.c read.c schedule.c \ menucmd.c ewmh_names.c icccm2.c windowshade.c focus_policy.c repeat.c \ execcontext.c menugeometry.c menudim.c condrc.c infostore.c fvwm_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = \ -L$(top_builddir)/libs -lfvwm $(Xft_LIBS) $(X_LIBS) $(xpm_LIBS) \ $(stroke_LIBS) $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 \ $(X_EXTRA_LIBS) -lm $(iconv_LIBS) $(Xrender_LIBS) $(Xcursor_LIBS) \ $(Bidi_LIBS) $(png_LIBS) $(rsvg_LIBS) $(intl_LIBS) AM_CPPFLAGS = \ -I$(top_srcdir) $(stroke_CFLAGS) $(Xft_CFLAGS) \ $(xpm_CFLAGS) $(X_CFLAGS) $(iconv_CFLAGS) $(Xrender_CFLAGS) \ $(Bidi_CFLAGS) $(png_CFLAGS) $(rsvg_CFLAGS) $(intl_CFLAGS) AM_CFLAGS = \ -DFVWM_MODULEDIR=\"$(FVWM_MODULEDIR)\" \ -DFVWM_DATADIR=\"$(FVWM_DATADIR)\" \ -DFVWM_CONFDIR=\"$(FVWM_CONFDIR)\" \ -DFVWM_COLORSET_PRIVATE=1 \ -DLOCALEDIR=\"$(LOCALEDIR)\" ## Create compatibility symlinks if available install-exec-local: @rm -f $(DESTDIR)$(bindir)/fvwm2 @$(LN_S) fvwm $(DESTDIR)$(bindir)/fvwm2 || \ echo "Minor warning: $(bindir)/fvwm2 symlink was not created" fvwm-2.6.7/fvwm/stack.c0000644000175700017570000013575113001406607011705 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include #include "libs/ftime.h" #include "libs/fvwmlib.h" #include "libs/gravity.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/defaults.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "module_list.h" #include "module_interface.h" #include "focus.h" #include "stack.h" #include "events.h" #include "borders.h" #include "virtual.h" #include "geometry.h" #include "icons.h" #include "ewmh.h" #include "frame.h" /* ---------------------------- local definitions -------------------------- */ /* If more than this many transients are in a single branch of a transient * tree, they will end up in more or less random stacking order. */ #define MAX_TRANSIENTS_IN_BRANCH 200000 /* Same for total levels of transients. */ #define MAX_TRANSIENT_LEVELS 10000 /* This number must fit in a signed int! */ #define LOWER_PENALTY (MAX_TRANSIENTS_IN_BRANCH * MAX_TRANSIENT_LEVELS) /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef enum { SM_RAISE = MARK_RAISE, SM_LOWER = MARK_LOWER, SM_RESTACK = MARK_RESTACK } stack_mode_t; /* ---------------------------- forward declarations ----------------------- */ static void __raise_or_lower_window( FvwmWindow *t, stack_mode_t mode, Bool allow_recursion, Bool is_new_window, Bool is_client_request); static void raise_or_lower_window( FvwmWindow *t, stack_mode_t mode, Bool allow_recursion, Bool is_new_window, Bool is_client_request); #if 0 static void ResyncFvwmStackRing(void); #endif static void ResyncXStackingOrder(void); static void BroadcastRestack(FvwmWindow *s1, FvwmWindow *s2); static Bool is_above_unmanaged(FvwmWindow *fw, Window *umtop); static int collect_transients_recursive( FvwmWindow *t, FvwmWindow *list_head, int layer, stack_mode_t mode, Bool do_include_target_window); /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ #define DEBUG_STACK_RING 1 #ifdef DEBUG_STACK_RING /* debugging function */ static void dump_stack_ring(void) { FvwmWindow *t1; if (!debugging_stack_ring) { return; } XBell(dpy, 0); fprintf(stderr,"dumping stack ring:\n"); for ( t1 = Scr.FvwmRoot.stack_next; t1 != &Scr.FvwmRoot; t1 = t1->stack_next) { fprintf(stderr," l=%d fw=%p f=0x%08x '%s'\n", t1->layer, t1, (int)FW_W_FRAME(t1), t1->name.name); } return; } /* debugging function */ void verify_stack_ring_consistency(void) { Window root, parent, *children; unsigned int nchildren; int i; FvwmWindow *t1, *t2; int last_layer; int last_index; if (!debugging_stack_ring) { return; } XFlush(dpy); t2 = Scr.FvwmRoot.stack_next; if (t2 == &Scr.FvwmRoot) { return; } last_layer = t2->layer; for ( t1 = t2->stack_next; t1 != &Scr.FvwmRoot; t2 = t1, t1 = t1->stack_next) { if (t1->layer > last_layer) { fprintf( stderr, "vsrc: stack ring is corrupt! '%s' (layer %d)" " is above '%s' (layer %d/%d)\n", t1->name.name, t1->layer, t2->name.name, t2->layer, last_layer); dump_stack_ring(); return; } last_layer = t1->layer; } t2 = &Scr.FvwmRoot; for ( t1 = t2->stack_next; t1 != &Scr.FvwmRoot; t2 = t1, t1 = t1->stack_next) { if (t1->stack_prev != t2) { break; } } if (t1 != &Scr.FvwmRoot || t1->stack_prev != t2) { fprintf( stderr, "vsrc: stack ring is corrupt -" " fvwm will probably crash! %p -> %p but %p <- %p", t2, t1, t1->stack_prev, t1); dump_stack_ring(); return; } MyXGrabServer(dpy); if (!XQueryTree(dpy, Scr.Root, &root, &parent, &children, &nchildren)) { MyXUngrabServer(dpy); return; } last_index = nchildren; for ( t1 = Scr.FvwmRoot.stack_next; t1 != &Scr.FvwmRoot; t1 = t1->stack_next) { /* find window in window list */ for ( i = 0; i < nchildren && FW_W_FRAME(t1) != children[i]; i++) { /* nothing to do here */ } if (i == nchildren) { fprintf( stderr,"vsrc: window already died:" " fw=%p w=0x%08x '%s'\n", t1, (int)FW_W_FRAME(t1), t1->name.name); } else if (i >= last_index) { fprintf( stderr, "vsrc: window is at wrong position" " in stack ring: fw=%p f=0x%08x '%s'\n", t1, (int)FW_W_FRAME(t1), t1->name.name); dump_stack_ring(); fprintf(stderr,"dumping X stacking order:\n"); for (i = nchildren; i-- > 0; ) { for ( t1 = Scr.FvwmRoot.stack_next; t1 != &Scr.FvwmRoot; t1 = t1->stack_next) { /* only dump frame windows */ if (FW_W_FRAME(t1) == children[i]) { fprintf( stderr, " f=0x%08x\n", (int)children[i]); break; } } } MyXUngrabServer(dpy); XFree(children); return; } last_index = i; } MyXUngrabServer(dpy); XFree(children); return; } #endif /* Add a whole ring of windows. The list_head itself will not be added. */ static void add_windowlist_to_stack_ring_after( FvwmWindow *list_head, FvwmWindow *add_after_win) { add_after_win->stack_next->stack_prev = list_head->stack_prev; list_head->stack_prev->stack_next = add_after_win->stack_next; add_after_win->stack_next = list_head->stack_next; list_head->stack_next->stack_prev = add_after_win; return; } static FvwmWindow *get_transientfor_top_fvwmwindow(FvwmWindow *t) { FvwmWindow *s; s = t; while (s && IS_TRANSIENT(s) && DO_STACK_TRANSIENT_PARENT(s)) { s = get_transientfor_fvwmwindow(s); if (s) { t = s; } } return t; } /* * Raise a target and all higher fvwm-managed windows above any * override_redirects: * - locate the highest override_redirect above our target * - put all the FvwmWindows from the target to the highest FvwmWindow * below the highest override_redirect in the restack list * - configure our target window above the override_redirect sibling, * and restack. */ static void raise_over_unmanaged(FvwmWindow *t) { int i; Window OR_Above = None; Window *wins; int count = 0; FvwmWindow *t2 = NULL; unsigned int flags; XWindowChanges changes; /* * Locate the highest override_redirect window above our target, and * the highest of our windows below it. * * Count the windows we need to restack, then build the stack list. */ if (!is_above_unmanaged(t, &OR_Above)) { for ( count = 0, t2 = Scr.FvwmRoot.stack_next; t2 != &Scr.FvwmRoot; t2 = t2->stack_next) { count++; count += get_visible_icon_window_count(t2); if (t2 == t) { break; } } if (count > 0) { wins = (Window*) safemalloc (count * sizeof (Window)); for ( i = 0, t2 = Scr.FvwmRoot.stack_next; t2 != &Scr.FvwmRoot; t2 = t2->stack_next) { wins[i++] = FW_W_FRAME(t2); if (IS_ICONIFIED(t2) && ! IS_ICON_SUPPRESSED(t2)) { if (FW_W_ICON_TITLE(t2) != None) { wins[i++] = FW_W_ICON_TITLE(t2); } if (FW_W_ICON_PIXMAP(t2) != None) { wins[i++] = FW_W_ICON_PIXMAP(t2); } } if (t2 == t) { break; } } memset(&changes, '\0', sizeof(changes)); changes.sibling = OR_Above; changes.stack_mode = Above; flags = CWSibling|CWStackMode; XConfigureWindow( dpy, FW_W_FRAME(t)/*topwin*/, flags, &changes); if (i > 1) { XRestackWindows(dpy, wins, i); } free (wins); } }/* end - we found an OR above our target */ return; } static Bool __is_restack_transients_needed( FvwmWindow *t, stack_mode_t mode) { if (DO_RAISE_TRANSIENT(t)) { if (mode == SM_RAISE || mode == SM_RESTACK) { return True; } } if (DO_LOWER_TRANSIENT(t)) { if (mode == SM_LOWER || mode == SM_RESTACK) { return True; } } return False; } static Bool __must_move_transients( FvwmWindow *t, stack_mode_t mode) { if (IS_ICONIFIED(t)) { return False; } /* raise */ if (__is_restack_transients_needed(t, mode) == True) { Bool scanning_above_window = True; FvwmWindow *q; for ( q = Scr.FvwmRoot.stack_next; q != &Scr.FvwmRoot && t->layer <= q->layer; q = q->stack_next) { if (t->layer < q->layer) { /* We're not interested in higher layers. */ continue; } else if (mode == SM_RESTACK && IS_TRANSIENT(q) && FW_W_TRANSIENTFOR(q) == FW_W(t)) { return True; } else if (t == q) { /* We found our window. All further transients * are below it. */ scanning_above_window = False; } else if (IS_TRANSIENT(q) && FW_W_TRANSIENTFOR(q) == FW_W(t)) { return True; } else if (scanning_above_window && mode == SM_RAISE) { /* raise: The window is not raised, so itself * and all transients will be raised. */ return True; } } } return False; } static Window __get_stacking_sibling(FvwmWindow *fw, Bool do_stack_below) { Window w; /* default to frame window */ w = FW_W_FRAME(fw); if (IS_ICONIFIED(fw) && do_stack_below == True) { /* override with icon windows when stacking below */ if (FW_W_ICON_PIXMAP(fw) != None) { w = FW_W_ICON_PIXMAP(fw); } else if (FW_W_ICON_TITLE(fw) != None) { w = FW_W_ICON_TITLE(fw); } } return w; } static void __sort_transient_ring(FvwmWindow *ring) { FvwmWindow *s; FvwmWindow *t; FvwmWindow *u; FvwmWindow *prev; if (ring->stack_next->stack_next == ring) { /* only one or zero windows */ return; } /* Implementation note: this sorting algorithm is about the most * inefficient possible. It just swaps the position of two adjacent * windows in the ring if they are in the wrong order. Since * transient windows are rare, this should not cause any notable * performance hit. Because it is important that the order of windows * with the same key is not changed, we can not just use qsort() here. */ for ( t = ring->stack_next, prev = ring; t->stack_next != ring; prev = t->stack_prev) { s = t->stack_next; if (t->scratch.i < s->scratch.i) { /* swap windows */ u = s->stack_next; s->stack_next = t; t->stack_next = u; u = t->stack_prev; t->stack_prev = s; s->stack_prev = u; s->stack_prev->stack_next = s; t->stack_next->stack_prev = t; if (prev != ring) { /* move further up the ring? */ t = prev; } else { /* hit start of ring */ } } else { /* correct order, advance one window */ t = t->stack_next; } } return; } static void __restack_window_list( FvwmWindow *r, FvwmWindow *s, int count, Bool do_broadcast_all, Bool do_lower) { FvwmWindow *t; unsigned int flags; int i; XWindowChanges changes; Window *wins; int do_stack_above; int is_reversed; if (count <= 0) { for (count = 0, t = r->stack_next; t != s; t = t->stack_next) { count++; count += get_visible_icon_window_count(t); } } /* restack the windows between r and s */ wins = (Window *)safemalloc((count + 3) * sizeof(Window)); for (t = r->stack_next, i = 0; t != s; t = t->stack_next) { if (i > count) { fvwm_msg( ERR, "__restack_window_list", "more transients than expected"); break; } wins[i++] = FW_W_FRAME(t); if (IS_ICONIFIED(t) && !IS_ICON_SUPPRESSED(t)) { if (FW_W_ICON_TITLE(t) != None) { wins[i++] = FW_W_ICON_TITLE(t); } if (FW_W_ICON_PIXMAP(t) != None) { wins[i++] = FW_W_ICON_PIXMAP(t); } } } changes.sibling = __get_stacking_sibling(r, True); if (changes.sibling == None) { changes.sibling = __get_stacking_sibling(s, False); is_reversed = 1; } else { is_reversed = 0; } if (changes.sibling == None) { do_stack_above = !do_lower; flags = CWStackMode; } else { do_stack_above = 0; flags = CWStackMode | CWSibling; } changes.stack_mode = (do_stack_above ^ is_reversed) ? Above : Below; XConfigureWindow(dpy, FW_W_FRAME(r->stack_next), flags, &changes); if (count > 1) { XRestackWindows(dpy, wins, count); } free(wins); EWMH_SetClientListStacking(); if (do_broadcast_all) { /* send out M_RESTACK for all windows, to make sure we don't * forget anything. */ BroadcastRestackAllWindows(); } else { /* send out (one or more) M_RESTACK packets for windows * between r and s */ BroadcastRestack(r, s); } return; } FvwmWindow *__get_window_to_insert_after(FvwmWindow *fw, stack_mode_t mode) { int test_layer; FvwmWindow *s; switch (mode) { case SM_LOWER: test_layer = fw->layer - 1; break; default: case SM_RAISE: case SM_RESTACK: test_layer = fw->layer; break; } for ( s = Scr.FvwmRoot.stack_next; s != &Scr.FvwmRoot; s = s->stack_next) { if (s == fw) { continue; } if (test_layer >= s->layer) { break; } } return s; } static void __mark_group_member( FvwmWindow *fw, FvwmWindow *start, FvwmWindow *end) { FvwmWindow *t; for (t = start; t != end; t = t->stack_next) { if (FW_W(t) == fw->wmhints->window_group || (t->wmhints && (t->wmhints->flags & WindowGroupHint) && t->wmhints->window_group == fw->wmhints->window_group)) { if (IS_IN_TRANSIENT_SUBTREE(t)) { /* have to move this one too */ SET_IN_TRANSIENT_SUBTREE(fw, 1); } } } return; } static Bool __mark_transient_subtree_test( FvwmWindow *s, FvwmWindow *start, FvwmWindow *end, int mark_mode, Bool do_ignore_icons, Bool use_window_group_hint) { Bool use_group_hint = False; FvwmWindow *r; if (IS_IN_TRANSIENT_SUBTREE(s)) { return False; } if (use_window_group_hint && DO_ICONIFY_WINDOW_GROUPS(s) && s->wmhints && (s->wmhints->flags & WindowGroupHint) && (s->wmhints->window_group != None) && (s->wmhints->window_group != FW_W(s)) && (s->wmhints->window_group != Scr.Root)) { use_group_hint = True; } if (!IS_TRANSIENT(s) && !use_group_hint) { return False; } if (do_ignore_icons && IS_ICONIFIED(s)) { return False; } r = (FvwmWindow *)s->scratch.p; if (IS_TRANSIENT(s)) { if (r && IS_IN_TRANSIENT_SUBTREE(r) && ((mark_mode == MARK_ALL) || __is_restack_transients_needed( r, (stack_mode_t)mark_mode) == True)) { /* have to move this one too */ SET_IN_TRANSIENT_SUBTREE(s, 1); /* used for stacking transients */ s->scratch.i += r->scratch.i + 1; return True; } } if (use_group_hint && !IS_IN_TRANSIENT_SUBTREE(s)) { __mark_group_member(s, start, end); if (IS_IN_TRANSIENT_SUBTREE(s)) { /* need another scan through the list */ return True; } } return False; } /* heavaly borrowed from mark_transient_subtree. This will mark a subtree as * long as it is straight, and return true if the operation is succussful. It * will abort and return False as soon as some inconsitance is hit. */ static Bool is_transient_subtree_straight( FvwmWindow *t, int layer, stack_mode_t mode, Bool do_ignore_icons, Bool use_window_group_hint) { FvwmWindow *s; FvwmWindow *start; FvwmWindow *end; int min_i; Bool is_in_gap; int mark_mode; switch (mode) { case SM_RAISE: mark_mode = MARK_RAISE; break; case SM_LOWER: mark_mode = MARK_LOWER; break; default: return False; } if (layer >= 0 && t->layer != layer) { return True; } if (t->stack_prev == NULL || t->stack_next == NULL) { /* the window is not placed correctly in the stack ring * (probably about to be destroyed) */ return False; } /* find out on which windows to operate */ /* iteration are done reverse (bottom up, since that's the way the * transients wil be stacked if all is well */ if (layer >= 0) { /* only work on the given layer */ start = &Scr.FvwmRoot; end = &Scr.FvwmRoot; for ( s = Scr.FvwmRoot.stack_prev; s != &Scr.FvwmRoot && s->layer <= layer; s = s->stack_prev) { if (s->layer == layer) { if (start == &Scr.FvwmRoot) { start = s; } end = s->stack_prev; } } } else { /* work on complete window list */ start = Scr.FvwmRoot.stack_prev; end = &Scr.FvwmRoot; } /* clean the temporary flag in all windows and precalculate the * transient frame windows */ for ( s = Scr.FvwmRoot.stack_next; s != &Scr.FvwmRoot; s = s->stack_next) { SET_IN_TRANSIENT_SUBTREE(s, 0); if (IS_TRANSIENT(s) && (layer < 0 || layer == s->layer)) { s->scratch.p = get_transientfor_fvwmwindow(s); } else { s->scratch.p = NULL; } } /* Indicate that no cleening is needed */ Scr.FvwmRoot.scratch.i = 1; /* now loop over the windows and mark the ones we need to move */ SET_IN_TRANSIENT_SUBTREE(t, 1); min_i = INT_MIN; is_in_gap = False; if (mode == SM_LOWER && t != start) { return False; } /* check that all transients above the window are in a sorted line * with no other windows between them */ for (s = t->stack_prev; s != end && !(is_in_gap && mode == SM_RAISE); s = s->stack_prev) { if ( __mark_transient_subtree_test( s, start, end, mark_mode, do_ignore_icons, use_window_group_hint)) { if (is_in_gap) { return False; } else if (s->scratch.i < min_i) { return False; } min_i = s->scratch.i; } else { is_in_gap = True; } } /* for */ if (is_in_gap && mode == SM_RAISE) { return False; } /* check that there are no transients left beneth the window */ for (s = start; s != t; s = s->stack_prev) { if ( __mark_transient_subtree_test( s, start, end, mark_mode, do_ignore_icons, use_window_group_hint)) { return False; } } return True; } /* function to test if all windows are at correct place from start. */ static Bool __is_restack_needed( FvwmWindow *t, stack_mode_t mode, Bool do_restack_transients, Bool is_new_window) { if (is_new_window) { return True; } else if (t->stack_prev == NULL || t->stack_next == NULL) { /* the window is about to be destroyed, and has been removed * from the stack ring. No need to restack. */ return False; } if (mode == SM_RESTACK) { return True; } if (do_restack_transients) { return !is_transient_subtree_straight( t, t->layer, mode, True, False); } else if (mode == SM_LOWER) { return (t->stack_next != &Scr.FvwmRoot && t->stack_next->layer == t->layer); } else if (mode == SM_RAISE) { return (t->stack_prev != &Scr.FvwmRoot && t->stack_prev->layer == t->layer); } return True; } static Bool __restack_window( FvwmWindow *t, stack_mode_t mode, Bool do_restack_transients, Bool is_new_window, Bool is_client_request) { FvwmWindow *s = NULL; FvwmWindow *r = NULL; FvwmWindow tmp_r; int count; if (!__is_restack_needed( t, mode, do_restack_transients, is_new_window)) { /* need to cancel out the effect of any M_RAISE/M_LOWER that * might already be send out. This is ugly. Better would be to * not send the messages in the first place. */ if (do_restack_transients) { s = t->stack_next; if (s == NULL) { return True; } while (IS_IN_TRANSIENT_SUBTREE(s)) { s = s->stack_next; } BroadcastRestack(t->stack_prev, s); } /* native/unmanaged windows might have raised. However some * buggy clients will keep issuing requests if the raise hacks * are done after processing their requests. */ return is_client_request; } count = 0; if (do_restack_transients) { /* collect the transients in a temp list */ tmp_r.stack_prev = &tmp_r; tmp_r.stack_next = &tmp_r; count = collect_transients_recursive( t, &tmp_r, t->layer, mode, False); if (count == 0) { do_restack_transients = False; } } count += 1 + get_visible_icon_window_count(t); /* now find the place to reinsert t and friends */ if (mode == SM_RESTACK) { s = t->stack_next; } else { s = __get_window_to_insert_after(t, mode); } remove_window_from_stack_ring(t); r = s->stack_prev; if (do_restack_transients) { /* re-sort the transient windows according to their scratch.i * register */ __sort_transient_ring(&tmp_r); /* insert all transients between r and s. */ add_windowlist_to_stack_ring_after(&tmp_r, r); } /* ** Re-insert t - below transients */ add_window_to_stack_ring_after(t, s->stack_prev); if (is_new_window && IS_TRANSIENT(t) && DO_STACK_TRANSIENT_PARENT(t) && !IS_ICONIFIED(t)) { /* now that the new transient is properly positioned in the * stack ring, raise/lower it again so that its parent is * raised/lowered too */ raise_or_lower_window(t, mode, True, False, is_client_request); /* make sure the stacking order is correct - may be the * sledge-hammer method, but the recursion ist too hard to * understand. */ ResyncXStackingOrder(); /* if the transient is on the top of the top layer pan frames * will have ended up under all windows after this. */ return (t->stack_prev != &Scr.FvwmRoot); } else { /* restack the windows between r and s */ __restack_window_list( r, s, count, do_restack_transients, mode == (SM_LOWER) ? True : False); } return False; } static Bool __raise_lower_recursion( FvwmWindow *t, stack_mode_t mode, Bool is_client_request) { FvwmWindow *t2; for ( t2 = Scr.FvwmRoot.stack_next; t2 != &Scr.FvwmRoot; t2 = t2->stack_next) { if (FW_W(t2) == FW_W_TRANSIENTFOR(t)) { if (t2 == t) { return False; } if (IS_ICONIFIED(t2) || t->layer != t2->layer) { break; } if (mode == SM_LOWER && (!IS_TRANSIENT(t2) || !DO_STACK_TRANSIENT_PARENT(t2))) { /* hit the highest level transient; lower this * subtree below all other subtrees of the * same window */ t->scratch.i = -LOWER_PENALTY; } else { /* Add a bonus to the stack ring position for * this branch of the transient tree over all * other branches. */ t->scratch.i = MAX_TRANSIENTS_IN_BRANCH; } __raise_or_lower_window( t2, mode, True, False, is_client_request); if (__is_restack_transients_needed(t2, mode)) { /* moving the parent moves our window already */ return True; } } } return False; } static void __raise_or_lower_window( FvwmWindow *t, stack_mode_t mode, Bool allow_recursion, Bool is_new_window, Bool is_client_request) { FvwmWindow *t2; Bool do_move_transients; /* Do not raise this window after command execution (see * HandleButtonPress()). */ SET_SCHEDULED_FOR_RAISE(t, 0); /* New windows are simply raised/lowered without touching the * transientfor at first. Then, further down in the code, * __raise_or_lower_window() is called again to raise/lower the * transientfor if necessary. We can not do the recursion stuff for * new windows because the __must_move_transients() call needs a * properly ordered stack ring - but the new window is still at the * front of the stack ring. */ if (allow_recursion && !is_new_window && !IS_ICONIFIED(t)) { /* This part makes Raise/Lower on a Transient act on its Main * and sibling Transients. * * The recursion is limited to one level - which caters for * most cases. This code does not handle the case where there * are trees of Main + Transient (i.e. where a * Main_window_with_Transients is itself Transient for another * window). */ if (IS_TRANSIENT(t) && DO_STACK_TRANSIENT_PARENT(t)) { if (__raise_lower_recursion( t, mode, is_client_request) == True) { return; } } } if (is_new_window) { do_move_transients = False; } else { do_move_transients = __must_move_transients(t, mode); } if (__restack_window( t, mode, do_move_transients, is_new_window, is_client_request) == True) { return; } if (mode == SM_RAISE) { /* This hack raises the target and all higher fvwm windows over * any style grabfocusoff override_redirect windows that may be * above it. This is used to cope with ill-behaved applications * that insist on using long-lived override_redirects. */ if (Scr.bo.do_raise_over_unmanaged) { raise_over_unmanaged(t); } /* * The following is a hack to raise X windows over native * windows which is needed for some (all ?) X servers running * under Windows or Windows NT. */ if (Scr.bo.is_raise_hack_needed) { /* RBW - 09/20/1999. I find that trying to raise * unmanaged windows causes problems with some apps. If * this seems to work well for everyone, I'll remove * the #if 0. */ #if 0 /* get *all* toplevels (even including * override_redirects) */ XQueryTree(dpy, Scr.Root, &junk, &junk, &tops, &num); /* raise from fw upwards to get them above NT windows */ for (i = 0; i < num; i++) { if (tops[i] == FW_W_FRAME(t)) { found = True; } if (found) { XRaiseWindow (dpy, tops[i]); } } XFree (tops); #endif for (t2 = t; t2 != &Scr.FvwmRoot; t2 = t2->stack_prev) { XRaiseWindow(dpy, FW_W_FRAME(t2)); } } /* This needs to be done after all the raise hacks. */ raisePanFrames(); /* If the window has been raised, make sure the decorations are * updated immediately in case we are in a complex function * (e.g. raise, unshade). */ XFlush(dpy); handle_all_expose(); } return; } static void raise_or_lower_window( FvwmWindow *t, stack_mode_t mode, Bool allow_recursion, Bool is_new_window, Bool is_client_request) { FvwmWindow *fw; /* clean the auxiliary registers used in stacking transients */ for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { fw->scratch.i = 0; } __raise_or_lower_window( t, mode, allow_recursion, is_new_window, is_client_request); return; } static Bool intersect( int x0, int y0, int w0, int h0, int x1, int y1, int w1, int h1) { return !((x0 >= x1 + w1) || (x0 + w0 <= x1) || (y0 >= y1 + h1) || (y0 + h0 <= y1)); } static Bool overlap(FvwmWindow *r, FvwmWindow *s) { rectangle g1; rectangle g2; Bool rc; if (r->Desk != s->Desk) { return False; } rc = get_visible_window_or_icon_geometry(r, &g1); if (rc == False) { return False; } rc = get_visible_window_or_icon_geometry(s, &g2); if (rc == False) { return False; } rc = intersect( g1.x, g1.y, g1.width, g1.height, g2.x, g2.y, g2.width, g2.height); return rc; } #if 0 /* ResyncFvwmStackRing - Rebuilds the stacking order ring of fvwm-managed windows. For use in cases where apps raise/lower their own windows in a way that makes it difficult to determine exactly where they ended up in the stacking order. - Based on code from Matthias Clasen. */ static void ResyncFvwmStackRing (void) { Window root, parent, *children; unsigned int nchildren; int i; FvwmWindow *t1, *t2; MyXGrabServer (dpy); if (!XQueryTree (dpy, Scr.Root, &root, &parent, &children, &nchildren)) { MyXUngrabServer (dpy); return; } t2 = &Scr.FvwmRoot; for (i = 0; i < nchildren; i++) { for (t1 = Scr.FvwmRoot.next; t1 != NULL; t1 = t1->next) { if (IS_ICONIFIED(t1) && !IS_ICON_SUPPRESSED(t1)) { if (FW_W_ICON_TITLE(t1) == children[i] || FW_W_ICON_PIXMAP(t1) == children[i]) { break; } } else { if (FW_W_FRAME(t1) == children[i]) { break; } } } if (t1 != NULL && t1 != t2) { /* Move the window to its new position, working from * the bottom up (that's the way XQueryTree presents * the list). */ /* Pluck from chain. */ remove_window_from_stack_ring(t1); add_window_to_stack_ring_after(t1, t2->stack_prev); if (t2 != &Scr.FvwmRoot && t2->layer > t1->layer) { /* oops, now our stack ring is out of order! */ /* emergency fix */ t1->layer = t2->layer; } t2 = t1; } } MyXUngrabServer (dpy); XFree (children); } #endif /* same as above but synchronizes the stacking order in X from the stack ring. */ static void ResyncXStackingOrder(void) { Window *wins; FvwmWindow *t; int count; int i; for (count = 0, t = Scr.FvwmRoot.next; t != NULL; count++, t = t->next) { /* nothing to do here */ } if (count > 0) { wins = (Window *)safemalloc(3 * count * sizeof (Window)); for ( i = 0, t = Scr.FvwmRoot.stack_next; count--; t = t->stack_next) { wins[i++] = FW_W_FRAME(t); if (IS_ICONIFIED(t) && !IS_ICON_SUPPRESSED(t)) { if (FW_W_ICON_TITLE(t) != None) { wins[i++] = FW_W_ICON_TITLE(t); } if (FW_W_ICON_PIXMAP(t) != None) { wins[i++] = FW_W_ICON_PIXMAP(t); } } } XRestackWindows(dpy, wins, i); free(wins); /* send out M_RESTACK for all windows, to make sure we don't * forget anything. */ BroadcastRestackAllWindows(); } return; } /* send RESTACK packets for all windows between s1 and s2 */ static void BroadcastRestack(FvwmWindow *s1, FvwmWindow *s2) { FvwmWindow *fw; int num; int i; int n; fmodule_list_itr moditr; fmodule *module; unsigned long *body, *bp, length; unsigned long max_wins_per_packet; if (s2 == &Scr.FvwmRoot) { s2 = s2->stack_prev; if (s2 == &Scr.FvwmRoot) { return; } } if (s1 == &Scr.FvwmRoot) { s1 = s1->stack_next; if (s1 == &Scr.FvwmRoot) { return; } /* s1 has been moved to the top of stack */ BroadcastPacket( M_RAISE_WINDOW, 3, (long)FW_W(s1), (long)FW_W_FRAME(s1), (unsigned long)s1); if (s1->stack_next == s2) { /* avoid sending empty RESTACK packet */ return; } } if (s1 == s2) { /* A useful M_RESTACK packet must contain at least two windows. */ return; } for ( fw = s1, num = 1; fw != s2 && fw != &Scr.FvwmRoot; fw = fw->stack_next, num++) { /* nothing */ } max_wins_per_packet = (FvwmPacketMaxSize - FvwmPacketHeaderSize) / 3; /* split packet if it is too long */ for ( ; num > 1; s1 = fw, num -= n) { n = min(num, max_wins_per_packet) - 1; length = FvwmPacketHeaderSize + 3 * (n + 1); body = (unsigned long *)safemalloc( length * sizeof(unsigned long)); bp = body; *(bp++) = START_FLAG; *(bp++) = M_RESTACK; *(bp++) = length; *(bp++) = fev_get_evtime(); for (fw = s1, i = 0; i <= n; i++, fw = fw->stack_next) { *(bp++) = FW_W(fw); *(bp++) = FW_W_FRAME(fw); *(bp++) = (unsigned long)fw; } /* The last window has to be in the header of the next part */ fw = fw->stack_prev; module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { PositiveWrite( module,body,length*sizeof(unsigned long)); } free(body); } #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return; } static int collect_transients_recursive( FvwmWindow *t, FvwmWindow *list_head, int layer, stack_mode_t mode, Bool do_include_target_window) { FvwmWindow *s; int count = 0; int m; switch (mode) { case SM_LOWER: m = MARK_LOWER; break; case SM_RAISE: m = MARK_RAISE; break; case SM_RESTACK: m = MARK_RESTACK; break; default: /* can not happen */ m = MARK_RAISE; break; } mark_transient_subtree(t, layer, m, True, False); /* now collect the marked windows in a separate list */ for (s = Scr.FvwmRoot.stack_next; s != &Scr.FvwmRoot; ) { FvwmWindow *tmp; if (s == t && do_include_target_window == False) { /* ignore the target window */ s = s->stack_next; continue; } tmp = s->stack_next; if (IS_IN_TRANSIENT_SUBTREE(s)) { remove_window_from_stack_ring(s); add_window_to_stack_ring_after( s, list_head->stack_prev); count++; count += get_visible_icon_window_count(t); } s = tmp; } return count; } static Bool is_above_unmanaged(FvwmWindow *fw, Window *umtop) { /* Chase through the entire stack of the server's windows looking for any unmanaged window that's higher than the target. Called from raise_over_unmanaged and is_on_top_of_layer. */ Bool ontop = True; Window junk; Window *tops; int i; unsigned int num; Window OR_Above = None; XWindowAttributes wa; if (fw->Desk != Scr.CurrentDesk) { return True; } if (!XQueryTree(dpy, Scr.Root, &junk, &junk, &tops, &num)) { return ontop; } /* * Locate the highest override_redirect window above our target, and * the highest of our windows below it. */ for (i = 0; i < num && tops[i] != FW_W_FRAME(fw); i++) { /* look for target window in list */ } for (; i < num; i++) { /* It might be just as well (and quicker) just to check for the * absence of an FvwmContext instead of for * override_redirect... */ if (!XGetWindowAttributes(dpy, tops[i], &wa)) { continue; } /* Don't forget to ignore the hidden frame resizing windows... */ if (wa.override_redirect == True && wa.class != InputOnly && tops[i] != Scr.NoFocusWin && (!is_frame_hide_window(tops[i]))) { OR_Above = tops[i]; } } /* end for */ if (OR_Above) { *umtop = OR_Above; ontop = False; } XFree (tops); return ontop; } static Bool is_on_top_of_layer_ignore_rom(FvwmWindow *fw) { FvwmWindow *t; Bool ontop = True; if (IS_SCHEDULED_FOR_DESTROY(fw)) { /* stack ring members are no longer valid */ return False; } if (DO_RAISE_TRANSIENT(fw)) { mark_transient_subtree(fw, fw->layer, MARK_RAISE, True, False); } for (t = fw->stack_prev; t != &Scr.FvwmRoot; t = t->stack_prev) { if (t->layer > fw->layer) { break; } if (t->Desk != fw->Desk) { continue; } /* For RaiseOverUnmanaged we can not determine if the window is * on top by checking if the window overlaps another one. If * it was below unmanaged windows, but on top of its layer, it * would be considered on top. */ if (Scr.bo.do_raise_over_unmanaged || overlap(fw, t)) { if (!DO_RAISE_TRANSIENT(fw) || (!IS_IN_TRANSIENT_SUBTREE(t) && t != fw)) { ontop = False; break; } } } return ontop; } static Bool __is_on_top_of_layer(FvwmWindow *fw, Bool client_entered) { Window junk; Bool ontop = False; if (Scr.bo.do_raise_over_unmanaged) { #define EXPERIMENTAL_ROU_HANDLING #ifdef EXPERIMENTAL_ROU_HANDLING /* RBW - 2002/08/15 - RaiseOverUnmanaged adds some overhead. The only way to let our caller know for sure whether we need to grab the mouse buttons because we may need to raise this window is to query the server's tree and look for any override_redirect windows above this one. But this function is called far too often to do this every time. Only if the window is at the top of the FvwmWindow stack do we need more information from the server; and then only at the last moment in HandleEnterNotify when we really need to know whether a raise will be needed if the user clicks in the client window. is_on_top_of_layer_and_above_unmanaged is called in that case. */ if (is_on_top_of_layer_ignore_rom(fw)) { if (client_entered) /* FIXME! - perhaps we should only do if MFCR */ { #ifdef ROUDEBUG printf("RBW-iotol - %8.8lx is on top," " checking server tree. ***\n", FW_W_CLIENT(fw)); #endif ontop = is_above_unmanaged(fw, &junk); #ifdef ROUDEBUG printf(" returning %d\n", (int) ontop); #endif } else { #ifdef ROUDEBUG printf("RBW-iotol - %8.8lx is on top," " *** NOT checking server tree.\n", FW_W_CLIENT(fw)); #endif ontop = True; } return ontop; } else { return False; } #else return False; /* Old pre-2002/08/22 handling. */ #endif } else { return is_on_top_of_layer_ignore_rom(fw); } } /* ---------------------------- interface functions ------------------------ */ /* Remove a window from the stack ring */ void remove_window_from_stack_ring(FvwmWindow *t) { if (IS_SCHEDULED_FOR_DESTROY(t)) { return; } t->stack_prev->stack_next = t->stack_next; t->stack_next->stack_prev = t->stack_prev; /* not really necessary, but gives a little more saftey */ t->stack_prev = NULL; t->stack_next = NULL; return; } /* Add window t to the stack ring after window t */ void add_window_to_stack_ring_after(FvwmWindow *t, FvwmWindow *add_after_win) { if (IS_SCHEDULED_FOR_DESTROY(t)) { return; } if (t == add_after_win || t == add_after_win->stack_next) { /* tried to add the window before or after itself */ fvwm_msg( ERR, "add_window_to_stack_ring_after", "BUG: tried to add window '%s' %s itself in stack" " ring\n", t->name.name, (t == add_after_win) ? "after" : "before"); return; } t->stack_next = add_after_win->stack_next; add_after_win->stack_next->stack_prev = t; t->stack_prev = add_after_win; add_after_win->stack_next = t; return; } FvwmWindow *get_next_window_in_stack_ring(const FvwmWindow *t) { return t->stack_next; } FvwmWindow *get_prev_window_in_stack_ring(const FvwmWindow *t) { return t->stack_prev; } FvwmWindow *get_transientfor_fvwmwindow(const FvwmWindow *t) { FvwmWindow *s; if (!t || !IS_TRANSIENT(t) || FW_W_TRANSIENTFOR(t) == Scr.Root || FW_W_TRANSIENTFOR(t) == None) { return NULL; } for (s = Scr.FvwmRoot.next; s != NULL; s = s->next) { if (FW_W(s) == FW_W_TRANSIENTFOR(t)) { return (s == t) ? NULL : s; } } return NULL; } /* Takes a window from the top of the stack ring and puts it at the appropriate * place. Called when new windows are created. */ Bool position_new_window_in_stack_ring(FvwmWindow *t, Bool do_lower) { if (t->stack_prev != &Scr.FvwmRoot) { /* Not at top of stack ring, so it is already in place. * add_window.c relies on this. */ return False; } /* RaiseWindow/LowerWindow will put the window in its layer */ raise_or_lower_window( t, (do_lower) ? SM_LOWER : SM_RAISE, False, True, False); return True; } /* Raise t and its transients to the top of its layer. For the pager to work * properly it is necessary that RaiseWindow *always* sends a proper M_RESTACK * packet, even if the stacking order didn't change. */ void RaiseWindow(FvwmWindow *t, Bool is_client_request) { BroadcastPacket( M_RAISE_WINDOW, 3, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t); raise_or_lower_window(t, SM_RAISE, True, False, is_client_request); focus_grab_buttons_on_layer(t->layer); #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return; } void LowerWindow(FvwmWindow *t, Bool is_client_request) { BroadcastPacket( M_LOWER_WINDOW, 3, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t); raise_or_lower_window(t, SM_LOWER, True, False, is_client_request); focus_grab_buttons_on_layer(t->layer); #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return; } void RestackWindow(FvwmWindow *t, Bool is_client_request) { raise_or_lower_window(t, SM_RESTACK, True, False, is_client_request); focus_grab_buttons_on_layer(t->layer); #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return; } /* return true if stacking order changed */ Bool HandleUnusualStackmodes( unsigned int stack_mode, FvwmWindow *r, Window rw, FvwmWindow *s, Window sw) { int do_restack = 0; FvwmWindow *t; /* DBUG("HandleUnusualStackmodes", "called with %d, %lx\n", stack_mode, s);*/ if ( ((rw != FW_W(r)) ^ IS_ICONIFIED(r)) || (s && (((sw != FW_W(s)) ^ IS_ICONIFIED(s)) || (r->Desk != s->Desk)))) { /* one of the relevant windows is unmapped */ return 0; } switch (stack_mode) { case TopIf: for ( t = r->stack_prev; t != &Scr.FvwmRoot && !do_restack; t = t->stack_prev) { do_restack = ((s == NULL || s == t) && overlap(t, r)); } if (do_restack) { RaiseWindow (r, True); } break; case BottomIf: for ( t = r->stack_next; t != &Scr.FvwmRoot && !do_restack; t = t->stack_next) { do_restack = ((s == NULL || s == t) && overlap(t, r)); } if (do_restack) { LowerWindow (r, True); } break; case Opposite: do_restack = ( HandleUnusualStackmodes(TopIf, r, rw, s, sw) || HandleUnusualStackmodes(BottomIf, r, rw, s, sw)); break; } /* DBUG("HandleUnusualStackmodes", "\t---> %d\n", do_restack);*/ #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return do_restack; } /* RBW - 01/07/1998 - this is here temporarily - I mean to move it to libfvwm eventually, along with some other chain manipulation functions. */ void BroadcastRestackAllWindows(void) { BroadcastRestack(Scr.FvwmRoot.stack_next, Scr.FvwmRoot.stack_prev); return; } /* send RESTACK packets for t, t->stack_prev and t->stack_next */ void BroadcastRestackThisWindow(FvwmWindow *t) { BroadcastRestack(t->stack_prev, t->stack_next); return; } /* returns 0 if s and t are on the same layer, <1 if t is on a lower layer and * >1 if t is on a higher layer. */ int compare_window_layers(FvwmWindow *t, FvwmWindow *s) { return t->layer - s->layer; } void set_default_layer(FvwmWindow *t, int layer) { t->default_layer = layer; return; } void set_layer(FvwmWindow *t, int layer) { t->layer = layer; return; } int get_layer(FvwmWindow *t) { return t->layer; } /* This function recursively finds the transients of the window t and sets their * is_in_transient_subtree flag. If a layer is given, only windows in this * layer are checked. If the layer is < 0, all windows are considered. */ void mark_transient_subtree( FvwmWindow *t, int layer, int mark_mode, Bool do_ignore_icons, Bool use_window_group_hint) { FvwmWindow *s; FvwmWindow *start; FvwmWindow *end; Bool is_finished; if (layer >= 0 && t->layer != layer) { return; } /* find out on which windows to operate */ if (layer >= 0) { /* only work on the given layer */ start = &Scr.FvwmRoot; end = &Scr.FvwmRoot; for ( s = Scr.FvwmRoot.stack_next; s != &Scr.FvwmRoot && s->layer >= layer; s = s->stack_next) { if (s == t) { /* ignore the target window */ continue; } if (s->layer == layer) { if (start == &Scr.FvwmRoot) { start = s; } end = s->stack_next; } } } else { /* work on complete window list */ start = Scr.FvwmRoot.stack_next; end = &Scr.FvwmRoot; } /* clean the temporary flag in all windows and precalculate the * transient frame windows */ if (Scr.FvwmRoot.scratch.i == 0) { for ( s = Scr.FvwmRoot.stack_next; s != &Scr.FvwmRoot; s = s->stack_next) { SET_IN_TRANSIENT_SUBTREE(s, 0); if ( IS_TRANSIENT(s) && (layer < 0 || layer == s->layer)) { s->scratch.p = get_transientfor_fvwmwindow(s); } else { s->scratch.p = NULL; } } } Scr.FvwmRoot.scratch.i = 0; /* now loop over the windows and mark the ones we need to move */ SET_IN_TRANSIENT_SUBTREE(t, 1); is_finished = False; while (!is_finished) { /* recursively search for all transient windows */ is_finished = True; for (s = start; s != end; s = s->stack_next) { if ( __mark_transient_subtree_test( s, start, end, mark_mode, do_ignore_icons, use_window_group_hint)) { is_finished = False; } } /* for */ } /* while */ return; } void new_layer(FvwmWindow *fw, int layer) { FvwmWindow *s; FvwmWindow *target; FvwmWindow *prev; FvwmWindow list_head; int add_after_layer; int count; int old_layer; Bool do_lower; if (layer < 0) { layer = 0; } fw = get_transientfor_top_fvwmwindow(fw); if (layer == fw->layer) { return; } old_layer = fw->layer; list_head.stack_next = &list_head; list_head.stack_prev = &list_head; count = collect_transients_recursive( fw, &list_head, fw->layer, (layer < fw->layer) ? SM_LOWER : SM_RAISE, True); if (count == 0) { /* no windows to move */ return; } add_after_layer = layer; if (layer < fw->layer) { /* lower below the windows in the new (lower) layer */ add_after_layer = layer; do_lower = True; } else { /* raise above the windows in the new (higher) layer */ add_after_layer = layer + 1; do_lower = False; } /* find the place to insert the windows */ for ( target = Scr.FvwmRoot.stack_next; target != &Scr.FvwmRoot; target = target->stack_next) { if (target->layer < add_after_layer) { /* add all windows before the current window */ break; } } /* insert windows at new position */ add_windowlist_to_stack_ring_after(&list_head, target->stack_prev); prev = NULL; for ( s = list_head.stack_next; prev != list_head.stack_prev; prev = s, s = s->stack_next) { s->layer = layer; /* redraw title and buttons to update layer buttons */ border_draw_decorations( s, PART_TITLEBAR, (Scr.Hilite == fw), True, CLEAR_NONE, NULL, NULL); EWMH_SetWMState(fw, False); } /* move the windows without modifying their stacking order */ __restack_window_list( list_head.stack_next->stack_prev, target, count, (count > 1), do_lower); focus_grab_buttons_on_layer(layer); focus_grab_buttons_on_layer(old_layer); return; } /* RBW - 11/13/1998 - 2 new fields to init - stacking order chain. */ void init_stack_and_layers(void) { Scr.BottomLayer = DEFAULT_BOTTOM_LAYER; Scr.DefaultLayer = DEFAULT_DEFAULT_LAYER; Scr.TopLayer = DEFAULT_TOP_LAYER; Scr.FvwmRoot.stack_next = &Scr.FvwmRoot; Scr.FvwmRoot.stack_prev = &Scr.FvwmRoot; set_layer(&Scr.FvwmRoot, DEFAULT_ROOT_WINDOW_LAYER); return; } Bool is_on_top_of_layer(FvwmWindow *fw) { return __is_on_top_of_layer(fw, False); } Bool is_on_top_of_layer_and_above_unmanaged(FvwmWindow *fw) { return __is_on_top_of_layer(fw, True); } /* ----------------------------- built in functions ----------------------- */ void CMD_Raise(F_CMD_ARGS) { RaiseWindow(exc->w.fw, False); return; } void CMD_Lower(F_CMD_ARGS) { LowerWindow(exc->w.fw, False); return; } void CMD_RestackTransients(F_CMD_ARGS) { RestackWindow(exc->w.fw, False); return; } void CMD_RaiseLower(F_CMD_ARGS) { Bool ontop; FvwmWindow * const fw = exc->w.fw; ontop = is_on_top_of_layer_ignore_rom(fw); if (ontop) { LowerWindow(fw, False); } else { RaiseWindow(fw, False); } return; } void CMD_Layer(F_CMD_ARGS) { int n, layer, val[2]; char *token; FvwmWindow * const fw = exc->w.fw; if (fw == NULL) { return; } token = PeekToken(action, NULL); if (StrEquals("default", token)) { layer = fw->default_layer; } else { n = GetIntegerArguments(action, NULL, val, 2); layer = fw->layer; if ((n == 1) || ((n == 2) && (val[0] != 0))) { layer += val[0]; } else if ((n == 2) && (val[1] >= 0)) { layer = val[1]; } else { layer = fw->default_layer; } } if (layer < 0) { layer = 0; } new_layer(fw, layer); #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return; } void CMD_DefaultLayers(F_CMD_ARGS) { char *bot = NULL; char *def = NULL; char *top = NULL; int i; bot = PeekToken(action, &action); if (bot) { i = atoi (bot); if (i < 0) { fvwm_msg( ERR, "DefaultLayers", "Layer must be non-negative." ); } else { Scr.BottomLayer = i; } } def = PeekToken(action, &action); if (def) { i = atoi (def); if (i < 0) { fvwm_msg( ERR, "DefaultLayers", "Layer must be non-negative." ); } else { Scr.DefaultLayer = i; } } top = PeekToken(action, &action); if (top) { i = atoi (top); if (i < 0) { fvwm_msg( ERR, "DefaultLayers", "Layer must be non-negative." ); } else { Scr.TopLayer = i; } } #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif return; } fvwm-2.6.7/fvwm/modconf.h0000644000175700017570000000015612773467231012237 00000000000000/* -*-c-*- */ #ifndef MODCONF_H #define MODCONF_H void ModuleConfig(char *action); #endif /* MODCONF_H */ fvwm-2.6.7/fvwm/module_interface.c0000644000175700017570000005354313001406607014103 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* * * code for talking with fvwm modules. * */ #include "config.h" #include #include #include #include "libs/ftime.h" #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/ColorUtils.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/wild.h" #include "fvwm.h" #include "externs.h" #include "functions.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "module_interface.h" #include "module_list.h" #include "events.h" #include "geometry.h" #include "libs/fvwmsignal.h" #include "decorations.h" #include "commands.h" /* A queue of commands from the modules */ static fqueue cqueue = FQUEUE_INIT; static const unsigned long dummy = 0; static unsigned long * make_vpacket(unsigned long *body, unsigned long event_type, unsigned long num, va_list ap) { unsigned long *bp = body; /* truncate long packets */ if (num > FvwmPacketMaxSize) { num = FvwmPacketMaxSize; } *(bp++) = START_FLAG; *(bp++) = event_type; *(bp++) = num+FvwmPacketHeaderSize; *(bp++) = fev_get_evtime(); for (; num > 0; --num) { *(bp++) = va_arg(ap, unsigned long); } return body; } /* RBW - 04/16/1999 - new packet builder for GSFR -- Arguments are pairs of lengths and argument data pointers. RBW - 05/01/2000 - A length of zero means that an int is being passed which must be stored in the packet as an unsigned long. This is a special hack to accommodate the old CONFIGARGS technique of sending the args for the M_CONFIGURE_WINDOW packet. */ static unsigned long make_new_vpacket(unsigned char *body, unsigned long event_type, unsigned long num, va_list ap) { long arglen; unsigned long addlen; unsigned long bodylen = 0; unsigned long *bp = (unsigned long *)body; unsigned long *bp1 = bp; unsigned long plen = 0; *(bp++) = START_FLAG; *(bp++) = event_type; /* Skip length field, we don't know it yet. */ bp++; *(bp++) = fev_get_evtime(); for (; num > 0; --num) { arglen = va_arg(ap, long); if (arglen <= 0) { if (arglen == 0) { arglen = -sizeof(int); } addlen = sizeof(unsigned long); } else { addlen = arglen; } bodylen += addlen; if (bodylen >= FvwmPacketMaxSize_byte) { fvwm_msg( ERR, "make_new_vpacket", "packet too long %ld %ld", (long)bodylen, (long)FvwmPacketMaxSize_byte); break; } if (arglen > 0) { register char *tmp = (char *)bp; memcpy(tmp, va_arg(ap, char *), arglen); tmp += arglen; bp = (unsigned long *)tmp; } else if (arglen == 0 || arglen == -sizeof(int)) { int *tmp; tmp = va_arg(ap, int *); *bp = (unsigned long) *tmp; bp++; } else if (arglen == -sizeof(long)) { unsigned long *tmp; tmp = va_arg(ap, unsigned long *); *bp = (unsigned long) *tmp; bp++; } else if (arglen == -sizeof(short)) { short *tmp; tmp = va_arg(ap, short *); *bp = (unsigned long) *tmp; bp++; } else { fvwm_msg( ERR, "make_new_vpacket", "can not handle arglen %ld, please contact" " fvwm-workers@fvwm.org. aborting...", arglen); abort(); } } /* Round up to a long word boundary. Most of the module interface still thinks in terms of an array of longss, so let's humor it. */ plen = (unsigned long) ((char *)bp - (char *)bp1); plen = ((plen + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long); *(((unsigned long*)bp1)+2) = (plen / (sizeof(unsigned long))); return plen; } void SendPacket( fmodule *module, unsigned long event_type, unsigned long num_datum, ...) { unsigned long body[FvwmPacketMaxSize]; va_list ap; va_start(ap, num_datum); make_vpacket(body, event_type, num_datum, ap); va_end(ap); PositiveWrite( module, body, (num_datum+FvwmPacketHeaderSize)*sizeof(body[0])); return; } void BroadcastPacket(unsigned long event_type, unsigned long num_datum, ...) { unsigned long body[FvwmPacketMaxSize]; va_list ap; fmodule_list_itr moditr; fmodule *module; va_start(ap,num_datum); make_vpacket(body, event_type, num_datum, ap); va_end(ap); module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { PositiveWrite( module, body, (num_datum+FvwmPacketHeaderSize)*sizeof(body[0])); } return; } /* RBW - 04/16/1999 - new style packet senders for GSFR -- */ static void SendNewPacket( fmodule *module, unsigned long event_type, unsigned long num_datum, ...) { unsigned char body[FvwmPacketMaxSize_byte]; va_list ap; unsigned long plen; va_start(ap,num_datum); plen = make_new_vpacket(body, event_type, num_datum, ap); va_end(ap); PositiveWrite(module, (void *) &body, plen); return; } static void BroadcastNewPacket(unsigned long event_type, unsigned long num_datum, ...) { unsigned char body[FvwmPacketMaxSize_byte]; va_list ap; fmodule_list_itr moditr; fmodule *module; unsigned long plen; va_start(ap,num_datum); plen = make_new_vpacket(body, event_type, num_datum, ap); va_end(ap); module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { PositiveWrite(module, (void *) &body, plen); } return; } action_flags *__get_allowed_actions(const FvwmWindow *fw) { static action_flags act; act.is_movable = is_function_allowed( F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False); act.is_deletable = is_function_allowed( F_DELETE, NULL, fw, RQORIG_PROGRAM_US, False); act.is_destroyable = is_function_allowed( F_DESTROY, NULL, fw, RQORIG_PROGRAM_US, False); act.is_closable = is_function_allowed( F_CLOSE, NULL, fw, RQORIG_PROGRAM_US, False); act.is_maximizable = is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False); act.is_resizable = is_function_allowed( F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, False); act.is_iconifiable = is_function_allowed( F_ICONIFY, NULL, fw, RQORIG_PROGRAM_US, False); return &act; } /* RBW - 04/16/1999 - new version for GSFR -- - args are now pairs: - length of arg data - pointer to arg data - number of arguments is the number of length/pointer pairs. - the 9th field, where flags used to be, is temporarily left as a dummy to preserve alignment of the other fields in the old packet: we should drop this before the next release. */ #define CONFIGARGS(_fw) 33, \ (unsigned long)(-sizeof(Window)), \ &FW_W(*(_fw)), \ (unsigned long)(-sizeof(Window)), \ &FW_W_FRAME(*(_fw)), \ (unsigned long)(-sizeof(void *)), \ &(_fw), \ (unsigned long)(0), \ &(*(_fw))->g.frame.x, \ (unsigned long)(0), \ &(*(_fw))->g.frame.y, \ (unsigned long)(0), \ &(*(_fw))->g.frame.width, \ (unsigned long)(0), \ &(*(_fw))->g.frame.height, \ (unsigned long)(0), \ &(*(_fw))->Desk, \ (unsigned long)(0), \ &(*(_fw))->layer, \ (unsigned long)(0), \ &(*(_fw))->hints.base_width, \ (unsigned long)(0), \ &(*(_fw))->hints.base_height, \ (unsigned long)(0), \ &(*(_fw))->hints.width_inc, \ (unsigned long)(0), \ &(*(_fw))->hints.height_inc, \ (unsigned long)(0), \ &(*(_fw))->orig_hints.width_inc, \ (unsigned long)(0), \ &(*(_fw))->orig_hints.height_inc, \ (unsigned long)(0), \ &(*(_fw))->hints.min_width, \ (unsigned long)(0), \ &(*(_fw))->hints.min_height, \ (unsigned long)(0), \ &(*(_fw))->hints.max_width, \ (unsigned long)(0), \ &(*(_fw))->hints.max_height, \ (unsigned long)(-sizeof(Window)), \ &FW_W_ICON_TITLE(*(_fw)), \ (unsigned long)(-sizeof(Window)), \ &FW_W_ICON_PIXMAP(*(_fw)), \ (unsigned long)(0), \ &(*(_fw))->hints.win_gravity, \ (unsigned long)(-sizeof(Pixel)), \ &(*(_fw))->colors.fore, \ (unsigned long)(-sizeof(Pixel)), \ &(*(_fw))->colors.back, \ (unsigned long)(0), \ &(*(_fw))->ewmh_hint_layer, \ (unsigned long)(sizeof(unsigned long)), \ &(*(_fw))->ewmh_hint_desktop, \ (unsigned long)(0), \ &(*(_fw))->ewmh_window_type, \ (unsigned long)(sizeof(short)), \ &(*(_fw))->title_thickness, \ (unsigned long)(sizeof(short)), \ &(*(_fw))->boundary_width, \ (unsigned long)(sizeof(short)), \ &dummy, \ (unsigned long)(sizeof(short)), \ &dummy, \ (unsigned long)(sizeof((*(_fw))->flags)), \ &(*(_fw))->flags, \ (unsigned long)(sizeof(action_flags)), \ __get_allowed_actions((*(_fw))) void SendConfig(fmodule *module, unsigned long event_type, const FvwmWindow *t) { const FvwmWindow **t1 = &t; /* RBW- SendPacket(module, event_type, CONFIGARGS(t)); */ SendNewPacket(module, event_type, CONFIGARGS(t1)); return; } void BroadcastConfig(unsigned long event_type, const FvwmWindow *t) { const FvwmWindow **t1 = &t; /* RBW- BroadcastPacket(event_type, CONFIGARGS(t)); */ BroadcastNewPacket(event_type, CONFIGARGS(t1)); return; } static unsigned long *make_named_packet( int *len, unsigned long event_type, const char *name, int num, ...) { unsigned long *body; va_list ap; /* Packet is the header plus the items plus enough items to hold the * name string. */ *len = FvwmPacketHeaderSize + num + (strlen(name) / sizeof(unsigned long)) + 1; /* truncate long packets */ if (*len > FvwmPacketMaxSize) { *len = FvwmPacketMaxSize; } body = (unsigned long *)safemalloc(*len * sizeof(unsigned long)); /* Zero out end of memory to avoid uninit memory access. */ body[*len-1] = 0; va_start(ap, num); make_vpacket(body, event_type, num, ap); va_end(ap); strncpy((char *)&body[FvwmPacketHeaderSize+num], name, (*len - FvwmPacketHeaderSize - num)*sizeof(unsigned long) - 1); body[2] = *len; return (body); } void SendName( fmodule *module, unsigned long event_type, unsigned long data1,unsigned long data2, unsigned long data3, const char *name) { unsigned long *body; int l; if (name == NULL) { return; } body = make_named_packet(&l, event_type, name, 3, data1, data2, data3); PositiveWrite(module, body, l*sizeof(unsigned long)); free(body); return; } void BroadcastName( unsigned long event_type, unsigned long data1, unsigned long data2, unsigned long data3, const char *name) { unsigned long *body; int l; fmodule_list_itr moditr; fmodule *module; if (name == NULL) { return; } body = make_named_packet(&l, event_type, name, 3, data1, data2, data3); module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { PositiveWrite(module, body, l*sizeof(unsigned long)); } free(body); return; } void BroadcastWindowIconNames(FvwmWindow *fw, Bool window, Bool icon) { if (window) { BroadcastName( M_WINDOW_NAME, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, fw->name.name); BroadcastName( M_VISIBLE_NAME, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, fw->visible_name); } if (icon) { BroadcastName( M_ICON_NAME, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, fw->icon_name.name); BroadcastName( MX_VISIBLE_ICON_NAME, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, fw->visible_icon_name); } return; } void SendFvwmPicture( fmodule *module, unsigned long event_type, unsigned long data1, unsigned long data2, unsigned long data3, FvwmPicture *picture, char *name) { unsigned long *body; unsigned long data4 = 0, data5 = 0, data6 = 0, data7 = 0, data8 = 0, data9 = 0; int l; if (!FMiniIconsSupported) { return; } if ((name == NULL) || (event_type != M_MINI_ICON)) { return; } if (picture != NULL) { data4 = picture->width; data5 = picture->height; data6 = picture->depth; data7 = picture->picture; data8 = picture->mask; data9 = picture->alpha; } body = make_named_packet( &l, event_type, name, 9, data1, data2, data3, data4, data5, data6, data7, data8, data9); PositiveWrite(module, body, l*sizeof(unsigned long)); free(body); return; } void BroadcastFvwmPicture( unsigned long event_type, unsigned long data1, unsigned long data2, unsigned long data3, FvwmPicture *picture, char *name) { unsigned long *body; unsigned long data4, data5, data6, data7, data8, data9; int l; fmodule_list_itr moditr; fmodule *module; if (!FMiniIconsSupported) { return; } if (picture != NULL) { data4 = picture->width; data5 = picture->height; data6 = picture->depth; data7 = picture->picture; data8 = picture->mask; data9 = picture->alpha; } else { data4 = 0; data5 = 0; data6 = 0; data7 = 0; data8 = 0; data9 = 0; } body = make_named_packet( &l, event_type, name, 9, data1, data2, data3, data4, data5, data6, data7, data8, data9); module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { PositiveWrite(module, body, l*sizeof(unsigned long)); } free(body); return; } /* * Reads a colorset command from a module and broadcasts it back out */ void BroadcastColorset(int n) { fmodule_list_itr moditr; fmodule *module; char *buf; buf = DumpColorset(n, &Colorset[n]); module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { SendName(module, M_CONFIG_INFO, 0, 0, 0, buf); } return; } /* * Broadcasts a string to all modules as M_CONFIG_INFO. */ void BroadcastPropertyChange( unsigned long argument, unsigned long data1, unsigned long data2, char *string) { fmodule_list_itr moditr; fmodule *module; module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { SendName(module, MX_PROPERTY_CHANGE, argument, data1, data2, string); } return; } /* * Broadcasts a string to all modules as M_CONFIG_INFO. */ void BroadcastConfigInfoString(char *string) { fmodule_list_itr moditr; fmodule *module; module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { SendName(module, M_CONFIG_INFO, 0, 0, 0, string); } return; } /* * Broadcasts the state of Xinerama support to all modules as M_CONFIG_INFO. */ void broadcast_xinerama_state(void) { BroadcastConfigInfoString((char *)FScreenGetConfiguration()); return; } /* * Broadcasts the ignored modifiers to all modules as M_CONFIG_INFO. */ void broadcast_ignore_modifiers(void) { char msg[32]; sprintf(msg, "IgnoreModifiers %d", GetUnusedModifiers()); BroadcastConfigInfoString(msg); return; } /* run the input command as if it cames from a button press or release */ void module_input_execute(struct fmodule_input *input) { XEvent e; const exec_context_t *exc; exec_context_changes_t ecc; int flags; memset(&e, 0, sizeof(e)); if (XFindContext(dpy, input->window, FvwmContext, (caddr_t *)&ecc.w.fw) == XCNOENT) { ecc.w.fw = NULL; input->window = None; } /* Query the pointer, the pager-drag-out feature doesn't work properly. * This is OK now that the Pager uses "Move pointer" * A real fix would be for the modules to pass the button press coords */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX,&JunkY, &e.xbutton.x_root, &e.xbutton.y_root, &e.xbutton.state) == False) { /* pointer is not on this screen */ /* If a module does XUngrabPointer(), it can now get proper * Popups */ e.xbutton.window = Scr.Root; ecc.w.fw = NULL; } else { e.xbutton.window = input->window; } e.xbutton.subwindow = None; e.xbutton.button = 1; /* If a module does XUngrabPointer(), it can now get proper Popups */ if (StrEquals(input->command, "popup")) { e.xbutton.type = ButtonPress; e.xbutton.state |= Button1Mask; } else { e.xbutton.type = ButtonRelease; e.xbutton.state &= (~(Button1Mask)); } e.xbutton.x = 0; e.xbutton.y = 0; fev_fake_event(&e); ecc.type = EXCT_MODULE; ecc.w.w = input->window; flags = (input->window == None) ? 0 : FUNC_DONT_DEFER; ecc.w.wcontext = GetContext(NULL, ecc.w.fw, &e, &(input->window)); ecc.x.etrigger = &e; ecc.m.module = input->module; exc = exc_create_context( &ecc, ECC_TYPE | ECC_ETRIGGER | ECC_FW | ECC_W | ECC_WCONTEXT | ECC_MODULE); execute_function(NULL, exc, input->command, flags); exc_destroy_context(exc); module_input_discard(input); return; } /* enqueue a module command on the command queue to be executed later */ void module_input_enqueue(struct fmodule_input *input) { if (input == NULL) { return; } DBUG("module_input_enqueue", input->command); fqueue_add_at_end(&cqueue, (void*)input); } /* * * Procedure: * ExecuteCommandQueue - runs command from the module command queue * This may be called recursively if a module command runs a function * that does a Wait, so it must be re-entrant * */ void ExecuteCommandQueue(void) { fmodule_input *input; while (fqueue_get_first(&cqueue, (void **)&input) == 1) { /* remove from queue */ fqueue_remove_or_operate_from_front( &cqueue, NULL, NULL, NULL, NULL); /* execute and destroy */ if (input->command) { DBUG("ExecuteCommandQueue", input->command); module_input_execute(input); } else { module_input_discard(input); } } return; } /* ** send an arbitrary string to all instances of a module */ void CMD_SendToModule(F_CMD_ARGS) { char *name,*str; unsigned long data0, data1, data2; fmodule_list_itr moditr; fmodule *module; FvwmWindow * const fw = exc->w.fw; /* FIXME: Without this, popup menus can't be implemented properly in * modules. Olivier: Why ? */ /* UngrabEm(); */ if (!action) { return; } str = GetNextToken(action, &name); if (!name) { return; } if (fw) { /* Modules may need to know which window this applies to */ data0 = FW_W(fw); data1 = FW_W_FRAME(fw); data2 = (unsigned long)fw; } else { data0 = 0; data1 = 0; data2 = 0; } module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { if ( (MOD_NAME(module) != NULL && matchWildcards(name,MOD_NAME(module))) || (MOD_ALIAS(module) && matchWildcards(name, MOD_ALIAS(module)))) { SendName(module,M_STRING,data0,data1,data2,str); FlushMessageQueue(module); } } free(name); return; } /* ** send an arbitrary string back to the calling module */ void CMD_Send_Reply(F_CMD_ARGS) { unsigned long data0, data1, data2; fmodule *module = exc->m.module; FvwmWindow * const fw = exc->w.fw; if (module == NULL) { return; } if (!action) { return; } if (fw) { /* Modules may need to know which window this applies to */ data0 = FW_W(fw); data1 = FW_W_FRAME(fw); data2 = (unsigned long)fw; } else { data0 = 0; data1 = 0; data2 = 0; } SendName(module, MX_REPLY, data0, data1, data2, action); FlushMessageQueue(module); return; } void CMD_Send_WindowList(F_CMD_ARGS) { FvwmWindow *t; fmodule *mod = exc->m.module; if (mod == NULL) { return; } SendPacket(mod, M_NEW_DESK, 1, (long)Scr.CurrentDesk); SendPacket( mod, M_NEW_PAGE, 7, (long)Scr.Vx, (long)Scr.Vy, (long)Scr.CurrentDesk, (long)Scr.MyDisplayWidth, (long)Scr.MyDisplayHeight, (long)((Scr.VxMax / Scr.MyDisplayWidth) + 1), (long)((Scr.VyMax / Scr.MyDisplayHeight) + 1)); if (Scr.Hilite != NULL) { SendPacket( mod, M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), (long)FW_W_FRAME(Scr.Hilite), (unsigned long)True, (long)Scr.Hilite->hicolors.fore, (long)Scr.Hilite->hicolors.back); } else { SendPacket( mod, M_FOCUS_CHANGE, 5, 0, 0, (unsigned long)True, (long)GetColor(DEFAULT_FORE_COLOR), (long)GetColor(DEFAULT_BACK_COLOR)); } if (Scr.DefaultIcon != NULL) { SendName(mod, M_DEFAULTICON, 0, 0, 0, Scr.DefaultIcon); } for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { SendConfig(mod,M_CONFIGURE_WINDOW,t); SendName( mod, M_WINDOW_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->name.name); SendName( mod, M_ICON_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->icon_name.name); SendName( mod, M_VISIBLE_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->visible_name); SendName( mod, MX_VISIBLE_ICON_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t,t->visible_icon_name); if (t->icon_bitmap_file != NULL && t->icon_bitmap_file != Scr.DefaultIcon) { SendName( mod, M_ICON_FILE, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->icon_bitmap_file); } SendName( mod, M_RES_CLASS, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->class.res_class); SendName( mod, M_RES_NAME, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->class.res_name); if (IS_ICONIFIED(t) && !IS_ICON_UNMAPPED(t)) { rectangle r; Bool rc; rc = get_visible_icon_geometry(t, &r); if (rc == True) { SendPacket( mod, M_ICONIFY, 7, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t, (long)r.x, (long)r.y, (long)r.width, (long)r.height); } } if ((IS_ICONIFIED(t))&&(IS_ICON_UNMAPPED(t))) { SendPacket( mod, M_ICONIFY, 7, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t, (long)0, (long)0, (long)0, (long)0); } if (FMiniIconsSupported && t->mini_icon != NULL) { SendFvwmPicture( mod, M_MINI_ICON, FW_W(t), FW_W_FRAME(t), (unsigned long)t, t->mini_icon, t->mini_pixmap_file); } } if (Scr.Hilite == NULL) { BroadcastPacket( M_FOCUS_CHANGE, 5, (long)0, (long)0, (unsigned long)True, (long)GetColor(DEFAULT_FORE_COLOR), (long)GetColor(DEFAULT_BACK_COLOR)); } else { BroadcastPacket( M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), (long)FW_W(Scr.Hilite), (unsigned long)True, (long)Scr.Hilite->hicolors.fore, (long)Scr.Hilite->hicolors.back); } SendPacket(mod, M_END_WINDOWLIST, 0); return; } fvwm-2.6.7/fvwm/schedule.h0000644000175700017570000000030412773467231012401 00000000000000/* -*-c-*- */ #ifndef SCHEDULE_H #define SCHEDULE_H void squeue_execute(void); int squeue_get_next_ms(void); int squeue_get_next_id(void); int squeue_get_last_id(void); #endif /* SCHEDULE_H */ fvwm-2.6.7/fvwm/events.h0000644000175700017570000000331712773467231012120 00000000000000/* -*-c-*- */ #ifndef EVENTS_H #define EVENTS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct { Window w; Atom atom; int event_type; int stop_at_event_type; char do_stop_at_event_type; } flush_property_notify_args; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void dispatch_event(XEvent *e); int GetContext(FvwmWindow **ret_fw, FvwmWindow *t, const XEvent *e, Window *w); int My_XNextEvent(Display *dpy, XEvent *event); void flush_accumulate_expose(Window w, XEvent *e); void handle_all_expose(void); Bool StashEventTime(const XEvent *ev); void CoerceEnterNotifyOnCurrentWindow(void); void InitEventHandlerJumpTable(void); void SendConfigureNotify( FvwmWindow *fw, int x, int y, int w, int h, int bw, Bool send_for_frame_too); void WaitForButtonsUp(Bool do_handle_expose); int discard_typed_events(int num_event_types, int *event_types); int flush_property_notify_stop_at_event_type( Atom atom, Window w, char do_stop_at_event_type, int stop_at_event_type); void sync_server(int toggle); Bool is_resizing_event_pending(FvwmWindow *fw); void events_handle_configure_request( XEvent *e, FvwmWindow *fw, Bool force_use_grav, int force_gravity); Bool test_typed_window_event(Display *display, XEvent *event, char *arg); #endif /* EVENTS_H */ fvwm-2.6.7/fvwm/infostore.c0000644000175700017570000001113113001406607012571 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "fvwm.h" #include "externs.h" #include "libs/FGettext.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "infostore.h" #include "misc.h" #include "functions.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ static MetaInfo *mi_store; /* ---------------------------- forward declarations ----------------------- */ static void delete_metainfo(const char *); /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ MetaInfo *new_metainfo(void) { MetaInfo *mi; mi = (MetaInfo *)safemalloc(sizeof(MetaInfo)); memset(mi, '\0', sizeof(MetaInfo)); return mi; } void insert_metainfo(char *key, char *value) { MetaInfo *mi; MetaInfo *mi_new; for (mi = mi_store; mi; mi = mi->next) { if (StrEquals(mi->key, key)) { /* We already have an entry in the list with that key, so * update the value of it only. */ free (mi->value); CopyString(&mi->value, value); return; } } /* It's a new item, add it to the list. */ mi_new = new_metainfo(); mi_new->key = key; CopyString(&mi_new->value, value); mi_new->next = mi_store; mi_store = mi_new; return; } static void delete_metainfo(const char *key) { MetaInfo *mi_current, *mi_prev; mi_prev = NULL; for(mi_current = mi_store; mi_current != NULL; mi_prev = mi_current, mi_current = mi_current->next) { if (StrEquals(mi_current->key, key)) { if (mi_prev == NULL) mi_store = mi_current->next; else mi_prev->next = mi_current->next; free(mi_current->key); free(mi_current->value); free(mi_current); break; } } return; } inline char *get_metainfo_value(const char *key) { MetaInfo *mi_current; for(mi_current = mi_store; mi_current; mi_current = mi_current->next) { if (StrEquals(mi_current->key, key)) return mi_current->value; } return NULL; } int get_metainfo_length(void) { MetaInfo *mi; int count; count = 0; for(mi = mi_store; mi; mi = mi->next) count++; return count; } MetaInfo * get_metainfo(void) { return mi_store; } void print_infostore(void) { MetaInfo *mi; fprintf(stderr, "Current items in infostore (key, value):\n\n"); if (get_metainfo_length() == 0) { fprintf(stderr, "No items are currently stored in the infostore.\n"); return; } for(mi = mi_store; mi; mi = mi->next) { fprintf(stderr, "%s\t%s\n", mi->key, mi->value); } return; } /* ---------------------------- interface functions ------------------------ */ /* ---------------------------- builtin commands --------------------------- */ void CMD_InfoStoreAdd(F_CMD_ARGS) { char *key, *value; char *token; token = PeekToken(action, &action); key = value = NULL; if (token) key = strdup(token); token = PeekToken(action, &action); if (token) value = strdup(token); if (!key || !value) { fvwm_msg(ERR, "CMD_InfoStore", "Bad arguments given."); return; } insert_metainfo(key, value); free(value); return; } void CMD_InfoStoreRemove(F_CMD_ARGS) { char *token; token = PeekToken(action, &action); if (!token) { fvwm_msg(ERR, "CMD_InfoStoreRemove", "No key given to remove item."); return; } delete_metainfo(token); return; } void CMD_InfoStoreClear(F_CMD_ARGS) { MetaInfo *mi; if (get_metainfo_length() == 0) return; for (mi = mi_store; mi; mi = mi->next) delete_metainfo(mi->key); } fvwm-2.6.7/fvwm/expand.h0000644000175700017570000000125412773467231012071 00000000000000/* -*-c-*- */ #ifndef EXPAND_H #define EXPAND_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ char *expand_vars( char *input, char *arguments[], Bool addto, Bool ismod, cond_rc_t *cond_rc, const exec_context_t *exc); #endif /* EXPAND_H */ fvwm-2.6.7/fvwm/add_window.h0000644000175700017570000000532012773467231012727 00000000000000/* -*-c-*- */ #ifndef ADD_WINDOW_H #define ADD_WINDOW_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define AW_NO_WINDOW NULL #define AW_UNMANAGED ((void *)1) /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void setup_visible_name(FvwmWindow *fw, Bool is_icon); void setup_wm_hints(FvwmWindow *fw); void setup_snapping(FvwmWindow *fw, window_style *pstyle); void setup_placement_penalty(FvwmWindow *fw, window_style *pstyle); void setup_focus_policy(FvwmWindow *fw); Bool setup_transientfor(FvwmWindow *fw); void setup_icon_size_limits(FvwmWindow *fw, window_style *pstyle); void setup_icon_background_parameters(FvwmWindow *fw, window_style *pstyle); void setup_icon_title_parameters(FvwmWindow *fw, window_style *pstyle); void setup_numeric_vals(FvwmWindow *fw, window_style *pstyle); Bool validate_transientfor(FvwmWindow *fw); void setup_title_geometry( FvwmWindow *fw, window_style *pstyle); void setup_window_font( FvwmWindow *fw, window_style *pstyle, Bool do_destroy); void setup_icon_font( FvwmWindow *fw, window_style *pstyle, Bool do_destroy); void setup_style_and_decor( FvwmWindow *fw, window_style *pstyle, short *buttons); void setup_frame_attributes( FvwmWindow *fw, window_style *pstyle); void change_auxiliary_windows( FvwmWindow *fw, short buttons); void setup_frame_geometry( FvwmWindow *fw); void setup_frame_size_limits( FvwmWindow *fw, window_style *pstyle); void increase_icon_hint_count( FvwmWindow *fw); void change_icon( FvwmWindow *fw, window_style *pstyle); void change_mini_icon( FvwmWindow *fw, window_style *pstyle); void change_icon_boxes( FvwmWindow *fw, window_style *pstyle); void FetchWmProtocols( FvwmWindow *); FvwmWindow *AddWindow( const char **ret_initial_map_command, const exec_context_t *exc, FvwmWindow *ReuseWin, initial_window_options_t * win_opts); void GetWindowSizeHints( FvwmWindow *fw); void GetWindowSizeHintsWithCheck( FvwmWindow *fw, int do_reject_invalid_size_constrains_on_existing_window); void free_window_names( FvwmWindow *tmp, Bool nukename, Bool nukeicon); void destroy_window( FvwmWindow *); void RestoreWithdrawnLocation( FvwmWindow *tmp, Bool is_restart_or_recapture, Window parent); void Reborder(void); void CaptureAllWindows(const exec_context_t *exc, Bool is_recapture); #endif /* ADD_WINDOW_H */ fvwm-2.6.7/fvwm/style.c0000644000175700017570000042352513001406607011737 00000000000000/* -*-c-*- */ /* 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 */ /* * This module was all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* code for parsing the fvwm style command */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/charmap.h" #include "libs/modifiers.h" #include "libs/ColorUtils.h" #include "libs/Parse.h" #include "libs/wild.h" #include "fvwm.h" #include "execcontext.h" #include "misc.h" #include "screen.h" #include "update.h" #include "style.h" #include "colorset.h" #include "ewmh.h" #include "placement.h" /* ---------------------------- local definitions -------------------------- */ #define SAFEFREE( p ) {if (p) {free(p);(p)=NULL;}} /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* list of window names with attributes */ static window_style *all_styles = NULL; static window_style *last_style_in_list = NULL; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static Bool __validate_titleformat_string(const char *formatstr) { const char *fmt; /* Setting this to "True" here ensures we don't erroneously report on * an invalid TitleFormat string which contains no placeholders * whatsoever. */ Bool ret_condition = True; for (fmt = formatstr; *fmt; fmt++) { if (*fmt != '%') continue; switch (*++fmt) { case 'c': case 'n': case 'r': case 't': case 'i': case 'I': ret_condition = True; break; default: ret_condition = False; break; } } return ret_condition; } static int blockor(char *dest, char *blk1, char *blk2, int length) { int i; char result = 0; for (i = 0; i < length; i++) { dest[i] = (blk1[i] | blk2[i]); result |= dest[i]; } return (result) ? 1 : 0; } static int blockand(char *dest, char *blk1, char *blk2, int length) { int i; char result = 0; for (i = 0; i < length; i++) { dest[i] = (blk1[i] & blk2[i]); result |= dest[i]; } return (result) ? 1 : 0; } static int blockunmask(char *dest, char *blk1, char *blk2, int length) { int i; char result = (char)0xff; for (i = 0; i < length; i++) { dest[i] = (blk1[i] & ~blk2[i]); result |= dest[i]; } return (result) ? 1 : 0; } static int blockissubset(char *sub, char *super, int length) { int i; for (i = 0; i < length; i++) { if ((sub[i] & super[i]) != sub[i]) { return 0; } } return 1; } static int blocksintersect(char *blk1, char *blk2, int length) { int i; for (i = 0; i < length; i++) { if (blk1[i] & blk2[i]) { return 1; } } return 0; } static int style_ids_are_equal(style_id_t *a, style_id_t *b) { if ( SID_GET_HAS_NAME(*a) && SID_GET_HAS_NAME(*b) && !strcmp(SID_GET_NAME(*a), SID_GET_NAME(*b))) { return 1; } if ( SID_GET_HAS_WINDOW_ID(*a) && SID_GET_HAS_WINDOW_ID(*b) && SID_GET_WINDOW_ID(*a) == SID_GET_WINDOW_ID(*b)) { return 1; } return 0; } static int style_id_equals_id(window_style *s, style_id_t* id) { return style_ids_are_equal(&SGET_ID(*s), id); } static int styles_have_same_id(window_style* s, window_style* t) { return style_ids_are_equal(&SGET_ID(*s), &SGET_ID(*t)); } static int fw_match_style_id(FvwmWindow *fw, style_id_t s_id) { if (SID_GET_HAS_NAME(s_id)) { if (matchWildcards(SID_GET_NAME(s_id), fw->class.res_class) == 1) { return 1; } if (matchWildcards(SID_GET_NAME(s_id), fw->class.res_name) == 1) { return 1; } if (matchWildcards(SID_GET_NAME(s_id), fw->visible_name) == 1) { return 1; } if (matchWildcards(SID_GET_NAME(s_id), fw->name.name) == 1) { return 1; } if (fw->style_name != NULL && matchWildcards(SID_GET_NAME(s_id), fw->style_name) == 1) { return 1; } } if (SID_GET_HAS_WINDOW_ID(s_id) && SID_GET_WINDOW_ID(s_id) == (XID)FW_W(fw)) { return 1; } return 0; } static int one_fw_can_match_both_ids(window_style *s, window_style *t) { if (SGET_ID_HAS_WINDOW_ID(*s) && SGET_ID_HAS_WINDOW_ID(*t) && SGET_WINDOW_ID(*s) != SGET_WINDOW_ID(*t)) { return 0; } return 1; } static void remove_icon_boxes_from_style(window_style *pstyle) { if (SHAS_ICON_BOXES(&pstyle->flags)) { free_icon_boxes(SGET_ICON_BOXES(*pstyle)); pstyle->flags.has_icon_boxes = 0; SSET_ICON_BOXES(*pstyle, NULL); } return; } static void copy_icon_boxes(icon_boxes **pdest, icon_boxes *src) { icon_boxes *last = NULL; icon_boxes *temp; *pdest = NULL; /* copy the icon boxes */ for ( ; src != NULL; src = src->next) { temp = (icon_boxes *)safemalloc(sizeof(icon_boxes)); memcpy(temp, src, sizeof(icon_boxes)); temp->next = NULL; if (last != NULL) last->next = temp; else *pdest = temp; last = temp; } } /* Check word after IconFill to see if its "Top,Bottom,Left,Right" */ static int Get_TBLR(char *token, unsigned char *IconFill) { /* init */ if (StrEquals(token, "B") || StrEquals(token, "BOT")|| StrEquals(token, "BOTTOM")) { /* turn on bottom and verical */ *IconFill = ICONFILLBOT | ICONFILLHRZ; } else if (StrEquals(token, "T") || StrEquals(token, "TOP")) { /* turn on vertical */ *IconFill = ICONFILLHRZ; } else if (StrEquals(token, "R") || StrEquals(token, "RGT") || StrEquals(token, "RIGHT")) { /* turn on right bit */ *IconFill = ICONFILLRGT; } else if (StrEquals(token, "L") || StrEquals(token, "LFT") || StrEquals(token, "LEFT")) { *IconFill = 0; } else { /* anything else is bad */ return 0; } /* return OK */ return 1; } static void cleanup_style_defaults(window_style *style) { int i; char *dflt; char *mask; mask = (char *)&(style->flag_mask); dflt = (char *)&(style->flag_default); for (i = 0; i < sizeof(style_flags); i++) { dflt[i] &= ~mask[i]; } return; } /* merge_styles - For a matching style, merge window_style to window_style * * Returned Value: * merged matching styles in callers window_style. * * Inputs: * merged_style - style resulting from the merge * add_style - the style to be added into the merge_style * do_free_src_and_alloc_copy * - free allocated parts of merge_style that are replaced * from add_style. Create a copy of of the replaced * styles in allocated memory. * * Note: * The only trick here is that on and off flags/buttons are * combined into the on flag/button. */ static void merge_styles( window_style *merged_style, window_style *add_style, Bool do_free_src_and_alloc_copy) { int i; char *merge_flags; char *add_flags; char *merge_mask; char *add_mask; char *merge_dflt; char *add_dflt; char *merge_change_mask; char *add_change_mask; if (add_style->flag_mask.has_icon) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_ICON_NAME(*merged_style)); SSET_ICON_NAME( *merged_style, (SGET_ICON_NAME(*add_style)) ? safestrdup(SGET_ICON_NAME(*add_style)) : NULL); } else { SSET_ICON_NAME( *merged_style, SGET_ICON_NAME(*add_style)); } } if (FMiniIconsSupported && add_style->flag_mask.has_mini_icon) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_MINI_ICON_NAME(*merged_style)); SSET_MINI_ICON_NAME( *merged_style, (SGET_MINI_ICON_NAME(*add_style)) ? safestrdup(SGET_MINI_ICON_NAME(*add_style)) : NULL); } else { SSET_MINI_ICON_NAME( *merged_style, SGET_MINI_ICON_NAME(*add_style)); } } if (add_style->flag_mask.has_decor) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_DECOR_NAME(*merged_style)); SSET_DECOR_NAME( *merged_style, (SGET_DECOR_NAME(*add_style)) ? safestrdup(SGET_DECOR_NAME(*add_style)) : NULL); } else { SSET_DECOR_NAME( *merged_style, SGET_DECOR_NAME(*add_style)); } } if (S_HAS_ICON_FONT(SCF(*add_style))) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_ICON_FONT(*merged_style)); SSET_ICON_FONT( *merged_style, (SGET_ICON_FONT(*add_style)) ? safestrdup(SGET_ICON_FONT(*add_style)) : NULL); } else { SSET_ICON_FONT( *merged_style, SGET_ICON_FONT(*add_style)); } } if (S_HAS_WINDOW_FONT(SCF(*add_style))) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_WINDOW_FONT(*merged_style)); SSET_WINDOW_FONT( *merged_style, (SGET_WINDOW_FONT(*add_style)) ? safestrdup(SGET_WINDOW_FONT(*add_style)) : NULL); } else { SSET_WINDOW_FONT( *merged_style, SGET_WINDOW_FONT(*add_style)); } } if (add_style->flags.use_start_on_desk) { SSET_START_DESK(*merged_style, SGET_START_DESK(*add_style)); SSET_START_PAGE_X( *merged_style, SGET_START_PAGE_X(*add_style)); SSET_START_PAGE_Y( *merged_style, SGET_START_PAGE_Y(*add_style)); } if (add_style->flags.use_start_on_screen) { SSET_START_SCREEN (*merged_style, SGET_START_SCREEN(*add_style)); } if (add_style->flag_mask.has_color_fore) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_FORE_COLOR_NAME(*merged_style)); SSET_FORE_COLOR_NAME( *merged_style, (SGET_FORE_COLOR_NAME(*add_style)) ? safestrdup(SGET_FORE_COLOR_NAME(*add_style)) : NULL); } else { SSET_FORE_COLOR_NAME( *merged_style, SGET_FORE_COLOR_NAME(*add_style)); } } if (add_style->flag_mask.has_color_back) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_BACK_COLOR_NAME(*merged_style)); SSET_BACK_COLOR_NAME( *merged_style, (SGET_BACK_COLOR_NAME(*add_style)) ? safestrdup(SGET_BACK_COLOR_NAME(*add_style)) : NULL); } else { SSET_BACK_COLOR_NAME( *merged_style, SGET_BACK_COLOR_NAME(*add_style)); } } if (add_style->flag_mask.has_color_fore_hi) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_FORE_COLOR_NAME_HI(*merged_style)); SSET_FORE_COLOR_NAME_HI( *merged_style, (SGET_FORE_COLOR_NAME_HI(*add_style)) ? safestrdup( SGET_FORE_COLOR_NAME_HI(*add_style)) : NULL); } else { SSET_FORE_COLOR_NAME_HI( *merged_style, SGET_FORE_COLOR_NAME_HI(*add_style)); } } if (add_style->flag_mask.has_color_back_hi) { if (do_free_src_and_alloc_copy) { SAFEFREE(SGET_BACK_COLOR_NAME_HI(*merged_style)); SSET_BACK_COLOR_NAME_HI( *merged_style, (SGET_BACK_COLOR_NAME_HI(*add_style)) ? safestrdup( SGET_BACK_COLOR_NAME_HI(*add_style)) : NULL); } else { SSET_BACK_COLOR_NAME_HI( *merged_style, SGET_BACK_COLOR_NAME_HI(*add_style)); } } if (add_style->flags.has_border_width) { SSET_BORDER_WIDTH( *merged_style, SGET_BORDER_WIDTH(*add_style)); } if (add_style->flags.has_handle_width) { SSET_HANDLE_WIDTH( *merged_style, SGET_HANDLE_WIDTH(*add_style)); } if (add_style->flags.has_icon_size_limits) { SSET_MIN_ICON_WIDTH( *merged_style, SGET_MIN_ICON_WIDTH(*add_style)); SSET_MIN_ICON_HEIGHT( *merged_style, SGET_MIN_ICON_HEIGHT(*add_style)); SSET_MAX_ICON_WIDTH( *merged_style, SGET_MAX_ICON_WIDTH(*add_style)); SSET_MAX_ICON_HEIGHT( *merged_style, SGET_MAX_ICON_HEIGHT(*add_style)); SSET_ICON_RESIZE_TYPE( *merged_style, SGET_ICON_RESIZE_TYPE(*add_style)); } if (add_style->flags.has_min_window_size) { SSET_MIN_WINDOW_WIDTH( *merged_style, SGET_MIN_WINDOW_WIDTH(*add_style)); SSET_MIN_WINDOW_HEIGHT( *merged_style, SGET_MIN_WINDOW_HEIGHT(*add_style)); } if (add_style->flags.has_max_window_size) { SSET_MAX_WINDOW_WIDTH( *merged_style, SGET_MAX_WINDOW_WIDTH(*add_style)); SSET_MAX_WINDOW_HEIGHT( *merged_style, SGET_MAX_WINDOW_HEIGHT(*add_style)); } if (add_style->flags.has_icon_background_relief) { SSET_ICON_BACKGROUND_RELIEF( *merged_style, SGET_ICON_BACKGROUND_RELIEF(*add_style)); } if (add_style->flags.has_icon_background_padding) { SSET_ICON_BACKGROUND_PADDING( *merged_style, SGET_ICON_BACKGROUND_PADDING(*add_style)); } if (add_style->flags.has_icon_title_relief) { SSET_ICON_TITLE_RELIEF( *merged_style, SGET_ICON_TITLE_RELIEF(*add_style)); } if (add_style->flags.has_window_shade_steps) { SSET_WINDOW_SHADE_STEPS( *merged_style, SGET_WINDOW_SHADE_STEPS(*add_style)); } if (add_style->flags.has_snap_attraction) { SSET_SNAP_PROXIMITY( *merged_style, SGET_SNAP_PROXIMITY(*add_style)); SSET_SNAP_MODE( *merged_style, SGET_SNAP_MODE(*add_style)); } if (add_style->flags.has_snap_grid) { SSET_SNAP_GRID_X( *merged_style, SGET_SNAP_GRID_X(*add_style)); SSET_SNAP_GRID_Y( *merged_style, SGET_SNAP_GRID_Y(*add_style)); } if (add_style->flags.has_edge_delay_ms_move) { SSET_EDGE_DELAY_MS_MOVE( *merged_style, SGET_EDGE_DELAY_MS_MOVE(*add_style)); } if (add_style->flags.has_edge_delay_ms_resize) { SSET_EDGE_DELAY_MS_RESIZE( *merged_style, SGET_EDGE_DELAY_MS_RESIZE(*add_style)); } if (add_style->flags.has_edge_resistance_move) { SSET_EDGE_RESISTANCE_MOVE( *merged_style, SGET_EDGE_RESISTANCE_MOVE(*add_style)); } if (add_style->flags.has_edge_resistance_xinerama_move) { SSET_EDGE_RESISTANCE_XINERAMA_MOVE( *merged_style, SGET_EDGE_RESISTANCE_XINERAMA_MOVE(*add_style)); } /* Note: Only one style cmd can define a window's iconboxes, the last * one encountered. */ if (SHAS_ICON_BOXES(&add_style->flag_mask)) { /* If style has iconboxes */ /* copy it */ if (do_free_src_and_alloc_copy) { remove_icon_boxes_from_style(merged_style); copy_icon_boxes( &SGET_ICON_BOXES(*merged_style), SGET_ICON_BOXES(*add_style)); } else { SSET_ICON_BOXES( *merged_style, SGET_ICON_BOXES(*add_style)); } } if (add_style->flags.use_layer) { SSET_LAYER(*merged_style, SGET_LAYER(*add_style)); } if (add_style->flags.do_start_shaded) { SSET_STARTS_SHADED_DIR( *merged_style, SGET_STARTS_SHADED_DIR(*add_style)); } if (add_style->flags.use_colorset) { SSET_COLORSET(*merged_style, SGET_COLORSET(*add_style)); } if (add_style->flags.use_colorset_hi) { SSET_COLORSET_HI(*merged_style, SGET_COLORSET_HI(*add_style)); } if (add_style->flags.use_border_colorset) { SSET_BORDER_COLORSET( *merged_style, SGET_BORDER_COLORSET(*add_style)); } if (add_style->flags.use_border_colorset_hi) { SSET_BORDER_COLORSET_HI( *merged_style,SGET_BORDER_COLORSET_HI(*add_style)); } if (add_style->flags.use_icon_title_colorset) { SSET_ICON_TITLE_COLORSET( *merged_style,SGET_ICON_TITLE_COLORSET(*add_style)); } if (add_style->flags.use_icon_title_colorset_hi) { SSET_ICON_TITLE_COLORSET_HI( *merged_style,SGET_ICON_TITLE_COLORSET_HI(*add_style)); } if (add_style->flags.use_icon_background_colorset) { SSET_ICON_BACKGROUND_COLORSET( *merged_style,SGET_ICON_BACKGROUND_COLORSET( *add_style)); } if (add_style->flags.has_placement_penalty) { SSET_NORMAL_PLACEMENT_PENALTY( *merged_style, SGET_NORMAL_PLACEMENT_PENALTY(*add_style)); SSET_ONTOP_PLACEMENT_PENALTY( *merged_style, SGET_ONTOP_PLACEMENT_PENALTY(*add_style)); SSET_ICON_PLACEMENT_PENALTY( *merged_style, SGET_ICON_PLACEMENT_PENALTY( *add_style)); SSET_STICKY_PLACEMENT_PENALTY( *merged_style, SGET_STICKY_PLACEMENT_PENALTY(*add_style)); SSET_BELOW_PLACEMENT_PENALTY( *merged_style, SGET_BELOW_PLACEMENT_PENALTY(*add_style)); SSET_EWMH_STRUT_PLACEMENT_PENALTY( *merged_style, SGET_EWMH_STRUT_PLACEMENT_PENALTY(*add_style)); } if (add_style->flags.has_placement_percentage_penalty) { SSET_99_PLACEMENT_PERCENTAGE_PENALTY( *merged_style, SGET_99_PLACEMENT_PERCENTAGE_PENALTY(*add_style)); SSET_95_PLACEMENT_PERCENTAGE_PENALTY( *merged_style, SGET_95_PLACEMENT_PERCENTAGE_PENALTY(*add_style)); SSET_85_PLACEMENT_PERCENTAGE_PENALTY( *merged_style, SGET_85_PLACEMENT_PERCENTAGE_PENALTY(*add_style)); SSET_75_PLACEMENT_PERCENTAGE_PENALTY( *merged_style, SGET_75_PLACEMENT_PERCENTAGE_PENALTY(*add_style)); } if (add_style->flags.has_placement_position_string) { SAFEFREE(SGET_PLACEMENT_POSITION_STRING(*merged_style)); SSET_PLACEMENT_POSITION_STRING( *merged_style, strdup(SGET_PLACEMENT_POSITION_STRING(*add_style))); } if (add_style->flags.has_initial_map_command_string) { SAFEFREE(SGET_INITIAL_MAP_COMMAND_STRING(*merged_style)); SSET_INITIAL_MAP_COMMAND_STRING( *merged_style, strdup(SGET_INITIAL_MAP_COMMAND_STRING(*add_style))); } if (add_style->flags.has_title_format_string) { SAFEFREE(SGET_TITLE_FORMAT_STRING(*merged_style)); SSET_TITLE_FORMAT_STRING(*merged_style, strdup(SGET_TITLE_FORMAT_STRING(*add_style))); } if (add_style->flags.has_icon_title_format_string) { SAFEFREE(SGET_ICON_TITLE_FORMAT_STRING(*merged_style)); SSET_ICON_TITLE_FORMAT_STRING(*merged_style, strdup(SGET_ICON_TITLE_FORMAT_STRING(*add_style))); } /* merge the style flags */ /*** ATTENTION: *** This must be the last thing that is done in this function! */ merge_flags = (char *)&(merged_style->flags); add_flags = (char *)&(add_style->flags); merge_mask = (char *)&(merged_style->flag_mask); add_mask = (char *)&(add_style->flag_mask); merge_dflt = (char *)&(merged_style->flag_default); add_dflt = (char *)&(add_style->flag_default); merge_change_mask = (char *)&(merged_style->change_mask); add_change_mask = (char *)&(add_style->change_mask); for (i = 0; i < sizeof(style_flags); i++) { char m; /* overwrite set styles */ merge_flags[i] |= (add_flags[i] & add_mask[i]); merge_flags[i] &= (add_flags[i] | ~add_mask[i]); /* overwrite default values */ m = add_dflt[i] & ~add_mask[i] & ~merge_mask[i]; merge_flags[i] |= (add_flags[i] & m); merge_flags[i] &= (add_flags[i] | ~m); /* overwrite even weaker default values */ m = ~add_dflt[i] & ~add_mask[i] & ~merge_dflt[i] & ~merge_mask[i]; merge_flags[i] |= (add_flags[i] & m); merge_flags[i] &= (add_flags[i] | ~m); /* other flags */ merge_change_mask[i] &= ~(add_mask[i]); merge_change_mask[i] |= add_change_mask[i]; merge_mask[i] |= add_mask[i]; merge_dflt[i] |= add_dflt[i]; merge_dflt[i] &= ~merge_mask[i]; } merged_style->has_style_changed |= add_style->has_style_changed; return; } static void free_style(window_style *style) { /* Free contents of style */ SAFEFREE(SGET_NAME(*style)); SAFEFREE(SGET_BACK_COLOR_NAME(*style)); SAFEFREE(SGET_FORE_COLOR_NAME(*style)); SAFEFREE(SGET_BACK_COLOR_NAME_HI(*style)); SAFEFREE(SGET_FORE_COLOR_NAME_HI(*style)); SAFEFREE(SGET_DECOR_NAME(*style)); SAFEFREE(SGET_ICON_FONT(*style)); SAFEFREE(SGET_WINDOW_FONT(*style)); SAFEFREE(SGET_ICON_NAME(*style)); SAFEFREE(SGET_MINI_ICON_NAME(*style)); remove_icon_boxes_from_style(style); SAFEFREE(SGET_PLACEMENT_POSITION_STRING(*style)); SAFEFREE(SGET_INITIAL_MAP_COMMAND_STRING(*style)); SAFEFREE(SGET_TITLE_FORMAT_STRING(*style)); SAFEFREE(SGET_ICON_TITLE_FORMAT_STRING(*style)); return; } /* Frees only selected members of a style; adjusts the flag_mask and * change_mask appropriately. */ static void free_style_mask(window_style *style, style_flags *mask) { style_flags local_mask; style_flags *pmask; /* mask out all bits that are not set in the target style */ pmask =&local_mask; blockand((char *)pmask, (char *)&style->flag_mask, (char *)mask, sizeof(style_flags)); /* Free contents of style */ if (pmask->has_color_back) { SAFEFREE(SGET_BACK_COLOR_NAME(*style)); } if (pmask->has_color_fore) { SAFEFREE(SGET_FORE_COLOR_NAME(*style)); } if (pmask->has_color_back_hi) { SAFEFREE(SGET_BACK_COLOR_NAME_HI(*style)); } if (pmask->has_color_fore_hi) { SAFEFREE(SGET_FORE_COLOR_NAME_HI(*style)); } if (pmask->has_decor) { SAFEFREE(SGET_DECOR_NAME(*style)); } if (pmask->common.has_icon_font) { SAFEFREE(SGET_ICON_FONT(*style)); } if (pmask->common.has_window_font) { SAFEFREE(SGET_WINDOW_FONT(*style)); } if (pmask->has_icon) { SAFEFREE(SGET_ICON_NAME(*style)); } if (pmask->has_mini_icon) { SAFEFREE(SGET_MINI_ICON_NAME(*style)); } if (pmask->has_icon_boxes) { remove_icon_boxes_from_style(style); } /* remove styles from definitiion */ blockunmask((char *)&style->flag_mask, (char *)&style->flag_mask, (char *)pmask, sizeof(style_flags)); blockunmask((char *)&style->flag_default, (char *)&style->flag_default, (char *)pmask, sizeof(style_flags)); blockunmask((char *)&style->change_mask, (char *)&style->change_mask, (char *)pmask, sizeof(style_flags)); return; } static void add_style_to_list(window_style *new_style) { /* This used to contain logic that returned if the style didn't contain * anything. I don't see why we should bother. dje. * * used to merge duplicate entries, but that is no longer * appropriate since conflicting styles are possible, and the * last match should win! */ if (last_style_in_list != NULL) { /* not first entry in list chain this entry to the list */ SSET_NEXT_STYLE(*last_style_in_list, new_style); } else { /* first entry in list set the list root pointer. */ all_styles = new_style; } SSET_PREV_STYLE(*new_style, last_style_in_list); SSET_NEXT_STYLE(*new_style, NULL); last_style_in_list = new_style; Scr.flags.do_need_style_list_update = 1; return; } /* end function */ static void remove_style_from_list(window_style *style, Bool do_free_style) { window_style *prev; window_style *next; prev = SGET_PREV_STYLE(*style); next = SGET_NEXT_STYLE(*style); if (!prev) { /* first style in list */ all_styles = next; } else { /* not first style in list */ SSET_NEXT_STYLE(*prev, next); } if (!next) { /* last style in list */ last_style_in_list = prev; } else { SSET_PREV_STYLE(*next, prev); } if (do_free_style) { free_style(style); free(style); } } static int remove_all_of_style_from_list(style_id_t style_id) { window_style *nptr = all_styles; window_style *next; int is_changed = 0; /* loop though styles */ while (nptr) { next = SGET_NEXT_STYLE(*nptr); /* Check if it's to be wiped */ if (style_id_equals_id(nptr, &style_id)) { remove_style_from_list(nptr, True); is_changed = 1; } /* move on */ nptr = next; } return is_changed; } static int __simplify_style_list(void) { window_style *cur; int has_modified; /* Step 1: * Remove styles that are completely overridden by later * style definitions. At the same time... * Step 2: * Merge styles with the same name if there are no * conflicting styles with other names set in between. */ for ( cur = last_style_in_list, has_modified = 0; cur; cur = SGET_PREV_STYLE(*cur)) { style_flags dummyflags; /* incremental flags set in styles with the same name */ style_flags sumflags; style_flags sumdflags; /* incremental flags set in styles with other names */ style_flags interflags; window_style *cmp; memset(&interflags, 0, sizeof(style_flags)); memcpy(&sumflags, &cur->flag_mask, sizeof(style_flags)); memcpy(&sumdflags, &cur->flag_default, sizeof(style_flags)); cmp = SGET_PREV_STYLE(*cur); while (cmp) { if (!styles_have_same_id(cur, cmp)) { if (one_fw_can_match_both_ids(cur, cmp)) { blockor((char *)&interflags, (char *)&interflags, (char *)&cmp->flag_mask, sizeof(style_flags)); blockor((char *)&interflags, (char *)&interflags, (char *)&cmp->flag_default, sizeof(style_flags)); } cmp = SGET_PREV_STYLE(*cmp); continue; } if (blockissubset( (char *)&cmp->flag_mask, (char *)&sumflags, sizeof(style_flags)) && blockissubset( (char *)&cmp->flag_default, (char *)&sumdflags, sizeof(style_flags))) { /* The style is a subset of later style * definitions; nuke it */ window_style *tmp = SGET_PREV_STYLE(*cmp); remove_style_from_list(cmp, True); cmp = tmp; has_modified = 1; continue; } /* remove all styles that are overridden later from the * style */ blockor((char *)&dummyflags, (char *)&sumdflags, (char *)&sumflags, sizeof(style_flags)); free_style_mask(cmp, &dummyflags); if ( !blocksintersect( (char *)&cmp->flag_mask, (char *)&interflags, sizeof(style_flags)) && !blocksintersect( (char *)&cmp->flag_default, (char *)&interflags, sizeof(style_flags))) { /* merge old style into new style */ window_style *tmp = SGET_PREV_STYLE(*cmp); window_style *prev = SGET_PREV_STYLE(*cur); window_style *next = SGET_NEXT_STYLE(*cur); /* Add the style to the set */ blockor((char *)&sumflags, (char *)&sumflags, (char *)&cmp->flag_mask, sizeof(style_flags)); blockor((char *)&sumdflags, (char *)&sumflags, (char *)&cmp->flag_default, sizeof(style_flags)); /* merge cmp into cur and delete it * afterwards */ merge_styles(cmp, cur, True); free_style(cur); memcpy(cur, cmp, sizeof(window_style)); /* restore fields overwritten by memcpy */ SSET_PREV_STYLE(*cur, prev); SSET_NEXT_STYLE(*cur, next); /* remove the style without freeing the * memory */ remove_style_from_list(cmp, False); /* release the style structure */ free(cmp); cmp = tmp; has_modified = 1; } else if ( !blocksintersect( (char *)&cur->flag_mask, (char *)&interflags, sizeof(style_flags)) && !blocksintersect( (char *)&cur->flag_default, (char *)&interflags, sizeof(style_flags))) { /* merge new style into old style */ window_style *tmp = SGET_PREV_STYLE(*cmp); /* Add the style to the set */ blockor((char *)&sumflags, (char *)&sumflags, (char *)&cur->flag_mask, sizeof(style_flags)); blockor((char *)&sumdflags, (char *)&sumflags, (char *)&cur->flag_default, sizeof(style_flags)); /* merge cur into cmp and delete it * afterwards */ merge_styles(cmp, cur, True); remove_style_from_list(cur, True); cur = cmp; cmp = tmp; has_modified = 1; memset(&interflags, 0, sizeof(style_flags)); continue; } else { /* Add it to the set of interfering styles. */ blockor((char *)&interflags, (char *)&interflags, (char *)&cmp->flag_mask, sizeof(style_flags)); blockor((char *)&interflags, (char *)&interflags, (char *)&cmp->flag_default, sizeof(style_flags)); cmp = SGET_PREV_STYLE(*cmp); } } } return has_modified; } static void style_set_old_focus_policy(window_style *ps, int policy) { focus_policy_t fp; switch (policy) { case 0: /* ClickToFocus */ FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_BY_PROGRAM(fp, 1); FPS_GRAB_FOCUS(fp, 1); FPS_RELEASE_FOCUS(fp, 1); FPS_RAISE_FOCUSED_CLIENT_CLICK(fp, 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(fp, 1); FPS_RAISE_FOCUSED_DECOR_CLICK(fp, 1); FPS_RAISE_UNFOCUSED_DECOR_CLICK(fp, 1); FPS_PASS_FOCUS_CLICK(fp, 1); FPS_PASS_RAISE_CLICK(fp, 1); FPS_ALLOW_FUNC_FOCUS_CLICK(fp, 1); FPS_ALLOW_FUNC_RAISE_CLICK(fp, 1); FPS_WARP_POINTER_ON_FOCUS_FUNC(fp, 0); break; case 1: /* MouseFocus */ FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_BY_PROGRAM(fp, 1); FPS_GRAB_FOCUS(fp, 0); FPS_RELEASE_FOCUS(fp, 0); FPS_RAISE_FOCUSED_CLIENT_CLICK(fp, 0); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(fp, 0); FPS_RAISE_FOCUSED_DECOR_CLICK(fp, 0); FPS_RAISE_UNFOCUSED_DECOR_CLICK(fp, 0); FPS_PASS_FOCUS_CLICK(fp, 1); FPS_PASS_RAISE_CLICK(fp, 1); FPS_ALLOW_FUNC_FOCUS_CLICK(fp, 0); FPS_ALLOW_FUNC_RAISE_CLICK(fp, 0); FPS_WARP_POINTER_ON_FOCUS_FUNC(fp, 1); break; case 2: /* SloppyFocus */ FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCF(*ps)), 1); FPS_FOCUS_BY_PROGRAM(fp, 1); FPS_GRAB_FOCUS(fp, 0); FPS_RELEASE_FOCUS(fp, 1); FPS_RAISE_FOCUSED_CLIENT_CLICK(fp, 0); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(fp, 0); FPS_RAISE_FOCUSED_DECOR_CLICK(fp, 0); FPS_RAISE_UNFOCUSED_DECOR_CLICK(fp, 0); FPS_PASS_FOCUS_CLICK(fp, 1); FPS_PASS_RAISE_CLICK(fp, 1); FPS_ALLOW_FUNC_FOCUS_CLICK(fp, 0); FPS_ALLOW_FUNC_RAISE_CLICK(fp, 0); FPS_WARP_POINTER_ON_FOCUS_FUNC(fp, 1); break; case 3: /* NeverFocus */ FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCF(*ps)), 0); FPS_FOCUS_BY_PROGRAM(fp, 1); FPS_GRAB_FOCUS(fp, 0); FPS_RELEASE_FOCUS(fp, 0); FPS_RAISE_FOCUSED_CLIENT_CLICK(fp, 0); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(fp, 0); FPS_RAISE_FOCUSED_DECOR_CLICK(fp, 0); FPS_RAISE_UNFOCUSED_DECOR_CLICK(fp, 0); FPS_PASS_FOCUS_CLICK(fp, 1); FPS_PASS_RAISE_CLICK(fp, 1); FPS_ALLOW_FUNC_FOCUS_CLICK(fp, 1); FPS_ALLOW_FUNC_RAISE_CLICK(fp, 1); FPS_WARP_POINTER_ON_FOCUS_FUNC(fp, 0); break; } FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCC(*ps)), 1); if (!FP_DO_FOCUS_BY_PROGRAM(S_FOCUS_POLICY(SCM(*ps)))) { FPS_FOCUS_BY_PROGRAM( S_FOCUS_POLICY(SCF(*ps)), FP_DO_FOCUS_BY_PROGRAM(fp)); FPS_FOCUS_BY_PROGRAM(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_FOCUS_BY_PROGRAM(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_GRAB_FOCUS(S_FOCUS_POLICY(SCM(*ps)))) { FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCF(*ps)), FP_DO_GRAB_FOCUS(fp)); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_RELEASE_FOCUS(S_FOCUS_POLICY(SCM(*ps)))) { FPS_RELEASE_FOCUS( S_FOCUS_POLICY(SCF(*ps)), FP_DO_RELEASE_FOCUS(fp)); FPS_RELEASE_FOCUS(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_RELEASE_FOCUS(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_RAISE_FOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_RAISE_FOCUSED_CLIENT_CLICK(fp)); FPS_RAISE_FOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_RAISE_FOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_RAISE_UNFOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_RAISE_UNFOCUSED_CLIENT_CLICK(fp)); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_RAISE_FOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_RAISE_FOCUSED_DECOR_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_RAISE_FOCUSED_DECOR_CLICK(fp)); FPS_RAISE_FOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_RAISE_FOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_RAISE_UNFOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_RAISE_UNFOCUSED_DECOR_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_RAISE_UNFOCUSED_DECOR_CLICK(fp)); FPS_RAISE_UNFOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_RAISE_UNFOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_PASS_FOCUS_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_PASS_FOCUS_CLICK(fp)); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_PASS_RAISE_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_PASS_RAISE_CLICK(fp)); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_ALLOW_FUNC_FOCUS_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_ALLOW_FUNC_FOCUS_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_ALLOW_FUNC_FOCUS_CLICK(fp)); FPS_ALLOW_FUNC_FOCUS_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_ALLOW_FUNC_FOCUS_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_ALLOW_FUNC_RAISE_CLICK(S_FOCUS_POLICY(SCM(*ps)))) { FPS_ALLOW_FUNC_RAISE_CLICK( S_FOCUS_POLICY(SCF(*ps)), FP_DO_ALLOW_FUNC_RAISE_CLICK(fp)); FPS_ALLOW_FUNC_RAISE_CLICK(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_ALLOW_FUNC_RAISE_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_WARP_POINTER_ON_FOCUS_FUNC( S_FOCUS_POLICY(SCM(*ps)))) { FPS_WARP_POINTER_ON_FOCUS_FUNC( S_FOCUS_POLICY(SCF(*ps)), FP_DO_WARP_POINTER_ON_FOCUS_FUNC(fp)); FPS_WARP_POINTER_ON_FOCUS_FUNC(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_WARP_POINTER_ON_FOCUS_FUNC(S_FOCUS_POLICY(SCC(*ps)), 1); } if (!FP_DO_SORT_WINDOWLIST_BY(S_FOCUS_POLICY(SCM(*ps)))) { FPS_SORT_WINDOWLIST_BY( S_FOCUS_POLICY(SCF(*ps)), FP_DO_SORT_WINDOWLIST_BY(fp)); FPS_SORT_WINDOWLIST_BY(S_FOCUS_POLICY(SCD(*ps)), 1); FPS_SORT_WINDOWLIST_BY(S_FOCUS_POLICY(SCC(*ps)), 1); } return; } static char *style_parse_button_style( window_style *ps, char *button_string, int on) { int button; char *rest; button = -1; GetIntegerArguments(button_string, &rest, &button, 1); button = BUTTON_INDEX(button); if (button < 0 || button >= NUMBER_OF_TITLE_BUTTONS) { fvwm_msg( ERR, "CMD_Style", "Button and NoButton styles require an argument"); } else { if (on) { ps->flags.is_button_disabled &= ~(1 << button); ps->flag_mask.is_button_disabled |= (1 << button); ps->change_mask.is_button_disabled |= (1 << button); } else { ps->flags.is_button_disabled |= (1 << button); ps->flag_mask.is_button_disabled |= (1 << button); ps->change_mask.is_button_disabled |= (1 << button); } } return rest; } static Bool style_parse_focus_policy_style( char *option, char *rest, char **ret_rest, Bool is_reversed, focus_policy_t *f, focus_policy_t *m, focus_policy_t *c) { char *optlist[] = { "SortWindowlistByFocus", "FocusClickButtons", "FocusClickModifiers", "ClickRaisesFocused", "ClickDecorRaisesFocused", "ClickIconRaisesFocused", "ClickRaisesUnfocused", "ClickDecorRaisesUnfocused", "ClickIconRaisesUnfocused", "ClickToFocus", "ClickDecorToFocus", "ClickIconToFocus", "EnterToFocus", "LeaveToUnfocus", "FocusByProgram", "FocusByFunction", "FocusByFunctionWarpPointer", "Lenient", "PassFocusClick", "PassRaiseClick", "IgnoreFocusClickMotion", "IgnoreRaiseClickMotion", "AllowFocusClickFunction", "AllowRaiseClickFunction", "GrabFocus", "GrabFocusTransient", "OverrideGrabFocus", "ReleaseFocus", "ReleaseFocusTransient", "OverrideReleaseFocus", NULL }; Bool found; int val; int index; char *token; if (ret_rest) { *ret_rest = rest; } found = True; val = !is_reversed; GetNextTokenIndex(option, optlist, 0, &index); switch (index) { case 0: /* SortWindowlistByFocus */ FPS_SORT_WINDOWLIST_BY( *f, (val) ? FPOL_SORT_WL_BY_FOCUS : FPOL_SORT_WL_BY_OPEN); FPS_SORT_WINDOWLIST_BY(*m, 1); FPS_SORT_WINDOWLIST_BY(*c, 1); break; case 1: /* FocusClickButtons */ if (is_reversed) { found = False; break; } token = PeekToken(rest, ret_rest); val = 0; for ( ; token != NULL && isdigit(*token); token++) { int button; char s[2]; s[0] = *token; s[1] = 0; button = atoi(s); if (button == 0) { val = ~0; } else if (button > NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { break; } else { val |= (1 << (button - 1)); } } if (token != NULL && *token != 0) { fvwm_msg( ERR, "style_parse_focus_policy_style", "illegal mouse button '%c'", *token); val = DEF_FP_MOUSE_BUTTONS; } if (token == NULL) { val = DEF_FP_MOUSE_BUTTONS; } FPS_MOUSE_BUTTONS(*f, val); FPS_MOUSE_BUTTONS(*m, 0x1FF); FPS_MOUSE_BUTTONS(*c, 0x1FF); break; case 2: /* FocusClickModifiers */ if (is_reversed) { found = False; break; } token = PeekToken(rest, ret_rest); if (token == NULL || modifiers_string_to_modmask(token, &val) == 1) { val = DEF_FP_MODIFIERS; } if (val & AnyModifier) { val = FPOL_ANY_MODIFIER; } FPS_MODIFIERS(*f, val); FPS_MODIFIERS(*m, 0xFF); FPS_MODIFIERS(*c, 0xFF); break; case 3: /* ClickRaisesFocused */ FPS_RAISE_FOCUSED_CLIENT_CLICK(*f, val); FPS_RAISE_FOCUSED_CLIENT_CLICK(*m, 1); FPS_RAISE_FOCUSED_CLIENT_CLICK(*c, 1); break; case 4: /* ClickDecorRaisesFocused */ FPS_RAISE_FOCUSED_DECOR_CLICK(*f, val); FPS_RAISE_FOCUSED_DECOR_CLICK(*m, 1); FPS_RAISE_FOCUSED_DECOR_CLICK(*c, 1); break; case 5: /* ClickIconRaisesFocused */ FPS_RAISE_FOCUSED_ICON_CLICK(*f, val); FPS_RAISE_FOCUSED_ICON_CLICK(*m, 1); FPS_RAISE_FOCUSED_ICON_CLICK(*c, 1); break; case 6: /* ClickRaisesUnfocused */ FPS_RAISE_UNFOCUSED_CLIENT_CLICK(*f, val); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(*m, 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(*c, 1); break; case 7: /* ClickDecorRaisesUnfocused */ FPS_RAISE_UNFOCUSED_DECOR_CLICK(*f, val); FPS_RAISE_UNFOCUSED_DECOR_CLICK(*m, 1); FPS_RAISE_UNFOCUSED_DECOR_CLICK(*c, 1); break; case 8: /* ClickIconRaisesUnfocused */ FPS_RAISE_UNFOCUSED_ICON_CLICK(*f, val); FPS_RAISE_UNFOCUSED_ICON_CLICK(*m, 1); FPS_RAISE_UNFOCUSED_ICON_CLICK(*c, 1); break; case 9: /* ClickToFocus */ FPS_FOCUS_CLICK_CLIENT(*f, val); FPS_FOCUS_CLICK_CLIENT(*m, 1); FPS_FOCUS_CLICK_CLIENT(*c, 1); break; case 10: /* ClickDecorToFocus */ FPS_FOCUS_CLICK_DECOR(*f, val); FPS_FOCUS_CLICK_DECOR(*m, 1); FPS_FOCUS_CLICK_DECOR(*c, 1); break; case 11: /* ClickIconToFocus */ FPS_FOCUS_CLICK_ICON(*f, val); FPS_FOCUS_CLICK_ICON(*m, 1); FPS_FOCUS_CLICK_ICON(*c, 1); break; case 12: /* EnterToFocus */ FPS_FOCUS_ENTER(*f, val); FPS_FOCUS_ENTER(*m, 1); FPS_FOCUS_ENTER(*c, 1); break; case 13: /* LeaveToUnfocus */ FPS_UNFOCUS_LEAVE(*f, val); FPS_UNFOCUS_LEAVE(*m, 1); FPS_UNFOCUS_LEAVE(*c, 1); break; case 14: /* FocusByProgram */ FPS_FOCUS_BY_PROGRAM(*f, val); FPS_FOCUS_BY_PROGRAM(*m, 1); FPS_FOCUS_BY_PROGRAM(*c, 1); break; case 15: /* FocusByFunction */ FPS_FOCUS_BY_FUNCTION(*f, val); FPS_FOCUS_BY_FUNCTION(*m, 1); FPS_FOCUS_BY_FUNCTION(*c, 1); break; case 16: /* FocusByFunctionWarpPointer */ FPS_WARP_POINTER_ON_FOCUS_FUNC(*f, val); FPS_WARP_POINTER_ON_FOCUS_FUNC(*m, 1); FPS_WARP_POINTER_ON_FOCUS_FUNC(*c, 1); break; case 17: /* Lenient */ FPS_LENIENT(*f, val); FPS_LENIENT(*m, 1); FPS_LENIENT(*c, 1); break; case 18: /* PassFocusClick */ FPS_PASS_FOCUS_CLICK(*f, val); FPS_PASS_FOCUS_CLICK(*m, 1); FPS_PASS_FOCUS_CLICK(*c, 1); break; case 19: /* PassRaiseClick */ FPS_PASS_RAISE_CLICK(*f, val); FPS_PASS_RAISE_CLICK(*m, 1); FPS_PASS_RAISE_CLICK(*c, 1); break; case 20: /* IgnoreFocusClickMotion */ FPS_IGNORE_FOCUS_CLICK_MOTION(*f, val); FPS_IGNORE_FOCUS_CLICK_MOTION(*m, 1); FPS_IGNORE_FOCUS_CLICK_MOTION(*c, 1); break; case 21: /* IgnoreRaiseClickMotion */ FPS_IGNORE_RAISE_CLICK_MOTION(*f, val); FPS_IGNORE_RAISE_CLICK_MOTION(*m, 1); FPS_IGNORE_RAISE_CLICK_MOTION(*c, 1); break; case 22: /* AllowFocusClickFunction */ FPS_ALLOW_FUNC_FOCUS_CLICK(*f, val); FPS_ALLOW_FUNC_FOCUS_CLICK(*m, 1); FPS_ALLOW_FUNC_FOCUS_CLICK(*c, 1); break; case 23: /* AllowRaiseClickFunction */ FPS_ALLOW_FUNC_RAISE_CLICK(*f, val); FPS_ALLOW_FUNC_RAISE_CLICK(*m, 1); FPS_ALLOW_FUNC_RAISE_CLICK(*c, 1); break; case 24: /* GrabFocus */ FPS_GRAB_FOCUS(*f, val); FPS_GRAB_FOCUS(*m, 1); FPS_GRAB_FOCUS(*c, 1); break; case 25: /* GrabFocusTransient */ FPS_GRAB_FOCUS_TRANSIENT(*f, val); FPS_GRAB_FOCUS_TRANSIENT(*m, 1); FPS_GRAB_FOCUS_TRANSIENT(*c, 1); break; case 26: /* OverrideGrabFocus */ FPS_OVERRIDE_GRAB_FOCUS(*f, val); FPS_OVERRIDE_GRAB_FOCUS(*m, 1); FPS_OVERRIDE_GRAB_FOCUS(*c, 1); break; case 27: /* ReleaseFocus */ FPS_RELEASE_FOCUS(*f, val); FPS_RELEASE_FOCUS(*m, 1); FPS_RELEASE_FOCUS(*c, 1); break; case 28: /* ReleaseFocusTransient */ FPS_RELEASE_FOCUS_TRANSIENT(*f, val); FPS_RELEASE_FOCUS_TRANSIENT(*m, 1); FPS_RELEASE_FOCUS_TRANSIENT(*c, 1); break; case 29: /* OverrideReleaseFocus */ FPS_OVERRIDE_RELEASE_FOCUS(*f, val); FPS_OVERRIDE_RELEASE_FOCUS(*m, 1); FPS_OVERRIDE_RELEASE_FOCUS(*c, 1); break; default: found = False; break; } return found; } static char *style_parse_icon_size_style( char *option, char *rest, window_style *ps) { int vals[4]; int i; option = PeekToken(rest, NULL); if (StrEquals(option, "Stretched")) { SSET_ICON_RESIZE_TYPE(*ps, ICON_RESIZE_TYPE_STRETCHED); option = PeekToken(rest, &rest); } else if (StrEquals(option, "Adjusted")) { SSET_ICON_RESIZE_TYPE(*ps, ICON_RESIZE_TYPE_ADJUSTED); option = PeekToken(rest, &rest); } else if (StrEquals(option, "Shrunk")) { SSET_ICON_RESIZE_TYPE(*ps, ICON_RESIZE_TYPE_SHRUNK); option = PeekToken(rest, &rest); } else { SSET_ICON_RESIZE_TYPE(*ps, ICON_RESIZE_TYPE_NONE); } switch (GetIntegerArguments(rest, &rest, vals, 4)) { case 0: /* No arguments results in default values */ vals[0] = vals[1] = UNSPECIFIED_ICON_DIMENSION; /* fall through */ case 2: /* Max and min values are the same */ vals[2] = vals[0]; vals[3] = vals[1]; /* fall through */ case 4: /* Validate values */ for (i = 0; i < 4; i++) { int use_default = 0; if (vals[i] != UNSPECIFIED_ICON_DIMENSION && (vals[i] < MIN_ALLOWABLE_ICON_DIMENSION || vals[i] > MAX_ALLOWABLE_ICON_DIMENSION)) { fvwm_msg( ERR, "CMD_Style", "IconSize dimension (%d) not in valid" " range (%d-%d)", vals[i], MIN_ALLOWABLE_ICON_DIMENSION, MAX_ALLOWABLE_ICON_DIMENSION); use_default = 1; } /* User requests default value for this dimension */ else if (vals[i] == UNSPECIFIED_ICON_DIMENSION) { use_default = 1; } if (use_default) { /* Set default value for this dimension. The * first two indexes refer to min values, the * latter two to max values. */ vals[i] = i < 2 ? MIN_ALLOWABLE_ICON_DIMENSION : MAX_ALLOWABLE_ICON_DIMENSION; } } SSET_MIN_ICON_WIDTH(*ps, vals[0]); SSET_MIN_ICON_HEIGHT(*ps, vals[1]); SSET_MAX_ICON_WIDTH(*ps, vals[2]); SSET_MAX_ICON_HEIGHT(*ps, vals[3]); ps->flags.has_icon_size_limits = 1; ps->flag_mask.has_icon_size_limits = 1; ps->change_mask.has_icon_size_limits = 1; break; default: fvwm_msg( ERR, "CMD_Style", "IconSize requires exactly 0, 2 or 4" " numerical arguments"); break; } return rest; } static char *style_parse_icon_box_style( icon_boxes **ret_ib, char *option, char *rest, window_style *ps) { icon_boxes *IconBoxes = NULL; Bool is_screen_given = False; int val[4]; int num; int i; option = PeekToken(rest, NULL); if (!option || StrEquals(option, "none")) { option = PeekToken(rest, &rest); /* delete icon boxes from style */ if (SGET_ICON_BOXES(*ps)) { remove_icon_boxes_from_style(ps); } (*ret_ib) = NULL; if (option) { /* disable default icon box */ S_SET_DO_IGNORE_ICON_BOXES(SCF(*ps), 1); } else { /* use default icon box */ S_SET_DO_IGNORE_ICON_BOXES(SCF(*ps), 0); } S_SET_DO_IGNORE_ICON_BOXES(SCM(*ps), 1); S_SET_DO_IGNORE_ICON_BOXES(SCC(*ps), 1); ps->flags.has_icon_boxes = 0; ps->flag_mask.has_icon_boxes = 1; ps->change_mask.has_icon_boxes = 1; return rest; } /* otherwise try to parse the icon box */ IconBoxes = (icon_boxes *)safemalloc(sizeof(icon_boxes)); /* clear it */ memset(IconBoxes, 0, sizeof(icon_boxes)); IconBoxes->IconScreen = FSCREEN_GLOBAL; /* init grid x */ IconBoxes->IconGrid[0] = 3; /* init grid y */ IconBoxes->IconGrid[1] = 3; /* check for screen (for 4 numbers) */ if (StrEquals(option, "screen")) { is_screen_given = True; option = PeekToken(rest, &rest); /* skip screen */ option = PeekToken(rest, &rest); /* get the screen spec */ IconBoxes->IconScreen = FScreenGetScreenArgument(option, FSCREEN_SPEC_PRIMARY); } /* try for 4 numbers x y x y */ num = GetIntegerArguments(rest, NULL, val, 4); /* if 4 numbers */ if (num == 4) { for (i = 0; i < 4; i++) { /* make sure the value fits into a short */ if (val[i] < -32768) { val[i] = -32768; } if (val[i] > 32767) { val[i] = 32767; } IconBoxes->IconBox[i] = val[i]; /* If leading minus sign */ option = PeekToken(rest, &rest); if (option[0] == '-') { IconBoxes->IconSign[i]='-'; } /* end leading minus sign */ } /* Note: here there is no test for valid co-ords, use geom */ } else if (is_screen_given) { /* screen-spec is given but not 4 numbers */ fvwm_msg( ERR,"CMD_Style", "IconBox requires 4 numbers if screen is given!" " Invalid: <%s>.", option); /* Drop the box */ free(IconBoxes); /* forget about it */ IconBoxes = 0; } else { /* Not 4 numeric args dje */ /* bigger than =32767x32767+32767+32767 */ int geom_flags; int l; int width; int height; /* read in 1 word w/o advancing */ option = PeekToken(rest, NULL); if (!option) { return rest; } l = strlen(option); if (l > 0 && l < 24) { /* advance */ option = PeekToken(rest, &rest); /* if word found, not too long */ geom_flags = FScreenParseGeometryWithScreen( option, &IconBoxes->IconBox[0], &IconBoxes->IconBox[1], (unsigned int*)&width, (unsigned int*)&height, &IconBoxes->IconScreen); if (width == 0 || !(geom_flags & WidthValue)) { /* zero width is invalid */ fvwm_msg( ERR,"CMD_Style", "IconBox requires 4 numbers or" " geometry! Invalid string <%s>.", option); /* Drop the box */ free(IconBoxes); /* forget about it */ IconBoxes = 0; } else { /* got valid iconbox geom */ if (geom_flags & XNegative) { IconBoxes->IconBox[0] = /* neg x coord */ IconBoxes->IconBox[0] - width - 2; /* save for later */ IconBoxes->IconSign[0]='-'; IconBoxes->IconSign[2]='-'; } if (geom_flags & YNegative) { IconBoxes->IconBox[1] = /* neg y coord */ IconBoxes->IconBox[1] - height -2; /* save for later */ IconBoxes->IconSign[1]='-'; IconBoxes->IconSign[3]='-'; } /* x + wid = right x */ IconBoxes->IconBox[2] = width + IconBoxes->IconBox[0]; /* y + height = bottom y */ IconBoxes->IconBox[3] = height + IconBoxes->IconBox[1]; } /* end icon geom worked */ } else { /* no word or too long; drop the box */ free(IconBoxes); /* forget about it */ IconBoxes = 0; } /* end word found, not too long */ } /* end not 4 args */ /* If we created an IconBox, put it in the chain. */ if (IconBoxes != 0) { /* no error */ if (SGET_ICON_BOXES(*ps) == 0) { /* first one, chain to root */ SSET_ICON_BOXES(*ps, IconBoxes); } else { /* else not first one, add to end of chain */ (*ret_ib)->next = IconBoxes; } /* end not first one */ /* new current box. save for grid */ (*ret_ib) = IconBoxes; } /* end no error */ S_SET_DO_IGNORE_ICON_BOXES(SCF(*ps), 0); S_SET_DO_IGNORE_ICON_BOXES(SCM(*ps), 1); S_SET_DO_IGNORE_ICON_BOXES(SCC(*ps), 1); ps->flags.has_icon_boxes = !!(SGET_ICON_BOXES(*ps)); ps->flag_mask.has_icon_boxes = 1; ps->change_mask.has_icon_boxes = 1; return rest; } static char *style_parse_icon_grid_style( char *option, char *rest, window_style *ps, icon_boxes *ib) { int val[4]; int num; int i; /* The grid always affects the prior iconbox */ if (ib == 0) { /* If no current box */ fvwm_msg( ERR,"CMD_Style", "IconGrid must follow an IconBox in same Style" " command"); return rest; } /* have a place to grid */ /* 2 ints */ num = GetIntegerArguments(rest, &rest, val, 2); if (num != 2 || val[0] < 1 || val[1] < 1) { fvwm_msg( ERR,"CMD_Style", "IconGrid needs 2 numbers > 0. Got %d numbers." " x=%d y=%d!", num, val[0], val[1]); /* reset grid */ ib->IconGrid[0] = 3; ib->IconGrid[1] = 3; } else { for (i = 0; i < 2; i++) { ib->IconGrid[i] = val[i]; } } /* end bad grid */ return rest; } static char *style_parse_icon_fill_style( char *option, char *rest, window_style *ps, icon_boxes *ib) { /* first type direction parsed */ unsigned char IconFill_1; /* second type direction parsed */ unsigned char IconFill_2; /* direction to fill iconbox */ /* The fill always affects the prior iconbox */ if (ib == 0) { /* If no current box */ fvwm_msg( ERR,"CMD_Style", "IconFill must follow an IconBox in same Style" " command"); return rest; } /* have a place to fill */ option = PeekToken(rest, &rest); /* top/bot/lft/rgt */ if (!option || Get_TBLR(option, &IconFill_1) == 0) { /* its wrong */ if (!option) { option = "(none)"; } fvwm_msg( ERR,"CMD_Style", "IconFill must be followed by T|B|R|L, found" " %s.", option); return rest; } /* first word valid */ /* read in second word */ option = PeekToken(rest, &rest); /* top/bot/lft/rgt */ if (!option || Get_TBLR(option, &IconFill_2) == 0) { /* its wrong */ if (!option) { option = "(none)"; } fvwm_msg( ERR,"CMD_Style", "IconFill must be followed by T|B|R|L," " found %s.", option); return rest; } if ((IconFill_1 & ICONFILLHRZ) == (IconFill_2 & ICONFILLHRZ)) { fvwm_msg( ERR, "CMD_Style", "IconFill must specify a horizontal" " and vertical direction."); return rest; } /* Its valid! */ /* merge in flags */ ib->IconFlags |= IconFill_1; /* ignore horiz in 2nd arg */ IconFill_2 &= ~ICONFILLHRZ; /* merge in flags */ ib->IconFlags |= IconFill_2; return rest; } static Bool style_parse_one_style_option( char *token, char *rest, char **ret_rest, char *prefix, window_style *ps, icon_boxes **cur_ib) { window_style *add_style; /* work area for button number */ int num; int i; int tmpno[3] = { -1, -1, -1 }; int val[4]; int spargs = 0; Bool found; int on; char *token_l = NULL; found = True; on = 1; while (token[0] == '!') { on ^= 1; token++; } if (prefix != NULL && *prefix != 0) { int l; l = strlen(prefix); if (strncasecmp(token, prefix, l) != 0) { /* add missing prefix */ token_l = (char *)safemalloc(l + strlen(token) + 1); strcpy(token_l, prefix); strcat(token_l, token); token = token_l; } } switch (tolower(token[0])) { case 'a': if (StrEquals(token, "ACTIVEPLACEMENT")) { ps->flags.placement_mode &= (~PLACE_RANDOM); ps->flag_mask.placement_mode |= PLACE_RANDOM; ps->change_mask.placement_mode |= PLACE_RANDOM; } else if (StrEquals(token, "ACTIVEPLACEMENTHONORSSTARTSONPAGE")) { ps->flags.manual_placement_honors_starts_on_page = on; ps->flag_mask.manual_placement_honors_starts_on_page = 1; ps->change_mask.manual_placement_honors_starts_on_page = 1; } else if (StrEquals( token, "ACTIVEPLACEMENTIGNORESSTARTSONPAGE")) { ps->flags.manual_placement_honors_starts_on_page = !on; ps->flag_mask.manual_placement_honors_starts_on_page = 1; ps->change_mask.manual_placement_honors_starts_on_page = 1; } else if (StrEquals(token, "AllowRestack")) { S_SET_DO_IGNORE_RESTACK(SCF(*ps), !on); S_SET_DO_IGNORE_RESTACK(SCM(*ps), 1); S_SET_DO_IGNORE_RESTACK(SCC(*ps), 1); } else if (StrEquals(token, "AllowMaximizeFixedSize")) { S_SET_MAXIMIZE_FIXED_SIZE_DISALLOWED(SCF(*ps), !on); S_SET_MAXIMIZE_FIXED_SIZE_DISALLOWED(SCM(*ps), 1); S_SET_MAXIMIZE_FIXED_SIZE_DISALLOWED(SCC(*ps), 1); } else { found = False; } break; case 'b': if (StrEquals(token, "BackColor")) { rest = GetNextToken(rest, &token); if (token) { SAFEFREE(SGET_BACK_COLOR_NAME(*ps)); SSET_BACK_COLOR_NAME(*ps, token); ps->flags.has_color_back = 1; ps->flag_mask.has_color_back = 1; ps->change_mask.has_color_back = 1; ps->flags.use_colorset = 0; ps->flag_mask.use_colorset = 1; ps->change_mask.use_colorset = 1; } else { fvwm_msg( ERR, "style_parse_on_estyle_option", "Style BackColor requires color" " argument"); } } else if (StrEquals(token, "Button")) { rest = style_parse_button_style(ps, rest, on); } else if (StrEquals(token, "BorderWidth")) { if (GetIntegerArguments(rest, &rest, val, 1)) { SSET_BORDER_WIDTH(*ps, (short)*val); ps->flags.has_border_width = 1; ps->flag_mask.has_border_width = 1; ps->change_mask.has_border_width = 1; } else { ps->flags.has_border_width = 0; ps->flag_mask.has_border_width = 1; ps->change_mask.has_border_width = 1; } } else if (StrEquals(token, "BackingStore")) { ps->flags.use_backing_store = BACKINGSTORE_ON; ps->flag_mask.use_backing_store = BACKINGSTORE_MASK; ps->change_mask.use_backing_store = BACKINGSTORE_MASK; } else if (StrEquals(token, "BackingStoreOff")) { ps->flags.use_backing_store = BACKINGSTORE_OFF; ps->flag_mask.use_backing_store = BACKINGSTORE_MASK; ps->change_mask.use_backing_store = BACKINGSTORE_MASK; } else if (StrEquals(token, "BackingStoreWindowDefault")) { ps->flags.use_backing_store = BACKINGSTORE_DEFAULT; ps->flag_mask.use_backing_store = BACKINGSTORE_MASK; ps->change_mask.use_backing_store = BACKINGSTORE_MASK; } else if (StrEquals(token, "BorderColorset")) { *val = -1; GetIntegerArguments(rest, &rest, val, 1); SSET_BORDER_COLORSET(*ps, *val); alloc_colorset(*val); ps->flags.use_border_colorset = (*val >= 0); ps->flag_mask.use_border_colorset = 1; ps->change_mask.use_border_colorset = 1; } else if (StrEquals(token, "BottomTitleRotated")) { S_SET_IS_BOTTOM_TITLE_ROTATED(SCF(*ps), on); S_SET_IS_BOTTOM_TITLE_ROTATED(SCM(*ps), 1); S_SET_IS_BOTTOM_TITLE_ROTATED(SCC(*ps), 1); } else if (StrEquals(token, "BottomTitleNotRotated")) { S_SET_IS_BOTTOM_TITLE_ROTATED(SCF(*ps), !on); S_SET_IS_BOTTOM_TITLE_ROTATED(SCM(*ps), 1); S_SET_IS_BOTTOM_TITLE_ROTATED(SCC(*ps), 1); } else if (StrEquals(token, "Borders")) { S_SET_HAS_NO_BORDER(SCF(*ps), !on); S_SET_HAS_NO_BORDER(SCM(*ps), 1); S_SET_HAS_NO_BORDER(SCC(*ps), 1); } else { found = False; } break; case 'c': if (StrEquals(token, "CascadePlacement")) { ps->flags.placement_mode = PLACE_CASCADE; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; } else if (StrEquals(token, "CLEVERPLACEMENT")) { ps->flags.placement_mode |= PLACE_CLEVER; ps->flag_mask.placement_mode |= PLACE_CLEVER; ps->change_mask.placement_mode |= PLACE_CLEVER; } else if (StrEquals(token, "CleverPlacementOff")) { ps->flags.placement_mode &= (~PLACE_CLEVER); ps->flag_mask.placement_mode |= PLACE_CLEVER; ps->change_mask.placement_mode |= PLACE_CLEVER; } else if (StrEquals(token, "CaptureHonorsStartsOnPage")) { ps->flags.capture_honors_starts_on_page = on; ps->flag_mask.capture_honors_starts_on_page = 1; ps->change_mask.capture_honors_starts_on_page = 1; } else if (StrEquals(token, "CaptureIgnoresStartsonPage")) { ps->flags.capture_honors_starts_on_page = !on; ps->flag_mask.capture_honors_starts_on_page = 1; ps->change_mask.capture_honors_starts_on_page = 1; } else if (StrEquals(token, "ColorSet")) { *val = -1; GetIntegerArguments(rest, &rest, val, 1); if (*val < 0) { *val = -1; } SSET_COLORSET(*ps, *val); alloc_colorset(*val); ps->flags.use_colorset = (*val >= 0); ps->flag_mask.use_colorset = 1; ps->change_mask.use_colorset = 1; } else if (StrEquals(token, "Color")) { char c = 0; char *next; next = GetNextToken(rest, &token); if (token == NULL) { fvwm_msg( ERR, "style_parse_one_style_option", "Color Style requires a color" " argument"); break; } if (strncasecmp(token, "rgb:", 4) == 0) { char *s; int i; /* spool to third '/' */ for (i = 0, s = token + 4; *s && i < 3; s++) { if (*s == '/') { i++; } } s--; if (i == 3) { *s = 0; /* spool to third '/' in original * string too */ for (i = 0, s = rest; *s && i < 3; s++) { if (*s == '/') { i++; } } next = s - 1; } } else { free(token); next = DoGetNextToken( rest, &token, NULL, ",/", &c); } rest = next; SAFEFREE(SGET_FORE_COLOR_NAME(*ps)); SSET_FORE_COLOR_NAME(*ps, token); ps->flags.has_color_fore = 1; ps->flag_mask.has_color_fore = 1; ps->change_mask.has_color_fore = 1; ps->flags.use_colorset = 0; ps->flag_mask.use_colorset = 1; ps->change_mask.use_colorset = 1; /* skip over '/' */ if (c != '/') { while (rest && *rest && isspace((unsigned char)*rest) && *rest != ',' && *rest != '/') { rest++; } if (*rest == '/') { rest++; } } rest=GetNextToken(rest, &token); if (!token) { fvwm_msg( ERR, "style_parse_one_style_option", "Color Style called with incomplete" " color argument."); break; } SAFEFREE(SGET_BACK_COLOR_NAME(*ps)); SSET_BACK_COLOR_NAME(*ps, token); ps->flags.has_color_back = 1; ps->flag_mask.has_color_back = 1; ps->change_mask.has_color_back = 1; break; } else if (StrEquals(token, "CirculateSkipIcon")) { S_SET_DO_CIRCULATE_SKIP_ICON(SCF(*ps), on); S_SET_DO_CIRCULATE_SKIP_ICON(SCM(*ps), 1); S_SET_DO_CIRCULATE_SKIP_ICON(SCC(*ps), 1); } else if (StrEquals(token, "CirculateSkipShaded")) { S_SET_DO_CIRCULATE_SKIP_SHADED(SCF(*ps), on); S_SET_DO_CIRCULATE_SKIP_SHADED(SCM(*ps), 1); S_SET_DO_CIRCULATE_SKIP_SHADED(SCC(*ps), 1); } else if (StrEquals(token, "CirculateHitShaded")) { S_SET_DO_CIRCULATE_SKIP_SHADED(SCF(*ps), !on); S_SET_DO_CIRCULATE_SKIP_SHADED(SCM(*ps), 1); S_SET_DO_CIRCULATE_SKIP_SHADED(SCC(*ps), 1); } else if (StrEquals(token, "CirculateHitIcon")) { S_SET_DO_CIRCULATE_SKIP_ICON(SCF(*ps), !on); S_SET_DO_CIRCULATE_SKIP_ICON(SCM(*ps), 1); S_SET_DO_CIRCULATE_SKIP_ICON(SCC(*ps), 1); } else if (StrEquals(token, "ClickToFocus")) { style_set_old_focus_policy(ps, 0); } else if (StrEquals(token, "ClickToFocusPassesClick")) { FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCF(*ps)), on); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCF(*ps)), on); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "ClickToFocusPassesClickOff")) { FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCF(*ps)), !on); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCF(*ps)), !on); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "ClickToFocusRaises")) { FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), on); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), on); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "ClickToFocusRaisesOff")) { FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), !on); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), !on); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "CirculateSkip")) { S_SET_DO_CIRCULATE_SKIP(SCF(*ps), on); S_SET_DO_CIRCULATE_SKIP(SCM(*ps), 1); S_SET_DO_CIRCULATE_SKIP(SCC(*ps), 1); } else if (StrEquals(token, "CirculateHit")) { S_SET_DO_CIRCULATE_SKIP(SCF(*ps), !on); S_SET_DO_CIRCULATE_SKIP(SCM(*ps), 1); S_SET_DO_CIRCULATE_SKIP(SCC(*ps), 1); } else if (StrEquals(token, "Closable")) { S_SET_IS_UNCLOSABLE(SCF(*ps), !on); S_SET_IS_UNCLOSABLE(SCM(*ps), 1); S_SET_IS_UNCLOSABLE(SCC(*ps), 1); } else { found = False; } break; case 'd': if (StrEquals(token, "DepressableBorder")) { S_SET_HAS_DEPRESSABLE_BORDER(SCF(*ps), on); S_SET_HAS_DEPRESSABLE_BORDER(SCM(*ps), 1); S_SET_HAS_DEPRESSABLE_BORDER(SCC(*ps), 1); } else if (StrEquals(token, "DecorateTransient")) { ps->flags.do_decorate_transient = on; ps->flag_mask.do_decorate_transient = 1; ps->change_mask.do_decorate_transient = 1; } else if (StrEquals(token, "DumbPlacement")) { ps->flags.placement_mode &= (~PLACE_SMART); ps->flag_mask.placement_mode |= PLACE_SMART; ps->change_mask.placement_mode |= PLACE_SMART; } else if (StrEquals(token, "DONTRAISETRANSIENT")) { S_SET_DO_RAISE_TRANSIENT(SCF(*ps), !on); S_SET_DO_RAISE_TRANSIENT(SCM(*ps), 1); S_SET_DO_RAISE_TRANSIENT(SCC(*ps), 1); } else if (StrEquals(token, "DONTLOWERTRANSIENT")) { S_SET_DO_LOWER_TRANSIENT(SCF(*ps), !on); S_SET_DO_LOWER_TRANSIENT(SCM(*ps), 1); S_SET_DO_LOWER_TRANSIENT(SCC(*ps), 1); } else if (StrEquals(token, "DontStackTransientParent")) { S_SET_DO_STACK_TRANSIENT_PARENT(SCF(*ps), !on); S_SET_DO_STACK_TRANSIENT_PARENT(SCM(*ps), 1); S_SET_DO_STACK_TRANSIENT_PARENT(SCC(*ps), 1); } else { found = False; } break; case 'e': if (StrEquals(token, "ExactWindowName")) { char *format; /* TA: This is being deprecated in favour of the more * generic: * * TitleFormat %n */ fvwm_msg(WARN, "style_parse_one_style_option", "ExactWindowName is deprecated -- using" " TitleFormat %%n"); format = strdup(DEFAULT_TITLE_FORMAT); SSET_TITLE_FORMAT_STRING(*ps, format); ps->flags.has_title_format_string = 1; ps->flag_mask.has_title_format_string = 1; ps->change_mask.has_title_format_string = 1; } else if (StrEquals(token, "ExactIconName")) { char *format; /* TA: This is being deprecated in favour of the more * generic: * * IconTitleFormat %n */ fvwm_msg(WARN, "style_parse_one_style_option", "ExactIconName is deprecated -- using" " IconTitleFormat %%n"); format = strdup(DEFAULT_TITLE_FORMAT); SSET_ICON_TITLE_FORMAT_STRING(*ps, format); ps->flags.has_icon_title_format_string = 1; ps->flag_mask.has_icon_title_format_string = 1; ps->change_mask.has_icon_title_format_string = 1; } else if (StrEquals(token, "EdgeMoveResistance")) { int num; unsigned has_move; unsigned has_xinerama_move; num = GetIntegerArguments(rest, &rest, val, 2); if (num == 1) { has_move = 1; has_xinerama_move = 0; } else if (num == 2) { has_move = 1; has_xinerama_move = 1; } else { val[0] = 0; val[1] = 0; has_move = 0; has_xinerama_move = 0; } if (val[0] < 0) { val[0] = 0; } if (val[1] < 0) { val[1] = 0; } ps->flags.has_edge_resistance_move = has_move; ps->flag_mask.has_edge_resistance_move = 1; ps->change_mask.has_edge_resistance_move = 1; SSET_EDGE_RESISTANCE_MOVE(*ps, val[0]); ps->flags.has_edge_resistance_xinerama_move = has_xinerama_move; ps->flag_mask.has_edge_resistance_xinerama_move = 1; ps->change_mask.has_edge_resistance_xinerama_move = 1; SSET_EDGE_RESISTANCE_XINERAMA_MOVE(*ps, val[1]); } else if (StrEquals(token, "EdgeMoveDelay")) { if (GetIntegerArguments(rest, &rest, val, 1)) { SSET_EDGE_DELAY_MS_MOVE(*ps, (short)*val); ps->flags.has_edge_delay_ms_move = 1; ps->flag_mask.has_edge_delay_ms_move = 1; ps->change_mask.has_edge_delay_ms_move = 1; } else { ps->flags.has_edge_delay_ms_move = 0; ps->flag_mask.has_edge_delay_ms_move = 1; ps->change_mask.has_edge_delay_ms_move = 1; } } else if (StrEquals(token, "EdgeResizeDelay")) { if (GetIntegerArguments(rest, &rest, val, 1)) { SSET_EDGE_DELAY_MS_RESIZE(*ps, (short)*val); ps->flags.has_edge_delay_ms_resize = 1; ps->flag_mask.has_edge_delay_ms_resize = 1; ps->change_mask.has_edge_delay_ms_resize = 1; } else { ps->flags.has_edge_delay_ms_resize = 0; ps->flag_mask.has_edge_delay_ms_resize = 1; ps->change_mask.has_edge_delay_ms_resize = 1; } } else { found = EWMH_CMD_Style(token, ps, on); } break; case 'f': if (strncasecmp(token, "fp", 2) == 0) { /* parse focus policy options */ found = style_parse_focus_policy_style( token + 2, rest, &rest, (on) ? False : True, &S_FOCUS_POLICY(SCF(*ps)), &S_FOCUS_POLICY(SCM(*ps)), &S_FOCUS_POLICY(SCC(*ps))); } else if (StrEquals(token, "Font")) { SAFEFREE(SGET_WINDOW_FONT(*ps)); rest = GetNextToken(rest, &token); SSET_WINDOW_FONT(*ps, token); S_SET_HAS_WINDOW_FONT(SCF(*ps), (token != NULL)); S_SET_HAS_WINDOW_FONT(SCM(*ps), 1); S_SET_HAS_WINDOW_FONT(SCC(*ps), 1); } else if (StrEquals(token, "ForeColor")) { rest = GetNextToken(rest, &token); if (token) { SAFEFREE(SGET_FORE_COLOR_NAME(*ps)); SSET_FORE_COLOR_NAME(*ps, token); ps->flags.has_color_fore = 1; ps->flag_mask.has_color_fore = 1; ps->change_mask.has_color_fore = 1; ps->flags.use_colorset = 0; ps->flag_mask.use_colorset = 1; ps->change_mask.use_colorset = 1; } else { fvwm_msg( ERR, "style_parse_one_style_option", "ForeColor Style needs color argument" ); } } else if (StrEquals(token, "FVWMBUTTONS")) { S_SET_HAS_MWM_BUTTONS(SCF(*ps), !on); S_SET_HAS_MWM_BUTTONS(SCM(*ps), 1); S_SET_HAS_MWM_BUTTONS(SCC(*ps), 1); } else if (StrEquals(token, "FVWMBORDER")) { S_SET_HAS_MWM_BORDER(SCF(*ps), !on); S_SET_HAS_MWM_BORDER(SCM(*ps), 1); S_SET_HAS_MWM_BORDER(SCC(*ps), 1); } else if (StrEquals(token, "FocusFollowsMouse")) { style_set_old_focus_policy(ps, 1); } else if (StrEquals(token, "FirmBorder")) { S_SET_HAS_DEPRESSABLE_BORDER(SCF(*ps), !on); S_SET_HAS_DEPRESSABLE_BORDER(SCM(*ps), 1); S_SET_HAS_DEPRESSABLE_BORDER(SCC(*ps), 1); } else if (StrEquals(token, "FixedPosition") || StrEquals(token, "FixedUSPosition")) { S_SET_IS_FIXED(SCF(*ps), on); S_SET_IS_FIXED(SCM(*ps), 1); S_SET_IS_FIXED(SCC(*ps), 1); } else if (StrEquals(token, "FixedPPosition")) { S_SET_IS_FIXED_PPOS(SCF(*ps), on); S_SET_IS_FIXED_PPOS(SCM(*ps), 1); S_SET_IS_FIXED_PPOS(SCC(*ps), 1); } else if (StrEquals(token, "FixedSize") || StrEquals(token, "FixedUSSize")) { S_SET_IS_SIZE_FIXED(SCF(*ps), on); S_SET_IS_SIZE_FIXED(SCM(*ps), 1); S_SET_IS_SIZE_FIXED(SCC(*ps), 1); } else if (StrEquals(token, "FixedPSize")) { S_SET_IS_PSIZE_FIXED(SCF(*ps), on); S_SET_IS_PSIZE_FIXED(SCM(*ps), 1); S_SET_IS_PSIZE_FIXED(SCC(*ps), 1); } else { found = False; } break; case 'g': if (StrEquals(token, "GrabFocusOff")) { FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCF(*ps)), !on); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "GrabFocus")) { FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCF(*ps)), on); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "GrabFocusTransientOff")) { FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCF(*ps)), !on); FPS_GRAB_FOCUS_TRANSIENT(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_GRAB_FOCUS_TRANSIENT(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "GrabFocusTransient")) { FPS_GRAB_FOCUS_TRANSIENT(S_FOCUS_POLICY(SCF(*ps)), on); FPS_GRAB_FOCUS_TRANSIENT(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_GRAB_FOCUS_TRANSIENT(S_FOCUS_POLICY(SCC(*ps)), 1); } else { found = False; } break; case 'h': if (StrEquals(token, "HintOverride")) { S_SET_HAS_MWM_OVERRIDE(SCF(*ps), on); S_SET_HAS_MWM_OVERRIDE(SCM(*ps), 1); S_SET_HAS_MWM_OVERRIDE(SCC(*ps), 1); } else if (StrEquals(token, "Handles")) { ps->flags.has_no_handles = !on; ps->flag_mask.has_no_handles = 1; ps->change_mask.has_no_handles = 1; } else if (StrEquals(token, "HandleWidth")) { if (GetIntegerArguments(rest, &rest, val, 1)) { SSET_HANDLE_WIDTH(*ps, (short)*val); ps->flags.has_handle_width = 1; ps->flag_mask.has_handle_width = 1; ps->change_mask.has_handle_width = 1; } else { ps->flags.has_handle_width = 0; ps->flag_mask.has_handle_width = 1; ps->change_mask.has_handle_width = 1; } } else if (StrEquals(token, "HilightFore")) { rest = GetNextToken(rest, &token); if (token) { SAFEFREE(SGET_FORE_COLOR_NAME_HI(*ps)); SSET_FORE_COLOR_NAME_HI(*ps, token); ps->flags.has_color_fore_hi = 1; ps->flag_mask.has_color_fore_hi = 1; ps->change_mask.has_color_fore_hi = 1; ps->flags.use_colorset_hi = 0; ps->flag_mask.use_colorset_hi = 1; ps->change_mask.use_colorset_hi = 1; } else { fvwm_msg( ERR, "style_parse_one_style_option", "HilightFore Style needs color" " argument"); } } else if (StrEquals(token, "HilightBack")) { rest = GetNextToken(rest, &token); if (token) { SAFEFREE(SGET_BACK_COLOR_NAME_HI(*ps)); SSET_BACK_COLOR_NAME_HI(*ps, token); ps->flags.has_color_back_hi = 1; ps->flag_mask.has_color_back_hi = 1; ps->change_mask.has_color_back_hi = 1; ps->flags.use_colorset_hi = 0; ps->flag_mask.use_colorset_hi = 1; ps->change_mask.use_colorset_hi = 1; } else { fvwm_msg( ERR, "style_parse_one_style_option", "HilightBack Style needs color" " argument"); } } else if (StrEquals(token, "HilightColorset")) { *val = -1; GetIntegerArguments(rest, &rest, val, 1); SSET_COLORSET_HI(*ps, *val); alloc_colorset(*val); ps->flags.use_colorset_hi = (*val >= 0); ps->flag_mask.use_colorset_hi = 1; ps->change_mask.use_colorset_hi = 1; } else if (StrEquals(token, "HilightBorderColorset")) { *val = -1; GetIntegerArguments(rest, &rest, val, 1); SSET_BORDER_COLORSET_HI(*ps, *val); alloc_colorset(*val); ps->flags.use_border_colorset_hi = (*val >= 0); ps->flag_mask.use_border_colorset_hi = 1; ps->change_mask.use_border_colorset_hi = 1; } else if (StrEquals(token, "HilightIconTitleColorset")) { *val = -1; GetIntegerArguments(rest, &rest, val, 1); SSET_ICON_TITLE_COLORSET_HI(*ps, *val); alloc_colorset(*val); ps->flags.use_icon_title_colorset_hi = (*val >= 0); ps->flag_mask.use_icon_title_colorset_hi = 1; ps->change_mask.use_icon_title_colorset_hi = 1; } else { found = False; } break; case 'i': if (StrEquals(token, "Icon")) { if (on == 1) { rest = GetNextToken(rest, &token); SAFEFREE(SGET_ICON_NAME(*ps)); SSET_ICON_NAME(*ps,token); ps->flags.has_icon = (token != NULL); ps->flag_mask.has_icon = 1; ps->change_mask.has_icon = 1; S_SET_IS_ICON_SUPPRESSED(SCF(*ps), 0); S_SET_IS_ICON_SUPPRESSED(SCM(*ps), 1); S_SET_IS_ICON_SUPPRESSED(SCC(*ps), 1); } else { S_SET_IS_ICON_SUPPRESSED(SCF(*ps), 1); S_SET_IS_ICON_SUPPRESSED(SCM(*ps), 1); S_SET_IS_ICON_SUPPRESSED(SCC(*ps), 1); } } else if (StrEquals(token, "IconBackgroundColorset")) { *val = -1; GetIntegerArguments(rest, &rest, val, 1); SSET_ICON_BACKGROUND_COLORSET(*ps, *val); alloc_colorset(*val); ps->flags.use_icon_background_colorset = (*val >= 0); ps->flag_mask.use_icon_background_colorset = 1; ps->change_mask.use_icon_background_colorset = 1; } else if (StrEquals(token, "IconBackgroundPadding")) { *val = ICON_BACKGROUND_PADDING; GetIntegerArguments(rest, &rest, val, 1); if (*val < 0) { *val = 0; } else if (*val > 50) { *val = 50; } SSET_ICON_BACKGROUND_PADDING(*ps, (unsigned char)*val); ps->flags.has_icon_background_padding = 1; ps->flag_mask.has_icon_background_padding = 1; ps->change_mask.has_icon_background_padding = 1; } else if (StrEquals(token, "IconBackgroundRelief")) { *val = ICON_RELIEF_WIDTH; GetIntegerArguments(rest, &rest, val, 1); if (*val < -50) { *val = -50; } else if (*val > 50) { *val = 50; } SSET_ICON_BACKGROUND_RELIEF(*ps, (signed char)*val); ps->flags.has_icon_background_relief = 1; ps->flag_mask.has_icon_background_relief = 1; ps->change_mask.has_icon_background_relief = 1; } else if (StrEquals(token, "IconFont")) { SAFEFREE(SGET_ICON_FONT(*ps)); rest = GetNextToken(rest, &token); SSET_ICON_FONT(*ps, token); S_SET_HAS_ICON_FONT(SCF(*ps), (token != NULL)); S_SET_HAS_ICON_FONT(SCM(*ps), 1); S_SET_HAS_ICON_FONT(SCC(*ps), 1); } else if (StrEquals(token, "IconOverride")) { S_SET_ICON_OVERRIDE(SCF(*ps), ICON_OVERRIDE); S_SET_ICON_OVERRIDE(SCM(*ps), ICON_OVERRIDE_MASK); S_SET_ICON_OVERRIDE(SCC(*ps), ICON_OVERRIDE_MASK); } else if (StrEquals(token, "IgnoreRestack")) { S_SET_DO_IGNORE_RESTACK(SCF(*ps), on); S_SET_DO_IGNORE_RESTACK(SCM(*ps), 1); S_SET_DO_IGNORE_RESTACK(SCC(*ps), 1); } else if (StrEquals(token, "IconTitle")) { S_SET_HAS_NO_ICON_TITLE(SCF(*ps), !on); S_SET_HAS_NO_ICON_TITLE(SCM(*ps), 1); S_SET_HAS_NO_ICON_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "IconTitleFormat")) { char *fmt_string = NULL; (rest != NULL) ? fmt_string = strdup(rest) : NULL; rest = NULL; /* Consume the string. */ if (fmt_string == NULL) { fmt_string = DEFAULT_TITLE_FORMAT; } if (!__validate_titleformat_string(fmt_string)) { fvwm_msg(ERR, "style_parse_one_style_option", "TitleFormat string invalid: %s", fmt_string); } SSET_ICON_TITLE_FORMAT_STRING(*ps, fmt_string); ps->flags.has_icon_title_format_string = 1; ps->flag_mask.has_icon_title_format_string = 1; ps->change_mask.has_icon_title_format_string = 1; } else if (StrEquals(token, "IconTitleColorset")) { *val = -1; GetIntegerArguments(rest,&rest, val, 1); SSET_ICON_TITLE_COLORSET(*ps, *val); alloc_colorset(*val); ps->flags.use_icon_title_colorset = (*val >= 0); ps->flag_mask.use_icon_title_colorset = 1; ps->change_mask.use_icon_title_colorset = 1; } else if (StrEquals(token, "IconTitleRelief")) { *val = ICON_RELIEF_WIDTH; GetIntegerArguments(rest, &rest, val, 1); if (*val < -50) { *val = -50; } else if (*val > 50) { *val = 50; } SSET_ICON_TITLE_RELIEF(*ps, (signed char)*val); ps->flags.has_icon_title_relief = 1; ps->flag_mask.has_icon_title_relief = 1; ps->change_mask.has_icon_title_relief = 1; } else if (StrEquals(token, "IconSize")) { rest = style_parse_icon_size_style(token, rest, ps); } else if (StrEquals(token, "IconBox")) { rest = style_parse_icon_box_style(cur_ib, token, rest, ps); } /* end iconbox parameter */ else if (StrEquals(token, "ICONGRID")) { rest = style_parse_icon_grid_style(token, rest, ps, *cur_ib); } else if (StrEquals(token, "ICONFILL")) { rest = style_parse_icon_fill_style(token, rest, ps, *cur_ib); } /* end iconfill */ else if (StrEquals(token, "IconifyWindowGroups")) { S_SET_DO_ICONIFY_WINDOW_GROUPS(SCF(*ps), on); S_SET_DO_ICONIFY_WINDOW_GROUPS(SCM(*ps), 1); S_SET_DO_ICONIFY_WINDOW_GROUPS(SCC(*ps), 1); } else if (StrEquals(token, "IconifyWindowGroupsOff")) { S_SET_DO_ICONIFY_WINDOW_GROUPS(SCF(*ps), !on); S_SET_DO_ICONIFY_WINDOW_GROUPS(SCM(*ps), 1); S_SET_DO_ICONIFY_WINDOW_GROUPS(SCC(*ps), 1); } else if (StrEquals(token, "Iconifiable")) { S_SET_IS_UNICONIFIABLE(SCF(*ps), !on); S_SET_IS_UNICONIFIABLE(SCM(*ps), 1); S_SET_IS_UNICONIFIABLE(SCC(*ps), 1); } else if (StrEquals(token, "IndexedWindowName")) { char *format; /* TA: This is being deprecated in favour of the more * generic: * * TitleFormat %n */ fvwm_msg(WARN, "style_parse_one_style_option", "IndexedWindowName is deprecated. " "Converting to use: TitleFormat %%n (%%t)"); format = strdup( "%n (%t)" ); SSET_TITLE_FORMAT_STRING(*ps, format); ps->flags.has_title_format_string = 1; ps->flag_mask.has_title_format_string = 1; ps->change_mask.has_title_format_string = 1; } else if (StrEquals(token, "IndexedIconName")) { char *format; /* TA: This is being deprecated in favour of the more * generic: * * TitleFormat %n */ fvwm_msg(WARN, "style_parse_one_style_option", "IndexedIconName is deprecated. " "Converting to use: IconTitleFormat %%n (%%t)"); format = strdup( "%n (%t)" ); SSET_ICON_TITLE_FORMAT_STRING(*ps, format); ps->flags.has_icon_title_format_string = 1; ps->flag_mask.has_icon_title_format_string = 1; ps->change_mask.has_icon_title_format_string = 1; } else if (StrEquals(token, "InitialMapCommand")) { char *s; s = (rest != NULL) ? strdup(rest) : NULL; SSET_INITIAL_MAP_COMMAND_STRING(*ps, s); ps->flags.has_initial_map_command_string = on; ps->flag_mask.has_initial_map_command_string = on; ps->change_mask.has_initial_map_command_string = 1; rest = NULL; /* consume the entire string */ } else { found = False; } break; case 'j': if (0) { } else { found = False; } break; case 'k': if (StrEquals(token, "KeepWindowGroupsOnDesk")) { S_SET_DO_USE_WINDOW_GROUP_HINT(SCF(*ps), on); S_SET_DO_USE_WINDOW_GROUP_HINT(SCM(*ps), 1); S_SET_DO_USE_WINDOW_GROUP_HINT(SCC(*ps), 1); } else { found = False; } break; case 'l': if (StrEquals(token, "LeftTitleRotatedCW")) { S_SET_IS_LEFT_TITLE_ROTATED_CW(SCF(*ps), on); S_SET_IS_LEFT_TITLE_ROTATED_CW(SCM(*ps), 1); S_SET_IS_LEFT_TITLE_ROTATED_CW(SCC(*ps), 1); } else if (StrEquals(token, "LeftTitleRotatedCCW")) { S_SET_IS_LEFT_TITLE_ROTATED_CW(SCF(*ps), !on); S_SET_IS_LEFT_TITLE_ROTATED_CW(SCM(*ps), 1); S_SET_IS_LEFT_TITLE_ROTATED_CW(SCC(*ps), 1); } else if (StrEquals(token, "Lenience")) { FPS_LENIENT(S_FOCUS_POLICY(SCF(*ps)), on); FPS_LENIENT(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_LENIENT(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "Layer")) { *val = -1; if (GetIntegerArguments(rest, &rest, val, 1) && *val < 0) { fvwm_msg(ERR, "style_parse_one_style_option", "Layer must be positive or zero."); } if (*val < 0) { SSET_LAYER(*ps, -9); /* mark layer unset */ ps->flags.use_layer = 0; ps->flag_mask.use_layer = 1; ps->change_mask.use_layer = 1; } else { SSET_LAYER(*ps, *val); ps->flags.use_layer = 1; ps->flag_mask.use_layer = 1; ps->change_mask.use_layer = 1; } } else if (StrEquals(token, "LOWERTRANSIENT")) { S_SET_DO_LOWER_TRANSIENT(SCF(*ps), on); S_SET_DO_LOWER_TRANSIENT(SCM(*ps), 1); S_SET_DO_LOWER_TRANSIENT(SCC(*ps), 1); } else { found = False; } break; case 'm': if (StrEquals(token, "ManualPlacement")) { ps->flags.placement_mode = PLACE_MANUAL; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; } else if (StrEquals(token, "ManualPlacementHonorsStartsOnPage")) { ps->flags.manual_placement_honors_starts_on_page = on; ps->flag_mask.manual_placement_honors_starts_on_page = 1; ps->change_mask.manual_placement_honors_starts_on_page = 1; } else if (StrEquals( token, "ManualPlacementIgnoresStartsOnPage")) { ps->flags.manual_placement_honors_starts_on_page = !on; ps->flag_mask.manual_placement_honors_starts_on_page = 1; ps->change_mask.manual_placement_honors_starts_on_page = 1; } else if (StrEquals(token, "Maximizable")) { S_SET_IS_UNMAXIMIZABLE(SCF(*ps), !on); S_SET_IS_UNMAXIMIZABLE(SCM(*ps), 1); S_SET_IS_UNMAXIMIZABLE(SCC(*ps), 1); } else if (StrEquals(token, "MinOverlapPlacement")) { ps->flags.placement_mode = PLACE_MINOVERLAP; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; } else if (StrEquals(token, "MinOverlapPercentPlacement")) { ps->flags.placement_mode = PLACE_MINOVERLAPPERCENT; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; } else if (StrEquals(token, "MinOverlapPlacementPenalties")) { float f[6] = {-1, -1, -1, -1, -1, -1}; Bool bad = False; num = 0; if (on != 0 && rest != NULL) { num = sscanf( rest, "%f %f %f %f %f %f", &f[0], &f[1], &f[2], &f[3], &f[4], &f[5]); for (i=0; i < num; i++) { PeekToken(rest,&rest); if (f[i] < 0) { bad = True; } } } if (bad) { fvwm_msg( ERR, "style_parse_one_style_option", "Bad argument to MinOverlap" "PlacementPenalties: %s", rest); break; } { pl_penalty_struct *p; p = SGET_PLACEMENT_PENALTY_PTR(*ps); *p = default_pl_penalty; } if (num > 0) { (*ps).pl_penalty.normal = f[0]; } if (num > 1) { (*ps).pl_penalty.ontop = f[1]; } if (num > 2) { (*ps).pl_penalty.icon = f[2]; } if (num > 3) { (*ps).pl_penalty.sticky = f[3]; } if (num > 4) { (*ps).pl_penalty.below = f[4]; } if (num > 5) { (*ps).pl_penalty.strut = f[5]; } ps->flags.has_placement_penalty = 1; ps->flag_mask.has_placement_penalty = 1; ps->change_mask.has_placement_penalty = 1; } else if (StrEquals( token, "MinOverlapPercentPlacementPenalties")) { Bool bad = False; num = 0; if (on != 0) { num = GetIntegerArguments(rest, &rest, val, 4); for (i=0; i < num; i++) { if (val[i] < 0) bad = True; } } if (bad) { fvwm_msg( ERR, "style_parse_one_style_option", "Bad argument to MinOverlapPercent" "PlacementPenalties: %s", rest); break; } { pl_percent_penalty_struct *p; p = SGET_PLACEMENT_PERCENTAGE_PENALTY_PTR(*ps); *p = default_pl_percent_penalty; } if (num > 0) { (*ps).pl_percent_penalty.p99 = val[0]; } if (num > 1) { (*ps).pl_percent_penalty.p95 = val[1]; } if (num > 2) { (*ps).pl_percent_penalty.p85 = val[2]; } if (num > 3) { (*ps).pl_percent_penalty.p75 = val[3]; } ps->flags.has_placement_percentage_penalty = 1; ps->flag_mask.has_placement_percentage_penalty = 1; ps->change_mask.has_placement_percentage_penalty = 1; } else if (StrEquals(token, "MwmButtons")) { S_SET_HAS_MWM_BUTTONS(SCF(*ps), on); S_SET_HAS_MWM_BUTTONS(SCM(*ps), 1); S_SET_HAS_MWM_BUTTONS(SCC(*ps), 1); } else if (StrEquals(token, "MiniIcon")) { if (!FMiniIconsSupported) { break; } rest = GetNextToken(rest, &token); if (token) { SAFEFREE(SGET_MINI_ICON_NAME(*ps)); SSET_MINI_ICON_NAME(*ps, token); ps->flags.has_mini_icon = 1; ps->flag_mask.has_mini_icon = 1; ps->change_mask.has_mini_icon = 1; } else { fvwm_msg( ERR, "style_parse_one_style_option", "MiniIcon Style requires an Argument"); } } else if (StrEquals(token, "MwmBorder")) { S_SET_HAS_MWM_BORDER(SCF(*ps), on); S_SET_HAS_MWM_BORDER(SCM(*ps), 1); S_SET_HAS_MWM_BORDER(SCC(*ps), 1); } else if (StrEquals(token, "MwmDecor")) { ps->flags.has_mwm_decor = on; ps->flag_mask.has_mwm_decor = 1; ps->change_mask.has_mwm_decor = 1; } else if (StrEquals(token, "MwmFunctions")) { ps->flags.has_mwm_functions = on; ps->flag_mask.has_mwm_functions = 1; ps->change_mask.has_mwm_functions = 1; } else if (StrEquals(token, "MouseFocus")) { style_set_old_focus_policy(ps, 1); } else if (StrEquals(token, "MouseFocusClickRaises")) { FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), on); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), on); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "MouseFocusClickRaisesOff")) { FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), !on); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_FOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCF(*ps)), !on); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCM(*ps)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK( S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "MinWindowSize")) { int val1; int val2; int val1_unit; int val2_unit; num = GetTwoArguments( rest, &val1, &val2, &val1_unit, &val2_unit); rest = SkipNTokens(rest, num); if (num != 2) { val1 = 0; val2 = 0; } else { val1 = val1 * val1_unit / 100; val2 = val2 * val2_unit / 100; } if (val1 < 0) { val1 = 0; } if (val2 < 0) { val2 = 0; } SSET_MIN_WINDOW_WIDTH(*ps, val1); SSET_MIN_WINDOW_HEIGHT(*ps, val2); ps->flags.has_min_window_size = 1; ps->flag_mask.has_min_window_size = 1; ps->change_mask.has_min_window_size = 1; } else if (StrEquals(token, "MaxWindowSize")) { int val1; int val2; int val1_unit; int val2_unit; num = GetTwoArguments( rest, &val1, &val2, &val1_unit, &val2_unit); rest = SkipNTokens(rest, num); if (num != 2) { val1 = DEFAULT_MAX_MAX_WINDOW_WIDTH; val2 = DEFAULT_MAX_MAX_WINDOW_HEIGHT; } else { val1 = val1 * val1_unit / 100; val2 = val2 * val2_unit / 100; } if (val1 < DEFAULT_MIN_MAX_WINDOW_WIDTH) { val1 = DEFAULT_MIN_MAX_WINDOW_WIDTH; } if (val1 > DEFAULT_MAX_MAX_WINDOW_WIDTH || val1 <= 0) { val1 = DEFAULT_MAX_MAX_WINDOW_WIDTH; } if (val2 < DEFAULT_MIN_MAX_WINDOW_HEIGHT) { val2 = DEFAULT_MIN_MAX_WINDOW_HEIGHT; } if (val2 > DEFAULT_MAX_MAX_WINDOW_HEIGHT || val2 <= 0) { val2 = DEFAULT_MAX_MAX_WINDOW_HEIGHT; } SSET_MAX_WINDOW_WIDTH(*ps, val1); SSET_MAX_WINDOW_HEIGHT(*ps, val2); ps->flags.has_max_window_size = 1; ps->flag_mask.has_max_window_size = 1; ps->change_mask.has_max_window_size = 1; } else if (StrEquals(token, "MoveByProgramMethod")) { int i; char *methodlist[] = { "AutoDetect", "UseGravity", "IgnoreGravity", NULL }; i = GetTokenIndex(rest, methodlist, 0, &rest); if (i == -1) { i = WS_CR_MOTION_METHOD_AUTO; } SCR_MOTION_METHOD(&ps->flags) = i; SCR_MOTION_METHOD(&ps->flag_mask) = WS_CR_MOTION_METHOD_MASK; SCR_MOTION_METHOD(&ps->change_mask) = WS_CR_MOTION_METHOD_MASK; } else { found = False; } break; case 'n': if (StrEquals(token, "NoActiveIconOverride")) { S_SET_ICON_OVERRIDE(SCF(*ps), NO_ACTIVE_ICON_OVERRIDE); S_SET_ICON_OVERRIDE(SCM(*ps), ICON_OVERRIDE_MASK); S_SET_ICON_OVERRIDE(SCC(*ps), ICON_OVERRIDE_MASK); } else if (StrEquals(token, "NoIconOverride")) { S_SET_ICON_OVERRIDE(SCF(*ps), NO_ICON_OVERRIDE); S_SET_ICON_OVERRIDE(SCM(*ps), ICON_OVERRIDE_MASK); S_SET_ICON_OVERRIDE(SCC(*ps), ICON_OVERRIDE_MASK); } else if (StrEquals(token, "NoIconTitle")) { S_SET_HAS_NO_ICON_TITLE(SCF(*ps), on); S_SET_HAS_NO_ICON_TITLE(SCM(*ps), 1); S_SET_HAS_NO_ICON_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "NOICON")) { S_SET_IS_ICON_SUPPRESSED(SCF(*ps), on); S_SET_IS_ICON_SUPPRESSED(SCM(*ps), 1); S_SET_IS_ICON_SUPPRESSED(SCC(*ps), 1); } else if (StrEquals(token, "NOTITLE")) { ps->flags.has_no_title = on; ps->flag_mask.has_no_title = 1; ps->change_mask.has_no_title = 1; } else if (StrEquals(token, "NoPPosition")) { ps->flags.use_no_pposition = on; ps->flag_mask.use_no_pposition = 1; ps->change_mask.use_no_pposition = 1; } else if (StrEquals(token, "NoUSPosition")) { ps->flags.use_no_usposition = on; ps->flag_mask.use_no_usposition = 1; ps->change_mask.use_no_usposition = 1; } else if (StrEquals(token, "NoTransientPPosition")) { ps->flags.use_no_transient_pposition = on; ps->flag_mask.use_no_transient_pposition = 1; ps->change_mask.use_no_transient_pposition = 1; } else if (StrEquals(token, "NoTransientUSPosition")) { ps->flags.use_no_transient_usposition = on; ps->flag_mask.use_no_transient_usposition = 1; ps->change_mask.use_no_transient_usposition = 1; } else if (StrEquals(token, "NoIconPosition")) { S_SET_USE_ICON_POSITION_HINT(SCF(*ps), !on); S_SET_USE_ICON_POSITION_HINT(SCM(*ps), 1); S_SET_USE_ICON_POSITION_HINT(SCC(*ps), 1); } else if (StrEquals(token, "NakedTransient")) { ps->flags.do_decorate_transient = !on; ps->flag_mask.do_decorate_transient = 1; ps->change_mask.do_decorate_transient = 1; } else if (StrEquals(token, "NODECORHINT")) { ps->flags.has_mwm_decor = !on; ps->flag_mask.has_mwm_decor = 1; ps->change_mask.has_mwm_decor = 1; } else if (StrEquals(token, "NOFUNCHINT")) { ps->flags.has_mwm_functions = !on; ps->flag_mask.has_mwm_functions = 1; ps->change_mask.has_mwm_functions = 1; } else if (StrEquals(token, "NOOVERRIDE")) { S_SET_HAS_MWM_OVERRIDE(SCF(*ps), !on); S_SET_HAS_MWM_OVERRIDE(SCM(*ps), 1); S_SET_HAS_MWM_OVERRIDE(SCC(*ps), 1); } else if (StrEquals(token, "NORESIZEOVERRIDE") || StrEquals(token, "NORESIZEHINTOVERRIDE")) { S_SET_HAS_OVERRIDE_SIZE(SCF(*ps), !on); S_SET_HAS_OVERRIDE_SIZE(SCM(*ps), 1); S_SET_HAS_OVERRIDE_SIZE(SCC(*ps), 1); } else if (StrEquals(token, "NOHANDLES")) { ps->flags.has_no_handles = on; ps->flag_mask.has_no_handles = 1; ps->change_mask.has_no_handles = 1; } else if (StrEquals(token, "NOLENIENCE")) { FPS_LENIENT(S_FOCUS_POLICY(SCF(*ps)), !on); FPS_LENIENT(S_FOCUS_POLICY(SCM(*ps)), 1); FPS_LENIENT(S_FOCUS_POLICY(SCC(*ps)), 1); } else if (StrEquals(token, "NoButton")) { rest = style_parse_button_style(ps, rest, !on); } else if (StrEquals(token, "NOOLDECOR")) { ps->flags.has_ol_decor = !on; ps->flag_mask.has_ol_decor = 1; ps->change_mask.has_ol_decor = 1; } else if (StrEquals(token, "NeverFocus")) { style_set_old_focus_policy(ps, 3); } else { found = False; } break; case 'o': if (StrEquals(token, "OLDECOR")) { ps->flags.has_ol_decor = on; ps->flag_mask.has_ol_decor = 1; ps->change_mask.has_ol_decor = 1; } else if (StrEquals(token, "Opacity")) { ps->flags.use_parent_relative = !on; ps->flag_mask.use_parent_relative = 1; ps->change_mask.use_parent_relative = 1; } else { found = False; } break; case 'p': if (StrEquals(token, "PositionPlacement")) { char *s; ps->flags.placement_mode = PLACE_POSITION; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; s = (rest != NULL) ? strdup(rest) : NULL; rest = NULL; /* consume the entire string */ SSET_PLACEMENT_POSITION_STRING(*ps, s); ps->flags.has_placement_position_string = 1; ps->flag_mask.has_placement_position_string = 1; ps->change_mask.has_placement_position_string = 1; } else if (StrEquals(token, "ParentalRelativity")) { ps->flags.use_parent_relative = on; ps->flag_mask.use_parent_relative = 1; ps->change_mask.use_parent_relative = 1; } else { found = False; } break; case 'q': if (0) { } else { found = False; } break; case 'r': if (StrEquals(token, "RAISETRANSIENT")) { S_SET_DO_RAISE_TRANSIENT(SCF(*ps), on); S_SET_DO_RAISE_TRANSIENT(SCM(*ps), 1); S_SET_DO_RAISE_TRANSIENT(SCC(*ps), 1); } else if (StrEquals(token, "RANDOMPLACEMENT")) { ps->flags.placement_mode |= PLACE_RANDOM; ps->flag_mask.placement_mode |= PLACE_RANDOM; ps->change_mask.placement_mode |= PLACE_RANDOM; } else if (StrEquals(token, "RECAPTUREHONORSSTARTSONPAGE")) { ps->flags.recapture_honors_starts_on_page = on; ps->flag_mask.recapture_honors_starts_on_page = 1; ps->change_mask.recapture_honors_starts_on_page = 1; } else if (StrEquals(token, "RECAPTUREIGNORESSTARTSONPAGE")) { ps->flags.recapture_honors_starts_on_page = !on; ps->flag_mask.recapture_honors_starts_on_page = 1; ps->change_mask.recapture_honors_starts_on_page = 1; } else if (StrEquals(token, "RESIZEHINTOVERRIDE")) { S_SET_HAS_OVERRIDE_SIZE(SCF(*ps), on); S_SET_HAS_OVERRIDE_SIZE(SCM(*ps), 1); S_SET_HAS_OVERRIDE_SIZE(SCC(*ps), 1); } else if (StrEquals(token, "ResizeOpaque")) { S_SET_DO_RESIZE_OPAQUE(SCF(*ps), on); S_SET_DO_RESIZE_OPAQUE(SCM(*ps), 1); S_SET_DO_RESIZE_OPAQUE(SCC(*ps), 1); } else if (StrEquals(token, "ResizeOutline")) { S_SET_DO_RESIZE_OPAQUE(SCF(*ps), !on); S_SET_DO_RESIZE_OPAQUE(SCM(*ps), 1); S_SET_DO_RESIZE_OPAQUE(SCC(*ps), 1); } else if (StrEquals(token, "RightTitleRotatedCW")) { S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCF(*ps), on); S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCM(*ps), 1); S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCC(*ps), 1); } else if (StrEquals(token, "RightTitleRotatedCCW")) { S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCF(*ps), !on); S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCM(*ps), 1); S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCC(*ps), 1); } else { found = False; } break; case 's': if (StrEquals(token, "SMARTPLACEMENT")) { ps->flags.placement_mode |= PLACE_SMART; ps->flag_mask.placement_mode |= PLACE_SMART; ps->change_mask.placement_mode |= PLACE_SMART; } else if (StrEquals(token, "SkipMapping")) { S_SET_DO_NOT_SHOW_ON_MAP(SCF(*ps), on); S_SET_DO_NOT_SHOW_ON_MAP(SCM(*ps), 1); S_SET_DO_NOT_SHOW_ON_MAP(SCC(*ps), 1); } else if (StrEquals(token, "ShowMapping")) { S_SET_DO_NOT_SHOW_ON_MAP(SCF(*ps), !on); S_SET_DO_NOT_SHOW_ON_MAP(SCM(*ps), 1); S_SET_DO_NOT_SHOW_ON_MAP(SCC(*ps), 1); } else if (StrEquals(token, "StackTransientParent")) { S_SET_DO_STACK_TRANSIENT_PARENT(SCF(*ps), on); S_SET_DO_STACK_TRANSIENT_PARENT(SCM(*ps), 1); S_SET_DO_STACK_TRANSIENT_PARENT(SCC(*ps), 1); } else if (StrEquals(token, "StickyIcon")) { S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCF(*ps), on); S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCM(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCC(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCF(*ps), on); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCM(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCC(*ps), 1); } else if (StrEquals(token, "StickyAcrossPagesIcon")) { S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCF(*ps), on); S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCM(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCC(*ps), 1); } else if (StrEquals(token, "StickyAcrossDesksIcon")) { S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCF(*ps), on); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCM(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCC(*ps), 1); } else if (StrEquals(token, "SlipperyIcon")) { S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCF(*ps), !on); S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCM(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_PAGES(SCC(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCF(*ps), !on); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCM(*ps), 1); S_SET_IS_ICON_STICKY_ACROSS_DESKS(SCC(*ps), 1); } else if (StrEquals(token, "SloppyFocus")) { style_set_old_focus_policy(ps, 2); } else if (StrEquals(token, "StartIconic")) { ps->flags.do_start_iconic = on; ps->flag_mask.do_start_iconic = 1; ps->change_mask.do_start_iconic = 1; } else if (StrEquals(token, "StartNormal")) { ps->flags.do_start_iconic = !on; ps->flag_mask.do_start_iconic = 1; ps->change_mask.do_start_iconic = 1; } else if (StrEquals(token, "StaysOnBottom")) { SSET_LAYER( *ps, (on) ? Scr.BottomLayer : Scr.DefaultLayer); ps->flags.use_layer = 1; ps->flag_mask.use_layer = 1; ps->change_mask.use_layer = 1; } else if (StrEquals(token, "StaysOnTop")) { SSET_LAYER( *ps, (on) ? Scr.BottomLayer : Scr.DefaultLayer); SSET_LAYER(*ps, Scr.TopLayer); ps->flags.use_layer = 1; ps->flag_mask.use_layer = 1; ps->change_mask.use_layer = 1; } else if (StrEquals(token, "StaysPut")) { SSET_LAYER(*ps, Scr.DefaultLayer); ps->flags.use_layer = 1; ps->flag_mask.use_layer = 1; ps->change_mask.use_layer = 1; } else if (StrEquals(token, "Sticky")) { S_SET_IS_STICKY_ACROSS_PAGES(SCF(*ps), on); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*ps), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*ps), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*ps), on); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*ps), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*ps), 1); } else if (StrEquals(token, "StickyAcrossPages")) { S_SET_IS_STICKY_ACROSS_PAGES(SCF(*ps), on); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*ps), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*ps), 1); } else if (StrEquals(token, "StickyAcrossDesks")) { S_SET_IS_STICKY_ACROSS_DESKS(SCF(*ps), on); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*ps), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*ps), 1); } else if (StrEquals(token, "StickyStippledTitle")) { S_SET_HAS_NO_STICKY_STIPPLED_TITLE(SCF(*ps), !on); S_SET_HAS_NO_STICKY_STIPPLED_TITLE(SCM(*ps), 1); S_SET_HAS_NO_STICKY_STIPPLED_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "StickyStippledIconTitle")) { S_SET_HAS_NO_STICKY_STIPPLED_ICON_TITLE(SCF(*ps), !on); S_SET_HAS_NO_STICKY_STIPPLED_ICON_TITLE(SCM(*ps), 1); S_SET_HAS_NO_STICKY_STIPPLED_ICON_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "Slippery")) { S_SET_IS_STICKY_ACROSS_PAGES(SCF(*ps), !on); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*ps), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*ps), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*ps), !on); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*ps), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*ps), 1); } else if (StrEquals(token, "STARTSONDESK")) { spargs = GetIntegerArguments(rest, NULL, tmpno, 1); if (spargs == 1) { PeekToken(rest,&rest); ps->flags.use_start_on_desk = 1; ps->flag_mask.use_start_on_desk = 1; ps->change_mask.use_start_on_desk = 1; /* RBW - 11/20/1998 - allow for the special * case of -1 */ SSET_START_DESK( *ps, (tmpno[0] > -1) ? tmpno[0] + 1 : tmpno[0]); } else { fvwm_msg(ERR,"style_parse_one_style_option", "bad StartsOnDesk arg: %s", rest); } } /* StartsOnPage is like StartsOnDesk-Plus */ else if (StrEquals(token, "STARTSONPAGE")) { char *ret_rest; spargs = GetIntegerArguments(rest, &ret_rest, tmpno, 3); if (spargs == 1 || spargs == 3) { /* We have a desk no., with or without page. */ /* RBW - 11/20/1998 - allow for the special * case of -1 */ /* Desk is now actual + 1 */ SSET_START_DESK( *ps, (tmpno[0] > -1) ? tmpno[0] + 1 : tmpno[0]); } if (spargs == 2 || spargs == 3) { if (spargs == 3) { /* RBW - 11/20/1998 - allow for the * special case of -1 */ SSET_START_PAGE_X( *ps, (tmpno[1] > -1) ? tmpno[1] + 1 : tmpno[1]); SSET_START_PAGE_Y( *ps, (tmpno[2] > -1) ? tmpno[2] + 1 : tmpno[2]); } else { SSET_START_PAGE_X( *ps, (tmpno[0] > -1) ? tmpno[0] + 1 : tmpno[0]); SSET_START_PAGE_Y( *ps, (tmpno[1] > -1) ? tmpno[1] + 1 : tmpno[1]); } } if (spargs < 1 || spargs > 3) { fvwm_msg(ERR, "style_parse_one_style_option", "bad StartsOnPage args: %s", rest); } else { ps->flags.use_start_on_desk = 1; ps->flag_mask.use_start_on_desk = 1; ps->change_mask.use_start_on_desk = 1; } rest = ret_rest; } else if (StrEquals(token, "STARTSONPAGEINCLUDESTRANSIENTS")) { ps->flags.use_start_on_page_for_transient = on; ps->flag_mask.use_start_on_page_for_transient = 1; ps->change_mask.use_start_on_page_for_transient = 1; } else if (StrEquals(token, "STARTSONPAGEIGNORESTRANSIENTS")) { ps->flags.use_start_on_page_for_transient = !on; ps->flag_mask.use_start_on_page_for_transient = 1; ps->change_mask.use_start_on_page_for_transient = 1; } else if (StrEquals(token, "StartsOnScreen")) { if (rest) { tmpno[0] = FScreenGetScreenArgument(rest, 'c'); PeekToken(rest,&rest); ps->flags.use_start_on_screen = 1; ps->flag_mask.use_start_on_screen = 1; ps->change_mask.use_start_on_screen = 1; SSET_START_SCREEN(*ps, tmpno[0]); } else { ps->flags.use_start_on_screen = 0; ps->flag_mask.use_start_on_screen = 1; ps->change_mask.use_start_on_screen = 1; } } else if (StrEquals(token, "STARTSANYWHERE")) { ps->flags.use_start_on_desk = 0; ps->flag_mask.use_start_on_desk = 1; ps->change_mask.use_start_on_desk = 1; } else if (StrEquals(token, "STARTSLOWERED")) { ps->flags.do_start_lowered = on; ps->flag_mask.do_start_lowered = 1; ps->change_mask.do_start_lowered = 1; } else if (StrEquals(token, "STARTSRAISED")) { ps->flags.do_start_lowered = !on; ps->flag_mask.do_start_lowered = 1; ps->change_mask.do_start_lowered = 1; } else if (StrEquals(token, "StartShaded")) { token = PeekToken(rest, &rest); if (token) { direction_t direction; direction = gravity_parse_dir_argument( token, &token, DIR_NONE); if (direction >= 0 && direction <= DIR_MASK) { SSET_STARTS_SHADED_DIR(*ps, direction); } else { fvwm_msg( ERR, "style_parse_one_style_option", "Option: %s is not valid with" " StartShaded", token); } } else { SSET_STARTS_SHADED_DIR(*ps, DIR_N); } ps->flags.do_start_shaded = on; ps->flag_mask.do_start_shaded = 1; ps->change_mask.do_start_shaded = 1; } else if (StrEquals(token, "SaveUnder")) { ps->flags.do_save_under = on; ps->flag_mask.do_save_under = 1; ps->change_mask.do_save_under = 1; } else if (StrEquals(token, "SaveUnderOff")) { ps->flags.do_save_under = !on; ps->flag_mask.do_save_under = 1; ps->change_mask.do_save_under = 1; } else if (StrEquals(token, "StippledTitle")) { S_SET_HAS_STIPPLED_TITLE(SCF(*ps), on); S_SET_HAS_STIPPLED_TITLE(SCM(*ps), 1); S_SET_HAS_STIPPLED_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "StippledTitleOff")) { S_SET_HAS_STIPPLED_TITLE(SCF(*ps), !on); S_SET_HAS_STIPPLED_TITLE(SCM(*ps), 1); S_SET_HAS_STIPPLED_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "StippledIconTitle")) { S_SET_HAS_STIPPLED_ICON_TITLE(SCF(*ps), on); S_SET_HAS_STIPPLED_ICON_TITLE(SCM(*ps), 1); S_SET_HAS_STIPPLED_ICON_TITLE(SCC(*ps), 1); } else if (StrEquals(token, "ScatterWindowGroups")) { S_SET_DO_USE_WINDOW_GROUP_HINT(SCF(*ps), !on); S_SET_DO_USE_WINDOW_GROUP_HINT(SCM(*ps), 1); S_SET_DO_USE_WINDOW_GROUP_HINT(SCC(*ps), 1); } else if (StrEquals(token, "State")) { unsigned int mask; unsigned int states; spargs = GetIntegerArguments(rest, NULL, tmpno, 1); if (spargs == 1 && tmpno[0] >= 0 && tmpno[0] <= 31) { PeekToken(rest,&rest); states = S_USER_STATES(SCF(*ps)); mask = (1 << tmpno[0]); if (on) { states |= mask; } else { states &= ~mask; } S_SET_USER_STATES(SCF(*ps), states); S_ADD_USER_STATES(SCM(*ps), mask); S_ADD_USER_STATES(SCC(*ps), mask); } else { fvwm_msg( ERR,"style_parse_one_style_option", "bad State arg: %s", rest); } } else if (StrEquals(token, "SnapAttraction")) { int val; char *token; int snap_proximity; int snap_mode; do { snap_proximity = DEFAULT_SNAP_ATTRACTION; snap_mode = DEFAULT_SNAP_ATTRACTION_MODE; if ( GetIntegerArguments( rest, &rest, &val, 1) != 1) { break; } if (val >= 0) { snap_proximity = val; } if (val == 0) { break; } token = PeekToken(rest, &rest); if (token == NULL) { break; } if (StrEquals(token, "All")) { snap_mode = SNAP_ICONS | SNAP_WINDOWS; token = PeekToken(rest, &rest); } else if (StrEquals(token, "None")) { snap_mode = SNAP_NONE; token = PeekToken(rest, &rest); } else if (StrEquals(token, "SameType")) { snap_mode = SNAP_SAME; token = PeekToken(rest, &rest); } else if (StrEquals(token, "Icons")) { snap_mode = SNAP_ICONS; token = PeekToken(rest, &rest); } else if (StrEquals(token, "Windows")) { snap_mode = SNAP_WINDOWS; token = PeekToken(rest, &rest); } if (token == NULL) { break; } if (StrEquals(token, "Screen")) { snap_mode |= SNAP_SCREEN; } else if (StrEquals(token, "ScreenWindows")) { snap_mode |= SNAP_SCREEN_WINDOWS; } else if (StrEquals(token, "ScreenIcons")) { snap_mode |= SNAP_SCREEN_ICONS; } else if (StrEquals(token, "ScreenAll")) { snap_mode |= SNAP_SCREEN_ALL; } } while (0); ps->flags.has_snap_attraction = 1; ps->flag_mask.has_snap_attraction = 1; ps->change_mask.has_snap_attraction = 1; SSET_SNAP_PROXIMITY(*ps, snap_proximity); SSET_SNAP_MODE(*ps, snap_mode); } else if (StrEquals(token, "SnapGrid")) { int num; num = GetIntegerArguments(rest, &rest, val, 2); if (num != 2) { val[0] = DEFAULT_SNAP_GRID_X; val[1] = DEFAULT_SNAP_GRID_Y; } if (val[0] < 0) { val[0] = DEFAULT_SNAP_GRID_X; } if (val[1] < 0) { val[1] = DEFAULT_SNAP_GRID_Y; } ps->flags.has_snap_grid = 1; ps->flag_mask.has_snap_grid = 1; ps->change_mask.has_snap_grid = 1; SSET_SNAP_GRID_X(*ps, val[0]); SSET_SNAP_GRID_Y(*ps, val[1]); } else { found = False; } break; case 't': if (StrEquals(token, "TileCascadePlacement")) { ps->flags.placement_mode = PLACE_TILECASCADE; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; } else if (StrEquals(token, "TileManualPlacement")) { ps->flags.placement_mode = PLACE_TILEMANUAL; ps->flag_mask.placement_mode = PLACE_MASK; ps->change_mask.placement_mode = PLACE_MASK; } else if (StrEquals(token, "Title")) { ps->flags.has_no_title = !on; ps->flag_mask.has_no_title = 1; ps->change_mask.has_no_title = 1; } else if (StrEquals(token, "TitleAtBottom")) { S_SET_TITLE_DIR(SCF(*ps), DIR_S); S_SET_TITLE_DIR(SCM(*ps), DIR_MAJOR_MASK); S_SET_TITLE_DIR(SCC(*ps), DIR_MAJOR_MASK); } else if (StrEquals(token, "TitleAtTop")) { S_SET_TITLE_DIR(SCF(*ps), DIR_N); S_SET_TITLE_DIR(SCM(*ps), DIR_MAJOR_MASK); S_SET_TITLE_DIR(SCC(*ps), DIR_MAJOR_MASK); } else if (StrEquals(token, "TitleAtLeft")) { S_SET_TITLE_DIR(SCF(*ps), DIR_W); S_SET_TITLE_DIR(SCM(*ps), DIR_MAJOR_MASK); S_SET_TITLE_DIR(SCC(*ps), DIR_MAJOR_MASK); } else if (StrEquals(token, "TitleAtRight")) { S_SET_TITLE_DIR(SCF(*ps), DIR_E); S_SET_TITLE_DIR(SCM(*ps), DIR_MAJOR_MASK); S_SET_TITLE_DIR(SCC(*ps), DIR_MAJOR_MASK); } else if (StrEquals(token, "TitleFormat")) { char *fmt_string = NULL; (rest != NULL) ? fmt_string = strdup(rest) : NULL; rest = NULL; /* Consume the string. */ if (fmt_string == NULL) { fmt_string = DEFAULT_TITLE_FORMAT; } if (!__validate_titleformat_string(fmt_string)) { fvwm_msg(ERR, "style_parse_one_style_option", "TitleFormat string invalid: %s", fmt_string); } SSET_TITLE_FORMAT_STRING(*ps, fmt_string); ps->flags.has_title_format_string = 1; ps->flag_mask.has_title_format_string = 1; ps->change_mask.has_title_format_string = 1; } else if (StrEquals(token, "TopTitleRotated")) { S_SET_IS_TOP_TITLE_ROTATED(SCF(*ps), on); S_SET_IS_TOP_TITLE_ROTATED(SCM(*ps), 1); S_SET_IS_TOP_TITLE_ROTATED(SCC(*ps), 1); } else if (StrEquals(token, "TopTitleNotRotated")) { S_SET_IS_TOP_TITLE_ROTATED(SCF(*ps), !on); S_SET_IS_TOP_TITLE_ROTATED(SCM(*ps), 1); S_SET_IS_TOP_TITLE_ROTATED(SCC(*ps), 1); } else { found = False; } break; case 'u': if (StrEquals(token, "UsePPosition")) { ps->flags.use_no_pposition = !on; ps->flag_mask.use_no_pposition = 1; ps->change_mask.use_no_pposition = 1; } else if (StrEquals(token, "UseUSPosition")) { ps->flags.use_no_usposition = !on; ps->flag_mask.use_no_usposition = 1; ps->change_mask.use_no_usposition = 1; } else if (StrEquals(token, "UseTransientPPosition")) { ps->flags.use_no_transient_pposition = !on; ps->flag_mask.use_no_transient_pposition = 1; ps->change_mask.use_no_transient_pposition = 1; } else if (StrEquals(token, "UseTransientUSPosition")) { ps->flags.use_no_transient_usposition = !on; ps->flag_mask.use_no_transient_usposition = 1; ps->change_mask.use_no_transient_usposition = 1; } else if (StrEquals(token, "UseIconPosition")) { S_SET_USE_ICON_POSITION_HINT(SCF(*ps), on); S_SET_USE_ICON_POSITION_HINT(SCM(*ps), 1); S_SET_USE_ICON_POSITION_HINT(SCC(*ps), 1); } else if (StrEquals(token, "UseTitleDecorRotation")) { S_SET_USE_TITLE_DECOR_ROTATION(SCF(*ps), on); S_SET_USE_TITLE_DECOR_ROTATION(SCM(*ps), 1); S_SET_USE_TITLE_DECOR_ROTATION(SCC(*ps), 1); } else if (StrEquals(token, "UseDecor")) { SAFEFREE(SGET_DECOR_NAME(*ps)); rest = GetNextToken(rest, &token); SSET_DECOR_NAME(*ps, token); ps->flags.has_decor = (token != NULL); ps->flag_mask.has_decor = 1; ps->change_mask.has_decor = 1; } else if (StrEquals(token, "UseStyle")) { int hit; token = PeekToken(rest, &rest); if (!token) { fvwm_msg(ERR, "style_parse_one_style_option", "UseStyle needs an argument"); break; } hit = 0; /* changed to accum multiple Style definitions * (veliaa@rpi.edu) */ for (add_style = all_styles; add_style; add_style = SGET_NEXT_STYLE(*add_style)) { if (SGET_ID_HAS_NAME(*add_style) && StrEquals(token, SGET_NAME(*add_style))) { /* match style */ hit = 1; merge_styles(ps, add_style, True); } /* end found matching style */ } /* end looking at all styles */ /* move forward one word */ if (!hit) { fvwm_msg( ERR, "style_parse_one_style_option", "UseStyle: %s style not found", token); } } else if (StrEquals(token, "Unmanaged")) { ps->flags.is_unmanaged = on; ps->flag_mask.is_unmanaged = 1; ps->change_mask.is_unmanaged = 1; } else { found = False; } break; case 'v': if (StrEquals(token, "VariablePosition") || StrEquals(token, "VariableUSPosition")) { S_SET_IS_FIXED(SCF(*ps), !on); S_SET_IS_FIXED(SCM(*ps), 1); S_SET_IS_FIXED(SCC(*ps), 1); } else if (StrEquals(token, "VariablePPosition")) { S_SET_IS_FIXED_PPOS(SCF(*ps), !on); S_SET_IS_FIXED_PPOS(SCM(*ps), 1); S_SET_IS_FIXED_PPOS(SCC(*ps), 1); } else if (StrEquals(token, "VariableSize") || StrEquals(token, "VariableUSSize")) { S_SET_IS_SIZE_FIXED(SCF(*ps), !on); S_SET_IS_SIZE_FIXED(SCM(*ps), 1); S_SET_IS_SIZE_FIXED(SCC(*ps), 1); } else if (StrEquals(token, "VariablePSize")) { S_SET_IS_PSIZE_FIXED(SCF(*ps), !on); S_SET_IS_PSIZE_FIXED(SCM(*ps), 1); S_SET_IS_PSIZE_FIXED(SCC(*ps), 1); } else { found = False; } break; case 'w': if (StrEquals(token, "WindowListSkip")) { S_SET_DO_WINDOW_LIST_SKIP(SCF(*ps), on); S_SET_DO_WINDOW_LIST_SKIP(SCM(*ps), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*ps), 1); } else if (StrEquals(token, "WindowListHit")) { S_SET_DO_WINDOW_LIST_SKIP(SCF(*ps), !on); S_SET_DO_WINDOW_LIST_SKIP(SCM(*ps), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*ps), 1); } else if (StrEquals(token, "WindowShadeSteps")) { int n = 0; int val = 0; int unit = 0; n = GetOnePercentArgument(rest, &val, &unit); if (n != 1) { val = 0; } else { PeekToken(rest,&rest); } /* we have a 'pixel' suffix if unit != 0; negative * values mean pixels */ val = (unit != 0) ? -val : val; ps->flags.has_window_shade_steps = 1; ps->flag_mask.has_window_shade_steps = 1; ps->change_mask.has_window_shade_steps = 1; SSET_WINDOW_SHADE_STEPS(*ps, val); } else if (StrEquals(token, "WindowShadeScrolls")) { S_SET_DO_SHRINK_WINDOWSHADE(SCF(*ps), !on); S_SET_DO_SHRINK_WINDOWSHADE(SCM(*ps), 1); S_SET_DO_SHRINK_WINDOWSHADE(SCC(*ps), 1); } else if (StrEquals(token, "WindowShadeShrinks")) { S_SET_DO_SHRINK_WINDOWSHADE(SCF(*ps), on); S_SET_DO_SHRINK_WINDOWSHADE(SCM(*ps), 1); S_SET_DO_SHRINK_WINDOWSHADE(SCC(*ps), 1); } else if (StrEquals(token, "WindowShadeLazy")) { S_SET_WINDOWSHADE_LAZINESS(SCF(*ps), WINDOWSHADE_LAZY); S_SET_WINDOWSHADE_LAZINESS( SCM(*ps), WINDOWSHADE_LAZY_MASK); S_SET_WINDOWSHADE_LAZINESS( SCC(*ps), WINDOWSHADE_LAZY_MASK); } else if (StrEquals(token, "WindowShadeAlwaysLazy")) { S_SET_WINDOWSHADE_LAZINESS( SCF(*ps), WINDOWSHADE_ALWAYS_LAZY); S_SET_WINDOWSHADE_LAZINESS( SCM(*ps), WINDOWSHADE_LAZY_MASK); S_SET_WINDOWSHADE_LAZINESS( SCC(*ps), WINDOWSHADE_LAZY_MASK); } else if (StrEquals(token, "WindowShadeBusy")) { S_SET_WINDOWSHADE_LAZINESS(SCF(*ps), WINDOWSHADE_BUSY); S_SET_WINDOWSHADE_LAZINESS( SCM(*ps), WINDOWSHADE_LAZY_MASK); S_SET_WINDOWSHADE_LAZINESS( SCC(*ps), WINDOWSHADE_LAZY_MASK); } else { found = False; } break; case 'x': case 'y': case 'z': if (0) { } else { found = False; } break; default: found = False; break; } if (ret_rest) { *ret_rest = rest; } if (token_l != NULL) { free(token_l); } return found; } static void parse_and_set_window_style(char *action, char *prefix, window_style *ps) { char *option; char *token; char *rest; Bool found; /* which current boxes to chain to */ icon_boxes *cur_ib = NULL; while (isspace((unsigned char)*action)) { action++; } while (action && *action && *action != '\n') { action = GetNextFullOption(action, &option); if (!option) { break; } token = PeekToken(option, &rest); if (!token) { free(option); break; } /* It might make more sense to capture the whole word, fix its * case, and use strcmp, but there aren't many caseless compares * because of this "switch" on the first letter. */ found = style_parse_one_style_option( token, rest, &rest, prefix, ps, &cur_ib); if (found == False) { fvwm_msg( ERR, "style_parse_and_set_window_style", "Bad style option: %s", option); /* Can't return here since all malloced memory will be * lost. Ignore rest of line instead. */ /* No, I think we /can/ return here. In fact, /not/ * bombing out leaves a half-done style in the list! * N.Bird 07-Sep-1999 */ /* domivogt (01-Oct-1999): Which is exactly what we * want! Why should all the styles be thrown away if a * single one is mis-spelled? Let's just continue * parsing styles. */ } else if (rest != NULL) { rest = SkipSpaces(rest,NULL,0); if (*rest) { fvwm_msg(WARN, "style_parse_and_set_window_style", "Unconsumed argument in %s: %s", option, rest); } } free(option); } /* end while still stuff on command */ return; } /* Process a style command. First built up in a temp area. * If valid, added to the list in a malloced area. * * *** Important note *** * * Remember that *all* styles need a flag, flag_mask and change_mask. * It is not enough to add the code for new styles in this function. * There *must* be corresponding code in handle_new_window_style() * and merge_styles() too. And don't forget that allocated memory * must be freed in ProcessDestroyStyle(). */ static void __style_command(F_CMD_ARGS, char *prefix, Bool is_window_style) { /* temp area to build name list */ window_style *ps; ps = (window_style *)safemalloc(sizeof(window_style)); /* init temp window_style area */ memset(ps, 0, sizeof(window_style)); /* init default focus policy */ fpol_init_default_fp(&S_FOCUS_POLICY(SCF(*ps))); /* mark style as changed */ ps->has_style_changed = 1; /* set global flag */ Scr.flags.do_need_window_update = 1; /* default StartsOnPage behavior for initial capture */ ps->flags.capture_honors_starts_on_page = 1; if (!is_window_style) { /* parse style name */ action = GetNextToken(action, &SGET_NAME(*ps)); /* in case there was no argument! */ if (SGET_NAME(*ps) == NULL) { free(ps); return; } SSET_ID_HAS_NAME(*ps, True); } else { SSET_WINDOW_ID(*ps, (XID)FW_W(exc->w.fw)); SSET_ID_HAS_WINDOW_ID(*ps, True); CopyString(&SGET_NAME(*ps), ""); /* safe */ } if (action == NULL) { free(SGET_NAME(*ps)); free(ps); return; } parse_and_set_window_style(action, prefix, ps); /* capture default icons */ if (SGET_ID_HAS_NAME(*ps) && StrEquals(SGET_NAME(*ps), "*")) { if (ps->flags.has_icon == 1) { if (Scr.DefaultIcon) { free(Scr.DefaultIcon); } Scr.DefaultIcon = SGET_ICON_NAME(*ps); ps->flags.has_icon = 0; ps->flag_mask.has_icon = 0; ps->change_mask.has_icon = 1; SSET_ICON_NAME(*ps, NULL); } } if (last_style_in_list && styles_have_same_id(ps, last_style_in_list)) { /* merge with previous style */ merge_styles(last_style_in_list, ps, True); free_style(ps); free(ps); } else { /* add temp name list to list */ add_style_to_list(ps); cleanup_style_defaults(ps); } return; } /* ---------------------------- interface functions ------------------------ */ /* Compare two flag structures passed as byte arrays. Only compare bits set in * the mask. * * Returned Value: * zero if the flags are the same * non-zero otherwise * * Inputs: * flags1 - first byte array of flags to compare * flags2 - second byte array of flags to compare * mask - byte array of flags to be considered for the comparison * len - number of bytes to compare */ Bool blockcmpmask(char *blk1, char *blk2, char *mask, int length) { int i; for (i = 0; i < length; i++) { if ((blk1[i] & mask[i]) != (blk2[i] & mask[i])) { /* flags are not the same, return 1 */ return False; } } return True; } void free_icon_boxes(icon_boxes *ib) { icon_boxes *temp; for ( ; ib != NULL; ib = temp) { temp = ib->next; if (ib->use_count == 0) { free(ib); } else { /* we can't delete the icon box yet, it is still in use */ ib->is_orphan = True; } } return; } void simplify_style_list(void) { /* one pass through the style list, then process other events first */ Scr.flags.do_need_style_list_update = __simplify_style_list(); return; } /* lookup_style - look through a list for a window name, or class * * Returned Value: * merged matching styles in callers window_style. * * Inputs: * fw - FvwmWindow structure to match against * styles - callers return area */ void lookup_style(FvwmWindow *fw, window_style *styles) { window_style *nptr; /* clear callers return area */ memset(styles, 0, sizeof(window_style)); /* look thru all styles in order defined. */ for (nptr = all_styles; nptr != NULL; nptr = SGET_NEXT_STYLE(*nptr)) { if (fw_match_style_id(fw, SGET_ID(*nptr))) { merge_styles(styles, nptr, False); } } EWMH_GetStyle(fw, styles); return; } /* This function sets the style update flags as necessary */ void check_window_style_change( FvwmWindow *t, update_win *flags, window_style *ret_style) { int i; char *wf; char *sf; char *sc; lookup_style(t, ret_style); if (!ret_style->has_style_changed && !IS_STYLE_DELETED(t)) { /* nothing to do */ return; } /*** common style flags ***/ wf = (char *)(&FW_COMMON_STATIC_FLAGS(t)); sf = (char *)(&SCFS(*ret_style)); if (IS_STYLE_DELETED(t)) { /* update all styles */ memset(flags, 0xff, sizeof(*flags)); SET_STYLE_DELETED(t, 0); /* copy the static common window flags */ for (i = 0; i < sizeof(SCFS(*ret_style)); i++) { wf[i] = sf[i]; } return; } /* All static common styles can simply be copied. For some there is * additional work to be done below. */ sc = (char *)(&SCCS(*ret_style)); for (i = 0; i < sizeof(SCFS(*ret_style)); i++) { wf[i] = (wf[i] & ~sc[i]) | (sf[i] & sc[i]); sf[i] = wf[i]; } /* is_sticky * is_icon_sticky */ if (S_IS_STICKY_ACROSS_PAGES(SCC(*ret_style)) || S_IS_STICKY_ACROSS_DESKS(SCC(*ret_style))) { flags->do_update_stick = 1; } else if (S_IS_ICON_STICKY_ACROSS_PAGES(SCC(*ret_style)) && IS_ICONIFIED(t) && !IS_STICKY_ACROSS_PAGES(t)) { flags->do_update_stick_icon = 1; } else if (S_IS_ICON_STICKY_ACROSS_DESKS(SCC(*ret_style)) && IS_ICONIFIED(t) && !IS_STICKY_ACROSS_DESKS(t)) { flags->do_update_stick_icon = 1; } /* focus policy */ if (fpol_is_policy_changed(&S_FOCUS_POLICY(SCC(*ret_style)))) { flags->do_setup_focus_policy = 1; } /* is_left_title_rotated_cw * is_right_title_rotated_cw * is_top_title_rotated * is_bottom_title_rotated */ if (S_IS_LEFT_TITLE_ROTATED_CW(SCC(*ret_style)) || S_IS_RIGHT_TITLE_ROTATED_CW(SCC(*ret_style)) || S_IS_TOP_TITLE_ROTATED(SCC(*ret_style)) || S_IS_BOTTOM_TITLE_ROTATED(SCC(*ret_style))) { flags->do_update_title_text_dir = 1; } /* title_dir */ if (S_TITLE_DIR(SCC(*ret_style))) { flags->do_update_title_dir = 1; } /* use_title_decor_rotation */ if (S_USE_TITLE_DECOR_ROTATION(SCC(*ret_style))) { flags->do_update_rotated_title = 1; } /* has_mwm_border * has_mwm_buttons */ if (S_HAS_MWM_BORDER(SCC(*ret_style)) || S_HAS_MWM_BUTTONS(SCC(*ret_style))) { flags->do_redecorate = 1; } /* has_icon_font */ if (S_HAS_ICON_FONT(SCC(*ret_style))) { flags->do_update_icon_font = 1; } /* has_window_font */ if (S_HAS_WINDOW_FONT(SCC(*ret_style))) { flags->do_update_window_font = 1; } /* has_stippled_title */ if (S_HAS_STIPPLED_TITLE(SCC(*ret_style)) || S_HAS_NO_STICKY_STIPPLED_TITLE(SCC(*ret_style)) || S_HAS_STIPPLED_ICON_TITLE(SCC(*ret_style)) || S_HAS_NO_STICKY_STIPPLED_ICON_TITLE(SCC(*ret_style))) { flags->do_redraw_decoration = 1; } /* has_no_icon_title * is_icon_suppressed * * handled below */ /*** private style flags ***/ /* nothing to do for these flags (only used when mapping new windows): * * do_place_random * do_place_smart * do_start_lowered * use_no_pposition * use_no_usposition * use_no_transient_pposition * use_no_transient_usposition * use_start_on_desk * use_start_on_page_for_transient * use_start_on_screen * manual_placement_honors_starts_on_page * capture_honors_starts_on_page * recapture_honors_starts_on_page * ewmh_placement_mode */ /* not implemented yet: * * handling the 'usestyle' style */ /* do_window_list_skip */ if (S_DO_WINDOW_LIST_SKIP(SCC(*ret_style))) { flags->do_update_modules_flags = 1; flags->do_update_ewmh_state_hints = 1; } /* has_icon * icon_override */ if (ret_style->change_mask.has_icon || S_ICON_OVERRIDE(SCC(*ret_style))) { flags->do_update_icon_font = 1; flags->do_update_icon = 1; } /* has_icon_background_padding * has_icon_background_relief * has_icon_title_relief */ if (ret_style->change_mask.has_icon_background_padding || ret_style->change_mask.has_icon_background_relief || ret_style->change_mask.has_icon_title_relief) { flags->do_update_icon = 1; } /* has_no_icon_title * is_icon_suppressed */ if (S_HAS_NO_ICON_TITLE(SCC(*ret_style)) || S_IS_ICON_SUPPRESSED(SCC(*ret_style))) { flags->do_update_icon_font = 1; flags->do_update_icon_title = 1; flags->do_update_icon = 1; flags->do_update_modules_flags = 1; } /* has_icon_size_limits */ if (ret_style->change_mask.has_icon_size_limits) { flags->do_update_icon_size_limits = 1; flags->do_update_icon = 1; } /* has_icon_boxes */ if (ret_style->change_mask.has_icon_boxes) { flags->do_update_icon_boxes = 1; flags->do_update_icon = 1; } /* do_ewmh_donate_icon */ if (S_DO_EWMH_DONATE_ICON(SCC(*ret_style))) { flags->do_update_ewmh_icon = 1; } /* has_mini_icon * do_ewmh_mini_icon_override */ if ( FMiniIconsSupported && ( ret_style->change_mask.has_mini_icon || S_DO_EWMH_MINI_ICON_OVERRIDE(SCC(*ret_style)))) { flags->do_update_mini_icon = 1; flags->do_update_ewmh_mini_icon = 1; flags->do_redecorate = 1; } /* do_ewmh_donate_mini_icon */ if (FMiniIconsSupported && S_DO_EWMH_DONATE_MINI_ICON(SCC(*ret_style))) { flags->do_update_ewmh_mini_icon = 1; } /* has_min_window_size */ /* has_max_window_size */ if (ret_style->change_mask.has_min_window_size) { flags->do_resize_window = 1; flags->do_update_ewmh_allowed_actions = 1; flags->do_update_modules_flags = 1; } if (ret_style->change_mask.has_max_window_size) { flags->do_resize_window = 1; flags->do_update_ewmh_allowed_actions = 1; flags->do_update_modules_flags = 1; } /* has_color_back * has_color_fore * use_colorset * use_border_colorset */ if (ret_style->change_mask.has_color_fore || ret_style->change_mask.has_color_back || ret_style->change_mask.use_colorset || ret_style->change_mask.use_border_colorset) { flags->do_update_window_color = 1; } /* has_color_back_hi * has_color_fore_hi * use_colorset_hi * use_border_colorset_hi */ if (ret_style->change_mask.has_color_fore_hi || ret_style->change_mask.has_color_back_hi || ret_style->change_mask.use_colorset_hi || ret_style->change_mask.use_border_colorset_hi) { flags->do_update_window_color_hi = 1; } /* use_icon_title_colorset */ if (ret_style->change_mask.use_icon_title_colorset) { flags->do_update_icon_title_cs = 1; } /* use_icon_title_colorset_hi */ if (ret_style->change_mask.use_icon_title_colorset_hi) { flags->do_update_icon_title_cs_hi = 1; } /* use_icon_title_colorset */ if (ret_style->change_mask.use_icon_title_colorset) { flags->do_update_icon_title_cs = 1; } /* use_icon_background_colorset */ if (ret_style->change_mask.use_icon_background_colorset) { flags->do_update_icon_background_cs = 1; } /* has_decor */ if (ret_style->change_mask.has_decor) { flags->do_redecorate = 1; flags->do_update_window_font_height = 1; } /* has_no_title */ if (ret_style->change_mask.has_no_title) { flags->do_redecorate = 1; flags->do_update_window_font = 1; } /* do_decorate_transient */ if (ret_style->change_mask.do_decorate_transient) { flags->do_redecorate_transient = 1; } /* has_ol_decor */ if (ret_style->change_mask.has_ol_decor) { /* old decor overrides 'has_no_icon_title'! */ flags->do_update_icon_font = 1; flags->do_update_icon_title = 1; flags->do_update_icon = 1; flags->do_redecorate = 1; } /* Changing layer. */ if (ret_style->change_mask.use_layer) { flags->do_update_layer = 1; } /* has_no_border * has_border_width * has_handle_width * has_mwm_decor * has_mwm_functions * has_no_handles * is_button_disabled */ if (S_HAS_NO_BORDER(SCC(*ret_style)) || ret_style->change_mask.has_border_width || ret_style->change_mask.has_handle_width || ret_style->change_mask.has_mwm_decor || ret_style->change_mask.has_mwm_functions || ret_style->change_mask.has_no_handles || ret_style->change_mask.is_button_disabled) { flags->do_redecorate = 1; flags->do_update_ewmh_allowed_actions = 1; flags->do_update_modules_flags = 1; } if (ret_style->change_mask.do_save_under || ret_style->change_mask.use_backing_store || ret_style->change_mask.use_parent_relative) { flags->do_update_frame_attributes = 1; } if (ret_style->change_mask.use_parent_relative && ret_style->flags.use_parent_relative) { /* needed only for Opacity -> ParentalRelativity */ flags->do_refresh = 1; } /* has_placement_penalty * has_placement_percentage_penalty */ if (ret_style->change_mask.has_placement_penalty || ret_style->change_mask.has_placement_percentage_penalty) { flags->do_update_placement_penalty = 1; } /* do_ewmh_ignore_strut_hints */ if (S_DO_EWMH_IGNORE_STRUT_HINTS(SCC(*ret_style))) { flags->do_update_working_area = 1; } /* do_ewmh_ignore_state_hints */ if (S_DO_EWMH_IGNORE_STATE_HINTS(SCC(*ret_style))) { flags->do_update_ewmh_state_hints = 1; flags->do_update_modules_flags = 1; } /* do_ewmh_use_staking_hints */ if (S_DO_EWMH_USE_STACKING_HINTS(SCC(*ret_style))) { flags->do_update_ewmh_stacking_hints = 1; } /* has_title_format_string */ if (ret_style->change_mask.has_title_format_string) { flags->do_update_visible_window_name = 1; flags->do_redecorate = 1; } /* has_icon_title_format_string */ if (ret_style->change_mask.has_icon_title_format_string) { flags->do_update_visible_icon_name = 1; flags->do_update_icon_title = 1; } /* is_fixed */ if (S_IS_FIXED(SCC(*ret_style)) || S_IS_FIXED_PPOS(SCC(*ret_style)) || S_IS_SIZE_FIXED(SCC(*ret_style)) || S_IS_PSIZE_FIXED(SCC(*ret_style)) || S_HAS_OVERRIDE_SIZE(SCC(*ret_style))) { flags->do_update_ewmh_allowed_actions = 1; flags->do_update_modules_flags = 1; } /* cr_motion_method */ if (SCR_MOTION_METHOD(&ret_style->change_mask)) { flags->do_update_cr_motion_method = 1; } return; } /* Mark all styles as unchanged. */ void reset_style_changes(void) { window_style *temp; for (temp = all_styles; temp != NULL; temp = SGET_NEXT_STYLE(*temp)) { temp->has_style_changed = 0; memset(&SCCS(*temp), 0, sizeof(SCCS(*temp))); memset(&(temp->change_mask), 0, sizeof(temp->change_mask)); } return; } /* Mark styles as updated if their colorset changed. */ void update_style_colorset(int colorset) { window_style *temp; for (temp = all_styles; temp != NULL; temp = SGET_NEXT_STYLE(*temp)) { if (SUSE_COLORSET(&temp->flags) && SGET_COLORSET(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_colorset = 1; Scr.flags.do_need_window_update = 1; } if (SUSE_COLORSET_HI(&temp->flags) && SGET_COLORSET_HI(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_colorset_hi = 1; Scr.flags.do_need_window_update = 1; } if (SUSE_BORDER_COLORSET(&temp->flags) && SGET_BORDER_COLORSET(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_border_colorset = 1; Scr.flags.do_need_window_update = 1; } if (SUSE_BORDER_COLORSET_HI(&temp->flags) && SGET_BORDER_COLORSET_HI(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_border_colorset_hi = 1; Scr.flags.do_need_window_update = 1; } if (SUSE_ICON_TITLE_COLORSET(&temp->flags) && SGET_ICON_TITLE_COLORSET(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_icon_title_colorset = 1; Scr.flags.do_need_window_update = 1; } if (SUSE_ICON_TITLE_COLORSET_HI(&temp->flags) && SGET_ICON_TITLE_COLORSET_HI(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_icon_title_colorset_hi = 1; Scr.flags.do_need_window_update = 1; } if (SUSE_ICON_BACKGROUND_COLORSET(&temp->flags) && SGET_ICON_BACKGROUND_COLORSET(*temp) == colorset) { temp->has_style_changed = 1; temp->change_mask.use_icon_background_colorset = 1; Scr.flags.do_need_window_update = 1; } } return; } /* Update fore and back colours for a specific window */ void update_window_color_style(FvwmWindow *fw, window_style *pstyle) { int cs = Scr.DefaultColorset; if (SUSE_COLORSET(&pstyle->flags)) { cs = SGET_COLORSET(*pstyle); fw->cs = cs; } else { fw->cs = -1; } if (SGET_FORE_COLOR_NAME(*pstyle) != NULL && !SUSE_COLORSET(&pstyle->flags)) { fw->colors.fore = GetColor(SGET_FORE_COLOR_NAME(*pstyle)); } else { fw->colors.fore = Colorset[cs].fg; } if (SGET_BACK_COLOR_NAME(*pstyle) != NULL && !SUSE_COLORSET(&pstyle->flags)) { fw->colors.back = GetColor(SGET_BACK_COLOR_NAME(*pstyle)); fw->colors.shadow = GetShadow(fw->colors.back); fw->colors.hilight = GetHilite(fw->colors.back); } else { fw->colors.hilight = Colorset[cs].hilite; fw->colors.shadow = Colorset[cs].shadow; fw->colors.back = Colorset[cs].bg; } if (SUSE_BORDER_COLORSET(&pstyle->flags)) { cs = SGET_BORDER_COLORSET(*pstyle); fw->border_cs = cs; fw->border_colors.hilight = Colorset[cs].hilite; fw->border_colors.shadow = Colorset[cs].shadow; fw->border_colors.back = Colorset[cs].bg; } else { fw->border_cs = -1; fw->border_colors.hilight = fw->colors.hilight; fw->border_colors.shadow = fw->colors.shadow; fw->border_colors.back = fw->colors.back; } } void update_window_color_hi_style(FvwmWindow *fw, window_style *pstyle) { int cs = Scr.DefaultColorset; if (SUSE_COLORSET_HI(&pstyle->flags)) { cs = SGET_COLORSET_HI(*pstyle); fw->cs_hi = cs; } else { fw->cs_hi = -1; } if ( SGET_FORE_COLOR_NAME_HI(*pstyle) != NULL && !SUSE_COLORSET_HI(&pstyle->flags)) { fw->hicolors.fore = GetColor(SGET_FORE_COLOR_NAME_HI(*pstyle)); } else { fw->hicolors.fore = Colorset[cs].fg; } if ( SGET_BACK_COLOR_NAME_HI(*pstyle) != NULL && !SUSE_COLORSET_HI(&pstyle->flags)) { fw->hicolors.back = GetColor(SGET_BACK_COLOR_NAME_HI(*pstyle)); fw->hicolors.shadow = GetShadow(fw->hicolors.back); fw->hicolors.hilight = GetHilite(fw->hicolors.back); } else { fw->hicolors.hilight = Colorset[cs].hilite; fw->hicolors.shadow = Colorset[cs].shadow; fw->hicolors.back = Colorset[cs].bg; } if (SUSE_BORDER_COLORSET_HI(&pstyle->flags)) { cs = SGET_BORDER_COLORSET_HI(*pstyle); fw->border_cs_hi = cs; fw->border_hicolors.hilight = Colorset[cs].hilite; fw->border_hicolors.shadow = Colorset[cs].shadow; fw->border_hicolors.back = Colorset[cs].bg; } else { fw->border_cs_hi = -1; fw->border_hicolors.hilight = fw->hicolors.hilight; fw->border_hicolors.shadow = fw->hicolors.shadow; fw->border_hicolors.back = fw->hicolors.back; } } void update_icon_title_cs_style(FvwmWindow *fw, window_style *pstyle) { if (SUSE_ICON_TITLE_COLORSET(&pstyle->flags)) { fw->icon_title_cs = SGET_ICON_TITLE_COLORSET(*pstyle); } else { fw->icon_title_cs = -1; } } void update_icon_title_cs_hi_style(FvwmWindow *fw, window_style *pstyle) { if (SUSE_ICON_TITLE_COLORSET_HI(&pstyle->flags)) { fw->icon_title_cs_hi = SGET_ICON_TITLE_COLORSET_HI(*pstyle); } else { fw->icon_title_cs_hi = -1; } } void update_icon_background_cs_style(FvwmWindow *fw, window_style *pstyle) { if (SUSE_ICON_BACKGROUND_COLORSET(&pstyle->flags)) { fw->icon_background_cs = SGET_ICON_BACKGROUND_COLORSET(*pstyle); } else { fw->icon_background_cs = -1; } } void style_destroy_style(style_id_t s_id) { FvwmWindow *t; if (remove_all_of_style_from_list(s_id)) { /* compact the current list of styles */ Scr.flags.do_need_style_list_update = 1; } else { return; } /* mark windows for update */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (fw_match_style_id(t, s_id)) { SET_STYLE_DELETED(t, 1); Scr.flags.do_need_window_update = 1; } } return; } void print_styles(int verbose) { window_style *nptr; int count = 0; int mem = 0; fprintf(stderr,"Info on fvwm Styles:\n"); if (verbose) { fprintf(stderr," List of Styles Names:\n"); } for (nptr = all_styles; nptr != NULL; nptr = SGET_NEXT_STYLE(*nptr)) { count++; if (SGET_ID_HAS_NAME(*nptr)) { mem += strlen(SGET_NAME(*nptr)); if (verbose) { fprintf(stderr," * %s\n", SGET_NAME(*nptr)); } } else { mem++; if (verbose) { fprintf(stderr," * 0x%lx\n", (unsigned long)SGET_WINDOW_ID(*nptr)); } } if (SGET_BACK_COLOR_NAME(*nptr)) { mem += strlen(SGET_BACK_COLOR_NAME(*nptr)); if (verbose > 1) { fprintf( stderr," Back Color: %s\n", SGET_BACK_COLOR_NAME(*nptr)); } } if (SGET_FORE_COLOR_NAME(*nptr)) { mem += strlen(SGET_FORE_COLOR_NAME(*nptr)); if (verbose > 1) { fprintf( stderr," Fore Color: %s\n", SGET_FORE_COLOR_NAME(*nptr)); } } if (SGET_BACK_COLOR_NAME_HI(*nptr)) { mem += strlen(SGET_BACK_COLOR_NAME_HI(*nptr)); if (verbose > 1) { fprintf( stderr," Back Color hi: %s\n", SGET_BACK_COLOR_NAME_HI(*nptr)); } } if (SGET_FORE_COLOR_NAME_HI(*nptr)) { mem += strlen(SGET_FORE_COLOR_NAME_HI(*nptr)); if (verbose > 1) { fprintf( stderr," Fore Color hi: %s\n", SGET_FORE_COLOR_NAME_HI(*nptr)); } } if (SGET_DECOR_NAME(*nptr)) { mem += strlen(SGET_DECOR_NAME(*nptr)); if (verbose > 1) { fprintf( stderr," Decor: %s\n", SGET_DECOR_NAME(*nptr)); } } if (SGET_WINDOW_FONT(*nptr)) { mem += strlen(SGET_WINDOW_FONT(*nptr)); if (verbose > 1) { fprintf( stderr," Window Font: %s\n", SGET_WINDOW_FONT(*nptr)); } } if (SGET_ICON_FONT(*nptr)) { mem += strlen(SGET_ICON_FONT(*nptr)); if (verbose > 1) { fprintf( stderr," Icon Font: %s\n", SGET_ICON_FONT(*nptr)); } } if (SGET_ICON_NAME(*nptr)) { mem += strlen(SGET_ICON_NAME(*nptr)); if (verbose > 1) { fprintf( stderr," Icon Name: %s\n", SGET_ICON_NAME(*nptr)); } } if (SGET_MINI_ICON_NAME(*nptr)) { mem += strlen(SGET_MINI_ICON_NAME(*nptr)); if (verbose > 1) { fprintf( stderr," MiniIcon Name: %s\n", SGET_MINI_ICON_NAME(*nptr)); } } if (SGET_ICON_BOXES(*nptr)) { mem += sizeof(icon_boxes); } } fprintf(stderr," Number of styles: %d, Memory Used: %d bits\n", count, (int)(count*sizeof(window_style) + mem)); return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_Style(F_CMD_ARGS) { __style_command(F_PASS_ARGS, NULL, False); return; } void CMD_WindowStyle(F_CMD_ARGS) { __style_command(F_PASS_ARGS, NULL, True); return; } void CMD_FocusStyle(F_CMD_ARGS) { __style_command(F_PASS_ARGS, "FP", False); return; } void CMD_DestroyStyle(F_CMD_ARGS) { char *name; style_id_t s_id; /* parse style name */ name = PeekToken(action, &action); /* in case there was no argument! */ if (name == NULL) return; memset(&s_id, 0, sizeof(style_id_t)); SID_SET_NAME(s_id, name); SID_SET_HAS_NAME(s_id, True); /* Do it */ style_destroy_style(s_id); return; } void CMD_DestroyWindowStyle(F_CMD_ARGS) { style_id_t s_id; memset(&s_id, 0, sizeof(style_id_t)); SID_SET_WINDOW_ID(s_id, (XID)FW_W(exc->w.fw)); SID_SET_HAS_WINDOW_ID(s_id, True); /* Do it */ style_destroy_style(s_id); return; } fvwm-2.6.7/fvwm/execcontext.c0000644000175700017570000001011013001406607013106 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #define FEVENT_PRIVILEGED_ACCESS #include "config.h" #undef FEVENT_PRIVILEGED_ACCESS #include #include "fvwm.h" #include "externs.h" #include "execcontext.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ #undef DEBUG_EXECCONTEXT #ifdef DEBUG_EXECCONTEXT static exec_context_t *x[256]; static int nx = 0; #endif /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void __exc_change_context( exec_context_t *exc, exec_context_changes_t *ecc, exec_context_change_mask_t mask) { if (mask & ECC_TYPE) { exc->type = ecc->type; } if (mask & ECC_ETRIGGER) { if (ecc->x.etrigger == NULL) { fev_copy_last_event(&exc->private_data.te); } else { exc->private_data.te = *ecc->x.etrigger; } exc->x.etrigger = &(exc->private_data.te); } if (mask & ECC_FW) { exc->w.fw = ecc->w.fw; } if (mask & ECC_W) { exc->w.w = ecc->w.w; } if (mask & ECC_WCONTEXT) { exc->w.wcontext = ecc->w.wcontext; } if (mask & ECC_MODULE) { exc->m.module = ecc->m.module; } return; } /* ---------------------------- interface functions ------------------------ */ const exec_context_t *exc_create_null_context(void) { exec_context_t *exc; #ifdef DEBUG_EXECCONTEXT int i; #endif exc = (exec_context_t *)safecalloc(1, sizeof(exec_context_t)); #ifdef DEBUG_EXECCONTEXT fprintf(stderr, "xxx+0 "); for(i=0;itype = EXCT_NULL; fev_make_null_event(&exc->private_data.te, dpy); exc->x.etrigger = &exc->private_data.te; exc->x.elast = fev_get_last_event_address(); exc->m.module = NULL; return exc; } const exec_context_t *exc_create_context( exec_context_changes_t *ecc, exec_context_change_mask_t mask) { exec_context_t *exc; #ifdef DEBUG_EXECCONTEXT if (!(mask & ECC_TYPE)) abort(); #endif exc = (exec_context_t *)exc_create_null_context(); __exc_change_context(exc, ecc, mask); return exc; } const exec_context_t *exc_clone_context( const exec_context_t *excin, exec_context_changes_t *ecc, exec_context_change_mask_t mask) { exec_context_t *exc; #ifdef DEBUG_EXECCONTEXT int i; #endif exc = (exec_context_t *)safemalloc(sizeof(exec_context_t)); #ifdef DEBUG_EXECCONTEXT fprintf(stderr, "xxx+= "); for(i=0;i /* for FILE below */ /** * Full pathname of file read in progress, or NULL. **/ extern const char *get_current_read_file(void); extern const char *get_current_read_dir(void); /** * Read and execute each line from stream. * * Parameters eventp, fw, context, and Module supply the context * for executing the commands. * cond_rc_t is passed thru incase piperead is running in a function. **/ void run_command_stream( cond_rc_t *cond_rc, FILE *f, const exec_context_t *exc); /** * Given a filename, open it and execute the commands therein. * * If the filename is not an absolute path, search for it in * fvwm_userdir (set in main()) or in FVWM_DATADIR. Return 1 * if the file was found and executed. **/ int run_command_file(char *filename, const exec_context_t *exc); #endif fvwm-2.6.7/fvwm/menugeometry.c0000644000175700017570000000637212773467232013334 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "misc.h" #include "screen.h" #include "menudim.h" #include "menuroot.h" #include "menuparameters.h" #include "menugeometry.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ Bool menu_get_geometry( struct MenuRoot *mr, Window *root_return, int *x_return, int *y_return, int *width_return, int *height_return, int *border_width_return, int *depth_return) { Status rc; Bool brc; int root_x; int root_y; rc = XGetGeometry( dpy, MR_WINDOW(mr), root_return, x_return, y_return, (unsigned int*)width_return, (unsigned int*)height_return, (unsigned int*)border_width_return, (unsigned int*)depth_return); if (rc == 0) { return False; } if (!MR_IS_TEAR_OFF_MENU(mr)) { return True; } brc = XTranslateCoordinates( dpy, MR_WINDOW(mr), Scr.Root, *x_return, *y_return, &root_x, &root_y, &JunkChild); if (brc == True) { *x_return = root_x; *y_return = root_y; } else { *x_return = 0; *y_return = 0; } return brc; } Bool menu_get_outer_geometry( struct MenuRoot *mr, struct MenuParameters *pmp, Window *root_return, int *x_return, int *y_return, int *width_return, int *height_return, int *border_width_return, int *depth_return) { if (MR_IS_TEAR_OFF_MENU(mr)) { return XGetGeometry( dpy, FW_W_FRAME(pmp->tear_off_root_menu_window), root_return,x_return,y_return, (unsigned int*)width_return, (unsigned int*)height_return, (unsigned int*)border_width_return, (unsigned int*)depth_return); } else { return menu_get_geometry( mr,root_return,x_return,y_return, width_return, height_return, border_width_return, depth_return); } } fvwm-2.6.7/fvwm/icccm2.h0000644000175700017570000000040112773467232011744 00000000000000/* -*-c-*- */ #ifndef ICCCM2_h #define ICCCM2_h extern void SetupICCCM2(Bool replace_wm); extern void CloseICCCM2(void); extern void icccm2_handle_selection_request(const XEvent *e); extern void icccm2_handle_selection_clear(void); #endif /* ICCCM2_H */ fvwm-2.6.7/fvwm/Makefile.in0000644000175700017570000007243513010103322012464 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = fvwm$(EXEEXT) subdir = fvwm DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)" PROGRAMS = $(bin_PROGRAMS) am_fvwm_OBJECTS = menus.$(OBJEXT) style.$(OBJEXT) borders.$(OBJEXT) \ events.$(OBJEXT) move_resize.$(OBJEXT) builtins.$(OBJEXT) \ add_window.$(OBJEXT) icons.$(OBJEXT) fvwm.$(OBJEXT) \ frame.$(OBJEXT) placement.$(OBJEXT) virtual.$(OBJEXT) \ menustyle.$(OBJEXT) conditional.$(OBJEXT) ewmh.$(OBJEXT) \ stack.$(OBJEXT) session.$(OBJEXT) colorset.$(OBJEXT) \ functions.$(OBJEXT) ewmh_events.$(OBJEXT) geometry.$(OBJEXT) \ module_list.$(OBJEXT) focus.$(OBJEXT) windowlist.$(OBJEXT) \ functable.$(OBJEXT) menuitem.$(OBJEXT) expand.$(OBJEXT) \ module_interface.$(OBJEXT) menubindings.$(OBJEXT) \ decorations.$(OBJEXT) ewmh_icons.$(OBJEXT) update.$(OBJEXT) \ bindings.$(OBJEXT) misc.$(OBJEXT) cursor.$(OBJEXT) \ colormaps.$(OBJEXT) modconf.$(OBJEXT) ewmh_conf.$(OBJEXT) \ read.$(OBJEXT) schedule.$(OBJEXT) menucmd.$(OBJEXT) \ ewmh_names.$(OBJEXT) icccm2.$(OBJEXT) windowshade.$(OBJEXT) \ focus_policy.$(OBJEXT) repeat.$(OBJEXT) execcontext.$(OBJEXT) \ menugeometry.$(OBJEXT) menudim.$(OBJEXT) condrc.$(OBJEXT) \ infostore.$(OBJEXT) fvwm_OBJECTS = $(am_fvwm_OBJECTS) fvwm_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(fvwm_SOURCES) DIST_SOURCES = $(fvwm_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ configdir = @FVWM_DATADIR@ EXTRA_DIST = $(config_DATA) config_DATA = ConfigFvwmDefaults fvwm_SOURCES = \ add_window.h bindings.h borders.h builtins.h colormaps.h colorset.h \ commands.h conditional.h condrc.h cursor.h decorations.h events.h \ eventhandler.h eventmask.h ewmh.h ewmh_intern.h expand.h externs.h \ focus.h functable.h functions.h fvwm.h geometry.h focus_policy.h \ icccm2.h icons.h menubindings.h menudim.h menugeometry.h \ menuitem.h menuroot.h menuparameters.h menus.h menustyle.h misc.h \ modconf.h module_interface.h module_list.h move_resize.h \ placement.h read.h repeat.h execcontext.h schedule.h screen.h \ session.h stack.h style.h update.h virtual.h window_flags.h frame.h \ infostore.h \ \ menus.c style.c borders.c events.c move_resize.c builtins.c \ add_window.c icons.c fvwm.c frame.c placement.c virtual.c \ menustyle.c conditional.c ewmh.c stack.c session.c colorset.c \ functions.c ewmh_events.c geometry.c module_list.c focus.c \ windowlist.c functable.c menuitem.c expand.c module_interface.c \ menubindings.c decorations.c ewmh_icons.c update.c bindings.c misc.c \ cursor.c colormaps.c modconf.c ewmh_conf.c read.c schedule.c \ menucmd.c ewmh_names.c icccm2.c windowshade.c focus_policy.c repeat.c \ execcontext.c menugeometry.c menudim.c condrc.c infostore.c fvwm_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = \ -L$(top_builddir)/libs -lfvwm $(Xft_LIBS) $(X_LIBS) $(xpm_LIBS) \ $(stroke_LIBS) $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 \ $(X_EXTRA_LIBS) -lm $(iconv_LIBS) $(Xrender_LIBS) $(Xcursor_LIBS) \ $(Bidi_LIBS) $(png_LIBS) $(rsvg_LIBS) $(intl_LIBS) AM_CPPFLAGS = \ -I$(top_srcdir) $(stroke_CFLAGS) $(Xft_CFLAGS) \ $(xpm_CFLAGS) $(X_CFLAGS) $(iconv_CFLAGS) $(Xrender_CFLAGS) \ $(Bidi_CFLAGS) $(png_CFLAGS) $(rsvg_CFLAGS) $(intl_CFLAGS) AM_CFLAGS = \ -DFVWM_MODULEDIR=\"$(FVWM_MODULEDIR)\" \ -DFVWM_DATADIR=\"$(FVWM_DATADIR)\" \ -DFVWM_CONFDIR=\"$(FVWM_CONFDIR)\" \ -DFVWM_COLORSET_PRIVATE=1 \ -DLOCALEDIR=\"$(LOCALEDIR)\" all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign fvwm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign fvwm/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) fvwm$(EXEEXT): $(fvwm_OBJECTS) $(fvwm_DEPENDENCIES) $(EXTRA_fvwm_DEPENDENCIES) @rm -f fvwm$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fvwm_OBJECTS) $(fvwm_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_window.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bindings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/borders.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtins.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colormaps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colorset.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conditional.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/condrc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cursor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decorations.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ewmh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ewmh_conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ewmh_events.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ewmh_icons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ewmh_names.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execcontext.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/focus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/focus_policy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fvwm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geometry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icccm2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infostore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menubindings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menucmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menudim.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menugeometry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menuitem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menustyle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module_interface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module_list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/move_resize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/placement.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repeat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/style.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virtual.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windowlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windowshade.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-configDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-configDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-configDATA install-exec-local: @rm -f $(DESTDIR)$(bindir)/fvwm2 @$(LN_S) fvwm $(DESTDIR)$(bindir)/fvwm2 || \ echo "Minor warning: $(bindir)/fvwm2 symlink was not created" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/fvwm/builtins.h0000644000175700017570000000061112773467232012440 00000000000000/* -*-c-*- */ #ifndef BUILTINS_H #define BUILTINS_H void refresh_window(Window w, Bool window_update); void ApplyDefaultFontAndColors(void); void InitFvwmDecor(FvwmDecor *decor); void reset_decor_changes(void); Bool ReadDecorFace(char *s, DecorFace *df, int button, int verbose); void FreeDecorFace(Display *dpy, DecorFace *df); void update_fvwm_colorset(int cset); #endif /* BUILTINS_H */ fvwm-2.6.7/fvwm/repeat.h0000644000175700017570000000131212773467232012066 00000000000000/* -*-c-*- */ #ifndef _REPEAT_ #define _REPEAT_ typedef enum { REPEAT_NONE = 0, REPEAT_COMMAND, /* I think we don't need all these REPEAT_BUILTIN, REPEAT_FUNCTION, REPEAT_TOP_FUNCTION, REPEAT_MODULE, */ REPEAT_MENU, REPEAT_POPUP, REPEAT_PAGE, REPEAT_DESK, REPEAT_DESK_AND_PAGE, REPEAT_FVWM_WINDOW } repeat_t; extern char *repeat_last_function; extern char *repeat_last_complex_function; extern char *repeat_last_builtin_function; extern char *repeat_last_module; /* extern char *repeat_last_top_function; extern char *repeat_last_menu; extern FvwmWindow *repeat_last_fvwm_window; */ Bool set_repeat_data(void *data, repeat_t type, const func_t *builtin); #endif /* _REPEAT_ */ fvwm-2.6.7/fvwm/builtins.c0000644000175700017570000025276313001406607012434 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include #include #include #include #include "libs/fvwmlib.h" #include "libs/fvwmsignal.h" #include "libs/setpgrp.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/ColorUtils.h" #include "libs/Graphics.h" #include "libs/wild.h" #include "libs/envvar.h" #include "libs/ClientMsg.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/FGettext.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/Flocale.h" #include "libs/Ficonv.h" #include "fvwm.h" #include "externs.h" #include "colorset.h" #include "bindings.h" #include "misc.h" #include "cursor.h" #include "functions.h" #include "commands.h" #include "screen.h" #include "builtins.h" #include "module_interface.h" #include "borders.h" #include "frame.h" #include "events.h" #include "ewmh.h" #include "virtual.h" #include "decorations.h" #include "add_window.h" #include "update.h" #include "style.h" #include "move_resize.h" #include "menus.h" #include "infostore.h" #ifdef HAVE_STROKE #include "stroke.h" #endif /* HAVE_STROKE */ /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ extern float rgpctMovementDefault[32]; extern int cpctMovementDefault; extern int cmsDelayDefault; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef enum {FakeMouseEvent, FakeKeyEvent} FakeEventType; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static char *exec_shell_name="/bin/sh"; /* button state strings must match the enumerated states */ static char *button_states[BS_MaxButtonStateName + 1] = { "ActiveUp", "ActiveDown", "InactiveUp", "InactiveDown", "ToggledActiveUp", "ToggledActiveDown", "ToggledInactiveUp", "ToggledInactiveDown", "Active", "Inactive", "ToggledActive", "ToggledInactive", "AllNormal", "AllToggled", "AllActive", "AllInactive", "AllUp", "AllDown", "AllActiveUp", "AllActiveDown", "AllInactiveUp", "AllInactiveDown", NULL }; /* ---------------------------- exported variables (globals) --------------- */ char *ModulePath = FVWM_MODULEDIR; int moduleTimeout = DEFAULT_MODULE_TIMEOUT; /* ---------------------------- local functions ---------------------------- */ /** Prepend rather than replace the image path. Used for obsolete PixmapPath and IconPath **/ static void obsolete_imagepaths( const char* pre_path ) { char* tmp = stripcpy( pre_path ); char* path = alloca(strlen( tmp ) + strlen(PictureGetImagePath()) + 2 ); strcpy( path, tmp ); free( tmp ); strcat( path, ":" ); strcat( path, PictureGetImagePath() ); PictureSetImagePath( path ); return; } /* * * Reads a title button description (veliaa@rpi.edu) * */ static char *ReadTitleButton( char *s, TitleButton *tb, Boolean append, int button) { char *end = NULL; char *spec; char *t; int i; int bs; int bs_start, bs_end; int pstyle = 0; DecorFace tmpdf; Bool multiple; int use_mask = 0; int set_mask = 0; s = SkipSpaces(s, NULL, 0); t = GetNextTokenIndex(s, button_states, 0, &bs); if (bs != BS_All) { s = SkipSpaces(t, NULL, 0); } if (bs == BS_All) { use_mask = 0; set_mask = 0; } else if (bs == BS_Active) { use_mask = BS_MASK_INACTIVE | BS_MASK_TOGGLED; set_mask = 0; } else if (bs == BS_Inactive) { use_mask = BS_MASK_INACTIVE | BS_MASK_TOGGLED; set_mask = BS_MASK_INACTIVE; } else if (bs == BS_ToggledActive) { use_mask = BS_MASK_INACTIVE | BS_MASK_TOGGLED; set_mask = BS_MASK_TOGGLED; } else if (bs == BS_ToggledInactive) { use_mask = BS_MASK_INACTIVE | BS_MASK_TOGGLED; set_mask = BS_MASK_INACTIVE | BS_MASK_TOGGLED; } else if (bs == BS_AllNormal) { use_mask = BS_MASK_TOGGLED; set_mask = 0; } else if (bs == BS_AllToggled) { use_mask = BS_MASK_TOGGLED; set_mask = BS_MASK_TOGGLED; } else if (bs == BS_AllActive) { use_mask = BS_MASK_INACTIVE; set_mask = 0; } else if (bs == BS_AllInactive) { use_mask = BS_MASK_INACTIVE; set_mask = BS_MASK_INACTIVE; } else if (bs == BS_AllUp) { use_mask = BS_MASK_DOWN; set_mask = 0; } else if (bs == BS_AllDown) { use_mask = BS_MASK_DOWN; set_mask = BS_MASK_DOWN; } else if (bs == BS_AllActiveUp) { use_mask = BS_MASK_INACTIVE | BS_MASK_DOWN; set_mask = 0; } else if (bs == BS_AllActiveDown) { use_mask = BS_MASK_INACTIVE | BS_MASK_DOWN; set_mask = BS_MASK_DOWN; } else if (bs == BS_AllInactiveUp) { use_mask = BS_MASK_INACTIVE | BS_MASK_DOWN; set_mask = BS_MASK_INACTIVE; } else if (bs == BS_AllInactiveDown) { use_mask = BS_MASK_INACTIVE | BS_MASK_DOWN; set_mask = BS_MASK_INACTIVE | BS_MASK_DOWN; } if ((bs & BS_MaxButtonStateMask) == bs) { multiple = False; bs_start = bs; bs_end = bs; } else { multiple = True; bs_start = 0; bs_end = BS_MaxButtonState - 1; for (i = bs_start; (i & use_mask) != set_mask && i <= bs_end; i++) { bs_start++; } } if (*s == '(') { int len; pstyle = 1; if (!(end = strchr(++s, ')'))) { fvwm_msg( ERR, "ReadTitleButton", "missing parenthesis: %s", s); return NULL; } s = SkipSpaces(s, NULL, 0); len = end - s + 1; spec = safemalloc(len); strncpy(spec, s, len - 1); spec[len - 1] = 0; } else { spec = s; } spec = SkipSpaces(spec, NULL, 0); /* setup temporary in case button read fails */ memset(&tmpdf, 0, sizeof(DecorFace)); DFS_FACE_TYPE(tmpdf.style) = SimpleButton; if (strncmp(spec, "--", 2) == 0) { /* only change flags */ Bool verbose = True; for (i = bs_start; i <= bs_end; ++i) { if (multiple && (i & use_mask) != set_mask) { continue; } ReadDecorFace(spec, &TB_STATE(*tb)[i], button, verbose); verbose = False; } } else if (ReadDecorFace(spec, &tmpdf, button, True)) { if (append) { DecorFace *head = &TB_STATE(*tb)[bs_start]; DecorFace *tail = head; DecorFace *next; while (tail->next) { tail = tail->next; } tail->next = (DecorFace *)safemalloc(sizeof(DecorFace)); memcpy(tail->next, &tmpdf, sizeof(DecorFace)); if (DFS_FACE_TYPE(tail->next->style) == VectorButton && DFS_FACE_TYPE((&TB_STATE(*tb)[bs_start])->style) == DefaultVectorButton) { /* override the default vector style */ memcpy( &tail->next->style, &head->style, sizeof(DecorFaceStyle)); DFS_FACE_TYPE(tail->next->style) = VectorButton; next = head->next; head->next = NULL; FreeDecorFace(dpy, head); memcpy(head, next, sizeof(DecorFace)); free(next); } for (i = bs_start + 1; i <= bs_end; ++i) { if (multiple && (i & use_mask) != set_mask) { continue; } head = &TB_STATE(*tb)[i]; tail = head; while (tail->next) { tail = tail->next; } tail->next = (DecorFace *)safemalloc( sizeof(DecorFace)); memset( &DFS_FLAGS(tail->next->style), 0, sizeof(DFS_FLAGS(tail->next->style))); DFS_FACE_TYPE(tail->next->style) = SimpleButton; tail->next->next = NULL; ReadDecorFace(spec, tail->next, button, False); if (DFS_FACE_TYPE(tail->next->style) == VectorButton && DFS_FACE_TYPE((&TB_STATE(*tb)[i])->style) == DefaultVectorButton) { /* override the default vector style */ memcpy( &tail->next->style, &head->style, sizeof(DecorFaceStyle)); DFS_FACE_TYPE(tail->next->style) = VectorButton; next = head->next; head->next = NULL; FreeDecorFace(dpy, head); memcpy(head, next, sizeof(DecorFace)); free(next); } } } else { FreeDecorFace(dpy, &TB_STATE(*tb)[bs_start]); memcpy( &(TB_STATE(*tb)[bs_start]), &tmpdf, sizeof(DecorFace)); for (i = bs_start + 1; i <= bs_end; ++i) { if (multiple && (i & use_mask) != set_mask) { continue; } ReadDecorFace( spec, &TB_STATE(*tb)[i], button, False); } } } if (pstyle) { free(spec); end++; end = SkipSpaces(end, NULL, 0); } return end; } /* Remove the given decor from all windows */ static void __remove_window_decors(F_CMD_ARGS, FvwmDecor *d) { const exec_context_t *exc2; exec_context_changes_t ecc; FvwmWindow *t; for (t = Scr.FvwmRoot.next; t; t = t->next) { if (t->decor == d) { /* remove the extra title height now because we delete * the current decor before calling ChangeDecor(). */ t->g.frame.height -= t->decor->title_height; t->decor = NULL; ecc.w.fw = t; ecc.w.wcontext = C_WINDOW; exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_WCONTEXT); execute_function( cond_rc, exc2, "ChangeDecor Default", 0); exc_destroy_context(exc2); } } return; } static void do_title_style(F_CMD_ARGS, Bool do_add) { char *parm; char *prev; FvwmDecor *decor = Scr.cur_decor ? Scr.cur_decor : &Scr.DefaultDecor; Scr.flags.do_need_window_update = 1; decor->flags.has_changed = 1; decor->titlebar.flags.has_changed = 1; for (prev = action ; (parm = PeekToken(action, &action)); prev = action) { if (!do_add && StrEquals(parm,"centered")) { TB_JUSTIFICATION(decor->titlebar) = JUST_CENTER; } else if (!do_add && StrEquals(parm,"leftjustified")) { TB_JUSTIFICATION(decor->titlebar) = JUST_LEFT; } else if (!do_add && StrEquals(parm,"rightjustified")) { TB_JUSTIFICATION(decor->titlebar) = JUST_RIGHT; } else if (!do_add && StrEquals(parm,"height")) { int height = 0; int next = 0; if (!action || sscanf(action, "%d%n", &height, &next) <= 0 || height < MIN_FONT_HEIGHT || height > MAX_FONT_HEIGHT) { if (height != 0) { fvwm_msg(ERR, "do_title_style", "bad height argument (height" " must be from 5 to 256)"); height = 0; } } if (decor->title_height != height || decor->min_title_height != 0) { decor->title_height = height; decor->min_title_height = 0; decor->flags.has_title_height_changed = 1; } if (action) action += next; } else if (!do_add && StrEquals(parm,"MinHeight")) { int height = 0; int next = 0; if (!action || sscanf(action, "%d%n", &height, &next) <= 0 || height < MIN_FONT_HEIGHT || height > MAX_FONT_HEIGHT) { if (height < MIN_FONT_HEIGHT) height = MIN_FONT_HEIGHT; else if (height > MAX_FONT_HEIGHT) height = 0; } if (decor->min_title_height != height) { decor->title_height = 0; decor->min_title_height = height; decor->flags.has_title_height_changed = 1; } if (action) action += next; } else { action = ReadTitleButton( prev, &decor->titlebar, do_add, -1); } } return; } /* * * Reads a multi-pixmap titlebar config. (tril@igs.net) * */ static char *ReadMultiPixmapDecor(char *s, DecorFace *df) { static char *pm_names[TBMP_NUM_PIXMAPS+1] = { "Main", "LeftMain", "RightMain", "LeftButtons", "RightButtons", "UnderText", "LeftOfText", "RightOfText", "LeftEnd", "RightEnd", "Buttons", NULL }; FvwmPicture **pm; FvwmAcs *acs; Pixel *pixels; char *token; Bool stretched; Bool load_pixmap = False; int pm_id, i = 0; FvwmPictureAttributes fpa; df->style.face_type = MultiPixmap; df->u.mp.pixmaps = pm = (FvwmPicture**)safecalloc( TBMP_NUM_PIXMAPS, sizeof(FvwmPicture*)); df->u.mp.acs = acs = (FvwmAcs *)safemalloc(TBMP_NUM_PIXMAPS * sizeof(FvwmAcs)); df->u.mp.pixels = pixels = (Pixel *)safemalloc(TBMP_NUM_PIXMAPS * sizeof(Pixel)); for(i=0; i < TBMP_NUM_PIXMAPS; i++) { acs[i].cs = -1; acs[i].alpha_percent = 100; } s = GetNextTokenIndex(s, pm_names, 0, &pm_id); while (pm_id >= 0) { stretched = False; load_pixmap = False; s = DoPeekToken(s, &token, ",()", NULL, NULL); if (StrEquals(token, "stretched")) { stretched = True; s = DoPeekToken(s, &token, ",", NULL, NULL); } else if (StrEquals(token, "tiled")) { s = DoPeekToken(s, &token, ",", NULL, NULL); } if (!token) { break; } if (pm[pm_id] || acs[pm_id].cs >= 0 || (df->u.mp.solid_flags & (1 << pm_id))) { fvwm_msg(WARN, "ReadMultiPixmapDecor", "Ignoring: already-specified %s", pm_names[i]); continue; } if (stretched) { df->u.mp.stretch_flags |= (1 << pm_id); } if (strncasecmp (token, "Colorset", 8) == 0) { int val; char *tmp; tmp = DoPeekToken(s, &token, ",", NULL, NULL); if (!GetIntegerArguments(token, NULL, &val, 1) || val < 0) { fvwm_msg( ERR, "ReadMultiPixmapDecor", "Colorset shoule take one or two " "positive integers as argument"); } else { acs[pm_id].cs = val; alloc_colorset(val); s = tmp; tmp = DoPeekToken(s, &token, ",", NULL, NULL); if (GetIntegerArguments(token, NULL, &val, 1)) { acs[pm_id].alpha_percent = max(0, min(100,val)); s = tmp; } } } else if (strncasecmp(token, "TiledPixmap", 11) == 0) { s = DoPeekToken(s, &token, ",", NULL, NULL); load_pixmap = True; } else if (strncasecmp(token, "AdjustedPixmap", 14) == 0) { s = DoPeekToken(s, &token, ",", NULL, NULL); load_pixmap = True; df->u.mp.stretch_flags |= (1 << pm_id); } else if (strncasecmp(token, "Solid", 5) == 0) { s = DoPeekToken(s, &token, ",", NULL, NULL); if (token) { df->u.mp.pixels[pm_id] = GetColor(token); df->u.mp.solid_flags |= (1 << pm_id); } } else { load_pixmap = True; } if (load_pixmap && token) { fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; /* ? */ pm[pm_id] = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, token, fpa); if (!pm[pm_id]) { fvwm_msg(ERR, "ReadMultiPixmapDecor", "Pixmap '%s' could not be loaded", token); } } if (pm_id == TBMP_BUTTONS) { if (pm[TBMP_LEFT_BUTTONS]) { PDestroyFvwmPicture(dpy, pm[TBMP_LEFT_BUTTONS]); } if (pm[TBMP_RIGHT_BUTTONS]) { PDestroyFvwmPicture(dpy, pm[TBMP_RIGHT_BUTTONS]); } df->u.mp.stretch_flags &= ~(1 << TBMP_LEFT_BUTTONS); df->u.mp.stretch_flags &= ~(1 << TBMP_RIGHT_BUTTONS); df->u.mp.solid_flags &= ~(1 << TBMP_LEFT_BUTTONS); df->u.mp.solid_flags &= ~(1 << TBMP_RIGHT_BUTTONS); if (pm[TBMP_BUTTONS]) { pm[TBMP_LEFT_BUTTONS] = PCloneFvwmPicture(pm[TBMP_BUTTONS]); acs[TBMP_LEFT_BUTTONS].cs = -1; pm[TBMP_RIGHT_BUTTONS] = PCloneFvwmPicture(pm[TBMP_BUTTONS]); acs[TBMP_RIGHT_BUTTONS].cs = -1; } else { pm[TBMP_RIGHT_BUTTONS] = pm[TBMP_LEFT_BUTTONS] = NULL; acs[TBMP_RIGHT_BUTTONS].cs = acs[TBMP_LEFT_BUTTONS].cs = acs[TBMP_BUTTONS].cs; acs[TBMP_RIGHT_BUTTONS].alpha_percent = acs[TBMP_LEFT_BUTTONS].alpha_percent = acs[TBMP_BUTTONS].alpha_percent; pixels[TBMP_LEFT_BUTTONS] = pixels[TBMP_RIGHT_BUTTONS] = pixels[TBMP_BUTTONS]; } if (stretched) { df->u.mp.stretch_flags |= (1 << TBMP_LEFT_BUTTONS) | (1 << TBMP_RIGHT_BUTTONS); } if (df->u.mp.solid_flags & (1 << TBMP_BUTTONS)) { df->u.mp.solid_flags |= (1 << TBMP_LEFT_BUTTONS); df->u.mp.solid_flags |= (1 << TBMP_RIGHT_BUTTONS); } if (pm[TBMP_BUTTONS]) { PDestroyFvwmPicture(dpy, pm[TBMP_BUTTONS]); pm[TBMP_BUTTONS] = NULL; } acs[TBMP_BUTTONS].cs = -1; df->u.mp.solid_flags &= ~(1 << TBMP_BUTTONS); } s = SkipSpaces(s, NULL, 0); s = GetNextTokenIndex(s, pm_names, 0, &pm_id); } if (!(pm[TBMP_MAIN] || acs[TBMP_MAIN].cs >= 0 || (df->u.mp.solid_flags & TBMP_MAIN)) && !(pm[TBMP_LEFT_MAIN] || acs[TBMP_LEFT_MAIN].cs >= 0 || (df->u.mp.solid_flags & TBMP_LEFT_MAIN)) && !(pm[TBMP_RIGHT_MAIN] || acs[TBMP_RIGHT_MAIN].cs >= 0 || (df->u.mp.solid_flags & TBMP_RIGHT_MAIN))) { fvwm_msg(ERR, "ReadMultiPixmapDecor", "No Main pixmap/colorset/solid found for TitleStyle " "MultiPixmap (you must specify either Main, " "or both LeftMain and RightMain)"); for (i=0; i < TBMP_NUM_PIXMAPS; i++) { if (pm[i]) { PDestroyFvwmPicture(dpy, pm[i]); } else if (!!(df->u.mp.solid_flags & i)) { PictureFreeColors( dpy, Pcmap, &df->u.mp.pixels[i], 1, 0, False); } } free(pm); free(acs); free(pixels); return NULL; } return s; } /* * * DestroyFvwmDecor -- frees all memory assocated with an FvwmDecor * structure, but does not free the FvwmDecor itself * */ static void DestroyFvwmDecor(FvwmDecor *decor) { int i; /* reset to default button set (frees allocated mem) */ DestroyAllButtons(decor); for (i = 0; i < BS_MaxButtonState; ++i) { FreeDecorFace(dpy, &TB_STATE(decor->titlebar)[i]); } FreeDecorFace(dpy, &decor->BorderStyle.active); FreeDecorFace(dpy, &decor->BorderStyle.inactive); if (decor->tag) { free(decor->tag); decor->tag = NULL; } return; } static void SetLayerButtonFlag( int layer, int multi, int set, FvwmDecor *decor, TitleButton *tb) { int i; int start = 0; int add = 2; if (multi) { if (multi == 2) { start = 1; } else if (multi == 3) { add = 1; } for (i = start; i < NUMBER_OF_TITLE_BUTTONS; i += add) { if (set) { TB_FLAGS(decor->buttons[i]).has_layer = 1; TB_LAYER(decor->buttons[i]) = layer; } else { TB_FLAGS(decor->buttons[i]).has_layer = 0; } } } else { if (set) { TB_FLAGS(*tb).has_layer = 1; TB_LAYER(*tb) = layer; } else { TB_FLAGS(*tb).has_layer = 0; } } return; } /* * * Changes a button decoration style (changes by veliaa@rpi.edu) * */ static void SetMWMButtonFlag( mwm_flags flag, int multi, int set, FvwmDecor *decor, TitleButton *tb) { int i; int start = 0; int add = 2; if (multi) { if (multi == 2) { start = 1; } else if (multi == 3) { add = 1; } for (i = start; i < NUMBER_OF_TITLE_BUTTONS; i += add) { if (set) { TB_MWM_DECOR_FLAGS(decor->buttons[i]) |= flag; } else { TB_MWM_DECOR_FLAGS(decor->buttons[i]) &= ~flag; } } } else { if (set) { TB_MWM_DECOR_FLAGS(*tb) |= flag; } else { TB_MWM_DECOR_FLAGS(*tb) &= ~flag; } } return; } static void do_button_style(F_CMD_ARGS, Bool do_add) { int i; int multi = 0; int button = 0; int do_return; char *text = NULL; char *prev = NULL; char *parm = NULL; TitleButton *tb = NULL; FvwmDecor *decor = Scr.cur_decor ? Scr.cur_decor : &Scr.DefaultDecor; parm = PeekToken(action, &text); if (parm && isdigit(*parm)) { button = atoi(parm); button = BUTTON_INDEX(button); } if (parm == NULL || button >= NUMBER_OF_TITLE_BUTTONS || button < 0) { fvwm_msg( ERR, "ButtonStyle", "Bad button style (1) in line %s", action); return; } Scr.flags.do_need_window_update = 1; do_return = 0; if (!isdigit(*parm)) { if (StrEquals(parm,"left")) { multi = 1; /* affect all left buttons */ } else if (StrEquals(parm,"right")) { multi = 2; /* affect all right buttons */ } else if (StrEquals(parm,"all")) { multi = 3; /* affect all buttons */ } else { /* we're either resetting buttons or an invalid button * set was specified */ if (StrEquals(parm,"reset")) { ResetAllButtons(decor); } else { fvwm_msg( ERR, "ButtonStyle", "Bad button style (2) in line %s", action); } multi = 3; do_return = 1; } } /* mark button style and decor as changed */ decor->flags.has_changed = 1; if (multi == 0) { /* a single button was specified */ tb = &decor->buttons[button]; TB_FLAGS(*tb).has_changed = 1; } else { for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { if (((multi & 1) && !(i & 1)) || ((multi & 2) && (i & 1))) { TB_FLAGS(decor->buttons[i]).has_changed = 1; } } } if (do_return == 1) { return; } for (prev = text; (parm = PeekToken(text, &text)); prev = text) { if (!do_add && strcmp(parm,"-") == 0) { char *tok; text = GetNextToken(text, &tok); while (tok) { int set = 1; char *old_tok = NULL; if (*tok == '!') { /* flag negate */ set = 0; old_tok = tok; tok++; } if (StrEquals(tok,"Clear")) { if (multi) { for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { if (((multi & 1) && !(i & 1)) || ((multi & 2) && (i & 1))) { TB_JUSTIFICATION(decor->buttons[i]) = (set) ? JUST_CENTER : JUST_RIGHT; memset(&TB_FLAGS(decor->buttons[i]), (set) ? 0 : 0xff, sizeof(TB_FLAGS(decor->buttons[i]))); /* ? not very useful if set == 0 ? */ } } } else { TB_JUSTIFICATION(*tb) = (set) ? JUST_CENTER : JUST_RIGHT; memset(&TB_FLAGS(*tb), (set) ? 0 : 0xff, sizeof(TB_FLAGS(*tb))); /* ? not very useful if * set == 0 ? */ } } else if (StrEquals(tok, "MWMDecorMenu")) { SetMWMButtonFlag( MWM_DECOR_MENU, multi, set, decor, tb); } else if (StrEquals(tok, "MWMDecorMin")) { SetMWMButtonFlag( MWM_DECOR_MINIMIZE, multi, set, decor, tb); } else if (StrEquals(tok, "MWMDecorMax")) { SetMWMButtonFlag( MWM_DECOR_MAXIMIZE, multi, set, decor, tb); } else if (StrEquals(tok, "MWMDecorShade")) { SetMWMButtonFlag( MWM_DECOR_SHADE, multi, set, decor, tb); } else if (StrEquals(tok, "MWMDecorStick")) { SetMWMButtonFlag( MWM_DECOR_STICK, multi, set, decor, tb); } else if (StrEquals(tok, "MwmDecorLayer")) { int layer, got_number; char *ltok; text = GetNextToken(text, <ok); if (ltok) { got_number = (sscanf(ltok, "%d", &layer) == 1); free (ltok); } else { got_number = 0; } if (!ltok || !got_number) { fvwm_msg(ERR, "ButtonStyle", "could not read" " integer value for" " layer -- line: %s", text); } else { SetLayerButtonFlag( layer, multi, set, decor, tb); } } else { fvwm_msg(ERR, "ButtonStyle", "unknown title button flag" " %s -- line: %s", tok, text); } if (set) { free(tok); } else { free(old_tok); } text = GetNextToken(text, &tok); } break; } else { if (multi) { for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { if (((multi & 1) && !(i & 1)) || ((multi & 2) && (i & 1))) { text = ReadTitleButton( prev, &decor->buttons[i], do_add, i); } } } else if (!(text = ReadTitleButton( prev, tb, do_add, button))) { break; } } } return; } static int update_decorface_colorset(DecorFace *df, int cset) { DecorFace *tdf; int has_changed = 0; for(tdf = df; tdf != NULL; tdf = tdf->next) { if (DFS_FACE_TYPE(tdf->style) == ColorsetButton && tdf->u.acs.cs == cset) { tdf->flags.has_changed = 1; has_changed = 1; } else if (DFS_FACE_TYPE(tdf->style) == MultiPixmap) { int i; for (i = 0; i < TBMP_NUM_PIXMAPS; i++) { if (tdf->u.mp.acs[i].cs == cset) { tdf->flags.has_changed = 1; has_changed = 1; } } } } return has_changed; } static int update_titlebutton_colorset(TitleButton *tb, int cset) { int i; int has_changed = 0; for(i = 0; i < BS_MaxButtonState; i++) { tb->state[i].flags.has_changed = update_decorface_colorset(&(tb->state[i]), cset); has_changed |= tb->state[i].flags.has_changed; } return has_changed; } static void update_decors_colorset(int cset) { int i; FvwmDecor *decor = &Scr.DefaultDecor; for(decor = &Scr.DefaultDecor; decor != NULL; decor = decor->next) { for(i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { decor->flags.has_changed |= update_titlebutton_colorset( &(decor->buttons[i]), cset); } decor->flags.has_changed |= update_titlebutton_colorset( &(decor->titlebar), cset); decor->flags.has_changed |= update_decorface_colorset( &(decor->BorderStyle.active), cset); decor->flags.has_changed |= update_decorface_colorset( &(decor->BorderStyle.inactive), cset); if (decor->flags.has_changed) { Scr.flags.do_need_window_update = 1; } } } static Bool __parse_vector_line_one_coord( char **ret_action, int *pcoord, int *poff, char *action) { int offset; int n; *ret_action = action; n = sscanf(action, "%d%n", pcoord, &offset); if (n < 1) { return False; } action += offset; /* check for offest */ if (*action == '+' || *action == '-') { n = sscanf(action, "%dp%n", poff, &offset); if (n < 1) { return False; } if (*poff < -128) { *poff = -128; } else if (*poff > 127) { *poff = 127; } action += offset; } else { *poff = 0; } *ret_action = action; return True; } static Bool __parse_vector_line( char **ret_action, int *px, int *py, int *pxoff, int *pyoff, int *pc, char *action) { Bool is_valid = True; int offset; int n; *ret_action = action; if (__parse_vector_line_one_coord(&action, px, pxoff, action) == False) { return False; } if (*action != 'x') { return False; } action++; if (__parse_vector_line_one_coord(&action, py, pyoff, action) == False) { return False; } if (*action != '@') { return False; } action++; /* read the line style */ n = sscanf(action, "%d%n", pc, &offset); if (n < 1) { return False; } action += offset; *ret_action = action; return is_valid; } /* ---------------------------- interface functions ------------------------ */ void refresh_window(Window w, Bool window_update) { XSetWindowAttributes attributes; unsigned long valuemask; valuemask = CWOverrideRedirect | CWBackingStore | CWSaveUnder | CWBackPixmap; attributes.override_redirect = True; attributes.save_under = False; attributes.background_pixmap = None; attributes.backing_store = NotUseful; w = XCreateWindow( dpy, w, 0, 0, Scr.MyDisplayWidth, Scr.MyDisplayHeight, 0, CopyFromParent, CopyFromParent, CopyFromParent, valuemask, &attributes); XMapWindow(dpy, w); if (Scr.flags.do_need_window_update && window_update) { flush_window_updates(); } XDestroyWindow(dpy, w); XSync(dpy, 0); handle_all_expose(); return; } void ApplyDefaultFontAndColors(void) { XGCValues gcv; unsigned long gcm; int cset = Scr.DefaultColorset; /* make GC's */ gcm = GCFunction|GCLineWidth|GCForeground|GCBackground; gcv.function = GXcopy; if (Scr.DefaultFont->font) { gcm |= GCFont; gcv.font = Scr.DefaultFont->font->fid; } gcv.line_width = 0; if (cset >= 0) { gcv.foreground = Colorset[cset].fg; gcv.background = Colorset[cset].bg; } else { gcv.foreground = Scr.StdFore; gcv.background = Scr.StdBack; } if (Scr.StdGC) { XChangeGC(dpy, Scr.StdGC, gcm, &gcv); } else { Scr.StdGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); } gcm = GCFunction|GCLineWidth|GCForeground; if (cset >= 0) { gcv.foreground = Colorset[cset].hilite; } else { gcv.foreground = Scr.StdHilite; } if (Scr.StdReliefGC) { XChangeGC(dpy, Scr.StdReliefGC, gcm, &gcv); } else { Scr.StdReliefGC = fvwmlib_XCreateGC( dpy, Scr.NoFocusWin, gcm, &gcv); } if (cset >= 0) { gcv.foreground = Colorset[cset].shadow; } else { gcv.foreground = Scr.StdShadow; } if (Scr.StdShadowGC) { XChangeGC(dpy, Scr.StdShadowGC, gcm, &gcv); } else { Scr.StdShadowGC = fvwmlib_XCreateGC( dpy, Scr.NoFocusWin, gcm, &gcv); } /* update the geometry window for move/resize */ if (Scr.SizeWindow != None) { resize_geometry_window(); } UpdateAllMenuStyles(); return; } void FreeDecorFace(Display *dpy, DecorFace *df) { int i; switch (DFS_FACE_TYPE(df->style)) { case GradientButton: if (df->u.grad.d_pixels != NULL && df->u.grad.d_npixels) { PictureFreeColors( dpy, Pcmap, df->u.grad.d_pixels, df->u.grad.d_npixels, 0, False); free(df->u.grad.d_pixels); } else if (Pdepth <= 8 && df->u.grad.xcs != NULL && df->u.grad.npixels > 0 && !df->u.grad.do_dither) { Pixel *p; int i; p = (Pixel *)safemalloc( df->u.grad.npixels * sizeof(Pixel)); for(i=0; i < df->u.grad.npixels; i++) { p[i] = df->u.grad.xcs[i].pixel; } PictureFreeColors( dpy, Pcmap, p, df->u.grad.npixels, 0, False); free(p); } if (df->u.grad.xcs != NULL) { free(df->u.grad.xcs); } break; case PixmapButton: case TiledPixmapButton: case StretchedPixmapButton: case AdjustedPixmapButton: case ShrunkPixmapButton: if (df->u.p) { PDestroyFvwmPicture(dpy, df->u.p); } break; case MultiPixmap: if (df->u.mp.pixmaps) { for (i = 0; i < TBMP_NUM_PIXMAPS; i++) { if (df->u.mp.pixmaps[i]) { PDestroyFvwmPicture( dpy, df->u.mp.pixmaps[i]); } else if (!!(df->u.mp.solid_flags & i)) { PictureFreeColors( dpy, Pcmap, &df->u.mp.pixels[i], 1, 0, False); } } free(df->u.mp.pixmaps); } if (df->u.mp.acs) { free(df->u.mp.acs); } if (df->u.mp.pixels) { free(df->u.mp.pixels); } break; case VectorButton: case DefaultVectorButton: if (df->u.vector.x) { free (df->u.vector.x); } if (df->u.vector.y) { free (df->u.vector.y); } /* free offsets for coord */ if (df->u.vector.xoff) { free(df->u.vector.xoff); } if (df->u.vector.yoff) { free(df->u.vector.yoff); } if (df->u.vector.c) { free (df->u.vector.c); } break; default: /* see below */ break; } /* delete any compound styles */ if (df->next) { FreeDecorFace(dpy, df->next); free(df->next); } df->next = NULL; memset(&df->style, 0, sizeof(df->style)); memset(&df->u, 0, sizeof(df->u)); DFS_FACE_TYPE(df->style) = SimpleButton; return; } /* * * Reads a button face line into a structure (veliaa@rpi.edu) * */ Bool ReadDecorFace(char *s, DecorFace *df, int button, int verbose) { int offset; char style[256], *file; char *action = s; /* some variants of scanf do not increase the assign count when %n is * used, so a return value of 1 is no error. */ if (sscanf(s, "%255s%n", style, &offset) < 1) { if (verbose) { fvwm_msg(ERR, "ReadDecorFace", "error in face `%s'", s); } return False; } style[255] = 0; if (strncasecmp(style, "--", 2) != 0) { s += offset; FreeDecorFace(dpy, df); /* determine button style */ if (strncasecmp(style,"Simple",6)==0) { memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = SimpleButton; } else if (strncasecmp(style,"Default",7)==0) { int b = -1, n = sscanf(s, "%d%n", &b, &offset); if (n < 1) { if (button == -1) { if (verbose) { fvwm_msg( ERR,"ReadDecorFace", "need default button" " number to load"); } return False; } b = button; } else { b = BUTTON_INDEX(b); s += offset; } if (b >= 0 && b < NUMBER_OF_TITLE_BUTTONS) { LoadDefaultButton(df, b); } else { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "button number out of range:" " %d", b); } return False; } } else if (strncasecmp(style,"Vector",6)==0 || (strlen(style)<=2 && isdigit(*style))) { /* normal coordinate list button style */ int i, num_coords, num; struct vector_coords *vc = &df->u.vector; /* get number of points */ if (strncasecmp(style,"Vector",6)==0) { num = sscanf(s,"%d%n",&num_coords,&offset); s += offset; } else { num = sscanf(style,"%d",&num_coords); } if (num < 1 || num_coords<2 || num_coords > MAX_TITLE_BUTTON_VECTOR_LINES) { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "Bad button style (2) in line:" " %s",action); } return False; } vc->num = num_coords; vc->use_fgbg = 0; vc->x = (signed char*)safemalloc(sizeof(char) * num_coords); vc->y = (signed char*)safemalloc(sizeof(char) * num_coords); vc->xoff = (signed char*)safemalloc(sizeof(char) * num_coords); vc->yoff = (signed char*)safemalloc(sizeof(char) * num_coords); vc->c = (signed char*)safemalloc(sizeof(char) * num_coords); /* get the points */ for (i = 0; i < vc->num; ++i) { int x; int y; int xoff = 0; int yoff = 0; int c; if (__parse_vector_line( &s, &x, &y, &xoff, &yoff, &c, s) == False) { break; } if (x < 0) { x = 0; } if (x > 100) { x = 100; } if (y < 0) { y = 0; } if (y > 100) { y = 100; } if (c < 0 || c > 4) { c = 4; } vc->x[i] = x; vc->y[i] = y; vc->c[i] = c; vc->xoff[i] = xoff; vc->yoff[i] = yoff; if (c == 2 || c == 3) { vc->use_fgbg = 1; } } if (i < vc->num) { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "Bad button style (3) in line" " %s", action); } free(vc->x); free(vc->y); free(vc->c); free(vc->xoff); free(vc->yoff); vc->x = NULL; vc->y = NULL; vc->c = NULL; vc->xoff = NULL; vc->yoff = NULL; return False; } memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = VectorButton; } else if (strncasecmp(style,"Solid",5)==0) { s = GetNextToken(s, &file); if (file) { memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = SolidButton; df->u.back = GetColor(file); free(file); } else { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "no color given for Solid" " face type: %s", action); } return False; } } else if (strncasecmp(style+1, "Gradient", 8)==0) { char **s_colors; int npixels, nsegs, *perc; XColor *xcs; Bool do_dither = False; if (!IsGradientTypeSupported(style[0])) { return False; } /* translate the gradient string into an array of * colors etc */ npixels = ParseGradient( s, &s, &s_colors, &perc, &nsegs); while (*s && isspace(*s)) { s++; } if (npixels <= 0) { return False; } /* grab the colors */ if (Pdepth <= 16) { do_dither = True; } xcs = AllocAllGradientColors( s_colors, perc, nsegs, npixels, do_dither); if (xcs == None) return False; df->u.grad.xcs = xcs; df->u.grad.npixels = npixels; df->u.grad.do_dither = do_dither; df->u.grad.d_pixels = NULL; memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = GradientButton; df->u.grad.gradient_type = toupper(style[0]); } else if (strncasecmp(style,"Pixmap",6)==0 || strncasecmp(style,"TiledPixmap",11)==0 || strncasecmp(style,"StretchedPixmap",15)==0 || strncasecmp(style,"AdjustedPixmap",14)==0 || strncasecmp(style,"ShrunkPixmap",12)==0) { FvwmPictureAttributes fpa; s = GetNextToken(s, &file); fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; /* ? */ df->u.p = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, file, fpa); if (df->u.p == NULL) { if (file) { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "couldn't load pixmap" " %s", file); } free(file); } return False; } if (file) { free(file); file = NULL; } memset(&df->style, 0, sizeof(df->style)); if (strncasecmp(style,"Tiled",5)==0) { DFS_FACE_TYPE(df->style) = TiledPixmapButton; } else if (strncasecmp(style,"Stretched",9)==0) { DFS_FACE_TYPE(df->style) = StretchedPixmapButton; } else if (strncasecmp(style,"Adjusted",8)==0) { DFS_FACE_TYPE(df->style) = AdjustedPixmapButton; } else if (strncasecmp(style,"Shrunk",6)==0) { DFS_FACE_TYPE(df->style) = ShrunkPixmapButton; } else { DFS_FACE_TYPE(df->style) = PixmapButton; } } else if (strncasecmp(style,"MultiPixmap",11)==0) { if (button != -1) { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "MultiPixmap is only valid" " for TitleStyle"); } return False; } s = ReadMultiPixmapDecor(s, df); if (!s) { return False; } } else if (FMiniIconsSupported && strncasecmp (style, "MiniIcon", 8) == 0) { memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = MiniIconButton; /* pixmap read in when the window is created */ df->u.p = NULL; } else if (strncasecmp (style, "Colorset", 8) == 0) { int val[2]; int n; n = GetIntegerArguments(s, NULL, val, 2); if (n == 0) { } memset(&df->style, 0, sizeof(df->style)); if (n > 0 && val[0] >= 0) { df->u.acs.cs = val[0]; alloc_colorset(val[0]); DFS_FACE_TYPE(df->style) = ColorsetButton; } df->u.acs.alpha_percent = 100; if (n > 1) { df->u.acs.alpha_percent = max(0, min(100,val[1])); } s = SkipNTokens(s, n); } else { if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "unknown style %s: %s", style, action); } return False; } } /* Process button flags ("--" signals start of flags, it is also checked for above) */ s = GetNextToken(s, &file); if (file && (strcmp(file,"--")==0)) { char *tok; s = GetNextToken(s, &tok); while (tok && *tok) { int set = 1; char *old_tok = NULL; if (*tok == '!') { /* flag negate */ set = 0; old_tok = tok; tok++; } if (StrEquals(tok,"Clear")) { memset(&DFS_FLAGS(df->style), (set) ? 0 : 0xff, sizeof(DFS_FLAGS(df->style))); /* ? what is set == 0 good for ? */ } else if (StrEquals(tok,"Left")) { if (set) { DFS_H_JUSTIFICATION(df->style) = JUST_LEFT; } else { DFS_H_JUSTIFICATION(df->style) = JUST_RIGHT; } } else if (StrEquals(tok,"Right")) { if (set) { DFS_H_JUSTIFICATION(df->style) = JUST_RIGHT; } else { DFS_H_JUSTIFICATION(df->style) = JUST_LEFT; } } else if (StrEquals(tok,"Centered")) { DFS_H_JUSTIFICATION(df->style) = JUST_CENTER; DFS_V_JUSTIFICATION(df->style) = JUST_CENTER; } else if (StrEquals(tok,"Top")) { if (set) { DFS_V_JUSTIFICATION(df->style) = JUST_TOP; } else { DFS_V_JUSTIFICATION(df->style) = JUST_BOTTOM; } } else if (StrEquals(tok,"Bottom")) { if (set) { DFS_V_JUSTIFICATION(df->style) = JUST_BOTTOM; } else { DFS_V_JUSTIFICATION(df->style) = JUST_TOP; } } else if (StrEquals(tok,"Flat")) { if (set) { DFS_BUTTON_RELIEF(df->style) = DFS_BUTTON_IS_FLAT; } else if (DFS_BUTTON_RELIEF(df->style) == DFS_BUTTON_IS_FLAT) { DFS_BUTTON_RELIEF(df->style) = DFS_BUTTON_IS_UP; } } else if (StrEquals(tok,"Sunk")) { if (set) { DFS_BUTTON_RELIEF(df->style) = DFS_BUTTON_IS_SUNK; } else if (DFS_BUTTON_RELIEF(df->style) == DFS_BUTTON_IS_SUNK) { DFS_BUTTON_RELIEF(df->style) = DFS_BUTTON_IS_UP; } } else if (StrEquals(tok,"Raised")) { if (set) { DFS_BUTTON_RELIEF(df->style) = DFS_BUTTON_IS_UP; } else { DFS_BUTTON_RELIEF(df->style) = DFS_BUTTON_IS_SUNK; } } else if (StrEquals(tok,"UseTitleStyle")) { if (set) { DFS_USE_TITLE_STYLE(df->style) = 1; DFS_USE_BORDER_STYLE(df->style) = 0; } else DFS_USE_TITLE_STYLE(df->style) = 0; } else if (StrEquals(tok,"HiddenHandles")) { DFS_HAS_HIDDEN_HANDLES(df->style) = !!set; } else if (StrEquals(tok,"NoInset")) { DFS_HAS_NO_INSET(df->style) = !!set; } else if (StrEquals(tok,"UseBorderStyle")) { if (set) { DFS_USE_BORDER_STYLE(df->style) = 1; DFS_USE_TITLE_STYLE(df->style) = 0; } else { DFS_USE_BORDER_STYLE(df->style) = 0; } } else if (verbose) { fvwm_msg( ERR, "ReadDecorFace", "unknown button face flag '%s'" " -- line: %s", tok, action); } if (set) { free(tok); } else { free(old_tok); } s = GetNextToken(s, &tok); } } if (file) { free(file); } return True; } /* * * Diverts a style definition to an FvwmDecor structure (veliaa@rpi.edu) * */ void AddToDecor(F_CMD_ARGS, FvwmDecor *decor) { if (!action) { return; } while (*action && isspace((unsigned char)*action)) { ++action; } if (!*action) { return; } Scr.cur_decor = decor; execute_function(cond_rc, exc, action, 0); Scr.cur_decor = NULL; return; } /* * * InitFvwmDecor -- initializes an FvwmDecor structure to defaults * */ void InitFvwmDecor(FvwmDecor *decor) { int i; DecorFace tmpdf; /* zero out the structures */ memset(decor, 0, sizeof (FvwmDecor)); memset(&tmpdf, 0, sizeof(DecorFace)); /* initialize title-bar button styles */ DFS_FACE_TYPE(tmpdf.style) = SimpleButton; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { int j = 0; for (; j < BS_MaxButtonState; ++j) { TB_STATE(decor->buttons[i])[j] = tmpdf; } } /* reset to default button set */ ResetAllButtons(decor); /* initialize title-bar styles */ for (i = 0; i < BS_MaxButtonState; ++i) { DFS_FACE_TYPE( TB_STATE(decor->titlebar)[i].style) = SimpleButton; } /* initialize border texture styles */ DFS_FACE_TYPE(decor->BorderStyle.active.style) = SimpleButton; DFS_FACE_TYPE(decor->BorderStyle.inactive.style) = SimpleButton; return; } void reset_decor_changes(void) { FvwmDecor *decor; for (decor = &Scr.DefaultDecor; decor; decor = decor->next) { decor->flags.has_changed = 0; decor->flags.has_title_height_changed = 0; } /* todo: must reset individual change flags too */ return; } void update_fvwm_colorset(int cset) { if (cset == Scr.DefaultColorset) { Scr.flags.do_need_window_update = 1; Scr.flags.has_default_color_changed = 1; } UpdateMenuColorset(cset); update_style_colorset(cset); update_decors_colorset(cset); return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_Beep(F_CMD_ARGS) { XBell(dpy, 0); return; } void CMD_Nop(F_CMD_ARGS) { return; } void CMD_EscapeFunc(F_CMD_ARGS) { return; } void CMD_CursorMove(F_CMD_ARGS) { int x = 0, y = 0; int val1, val2, val1_unit, val2_unit; int x_unit, y_unit; int virtual_x, virtual_y; int x_pages, y_pages; if (GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit) != 2) { fvwm_msg(ERR, "movecursor", "CursorMove needs 2 arguments"); return; } if (FQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ return; } x_unit = val1 * val1_unit / 100; y_unit = val2 * val2_unit / 100; x += x_unit; y += y_unit; virtual_x = Scr.Vx; virtual_y = Scr.Vy; if (x >= 0) { x_pages = x / Scr.MyDisplayWidth; } else { x_pages = ((x + 1) / Scr.MyDisplayWidth) - 1; } virtual_x += x_pages * Scr.MyDisplayWidth; x -= x_pages * Scr.MyDisplayWidth; if (virtual_x < 0) { x += virtual_x; virtual_x = 0; } else if (virtual_x > Scr.VxMax) { x += virtual_x - Scr.VxMax; virtual_x = Scr.VxMax; } if (y >= 0) { y_pages = y / Scr.MyDisplayHeight; } else { y_pages = ((y + 1) / Scr.MyDisplayHeight) - 1; } virtual_y += y_pages * Scr.MyDisplayHeight; y -= y_pages * Scr.MyDisplayHeight; if (virtual_y < 0) { y += virtual_y; virtual_y = 0; } else if (virtual_y > Scr.VyMax) { y += virtual_y - Scr.VyMax; virtual_y = Scr.VyMax; } /* TA: (2010/12/19): Only move to the new page if scrolling is * enabled and the viewport is able to change based on where the * pointer is. */ if ((virtual_x != Scr.Vx && Scr.EdgeScrollX != 0) || (virtual_y != Scr.Vy && Scr.EdgeScrollY != 0)) { MoveViewport(virtual_x, virtual_y, True); } /* TA: (2010/12/19): If the cursor is about to enter a pan-window, or * is one, or the cursor's next step is to go beyond the page * boundary, stop the cursor from moving in that direction, *if* we've * disallowed edge scrolling. * * Whilst this stops the cursor short of the edge of the screen in a * given direction, this is the desired behaviour. */ if (Scr.EdgeScrollX == 0 && (x >= Scr.MyDisplayWidth || x + x_unit >= Scr.MyDisplayWidth)) return; if (Scr.EdgeScrollY == 0 && (y >= Scr.MyDisplayHeight || y + y_unit >= Scr.MyDisplayHeight)) return; FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, Scr.MyDisplayWidth, Scr.MyDisplayHeight, x, y); return; } void CMD_Delete(F_CMD_ARGS) { FvwmWindow * const fw = exc->w.fw; if (!is_function_allowed(F_DELETE, NULL, fw, RQORIG_PROGRAM_US, True)) { XBell(dpy, 0); return; } if (IS_TEAR_OFF_MENU(fw)) { /* 'soft' delete tear off menus. Note: we can't send the * message to the menu window directly because it was created * using a different display. The client message would never * be read from there. */ send_clientmessage( dpy, FW_W_PARENT(fw), _XA_WM_DELETE_WINDOW, CurrentTime); return; } if (WM_DELETES_WINDOW(fw)) { send_clientmessage( dpy, FW_W(fw), _XA_WM_DELETE_WINDOW, CurrentTime); return; } else { XBell(dpy, 0); } XFlush(dpy); return; } void CMD_Destroy(F_CMD_ARGS) { FvwmWindow * const fw = exc->w.fw; if (IS_TEAR_OFF_MENU(fw)) { CMD_Delete(F_PASS_ARGS); return; } if (!is_function_allowed(F_DESTROY, NULL, fw, True, True)) { XBell(dpy, 0); return; } if ( XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) != 0) { XKillClient(dpy, FW_W(fw)); } destroy_window(fw); XFlush(dpy); return; } void CMD_Close(F_CMD_ARGS) { FvwmWindow * const fw = exc->w.fw; if (IS_TEAR_OFF_MENU(fw)) { CMD_Delete(F_PASS_ARGS); return; } if (!is_function_allowed(F_CLOSE, NULL, fw, True, True)) { XBell(dpy, 0); return; } if (WM_DELETES_WINDOW(fw)) { send_clientmessage( dpy, FW_W(fw), _XA_WM_DELETE_WINDOW, CurrentTime); return; } if ( XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) != 0) { XKillClient(dpy, FW_W(fw)); } destroy_window(fw); XFlush(dpy); return; } void CMD_Restart(F_CMD_ARGS) { Done(1, action); return; } void CMD_ExecUseShell(F_CMD_ARGS) { char *arg=NULL; static char shell_set = 0; if (shell_set) { free(exec_shell_name); } shell_set = 1; action = GetNextToken(action,&arg); if (arg) /* specific shell was specified */ { exec_shell_name = arg; } else /* no arg, so use $SHELL -- not working??? */ { if (getenv("SHELL")) { exec_shell_name = safestrdup(getenv("SHELL")); } else { /* if $SHELL not set, use default */ exec_shell_name = safestrdup("/bin/sh"); } } } void CMD_Exec(F_CMD_ARGS) { char *cmd=NULL; /* if it doesn't already have an 'exec' as the first word, add that * to keep down number of procs started */ /* need to parse string better to do this right though, so not doing * this for now... */ #if 0 if (strncasecmp(action,"exec",4)!=0) { cmd = (char *)safemalloc(strlen(action)+6); strcpy(cmd,"exec "); strcat(cmd,action); } else #endif { cmd = safestrdup(action); } if (!cmd) { return; } /* Use to grab the pointer here, but the fork guarantees that * we wont be held up waiting for the function to finish, * so the pointer-gram just caused needless delay and flashing * on the screen */ /* Thought I'd try vfork and _exit() instead of regular fork(). * The man page says that its better. */ /* Not everyone has vfork! */ /* According to the man page, vfork should never be used at all. */ if (!(fork())) /* child process */ { /* This is for fixing a problem with rox filer */ int fd; fvmm_deinstall_signals(); fd = open("/dev/null", O_RDONLY, 0); dup2(fd,STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); if (fvwm_setpgrp() == -1) { fvwm_msg(ERR, "exec_function", "setpgrp failed (%s)", strerror(errno)); exit(100); } if (execl(exec_shell_name, exec_shell_name, "-c", cmd, NULL) == -1) { fvwm_msg(ERR, "exec_function", "execl failed (%s)", strerror(errno)); exit(100); } } free(cmd); return; } void CMD_Refresh(F_CMD_ARGS) { refresh_window(Scr.Root, True); return; } void CMD_RefreshWindow(F_CMD_ARGS) { FvwmWindow * const fw = exc->w.fw; refresh_window( (exc->w.wcontext == C_ICON) ? FW_W_ICON_TITLE(fw) : FW_W_FRAME(fw), True); return; } void CMD_Wait(F_CMD_ARGS) { Bool done = False; Bool redefine_cursor = False; Bool is_ungrabbed; char *escape; Window nonewin = None; char *wait_string, *rest; FvwmWindow *t; /* try to get a single token */ rest = GetNextToken(action, &wait_string); if (wait_string) { while (*rest && isspace((unsigned char)*rest)) { rest++; } if (*rest) { int i; char *temp; /* nope, multiple tokens - try old syntax */ /* strip leading and trailing whitespace */ temp = action; while (*temp && isspace((unsigned char)*temp)) { temp++; } free(wait_string); wait_string = safestrdup(temp); for (i = strlen(wait_string) - 1; i >= 0 && isspace(wait_string[i]); i--) { wait_string[i] = 0; } } } else { wait_string = safestrdup(""); } is_ungrabbed = UngrabEm(GRAB_NORMAL); while (!done && !isTerminated) { XEvent e; if (BUSY_WAIT & Scr.BusyCursor) { XDefineCursor(dpy, Scr.Root, Scr.FvwmCursors[CRS_WAIT]); redefine_cursor = True; } if (My_XNextEvent(dpy, &e)) { dispatch_event(&e); if (XFindContext( dpy, e.xmap.window, FvwmContext, (caddr_t *)&t) == XCNOENT) { t = NULL; } if (e.type == MapNotify && e.xmap.event == Scr.Root) { if (!*wait_string) { done = True; } if (t && matchWildcards( wait_string, t->name.name) == True) { done = True; } else if (t && t->class.res_class && matchWildcards( wait_string, t->class.res_class) == True) { done = True; } else if (t && t->class.res_name && matchWildcards( wait_string, t->class.res_name) == True) { done = True; } } else if (e.type == KeyPress) { /* should I be using or w.fw>? * DV: t */ int context; XClassHint *class; char *name; context = GetContext(&t, t, &e, &nonewin); if (t != NULL) { class = &(t->class); name = t->name.name; } else { class = NULL; name = NULL; } escape = CheckBinding( Scr.AllBindings, STROKE_ARG(0) e.xkey.keycode, e.xkey.state, GetUnusedModifiers(), context, BIND_KEYPRESS, class, name); if (escape != NULL) { if (!strcasecmp(escape,"escapefunc")) { done = True; } } } } } if (redefine_cursor) { XDefineCursor(dpy, Scr.Root, Scr.FvwmCursors[CRS_ROOT]); } if (is_ungrabbed) { GrabEm(CRS_NONE, GRAB_NORMAL); } free(wait_string); return; } void CMD_Quit(F_CMD_ARGS) { if (master_pid != getpid()) { kill(master_pid, SIGTERM); } Done(0,NULL); return; } void CMD_QuitScreen(F_CMD_ARGS) { Done(0,NULL); return; } void CMD_Echo(F_CMD_ARGS) { int len; if (!action) { action = ""; } len = strlen(action); if (len != 0) { if (action[len-1]=='\n') { action[len-1]='\0'; } } fvwm_msg(ECHO, "Echo", "%s", action); return; } void CMD_PrintInfo(F_CMD_ARGS) { int verbose; char *rest, *subject = NULL; rest = GetNextToken(action, &subject); if (!rest || GetIntegerArguments(rest, NULL, &verbose, 1) != 1) { verbose = 0; } if (StrEquals(subject, "Colors")) { PicturePrintColorInfo(verbose); } else if (StrEquals(subject, "Locale")) { FlocalePrintLocaleInfo(dpy, verbose); } else if (StrEquals(subject, "NLS")) { FGettextPrintLocalePath(verbose); } else if (StrEquals(subject, "style")) { print_styles(verbose); } else if (StrEquals(subject, "ImageCache")) { PicturePrintImageCache(verbose); } else if (StrEquals(subject, "Bindings")) { print_bindings(); } else if (StrEquals(subject, "InfoStore")) { print_infostore(); } else { fvwm_msg(ERR, "PrintInfo", "Unknown subject '%s'", action); } if (subject) { free(subject); } return; } void CMD_ColormapFocus(F_CMD_ARGS) { if (MatchToken(action,"FollowsFocus")) { Scr.ColormapFocus = COLORMAP_FOLLOWS_FOCUS; } else if (MatchToken(action,"FollowsMouse")) { Scr.ColormapFocus = COLORMAP_FOLLOWS_MOUSE; } else { fvwm_msg(ERR, "SetColormapFocus", "ColormapFocus requires 1 arg: FollowsFocus or" " FollowsMouse"); return; } return; } void CMD_ClickTime(F_CMD_ARGS) { int val; if (GetIntegerArguments(action, NULL, &val, 1) != 1) { Scr.ClickTime = DEFAULT_CLICKTIME; } else { Scr.ClickTime = (val < 0)? 0 : val; } /* Use a negative value during startup and change sign afterwards. This * speeds things up quite a bit. */ if (fFvwmInStartup) { Scr.ClickTime = -Scr.ClickTime; } return; } void CMD_ImagePath(F_CMD_ARGS) { PictureSetImagePath( action ); return; } void CMD_IconPath(F_CMD_ARGS) { fvwm_msg(ERR, "iconPath_function", "IconPath is deprecated since 2.3.0; use ImagePath instead."); obsolete_imagepaths( action ); return; } void CMD_PixmapPath(F_CMD_ARGS) { fvwm_msg(ERR, "pixmapPath_function", "PixmapPath is deprecated since 2.3.0; use ImagePath" " instead." ); obsolete_imagepaths( action ); return; } void CMD_LocalePath(F_CMD_ARGS) { FGettextSetLocalePath( action ); return; } void CMD_ModulePath(F_CMD_ARGS) { static int need_to_free = 0; setPath( &ModulePath, action, need_to_free ); need_to_free = 1; return; } void CMD_ModuleTimeout(F_CMD_ARGS) { int timeout; moduleTimeout = DEFAULT_MODULE_TIMEOUT; if (GetIntegerArguments(action, NULL, &timeout, 1) == 1 && timeout > 0) { moduleTimeout = timeout; } return; } void CMD_HilightColor(F_CMD_ARGS) { char *fore; char *back; if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) { fvwm_msg( ERR, "SetHiColor", "Decors do not support the HilightColor command" " anymore. Please use" " 'Style HilightFore ' and" " 'Style HilightBack ' instead." " Sorry for the inconvenience."); return; } action = GetNextToken(action, &fore); GetNextToken(action, &back); if (fore && back) { action = safemalloc(strlen(fore) + strlen(back) + 29); sprintf(action, "* HilightFore %s, HilightBack %s", fore, back); CMD_Style(F_PASS_ARGS); } if (fore) { free(fore); } if (back) { free(back); } return; } void CMD_HilightColorset(F_CMD_ARGS) { char *newaction; if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) { fvwm_msg( ERR, "SetHiColorset", "Decors do not support the HilightColorset command " "anymore. Please use " "'Style HilightColorset '" " instead. Sorry for the inconvenience."); return; } if (action) { newaction = safemalloc(strlen(action) + 32); sprintf(newaction, "* HilightColorset %s", action); action = newaction; CMD_Style(F_PASS_ARGS); free(newaction); } return; } void CMD_TitleStyle(F_CMD_ARGS) { do_title_style(F_PASS_ARGS, False); return; } /* SetTitleStyle */ /* * * Appends a titlestyle (veliaa@rpi.edu) * */ void CMD_AddTitleStyle(F_CMD_ARGS) { do_title_style(F_PASS_ARGS, True); return; } void CMD_PropertyChange(F_CMD_ARGS) { char string[256]; char *token; char *rest; int ret; unsigned long argument; unsigned long data1; unsigned long data2; /* argument */ token = PeekToken(action, &rest); if (token == NULL) { return; } ret = sscanf(token, "%lu", &argument); if (ret < 1) { return; } /* data1 */ data1 = 0; token = PeekToken(rest, &rest); if (token != NULL) { ret = sscanf(token, "%lu", &data1); if (ret < 1) { rest = NULL; } } /* data2 */ data2 = 0; token = PeekToken(rest, &rest); if (token != NULL) { ret = sscanf(token, "%lu", &data2); if (ret < 1) { rest = NULL; } } /* string */ memset(string, 0, 256); if (rest != NULL) { ret = sscanf(rest, "%255c", &(string[0])); } BroadcastPropertyChange(argument, data1, data2, string); return; } void CMD_DefaultIcon(F_CMD_ARGS) { if (Scr.DefaultIcon) { free(Scr.DefaultIcon); } GetNextToken(action, &Scr.DefaultIcon); return; } void CMD_DefaultColorset(F_CMD_ARGS) { int cset; if (GetIntegerArguments(action, NULL, &cset, 1) != 1) { return; } Scr.DefaultColorset = cset; if (Scr.DefaultColorset < 0) { Scr.DefaultColorset = -1; } alloc_colorset(Scr.DefaultColorset); Scr.flags.do_need_window_update = 1; Scr.flags.has_default_color_changed = 1; return; } void CMD_DefaultColors(F_CMD_ARGS) { char *fore = NULL; char *back = NULL; action = GetNextToken(action, &fore); if (action) { action = GetNextToken(action, &back); } if (!back) { back = safestrdup(DEFAULT_BACK_COLOR); } if (!fore) { fore = safestrdup(DEFAULT_FORE_COLOR); } if (!StrEquals(fore, "-")) { PictureFreeColors(dpy, Pcmap, &Scr.StdFore, 1, 0, True); Scr.StdFore = GetColor(fore); } if (!StrEquals(back, "-")) { PictureFreeColors(dpy, Pcmap, &Scr.StdBack, 3, 0, True); Scr.StdBack = GetColor(back); Scr.StdHilite = GetHilite(Scr.StdBack); Scr.StdShadow = GetShadow(Scr.StdBack); } free(fore); free(back); Scr.DefaultColorset = -1; Scr.flags.do_need_window_update = 1; Scr.flags.has_default_color_changed = 1; return; } void CMD_DefaultFont(F_CMD_ARGS) { char *font; FlocaleFont *new_font; FvwmWindow *t; font = PeekToken(action, &action); if (!font) { /* Try 'fixed', pass NULL font name */ } if (!(new_font = FlocaleLoadFont(dpy, font, "fvwm"))) { if (Scr.DefaultFont == NULL) { exit(1); } else { return; } } FlocaleUnloadFont(dpy, Scr.DefaultFont); Scr.DefaultFont = new_font; /* we should do that here because a redraw can happen before flush_window_updates is called ... */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (USING_DEFAULT_ICON_FONT(t)) { t->icon_font = Scr.DefaultFont; } if (USING_DEFAULT_WINDOW_FONT(t)) { t->title_font = Scr.DefaultFont; } } /* set flags to indicate that the font has changed */ Scr.flags.do_need_window_update = 1; Scr.flags.has_default_font_changed = 1; return; } void CMD_IconFont(F_CMD_ARGS) { char *newaction; if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) { fvwm_msg( ERR, "LoadIconFont", "Decors do not support the IconFont command anymore." " Please use 'Style IconFont '" " instead. Sorry for the inconvenience."); return; } if (action) { newaction = safemalloc(strlen(action) + 16); sprintf(newaction, "* IconFont %s", action); action = newaction; CMD_Style(F_PASS_ARGS); free(newaction); } return; } void CMD_WindowFont(F_CMD_ARGS) { char *newaction; if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) { fvwm_msg( ERR, "LoadWindowFont", "Decors do not support the WindowFont command anymore." " Please use 'Style Font '" " instead. Sorry for the inconvenience."); return; } if (action) { newaction = safemalloc(strlen(action) + 16); sprintf(newaction, "* Font %s", action); action = newaction; CMD_Style(F_PASS_ARGS); free(newaction); } return; } /* * * Changes the window's FvwmDecor pointer (veliaa@rpi.edu) * */ void CMD_ChangeDecor(F_CMD_ARGS) { char *item; FvwmDecor *decor = &Scr.DefaultDecor; FvwmDecor *found = NULL; FvwmWindow * const fw = exc->w.fw; item = PeekToken(action, &action); if (!action || !item) { return; } /* search for tag */ for (; decor; decor = decor->next) { if (decor->tag && StrEquals(item, decor->tag)) { found = decor; break; } } if (!found) { XBell(dpy, 0); return; } SET_DECOR_CHANGED(fw, 1); fw->decor = found; apply_decor_change(fw); return; } /* * * Destroys an FvwmDecor (veliaa@rpi.edu) * */ void CMD_DestroyDecor(F_CMD_ARGS) { char *item; FvwmDecor *decor = Scr.DefaultDecor.next; FvwmDecor *prev = &Scr.DefaultDecor, *found = NULL; Bool do_recreate = False; item = PeekToken(action, &action); if (!item) { return; } if (StrEquals(item, "recreate")) { do_recreate = True; item = PeekToken(action, NULL); } if (!item) { return; } /* search for tag */ for (; decor; decor = decor->next) { if (decor->tag && StrEquals(item, decor->tag)) { found = decor; break; } prev = decor; } if (found && (found != &Scr.DefaultDecor || do_recreate)) { if (!do_recreate) { __remove_window_decors(F_PASS_ARGS, found); } DestroyFvwmDecor(found); if (do_recreate) { int i; InitFvwmDecor(found); found->tag = safestrdup(item); Scr.flags.do_need_window_update = 1; found->flags.has_changed = 1; found->flags.has_title_height_changed = 0; found->titlebar.flags.has_changed = 1; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { TB_FLAGS(found->buttons[i]).has_changed = 1; } } else { prev->next = found->next; free(found); } } return; } /* * * Initiates an AddToDecor (veliaa@rpi.edu) * */ void CMD_AddToDecor(F_CMD_ARGS) { FvwmDecor *decor; FvwmDecor *found = NULL; char *item = NULL; action = GetNextToken(action, &item); if (!item) { return; } if (!action) { free(item); return; } /* search for tag */ for (decor = &Scr.DefaultDecor; decor; decor = decor->next) { if (decor->tag && StrEquals(item, decor->tag)) { found = decor; break; } } if (!found) { /* then make a new one */ found = (FvwmDecor *)safemalloc(sizeof( FvwmDecor )); InitFvwmDecor(found); found->tag = item; /* tag it */ /* add it to list */ for (decor = &Scr.DefaultDecor; decor->next; decor = decor->next) { /* nop */ } decor->next = found; } else { free(item); } if (found) { AddToDecor(F_PASS_ARGS, found); /* Set + state to last decor */ set_last_added_item(ADDED_DECOR, found); } return; } /* * * Updates window decoration styles (veliaa@rpi.edu) * */ void CMD_UpdateDecor(F_CMD_ARGS) { FvwmWindow *fw2; FvwmDecor *decor, *found = NULL; FvwmWindow *hilight = Scr.Hilite; char *item = NULL; action = GetNextToken(action, &item); if (item) { /* search for tag */ for (decor = &Scr.DefaultDecor; decor; decor = decor->next) { if (decor->tag && StrEquals(item, decor->tag)) { found = decor; break; } } free(item); } for (fw2 = Scr.FvwmRoot.next; fw2; fw2 = fw2->next) { /* update specific decor, or all */ if (found) { if (fw2->decor == found) { border_draw_decorations( fw2, PART_ALL, True, True, CLEAR_ALL, NULL, NULL); border_draw_decorations( fw2, PART_ALL, False, True, CLEAR_ALL, NULL, NULL); } } else { border_draw_decorations( fw2, PART_ALL, True, True, CLEAR_ALL, NULL, NULL); border_draw_decorations( fw2, PART_ALL, False, True, CLEAR_ALL, NULL, NULL); } } border_draw_decorations( hilight, PART_ALL, True, True, CLEAR_ALL, NULL, NULL); } void CMD_ButtonStyle(F_CMD_ARGS) { do_button_style(F_PASS_ARGS, False); return; } /* * * Appends a button decoration style (veliaa@rpi.edu) * */ void CMD_AddButtonStyle(F_CMD_ARGS) { do_button_style(F_PASS_ARGS, True); return; } void CMD_SetEnv(F_CMD_ARGS) { char *szVar = NULL; char *szValue = NULL; char *szPutenv = NULL; action = GetNextToken(action, &szVar); if (!szVar) { return; } action = GetNextToken(action, &szValue); if (!szValue) { szValue = safestrdup(""); } szPutenv = safemalloc(strlen(szVar) + strlen(szValue) + 2); sprintf(szPutenv,"%s=%s", szVar, szValue); flib_putenv(szVar, szPutenv); free(szVar); free(szPutenv); free(szValue); return; } void CMD_UnsetEnv(F_CMD_ARGS) { char *szVar = NULL; szVar = PeekToken(action, &action); if (!szVar) { return; } flib_unsetenv(szVar); return; } void CMD_GlobalOpts(F_CMD_ARGS) { char *opt; char *replace; char buf[64]; int i; Bool is_bugopt; char *optlist[] = { "WindowShadeShrinks", "WindowShadeScrolls", "SmartPlacementIsReallySmart", "SmartPlacementIsNormal", "ClickToFocusDoesntPassClick", "ClickToFocusPassesClick", "ClickToFocusDoesntRaise", "ClickToFocusRaises", "MouseFocusClickDoesntRaise", "MouseFocusClickRaises", "NoStipledTitles", "StipledTitles", "CaptureHonorsStartsOnPage", "CaptureIgnoresStartsOnPage", "RecaptureHonorsStartsOnPage", "RecaptureIgnoresStartsOnPage", "ActivePlacementHonorsStartsOnPage", "ActivePlacementIgnoresStartsOnPage", "RaiseOverNativeWindows", "IgnoreNativeWindows", NULL }; char *replacelist[] = { /* These options are mapped to the Style * command */ NULL, /* NULL means to use "Style * " */ NULL, "* MinOverlapPlacement", "* TileCascadePlacement", "* ClickToFocusPassesClickOff", "* ClickToFocusPassesClick", "* ClickToFocusRaisesOff", "* ClickToFocusRaises", "* MouseFocusClickRaisesOff", "* MouseFocusClickRaises", "* StippledTitleOff", "* StippledTitle", NULL, NULL, NULL, NULL, "* ManualPlacementHonorsStartsOnPage", "* ManualPlacementIgnoresStartsOnPage", /* These options are mapped to the BugOpts command */ "RaiseOverNativeWindows on", "RaiseOverNativeWindows off" }; fvwm_msg(ERR, "SetGlobalOptions", "The GlobalOpts command is obsolete."); for (action = GetNextSimpleOption(action, &opt); opt; action = GetNextSimpleOption(action, &opt)) { replace = NULL; is_bugopt = False; i = GetTokenIndex(opt, optlist, 0, NULL); if (i > -1) { char *cmd; char *tmp; replace = replacelist[i]; if (replace == NULL) { replace = &(buf[0]); sprintf(buf, "* %s", opt); } else if (*replace != '*') { is_bugopt = True; } tmp = action; action = replace; if (!is_bugopt) { CMD_Style(F_PASS_ARGS); cmd = "Style"; } else { CMD_BugOpts(F_PASS_ARGS); cmd = "BugOpts"; } action = tmp; fvwm_msg( ERR, "SetGlobalOptions", "Please replace 'GlobalOpts %s' with '%s %s'.", opt, cmd, replace); } else { fvwm_msg(ERR, "SetGlobalOptions", "Unknown Global Option '%s'", opt); } /* should never be null, but checking anyways... */ if (opt) { free(opt); } } if (opt) { free(opt); } return; } void CMD_BugOpts(F_CMD_ARGS) { char *opt; int toggle; char *optstring; /* fvwm_msg(DBG,"SetGlobalOptions","init action == '%s'\n",action); */ while (action && *action && *action != '\n') { action = GetNextFullOption(action, &optstring); if (!optstring) { /* no more options */ return; } toggle = ParseToggleArgument( SkipNTokens(optstring,1), NULL, 2, False); opt = PeekToken(optstring, NULL); free(optstring); if (!opt) { return; } /* toggle = ParseToggleArgument(rest, &rest, 2, False);*/ if (StrEquals(opt, "FlickeringMoveWorkaround")) { switch (toggle) { case -1: Scr.bo.do_disable_configure_notify ^= 1; break; case 0: case 1: Scr.bo.do_disable_configure_notify = toggle; break; default: Scr.bo.do_disable_configure_notify = 0; break; } } else if (StrEquals(opt, "MixedVisualWorkaround")) { switch (toggle) { case -1: Scr.bo.do_install_root_cmap ^= 1; break; case 0: case 1: Scr.bo.do_install_root_cmap = toggle; break; default: Scr.bo.do_install_root_cmap = 0; break; } } else if (StrEquals(opt, "ModalityIsEvil")) { switch (toggle) { case -1: Scr.bo.is_modality_evil ^= 1; break; case 0: case 1: Scr.bo.is_modality_evil = toggle; break; default: Scr.bo.is_modality_evil = 0; break; } if (Scr.bo.is_modality_evil) { SetMWM_INFO(Scr.NoFocusWin); } } else if (StrEquals(opt, "RaiseOverNativeWindows")) { switch (toggle) { case -1: Scr.bo.is_raise_hack_needed ^= 1; break; case 0: case 1: Scr.bo.is_raise_hack_needed = toggle; break; default: Scr.bo.is_raise_hack_needed = 0; break; } } else if (StrEquals(opt, "RaiseOverUnmanaged")) { switch (toggle) { case -1: Scr.bo.do_raise_over_unmanaged ^= 1; break; case 0: case 1: Scr.bo.do_raise_over_unmanaged = toggle; break; default: Scr.bo.do_raise_over_unmanaged = 0; break; } } else if (StrEquals(opt, "FlickeringQtDialogsWorkaround")) { switch (toggle) { case -1: Scr.bo.do_enable_flickering_qt_dialogs_workaround ^= 1; break; case 0: case 1: Scr.bo.do_enable_flickering_qt_dialogs_workaround = toggle; break; default: Scr.bo.do_enable_flickering_qt_dialogs_workaround = 0; break; } } else if (StrEquals(opt, "QtDragnDropWorkaround") ) { switch (toggle) { case -1: Scr.bo.do_enable_qt_drag_n_drop_workaround ^= 1; break; case 0: case 1: Scr.bo.do_enable_qt_drag_n_drop_workaround = toggle; break; default: Scr.bo.do_enable_qt_drag_n_drop_workaround = 0; break; } } else if (EWMH_BugOpts(opt, toggle)) { /* work is done in EWMH_BugOpts */ } else if (StrEquals(opt, "DisplayNewWindowNames")) { switch (toggle) { case -1: Scr.bo.do_display_new_window_names ^= 1; break; case 0: case 1: Scr.bo.do_display_new_window_names = toggle; break; default: Scr.bo.do_display_new_window_names = 0; break; } } else if (StrEquals(opt, "ExplainWindowPlacement")) { switch (toggle) { case -1: Scr.bo.do_explain_window_placement ^= 1; break; case 0: case 1: Scr.bo.do_explain_window_placement = toggle; break; default: Scr.bo.do_explain_window_placement = 0; break; } } else if (StrEquals(opt, "DebugCRMotionMethod")) { switch (toggle) { case -1: Scr.bo.do_debug_cr_motion_method ^= 1; break; case 0: case 1: Scr.bo.do_debug_cr_motion_method = toggle; break; default: Scr.bo.do_debug_cr_motion_method = 0; break; } } else if (StrEquals(opt, "TransliterateUtf8")) { FiconvSetTransliterateUtf8(toggle); } else { fvwm_msg(ERR, "SetBugOptions", "Unknown Bug Option '%s'", opt); } } return; } void CMD_Emulate(F_CMD_ARGS) { char *style; style = PeekToken(action, NULL); if (!style || StrEquals(style, "fvwm")) { Scr.gs.do_emulate_mwm = False; Scr.gs.do_emulate_win = False; } else if (StrEquals(style, "mwm")) { Scr.gs.do_emulate_mwm = True; Scr.gs.do_emulate_win = False; } else if (StrEquals(style, "win")) { Scr.gs.do_emulate_mwm = False; Scr.gs.do_emulate_win = True; } else { fvwm_msg(ERR, "Emulate", "Unknown style '%s'", style); return; } Scr.flags.do_need_window_update = 1; Scr.flags.has_default_font_changed = 1; Scr.flags.has_default_color_changed = 1; return; } void CMD_ColorLimit(F_CMD_ARGS) { fvwm_msg( WARN, "ColorLimit", "ColorLimit is obsolete,\n\tuse the " "fvwm -color-limit option"); return; } /* set animation parameters */ void CMD_SetAnimation(F_CMD_ARGS) { char *opt; int delay; float pct; int i = 0; opt = PeekToken(action, &action); if (!opt || sscanf(opt,"%d",&delay) != 1) { fvwm_msg(ERR,"SetAnimation", "Improper milli-second delay as first argument"); return; } if (delay > 500) { fvwm_msg(WARN,"SetAnimation", "Using longer than .5 seconds as between frame" " animation delay"); } cmsDelayDefault = delay; for (opt = PeekToken(action, &action); opt; opt = PeekToken(action, &action)) { if (sscanf(opt,"%f",&pct) != 1) { fvwm_msg(ERR,"SetAnimation", "Use fractional values ending in 1.0 as args" " 2 and on"); return; } rgpctMovementDefault[i++] = pct; } /* No pct entries means don't change them at all */ if (i > 0 && rgpctMovementDefault[i-1] != 1.0) { rgpctMovementDefault[i++] = 1.0; } return; } /* Determine which modifiers are required with a keycode to make . */ static Bool FKeysymToKeycode (Display *dpy, KeySym keysym, unsigned int *keycode, unsigned int *modifiers) { int m; *keycode = XKeysymToKeycode(dpy, keysym); *modifiers = 0; for (m = 0; m <= 8; ++m) { KeySym ks = fvwm_KeycodeToKeysym(dpy, *keycode, m, 0); if (ks == keysym) { switch (m) { case 0: /* No modifiers */ break; case 1: /* Shift modifier */ *modifiers |= ShiftMask; break; default: fvwm_msg(ERR, "FKeysymToKeycode", "Unhandled modifier %d", m); break; } return True; } } return False; } static void __fake_event(F_CMD_ARGS, FakeEventType type) { char *token; char *optlist[] = { "press", "p", "release", "r", "wait", "w", "modifiers", "m", "depth", "d", NULL }; unsigned int mask = 0; Window root = Scr.Root; int maxdepth = 0; static char args[128]; strncpy(args, action, sizeof(args) - 1); /* get the mask of pressed/released buttons/keys */ FQueryPointer( dpy, Scr.Root, &root, &JunkRoot, &JunkX, &JunkY, &JunkX, &JunkY, &mask); token = PeekToken(action, &action); while (token && action) { int index = GetTokenIndex(token, optlist, 0, NULL); int val, depth; XEvent e; Window w; Window child_w; int x = 0; int y = 0; int rx = 0; int ry = 0; Bool do_unset; long add_mask = 0; KeySym keysym = NoSymbol; XFlush(dpy); do_unset = True; switch (index) { case 0: case 1: do_unset = False; /* fall through */ case 2: case 3: /* key/button press or release */ if (type == FakeMouseEvent) { if ((GetIntegerArguments( action, &action, &val, 1) != 1) || val < 1 || val > NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { fvwm_msg( ERR, "__fake_event", "Invalid button specifier in" " \"%s\" for FakeClick.", args); return; /* error */ } } else /* type == FakeKeyEvent */ { char *key = PeekToken(action, &action); if (key == NULL) { fvwm_msg( ERR, "__fake_event", "No keysym specifier in \"%s\"" " for FakeKeypress.", args); return; } /* Do *NOT* use FvwmStringToKeysym() as it is * case insensitive. */ keysym = XStringToKeysym(key); if (keysym == NoSymbol) { fvwm_msg( ERR, "__fake_event", "Invalid keysym specifier (%s)" " in \"%s\" for FakeKeypress.", key, args); return; } } w = None; child_w = root; for (depth = 1; depth != maxdepth && w != child_w && child_w != None; depth++) { w = child_w; if (FQueryPointer( dpy, w, &root, &child_w, &rx, &ry, &x, &y, &JunkMask) == False) { /* pointer is on a different * screen - that's okay here */ } } if (type == FakeMouseEvent) { e.type = (do_unset) ? ButtonRelease : ButtonPress; e.xbutton.display = dpy; e.xbutton.window = w; e.xbutton.subwindow = None; e.xbutton.root = root; e.xbutton.time = fev_get_evtime(); e.xbutton.x = x; e.xbutton.y = y; e.xbutton.x_root = rx; e.xbutton.y_root = ry; e.xbutton.button = val; e.xbutton.state = mask; e.xbutton.same_screen = (Scr.Root == root); /* SS: I think this mask handling code is * buggy. * The value of is overridden during a * "wait" operation. Also why are we only using * Button1Mask? What if the user has requested * a FakeClick using some other button? */ /* DV: Button1Mask is actually a bit. Shifting * it by (val -1) bits to the left gives * Button2Mask, Button3Mask etc. */ if (do_unset) { mask &= ~(Button1Mask << (val - 1)); } else { mask |= (Button1Mask << (val - 1)); } add_mask = (do_unset) ? ButtonPressMask : ButtonReleaseMask; } else { /* type == FakeKeyEvent */ e.type = (do_unset ? KeyRelease : KeyPress); e.xkey.display = dpy; e.xkey.subwindow = None; e.xkey.root = root; e.xkey.time = fev_get_evtime(); e.xkey.x = x; e.xkey.y = y; e.xkey.x_root = rx; e.xkey.y_root = ry; e.xkey.same_screen = (Scr.Root == root); w = e.xkey.window = exc->w.w; if (FKeysymToKeycode( dpy, keysym, &(e.xkey.keycode), &(e.xkey.state)) != True) { fvwm_msg(DBG, "__fake_event", "FKeysymToKeycode failed"); return; } e.xkey.state |= mask; add_mask = (do_unset) ? KeyReleaseMask : KeyPressMask; } FSendEvent(dpy, w, True, SubstructureNotifyMask | add_mask, &e); XFlush(dpy); break; case 4: case 5: /* wait */ if ((GetIntegerArguments( action, &action, &val, 1) != 1) || val <= 0 || val > 1000000) { fvwm_msg(ERR, "__fake_event", "Invalid wait value in \"%s\"", args); return; } usleep(1000 * val); if (FQueryPointer( dpy, Scr.Root, &root, &JunkRoot, &JunkX, &JunkY, &JunkX, &JunkY, &mask) == False) { /* pointer is on a different screen - * that's okay here */ } break; case 6: case 7: /* set modifier */ if (GetIntegerArguments(action, &action, &val, 1) != 1) { fvwm_msg( ERR, "__fake_event", "Invalid modifier value in \"%s\"", args); return; } do_unset = False; if (val < 0) { do_unset = True; val = -val; } if (val == 6) { val = ShiftMask; } else if (val == 7) { val = LockMask; } else if (val == 8) { val = ControlMask; } else if (val >=1 && val <= 5) { val = (Mod1Mask << (val - 1)); } else { /* error */ return; } /* SS: Could be buggy if a "modifier" operation * preceeds a "wait" operation. */ if (do_unset) { mask &= ~val; } else { mask |= val; } break; case 8: case 9: /* new max depth */ if (GetIntegerArguments(action, &action, &val, 1) != 1) { fvwm_msg(ERR, "__fake_event", "Invalid depth value in \"%s\"", args); return; } maxdepth = val; break; default: fvwm_msg(ERR, "__fake_event", "Invalid command (%s) in \"%s\"", token, args); return; } if (action) { token = PeekToken(action, &action); } } return; } void CMD_FakeClick(F_CMD_ARGS) { __fake_event(F_PASS_ARGS, FakeMouseEvent); return; } void CMD_FakeKeypress(F_CMD_ARGS) { __fake_event(F_PASS_ARGS, FakeKeyEvent); return; } /* A function to handle stroke (olicha Nov 11, 1999) */ #ifdef HAVE_STROKE void CMD_StrokeFunc(F_CMD_ARGS) { int finished = 0; int abort = 0; int modifiers = exc->x.etrigger->xbutton.state; int start_event_type = exc->x.etrigger->type; char sequence[STROKE_MAX_SEQUENCE + 1]; char *stroke_action, *name; char *opt = NULL; Bool finish_on_release = True; KeySym keysym; Bool restore_repeat = False; Bool echo_sequence = False; Bool draw_motion = False; int i = 0; int *x = NULL; int *y = NULL; const int STROKE_CHUNK_SIZE = 0xff; int coords_size = STROKE_CHUNK_SIZE; Window JunkRoot, JunkChild; int JunkX, JunkY; int tmpx, tmpy; unsigned int JunkMask; Bool feed_back = False; int stroke_width = 1; XEvent e; XClassHint *class; if (!GrabEm(CRS_STROKE, GRAB_NORMAL)) { XBell(dpy, 0); return; } x = (int*)safemalloc(coords_size * sizeof(int)); y = (int*)safemalloc(coords_size * sizeof(int)); e = *exc->x.etrigger; /* set the default option */ if (e.type == KeyPress || e.type == ButtonPress) { finish_on_release = True; } else { finish_on_release = False; } /* parse the option */ for (action = GetNextSimpleOption(action, &opt); opt; action = GetNextSimpleOption(action, &opt)) { if (StrEquals("NotStayPressed",opt)) { finish_on_release = False; } else if (StrEquals("EchoSequence",opt)) { echo_sequence = True; } else if (StrEquals("DrawMotion",opt)) { draw_motion = True; } else if (StrEquals("FeedBack",opt)) { feed_back = True; } else if (StrEquals("StrokeWidth",opt)) { /* stroke width takes a positive integer argument */ if (opt) { free(opt); } action = GetNextToken(action, &opt); if (!opt) { fvwm_msg( WARN, "StrokeWidth", "needs an integer argument"); } /* we allow stroke_width == 0 which means drawing a * `fast' line of width 1; the upper level of 100 is * arbitrary */ else if (!sscanf(opt, "%d", &stroke_width) || stroke_width < 0 || stroke_width > 100) { fvwm_msg( WARN, "StrokeWidth", "Bad integer argument %d", stroke_width); stroke_width = 1; } } else { fvwm_msg(WARN,"StrokeFunc","Unknown option %s", opt); } if (opt) { free(opt); } } if (opt) { free(opt); } /* Force auto repeat off and grab the Keyboard to get proper * KeyRelease events if we need it. * Some computers do not support KeyRelease events, can we * check this here ? No ? */ if (start_event_type == KeyPress && finish_on_release) { XKeyboardState kstate; XGetKeyboardControl(dpy, &kstate); if (kstate.global_auto_repeat == AutoRepeatModeOn) { XAutoRepeatOff(dpy); restore_repeat = True; } MyXGrabKeyboard(dpy); } /* be ready to get a stroke sequence */ stroke_init(); if (draw_motion) { MyXGrabServer(dpy); if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x[0], &y[0], &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ x[0] = 0; y[0] = 0; } XSetLineAttributes( dpy,Scr.XorGC,stroke_width,LineSolid,CapButt,JoinMiter); } while (!finished && !abort) { /* block until there is an event */ FMaskEvent( dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | ButtonMotionMask | PointerMotionMask, &e); switch (e.type) { case MotionNotify: if (e.xmotion.same_screen == False) { continue; } if (e.xany.window != Scr.Root) { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &tmpx, &tmpy, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ tmpx = 0; tmpy = 0; } } else { tmpx = e.xmotion.x; tmpy = e.xmotion.y; } stroke_record(tmpx,tmpy); if (draw_motion && (x[i] != tmpx || y[i] != tmpy)) { i++; if (i >= coords_size) { coords_size += STROKE_CHUNK_SIZE; x = (int*)saferealloc( (void *)x, coords_size * sizeof(int)); y = (int*)saferealloc( (void *)y, coords_size * sizeof(int)); } x[i] = tmpx; y[i] = tmpy; XDrawLine( dpy, Scr.Root, Scr.XorGC, x[i-1], y[i-1], x[i], y[i]); } break; case ButtonRelease: if (finish_on_release && start_event_type == ButtonPress) { finished = 1; } break; case KeyRelease: if (finish_on_release && start_event_type == KeyPress) { finished = 1; } break; case KeyPress: keysym = XLookupKeysym(&e.xkey, 0); /* abort if Escape or Delete is pressed (as in menus.c) */ if (keysym == XK_Escape || keysym == XK_Delete || keysym == XK_KP_Separator) { abort = 1; } /* finish on enter or space (as in menus.c) */ if (keysym == XK_Return || keysym == XK_KP_Enter || keysym == XK_space) { finished = 1; } break; case ButtonPress: if (!finish_on_release) { finished = 1; } break; default: break; } } if (draw_motion) { while (i > 0) { XDrawLine( dpy, Scr.Root, Scr.XorGC, x[i-1], y[i-1], x[i], y[i]); i--; } XSetLineAttributes(dpy,Scr.XorGC,0,LineSolid,CapButt,JoinMiter); MyXUngrabServer(dpy); } if (x != NULL) { free(x); free(y); } if (start_event_type == KeyPress && finish_on_release) { MyXUngrabKeyboard(dpy); } UngrabEm(GRAB_NORMAL); if (restore_repeat) { XAutoRepeatOn(dpy); } /* get the stroke sequence */ stroke_trans(sequence); if (echo_sequence) { char num_seq[STROKE_MAX_SEQUENCE + 1]; for (i = 0; sequence[i] != '\0';i++) { /* Telephone to numeric pad */ if ('7' <= sequence[i] && sequence[i] <= '9') { num_seq[i] = sequence[i]-6; } else if ('1' <= sequence[i] && sequence[i] <= '3') { num_seq[i] = sequence[i]+6; } else { num_seq[i] = sequence[i]; } } num_seq[i++] = '\0'; fvwm_msg(INFO, "StrokeFunc", "stroke sequence: %s (N%s)", sequence, num_seq); } if (abort) { return; } if (exc->w.fw == NULL) { class = NULL; name = NULL; } else { class = &exc->w.fw->class; name = exc->w.fw->name.name; } /* check for a binding */ stroke_action = CheckBinding( Scr.AllBindings, sequence, 0, modifiers, GetUnusedModifiers(), exc->w.wcontext, BIND_STROKE, class, name); /* execute the action */ if (stroke_action != NULL) { const exec_context_t *exc2; exec_context_changes_t ecc; if (feed_back && atoi(sequence) != 0) { GrabEm(CRS_WAIT, GRAB_BUSY); usleep(200000); UngrabEm(GRAB_BUSY); } ecc.x.etrigger = &e; exc2 = exc_clone_context(exc, &ecc, ECC_ETRIGGER); execute_function(cond_rc, exc2, stroke_action, 0); exc_destroy_context(exc2); } return; } #endif /* HAVE_STROKE */ void CMD_State(F_CMD_ARGS) { unsigned int state; int toggle; int n; FvwmWindow * const fw = exc->w.fw; n = GetIntegerArguments(action, &action, (int *)&state, 1); if (n <= 0) { return; } if (state > 31) { fvwm_msg(ERR, "CMD_State", "Illegal state %d\n", state); return; } toggle = ParseToggleArgument(action, NULL, -1, 0); state = (1 << state); switch (toggle) { case -1: TOGGLE_USER_STATES(fw, state); break; case 0: CLEAR_USER_STATES(fw, state); break; case 1: default: SET_USER_STATES(fw, state); break; } return; } fvwm-2.6.7/fvwm/ewmh_conf.c0000644000175700017570000002046712773467232012562 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ /* 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 #include #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "cursor.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "update.h" #include "stack.h" #include "style.h" #include "externs.h" #include "icons.h" #include "ewmh.h" #include "ewmh_intern.h" #include "move_resize.h" /* * CMDS */ static void set_state_workaround(void) { FvwmWindow *t; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if ((t->Desk != Scr.CurrentDesk) && (!is_window_sticky_across_desks(t) && !IS_ICON_UNMAPPED(t))) { if (Scr.bo.do_enable_ewmh_iconic_state_workaround) { SetMapStateProp(t, NormalState); } else { SetMapStateProp(t, IconicState); } } } } Bool EWMH_BugOpts(char *opt, Bool toggle) { Bool save_isw = Scr.bo.do_enable_ewmh_iconic_state_workaround; if (StrEquals(opt,"EWMHIconicStateWorkaround")) { switch (toggle) { case -1: Scr.bo.do_enable_ewmh_iconic_state_workaround ^= 1; break; case 0: case 1: Scr.bo.do_enable_ewmh_iconic_state_workaround = toggle; break; default: Scr.bo.do_enable_ewmh_iconic_state_workaround = 0; break; } if (save_isw != Scr.bo.do_enable_ewmh_iconic_state_workaround) { set_state_workaround(); } return True; } return False; } void CMD_EwmhNumberOfDesktops(F_CMD_ARGS) { int val[2]; int num; num = GetIntegerArguments(action, NULL, val, 2); if ((num != 1 && num != 2) || val[0] < 1 || (num == 2 && val[1] < val[0] && val[1] != 0)) { fvwm_msg(ERR,"EwmhNumberOfDesktops", "Bad arguments to EwmhNumberOfDesktops"); return; } if (num == 2 && ewmhc.MaxDesktops != val[1]) { ewmhc.MaxDesktops = val[1]; num = 3; } else if (num == 1 && ewmhc.MaxDesktops != 0) { ewmhc.MaxDesktops = 0; num = 3; } if (ewmhc.NumberOfDesktops != val[0]) { ewmhc.NumberOfDesktops = val[0]; num = 3; } if (num == 3) { ewmhc.NeedsToCheckDesk = True; EWMH_SetNumberOfDesktops(); } } void CMD_EwmhBaseStruts(F_CMD_ARGS) { int val[4]; if (GetIntegerArguments(action, NULL, val, 4) != 4 || val[0] < 0 || val[1] < 0 || val[2] < 0 || val[3] < 0) { fvwm_msg(ERR,"CMD_EwmhBaseStruts", "EwmhBaseStruts needs four positive arguments"); return; } if (ewmhc.BaseStrut.left != val[0] || ewmhc.BaseStrut.right != val[1] || ewmhc.BaseStrut.top != val[2] || ewmhc.BaseStrut.bottom != val[3]) { ewmhc.BaseStrut.left = val[0]; ewmhc.BaseStrut.right = val[1]; ewmhc.BaseStrut.top = val[2]; ewmhc.BaseStrut.bottom = val[3]; EWMH_UpdateWorkArea(); } } /* * Styles */ Bool EWMH_CMD_Style(char *token, window_style *ptmpstyle, int on) { int found = False; if (StrEquals(token, "EWMHDonateIcon")) { found = True; S_SET_DO_EWMH_DONATE_ICON(SCF(*ptmpstyle), on); S_SET_DO_EWMH_DONATE_ICON(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_DONATE_ICON(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHDonateMiniIcon")) { found = True; S_SET_DO_EWMH_DONATE_MINI_ICON(SCF(*ptmpstyle), on); S_SET_DO_EWMH_DONATE_MINI_ICON(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_DONATE_MINI_ICON(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHDontDonateIcon")) { found = True; S_SET_DO_EWMH_DONATE_ICON(SCF(*ptmpstyle), !on); S_SET_DO_EWMH_DONATE_ICON(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_DONATE_ICON(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHDontDonateMiniIcon")) { found = True; S_SET_DO_EWMH_DONATE_MINI_ICON(SCF(*ptmpstyle), !on); S_SET_DO_EWMH_DONATE_MINI_ICON(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_DONATE_MINI_ICON(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHMaximizeIgnoreWorkingArea")) { found = True; S_SET_EWMH_MAXIMIZE_MODE( SCF(*ptmpstyle), EWMH_IGNORE_WORKING_AREA); S_SET_EWMH_MAXIMIZE_MODE( SCM(*ptmpstyle), EWMH_WORKING_AREA_MASK); S_SET_EWMH_MAXIMIZE_MODE( SCC(*ptmpstyle), EWMH_WORKING_AREA_MASK); } else if (StrEquals(token, "EWMHMaximizeUseWorkingArea")) { found = True; S_SET_EWMH_MAXIMIZE_MODE( SCF(*ptmpstyle), EWMH_USE_WORKING_AREA); S_SET_EWMH_MAXIMIZE_MODE( SCM(*ptmpstyle), EWMH_WORKING_AREA_MASK); S_SET_EWMH_MAXIMIZE_MODE( SCC(*ptmpstyle), EWMH_WORKING_AREA_MASK); } else if (StrEquals(token, "EWMHMaximizeUseDynamicWorkingArea")) { found = True; S_SET_EWMH_MAXIMIZE_MODE( SCF(*ptmpstyle), EWMH_USE_DYNAMIC_WORKING_AREA); S_SET_EWMH_MAXIMIZE_MODE( SCM(*ptmpstyle), EWMH_WORKING_AREA_MASK); S_SET_EWMH_MAXIMIZE_MODE( SCC(*ptmpstyle), EWMH_WORKING_AREA_MASK); } else if (StrEquals(token, "EWMHMiniIconOverride")) { found = True; S_SET_DO_EWMH_MINI_ICON_OVERRIDE(SCF(*ptmpstyle), on); S_SET_DO_EWMH_MINI_ICON_OVERRIDE(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_MINI_ICON_OVERRIDE(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHNoMiniIconOverride")) { found = True; S_SET_DO_EWMH_MINI_ICON_OVERRIDE(SCF(*ptmpstyle), !on); S_SET_DO_EWMH_MINI_ICON_OVERRIDE(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_MINI_ICON_OVERRIDE(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHPlacementIgnoreWorkingArea")) { found = True; ptmpstyle->flags.ewmh_placement_mode = EWMH_IGNORE_WORKING_AREA; ptmpstyle->flag_mask.ewmh_placement_mode = EWMH_WORKING_AREA_MASK; ptmpstyle->change_mask.ewmh_placement_mode = EWMH_WORKING_AREA_MASK; } else if (StrEquals(token, "EWMHPlacementUseWorkingArea")) { found = True; ptmpstyle->flags.ewmh_placement_mode = EWMH_USE_WORKING_AREA; ptmpstyle->flag_mask.ewmh_placement_mode = EWMH_WORKING_AREA_MASK; ptmpstyle->change_mask.ewmh_placement_mode = EWMH_WORKING_AREA_MASK; } else if (StrEquals(token, "EWMHPlacementUseDynamicWorkingArea")) { found = True; ptmpstyle->flags.ewmh_placement_mode = EWMH_USE_DYNAMIC_WORKING_AREA; ptmpstyle->flag_mask.ewmh_placement_mode = EWMH_WORKING_AREA_MASK; ptmpstyle->change_mask.ewmh_placement_mode = EWMH_WORKING_AREA_MASK; } else if (StrEquals(token, "EWMHUseStackingOrderHints")) { found = True; S_SET_DO_EWMH_USE_STACKING_HINTS(SCF(*ptmpstyle), on); S_SET_DO_EWMH_USE_STACKING_HINTS(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_USE_STACKING_HINTS(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHIgnoreStackingOrderHints")) { found = True; S_SET_DO_EWMH_USE_STACKING_HINTS(SCF(*ptmpstyle), !on); S_SET_DO_EWMH_USE_STACKING_HINTS(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_USE_STACKING_HINTS(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHUseStateHints")) { found = True; S_SET_DO_EWMH_IGNORE_STATE_HINTS(SCF(*ptmpstyle), !on); S_SET_DO_EWMH_IGNORE_STATE_HINTS(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_IGNORE_STATE_HINTS(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHIgnoreStateHints")) { found = True; S_SET_DO_EWMH_IGNORE_STATE_HINTS(SCF(*ptmpstyle), on); S_SET_DO_EWMH_IGNORE_STATE_HINTS(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_IGNORE_STATE_HINTS(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHUseStrutHints")) { found = True; S_SET_DO_EWMH_IGNORE_STRUT_HINTS(SCF(*ptmpstyle), !on); S_SET_DO_EWMH_IGNORE_STRUT_HINTS(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_IGNORE_STRUT_HINTS(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHIgnoreStrutHints")) { found = True; S_SET_DO_EWMH_IGNORE_STRUT_HINTS(SCF(*ptmpstyle), on); S_SET_DO_EWMH_IGNORE_STRUT_HINTS(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_IGNORE_STRUT_HINTS(SCC(*ptmpstyle), 1); } else if (StrEquals(token, "EWMHIgnoreWindowType")) { found = True; S_SET_DO_EWMH_IGNORE_WINDOW_TYPE(SCF(*ptmpstyle), on); S_SET_DO_EWMH_IGNORE_WINDOW_TYPE(SCM(*ptmpstyle), 1); S_SET_DO_EWMH_IGNORE_WINDOW_TYPE(SCC(*ptmpstyle), 1); } return found; } fvwm-2.6.7/fvwm/menuitem.h0000644000175700017570000001060312773467232012434 00000000000000/* -*-c-*- */ #ifndef MENUITEM_H #define MENUITEM_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ #define MI_NEXT_ITEM(i) ((i)->next) #define MI_PREV_ITEM(i) ((i)->prev) #define MI_LABEL(i) ((i)->label) #define MI_LABEL_OFFSET(i) ((i)->label_offset) #define MI_LABEL_STRLEN(i) ((i)->label_strlen) #define MI_PICTURE(i) ((i)->picture) #define MI_MINI_ICON(i) ((i)->lpicture) #define MI_Y_OFFSET(i) ((i)->y_offset) #define MI_HEIGHT(i) ((i)->height) #define MI_ACTION(i) ((i)->action) #define MI_FUNC_TYPE(i) ((i)->func_type) #define MI_HOTKEY_COFFSET(i) ((i)->hotkey_coffset) #define MI_HOTKEY_COLUMN(i) ((i)->hotkey_column) /* flags */ #define MI_IS_SEPARATOR(i) ((i)->flags.is_separator) #define MI_IS_TEAR_OFF_BAR(i) ((i)->flags.is_tear_off_bar) #define MI_IS_TITLE(i) ((i)->flags.is_title) #define MI_IS_TITLE_CENTERED(i) ((i)->flags.is_title_centered) #define MI_IS_POPUP(i) ((i)->flags.is_popup) #define MI_IS_MENU(i) ((i)->flags.is_menu) #define MI_IS_CONTINUATION(i) ((i)->flags.is_continuation) #define MI_HAS_TEXT(i) ((i)->flags.has_text) #define MI_HAS_PICTURE(i) ((i)->flags.has_picture) #define MI_HAS_HOTKEY(i) ((i)->flags.has_hotkey) #define MI_IS_HOTKEY_AUTOMATIC(i) ((i)->flags.is_hotkey_automatic) #define MI_IS_SELECTABLE(i) ((i)->flags.is_selectable) /* temporary flags */ #define MI_WAS_DESELECTED(i) ((i)->flags.was_deselected) /* ---------------------------- forward declarations ----------------------- */ struct MenuStyle; /* ---------------------------- type definitions --------------------------- */ /* IMPORTANT NOTE: Don't put members into this struct that can change while the * menu is visible! This will wreak havoc on recursive menus. */ typedef struct MenuItem { /* next and prev menu items */ struct MenuItem *next; struct MenuItem *prev; /* the strings displayed in the item */ char *label[MAX_MENU_ITEM_LABELS]; /* witdh of label[i] */ int label_offset[MAX_MENU_ITEM_LABELS]; /* strlen(label[i]) */ int label_strlen[MAX_MENU_ITEM_LABELS]; /* Pixmap to show above label*/ FvwmPicture *picture; /* Pics to show left/right of label */ FvwmPicture *lpicture[MAX_MENU_ITEM_MINI_ICONS]; /* y offset and height for item */ int y_offset; int height; /* action to be performed */ char *action; /* type of built in function */ short func_type; /* Hot key offset (pete@tecc.co.uk). */ int hotkey_coffset; /* The column number the hotkey is defined in*/ char hotkey_column; struct { unsigned is_continuation : 1; unsigned is_separator : 1; unsigned is_tear_off_bar : 1; unsigned is_title : 1; unsigned is_title_centered : 1; unsigned is_popup : 1; unsigned is_menu : 1; unsigned has_text : 1; unsigned has_picture : 1; unsigned has_hotkey : 1; unsigned is_hotkey_automatic : 1; unsigned is_selectable : 1; /* temporary flags */ unsigned was_deselected : 1; } flags; } MenuItem; typedef struct MenuItemPartSizesT { int label_width[MAX_MENU_ITEM_LABELS]; int icon_width[MAX_MENU_ITEM_MINI_ICONS]; int picture_width; int triangle_width; int title_width; } MenuItemPartSizesT; typedef struct MenuPaintItemParameters { struct MenuStyle *ms; Window w; struct MenuItem *selected_item; struct MenuDimensions *dim; FvwmWindow *fw; XEvent *ev; int used_mini_icons; struct MenuRoot *cb_mr; /* number of item labels present in the item format */ Bool (*cb_reset_bg)(struct MenuRoot *mr, XEvent *pevent); struct { unsigned is_first_item : 1; unsigned is_left_triangle : 1; } flags; } MenuPaintItemParameters; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ struct MenuItem *menuitem_clone(struct MenuItem *mi); struct MenuItem *menuitem_create(void); void menuitem_free(struct MenuItem *mi); void menuitem_get_size( struct MenuItem *mi, struct MenuItemPartSizesT *mipst, FlocaleFont *font, Bool do_reverse_icon_order); void menuitem_paint( struct MenuItem *mi, struct MenuPaintItemParameters *mpip); int menuitem_middle_y_offset(struct MenuItem *mi, struct MenuStyle *ms); #endif /* MENUITEM_H */ fvwm-2.6.7/fvwm/misc.h0000644000175700017570000000450612773467232011551 00000000000000/* -*-c-*- */ #ifndef MISC_H #define MISC_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ enum { GRAB_ALL = 0, /* sum of all grabs */ GRAB_STARTUP = 1, /* Startup busy cursor */ GRAB_NORMAL = 2, /* DeferExecution, Move, Resize, ... */ GRAB_MENU = 3, /* a menus.c grabing */ GRAB_BUSY = 4, /* BusyCursor stuff */ GRAB_BUSYMENU = 5, /* Allows menus.c to regrab the cursor */ GRAB_PASSIVE = 6, /* Override of passive grab, only prevents grab * to be released too early */ GRAB_FREEZE_CURSOR = 7, /* Freeze the cursor shape if a window is * pressed. */ GRAB_MAXVAL /* last GRAB macro + 1 */ }; /* ---------------------------- global macros ------------------------------ */ #ifdef ICON_DEBUG #define ICON_DBG(X) fprintf X; #else #define ICON_DBG(X) #endif /* ---------------------------- type definitions --------------------------- */ /* message levels for fvwm_msg */ typedef enum { DBG = 0, ECHO, INFO, WARN, OLD, ERR } fvwm_msg_t; typedef enum { ADDED_NONE = 0, ADDED_MENU, ADDED_DECOR, ADDED_FUNCTION } last_added_item_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ Bool GrabEm( int cursor, int grab_context); Bool UngrabEm( int ungrab_context); int GetTwoArguments( char *action, int *val1, int *val2, int *val1_unit, int *val2_unit); void NewFontAndColor( FlocaleFont *flf, Pixel color, Pixel backcolor); void Keyboard_shortcuts( XEvent *ev, FvwmWindow *fw, int *x_defect, int *y_defect, int ReturnEvent); Bool check_if_fvwm_window_exists( FvwmWindow *fw); int truncate_to_multiple( int x, int m); Bool IsRectangleOnThisPage( const rectangle *rec, int desk); FvwmWindow *get_pointer_fvwm_window(void); Time get_server_time(void); void fvwm_msg(fvwm_msg_t type, char *id, char *msg, ...) __attribute__ ((format (printf, 3, 4))); void fvwm_msg_report_app(void); void fvwm_msg_report_app_and_workers(void); void set_last_added_item(last_added_item_t type, void *item); void print_g(char *text, rectangle *g); #endif /* MISC_H */ fvwm-2.6.7/fvwm/frame.c0000644000175700017570000014520513003342500011656 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/Grab.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "events.h" #include "misc.h" #include "screen.h" #include "geometry.h" #include "module_interface.h" #include "focus.h" #include "borders.h" #include "frame.h" #include "ewmh.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { int decor_grav; int title_grav; int lbutton_grav; int rbutton_grav; int parent_grav; int client_grav; } frame_decor_gravities_type; typedef struct { /* filled when args are created */ frame_move_resize_mode mode; frame_decor_gravities_type grav; size_borders b_g; size_borders b_no_title_g; rectangle curr_sidebar_g; rectangle start_g; rectangle end_g; rectangle delta_g; rectangle current_g; rectangle client_g; int anim_steps; Window w_with_focus; int current_step; int curr_titlebar_compression; direction_t shade_dir; window_parts trans_parts; struct { unsigned do_force : 1; unsigned do_not_configure_client : 1; unsigned do_not_draw : 1; unsigned do_restore_gravity : 1; unsigned do_set_bit_gravity : 1; unsigned do_update_shape : 1; unsigned had_handles : 1; unsigned is_lazy_shading : 1; unsigned is_setup : 1; unsigned is_shading : 1; unsigned was_moved : 1; } flags; /* used during the animation */ int next_titlebar_compression; rectangle next_sidebar_g; rectangle next_g; rectangle dstep_g; size_rect parent_s; int minimal_w_offset; int minimal_h_offset; struct { /* cleared before each step */ unsigned do_hide_parent : 1; unsigned do_unhide_parent : 1; unsigned is_hidden : 1; unsigned was_hidden : 1; } step_flags; } mr_args_internal; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* windows used to hide animation steps */ static struct { Window parent; Window w[4]; } hide_wins; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ #if 0 static void print_g(char *text, rectangle *g) { if (g == NULL) { fprintf(stderr, "%s: (null)", (text == NULL) ? "" : text); } else { fprintf(stderr, "%s: %4d %4d %4dx%4d (%4d - %4d %4d - %4d)\n", (text == NULL) ? "" : text, g->x, g->y, g->width, g->height, g->x, g->x + g->width - 1, g->y, g->y + g->height - 1); } } #endif static void combine_gravities( frame_decor_gravities_type *ret_grav, frame_decor_gravities_type *grav_x, frame_decor_gravities_type *grav_y) { ret_grav->decor_grav = gravity_combine_xy_grav( grav_x->decor_grav, grav_y->decor_grav); ret_grav->title_grav = gravity_combine_xy_grav( grav_x->title_grav, grav_y->title_grav); ret_grav->lbutton_grav = gravity_combine_xy_grav( grav_x->lbutton_grav, grav_y->lbutton_grav); ret_grav->rbutton_grav = gravity_combine_xy_grav( grav_x->rbutton_grav, grav_y->rbutton_grav); ret_grav->parent_grav = gravity_combine_xy_grav( grav_x->parent_grav, grav_y->parent_grav); ret_grav->client_grav = gravity_combine_xy_grav( grav_x->client_grav, grav_y->client_grav); return; } static void get_resize_decor_gravities_one_axis( frame_decor_gravities_type *ret_grav, direction_t title_dir, frame_move_resize_mode axis_mode, direction_t neg_dir, direction_t pos_dir, int is_moving) { int title_grav; int neg_grav; int pos_grav; title_grav = gravity_dir_to_grav(title_dir); neg_grav = gravity_dir_to_grav(neg_dir); pos_grav = gravity_dir_to_grav(pos_dir); if (title_dir != DIR_NONE) { ret_grav->decor_grav = title_grav; ret_grav->lbutton_grav = title_grav; ret_grav->title_grav = title_grav; ret_grav->rbutton_grav = title_grav; } else { ret_grav->decor_grav = neg_grav; ret_grav->lbutton_grav = neg_grav; ret_grav->title_grav = neg_grav; ret_grav->rbutton_grav = pos_grav; } switch (axis_mode) { case FRAME_MR_SCROLL: ret_grav->client_grav = (is_moving) ? neg_grav : pos_grav; break; case FRAME_MR_SHRINK: ret_grav->client_grav = (is_moving) ? pos_grav : neg_grav; break; case FRAME_MR_OPAQUE: case FRAME_MR_FORCE_SETUP: case FRAME_MR_FORCE_SETUP_NO_W: case FRAME_MR_SETUP: case FRAME_MR_SETUP_BY_APP: ret_grav->client_grav = neg_grav; break; case FRAME_MR_DONT_DRAW: default: /* can not happen, just a dummy to keep -Wall happy */ ret_grav->client_grav = pos_grav; break; } ret_grav->parent_grav = ret_grav->client_grav; return; } static void frame_get_titlebar_dimensions_only( FvwmWindow *fw, rectangle *frame_g, size_borders *bs, rectangle *ret_titlebar_g) { if (!HAS_TITLE(fw)) { return; } switch (GET_TITLE_DIR(fw)) { case DIR_W: case DIR_E: ret_titlebar_g->x = (GET_TITLE_DIR(fw) == DIR_W) ? bs->top_left.width : frame_g->width - bs->bottom_right.width - fw->title_thickness; ret_titlebar_g->y = bs->top_left.height; ret_titlebar_g->width = fw->title_thickness; ret_titlebar_g->height = frame_g->height - bs->total_size.height; break; case DIR_N: case DIR_S: default: /* default makes gcc4 happy */ ret_titlebar_g->y = (GET_TITLE_DIR(fw) == DIR_N) ? bs->top_left.height : frame_g->height - bs->bottom_right.height - fw->title_thickness; ret_titlebar_g->x = bs->top_left.width; ret_titlebar_g->width = frame_g->width - bs->total_size.width; ret_titlebar_g->height = fw->title_thickness; break; } return; } static void frame_setup_border( FvwmWindow *fw, rectangle *frame_g, window_parts setup_parts, rectangle *diff_g) { XWindowChanges xwc; Window w; window_parts part; rectangle sidebar_g; rectangle part_g; Bool dummy; if (HAS_NO_BORDER(fw)) { return; } frame_get_sidebar_geometry( fw, NULL, frame_g, &sidebar_g, &dummy, &dummy); for (part = PART_BORDER_N; (part & PART_FRAME); part <<= 1) { if ((part & PART_FRAME & setup_parts) == PART_NONE) { continue; } border_get_part_geometry(fw, part, &sidebar_g, &part_g, &w); if (part_g.width <= 0 || part_g.height <= 0) { xwc.x = -1; xwc.y = -1; xwc.width = 1; xwc.height = 1; } else { xwc.x = part_g.x; xwc.y = part_g.y; xwc.width = part_g.width; xwc.height = part_g.height; } if (diff_g != NULL) { if (part == PART_BORDER_NE || part == PART_BORDER_E || part == PART_BORDER_SE) { xwc.x -= diff_g->width; } if (part == PART_BORDER_SW || part == PART_BORDER_S || part == PART_BORDER_SE) { xwc.y -= diff_g->height; } } XConfigureWindow(dpy, w, CWWidth | CWHeight | CWX | CWY, &xwc); } return; } static void frame_setup_titlebar( FvwmWindow *fw, rectangle *frame_g, window_parts setup_parts, rectangle *diff_g) { frame_title_layout_t title_layout; int i; if (!HAS_TITLE(fw)) { return; } frame_get_titlebar_dimensions(fw, frame_g, diff_g, &title_layout); /* configure buttons */ for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if (FW_W_BUTTON(fw, i) != None && (setup_parts & PART_BUTTONS)) { XMoveResizeWindow( dpy, FW_W_BUTTON(fw, i), title_layout.button_g[i].x, title_layout.button_g[i].y, title_layout.button_g[i].width, title_layout.button_g[i].height); } } /* configure title */ if (setup_parts & PART_TITLE) { XMoveResizeWindow( dpy, FW_W_TITLE(fw), title_layout.title_g.x, title_layout.title_g.y, title_layout.title_g.width, title_layout.title_g.height); } return; } static void __frame_setup_window( FvwmWindow *fw, rectangle *frame_g, Bool do_send_configure_notify, Bool do_force, Bool is_application_request) { frame_move_resize_args mr_args; Bool is_resized = False; Bool is_moved = False; rectangle new_g; new_g = *frame_g; /* sanity checks */ if (new_g.width < 1) { new_g.width = 1; } if (new_g.height < 1) { new_g.height = 1; } /* set some flags */ if (new_g.width != fw->g.frame.width || new_g.height != fw->g.frame.height) { is_resized = True; } if (new_g.x != fw->g.frame.x || new_g.y != fw->g.frame.y) { is_moved = True; } /* setup the window */ if (is_resized || do_force) { frame_move_resize_mode mode; if (is_application_request) { mode = FRAME_MR_SETUP_BY_APP; } else if (do_force) { mode = FRAME_MR_FORCE_SETUP; } else { mode = FRAME_MR_SETUP; } mr_args = frame_create_move_resize_args( fw, mode, NULL, &new_g, 0, DIR_NONE); frame_move_resize(fw, mr_args); ((mr_args_internal *)mr_args)->flags.was_moved = 0; frame_free_move_resize_args(fw, mr_args); fw->g.frame = *frame_g; } else if (is_moved) { unsigned int draw_parts = PART_NONE; /* inform the application of the change * * According to the July 27, 1988 ICCCM draft, we should send a * synthetic ConfigureNotify event to the client if the window * was moved but not resized. */ XMoveWindow(dpy, FW_W_FRAME(fw), frame_g->x, frame_g->y); fw->g.frame = *frame_g; if ((draw_parts = border_get_transparent_decorations_part(fw)) != PART_NONE) { border_draw_decorations( fw, draw_parts, ((fw == get_focus_window())) ? True : False, True, CLEAR_ALL, NULL, NULL); } fw->g.frame = *frame_g; do_send_configure_notify = True; } /* must not send events to shaded windows because this might cause them * to look at their current geometry */ if (do_send_configure_notify && !IS_SHADED(fw)) { SendConfigureNotify( fw, new_g.x, new_g.y, new_g.width, new_g.height, 0, True); } /* get things updated */ XFlush(dpy); if (is_moved || is_resized) { /* inform the modules of the change */ BroadcastConfig(M_CONFIGURE_WINDOW,fw); } return; } static void frame_reparent_hide_windows( Window w) { int i; hide_wins.parent = w; for (i = 0; i < 4 ; i++) { if (w == Scr.Root) { XUnmapWindow(dpy, hide_wins.w[i]); } XReparentWindow(dpy, hide_wins.w[i], w, -1, -1); } if (w != Scr.Root) { XRaiseWindow(dpy, hide_wins.w[0]); XRestackWindows(dpy, hide_wins.w, 4); } return; } /* Returns True if the frame is so small that the parent window would have a * width or height smaller than one pixel. */ static Bool frame_is_parent_hidden( FvwmWindow *fw, rectangle *frame_g) { size_borders b; get_window_borders(fw, &b); if (frame_g->width <= b.total_size.width || frame_g->height <= b.total_size.height) { return True; } return False; } /* Returns the number of pixels that the title bar is too short to accomodate * all the title buttons and a title window that has at least a length of one * pixel. */ static int frame_get_titlebar_compression( FvwmWindow *fw, rectangle *frame_g) { size_borders b; int space; int need_space; if (!HAS_TITLE(fw)) { return 0; } get_window_borders(fw, &b); if (HAS_VERTICAL_TITLE(fw)) { space = frame_g->height - b.total_size.height; } else { space = frame_g->width - b.total_size.width; } need_space = (fw->nr_left_buttons + fw->nr_right_buttons) * fw->title_thickness + MIN_WINDOW_TITLE_LENGTH; if (space < need_space) { return need_space - space; } return 0; } /* Calculates the gravities for the various parts of the decor through ret_grav. * This can be passed to frame_set_decor_gravities. * * title_dir * The direction of the title in the frame. * rmode * The mode for the resize operation */ static void frame_get_resize_decor_gravities( frame_decor_gravities_type *ret_grav, direction_t title_dir, frame_move_resize_mode rmode, rectangle *delta_g) { frame_decor_gravities_type grav_x; frame_decor_gravities_type grav_y; direction_t title_dir_x; direction_t title_dir_y; gravity_split_xy_dir(&title_dir_x, &title_dir_y, title_dir); get_resize_decor_gravities_one_axis( &grav_x, title_dir_x, rmode, DIR_W, DIR_E, (delta_g->x != 0)); get_resize_decor_gravities_one_axis( &grav_y, title_dir_y, rmode, DIR_N, DIR_S, (delta_g->y != 0)); combine_gravities(ret_grav, &grav_x, &grav_y); return; } /* sets the gravity for the various parts of the window */ static void frame_set_decor_gravities( FvwmWindow *fw, frame_decor_gravities_type *grav, int do_set1_restore2_bit_gravity) { int valuemask; XSetWindowAttributes xcwa; int i; Bool button_reverted = False; /* using bit gravity can reduce redrawing dramatically */ valuemask = CWWinGravity; xcwa.win_gravity = grav->client_grav; if (do_set1_restore2_bit_gravity == 1) { XWindowAttributes xwa; if (!fw->attr_backup.is_bit_gravity_stored && XGetWindowAttributes(dpy, FW_W(fw), &xwa)) { fw->attr_backup.bit_gravity = xwa.bit_gravity; } fw->attr_backup.is_bit_gravity_stored = 1; valuemask |= CWBitGravity; xcwa.bit_gravity = grav->client_grav; } else if (do_set1_restore2_bit_gravity == 2) { fw->attr_backup.is_bit_gravity_stored = 0; valuemask |= CWBitGravity; xcwa.bit_gravity = fw->attr_backup.bit_gravity; } XChangeWindowAttributes(dpy, FW_W(fw), valuemask, &xcwa); xcwa.win_gravity = grav->parent_grav; valuemask = CWWinGravity; XChangeWindowAttributes(dpy, FW_W_PARENT(fw), valuemask, &xcwa); if (!HAS_TITLE(fw)) { return; } xcwa.win_gravity = grav->title_grav; XChangeWindowAttributes(dpy, FW_W_TITLE(fw), valuemask, &xcwa); if (fw->title_text_rotation == ROTATION_270 || fw->title_text_rotation == ROTATION_180) { button_reverted = True; } if (button_reverted) { xcwa.win_gravity = grav->rbutton_grav; } else { xcwa.win_gravity = grav->lbutton_grav; } for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i += 2) { if (FW_W_BUTTON(fw, i)) { XChangeWindowAttributes( dpy, FW_W_BUTTON(fw, i), valuemask, &xcwa); } } if (button_reverted) { xcwa.win_gravity = grav->lbutton_grav; } else { xcwa.win_gravity = grav->rbutton_grav; } for (i = 1; i < NUMBER_OF_TITLE_BUTTONS; i += 2) { if (FW_W_BUTTON(fw, i)) { XChangeWindowAttributes( dpy, FW_W_BUTTON(fw, i), valuemask, &xcwa); } } return; } /* Just restore the win and bit gravities on the client window. */ static void frame_restore_client_gravities(FvwmWindow *fw) { XSetWindowAttributes xcwa; long valuemask; valuemask = CWWinGravity; if (fw->attr_backup.is_bit_gravity_stored) { fw->attr_backup.is_bit_gravity_stored = 0; xcwa.bit_gravity = fw->attr_backup.bit_gravity; valuemask |= CWBitGravity; } xcwa.win_gravity = fw->hints.win_gravity; XChangeWindowAttributes(dpy, FW_W(fw), valuemask, &xcwa); return; } /* Prepares the structure for the next animation step. */ static void frame_next_move_resize_args( frame_move_resize_args mr_args) { mr_args_internal *mra; mra = (mr_args_internal *)mr_args; mra->curr_sidebar_g = mra->next_sidebar_g; mra->current_g = mra->next_g; mra->step_flags.was_hidden = mra->step_flags.is_hidden; mra->curr_titlebar_compression = mra->next_titlebar_compression; return; } static rectangle *frame_get_hidden_pos( FvwmWindow *fw, mr_args_internal *mra, Bool do_unhide, rectangle *ret_hidden_g) { rectangle *target_g; direction_t dir_x; direction_t dir_y; if (do_unhide == False) { gravity_split_xy_dir(&dir_x, &dir_y, mra->shade_dir); ret_hidden_g->x = (dir_x == DIR_E) ? -mra->client_g.width + mra->parent_s.width : 0; ret_hidden_g->y = (dir_y == DIR_S) ? -mra->client_g.height + mra->parent_s.height : 0; target_g = &mra->next_g; } else { gravity_split_xy_dir(&dir_x, &dir_y, SHADED_DIR(fw)); if (mra->mode == FRAME_MR_SCROLL) { ret_hidden_g->x = (dir_x == DIR_W) ? -mra->client_g.width + mra->parent_s.width : 0; ret_hidden_g->y = (dir_y == DIR_N) ? -mra->client_g.height + mra->parent_s.height : 0; } else { ret_hidden_g->x = (dir_x == DIR_E) ? -mra->client_g.width + mra->parent_s.width : 0; ret_hidden_g->y = (dir_y == DIR_S) ? -mra->client_g.height + mra->parent_s.height : 0; } target_g = &mra->next_g; } return target_g; } static void frame_update_hidden_window_pos( FvwmWindow *fw, mr_args_internal *mra, Bool do_unhide) { rectangle *target_g; rectangle hidden_g; target_g = frame_get_hidden_pos(fw, mra, do_unhide, &hidden_g); XMoveResizeWindow( dpy, FW_W_PARENT(fw), mra->b_g.top_left.width, mra->b_g.top_left.height, max(1, target_g->width - mra->b_g.total_size.width), max(1, target_g->height - mra->b_g.total_size.height)); XMoveResizeWindow( dpy, FW_W(fw), hidden_g.x, hidden_g.y, mra->client_g.width, mra->client_g.height); mra->flags.was_moved = 1; return; } static void frame_prepare_animation_shape( FvwmWindow *fw, mr_args_internal *mra, int parent_x, int parent_y) { rectangle parent_g; rectangle client_g; if (!FShapesSupported) { return; } parent_g.x = parent_x; parent_g.y = parent_y; parent_g.width = mra->parent_s.width; parent_g.height = mra->parent_s.height; gravity_move_resize_parent_child( mra->grav.parent_grav, &mra->dstep_g, &parent_g); client_g = mra->client_g; frame_get_hidden_pos(fw, mra, True, &client_g); client_g.x += parent_g.x; client_g.y += parent_g.y; FShapeCombineShape( dpy, Scr.NoFocusWin, FShapeBounding, client_g.x, client_g.y, FW_W(fw), FShapeBounding, FShapeSet); if (HAS_TITLE(fw)) { rectangle tb_g; XRectangle rect; SUPPRESS_UNUSED_VAR_WARNING(rect); frame_get_titlebar_dimensions_only( fw, &mra->next_g, &mra->b_no_title_g, &tb_g); /* windows w/ titles */ rect.x = tb_g.x; rect.y = tb_g.y; rect.width = tb_g.width; rect.height = tb_g.height; FShapeCombineRectangles( dpy, Scr.NoFocusWin, FShapeBounding, 0, 0, &rect, 1, FShapeUnion, Unsorted); } return; } static void frame_mrs_prepare_vars( FvwmWindow *fw, mr_args_internal *mra) { Bool dummy; int i; /* preparations */ i = mra->current_step; mra->next_g = mra->start_g; mra->next_g.x += (mra->delta_g.x * i) / mra->anim_steps; mra->next_g.y += (mra->delta_g.y * i) / mra->anim_steps; mra->next_g.width += (mra->delta_g.width * i) / mra->anim_steps; mra->next_g.height += (mra->delta_g.height * i) / mra->anim_steps; frame_get_sidebar_geometry( fw, NULL, &mra->next_g, &mra->next_sidebar_g, &dummy, &dummy); fvwmrect_subtract_rectangles( &mra->dstep_g, &mra->next_g, &mra->current_g); mra->next_titlebar_compression = frame_get_titlebar_compression(fw, &mra->next_g); mra->step_flags.is_hidden = (frame_is_parent_hidden(fw, &mra->next_g) == True); mra->step_flags.do_hide_parent = ((!mra->step_flags.was_hidden || mra->flags.do_force) && mra->step_flags.is_hidden); mra->step_flags.do_unhide_parent = ((mra->step_flags.was_hidden || mra->flags.do_force) && !mra->step_flags.is_hidden); /* get the parent's dimensions */ mra->parent_s.width = mra->next_g.width - mra->b_g.total_size.width; if (mra->parent_s.width < 1) { mra->minimal_w_offset = 1 - mra->parent_s.width; mra->parent_s.width = 1; } else { mra->minimal_w_offset = 0; } mra->parent_s.height = mra->next_g.height - mra->b_g.total_size.height; if (mra->parent_s.height < 1) { mra->minimal_h_offset = 1 - mra->parent_s.height; mra->parent_s.height = 1; } else { mra->minimal_h_offset = 0; } return; } static void frame_mrs_hide_changing_parts( mr_args_internal *mra) { int l_add; int t_add; int r_add; int b_add; int w; int h; t_add = 0; l_add = 0; b_add = 0; r_add = 0; if (mra->mode == FRAME_MR_SHRINK) { if (mra->dstep_g.x > 0) { l_add = mra->dstep_g.x; } if (mra->dstep_g.y > 0) { t_add = mra->dstep_g.y; } } else if (mra->mode == FRAME_MR_SCROLL) { if (mra->dstep_g.x == 0 && mra->dstep_g.width < 0) { l_add = -mra->dstep_g.width; } if (mra->dstep_g.y == 0 && mra->dstep_g.height < 0) { t_add = -mra->dstep_g.height; } } if (l_add > 0) { l_add -= mra->minimal_w_offset; } else { r_add = (mra->dstep_g.width < 0) ? -mra->dstep_g.width : 0; r_add -= mra->minimal_w_offset; } if (t_add > 0) { t_add -= mra->minimal_h_offset; } else { b_add = (mra->dstep_g.height < 0) ? -mra->dstep_g.height : 0; b_add -= mra->minimal_h_offset; } /* cover top border */ w = mra->current_g.width; h = mra->b_g.top_left.height + t_add; if (w > 0 && h > 0) { XMoveResizeWindow(dpy, hide_wins.w[0], 0, 0, w, h); XMapWindow(dpy, hide_wins.w[0]); } /* cover left border */ w = mra->b_g.top_left.width + l_add; h = mra->current_g.height; if (w > 0 && h > 0) { XMoveResizeWindow(dpy, hide_wins.w[1], 0, 0, w, h); XMapWindow(dpy, hide_wins.w[1]); } /* cover bottom border and possibly part of the client */ w = mra->current_g.width; h = mra->b_g.bottom_right.height + b_add; if (w > 0 && h > 0) { XMoveResizeWindow( dpy, hide_wins.w[2], 0, mra->current_g.height - mra->b_g.bottom_right.height - b_add, w, h); XMapWindow(dpy, hide_wins.w[2]); } /* cover right border and possibly part of the client */ w = mra->b_g.bottom_right.width + r_add; h = mra->current_g.height; if (w > 0 && h > 0) { XMoveResizeWindow( dpy, hide_wins.w[3], mra->current_g.width - mra->b_g.bottom_right.width - r_add, 0, w, h); XMapWindow(dpy, hide_wins.w[3]); } return; } static void frame_mrs_hide_unhide_parent( FvwmWindow *fw, mr_args_internal *mra) { XSetWindowAttributes xswa; if (mra->step_flags.do_unhide_parent) { Window w[2]; /* update the hidden position of the client */ frame_update_hidden_window_pos(fw, mra, True); w[0] = hide_wins.w[3]; w[1] = FW_W_PARENT(fw); XRestackWindows(dpy, w, 2); } else if (mra->step_flags.do_hide_parent) { /* When the parent gets hidden, unmap it automatically, lower * it while hidden, then remap it. Necessary to eliminate * flickering. */ xswa.win_gravity = UnmapGravity; XChangeWindowAttributes( dpy, FW_W_PARENT(fw), CWWinGravity, &xswa); } return; } static void frame_mrs_hide_unhide_parent2( FvwmWindow *fw, mr_args_internal *mra) { XSetWindowAttributes xswa; /* finish hiding the parent */ if (mra->step_flags.do_hide_parent) { xswa.win_gravity = mra->grav.parent_grav; XChangeWindowAttributes( dpy, FW_W_PARENT(fw), CWWinGravity, &xswa); /* update the hidden position of the client */ frame_update_hidden_window_pos(fw, mra, False); XLowerWindow(dpy, FW_W_PARENT(fw)); XMapWindow(dpy, FW_W_PARENT(fw)); } return; } static void frame_mrs_setup_draw_decorations( FvwmWindow *fw, mr_args_internal *mra) { window_parts setup_parts; /* setup the title bar and the border */ setup_parts = PART_TITLE; if (mra->curr_titlebar_compression != mra->next_titlebar_compression || mra->mode == FRAME_MR_FORCE_SETUP) { setup_parts |= PART_BUTTONS; } frame_setup_titlebar(fw, &mra->next_g, setup_parts, &mra->dstep_g); frame_setup_border(fw, &mra->next_g, PART_ALL, &mra->dstep_g); /* draw the border and the titlebar */ if (mra->flags.do_not_draw == 1) { /* nothing */ } else if (!mra->flags.is_shading || !mra->flags.is_lazy_shading) { /* draw as usual */ border_draw_decorations( fw, PART_ALL, (mra->w_with_focus != None) ? True : False, (mra->flags.do_force) ? True : False, CLEAR_ALL, &mra->current_g, &mra->next_g); } else /* lazy shading */ { /* Lazy shading relies on the proper window gravities and does * not redraw the decorations during the animation. Only draw * on the first step. */ if (mra->current_step == 1) { rectangle lazy_g; /* Use the larger width and height values from the * current and the final geometry to get proper * decorations. */ lazy_g.x = mra->current_g.x; lazy_g.y = mra->current_g.y; lazy_g.width = max( mra->current_g.width, mra->end_g.width); lazy_g.height = max( mra->current_g.height, mra->end_g.height); border_draw_decorations( fw, PART_ALL, (mra->w_with_focus != None) ? True : False, True, CLEAR_ALL, &mra->current_g, &lazy_g); } } return; } static void frame_mrs_resize_move_windows( FvwmWindow *fw, mr_args_internal *mra) { /* setup the parent, the frame and the client window */ if (!mra->flags.is_shading) { if (!mra->step_flags.is_hidden && !mra->flags.do_not_configure_client) { XMoveResizeWindow( dpy, FW_W(fw), 0, 0, mra->parent_s.width, mra->parent_s.height); mra->client_g.width = mra->parent_s.width; mra->client_g.height = mra->parent_s.height; } else { XMoveWindow(dpy, FW_W(fw), 0, 0); } mra->flags.was_moved = 1; #if 0 /* reduces flickering */ /* dv (11-Aug-2002): ... and slows down large scripts * dramatically. Rather let it flicker */ if (mra->flags.is_setup) { usleep(1000); } #endif XSync(dpy, 0); XMoveResizeWindow( dpy, FW_W_PARENT(fw), mra->b_g.top_left.width, mra->b_g.top_left.height, mra->parent_s.width, mra->parent_s.height); } else { int x; int y; x = mra->b_g.top_left.width; y = mra->b_g.top_left.height; if (mra->mode == FRAME_MR_SCROLL) { if (mra->dstep_g.x == 0) { x -= mra->dstep_g.width - mra->minimal_w_offset; } if (mra->dstep_g.y == 0) { y -= mra->dstep_g.height - mra->minimal_h_offset;; } } else if (mra->mode == FRAME_MR_SHRINK) { x += mra->dstep_g.x; y += mra->dstep_g.y; } if (x > 0) { x -= mra->minimal_w_offset; } else if (x < 0) { x += mra->minimal_w_offset; } if (y > 0) { y -= mra->minimal_h_offset; } else if (y < 0) { y += mra->minimal_h_offset; } XMoveResizeWindow( dpy, FW_W_PARENT(fw), x, y, mra->parent_s.width, mra->parent_s.height); if (mra->flags.do_update_shape) { /* Step 1: apply the union of the old and new shapes. * This way so that the client stays visible - rather * let the background show through than force an * Expose event. */ frame_prepare_animation_shape(fw, mra, x, y); FShapeCombineShape( dpy, FW_W_FRAME(fw), FShapeBounding, 0, 0, Scr.NoFocusWin, FShapeBounding, FShapeUnion); } } XMoveResizeWindow( dpy, FW_W_FRAME(fw), mra->next_g.x, mra->next_g.y, mra->next_g.width, mra->next_g.height); if (mra->flags.do_update_shape) { /* Step 2: clip the previous shape. */ FShapeCombineShape( dpy, FW_W_FRAME(fw), FShapeBounding, 0, 0, Scr.NoFocusWin, FShapeBounding, FShapeSet); } return; } static void frame_move_resize_step( FvwmWindow *fw, mr_args_internal *mra) { frame_mrs_prepare_vars(fw, mra); frame_mrs_hide_changing_parts(mra); frame_mrs_hide_unhide_parent(fw, mra); frame_mrs_setup_draw_decorations(fw, mra); frame_mrs_resize_move_windows(fw, mra); frame_mrs_hide_unhide_parent2(fw, mra); fw->g.frame = mra->next_g; return; } static void frame_has_handles_and_tiled_border( FvwmWindow *fw, int *ret_has_handles, int *ret_has_tiled_border) { DecorFace *df; *ret_has_handles = 1; if (!HAS_HANDLES(fw)) { *ret_has_handles = 0; } df = border_get_border_style(fw, (fw == Scr.Hilite) ? True : False); if (DFS_HAS_HIDDEN_HANDLES(df->style)) { *ret_has_handles = 0; } *ret_has_tiled_border = (DFS_FACE_TYPE(df->style) == TiledPixmapButton) || (DFS_FACE_TYPE(df->style) == ColorsetButton && !CSET_IS_TRANSPARENT_PR(df->u.acs.cs) && CSET_HAS_PIXMAP(df->u.acs.cs)); return; } static int frame_get_shading_laziness( FvwmWindow *fw, mr_args_internal *mra) { int has_handles; int has_tiled_pixmap_border; int using_border_style; if (!mra->flags.is_shading || mra->anim_steps <= 2) { return 0; } frame_has_handles_and_tiled_border( fw, &has_handles, &has_tiled_pixmap_border); if (HAS_TITLE(fw) && has_tiled_pixmap_border) { using_border_style = border_is_using_border_style( fw, (fw == Scr.Hilite) ? True : False); } else { using_border_style = 0; } switch (WINDOWSHADE_LAZINESS(fw)) { case WINDOWSHADE_ALWAYS_LAZY: return 1; case WINDOWSHADE_BUSY: if (has_handles) { return 0; } /* fall through */ case WINDOWSHADE_LAZY: default: if (has_tiled_pixmap_border && !HAS_NO_BORDER(fw)) { return 0; } else if (has_tiled_pixmap_border && HAS_TITLE(fw) && using_border_style) { return 0; } return 1; } } void frame_reshape_border(FvwmWindow *fw) { int grav; int off_x = 0; int off_y = 0; rectangle naked_g; rectangle *new_g; /* calculate the new offsets */ if (!IS_MAXIMIZED(fw)) { grav = fw->hints.win_gravity; new_g = &fw->g.normal; } else { /* maximized windows are always considered to have * NorthWestGravity */ grav = NorthWestGravity; new_g = &fw->g.max; off_x = fw->g.normal.x - fw->g.max.x; off_y = fw->g.normal.y - fw->g.max.y; } gravity_get_naked_geometry(grav, fw, &naked_g, new_g); gravity_translate_to_northwest_geometry_no_bw( grav, fw, &naked_g, &naked_g); set_window_border_size(fw, fw->unshaped_boundary_width); gravity_add_decoration(grav, fw, new_g, &naked_g); if (IS_MAXIMIZED(fw)) { /* prevent random paging when unmaximizing after the border * width has changed */ fw->g.max_offset.x += fw->g.normal.x - fw->g.max.x - off_x; fw->g.max_offset.y += fw->g.normal.y - fw->g.max.y - off_y; } if (IS_SHADED(fw)) { get_unshaded_geometry(fw, new_g); if (USED_TITLE_DIR_FOR_SHADING(fw)) { SET_SHADED_DIR(fw, GET_TITLE_DIR(fw)); } get_shaded_geometry(fw, &fw->g.frame, new_g); frame_force_setup_window( fw, fw->g.frame.x, fw->g.frame.y, fw->g.frame.width, fw->g.frame.height, False); } else { get_relative_geometry(new_g, new_g); frame_force_setup_window( fw, new_g->x, new_g->y, new_g->width, new_g->height, True); } return; } /* ---------------------------- interface functions ------------------------ */ /* Initialise structures local to frame.c */ void frame_init(void) { XSetWindowAttributes xswa; unsigned long valuemask; int i; xswa.override_redirect = True; xswa.backing_store = NotUseful; xswa.save_under = False; xswa.win_gravity = UnmapGravity; xswa.background_pixmap = None; valuemask = CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBackPixmap | CWWinGravity; hide_wins.parent = Scr.Root; for (i = 0; i < 4; i++) { hide_wins.w[i] = XCreateWindow( dpy, Scr.Root, -1, -1, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &xswa); if (hide_wins.w[i] == None) { fvwm_msg(ERR, "frame_init", "Could not create internal windows. Exiting"); MyXUngrabServer(dpy); exit(1); } } return; } Bool is_frame_hide_window( Window w) { int i; if (w == None) { return False; } for (i = 0; i < 4; i++) { if (w == hide_wins.w[i]) { return True; } } return False; } void frame_destroyed_frame( Window frame_w) { if (hide_wins.parent == frame_w) { /* Oops, the window containing the hide windows was destroyed! * Let it die and create them from scratch. */ frame_init(); } return; } void frame_get_titlebar_dimensions( FvwmWindow *fw, rectangle *frame_g, rectangle *diff_g, frame_title_layout_t *title_layout) { size_borders b; int i; int tb_length; int tb_thick; int tb_x; int tb_y; int b_length; int b_w; int b_h; int t_length; int t_w; int t_h; int br_sub; int nbuttons; int nbuttons_big; int *padd_coord; int *b_l; Bool revert_button = False; if (!HAS_TITLE(fw)) { return; } get_window_borders_no_title(fw, &b); if (HAS_VERTICAL_TITLE(fw)) { tb_length = frame_g->height - b.total_size.height; } else { tb_length = frame_g->width - b.total_size.width; } /* find out the length of the title and the buttons */ tb_thick = fw->title_thickness; nbuttons = fw->nr_left_buttons + fw->nr_right_buttons; nbuttons_big = 0; b_length = tb_thick; t_length = tb_length - nbuttons * b_length; if (nbuttons > 0 && t_length < MIN_WINDOW_TITLE_LENGTH) { int diff = MIN_WINDOW_TITLE_LENGTH - t_length; int pixels = diff / nbuttons; b_length -= pixels; t_length += nbuttons * pixels; nbuttons_big = nbuttons - (MIN_WINDOW_TITLE_LENGTH - t_length); t_length = MIN_WINDOW_TITLE_LENGTH; } if (b_length < MIN_WINDOW_TITLEBUTTON_LENGTH) { /* don't draw the buttons */ nbuttons = 0; nbuttons_big = 0; b_length = 0; t_length = tb_length; } if (t_length < 0) { t_length = 0; } fw->title_length = t_length; /* prepare variables */ if (HAS_VERTICAL_TITLE(fw)) { tb_y = b.top_left.height; br_sub = (diff_g != NULL) ? diff_g->height : 0; if (GET_TITLE_DIR(fw) == DIR_W) { tb_x = b.top_left.width; } else { tb_x = frame_g->width - b.bottom_right.width - tb_thick; if (diff_g != NULL) { tb_x -= diff_g->width; } } padd_coord = &tb_y; b_w = tb_thick; b_h = b_length; t_w = tb_thick; t_h = t_length; b_l = &b_h; } else { tb_x = b.top_left.width; br_sub = (diff_g != NULL) ? diff_g->width : 0; if (GET_TITLE_DIR(fw) == DIR_N) { tb_y = b.top_left.height; } else { tb_y = frame_g->height - b.bottom_right.height - tb_thick; if (diff_g != NULL) { tb_y -= diff_g->height; } } padd_coord = &tb_x; b_w = b_length; b_h = tb_thick; t_w = t_length; t_h = tb_thick; b_l = &b_w; } if (fw->title_text_rotation == ROTATION_270 || fw->title_text_rotation == ROTATION_180) { revert_button = True; } /* configure left buttons */ for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if ((revert_button && !(i & 1)) || (!revert_button && (i & 1)) || FW_W_BUTTON(fw, i) == None) { continue; } if (b_length <= 0) { title_layout->button_g[i].x = -1; title_layout->button_g[i].y = -1; title_layout->button_g[i].width = 1; title_layout->button_g[i].height = 1; } else { title_layout->button_g[i].x = tb_x; title_layout->button_g[i].y = tb_y; title_layout->button_g[i].width = b_w; title_layout->button_g[i].height = b_h; } *padd_coord += b_length; nbuttons_big--; if (nbuttons_big == 0) { b_length--; (*b_l)--; } } /* configure title */ if (t_length == 0) { title_layout->title_g.x = -1; title_layout->title_g.y = -1; title_layout->title_g.width = 1; title_layout->title_g.height = 1; } else { title_layout->title_g.x = tb_x; title_layout->title_g.y = tb_y; title_layout->title_g.width = t_w; title_layout->title_g.height = t_h; } *padd_coord += t_length; /* configure right buttons */ *padd_coord -= br_sub; for (i = NUMBER_OF_TITLE_BUTTONS-1; i > -1; i--) { if ((revert_button && (i & 1)) || (!revert_button && !(i & 1)) || FW_W_BUTTON(fw, i) == None) { continue; } if (b_length <= 0) { title_layout->button_g[i].x = -1; title_layout->button_g[i].y = -1; title_layout->button_g[i].width = 1; title_layout->button_g[i].height = 1; } else { title_layout->button_g[i].x = tb_x; title_layout->button_g[i].y = tb_y; title_layout->button_g[i].width = b_w; title_layout->button_g[i].height = b_h; } *padd_coord += b_length; nbuttons_big--; if (nbuttons_big == 0) { b_length--; (*b_l)--; } } return; } void frame_get_sidebar_geometry( FvwmWindow *fw, DecorFaceStyle *borderstyle, rectangle *frame_g, rectangle *ret_g, Bool *ret_has_x_marks, Bool *ret_has_y_marks) { int min_w; size_borders b; ret_g->x = 0; ret_g->y = 0; ret_g->width = 0; ret_g->height = 0; *ret_has_x_marks = False; *ret_has_y_marks = False; if (HAS_NO_BORDER(fw)) { return; } /* get the corner size */ if (!HAS_HANDLES(fw)) { *ret_has_x_marks = False; *ret_has_y_marks = False; } else if (borderstyle == NULL) { if (fw->decor_state.parts_drawn & PART_X_HANDLES) { *ret_has_x_marks = True; } if (fw->decor_state.parts_drawn & PART_Y_HANDLES) { *ret_has_y_marks = True; } } else if (!DFS_HAS_HIDDEN_HANDLES(*borderstyle)) { *ret_has_x_marks = True; *ret_has_y_marks = True; } ret_g->x = fw->corner_width; ret_g->y = fw->corner_width; min_w = 2 * fw->corner_width + 4; /* limit by available space, remove handle marks if necessary */ if (frame_g->width < min_w) { ret_g->x = frame_g->width / 3; *ret_has_y_marks = False; } if (frame_g->height < min_w) { ret_g->y = frame_g->height / 3; *ret_has_x_marks = False; } get_window_borders_no_title(fw, &b); if (ret_g->x < b.top_left.width) { ret_g->x = b.top_left.width; } if (ret_g->y < b.top_left.height) { ret_g->y = b.top_left.height; } /* length of the side bars */ ret_g->width = frame_g->width - 2 * ret_g->x; ret_g->height = frame_g->height - 2 * ret_g->y; return; } int frame_window_id_to_context( FvwmWindow *fw, Window w, int *ret_num) { int context = C_ROOT; *ret_num = -1; if (fw == NULL || w == None) { return C_ROOT; } if (w == FW_W_TITLE(fw)) { context = C_TITLE; } else if (Scr.EwmhDesktop && (w == FW_W(Scr.EwmhDesktop) || w == FW_W_PARENT(Scr.EwmhDesktop) || w == FW_W_FRAME(Scr.EwmhDesktop))) { context = C_EWMH_DESKTOP; } else if (w == FW_W(fw) || w == FW_W_PARENT(fw) || w == FW_W_FRAME(fw)) { context = C_WINDOW; } else if (w == FW_W_ICON_TITLE(fw) || w == FW_W_ICON_PIXMAP(fw)) { context = C_ICON; } else if (w == FW_W_CORNER(fw, 0)) { *ret_num = 0; context = C_F_TOPLEFT; } else if (w == FW_W_CORNER(fw, 1)) { *ret_num = 1; context = C_F_TOPRIGHT; } else if (w == FW_W_CORNER(fw, 2)) { *ret_num = 2; context = C_F_BOTTOMLEFT; } else if (w == FW_W_CORNER(fw, 3)) { *ret_num = 3; context = C_F_BOTTOMRIGHT; } else if (w == FW_W_SIDE(fw, 0)) { *ret_num = 0; context = C_SB_TOP; } else if (w == FW_W_SIDE(fw, 1)) { *ret_num = 1; context = C_SB_RIGHT; } else if (w == FW_W_SIDE(fw, 2)) { *ret_num = 2; context = C_SB_BOTTOM; } else if (w == FW_W_SIDE(fw, 3)) { *ret_num = 3; context = C_SB_LEFT; } else { int i; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if (w == FW_W_BUTTON(fw, i) && ((!(i & 1) && i / 2 < Scr.nr_left_buttons) || ( (i & 1) && i / 2 < Scr.nr_right_buttons))) { context = (1 << i) * C_L1; *ret_num = i; break; } } } if (!HAS_HANDLES(fw) && (context & (C_SIDEBAR | C_FRAME))) { context = C_SIDEBAR; } return context; } /* Creates a structure that must be passed to frame_move_resize(). The * structure *must* be deleted with frame_free_move_resize_args() as soon as the * move or resize operation is finished. Prepares the window for a move/resize * operation. * * Arguments: * fw * The window to move or resize. * mr_mode * The mode of operation: * FRAME_MR_SETUP: setup the frame * FRAME_MR_FORCE_SETUP: same, but forces all updates * FRAME_MR_OPAQUE: resize the frame in an opaque fashion * FRAME_MR_SHRINK: shrink the client window (useful for shading only) * FRAME_MR_SCROLL: scroll the client window (useful for shading only) * start_g * The initial geometry of the frame. If a NULL pointer is passed, the * frame_g member of the window is used instead. * end_g * The desired new geometry of the frame. * anim_steps * The number of animation steps in between * = 0: The operation is finished in a single step. * > 0: The given number of steps are drawn in between. * < 0: Each step resizes the window by the given number of pixels. * (the sign of the number is flipped first). * This argument is used only with FRAME_MR_SHRINK and FRAME_MR_SCROLL. */ frame_move_resize_args frame_create_move_resize_args( FvwmWindow *fw, frame_move_resize_mode mr_mode, rectangle *start_g, rectangle *end_g, int anim_steps, int shade_dir) { mr_args_internal *mra; Bool dummy; Bool rc; int whdiff; int xydiff; int diff; /* set some variables */ mra = (mr_args_internal *)safecalloc(1, sizeof(mr_args_internal)); memset(mra, 0, sizeof(*mra)); if (mr_mode & FRAME_MR_DONT_DRAW) { mr_mode &= ~FRAME_MR_DONT_DRAW; mra->flags.do_not_draw = 1; } else { mra->flags.do_not_draw = 0; } if (mr_mode == FRAME_MR_SETUP_BY_APP) { mr_mode = FRAME_MR_SETUP; mra->flags.do_set_bit_gravity = 0; } else { mra->flags.do_set_bit_gravity = 1; } if (mr_mode == FRAME_MR_FORCE_SETUP_NO_W) { mr_mode = FRAME_MR_FORCE_SETUP; mra->flags.do_not_configure_client = 1; } mra->mode = mr_mode; mra->shade_dir = (direction_t)shade_dir; mra->w_with_focus = (fw == get_focus_window()) ? FW_W(fw) : None; /* calculate various geometries */ if (!IS_SHADED(fw)) { rc = XGetGeometry( dpy, FW_W(fw), &JunkRoot, &mra->client_g.x, &mra->client_g.y, (unsigned int*)&mra->client_g.width, (unsigned int*)&mra->client_g.height, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth); if (rc == True) { rc = XTranslateCoordinates( dpy, FW_W_PARENT(fw), Scr.Root, mra->client_g.x, mra->client_g.y, &mra->client_g.x, &mra->client_g.y, &JunkChild); } if (rc == False) { /* Can only happen if the window died */ get_client_geometry(fw, &mra->client_g); } } else { /* If the window was reisez while shaded the client window * will not have been resized. Use the frame to get the * geometry */ get_client_geometry(fw, &mra->client_g); } get_window_borders(fw, &mra->b_g); get_window_borders_no_title(fw, &mra->b_no_title_g); mra->start_g = (start_g != NULL) ? *start_g : fw->g.frame; frame_get_sidebar_geometry( fw, NULL, &mra->start_g, &mra->curr_sidebar_g, &dummy, &dummy); mra->end_g = *end_g; mra->current_g = mra->start_g; mra->next_g = mra->end_g; mra->curr_titlebar_compression = frame_get_titlebar_compression(fw, &mra->start_g); fvwmrect_subtract_rectangles( &mra->delta_g, &mra->end_g, &mra->start_g); /* calcuate the number of animation steps */ switch (mra->mode) { case FRAME_MR_SHRINK: case FRAME_MR_SCROLL: whdiff = max(abs(mra->delta_g.width), abs(mra->delta_g.height)); xydiff = max(abs(mra->delta_g.x), abs(mra->delta_g.y)); diff = max(whdiff, xydiff); if (diff == 0) { mra->anim_steps = 0; } else if (anim_steps < 0) { mra->anim_steps = -(diff - 1) / anim_steps; } else if (anim_steps > 0 && anim_steps >= diff) { mra->anim_steps = diff - 1; } else { mra->anim_steps = anim_steps; } mra->anim_steps++; break; case FRAME_MR_FORCE_SETUP: case FRAME_MR_SETUP: case FRAME_MR_OPAQUE: default: mra->anim_steps = 1; break; } /* various flags */ mra->flags.was_moved = 0; mra->step_flags.was_hidden = (frame_is_parent_hidden(fw, &mra->start_g) == True); mra->flags.is_setup = (mra->mode == FRAME_MR_FORCE_SETUP || mra->mode == FRAME_MR_SETUP); mra->flags.do_force = (mra->mode == FRAME_MR_FORCE_SETUP); mra->flags.is_shading = !(mra->flags.is_setup || mra->mode == FRAME_MR_OPAQUE); mra->flags.do_update_shape = (FShapesSupported && mra->flags.is_shading && fw->wShaped); /* Lazy shading does not draw the hadle marks. Disable them in the * window flags if necessary. Restores the marks when mr_args are * freed. Lazy shading is considerably faster but causes funny looks * if either the border uses a tiled pixmap background. */ mra->flags.had_handles = HAS_HANDLES(fw); mra->flags.is_lazy_shading = frame_get_shading_laziness(fw, mra); mra->trans_parts = border_get_transparent_decorations_part(fw); if (mra->flags.is_lazy_shading) { SET_HAS_HANDLES(fw, 0); } /* Set gravities for the window parts. */ frame_get_resize_decor_gravities( &mra->grav, GET_TITLE_DIR(fw), mra->mode, &mra->delta_g); if (mra->flags.is_setup && mra->delta_g.x == 0 && mra->delta_g.y == 0 && mra->delta_g.width == 0 && mra->delta_g.height == 0) { frame_decor_gravities_type grav; /* The caller has already set the frame geometry. Use * StaticGravity so the sub windows are not moved to funny * places. */ grav.decor_grav = StaticGravity; grav.title_grav = StaticGravity; grav.lbutton_grav = StaticGravity; grav.rbutton_grav = StaticGravity; grav.parent_grav = StaticGravity; grav.client_grav = StaticGravity; frame_set_decor_gravities( fw, &grav, (mra->flags.do_set_bit_gravity) ? 1 : 0); mra->flags.do_restore_gravity = 1; mra->flags.do_force = 1; } else { frame_set_decor_gravities( fw, &mra->grav, (mra->flags.do_set_bit_gravity) ? 1 : 0); } frame_reparent_hide_windows(FW_W_FRAME(fw)); return (frame_move_resize_args)mra; } /* Changes the final_geometry in a frame_move_resize_args structure. This is * useful during opaque resize operations to avoid creating and destroying the * args for each animation step. * * If FRAME_MR_SHRINK or FRAME_MR_SCROLL was used to greate the mr_args, the * function does nothing. */ void frame_update_move_resize_args( frame_move_resize_args mr_args, rectangle *end_g) { mr_args_internal *mra; mra = (mr_args_internal *)mr_args; mra->end_g = *end_g; fvwmrect_subtract_rectangles( &mra->delta_g, &mra->end_g, &mra->start_g); return; } /* Destroys the structure allocated with frame_create_move_resize_args(). Does * some clean up operations on the modified window first. */ void frame_free_move_resize_args( FvwmWindow *fw, frame_move_resize_args mr_args) { mr_args_internal *mra; mra = (mr_args_internal *)mr_args; SET_HAS_HANDLES(fw, mra->flags.had_handles); fw->g.frame = mra->end_g; if (mra->flags.is_lazy_shading) { border_draw_decorations( fw, PART_ALL, (mra->w_with_focus != None) ? True : False, True, CLEAR_ALL, &mra->current_g, &mra->end_g); } else if (mra->trans_parts != PART_NONE) { border_draw_decorations( fw, mra->trans_parts, (mra->w_with_focus != None) ? True : False, True, CLEAR_ALL, &mra->current_g, &mra->end_g); } update_absolute_geometry(fw); frame_reparent_hide_windows(Scr.NoFocusWin); if (mra->w_with_focus != None && FP_IS_LENIENT(FW_FOCUS_POLICY(fw))) { /* domivogt (28-Dec-1999): For some reason the XMoveResize() on * the frame window removes the input focus from the client * window. I have no idea why, but if we explicitly restore * the focus here everything works fine. */ FOCUS_SET(mra->w_with_focus, fw); } if (mra->flags.do_update_shape) { /* unset shape */ FShapeCombineMask( dpy, FW_W_FRAME(fw), FShapeBounding, 0, 0, None, FShapeSet); } frame_setup_shape(fw, mra->end_g.width, mra->end_g.height, fw->wShaped); if (mra->flags.do_restore_gravity) { /* TA: 2011-09-04: There might be a chance some clients with * a gravity other than Static (such as non-NW gravity) * might not react well -- but setting the gravity to the * main window hint will break clients being remapped as * subwindows, c.f. XEmbed. * * Note that we should probably consider handling * GravityNotify events ourselves, since we already set * StructureNotify and SubstructureNotify events on * FW_W_PARENT for example. * * mra->grav.client_grav = fw->hints.win_gravity; */ frame_set_decor_gravities( fw, &mra->grav, (mra->flags.do_set_bit_gravity) ? 2 : 0); } else { frame_restore_client_gravities(fw); } if (!IS_SHADED(fw) && mra->flags.was_moved) { SendConfigureNotify( fw, fw->g.frame.x, fw->g.frame.y, fw->g.frame.width, fw->g.frame.height, 0, True); mra->flags.was_moved = 0; } focus_grab_buttons_on_layer(fw->layer); /* free the memory */ free(mr_args); return; } void frame_move_resize( FvwmWindow *fw, frame_move_resize_args mr_args) { mr_args_internal *mra; Bool is_grabbed = False; int i; mra = (mr_args_internal *)mr_args; /* freeze the cursor shape; otherwise it may flash to a different shape * during the animation */ if (mra->anim_steps > 1) { is_grabbed = GrabEm(None, GRAB_FREEZE_CURSOR); } /* animation */ for (i = 1; i <= mra->anim_steps; i++, frame_next_move_resize_args(mra)) { mra->current_step = i; frame_move_resize_step(fw, mra); } if (is_grabbed == True) { UngrabEm(GRAB_FREEZE_CURSOR); } return; } /*********************************************************************** * * Procedure: * frame_setup_window - set window sizes * * Inputs: * fw - the FvwmWindow pointer * x - the x coordinate of the upper-left outer corner of the frame * y - the y coordinate of the upper-left outer corner of the frame * w - the width of the frame window w/o border * h - the height of the frame window w/o border * * Special Considerations: * This routine will check to make sure the window is not completely * off the display, if it is, it'll bring some of it back on. * * The fw->frame_XXX variables should NOT be updated with the * values of x,y,w,h prior to calling this routine, since the new * values are compared against the old to see whether a synthetic * ConfigureNotify event should be sent. (It should be sent if the * window was moved but not resized.) * ************************************************************************/ void frame_setup_window( FvwmWindow *fw, int x, int y, int w, int h, Bool do_send_configure_notify) { rectangle g; g.x = x; g.y = y; g.width = w; g.height = h; __frame_setup_window(fw, &g, do_send_configure_notify, False, False); return; } void frame_setup_window_app_request( FvwmWindow *fw, int x, int y, int w, int h, Bool do_send_configure_notify) { rectangle g; g.x = x; g.y = y; g.width = w; g.height = h; __frame_setup_window(fw, &g, do_send_configure_notify, False, True); return; } void frame_force_setup_window( FvwmWindow *fw, int x, int y, int w, int h, Bool do_send_configure_notify) { rectangle g; g.x = x; g.y = y; g.width = w; g.height = h; __frame_setup_window(fw, &g, do_send_configure_notify, True, False); return; } /**************************************************************************** * * Sets up the shaped window borders * ****************************************************************************/ void frame_setup_shape(FvwmWindow *fw, int w, int h, int shape_mode) { rectangle r; size_borders b; if (!FShapesSupported) { return; } if (fw->wShaped != shape_mode) { fw->wShaped = shape_mode; frame_reshape_border(fw); } if (!shape_mode) { /* unset shape */ FShapeCombineMask( dpy, FW_W_FRAME(fw), FShapeBounding, 0, 0, None, FShapeSet); } else { /* shape the window */ get_window_borders(fw, &b); FShapeCombineShape( dpy, FW_W_FRAME(fw), FShapeBounding, b.top_left.width, b.top_left.height, FW_W(fw), FShapeBounding, FShapeSet); if (FW_W_TITLE(fw)) { XRectangle rect; /* windows w/ titles */ r.width = w; r.height = h; get_title_geometry(fw, &r); rect.x = r.x; rect.y = r.y; rect.width = r.width; rect.height = r.height; SUPPRESS_UNUSED_VAR_WARNING(rect); FShapeCombineRectangles( dpy, FW_W_FRAME(fw), FShapeBounding, 0, 0, &rect, 1, FShapeUnion, Unsorted); } } return; } /* ---------------------------- builtin commands --------------------------- */ fvwm-2.6.7/fvwm/colormaps.h0000644000175700017570000000626612773467232012622 00000000000000/* -*-c-*- */ /* This module is all new * by Rob Nation * * This code handles colormaps for fvwm. * * Copyright 1994 Robert Nation. No restrictions are placed on this code, * as long as the copyright notice is preserved . No guarantees or * warrantees of any sort whatsoever are given or implied or anything. */ #ifndef COLORMAP_H #define COLORMAP_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* colormap notify event handler * * This procedure handles both a client changing its own colormap, and * a client explicitly installing its colormap itself (only the window * manager should do that, so we must set it correctly). */ void colormap_handle_colormap_notify(const evh_args_t *ea); /* Re-Install the active colormap */ void ReInstallActiveColormap(void); /* install the colormaps for one fvwm window * * Inputs: * type - type of event that caused the installation * tmp - for a subset of event types, the address of the * window structure, whose colormaps are to be installed. */ void InstallWindowColormaps(const FvwmWindow *tmp); /* Force (un)loads root colormap(s) * * These matching routines provide a mechanism to insure that * the root colormap(s) is installed during operations like * rubber banding that require colors from * that colormap. Calls may be nested arbitrarily deeply, * as long as there is one UninstallRootColormap call per * InstallRootColormap call. * * The final UninstallRootColormap will cause the colormap list * which would otherwise have be loaded to be loaded, unless * Enter or Leave Notify events are queued, indicating some * other colormap list would potentially be loaded anyway. */ void InstallRootColormap(void); /* Unstacks one layer of root colormap pushing * If we peel off the last layer, re-install the application colormap */ void UninstallRootColormap(void); /* Force (un)loads fvwm colormap(s) * * This is used to ensure the fvwm colormap is installed during * menu operations */ void InstallFvwmColormap(void); void UninstallFvwmColormap(void); /* Gets the WM_COLORMAP_WINDOWS property from the window * * This property typically doesn't exist, but a few applications * use it. These seem to occur mostly on SGI machines. */ void FetchWmColormapWindows (FvwmWindow *tmp); /* clasen@mathematik.uni-freiburg.de - 03/01/1999 - new * boolean for handling of client-side InstallColormap * as described in the ICCCM 2.0 */ void set_client_controls_colormaps(Bool flag); /* Looks through the window list for any matching COLORMAP_WINDOWS * windows and installs the colormap if one exists. */ void EnterSubWindowColormap(Window win); void LeaveSubWindowColormap(Window win); #endif /* COLORMAP_H */ fvwm-2.6.7/fvwm/menuitem.c0000644000175700017570000005531013001406607012413 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/Picture.h" #include "libs/Graphics.h" #include "libs/PictureGraphics.h" #include "libs/Rectangles.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "misc.h" #include "screen.h" #include "menudim.h" #include "menustyle.h" #include "menuitem.h" #include "decorations.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void clear_menu_item_background( MenuPaintItemParameters *mpip, int x, int y, int w, int h) { MenuStyle *ms = mpip->ms; if (!ST_HAS_MENU_CSET(ms) && ST_FACE(ms).type == GradientMenu && (ST_FACE(ms).gradient_type == D_GRADIENT || ST_FACE(ms).gradient_type == B_GRADIENT)) { XEvent e; e.xexpose.x = x; e.xexpose.y = y; e.xexpose.width = w; e.xexpose.height = h; mpip->cb_reset_bg(mpip->cb_mr, &e); } else { XClearArea(dpy, mpip->w, x, y, w, h, False); } } /* * * Draws two horizontal lines to form a separator * */ static void draw_separator( Window w, GC TopGC, GC BottomGC, int x1, int y, int x2) { XDrawLine(dpy, w, TopGC , x1, y, x2, y); XDrawLine(dpy, w, BottomGC, x1-1, y+1, x2+1, y+1); return; } /* * * Draws a tear off bar. Similar to a separator, but with a dashed line. * */ static void draw_tear_off_bar( Window w, GC TopGC, GC BottomGC, int x1, int y, int x2) { XGCValues xgcv; int width; int offset; xgcv.line_style = LineOnOffDash; xgcv.dashes = MENU_TEAR_OFF_BAR_DASH_WIDTH; XChangeGC(dpy, TopGC, GCLineStyle | GCDashList, &xgcv); XChangeGC(dpy, BottomGC, GCLineStyle | GCDashList, &xgcv); width = (x2 - x1 + 1); offset = (width / MENU_TEAR_OFF_BAR_DASH_WIDTH) * MENU_TEAR_OFF_BAR_DASH_WIDTH; offset = (width - offset) / 2; x1 += offset; x2 += offset; XDrawLine(dpy, w, TopGC, x1, y, x2, y); XDrawLine(dpy, w, BottomGC, x1, y + 1, x2, y + 1); xgcv.line_style = LineSolid; XChangeGC(dpy, TopGC, GCLineStyle, &xgcv); XChangeGC(dpy, BottomGC, GCLineStyle, &xgcv); return; } static void draw_highlight_background( struct MenuPaintItemParameters *mpip, int x, int y, int width, int height, colorset_t *cs, GC gc) { if (cs != NULL && cs->pixmap && cs->pixmap_type != PIXMAP_TILED) { Pixmap p; p = CreateOffsetBackgroundPixmap( dpy, mpip->w, 0, 0, width, height, cs, Pdepth, gc, False); switch (cs->pixmap_type) { case PIXMAP_STRETCH_X: /* todo: optimize to only create one pixmap and gc per * mr. */ case PIXMAP_STRETCH_Y: { XGCValues gcv; int gcm; GC bgc; gcv.tile = p; gcv.fill_style = FillTiled; gcm = GCFillStyle | GCTile; /* vertcal gradients has to be aligned properly */ if (cs->pixmap_type == PIXMAP_STRETCH_Y) { gcv.ts_y_origin = y; gcm|=GCTileStipYOrigin; } else if (cs->pixmap_type == PIXMAP_STRETCH_X) { gcv.ts_x_origin = x; gcm|=GCTileStipXOrigin; } bgc = fvwmlib_XCreateGC(dpy, mpip->w, gcm, &gcv); XFillRectangle(dpy, mpip->w, bgc, x, y, width, height); XFreeGC(dpy, bgc); break; } default: XCopyArea(dpy, p, mpip->w, gc, 0, 0, width, height, x, y); break; } XFreePixmap(dpy, p); } else { XFillRectangle(dpy, mpip->w, gc, x, y, width, height); } } /* ---------------------------- interface functions ------------------------ */ /* Allocates a new, empty menu item */ struct MenuItem *menuitem_create(void) { MenuItem *mi; mi = (MenuItem *)safemalloc(sizeof(MenuItem)); memset(mi, 0, sizeof(MenuItem)); return mi; } /* Frees a menu item and all of its allocated resources. */ void menuitem_free(struct MenuItem *mi) { int i; if (!mi) { return; } for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i] != NULL) { free(MI_LABEL(mi)[i]); } } if (MI_ACTION(mi) != NULL) { free(MI_ACTION(mi)); } if (MI_PICTURE(mi)) { PDestroyFvwmPicture(dpy, MI_PICTURE(mi)); } for (i = 0; i < MAX_MENU_ITEM_MINI_ICONS; i++) { if (MI_MINI_ICON(mi)[i]) { PDestroyFvwmPicture(dpy, MI_MINI_ICON(mi)[i]); } } free(mi); return; } /* Duplicate a menu item into newly allocated memory. The new item is * completely independent of the old one. */ struct MenuItem *menuitem_clone(struct MenuItem *mi) { MenuItem *new_mi; int i; /* copy everything */ new_mi = (MenuItem *)safemalloc(sizeof(MenuItem)); memcpy(new_mi, mi, sizeof(MenuItem)); /* special treatment for a few parts */ MI_NEXT_ITEM(new_mi) = NULL; MI_PREV_ITEM(new_mi) = NULL; MI_WAS_DESELECTED(new_mi) = 0; if (MI_ACTION(mi) != NULL) { MI_ACTION(new_mi) = safestrdup(MI_ACTION(mi)); } for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i] != NULL) { MI_LABEL(new_mi)[i] = strdup(MI_LABEL(mi)[i]); } } if (MI_PICTURE(mi) != NULL) { MI_PICTURE(new_mi) = PCloneFvwmPicture(MI_PICTURE(mi)); } for (i = 0; i < MAX_MENU_ITEM_MINI_ICONS; i++) { if (MI_MINI_ICON(mi)[i] != NULL) { MI_MINI_ICON(new_mi)[i] = PCloneFvwmPicture(MI_MINI_ICON(mi)[i]); } } return new_mi; } /* Calculate the size of the various parts of the item. The sizes are returned * through mipst. */ void menuitem_get_size( struct MenuItem *mi, struct MenuItemPartSizesT *mipst, FlocaleFont *font, Bool do_reverse_icon_order) { int i; int j; int w; memset(mipst, 0, sizeof(MenuItemPartSizesT)); if (MI_IS_POPUP(mi)) { mipst->triangle_width = MENU_TRIANGLE_WIDTH; } else if (MI_IS_TITLE(mi) && !MI_HAS_PICTURE(mi)) { Bool is_formatted = False; /* titles stretch over the whole menu width, so count the * maximum separately if the title is unformatted. */ for (j = 1; j < MAX_MENU_ITEM_LABELS; j++) { if (MI_LABEL(mi)[j] != NULL) { is_formatted = True; break; } else { MI_LABEL_OFFSET(mi)[j] = 0; } } if (!is_formatted && MI_LABEL(mi)[0] != NULL) { MI_LABEL_STRLEN(mi)[0] = strlen(MI_LABEL(mi)[0]); w = FlocaleTextWidth( font, MI_LABEL(mi)[0], MI_LABEL_STRLEN(mi)[0]); MI_LABEL_OFFSET(mi)[0] = w; MI_IS_TITLE_CENTERED(mi) = True; if (mipst->title_width < w) { mipst->title_width = w; } return; } } /* regular item or formatted title */ for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i]) { MI_LABEL_STRLEN(mi)[i] = strlen(MI_LABEL(mi)[i]); w = FlocaleTextWidth( font, MI_LABEL(mi)[i], MI_LABEL_STRLEN(mi)[i]); MI_LABEL_OFFSET(mi)[i] = w; if (mipst->label_width[i] < w) { mipst->label_width[i] = w; } } } if (MI_PICTURE(mi) && mipst->picture_width < MI_PICTURE(mi)->width) { mipst->picture_width = MI_PICTURE(mi)->width; } for (i = 0; i < MAX_MENU_ITEM_MINI_ICONS; i++) { if (MI_MINI_ICON(mi)[i]) { int k; /* Reverse mini icon order for left submenu style. */ k = (do_reverse_icon_order == True) ? MAX_MENU_ITEM_MINI_ICONS - 1 - i : i; mipst->icon_width[k] = MI_MINI_ICON(mi)[i]->width; } } return; } /* * * Procedure: * menuitem_paint - draws a single entry in a popped up menu * * mr - the menu instance that holds the menu item * mi - the menu item to redraw * fw - the FvwmWindow structure to check against allowed functions * */ void menuitem_paint( struct MenuItem *mi, struct MenuPaintItemParameters *mpip) { struct MenuStyle *ms = mpip->ms; struct MenuDimensions *dim = mpip->dim; static FlocaleWinString *fws = NULL; int y_offset; int text_y; int y_height; int x; int y; int lit_x_start; int lit_x_end; gc_quad_t gcs; gc_quad_t off_gcs; int cs = -1; int off_cs; FvwmRenderAttributes fra; /*Pixel fg, fgsh;*/ int relief_thickness = ST_RELIEF_THICKNESS(ms); Bool is_item_selected; Bool item_cleared = False; Bool xft_clear = False; Bool empty_inter = False; XRectangle b; Region region = None; int i; int sx1; int sx2; FlocaleFont* font; if (!mi) { return; } is_item_selected = (mi == mpip->selected_item); if (MI_IS_TITLE(mi)) { font = ST_PTITLEFONT(ms); } else { font = ST_PSTDFONT(ms); } y_offset = MI_Y_OFFSET(mi); y_height = MI_HEIGHT(mi); if (MI_IS_SELECTABLE(mi)) { text_y = y_offset + MDIM_ITEM_TEXT_Y_OFFSET(*dim); } else { text_y = y_offset + font->ascent + ST_TITLE_GAP_ABOVE(ms); } /* center text vertically if the pixmap is taller */ if (MI_PICTURE(mi)) { text_y += MI_PICTURE(mi)->height; } for (i = 0; i < mpip->used_mini_icons; i++) { y = 0; if (MI_MINI_ICON(mi)[i]) { if (MI_MINI_ICON(mi)[i]->height > y) { y = MI_MINI_ICON(mi)[i]->height; } } y -= font->height; if (y > 1) { text_y += y / 2; } } off_cs = ST_HAS_MENU_CSET(ms) ? ST_CSET_MENU(ms) : -1; /* Note: it's ok to pass a NULL label to is_function_allowed. */ if ( !IS_EWMH_DESKTOP_FW(mpip->fw) && !is_function_allowed( MI_FUNC_TYPE(mi), MI_LABEL(mi)[0], mpip->fw, RQORIG_PROGRAM_US, False)) { gcs = ST_MENU_STIPPLE_GCS(ms); off_gcs = gcs; off_cs = ST_HAS_GREYED_CSET(ms) ? ST_CSET_GREYED(ms) : -1; } else if (is_item_selected) { gcs = ST_MENU_ACTIVE_GCS(ms); off_gcs = ST_MENU_INACTIVE_GCS(ms); } else if (MI_IS_TITLE(mi)) { gcs = ST_MENU_TITLE_GCS(ms); off_gcs = ST_MENU_INACTIVE_GCS(ms); } else { gcs = ST_MENU_INACTIVE_GCS(ms); off_gcs = ST_MENU_INACTIVE_GCS(ms); } if (is_item_selected) { cs = (ST_HAS_ACTIVE_CSET(ms)) ? ST_CSET_ACTIVE(ms) : -1; } else if (MI_IS_TITLE(mi)) { cs = (ST_HAS_TITLE_CSET(ms)) ? ST_CSET_TITLE(ms) : off_cs; } else { cs = off_cs; } /* * Hilight the item. */ if (FftSupport && ST_PSTDFONT(ms)->fftf.fftfont != NULL) { xft_clear = True; } /* Hilight or clear the background. */ lit_x_start = -1; lit_x_end = -1; if (is_item_selected && (ST_DO_HILIGHT_BACK(ms) || ST_DO_HILIGHT_FORE(ms))) { /* Hilight the background. */ if (MDIM_HILIGHT_WIDTH(*dim) - 2 * relief_thickness > 0) { lit_x_start = MDIM_HILIGHT_X_OFFSET(*dim) + relief_thickness; lit_x_end = lit_x_start + MDIM_HILIGHT_WIDTH(*dim) - 2 * relief_thickness; if (ST_DO_HILIGHT_BACK(ms)) { draw_highlight_background( mpip, lit_x_start, y_offset + relief_thickness, lit_x_end - lit_x_start, y_height - relief_thickness, (cs >= 0 ? &Colorset[cs] : NULL), gcs.back_gc); item_cleared = True; } } } else if ((MI_WAS_DESELECTED(mi) && (relief_thickness > 0 || ST_DO_HILIGHT_BACK(ms) || ST_DO_HILIGHT_FORE(ms)) && (ST_FACE(ms).type != GradientMenu || ST_HAS_MENU_CSET(ms)))) { int x1; int x2; /* we clear if xft_clear and !ST_HAS_MENU_CSET(ms) as the * non colorset code is too complicate ... olicha */ int d = 0; if (MI_PREV_ITEM(mi) && mpip->selected_item == MI_PREV_ITEM(mi)) { /* Don't paint over the hilight relief. */ d = relief_thickness; } /* Undo the hilighting. */ x1 = min( MDIM_HILIGHT_X_OFFSET(*dim), MDIM_ITEM_X_OFFSET(*dim)); x2 = max( MDIM_HILIGHT_X_OFFSET(*dim) + MDIM_HILIGHT_WIDTH(*dim), MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim)); clear_menu_item_background( mpip, x1, y_offset + d, x2 - x1, y_height + relief_thickness - d); item_cleared = True; } else if (MI_IS_TITLE(mi)) { lit_x_start = MDIM_ITEM_X_OFFSET(*dim); lit_x_end = lit_x_start + MDIM_ITEM_WIDTH(*dim); /* Hilight the background. */ if ( MDIM_HILIGHT_WIDTH(*dim) > 0 && ST_DO_HILIGHT_TITLE_BACK(ms)) { draw_highlight_background( mpip, lit_x_start, y_offset + relief_thickness, lit_x_end - lit_x_start, y_height - relief_thickness, (cs >= 0 ? &Colorset[cs] : NULL), gcs.back_gc); item_cleared = True; } } MI_WAS_DESELECTED(mi) = False; memset(&fra, 0, sizeof(fra)); fra.mask = 0; /* Hilight 3D */ if (is_item_selected && relief_thickness > 0) { GC rgc; GC sgc; rgc = gcs.hilight_gc; sgc = gcs.shadow_gc; if (ST_IS_ITEM_RELIEF_REVERSED(ms)) { GC tgc = rgc; /* swap gcs for reversed relief */ rgc = sgc; sgc = tgc; } if (MDIM_HILIGHT_WIDTH(*dim) - 2 * relief_thickness > 0) { /* The relief reaches down into the next item, hence * the value for the second y coordinate: * MI_HEIGHT(mi) + 1 */ RelieveRectangle( dpy, mpip->w, MDIM_HILIGHT_X_OFFSET(*dim), y_offset, MDIM_HILIGHT_WIDTH(*dim) - 1, MI_HEIGHT(mi) - 1 + relief_thickness, rgc, sgc, relief_thickness); } } /* * Draw the item itself. */ /* Calculate the separator offsets. */ if (ST_HAS_LONG_SEPARATORS(ms)) { sx1 = MDIM_ITEM_X_OFFSET(*dim) + relief_thickness; sx2 = MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim) - 1 - relief_thickness; } else { sx1 = MDIM_ITEM_X_OFFSET(*dim) + relief_thickness + MENU_SEPARATOR_SHORT_X_OFFSET; sx2 = MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim) - 1 - relief_thickness - MENU_SEPARATOR_SHORT_X_OFFSET; } if (MI_IS_SEPARATOR(mi)) { if (sx1 < sx2) { /* It's a separator. */ draw_separator( mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1, y_offset + y_height - MENU_SEPARATOR_HEIGHT, sx2); /* Nothing else to do. */ } return; } else if (MI_IS_TEAR_OFF_BAR(mi)) { int tx1; int tx2; tx1 = MDIM_ITEM_X_OFFSET(*dim) + relief_thickness + MENU_TEAR_OFF_BAR_X_OFFSET; tx2 = MDIM_ITEM_X_OFFSET(*dim) + MDIM_ITEM_WIDTH(*dim) - 1 - relief_thickness - MENU_TEAR_OFF_BAR_X_OFFSET; if (tx1 < tx2) { /* It's a tear off bar. */ draw_tear_off_bar( mpip->w, gcs.shadow_gc, gcs.hilight_gc, tx1, y_offset + relief_thickness + MENU_TEAR_OFF_BAR_Y_OFFSET, tx2); } /* Nothing else to do. */ return; } else if (MI_IS_TITLE(mi)) { /* Separate the title. */ if (ST_TITLE_UNDERLINES(ms) > 0 && !mpip->flags.is_first_item) { int add = (MI_IS_SELECTABLE(MI_PREV_ITEM(mi))) ? relief_thickness : 0; text_y += MENU_SEPARATOR_HEIGHT + add; y = y_offset + add; if (sx1 < sx2) { draw_separator( mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1, y, sx2); } } /* Underline the title. */ switch (ST_TITLE_UNDERLINES(ms)) { case 0: break; case 1: if (MI_NEXT_ITEM(mi) != NULL) { y = y_offset + y_height - MENU_SEPARATOR_HEIGHT; draw_separator( mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1, y, sx2); } break; default: for (i = ST_TITLE_UNDERLINES(ms); i-- > 0; ) { y = y_offset + y_height - 1 - i * MENU_UNDERLINE_HEIGHT; XDrawLine( dpy, mpip->w, gcs.shadow_gc, sx1, y, sx2, y); } break; } } /* * Draw the labels. */ if (fws == NULL) { FlocaleAllocateWinString(&fws); } fws->win = mpip->w; fws->y = text_y; fws->flags.has_colorset = 0; b.y = text_y - font->ascent; b.height = font->height + 1; /* ? */ if (!item_cleared && mpip->ev) { int u,v; if (!frect_get_seg_intersection( mpip->ev->xexpose.y, mpip->ev->xexpose.height, b.y, b.height, &u, &v)) { /* empty intersection */ empty_inter = True; } b.y = u; b.height = v; } for (i = MAX_MENU_ITEM_LABELS; i-- > 0; ) { if (!empty_inter && MI_LABEL(mi)[i] && *(MI_LABEL(mi)[i])) { Bool draw_string = True; int text_width; int tmp_cs; if (MI_LABEL_OFFSET(mi)[i] >= lit_x_start && MI_LABEL_OFFSET(mi)[i] < lit_x_end) { /* label is in hilighted area */ fws->gc = gcs.fore_gc; tmp_cs = cs; } else { /* label is in unhilighted area */ fws->gc = off_gcs.fore_gc; tmp_cs = off_cs; } if (tmp_cs >= 0) { fws->colorset = &Colorset[tmp_cs]; fws->flags.has_colorset = 1; } fws->str = MI_LABEL(mi)[i]; b.x = fws->x = MI_LABEL_OFFSET(mi)[i]; b.width = text_width = FlocaleTextWidth( font, fws->str, strlen(fws->str)); if (!item_cleared && mpip->ev) { int s_x,s_w; if (frect_get_seg_intersection( mpip->ev->xexpose.x, mpip->ev->xexpose.width, fws->x, text_width, &s_x, &s_w)) { b.x = s_x; b.width = s_w; region = XCreateRegion(); XUnionRectWithRegion( &b, region, region); fws->flags.has_clip_region = True; fws->clip_region = region; draw_string = True; XSetRegion(dpy, fws->gc, region); } else { /* empty intersection */ draw_string = False; } } if (draw_string) { if (!item_cleared && xft_clear) { clear_menu_item_background( mpip, b.x, b.y, b.width, b.height); } FlocaleDrawString(dpy, font, fws, 0); /* hot key */ if (MI_HAS_HOTKEY(mi) && !MI_IS_TITLE(mi) && (!MI_IS_HOTKEY_AUTOMATIC(mi) || ST_USE_AUTOMATIC_HOTKEYS(ms)) && MI_HOTKEY_COLUMN(mi) == i) { FlocaleDrawUnderline( dpy, ST_PSTDFONT(ms), fws, MI_HOTKEY_COFFSET(mi)); } } } if (region) { XDestroyRegion(region); region = None; fws->flags.has_clip_region = False; fws->clip_region = None; XSetClipMask(dpy, fws->gc, None); } } /* * Draw the submenu triangle. */ if (MI_IS_POPUP(mi)) { GC tmp_gc; if (MDIM_TRIANGLE_X_OFFSET(*dim) >= lit_x_start && MDIM_TRIANGLE_X_OFFSET(*dim) < lit_x_end && is_item_selected) { /* triangle is in hilighted area */ if (ST_TRIANGLES_USE_FORE(ms)) { tmp_gc = gcs.fore_gc; } else { tmp_gc = gcs.hilight_gc; } } else { /* triangle is in unhilighted area */ if (ST_TRIANGLES_USE_FORE(ms)) { tmp_gc = off_gcs.fore_gc; } else { tmp_gc = off_gcs.hilight_gc; } } y = y_offset + (y_height - MENU_TRIANGLE_HEIGHT + relief_thickness) / 2; if (ST_TRIANGLES_USE_FORE(ms)) { DrawTrianglePattern( dpy, mpip->w, tmp_gc, tmp_gc, tmp_gc, MDIM_TRIANGLE_X_OFFSET(*dim), y, MENU_TRIANGLE_WIDTH, MENU_TRIANGLE_HEIGHT, 0, (mpip->flags.is_left_triangle) ? 'l' : 'r', ST_HAS_TRIANGLE_RELIEF(ms), !ST_HAS_TRIANGLE_RELIEF(ms), is_item_selected); } else { DrawTrianglePattern( dpy, mpip->w, gcs.hilight_gc, gcs.shadow_gc, tmp_gc, MDIM_TRIANGLE_X_OFFSET(*dim), y, MENU_TRIANGLE_WIDTH, MENU_TRIANGLE_HEIGHT, 0, (mpip->flags.is_left_triangle) ? 'l' : 'r', ST_HAS_TRIANGLE_RELIEF(ms), !ST_HAS_TRIANGLE_RELIEF(ms), is_item_selected); } } /* * Draw the item picture. */ if (MI_PICTURE(mi)) { GC tmp_gc; int tmp_cs; Bool draw_picture = True; x = menudim_middle_x_offset(mpip->dim) - MI_PICTURE(mi)->width / 2; y = y_offset + ((MI_IS_SELECTABLE(mi)) ? relief_thickness : 0); if (x >= lit_x_start && x < lit_x_end) { tmp_gc = gcs.fore_gc; tmp_cs = cs; } else { tmp_gc = off_gcs.fore_gc; tmp_cs = off_cs; } fra.mask = FRAM_DEST_IS_A_WINDOW; if (tmp_cs >= 0) { fra.mask |= FRAM_HAVE_ICON_CSET; fra.colorset = &Colorset[tmp_cs]; } b.x = x; b.y = y; b.width = MI_PICTURE(mi)->width; b.height = MI_PICTURE(mi)->height; if (!item_cleared && mpip->ev) { if (!frect_get_intersection( mpip->ev->xexpose.x, mpip->ev->xexpose.y, mpip->ev->xexpose.width, mpip->ev->xexpose.height, b.x, b.y, b.width, b.height, &b)) { draw_picture = False; } } if (draw_picture) { if ( !item_cleared && (MI_PICTURE(mi)->alpha != None || (tmp_cs >=0 && Colorset[tmp_cs].icon_alpha_percent < 100))) { clear_menu_item_background( mpip, b.x, b.y, b.width, b.height); } PGraphicsRenderPicture( dpy, mpip->w, MI_PICTURE(mi), &fra, mpip->w, tmp_gc, Scr.MonoGC, Scr.AlphaGC, b.x - x, b.y - y, b.width, b.height, b.x, b.y, b.width, b.height, False); } } /* * Draw the mini icons. */ for (i = 0; i < mpip->used_mini_icons; i++) { int k; Bool draw_picture = True; /* We need to reverse the mini icon order for left submenu * style. */ k = (ST_USE_LEFT_SUBMENUS(ms)) ? mpip->used_mini_icons - 1 - i : i; if (MI_MINI_ICON(mi)[i]) { GC tmp_gc; int tmp_cs; if (MI_PICTURE(mi)) { y = y_offset + MI_HEIGHT(mi) - MI_MINI_ICON(mi)[i]->height; } else { y = y_offset + (MI_HEIGHT(mi) + ((MI_IS_SELECTABLE(mi)) ? relief_thickness : 0) - MI_MINI_ICON(mi)[i]->height) / 2; } if (MDIM_ICON_X_OFFSET(*dim)[k] >= lit_x_start && MDIM_ICON_X_OFFSET(*dim)[k] < lit_x_end) { /* icon is in hilighted area */ tmp_gc = gcs.fore_gc; tmp_cs = cs; } else { /* icon is in unhilighted area */ tmp_gc = off_gcs.fore_gc; tmp_cs = off_cs; } fra.mask = FRAM_DEST_IS_A_WINDOW; if (tmp_cs >= 0) { fra.mask |= FRAM_HAVE_ICON_CSET; fra.colorset = &Colorset[tmp_cs]; } b.x = MDIM_ICON_X_OFFSET(*dim)[k]; b.y = y; b.width = MI_MINI_ICON(mi)[i]->width; b.height = MI_MINI_ICON(mi)[i]->height; if (!item_cleared && mpip->ev) { if (!frect_get_intersection( mpip->ev->xexpose.x, mpip->ev->xexpose.y, mpip->ev->xexpose.width, mpip->ev->xexpose.height, b.x, b.y, b.width, b.height, &b)) { draw_picture = False; } } if (draw_picture) { if (!item_cleared && (MI_MINI_ICON(mi)[i]->alpha != None || (tmp_cs >=0 && Colorset[tmp_cs].icon_alpha_percent < 100))) { clear_menu_item_background( mpip, b.x, b.y, b.width, b.height); } PGraphicsRenderPicture( dpy, mpip->w, MI_MINI_ICON(mi)[i], &fra, mpip->w, tmp_gc, Scr.MonoGC, Scr.AlphaGC, b.x - MDIM_ICON_X_OFFSET(*dim)[k], b.y - y, b.width, b.height, b.x, b.y, b.width, b.height, False); } } } return; } /* returns the center y coordinate of the menu item */ int menuitem_middle_y_offset(struct MenuItem *mi, struct MenuStyle *ms) { int r; if (!mi) { return ST_BORDER_WIDTH(ms); } r = (MI_IS_SELECTABLE(mi)) ? ST_RELIEF_THICKNESS(ms) : 0; return MI_Y_OFFSET(mi) + (MI_HEIGHT(mi) + r) / 2; } fvwm-2.6.7/fvwm/move_resize.h0000644000175700017570000000231512773467232013141 00000000000000/* -*-c-*- */ #ifndef _MOVE_RESIZE_ #define _MOVE_RESIZE_ struct MenuRepaintTransparentParameters; void switch_move_resize_grid(Bool state); void AnimatedMoveOfWindow( Window w,int startX,int startY,int endX, int endY,Bool fWarpPointerToo, int cusDelay, float *ppctMovement, struct MenuRepaintTransparentParameters *pmrtp); void AnimatedMoveFvwmWindow( FvwmWindow *fw, Window w, int startX, int startY, int endX, int endY, Bool fWarpPointerToo, int cmsDelay, float *ppctMovement); Bool __move_loop( const exec_context_t *exc, int XOffset, int YOffset, int Width, int Height, int *FinalX, int *FinalY, Bool do_move_opaque, int cursor); int is_window_sticky_across_pages(FvwmWindow *fw); int is_window_sticky_across_desks(FvwmWindow *fw); void handle_stick( F_CMD_ARGS, int toggle_page, int toggle_desk, int do_not_draw, int do_silently); void resize_geometry_window(void); void __move_icon( FvwmWindow *fw, int x, int y, int old_x, int old_y, Bool do_move_animated, Bool do_warp_pointer); int placement_binding(int button,KeySym keysym,int modifier,char *action); int GetMoveArguments( char **paction, int w, int h, int *pFinalX, int *pFinalY, Bool *fWarp, Bool *fPointer, Bool fKeep); #endif /* _MOVE_RESIZE_ */ fvwm-2.6.7/fvwm/commands.h0000644000175700017570000002267212773467232012423 00000000000000/* -*-c-*- */ #ifndef COMMANDS_H #define COMMANDS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ enum { F_UNDEFINED = -1, /* functions that need no window */ F_NOP = 0, F_ADDFUNC, F_ADDMENU, F_ADDMENU2, F_ALL, F_ANY, F_BEEP, F_BREAK, F_BUG_OPTS, F_BUSY_CURSOR, F_BUTTON_STATE, F_BUTTON_STYLE, F_CHANGE_MENUSTYLE, F_CIRCULATE_DOWN, F_CIRCULATE_UP, F_CLICK, F_CLOSE, F_COLORMAP_FOCUS, F_COND, F_CONDCASE, F_CONFIG_LIST, F_COPY_MENU_STYLE, F_CURRENT, F_CURSOR_STYLE, F_DESCHEDULE, F_DESKTOP_NAME, F_DESTROY_FUNCTION, F_DESTROY_MENU, F_DESTROY_MENUSTYLE, F_DESTROY_STYLE, F_DFLT_COLORS, F_DFLT_COLORSET, F_DFLT_FONT, F_DFLT_ICON, F_DFLT_LAYERS, F_DIRECTION, F_EDGE_COMMAND, F_EDGE_LEAVE_COMMAND, F_EDGE_RES, F_EDGE_SCROLL, F_EMULATE, F_ESCAPE_FUNC, F_EWMH_BASE_STRUTS, F_EWMH_NUMBER_OF_DESKTOPS, F_EXEC, F_EXEC_SETUP, F_FAKE_CLICK, F_FAKE_KEYPRESS, F_FOCUSSTYLE, F_FUNCTION, F_GLOBAL_OPTS, F_GOTO_DESK, F_GOTO_PAGE, F_HICOLOR, F_HICOLORSET, F_HIDEGEOMWINDOW, F_ICONFONT, F_ICON_PATH, F_IGNORE_MODIFIERS, F_IMAGE_PATH, F_INFOSTOREADD, F_INFOSTOREREMOVE, F_INFOSTORECLEAR, F_KEEPRC, F_KEY, F_KILL_MODULE, F_LAYER, F_LOCALE_PATH, F_MENUSTYLE, F_MODULE, F_MODULE_LISTEN_ONLY, F_MODULE_PATH, F_MODULE_SYNC, F_MOUSE, F_MOVECURSOR, F_MOVE_TO_DESK, F_NEXT, F_NONE, F_OPAQUE, F_PICK, F_PIXMAP_PATH, F_POINTERKEY, F_POINTERWINDOW, F_POPUP, F_PREV, F_PRINTINFO, F_QUIT, F_QUIT_SESSION, F_QUIT_SCREEN, F_READ, F_RECAPTURE, F_RECAPTURE_WINDOW, F_REFRESH, F_REPEAT, F_RESTART, F_SAVE_SESSION, F_SAVE_QUIT_SESSION, F_SCANFORWINDOW, F_SCHEDULE, F_SCROLL, F_SETDESK, F_SETENV, F_SET_ANIMATION, F_SET_MASK, F_SET_NOGRAB_MASK, F_SET_SYNC_MASK, F_SHADE_ANIMATE, F_SILENT, F_SNAP_ATT, F_SNAP_GRID, F_STAYSUP, STROKE_ARG(F_STROKE) STROKE_ARG(F_STROKE_FUNC) F_STYLE, F_TEARMENUOFF, F_TEST_, F_TESTRC, F_THISWINDOW, F_TITLE, F_TITLESTYLE, F_TOGGLE_PAGE, F_UPDATE_STYLES, F_WAIT, F_WINDOWFONT, F_WINDOWLIST, F_XINERAMA, F_XINERAMAPRIMARYSCREEN, F_XINERAMASLS, F_XINERAMASLSSCREENS, F_XINERAMASLSSIZE, F_XOR, F_XSYNC, F_XSYNCHRONIZE, /* functions that need a window to operate on */ F_ADD_BUTTON_STYLE, F_ADD_DECOR, F_ADD_TITLE_STYLE, F_ANIMATED_MOVE, F_BORDERSTYLE, F_CHANGE_DECOR, F_COLOR_LIMIT, F_DELETE, F_DESTROY, F_DESTROY_DECOR, F_DESTROY_MOD, F_DESTROY_WINDOW_STYLE, F_ECHO, F_ECHO_FUNC_DEFINITION, F_FLIP_FOCUS, F_FOCUS, F_ICONIFY, F_LOWER, F_MAXIMIZE, F_MOVE, F_MOVE_THRESHOLD, F_MOVE_TO_PAGE, F_MOVE_TO_SCREEN, F_PLACEAGAIN, F_RAISE, F_RAISELOWER, F_RESIZE, F_RESIZE_MAXIMIZE, F_RESIZEMOVE, F_RESIZEMOVE_MAXIMIZE, F_RESTACKTRANSIENTS, F_SEND_STRING, F_STATE, F_STICK, F_STICKACROSSDESKS, F_STICKACROSSPAGES, F_UPDATE_DECOR, F_WARP, F_WINDOWID, F_WINDOW_SHADE, F_WINDOW_STYLE, F_END_OF_LIST = 999, /* Functions for use by modules only! */ F_SEND_WINDOW_LIST = 1000, F_SEND_REPLY }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* This file contains all command prototypes. */ void CMD_Plus(F_CMD_ARGS); void CMD_AddButtonStyle(F_CMD_ARGS); void CMD_AddTitleStyle(F_CMD_ARGS); void CMD_AddToDecor(F_CMD_ARGS); void CMD_AddToFunc(F_CMD_ARGS); void CMD_AddToMenu(F_CMD_ARGS); void CMD_Alias(F_CMD_ARGS); void CMD_All(F_CMD_ARGS); void CMD_AnimatedMove(F_CMD_ARGS); void CMD_Any(F_CMD_ARGS); void CMD_Beep(F_CMD_ARGS); void CMD_Break(F_CMD_ARGS); void CMD_BorderStyle(F_CMD_ARGS); void CMD_BugOpts(F_CMD_ARGS); void CMD_BusyCursor(F_CMD_ARGS); void CMD_ButtonState(F_CMD_ARGS); void CMD_ButtonStyle(F_CMD_ARGS); void CMD_ChangeDecor(F_CMD_ARGS); void CMD_ChangeMenuStyle(F_CMD_ARGS); void CMD_CleanupColorsets(F_CMD_ARGS); void CMD_ClickTime(F_CMD_ARGS); void CMD_Close(F_CMD_ARGS); void CMD_ColorLimit(F_CMD_ARGS); void CMD_ColormapFocus(F_CMD_ARGS); void CMD_Colorset(F_CMD_ARGS); void CMD_CopyMenuStyle(F_CMD_ARGS); void CMD_Current(F_CMD_ARGS); void CMD_CursorMove(F_CMD_ARGS); void CMD_CursorStyle(F_CMD_ARGS); void CMD_DefaultColors(F_CMD_ARGS); void CMD_DefaultColorset(F_CMD_ARGS); void CMD_DefaultFont(F_CMD_ARGS); void CMD_DefaultIcon(F_CMD_ARGS); void CMD_DefaultLayers(F_CMD_ARGS); void CMD_Delete(F_CMD_ARGS); void CMD_Deschedule(F_CMD_ARGS); void CMD_Desk(F_CMD_ARGS); void CMD_DesktopName(F_CMD_ARGS); void CMD_DesktopSize(F_CMD_ARGS); void CMD_Destroy(F_CMD_ARGS); void CMD_DestroyDecor(F_CMD_ARGS); void CMD_DestroyFunc(F_CMD_ARGS); void CMD_DestroyMenu(F_CMD_ARGS); void CMD_DestroyMenuStyle(F_CMD_ARGS); void CMD_DestroyModuleConfig(F_CMD_ARGS); void CMD_DestroyStyle(F_CMD_ARGS); void CMD_DestroyWindowStyle(F_CMD_ARGS); void CMD_Direction(F_CMD_ARGS); void CMD_Echo(F_CMD_ARGS); void CMD_EchoFuncDefinition(F_CMD_ARGS); void CMD_EdgeCommand(F_CMD_ARGS); void CMD_EdgeLeaveCommand(F_CMD_ARGS); void CMD_EdgeResistance(F_CMD_ARGS); void CMD_EdgeScroll(F_CMD_ARGS); void CMD_EdgeThickness(F_CMD_ARGS); void CMD_Emulate(F_CMD_ARGS); void CMD_EscapeFunc(F_CMD_ARGS); void CMD_EwmhBaseStruts(F_CMD_ARGS); void CMD_EwmhNumberOfDesktops(F_CMD_ARGS); void CMD_Exec(F_CMD_ARGS); void CMD_ExecUseShell(F_CMD_ARGS); void CMD_FakeClick(F_CMD_ARGS); void CMD_FakeKeypress(F_CMD_ARGS); void CMD_FlipFocus(F_CMD_ARGS); void CMD_Focus(F_CMD_ARGS); void CMD_FocusStyle(F_CMD_ARGS); void CMD_Function(F_CMD_ARGS); void CMD_GlobalOpts(F_CMD_ARGS); void CMD_GotoDesk(F_CMD_ARGS); void CMD_GotoDeskAndPage(F_CMD_ARGS); void CMD_GotoPage(F_CMD_ARGS); void CMD_HideGeometryWindow(F_CMD_ARGS); void CMD_HilightColor(F_CMD_ARGS); void CMD_HilightColorset(F_CMD_ARGS); void CMD_IconFont(F_CMD_ARGS); void CMD_Iconify(F_CMD_ARGS); void CMD_IconPath(F_CMD_ARGS); void CMD_IgnoreModifiers(F_CMD_ARGS); void CMD_ImagePath(F_CMD_ARGS); void CMD_InfoStoreAdd(F_CMD_ARGS); void CMD_InfoStoreClear(F_CMD_ARGS); void CMD_InfoStoreRemove(F_CMD_ARGS); void CMD_KeepRc(F_CMD_ARGS); void CMD_Key(F_CMD_ARGS); void CMD_KillModule(F_CMD_ARGS); void CMD_Layer(F_CMD_ARGS); void CMD_LocalePath(F_CMD_ARGS); void CMD_Lower(F_CMD_ARGS); void CMD_Maximize(F_CMD_ARGS); void CMD_Menu(F_CMD_ARGS); void CMD_MenuStyle(F_CMD_ARGS); void CMD_Module(F_CMD_ARGS); void CMD_ModuleListenOnly(F_CMD_ARGS); void CMD_ModulePath(F_CMD_ARGS); void CMD_ModuleSynchronous(F_CMD_ARGS); void CMD_ModuleTimeout(F_CMD_ARGS); void CMD_Mouse(F_CMD_ARGS); void CMD_Move(F_CMD_ARGS); void CMD_MoveThreshold(F_CMD_ARGS); void CMD_MoveToDesk(F_CMD_ARGS); void CMD_MoveToPage(F_CMD_ARGS); void CMD_MoveToScreen(F_CMD_ARGS); void CMD_Next(F_CMD_ARGS); void CMD_None(F_CMD_ARGS); void CMD_Nop(F_CMD_ARGS); void CMD_NoWindow(F_CMD_ARGS); void CMD_OpaqueMoveSize(F_CMD_ARGS); void CMD_Pick(F_CMD_ARGS); void CMD_PipeRead(F_CMD_ARGS); void CMD_PixmapPath(F_CMD_ARGS); void CMD_PlaceAgain(F_CMD_ARGS); void CMD_PointerKey(F_CMD_ARGS); void CMD_PointerWindow(F_CMD_ARGS); void CMD_Popup(F_CMD_ARGS); void CMD_Prev(F_CMD_ARGS); void CMD_PrintInfo(F_CMD_ARGS); void CMD_PropertyChange(F_CMD_ARGS); void CMD_Quit(F_CMD_ARGS); void CMD_QuitScreen(F_CMD_ARGS); void CMD_QuitSession(F_CMD_ARGS); void CMD_Raise(F_CMD_ARGS); void CMD_RaiseLower(F_CMD_ARGS); void CMD_Read(F_CMD_ARGS); void CMD_ReadWriteColors(F_CMD_ARGS); void CMD_Recapture(F_CMD_ARGS); void CMD_RecaptureWindow(F_CMD_ARGS); void CMD_Refresh(F_CMD_ARGS); void CMD_RefreshWindow(F_CMD_ARGS); void CMD_Repeat(F_CMD_ARGS); void CMD_Resize(F_CMD_ARGS); void CMD_ResizeMaximize(F_CMD_ARGS); void CMD_ResizeMove(F_CMD_ARGS); void CMD_ResizeMoveMaximize(F_CMD_ARGS); void CMD_RestackTransients(F_CMD_ARGS); void CMD_Restart(F_CMD_ARGS); void CMD_SaveQuitSession(F_CMD_ARGS); void CMD_SaveSession(F_CMD_ARGS); void CMD_ScanForWindow(F_CMD_ARGS); void CMD_Schedule(F_CMD_ARGS); void CMD_Scroll(F_CMD_ARGS); void CMD_Send_ConfigInfo(F_CMD_ARGS); void CMD_Send_Reply(F_CMD_ARGS); void CMD_Send_WindowList(F_CMD_ARGS); void CMD_SendToModule(F_CMD_ARGS); void CMD_set_mask(F_CMD_ARGS); void CMD_set_nograb_mask(F_CMD_ARGS); void CMD_set_sync_mask(F_CMD_ARGS); void CMD_SetAnimation(F_CMD_ARGS); void CMD_SetEnv(F_CMD_ARGS); void CMD_Silent(F_CMD_ARGS); void CMD_SnapAttraction(F_CMD_ARGS); void CMD_SnapGrid(F_CMD_ARGS); void CMD_State(F_CMD_ARGS); void CMD_Stick(F_CMD_ARGS); void CMD_StickAcrossDesks(F_CMD_ARGS); void CMD_StickAcrossPages(F_CMD_ARGS); #ifdef HAVE_STROKE void CMD_Stroke(F_CMD_ARGS); void CMD_StrokeFunc(F_CMD_ARGS); #endif /* HAVE_STROKE */ void CMD_Style(F_CMD_ARGS); void CMD_TearMenuOff(F_CMD_ARGS); void CMD_Test(F_CMD_ARGS); void CMD_TestRc(F_CMD_ARGS); void CMD_ThisWindow(F_CMD_ARGS); void CMD_Title(F_CMD_ARGS); void CMD_TitleStyle(F_CMD_ARGS); void CMD_Unalias(F_CMD_ARGS); void CMD_UnsetEnv(F_CMD_ARGS); void CMD_UpdateDecor(F_CMD_ARGS); void CMD_UpdateStyles(F_CMD_ARGS); void CMD_Wait(F_CMD_ARGS); void CMD_WarpToWindow(F_CMD_ARGS); void CMD_WindowFont(F_CMD_ARGS); void CMD_WindowId(F_CMD_ARGS); void CMD_WindowList(F_CMD_ARGS); void CMD_WindowShade(F_CMD_ARGS); void CMD_WindowShadeAnimate(F_CMD_ARGS); void CMD_WindowStyle(F_CMD_ARGS); void CMD_Xinerama(F_CMD_ARGS); void CMD_XineramaPrimaryScreen(F_CMD_ARGS); void CMD_XineramaSls(F_CMD_ARGS); void CMD_XineramaSlsScreens(F_CMD_ARGS); void CMD_XineramaSlsSize(F_CMD_ARGS); void CMD_XorPixmap(F_CMD_ARGS); void CMD_XorValue(F_CMD_ARGS); void CMD_XSync(F_CMD_ARGS); void CMD_XSynchronize(F_CMD_ARGS); #endif /* COMMANDS_H */ fvwm-2.6.7/fvwm/placement.c0000644000175700017570000016377513001406607012557 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/XResource.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "cursor.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "placement.h" #include "geometry.h" #include "update.h" #include "style.h" #include "move_resize.h" #include "virtual.h" #include "stack.h" #include "ewmh.h" #include "icons.h" #include "add_window.h" /* ---------------------------- local definitions -------------------------- */ #define MAX_NUM_PLACEMENT_ALGOS 31 #define CP_GET_NEXT_STEP 5 /* ---------------------------- local macros ------------------------------- */ #ifndef MIN #define MIN(A,B) ((A)<(B)? (A):(B)) #endif #ifndef MAX #define MAX(A,B) ((A)>(B)? (A):(B)) #endif #define NORMAL_PLACEMENT_PENALTY(p) (p->normal) #define ONTOP_PLACEMENT_PENALTY(p) (p->ontop) #define ICON_PLACEMENT_PENALTY(p) (p->icon) #define STICKY_PLACEMENT_PENALTY(p) (p->sticky) #define BELOW_PLACEMENT_PENALTY(p) (p->below) #define EWMH_STRUT_PLACEMENT_PENALTY(p) (p->strut) #define PERCENTAGE_99_PENALTY(p) (p->p99) #define PERCENTAGE_95_PENALTY(p) (p->p95) #define PERCENTAGE_85_PENALTY(p) (p->p85) #define PERCENTAGE_75_PENALTY(p) (p->p75) /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef enum { PR_POS_NORMAL = 0, PR_POS_IGNORE_PPOS, PR_POS_USE_PPOS, PR_POS_IGNORE_USPOS, PR_POS_USE_USPOS, PR_POS_PLACE_AGAIN, PR_POS_CAPTURE, PR_POS_USPOS_OVERRIDE_SOS } preason_pos_t; typedef enum { PR_SCREEN_CURRENT = 0, PR_SCREEN_STYLE, PR_SCREEN_X_RESOURCE_FVWMSCREEN, PR_SCREEN_IGNORE_CAPTURE } preason_screen_t; typedef enum { PR_PAGE_CURRENT = 0, PR_PAGE_STYLE, PR_PAGE_X_RESOURCE_PAGE, PR_PAGE_IGNORE_CAPTURE, PR_PAGE_IGNORE_INVALID, PR_PAGE_STICKY } preason_page_t; typedef enum { PR_DESK_CURRENT = 0, PR_DESK_STYLE, PR_DESK_X_RESOURCE_DESK, PR_DESK_X_RESOURCE_PAGE, PR_DESK_CAPTURE, PR_DESK_STICKY, PR_DESK_WINDOW_GROUP_LEADER, PR_DESK_WINDOW_GROUP_MEMBER, PR_DESK_TRANSIENT, PR_DESK_XPROP_XA_WM_DESKTOP } preason_desk_t; typedef struct { struct { preason_pos_t reason; int x; int y; int algo; char *pl_position_string; unsigned do_not_manual_icon_placement : 1; unsigned do_adjust_off_screen : 1; unsigned do_adjust_off_page : 1; unsigned is_pl_position_string_invalid : 1; unsigned has_tile_failed : 1; unsigned has_manual_failed : 1; unsigned has_placement_failed : 1; } pos; struct { preason_screen_t reason; int screen; rectangle g; unsigned was_modified_by_ewmh_workingarea : 1; } screen; struct { preason_page_t reason; int px; int py; unsigned do_switch_page : 1; unsigned do_honor_starts_on_page : 1; unsigned do_ignore_starts_on_page : 1; } page; struct { preason_desk_t reason; preason_desk_t sod_reason; int desk; unsigned do_switch_desk : 1; } desk; } pl_reason_t; typedef struct { int desk; int page_x; int page_y; int screen; } pl_start_style_t; typedef struct { unsigned do_forbid_manual_placement : 1; unsigned do_honor_starts_on_page : 1; unsigned do_honor_starts_on_screen : 1; unsigned do_not_use_wm_placement : 1; } pl_flags_t; typedef float pl_penalty_t; typedef enum { PL_LOOP_END, PL_LOOP_CONT } pl_loop_rc_t; struct pl_arg_t; struct pl_ret_t; typedef struct { /* If this funtion pointer is not NULL, use this function to return * the desired position in a single call */ pl_penalty_t (*get_pos_simple)( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); /* otherwise use these three in a loop */ pl_loop_rc_t (*get_first_pos)( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); pl_loop_rc_t (*get_next_pos)( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg, position hint_p); pl_penalty_t (*get_pos_penalty)( position *ret_hint_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); } pl_algo_t; typedef struct pl_scratch_t { const pl_penalty_struct *pp; const pl_percent_penalty_struct *ppp; } pl_scratch_t; typedef struct pl_arg_t { const pl_algo_t *algo; const exec_context_t *exc; const window_style *style; pl_reason_t *reason; FvwmWindow *place_fw; pl_scratch_t *scratch; rectangle place_g; position place_p2; rectangle screen_g; position page_p1; position page_p2; position pdelta_p; struct { unsigned use_percent : 1; unsigned use_ewmh_dynamic_working_areapercent : 1; unsigned do_honor_starts_on_page : 1; } flags; } pl_arg_t; typedef struct pl_ret_t { position best_p; pl_penalty_t best_penalty; struct { unsigned do_resize_too : 1; } flags; } pl_ret_t; /* ---------------------------- forward declarations ----------------------- */ static pl_loop_rc_t __pl_minoverlap_get_first_pos( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); static pl_loop_rc_t __pl_minoverlap_get_next_pos( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg, position hint_p); static pl_penalty_t __pl_minoverlap_get_pos_penalty( position *ret_hint_p, struct pl_ret_t *ret, const pl_arg_t *arg); static pl_penalty_t __pl_smart_get_pos_penalty( position *ret_hint_p, struct pl_ret_t *ret, const pl_arg_t *arg); static pl_penalty_t __pl_position_get_pos_simple( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); static pl_penalty_t __pl_cascade_get_pos_simple( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); static pl_penalty_t __pl_manual_get_pos_simple( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg); /* ---------------------------- local variables ---------------------------- */ const pl_algo_t minoverlap_placement_algo = { NULL, __pl_minoverlap_get_first_pos, __pl_minoverlap_get_next_pos, __pl_minoverlap_get_pos_penalty }; const pl_algo_t smart_placement_algo = { NULL, __pl_minoverlap_get_first_pos, __pl_minoverlap_get_next_pos, __pl_smart_get_pos_penalty }; const pl_algo_t position_placement_algo = { __pl_position_get_pos_simple }; const pl_algo_t cascade_placement_algo = { __pl_cascade_get_pos_simple }; const pl_algo_t manual_placement_algo = { __pl_manual_get_pos_simple }; /* ---------------------------- exported variables (globals) --------------- */ const pl_penalty_struct default_pl_penalty = { 1, PLACEMENT_AVOID_ONTOP, PLACEMENT_AVOID_ICON, PLACEMENT_AVOID_STICKY, PLACEMENT_AVOID_BELOW, PLACEMENT_AVOID_EWMH_STRUT }; const pl_percent_penalty_struct default_pl_percent_penalty = { PLACEMENT_AVOID_COVER_99, PLACEMENT_AVOID_COVER_95, PLACEMENT_AVOID_COVER_85, PLACEMENT_AVOID_COVER_75 }; /* ---------------------------- local functions (PositionPlacement) -------- */ static pl_penalty_t __pl_position_get_pos_simple( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg) { char *spos; Bool fPointer; int n; int i; Bool is_under_mouse; is_under_mouse = False; spos = SGET_PLACEMENT_POSITION_STRING(*arg->style); if (spos == NULL || *spos == 0) { spos = DEFAULT_PLACEMENT_POSITION_STRING; i = 1; } else if (StrEquals(spos, "Center")) { spos = DEFAULT_PLACEMENT_POS_CENTER_STRING; i = 1; } else if (StrEquals(spos, "UnderMouse")) { spos = DEFAULT_PLACEMENT_POS_MOUSE_STRING; i = 1; is_under_mouse = True; } else { i = 0; } arg->reason->pos.pl_position_string = spos; for (n = -1; i < 2 && n < 2; i++) { fPointer = False; ret_p->x = 0; ret_p->y = 0; n = GetMoveArguments( &spos, arg->place_g.width, arg->place_g.height, &ret_p->x, &ret_p->y, NULL, &fPointer, False); spos = DEFAULT_PLACEMENT_POSITION_STRING; if (n < 2) { arg->reason->pos.is_pl_position_string_invalid = 1; } } if (n < 2) { /* bug */ abort(); } if (is_under_mouse) { /* TA: 20090218: Try and keep the window on-screen if we * can. */ /* TA: 20120316: Imply the working-area when under the mouse -- this * brings it in-line with making the EWMH working area the default. * Note that "UnderMouse" is a special case, deliberately. All other * PositionPlacement commands are deliberately NOT subject to ewmhiwa * options. */ EWMH_GetWorkAreaIntersection( arg->place_fw, (int *)&arg->screen_g.x, (int *)&arg->screen_g.y, (int *)&arg->screen_g.width, (int *)&arg->screen_g.height, EWMH_USE_WORKING_AREA); if (ret_p->x + arg->place_fw->g.frame.width > arg->screen_g.x + arg->screen_g.width) { ret_p->x = (arg->screen_g.x + arg->screen_g.width) - arg->place_fw->g.frame.width; } if (ret_p->y + arg->place_fw->g.frame.height > arg->screen_g.y + arg->screen_g.height) { ret_p->y = (arg->screen_g.y + arg->screen_g.height) - arg->place_fw->g.frame.height; } } /* Don't let the upper left corner be offscreen. */ if (ret_p->x < arg->screen_g.x) { ret_p->x = arg->screen_g.x; } if (ret_p->y < arg->screen_g.y) { ret_p->y = arg->screen_g.y; } if (arg->flags.do_honor_starts_on_page) { ret_p->x -= arg->pdelta_p.x; ret_p->y -= arg->pdelta_p.y; } return 0; } /* ---------------------------- local functions (CascadePlacement)---------- */ static pl_penalty_t __pl_cascade_get_pos_simple( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg) { size_borders b; int w; FvwmWindow *t; t = (Scr.cascade_window != NULL) ? Scr.cascade_window : arg->place_fw; w = t->title_thickness; if (w == 0) { w = t->boundary_width; } if (w == 0) { w = PLACEMENT_FALLBACK_CASCADE_STEP; } if (Scr.cascade_window != NULL) { Scr.cascade_x += w; Scr.cascade_y += w; switch (GET_TITLE_DIR(t)) { case DIR_S: case DIR_N: Scr.cascade_y += w; break; case DIR_E: case DIR_W: Scr.cascade_x += w; break; default: break; } } Scr.cascade_window = arg->place_fw; if (Scr.cascade_x > arg->screen_g.width / 2) { Scr.cascade_x = arg->place_fw->title_thickness; } if (Scr.cascade_y > arg->screen_g.height / 2) { Scr.cascade_y = 2 * arg->place_fw->title_thickness; } ret_p->x = Scr.cascade_x + arg->page_p1.x; ret_p->y = Scr.cascade_y + arg->page_p1.y; /* try to keep the window on the screen */ get_window_borders(arg->place_fw, &b); if (ret_p->x + arg->place_g.width >= arg->page_p2.x) { ret_p->x = arg->page_p2.x - arg->place_g.width - b.total_size.width; Scr.cascade_x = arg->place_fw->title_thickness; switch (GET_TITLE_DIR(t)) { case DIR_E: case DIR_W: Scr.cascade_x += arg->place_fw->title_thickness; default: break; } } if (ret_p->y + arg->place_g.height >= arg->page_p2.y) { ret_p->y = arg->page_p2.y - arg->place_g.height - b.total_size.height; Scr.cascade_y = arg->place_fw->title_thickness; switch (GET_TITLE_DIR(t)) { case DIR_N: case DIR_S: Scr.cascade_y += arg->place_fw->title_thickness; default: break; } } /* the left and top sides are more important in huge windows */ if (ret_p->x < arg->page_p1.x) { ret_p->x = arg->page_p1.x; } if (ret_p->y < arg->page_p1.y) { ret_p->y = arg->page_p1.y; } return 0; } /* ---------------------------- local functions (ManualPlacement)----------- */ static pl_penalty_t __pl_manual_get_pos_simple( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg) { ret_p->x = 0; ret_p->y = 0; if (GrabEm(CRS_POSITION, GRAB_NORMAL)) { int DragWidth; int DragHeight; int mx; int my; /* Grabbed the pointer - continue */ MyXGrabServer(dpy); if ( XGetGeometry( dpy, FW_W(arg->place_fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&DragWidth, (unsigned int*)&DragHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { MyXUngrabServer(dpy); UngrabEm(GRAB_NORMAL); return -1; } SET_PLACED_BY_FVWM(arg->place_fw, 0); MyXGrabKeyboard(dpy); DragWidth = arg->place_g.width; DragHeight = arg->place_g.height; if (Scr.SizeWindow != None) { XMapRaised(dpy, Scr.SizeWindow); } FScreenGetScrRect( NULL, FSCREEN_GLOBAL, &mx, &my, NULL, NULL); if (__move_loop( arg->exc, mx, my, DragWidth, DragHeight, &ret_p->x, &ret_p->y, False, CRS_POSITION)) { ret->flags.do_resize_too = 1; } if (Scr.SizeWindow != None) { XUnmapWindow(dpy, Scr.SizeWindow); } MyXUngrabKeyboard(dpy); MyXUngrabServer(dpy); UngrabEm(GRAB_NORMAL); } else { /* couldn't grab the pointer - better do something */ XBell(dpy, 0); ret_p->x = 0; ret_p->y = 0; arg->reason->pos.has_manual_failed = 1; } if (arg->flags.do_honor_starts_on_page) { ret_p->x -= arg->pdelta_p.x; ret_p->y -= arg->pdelta_p.y; } return 0; } /* ---------------------------- local functions (MinoverlapPlacement) ------ */ /* MinoverlapPlacement by Anthony Martin * This algorithm places a new window such that there is a minimum amount of * interference with other windows. If it can place a window without any * interference, fine. Otherwise, it places it so that the area of of * interference between the new window and the other windows is minimized */ static int __pl_minoverlap_get_next_x(const pl_arg_t *arg) { FvwmWindow *other_fw; int xnew; int xtest; int stickyx; int stickyy; int start,i; int win_left; rectangle g; Bool rc; int x; int y; x = arg->place_g.x; y = arg->place_g.y; if (arg->flags.use_percent == 1) { start = 0; } else { start = CP_GET_NEXT_STEP; } /* Test window at far right of screen */ xnew = arg->page_p2.x; xtest = arg->page_p2.x - arg->place_g.width; if (xtest > x) { xnew = xtest; } /* test the borders of the working area */ xtest = arg->page_p1.x + Scr.Desktops->ewmh_working_area.x; if (xtest > x) { xnew = MIN(xnew, xtest); } xtest = arg->page_p1.x + (Scr.Desktops->ewmh_working_area.x + Scr.Desktops->ewmh_working_area.width) - arg->place_g.width; if (xtest > x) { xnew = MIN(xnew, xtest); } /* Test the values of the right edges of every window */ for ( other_fw = Scr.FvwmRoot.next; other_fw != NULL; other_fw = other_fw->next) { if ( other_fw == arg->place_fw || (other_fw->Desk != arg->place_fw->Desk && !IS_STICKY_ACROSS_DESKS(other_fw)) || IS_EWMH_DESKTOP(FW_W(other_fw))) { continue; } if (IS_STICKY_ACROSS_PAGES(other_fw)) { stickyx = arg->pdelta_p.x; stickyy = arg->pdelta_p.y; } else { stickyx = 0; stickyy = 0; } if (IS_ICONIFIED(other_fw)) { rc = get_visible_icon_geometry(other_fw, &g); if (rc == True && y < g.y + g.height - stickyy && g.y - stickyy < arg->place_g.height + y) { win_left = arg->page_p1.x + g.x - stickyx - arg->place_g.width; for (i = start; i <= CP_GET_NEXT_STEP; i++) { xtest = win_left + g.width * (CP_GET_NEXT_STEP - i) / CP_GET_NEXT_STEP; if (xtest > x) { xnew = MIN(xnew, xtest); } } win_left = arg->page_p1.x + g.x - stickyx; for (i = start; i <= CP_GET_NEXT_STEP; i++) { xtest = (win_left) + g.width * i / CP_GET_NEXT_STEP; if (xtest > x) { xnew = MIN(xnew, xtest); } } } } else if ( y < other_fw->g.frame.height + other_fw->g.frame.y - stickyy && other_fw->g.frame.y - stickyy < arg->place_g.height + y && arg->page_p1.x < other_fw->g.frame.width + other_fw->g.frame.x - stickyx && other_fw->g.frame.x - stickyx < arg->page_p2.x) { win_left = other_fw->g.frame.x - stickyx - arg->place_g.width; for (i = start; i <= CP_GET_NEXT_STEP; i++) { xtest = win_left + other_fw->g.frame.width * (CP_GET_NEXT_STEP - i) / CP_GET_NEXT_STEP; if (xtest > x) { xnew = MIN(xnew, xtest); } } win_left = other_fw->g.frame.x - stickyx; for (i = start; i <= CP_GET_NEXT_STEP; i++) { xtest = win_left + other_fw->g.frame.width * i / CP_GET_NEXT_STEP; if (xtest > x) { xnew = MIN(xnew, xtest); } } } } return xnew; } static int __pl_minoverlap_get_next_y(const pl_arg_t *arg) { FvwmWindow *other_fw; int ynew; int ytest; int stickyy; int win_top; int start; int i; rectangle g; int y; y = arg->place_g.y; if (arg->flags.use_percent == 1) { start = 0; } else { start = CP_GET_NEXT_STEP; } /* Test window at far bottom of screen */ ynew = arg->page_p2.y; ytest = arg->page_p2.y - arg->place_g.height; if (ytest > y) { ynew = ytest; } /* test the borders of the working area */ ytest = arg->page_p1.y + Scr.Desktops->ewmh_working_area.y; if (ytest > y) { ynew = MIN(ynew, ytest); } ytest = arg->screen_g.y + (Scr.Desktops->ewmh_working_area.y + Scr.Desktops->ewmh_working_area.height) - arg->place_g.height; if (ytest > y) { ynew = MIN(ynew, ytest); } /* Test the values of the bottom edge of every window */ for ( other_fw = Scr.FvwmRoot.next; other_fw != NULL; other_fw = other_fw->next) { if ( other_fw == arg->place_fw || ( other_fw->Desk != arg->place_fw->Desk && !IS_STICKY_ACROSS_DESKS(other_fw)) || IS_EWMH_DESKTOP(FW_W(other_fw))) { continue; } if (IS_STICKY_ACROSS_PAGES(other_fw)) { stickyy = arg->pdelta_p.y; } else { stickyy = 0; } if (IS_ICONIFIED(other_fw)) { get_visible_icon_geometry(other_fw, &g); win_top = g.y - stickyy; for (i = start; i <= CP_GET_NEXT_STEP; i++) { ytest = win_top + g.height * i / CP_GET_NEXT_STEP; if (ytest > y) { ynew = MIN(ynew, ytest); } } win_top = g.y - stickyy - arg->place_g.height; for (i = start; i <= CP_GET_NEXT_STEP; i++) { ytest = win_top + g.height * (CP_GET_NEXT_STEP - i) / CP_GET_NEXT_STEP; if (ytest > y) { ynew = MIN(ynew, ytest); } } } else { win_top = other_fw->g.frame.y - stickyy; for (i = start; i <= CP_GET_NEXT_STEP; i++) { ytest = win_top + other_fw->g.frame.height * i / CP_GET_NEXT_STEP; if (ytest > y) { ynew = MIN(ynew, ytest); } } win_top = other_fw->g.frame.y - stickyy - arg->place_g.height; for (i = start; i <= CP_GET_NEXT_STEP; i++) { ytest = win_top + other_fw->g.frame.height * (CP_GET_NEXT_STEP - i) / CP_GET_NEXT_STEP; if (ytest > y) { ynew = MIN(ynew, ytest); } } } } return ynew; } static pl_loop_rc_t __pl_minoverlap_get_first_pos( position *ret_p, struct pl_ret_t *ret, const pl_arg_t *arg) { /* top left corner of page */ ret_p->x = arg->page_p1.x; ret_p->y = arg->page_p1.y; return PL_LOOP_CONT; } static pl_loop_rc_t __pl_minoverlap_get_next_pos( position *ret_p, struct pl_ret_t *ret, const struct pl_arg_t *arg, position hint_p) { ret_p->x = arg->place_g.x; ret_p->y = arg->place_g.y; if (ret_p->x + arg->place_g.width <= arg->page_p2.x) { /* try next x */ ret_p->x = __pl_minoverlap_get_next_x(arg); ret_p->y = arg->place_g.y; } if (ret_p->x + arg->place_g.width > arg->page_p2.x) { /* out of room in x direction. Try next y. Reset x.*/ ret_p->x = arg->page_p1.x; ret_p->y = __pl_minoverlap_get_next_y(arg); } if (ret_p->y + arg->place_g.height > arg->page_p2.y) { /* PageBottom */ return PL_LOOP_END; } return PL_LOOP_CONT; } static pl_penalty_t __pl_minoverlap_get_avoidance_penalty( const pl_arg_t *arg, FvwmWindow *other_fw, const rectangle *other_g) { pl_penalty_t anew; pl_penalty_t avoidance_factor; position other_p2; const pl_penalty_struct *opp; const pl_percent_penalty_struct *oppp; opp = (arg->scratch->pp != 0 && 0) ? arg->scratch->pp : &other_fw->pl_penalty; oppp = (arg->scratch->ppp != 0 && 0) ? arg->scratch->ppp : &other_fw->pl_percent_penalty; other_p2.x = other_g->x + other_g->width; other_p2.y = other_g->y + other_g->height; { long x1 = MAX(arg->place_g.x, other_g->x); long x2 = MIN(arg->place_p2.x, other_p2.x); long y1 = MAX(arg->place_g.y, other_g->y); long y2 = MIN(arg->place_p2.y, other_p2.y); /* overlapping area in pixels (windows are guaranteed to * overlap when this function is called) */ anew = (x2 - x1) * (y2 - y1); } if (IS_ICONIFIED(other_fw)) { avoidance_factor = ICON_PLACEMENT_PENALTY(opp); } else if (compare_window_layers(other_fw, arg->place_fw) > 0) { avoidance_factor = ONTOP_PLACEMENT_PENALTY(opp); } else if (compare_window_layers(other_fw, arg->place_fw) < 0) { avoidance_factor = BELOW_PLACEMENT_PENALTY(opp); } else if ( IS_STICKY_ACROSS_PAGES(other_fw) || IS_STICKY_ACROSS_DESKS(other_fw)) { avoidance_factor = STICKY_PLACEMENT_PENALTY(opp); } else { avoidance_factor = NORMAL_PLACEMENT_PENALTY(opp); } if (arg->flags.use_percent == 1) { pl_penalty_t cover_factor; long other_area; long place_area; other_area = other_g->width * other_g->height; place_area = arg->place_g.width * arg->place_g.height; cover_factor = 0; if (other_area != 0 && place_area != 0) { anew = 100 * MAX(anew / other_area, anew / place_area); if (anew >= 99) { cover_factor = PERCENTAGE_99_PENALTY(oppp); } else if (anew > 94) { cover_factor = PERCENTAGE_95_PENALTY(oppp); } else if (anew > 84) { cover_factor = PERCENTAGE_85_PENALTY(oppp); } else if (anew > 74) { cover_factor = PERCENTAGE_75_PENALTY(oppp); } } if (avoidance_factor >= 1) { avoidance_factor += cover_factor; } } if ( arg->flags.use_ewmh_dynamic_working_areapercent == 1 && DO_EWMH_IGNORE_STRUT_HINTS(other_fw) == 0 && ( other_fw->dyn_strut.left > 0 || other_fw->dyn_strut.right > 0 || other_fw->dyn_strut.top > 0 || other_fw->dyn_strut.bottom > 0)) { const pl_penalty_struct *mypp; mypp = (arg->scratch->pp != 0 && 0) ? arg->scratch->pp : &arg->place_fw->pl_penalty; /* if we intersect a window which reserves space */ avoidance_factor += (avoidance_factor >= 1) ? EWMH_STRUT_PLACEMENT_PENALTY(mypp) : 0; } anew *= avoidance_factor; return anew; } static pl_penalty_t __pl_minoverlap_get_pos_penalty( position *ret_hint_p, struct pl_ret_t *ret, const struct pl_arg_t *arg) { FvwmWindow *other_fw; pl_penalty_t penalty; size_borders b; penalty = 0; for ( other_fw = Scr.FvwmRoot.next; other_fw != NULL; other_fw = other_fw->next) { rectangle other_g; get_window_borders(other_fw, &b); if ( arg->place_fw == other_fw || IS_EWMH_DESKTOP(FW_W(other_fw))) { continue; } /* RBW - account for sticky windows... */ if ( other_fw->Desk != arg->place_fw->Desk && IS_STICKY_ACROSS_DESKS(other_fw) == 0) { continue; } (void)get_visible_window_or_icon_geometry(other_fw, &other_g); if (IS_STICKY_ACROSS_PAGES(other_fw)) { other_g.x -= arg->pdelta_p.x; other_g.y -= arg->pdelta_p.y; } if ( arg->place_g.x < other_g.x + other_g.width && arg->place_p2.x > other_g.x && arg->place_g.y < other_g.y + other_g.height && arg->place_p2.y > other_g.y) { pl_penalty_t anew; anew = __pl_minoverlap_get_avoidance_penalty( arg, other_fw, &other_g); penalty += anew; if ( penalty > ret->best_penalty && ret->best_penalty != -1) { /* TA: 20091230: Fix over-zealous penalties * by explicitly forcing the window on-screen * here. The y-axis is only affected here, * due to how the xoffset calculations happen * prior to setting the x-axis. When we get * penalties which are "over-zealous" -- and * by not taking into account the size of the * window borders, the window was being placed * off screen. */ if (ret->best_p.y + arg->place_g.height > arg->page_p2.y) { ret->best_p.y = (arg->page_p2.y - arg->place_g.height - b.total_size.height); ret->best_penalty = 0; penalty = 0; } /* stop looking; the penalty is too high */ return penalty; } } } /* now handle the working area */ { const pl_penalty_struct *mypp; mypp = (arg->scratch->pp != 0 && 0) ? arg->scratch->pp : &arg->place_fw->pl_penalty; if (arg->flags.use_ewmh_dynamic_working_areapercent == 1) { penalty += EWMH_STRUT_PLACEMENT_PENALTY(mypp) * EWMH_GetStrutIntersection( arg->place_g.x, arg->place_g.y, arg->place_p2.x, arg->place_p2.y, arg->flags.use_percent); } else { /* EWMH_USE_DYNAMIC_WORKING_AREA, count the base strut */ penalty += EWMH_STRUT_PLACEMENT_PENALTY(mypp) * EWMH_GetBaseStrutIntersection( arg->place_g.x, arg->place_g.y, arg->place_p2.x, arg->place_p2.y, arg->flags.use_percent); } } return penalty; } /* ---------------------------- local functions (SmartPlacement) ----------- */ static pl_penalty_t __pl_smart_get_pos_penalty( position *ret_hint_p, struct pl_ret_t *ret, const struct pl_arg_t *arg) { pl_penalty_t p; arg->scratch->pp = &default_pl_penalty; arg->scratch->ppp = &default_pl_percent_penalty; p = __pl_minoverlap_get_pos_penalty(ret_hint_p, ret, arg); if (p != 0) { p = -1; } return p; } /* ---------------------------- local functions ---------------------------- */ static int placement_loop(pl_ret_t *ret, pl_arg_t *arg) { position next_p; pl_penalty_t penalty; pl_loop_rc_t loop_rc; if (arg->algo->get_pos_simple != NULL) { position pos; penalty = arg->algo->get_pos_simple(&pos, ret, arg); arg->place_g.x = pos.x; arg->place_g.y = pos.y; ret->best_penalty = penalty; ret->best_p.x = pos.x; ret->best_p.y = pos.y; loop_rc = PL_LOOP_END; } else { loop_rc = arg->algo->get_first_pos(&next_p, ret, arg); arg->place_g.x = next_p.x; arg->place_g.y = next_p.y; ret->best_p.x = next_p.x; ret->best_p.y = next_p.y; } while (loop_rc != PL_LOOP_END) { position hint_p; pl_scratch_t scratch; memset(&scratch, 0, sizeof(scratch)); arg->scratch = &scratch; arg->place_p2.x = arg->place_g.x + arg->place_g.width; arg->place_p2.y = arg->place_g.y + arg->place_g.height; hint_p.x = arg->place_g.x; hint_p.y = arg->place_g.y; penalty = arg->algo->get_pos_penalty(&hint_p, ret, arg); /* I've added +0.0001 because with my machine the < test fail * with certain *equal* float numbers! */ if ( penalty >= 0 && ( ret->best_penalty < 0 || penalty + 0.0001 < ret->best_penalty)) { ret->best_p.x = arg->place_g.x; ret->best_p.y = arg->place_g.y; ret->best_penalty = penalty; } if (penalty == 0) { break; } loop_rc = arg->algo->get_next_pos(&next_p, ret, arg, hint_p); arg->place_g.x = next_p.x; arg->place_g.y = next_p.y; } if (ret->best_penalty < 0) { ret->best_penalty = -1; } return (ret->best_penalty == -1) ? -1 : 0; } static void __place_get_placement_flags( pl_flags_t *ret_flags, FvwmWindow *fw, window_style *pstyle, initial_window_options_t *win_opts, int mode, pl_reason_t *reason) { Bool override_ppos; Bool override_uspos; Bool has_ppos = False; Bool has_uspos = False; /* Windows use the position hint if these conditions are met: * * The program specified a USPosition hint and it is not overridden * with the No(Transient)USPosition style. * * OR * * The program specified a PPosition hint and it is not overridden * with the No(Transient)PPosition style. * * Windows without a position hint are placed using wm placement. */ if (IS_TRANSIENT(fw)) { override_ppos = SUSE_NO_TRANSIENT_PPOSITION(&pstyle->flags); override_uspos = SUSE_NO_TRANSIENT_USPOSITION(&pstyle->flags); } else { override_ppos = SUSE_NO_PPOSITION(&pstyle->flags); override_uspos = SUSE_NO_USPOSITION(&pstyle->flags); } if (fw->hints.flags & PPosition) { if (!override_ppos) { has_ppos = True; reason->pos.reason = PR_POS_USE_PPOS; } else { reason->pos.reason = PR_POS_IGNORE_PPOS; } } if (fw->hints.flags & USPosition) { if (!override_uspos) { has_uspos = True; reason->pos.reason = PR_POS_USE_USPOS; } else if (reason->pos.reason != PR_POS_USE_PPOS) { reason->pos.reason = PR_POS_IGNORE_USPOS; } } if (mode == PLACE_AGAIN) { ret_flags->do_not_use_wm_placement = 0; reason->pos.reason = PR_POS_PLACE_AGAIN; } else if (has_ppos || has_uspos) { ret_flags->do_not_use_wm_placement = 1; } else if (win_opts->flags.do_override_ppos) { ret_flags->do_not_use_wm_placement = 1; reason->pos.reason = PR_POS_CAPTURE; } else if (!ret_flags->do_honor_starts_on_page && fw->wmhints && (fw->wmhints->flags & StateHint) && fw->wmhints->initial_state == IconicState) { ret_flags->do_forbid_manual_placement = 1; reason->pos.do_not_manual_icon_placement = 1; } return; } static int __add_algo( const pl_algo_t **algos, int num_algos, const pl_algo_t *new_algo) { if (num_algos >= MAX_NUM_PLACEMENT_ALGOS) { return MAX_NUM_PLACEMENT_ALGOS; } algos[num_algos] = new_algo; num_algos++; return num_algos; } static int __place_get_wm_pos( const exec_context_t *exc, window_style *pstyle, rectangle *attr_g, pl_flags_t flags, rectangle screen_g, pl_start_style_t start_style, int mode, initial_window_options_t *win_opts, pl_reason_t *reason, int pdeltax, int pdeltay) { const pl_algo_t *algos[MAX_NUM_PLACEMENT_ALGOS + 1]; int num_algos; unsigned int placement_mode = SPLACEMENT_MODE(&pstyle->flags); pl_arg_t arg; pl_ret_t ret; int i; /* BEGIN init placement agrs and ret */ memset(&arg, 0, sizeof(arg)); arg.exc = exc; arg.style = pstyle; arg.reason = reason; arg.place_fw = exc->w.fw; arg.place_g = arg.place_fw->g.frame; arg.screen_g = screen_g; arg.page_p1.x = arg.screen_g.x - pdeltax; arg.page_p1.y = arg.screen_g.y - pdeltay; arg.page_p2.x = arg.page_p1.x + screen_g.width; arg.page_p2.y = arg.page_p1.y + screen_g.height; arg.pdelta_p.x = pdeltax; arg.pdelta_p.y = pdeltay; arg.flags.use_percent = 0; arg.flags.do_honor_starts_on_page = flags.do_honor_starts_on_page; if (SEWMH_PLACEMENT_MODE(&pstyle->flags) == EWMH_USE_WORKING_AREA) { arg.flags.use_ewmh_dynamic_working_areapercent = 1; } memset(&ret, 0, sizeof(ret)); ret.best_penalty = -1.0; /* END init placement agrs and ret */ /* override if manual placement happens */ SET_PLACED_BY_FVWM(arg.place_fw, 1); if (flags.do_forbid_manual_placement) { switch (placement_mode) { case PLACE_MANUAL: case PLACE_MANUAL_B: placement_mode = PLACE_CASCADE; break; case PLACE_TILEMANUAL: placement_mode = PLACE_TILECASCADE; break; default: break; } } reason->pos.algo = placement_mode; /* first, try various "smart" placement */ num_algos = 0; switch (placement_mode) { case PLACE_POSITION: num_algos = __add_algo( algos, num_algos, &position_placement_algo); break; case PLACE_TILEMANUAL: num_algos = __add_algo( algos, num_algos, &smart_placement_algo); num_algos = __add_algo( algos, num_algos, &manual_placement_algo); break; case PLACE_MINOVERLAPPERCENT: arg.flags.use_percent = 1; /* fall through */ case PLACE_MINOVERLAP: num_algos = __add_algo( algos, num_algos, &minoverlap_placement_algo); break; case PLACE_TILECASCADE: num_algos = __add_algo( algos, num_algos, &smart_placement_algo); num_algos = __add_algo( algos, num_algos, &cascade_placement_algo); break; case PLACE_MANUAL: case PLACE_MANUAL_B: num_algos = __add_algo( algos, num_algos, &manual_placement_algo); break; case PLACE_CASCADE: case PLACE_CASCADE_B: num_algos = __add_algo( algos, num_algos, &cascade_placement_algo); break; default: /* can't happen */ break; } /* try all the placement algorithms */ for (i = 0 ; ret.best_penalty < 0 && i < num_algos; i++) { arg.algo = algos[i]; placement_loop(&ret, &arg); } if (ret.best_penalty >= 0) { /* placement succed */ attr_g->x = ret.best_p.x; attr_g->y = ret.best_p.y; } else { /* fall back to default position */ attr_g->x = 0; attr_g->y = 0; reason->pos.has_placement_failed = 1; } return ret.flags.do_resize_too; } static int __place_get_nowm_pos( const exec_context_t *exc, window_style *pstyle, rectangle *attr_g, pl_flags_t flags, rectangle screen_g, pl_start_style_t start_style, int mode, initial_window_options_t *win_opts, pl_reason_t *reason, int pdeltax, int pdeltay) { FvwmWindow *fw = exc->w.fw; size_borders b; if (!win_opts->flags.do_override_ppos) { SET_PLACED_BY_FVWM(fw, False); } /* the USPosition was specified, or the window is a transient, or it * starts iconic so place it automatically */ if ( SUSE_START_ON_SCREEN(&pstyle->flags) && flags.do_honor_starts_on_screen) { fscreen_scr_t mangle_screen; /* If StartsOnScreen has been given for a window, translate its * USPosition so that it is relative to that particular screen. * If we don't do this, then a geometry would completely * cancel the effect of the StartsOnScreen style. However, some * applications try to remember their position. This would * break if these were translated to screen coordinates. There * is no reliable way to do it. Currently, if the desired * place does not intersect the target screen, we assume the * window position must be adjusted to the screen origin. So * there are two ways to get a window to pop up on a particular * Xinerama screen. 1: The intuitive way giving a geometry * hint relative to the desired screen's 0,0 along with the * appropriate StartsOnScreen style (or *wmscreen resource), or * 2: Do NOT specify a Xinerama screen (or specify it to be * 'g') and give the geometry hint in terms of the global * screen. */ mangle_screen = FScreenFetchMangledScreenFromUSPosHints( &(fw->hints)); if (mangle_screen != FSCREEN_GLOBAL) { /* whoever set this hint knew exactly what he was * doing; so ignore the StartsOnScreen style */ flags.do_honor_starts_on_screen = 0; reason->pos.reason = PR_POS_USPOS_OVERRIDE_SOS; } else if (attr_g->x + attr_g->width < screen_g.x || attr_g->x >= screen_g.x + screen_g.width || attr_g->y + attr_g->height < screen_g.y || attr_g->y >= screen_g.y + screen_g.height) { /* desired coordinates do not intersect the target * screen. Let's assume the application specified * global coordinates and translate them to the screen. */ FScreenTranslateCoordinates( NULL, start_style.screen, NULL, FSCREEN_GLOBAL, &attr_g->x, &attr_g->y); reason->pos.do_adjust_off_screen = 1; } } /* If SkipMapping, and other legalities are observed, adjust for * StartsOnPage. */ if (DO_NOT_SHOW_ON_MAP(fw) && flags.do_honor_starts_on_page && (!IS_TRANSIENT(fw) || SUSE_START_ON_PAGE_FOR_TRANSIENT(&pstyle->flags)) #if 0 /* dv 08-Jul-2003: Do not use this. Instead, force the window on * the requested page even if the application requested a different * position. */ && (SUSE_NO_PPOSITION(&pstyle->flags) || !(fw->hints.flags & PPosition)) /* dv 08-Jul-2003: This condition is always true because we * already checked for flags.do_honor_starts_on_page above. */ /* RBW - allow StartsOnPage to go through, even if iconic. */ && ((!(fw->wmhints && (fw->wmhints->flags & StateHint) && fw->wmhints->initial_state == IconicState)) || flags.do_honor_starts_on_page) #endif ) { int old_x; int old_y; old_x = attr_g->x; old_y = attr_g->y; /* We're placing a SkipMapping window - either capturing one * that's previously been mapped, or overriding USPosition - so * what we have here is its actual untouched coordinates. In * case it was a StartsOnPage window, we have to 1) convert the * existing x,y offsets relative to the requested page (i.e., * as though there were only one page, no virtual desktop), * then 2) readjust relative to the current page. */ if (attr_g->x < 0) { attr_g->x += Scr.MyDisplayWidth; } attr_g->x %= Scr.MyDisplayWidth; attr_g->x -= pdeltax; /* Noticed a quirk here. With some apps (e.g., xman), we find * the placement has moved 1 pixel away from where we * originally put it when we come through here. Why is this * happening? Probably attr_backup.border_width, try xclock * -borderwidth 100 */ if (attr_g->y < 0) { attr_g->y += Scr.MyDisplayHeight; } attr_g->y %= Scr.MyDisplayHeight; attr_g->y -= pdeltay; if (attr_g->x != old_x || attr_g->y != old_y) { reason->pos.do_adjust_off_page = 1; } } /* put it where asked, mod title bar */ /* if the gravity is towards the top, move it by the title height */ { rectangle final_g; int gravx; int gravy; gravity_get_offsets(fw->hints.win_gravity, &gravx, &gravy); final_g.x = attr_g->x + gravx * fw->attr_backup.border_width; final_g.y = attr_g->y + gravy * fw->attr_backup.border_width; /* Virtually all applications seem to share a common bug: they * request the top left pixel of their *border* as their origin * instead of the top left pixel of their client window, e.g. * 'xterm -g +0+0' creates an xterm that tries to map at (0 0) * although its border (width 1) would not be visible if it ran * under plain X. It should have tried to map at (1 1) * instead. This clearly violates the ICCCM, but trying to * change this is like tilting at windmills. So we have to add * the border width here. */ final_g.x += fw->attr_backup.border_width; final_g.y += fw->attr_backup.border_width; final_g.width = 0; final_g.height = 0; if (mode == PLACE_INITIAL) { get_window_borders(fw, &b); gravity_resize( fw->hints.win_gravity, &final_g, b.total_size.width, b.total_size.height); } attr_g->x = final_g.x; attr_g->y = final_g.y; } return 0; } /* Handles initial placement and sizing of a new window * * Return value: * * 0 = window lost * 1 = OK * 2 = OK, window must be resized too */ static int __place_window( const exec_context_t *exc, window_style *pstyle, rectangle *attr_g, pl_start_style_t start_style, int mode, initial_window_options_t *win_opts, pl_reason_t *reason) { FvwmWindow *t; int is_skipmapping_forbidden; int px = 0; int py = 0; int pdeltax = 0; int pdeltay = 0; rectangle screen_g; int rc = 0; pl_flags_t flags; extern Bool Restarting; FvwmWindow *fw = exc->w.fw; memset(&flags, 0, sizeof(flags)); /* Select a desk to put the window on (in list of priority): * 1. Sticky Windows stay on the current desk. * 2. Windows specified with StartsOnDesk go where specified * 3. Put it on the desk it was on before the restart. * 4. Transients go on the same desk as their parents. * 5. Window groups stay together (if the KeepWindowGroupsOnDesk style * is used). */ /* Let's get the StartsOnDesk/Page tests out of the way first. */ if ( SUSE_START_ON_DESK(&pstyle->flags) || SUSE_START_ON_SCREEN(&pstyle->flags)) { flags.do_honor_starts_on_page = 1; flags.do_honor_starts_on_screen = 1; /* * Honor the flag unless... * it's a restart or recapture, and that option's disallowed... */ if (win_opts->flags.do_override_ppos && (Restarting || (Scr.flags.are_windows_captured)) && !SRECAPTURE_HONORS_STARTS_ON_PAGE(&pstyle->flags)) { flags.do_honor_starts_on_page = 0; flags.do_honor_starts_on_screen = 0; reason->page.reason = (preason_page_t)PR_PAGE_IGNORE_CAPTURE; reason->page.do_ignore_starts_on_page = 1; reason->screen.reason = (preason_screen_t)PR_PAGE_IGNORE_CAPTURE; } /* * it's a cold start window capture, and that's disallowed... */ if (win_opts->flags.do_override_ppos && (!Restarting && !(Scr.flags.are_windows_captured)) && !SCAPTURE_HONORS_STARTS_ON_PAGE(&pstyle->flags)) { flags.do_honor_starts_on_page = 0; flags.do_honor_starts_on_screen = 0; reason->page.reason = PR_PAGE_IGNORE_CAPTURE; reason->page.do_ignore_starts_on_page = 1; reason->screen.reason = (preason_screen_t)PR_PAGE_IGNORE_CAPTURE; } /* * it's ActivePlacement and SkipMapping, and that's disallowed. */ switch (SPLACEMENT_MODE(&pstyle->flags)) { case PLACE_MANUAL: case PLACE_MANUAL_B: case PLACE_TILEMANUAL: is_skipmapping_forbidden = !SMANUAL_PLACEMENT_HONORS_STARTS_ON_PAGE( &pstyle->flags); break; default: is_skipmapping_forbidden = 0; break; } if (win_opts->flags.do_override_ppos || !DO_NOT_SHOW_ON_MAP(fw)) { is_skipmapping_forbidden = 0; } if (is_skipmapping_forbidden == 1) { flags.do_honor_starts_on_page = 0; reason->page.reason = PR_PAGE_IGNORE_INVALID; reason->page.do_ignore_starts_on_page = 1; fvwm_msg( WARN, "__place_window", "invalid style combination used: StartsOnPage" "/StartsOnDesk and SkipMapping don't work with" " ManualPlacement and TileManualPlacement." " Putting window on current page, please use" " another placement style or" " ActivePlacementHonorsStartsOnPage."); } } /* get the screen coordinates to place window on */ if (SUSE_START_ON_SCREEN(&pstyle->flags)) { if (flags.do_honor_starts_on_screen) { /* use screen from style */ FScreenGetScrRect( NULL, start_style.screen, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); reason->screen.screen = start_style.screen; } else { /* use global screen */ FScreenGetScrRect( NULL, FSCREEN_GLOBAL, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); reason->screen.screen = FSCREEN_GLOBAL; } } else { /* use current screen */ FScreenGetScrRect( NULL, FSCREEN_CURRENT, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); reason->screen.screen = FSCREEN_CURRENT; } if (SPLACEMENT_MODE(&pstyle->flags) != PLACE_MINOVERLAPPERCENT && SPLACEMENT_MODE(&pstyle->flags) != PLACE_MINOVERLAP && SPLACEMENT_MODE(&pstyle->flags) != PLACE_POSITION) { /* TA: In the case of PositionPlacement, the "ewmhiwa" option * will have already modified this for us -- so don't do it * for this placement policy. */ EWMH_GetWorkAreaIntersection( fw, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height, SEWMH_PLACEMENT_MODE(&pstyle->flags)); reason->screen.was_modified_by_ewmh_workingarea = 1; } reason->screen.g = screen_g; /* Don't alter the existing desk location during Capture/Recapture. */ if (!win_opts->flags.do_override_ppos) { fw->Desk = Scr.CurrentDesk; reason->desk.reason = PR_DESK_CURRENT; } else { reason->desk.reason = PR_DESK_CAPTURE; } if (S_IS_STICKY_ACROSS_DESKS(SFC(pstyle->flags))) { fw->Desk = Scr.CurrentDesk; reason->desk.reason = PR_DESK_STICKY; } else if (SUSE_START_ON_DESK(&pstyle->flags) && start_style.desk && flags.do_honor_starts_on_page) { fw->Desk = (start_style.desk > -1) ? start_style.desk - 1 : start_style.desk; reason->desk.reason = reason->desk.sod_reason; } else { if ((DO_USE_WINDOW_GROUP_HINT(fw)) && (fw->wmhints) && (fw->wmhints->flags & WindowGroupHint)&& (fw->wmhints->window_group != None) && (fw->wmhints->window_group != Scr.Root)) { /* Try to find the group leader or another window in * the group */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (FW_W(t) == fw->wmhints->window_group) { /* found the group leader, break out */ fw->Desk = t->Desk; reason->desk.reason = PR_DESK_WINDOW_GROUP_LEADER; break; } else if (t->wmhints && (t->wmhints->flags & WindowGroupHint) && (t->wmhints->window_group == fw->wmhints->window_group)) { /* found a window from the same group, * but keep looking for the group * leader */ fw->Desk = t->Desk; reason->desk.reason = PR_DESK_WINDOW_GROUP_MEMBER; } } } if ((IS_TRANSIENT(fw))&&(FW_W_TRANSIENTFOR(fw)!=None)&& (FW_W_TRANSIENTFOR(fw) != Scr.Root)) { /* Try to find the parent's desktop */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (FW_W(t) == FW_W_TRANSIENTFOR(fw)) { fw->Desk = t->Desk; reason->desk.reason = PR_DESK_TRANSIENT; break; } } } { /* migo - I am not sure this block is ever needed */ Atom atype; int aformat; unsigned long nitems, bytes_remain; unsigned char *prop; if ( XGetWindowProperty( dpy, FW_W(fw), _XA_WM_DESKTOP, 0L, 1L, True, _XA_WM_DESKTOP, &atype, &aformat, &nitems, &bytes_remain, &prop) == Success) { if (prop != NULL) { fw->Desk = *(unsigned long *)prop; XFree(prop); reason->desk.reason = PR_DESK_XPROP_XA_WM_DESKTOP; } } } } reason->desk.desk = fw->Desk; /* I think it would be good to switch to the selected desk * whenever a new window pops up, except during initialization */ /* RBW - 11/02/1998 -- I dont. */ if (!win_opts->flags.do_override_ppos && !DO_NOT_SHOW_ON_MAP(fw)) { if (Scr.CurrentDesk != fw->Desk) { reason->desk.do_switch_desk = 1; } goto_desk(fw->Desk); } /* Don't move viewport if SkipMapping, or if recapturing the window, * adjust the coordinates later. Otherwise, just switch to the target * page - it's ever so much simpler. */ if (S_IS_STICKY_ACROSS_PAGES(SFC(pstyle->flags))) { reason->page.reason = PR_PAGE_STICKY; } else if (SUSE_START_ON_DESK(&pstyle->flags)) { if (start_style.page_x != 0 && start_style.page_y != 0) { px = start_style.page_x - 1; py = start_style.page_y - 1; reason->page.reason = PR_PAGE_STYLE; px *= Scr.MyDisplayWidth; py *= Scr.MyDisplayHeight; if (!win_opts->flags.do_override_ppos && !DO_NOT_SHOW_ON_MAP(fw)) { MoveViewport(px,py,True); reason->page.do_switch_page = 1; } else if (flags.do_honor_starts_on_page) { /* Save the delta from current page */ pdeltax = Scr.Vx - px; pdeltay = Scr.Vy - py; reason->page.do_honor_starts_on_page = 1; } } } /* pick a location for the window. */ __place_get_placement_flags( &flags, fw, pstyle, win_opts, mode, reason); if (flags.do_not_use_wm_placement) { rc = __place_get_nowm_pos( exc, pstyle, attr_g, flags, screen_g, start_style, mode, win_opts, reason, pdeltax, pdeltay); } else { rc = __place_get_wm_pos( exc, pstyle, attr_g, flags, screen_g, start_style, mode, win_opts, reason, pdeltax, pdeltay); } reason->pos.x = attr_g->x; reason->pos.y = attr_g->y; return rc; } static void __place_handle_x_resources( FvwmWindow *fw, window_style *pstyle, pl_reason_t *reason) { int client_argc = 0; char **client_argv = NULL; XrmValue rm_value; /* Used to parse command line of clients for specific desk requests. */ /* Todo: check for multiple desks. */ XrmDatabase db = NULL; static XrmOptionDescRec table [] = { /* Want to accept "-workspace N" or -xrm "fvwm*desk:N" as * options to specify the desktop. I have to include dummy * options that are meaningless since Xrm seems to allow -w to * match -workspace if there would be no ambiguity. */ {"-workspacf", "*junk", XrmoptionSepArg, (caddr_t) NULL}, {"-workspace", "*desk", XrmoptionSepArg, (caddr_t) NULL}, {"-xrn", NULL, XrmoptionResArg, (caddr_t) NULL}, {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL}, }; int t1 = -1, t2 = -1, t3 = -1, spargs = 0; /* Find out if the client requested a specific desk on the command * line. * RBW - 11/20/1998 - allow a desk of -1 to work. */ if (XGetCommand(dpy, FW_W(fw), &client_argv, &client_argc) == 0) { return; } if (client_argc <= 0 || client_argv == NULL) { return; } /* Get global X resources */ MergeXResources(dpy, &db, False); /* command line takes precedence over all */ MergeCmdLineResources( &db, table, 4, client_argv[0], &client_argc, client_argv, True); /* parse the database values */ if (GetResourceString(db, "desk", client_argv[0], &rm_value) && rm_value.size != 0) { SGET_START_DESK(*pstyle) = atoi(rm_value.addr); /* RBW - 11/20/1998 */ if (SGET_START_DESK(*pstyle) > -1) { SSET_START_DESK( *pstyle, SGET_START_DESK(*pstyle) + 1); } reason->desk.sod_reason = PR_DESK_X_RESOURCE_DESK; pstyle->flags.use_start_on_desk = 1; } if (GetResourceString(db, "fvwmscreen", client_argv[0], &rm_value) && rm_value.size != 0) { SSET_START_SCREEN( *pstyle, FScreenGetScreenArgument(rm_value.addr, 'c')); reason->screen.reason = PR_SCREEN_X_RESOURCE_FVWMSCREEN; reason->screen.screen = SGET_START_SCREEN(*pstyle); pstyle->flags.use_start_on_screen = 1; } if (GetResourceString(db, "page", client_argv[0], &rm_value) && rm_value.size != 0) { spargs = sscanf( rm_value.addr, "%d %d %d", &t1, &t2, &t3); switch (spargs) { case 1: pstyle->flags.use_start_on_desk = 1; SSET_START_DESK(*pstyle, (t1 > -1) ? t1 + 1 : t1); reason->desk.sod_reason = PR_DESK_X_RESOURCE_PAGE; break; case 2: pstyle->flags.use_start_on_desk = 1; SSET_START_PAGE_X(*pstyle, (t1 > -1) ? t1 + 1 : t1); SSET_START_PAGE_Y(*pstyle, (t2 > -1) ? t2 + 1 : t2); reason->page.reason = PR_PAGE_X_RESOURCE_PAGE; reason->page.px = SGET_START_PAGE_X(*pstyle); reason->page.py = SGET_START_PAGE_Y(*pstyle); break; case 3: pstyle->flags.use_start_on_desk = 1; SSET_START_DESK(*pstyle, (t1 > -1) ? t1 + 1 : t1); reason->desk.sod_reason = PR_DESK_X_RESOURCE_PAGE; SSET_START_PAGE_X(*pstyle, (t2 > -1) ? t2 + 1 : t2); SSET_START_PAGE_Y(*pstyle, (t3 > -1) ? t3 + 1 : t3); reason->page.reason = PR_PAGE_X_RESOURCE_PAGE; reason->page.px = SGET_START_PAGE_X(*pstyle); reason->page.py = SGET_START_PAGE_Y(*pstyle); break; default: break; } } XFreeStringList(client_argv); XrmDestroyDatabase(db); return; } static void __explain_placement(FvwmWindow *fw, pl_reason_t *reason) { char explanation[2048]; char *r; char *s; char t[32]; int do_show_page; int is_placed_by_algo; *explanation = 0; s = explanation; strcat(s, "placed new window 0x%x '%s':\n"); s += strlen(s); sprintf( s, " initial size %dx%d\n", fw->g.frame.width, fw->g.frame.height); s += strlen(s); switch (reason->desk.reason) { case PR_DESK_CURRENT: r = "current desk"; break; case PR_DESK_STYLE: r = "specified by style"; break; case PR_DESK_X_RESOURCE_DESK: r = "specified by 'desk' X resource"; break; case PR_DESK_X_RESOURCE_PAGE: r = "specified by 'page' X resource"; break; case PR_DESK_CAPTURE: r = "window was (re)captured"; break; case PR_DESK_STICKY: r = "window is sticky"; break; case PR_DESK_WINDOW_GROUP_LEADER: r = "same desk as window group leader"; break; case PR_DESK_WINDOW_GROUP_MEMBER: r = "same desk as window group member"; break; case PR_DESK_TRANSIENT: r = "transient window placed on same desk as parent"; break; case PR_DESK_XPROP_XA_WM_DESKTOP: r = "specified by _XA_WM_DESKTOP property"; break; default: r = "bug"; break; } sprintf(s, " desk %d (%s)\n", reason->desk.desk, r); s += strlen(s); if (reason->desk.do_switch_desk == 1) { sprintf(s, " (switched to desk)\n"); s += strlen(s); } /* page */ do_show_page = 1; switch (reason->page.reason) { case PR_PAGE_CURRENT: do_show_page = 0; r = "current page"; break; case PR_PAGE_STYLE: r = "specified by style"; break; case PR_PAGE_X_RESOURCE_PAGE: r = "specified by 'page' X resource"; break; case PR_PAGE_IGNORE_CAPTURE: r = "window was (re)captured"; break; case PR_PAGE_IGNORE_INVALID: r = "requested page ignored because of invalid style" " combination"; break; case PR_PAGE_STICKY: do_show_page = 0; r = "current page (window is sticky)"; break; default: r = "bug"; break; } if (do_show_page == 0) { sprintf(s, " %s\n", r); } else { sprintf( s, " page %d %d (%s)\n", reason->page.px - 1, reason->page.py - 1, r); } s += strlen(s); if (reason->page.do_switch_page == 1) { sprintf(s, " (switched to page)\n"); s += strlen(s); } if (reason->page.do_ignore_starts_on_page == 1) { sprintf(s, " (possibly ignored StartsOnPage)\n"); s += strlen(s); } /* screen */ if (FScreenIsEnabled() == True || FScreenIsSLSEnabled() == True) { switch (reason->screen.reason) { case PR_SCREEN_CURRENT: r = "current screen"; break; case PR_SCREEN_STYLE: r = "specified by style"; break; case PR_SCREEN_X_RESOURCE_FVWMSCREEN: r = "specified by 'fvwmscreen' X resource"; break; case PR_SCREEN_IGNORE_CAPTURE: r = "window was (re)captured"; break; default: r = "bug"; break; } FScreenSpecToString(t, 32, reason->screen.screen); sprintf( s, " screen: %s: %d %d %dx%d (%s)\n", t, reason->screen.g.x, reason->screen.g.y, reason->screen.g.width, reason->screen.g.height, r); s += strlen(s); if (reason->screen.was_modified_by_ewmh_workingarea == 1) { sprintf( s, " (screen area modified by EWMH working" " area)\n"); s += strlen(s); } } /* position */ is_placed_by_algo = 0; switch (reason->pos.reason) { case PR_POS_NORMAL: is_placed_by_algo = 1; r = "normal placement"; break; case PR_POS_IGNORE_PPOS: is_placed_by_algo = 1; r = "ignored program specified position"; break; case PR_POS_USE_PPOS: r = "used program specified position"; break; case PR_POS_IGNORE_USPOS: is_placed_by_algo = 1; r = "ignored user specified position"; break; case PR_POS_USE_USPOS: r = "used user specified position"; break; case PR_POS_PLACE_AGAIN: is_placed_by_algo = 1; r = "by PlaceAgain command"; break; case PR_POS_CAPTURE: r = "window was (re)captured"; break; case PR_POS_USPOS_OVERRIDE_SOS: r = "StartsOnPage style overridden by application via USPos"; break; default: r = "bug"; break; } sprintf(s, " position %d %d", reason->pos.x, reason->pos.y); s += strlen(s); if (is_placed_by_algo == 1) { char *a; char *b; b = ""; switch (reason->pos.algo) { case PLACE_POSITION: a = "Position args: "; b = reason->pos.pl_position_string; break; case PLACE_TILEMANUAL: a = "TileManual"; break; case PLACE_MANUAL: case PLACE_MANUAL_B: a = "Manual"; break; case PLACE_MINOVERLAPPERCENT: a = "MinOverlapPercent"; break; case PLACE_TILECASCADE: a = "TileCascade"; break; case PLACE_CASCADE: case PLACE_CASCADE_B: a = "Cascade"; break; case PLACE_MINOVERLAP: a = "MinOverlap"; break; default: a = "bug"; break; } sprintf(s, ", placed by fvwm (%s)\n", r); s += strlen(s); sprintf(s, " placement method: %s%s\n", a, b); s += strlen(s); if (reason->pos.do_not_manual_icon_placement == 1) { sprintf(s, " (icon not placed manually)\n"); s += strlen(s); } if (reason->pos.is_pl_position_string_invalid == 1) { sprintf(s, " (invalid position string)\n"); s += strlen(s); } if (reason->pos.has_tile_failed == 1) { sprintf(s, " (tile placement failed)\n"); s += strlen(s); } if (reason->pos.has_manual_failed == 1) { sprintf(s, " (manual placement failed)\n"); s += strlen(s); } if (reason->pos.has_placement_failed == 1) { sprintf(s, " (placement failed default pos 0 0)\n"); s += strlen(s); } } else { sprintf(s, " (%s)\n", r); s += strlen(s); } if (reason->pos.do_adjust_off_screen == 1) { sprintf(s, " (adjusted to force window on screen)\n"); s += strlen(s); } if (reason->pos.do_adjust_off_page == 1) { sprintf(s, " (adjusted to force window on page)\n"); s += strlen(s); } fvwm_msg( INFO, "__explain_placement", explanation, (int)FW_W(fw), fw->name.name); return; } /* ---------------------------- interface functions ------------------------ */ Bool setup_window_placement( FvwmWindow *fw, window_style *pstyle, rectangle *attr_g, initial_window_options_t *win_opts, placement_mode_t mode) { int rc; const exec_context_t *exc; exec_context_changes_t ecc; pl_reason_t reason; pl_start_style_t start_style; memset(&reason, 0, sizeof(reason)); if (pstyle->flags.use_start_on_desk) { reason.desk.sod_reason = PR_DESK_STYLE; reason.page.px = SGET_START_PAGE_X(*pstyle); reason.page.py = SGET_START_PAGE_Y(*pstyle); } if (pstyle->flags.use_start_on_screen) { reason.screen.reason = PR_SCREEN_STYLE; reason.screen.screen = SGET_START_SCREEN(*pstyle); } __place_handle_x_resources(fw, pstyle, &reason); if (pstyle->flags.do_start_iconic) { win_opts->initial_state = IconicState; } ecc.type = EXCT_NULL; ecc.w.fw = fw; exc = exc_create_context(&ecc, ECC_TYPE | ECC_FW); start_style.desk = SGET_START_DESK(*pstyle); start_style.page_x = SGET_START_PAGE_X(*pstyle); start_style.page_y = SGET_START_PAGE_Y(*pstyle); start_style.screen = SGET_START_SCREEN(*pstyle); rc = __place_window( exc, pstyle, attr_g, start_style, mode, win_opts, &reason); exc_destroy_context(exc); if (Scr.bo.do_explain_window_placement == 1) { __explain_placement(fw, &reason); } return (rc == 0) ? False : True; } /* ---------------------------- builtin commands --------------------------- */ void CMD_PlaceAgain(F_CMD_ARGS) { int old_desk; char *token; float noMovement[1] = {1.0}; float *ppctMovement = noMovement; rectangle attr_g; XWindowAttributes attr; Bool do_move_animated = False; Bool do_place_icon = False; FvwmWindow * const fw = exc->w.fw; if (!XGetWindowAttributes(dpy, FW_W(fw), &attr)) { return; } while ((token = PeekToken(action, &action)) != NULL) { if (StrEquals("Anim", token)) { ppctMovement = NULL; do_move_animated = True; } else if (StrEquals("icon", token)) { do_place_icon = True; } } old_desk = fw->Desk; if (IS_ICONIFIED(fw) && !do_place_icon) { return; } if (IS_ICONIFIED(fw) && do_place_icon) { rectangle new_g; rectangle old_g; if (IS_ICON_SUPPRESSED(fw)) { return; } fw->Desk = Scr.CurrentDesk; get_icon_geometry(fw, &old_g); SET_ICON_MOVED(fw, 0); AutoPlaceIcon(fw, NULL, False); get_icon_geometry(fw, &new_g); __move_icon( fw, new_g.x, new_g.y, old_g.x, old_g.y, do_move_animated, False); } else { window_style style; initial_window_options_t win_opts; memset(&win_opts, 0, sizeof(win_opts)); lookup_style(fw, &style); attr_g.x = attr.x; attr_g.y = attr.y; attr_g.width = attr.width; attr_g.height = attr.height; setup_window_placement( exc->w.fw, &style, &attr_g, &win_opts, PLACE_AGAIN); AnimatedMoveFvwmWindow( fw, FW_W_FRAME(fw), -1, -1, attr_g.x, attr_g.y, False, -1, ppctMovement); } if (fw->Desk != old_desk) { int new_desk = fw->Desk; fw->Desk = old_desk; do_move_window_to_desk(fw, new_desk); } return; } fvwm-2.6.7/fvwm/ewmh_events.c0000644000175700017570000010473412773467232013141 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ /* 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 #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "virtual.h" #include "commands.h" #include "update.h" #include "style.h" #include "stack.h" #include "events.h" #include "ewmh.h" #include "ewmh_intern.h" #include "decorations.h" #include "geometry.h" #include "borders.h" extern ewmh_atom ewmh_atom_wm_state[]; #define DEBUG_EWMH_INIT_STATE 0 /* * root */ int ewmh_CurrentDesktop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev->xclient.data.l[0] < 0 || ev->xclient.data.l[0] > 0x7fffffff) { fvwm_msg( WARN, "ewmh_CurrentDesktop", "The application window (id %#lx)\n" " \"%s\" tried to switch to an invalid desktop (%ld)\n" " using an EWMH client message.\n" " fvwm is ignoring this request.\n", fw ? FW_W(fw) : 0, fw ? fw->name.name : "(none)", ev->xclient.data.l[0]); fvwm_msg_report_app_and_workers(); return -1; } goto_desk(ev->xclient.data.l[0]); return -1; } int ewmh_DesktopGeometry( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { char action[256]; long width = ev->xclient.data.l[0]; long height = ev->xclient.data.l[1]; width = width / Scr.MyDisplayWidth; height = height / Scr.MyDisplayHeight; if (width <= 0 || height <= 0) { fvwm_msg( WARN, "ewmh_DesktopGeometry", "The application window (id %#lx)\n" " \"%s\" tried to set an invalid desktop geometry" " (%ldx%ld)\n" " using an EWMH client message.\n" " fvwm is ignoring this request.\n", fw ? FW_W(fw) : 0, fw ? fw->name.name : "(none)", ev->xclient.data.l[0], ev->xclient.data.l[1]); fvwm_msg_report_app_and_workers(); return -1; } sprintf(action, "DesktopSize %ld %ld", width, height); execute_function_override_window(NULL, NULL, action, 0, NULL); return -1; } int ewmh_DesktopViewPort( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if ( ev->xclient.data.l[0] < 0 || ev->xclient.data.l[0] > 0x7fffffff || ev->xclient.data.l[1] < 0 || ev->xclient.data.l[1] > 0x7fffffff) { fvwm_msg( WARN, "ewmh_DesktopViewPort", "The application window (id %#lx)\n" " \"%s\" tried to switch to an invalid page" " (%ldx%ld)\n" " using an EWMH client message.\n" " fvwm is ignoring this request.\n", fw ? FW_W(fw) : 0, fw ? fw->name.name : "(none)", ev->xclient.data.l[0], ev->xclient.data.l[1]); fvwm_msg_report_app_and_workers(); return -1; } MoveViewport(ev->xclient.data.l[0], ev->xclient.data.l[1], 1); return -1; } int ewmh_NumberOfDesktops( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int d = ev->xclient.data.l[0]; /* not a lot of sinification for fvwm */ if (d > 0 && (d <= ewmhc.MaxDesktops || ewmhc.MaxDesktops == 0)) { ewmhc.NumberOfDesktops = d; EWMH_SetNumberOfDesktops(); } else { fvwm_msg( WARN, "ewmh_NumberOfDesktops", "The application window (id %#lx)\n" " \"%s\" tried to set an invalid number of desktops" " (%ld)\n" " using an EWMH client message.\n" " fvwm is ignoring this request.\n", fw ? FW_W(fw) : 0, fw ? fw->name.name : "(none)", ev->xclient.data.l[0]); fvwm_msg_report_app_and_workers(); } return -1; } /* * window */ int ewmh_ActiveWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL) { return 0; } execute_function_override_window( NULL, NULL, "EWMHActivateWindowFunc", 0, fw); return 0; } int ewmh_CloseWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL) { return 0; } if (!is_function_allowed(F_CLOSE, NULL, fw, RQORIG_PROGRAM_US, False)) { return 0; } execute_function_override_window(NULL, NULL, "Close", 0, fw); return 0; } int ewmh_MoveResizeWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int do_reconfigure; int win_gravity; int value_mask; if (ev == NULL) { return 0; } win_gravity = ev->xclient.data.l[0] & 0xff; value_mask = (ev->xclient.data.l[0] >> 8) & 0xf; if (fw == NULL) { /* unmanaged window */ do_reconfigure = 1; } else { int func; if ( ((value_mask & CWWidth) == 0 || ev->xclient.data.l[3] == fw->g.normal.width) && ((value_mask & CWHeight) == 0 || ev->xclient.data.l[4] == fw->g.normal.height)) { func = F_MOVE; } else { func = F_RESIZE; } do_reconfigure = !!is_function_allowed( func, NULL, fw, RQORIG_PROGRAM, False); } if (do_reconfigure == 1) { XEvent e; XConfigureRequestEvent *cre = &e.xconfigurerequest; cre->value_mask = value_mask; cre->x = ev->xclient.data.l[1]; cre->y = ev->xclient.data.l[2]; cre->width = ev->xclient.data.l[3]; cre->height = ev->xclient.data.l[4]; cre->window = ev->xclient.window; events_handle_configure_request(&e, fw, True, win_gravity); } return 0; } int ewmh_RestackWindow( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int do_restack; if (ev == NULL) { return 0; } if (fw == NULL) { /* unmanaged window */ do_restack = 1; } else { do_restack = !!DO_EWMH_USE_STACKING_HINTS(fw); } if (do_restack == 1) { XEvent e; XConfigureRequestEvent *cre = &e.xconfigurerequest; cre->value_mask = CWSibling | CWStackMode; cre->above = ev->xclient.data.l[1]; cre->detail = ev->xclient.data.l[2]; cre->window = ev->xclient.window; events_handle_configure_request(&e, fw, True, ForgetGravity); } return 0; } int ewmh_WMDesktop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev != NULL && style == NULL) { /* client message */ unsigned long d = (unsigned long)ev->xclient.data.l[0]; /* the spec says that if d = 0xFFFFFFFF then we have to Stick * the window however KDE use 0xFFFFFFFE :o) */ if (d == (unsigned long)-2 || d == (unsigned long)-1) { execute_function_override_window( NULL, NULL, "Stick on", 0, fw); } else if (d > 0) { if (IS_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw)) { execute_function_override_window( NULL, NULL, "Stick off", 0, fw); } if (fw->Desk != d) { do_move_window_to_desk(fw, (int)d); } } else { fvwm_msg( WARN, "ewmh_WMDesktop", "The application window (id %#lx)\n" " \"%s\" tried to move to an invalid desk" " (%ld)\n" " using an EWMH client message.\n" " fvwm is ignoring this request.\n", fw ? FW_W(fw) : 0, fw ? fw->name.name : "(none)", ev->xclient.data.l[0]); fvwm_msg_report_app_and_workers(); } return 0; } if (style != NULL && ev == NULL) { /* start on desk */ CARD32 *val; int size = 0; if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_WM_DESKTOP( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_WM_DESKTOP(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_DESKTOP", EWMH_ATOM_LIST_CLIENT_WIN, &size); if (val == NULL) { SET_HAS_EWMH_INIT_WM_DESKTOP(fw, EWMH_STATE_NO_HINT); return 0; } #if DEBUG_EWMH_INIT_STATE fprintf( stderr, "ewmh WM_DESKTOP hint for window 0x%lx " "(%i,%lu,%u)\n", FW_W(fw), HAS_EWMH_INIT_WM_DESKTOP(fw), fw->ewmh_hint_desktop, val[0]); #endif if (val[0] == (CARD32)-2 || val[0] == (CARD32)-1) { S_SET_IS_STICKY_ACROSS_PAGES(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*style), 1); } else if (val[0] < 256) { /* prevent crazy hints ?? */ style->flags.use_start_on_desk = 1; style->flag_mask.use_start_on_desk = 1; style->change_mask.use_start_on_desk = 1; SSET_START_DESK(*style, val[0]); } SET_HAS_EWMH_INIT_WM_DESKTOP(fw, EWMH_STATE_HAS_HINT); fw->ewmh_hint_desktop = val[0]; free(val); } return 0; } int ewmh_MoveResize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int dir = -1; int x_warp = 0; int y_warp = 0; Bool move = False; char cmd[256]; if (ev == NULL) { return 0; } dir = ev->xclient.data.l[2]; switch(dir) { case _NET_WM_MOVERESIZE_SIZE_TOPLEFT: break; case _NET_WM_MOVERESIZE_SIZE_TOP: x_warp = 50; break; case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: x_warp = 100; break; case _NET_WM_MOVERESIZE_SIZE_RIGHT: x_warp = 100; y_warp = 50; break; case _NET_WM_MOVERESIZE_SIZE_KEYBOARD: case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: x_warp = 100; y_warp = 100; break; case _NET_WM_MOVERESIZE_SIZE_BOTTOM: x_warp = 50; y_warp = 100; break; case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: y_warp = 100; break; case _NET_WM_MOVERESIZE_SIZE_LEFT: y_warp = 50; break; case _NET_WM_MOVERESIZE_MOVE_KEYBOARD: case _NET_WM_MOVERESIZE_MOVE: move = True; break; default: return 0; } if (move) { if ( !is_function_allowed( F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False)) { return 0; } } else { if ( !is_function_allowed( F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { return 0; } } if (!move) { sprintf(cmd, "WarpToWindow %i %i",x_warp,y_warp); execute_function_override_window(NULL, NULL, cmd, 0, fw); } if (move) { execute_function_override_window( NULL, NULL, "Move", 0, fw); } else { execute_function_override_window( NULL, NULL, "Resize", 0, fw); } return 0; } /* * WM_STATE* */ int ewmh_WMState( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { unsigned long maximize = 0; if (ev != NULL) { ewmh_atom *a1,*a2; a1 = ewmh_GetEwmhAtomByAtom( ev->xclient.data.l[1], EWMH_ATOM_LIST_WM_STATE); a2 = ewmh_GetEwmhAtomByAtom( ev->xclient.data.l[2], EWMH_ATOM_LIST_WM_STATE); if (a1 != NULL) { maximize |= a1->action(fw, ev, NULL, 0); } if (a2 != NULL) { maximize |= a2->action(fw, ev, NULL, 0); } } else if (style != NULL) { CARD32 *val; unsigned int nitems; int size = 0; int i; ewmh_atom *list = ewmh_atom_wm_state; int has_hint = 0; val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_STATE", EWMH_ATOM_LIST_CLIENT_WIN, &size); if (val == NULL) { size = 0; } #if DEBUG_EWMH_INIT_STATE if (size != 0) { fprintf( stderr, "Window 0x%lx has an init" " _NET_WM_STATE hint\n",FW_W(fw)); } #endif nitems = size / sizeof(CARD32); while(list->name != NULL) { has_hint = 0; for(i = 0; i < nitems; i++) { if (list->atom == val[i]) { has_hint = 1; } } list->action(fw, NULL, style, has_hint); list++; } if (val != NULL) { free(val); } return 0; } if (maximize != 0) { int max_vert = (maximize & EWMH_MAXIMIZE_VERT)? 100:0; int max_horiz = (maximize & EWMH_MAXIMIZE_HORIZ)? 100:0; char cmd[256]; if (maximize & EWMH_MAXIMIZE_REMOVE) { sprintf(cmd,"Maximize off"); } else { if (!is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { return 0; } sprintf(cmd,"Maximize on %i %i", max_horiz, max_vert); } execute_function_override_window(NULL, NULL, cmd, 0, fw); } return 0; } int ewmh_WMStateFullScreen( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { return (IS_EWMH_FULLSCREEN(fw)); } if (ev == NULL && style != NULL) { /* start full screen */ unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf(stderr,"\tFullscreen\n"); } #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_FULLSCREEN_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_FULLSCREEN_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_FULLSCREEN_STATE( fw, EWMH_STATE_NO_HINT); return 0; } SET_EWMH_FULLSCREEN(fw,True); SET_HAS_EWMH_INIT_FULLSCREEN_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* client message */ int bool_arg = ev->xclient.data.l[0]; int is_full_screen; is_full_screen = IS_EWMH_FULLSCREEN(fw); if ((bool_arg == NET_WM_STATE_TOGGLE && !is_full_screen) || bool_arg == NET_WM_STATE_ADD) { EWMH_fullscreen(fw); } else { if (HAS_EWMH_INIT_FULLSCREEN_STATE(fw) == EWMH_STATE_HAS_HINT) { /* the application started fullscreen */ SET_HAS_EWMH_INIT_FULLSCREEN_STATE( fw, EWMH_STATE_NO_HINT); } /* unmaximize will restore is_ewmh_fullscreen, * layer and apply_decor_change */ execute_function_override_window( NULL, NULL, "Maximize off", 0, fw); } if ((IS_EWMH_FULLSCREEN(fw) && !DO_EWMH_USE_STACKING_HINTS(fw)) || (!IS_EWMH_FULLSCREEN(fw) && DO_EWMH_USE_STACKING_HINTS(fw))) { /* On: if not raised by a layer cmd raise * Off: if lowered by a layer cmd raise */ execute_function_override_window( NULL, NULL, "Raise", 0, fw); } } return 0; } int ewmh_WMStateHidden( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (HAS_EWMH_INIT_HIDDEN_STATE(fw) == EWMH_STATE_HAS_HINT) { return True; } return False; } return IS_ICONIFIED(fw); } if (ev == NULL && style != NULL) { /* start iconified */ unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) fprintf(stderr,"\tHidden\n"); #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_HIDDEN_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_HIDDEN_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_HIDDEN_STATE(fw, EWMH_STATE_NO_HINT); return 0; } style->flags.do_start_iconic = 1; style->flag_mask.do_start_iconic = 1; style->change_mask.do_start_iconic = 1; SET_HAS_EWMH_INIT_HIDDEN_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* client message */ char cmd[16]; int bool_arg = ev->xclient.data.l[0]; if ((bool_arg == NET_WM_STATE_TOGGLE && !IS_ICONIFIED(fw)) || bool_arg == NET_WM_STATE_ADD) { /* iconify */ if ( !is_function_allowed( F_ICONIFY, NULL, fw, RQORIG_PROGRAM_US, False)) { return 0; } sprintf(cmd, "Iconify on"); } else { /* deiconify */ sprintf(cmd, "Iconify off"); } execute_function_override_window(NULL, NULL, cmd, 0, fw); } return 0; } int ewmh_WMStateMaxHoriz( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { #if 0 return (IS_MAXIMIZED(fw) && !IS_EWMH_FULLSCREEN(fw)); #else /* DV: the notion of vertical/horizontal maximization does not * make any sense in fvwm, so just claim we're never maximized */ return 0; #endif } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf( stderr, "\t Maxhoriz %i\n", HAS_EWMH_INIT_MAXHORIZ_STATE(fw)); } #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_MAXHORIZ_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } /* If the initial state is STATE_NO_HINT we still want to * override it, since having just one of MAXIMIZED_HORIZ or * MAXIMIZED_HORZ is enough to make the window maximized. */ if (HAS_EWMH_INIT_MAXHORIZ_STATE(fw) == EWMH_STATE_HAS_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_MAXHORIZ_STATE( fw, EWMH_STATE_NO_HINT); return 0; } SET_HAS_EWMH_INIT_MAXHORIZ_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* client message */ int cmd_arg = ev->xclient.data.l[0]; if ( !IS_MAXIMIZED(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_ADD)) { return EWMH_MAXIMIZE_HORIZ; } else if ( IS_MAXIMIZED(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_REMOVE)) { return EWMH_MAXIMIZE_REMOVE; } } return 0; } int ewmh_WMStateMaxVert( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { #if 0 return (IS_MAXIMIZED(fw) && !IS_EWMH_FULLSCREEN(fw)); #else /* DV: the notion of vertical/horizontal maximization does not * make any sense in fvwm, so just claim we're never maximized */ return 0; #endif } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf( stderr, "\t Maxvert %i\n", HAS_EWMH_INIT_MAXVERT_STATE(fw)); } #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_MAXVERT_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_MAXVERT_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_MAXVERT_STATE( fw, EWMH_STATE_NO_HINT); return 0; } SET_HAS_EWMH_INIT_MAXVERT_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* client message */ int cmd_arg = ev->xclient.data.l[0]; if ( !IS_MAXIMIZED(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_ADD)) { return EWMH_MAXIMIZE_VERT; } else if ( IS_MAXIMIZED(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_REMOVE)) { return EWMH_MAXIMIZE_REMOVE; } } return 0; } int ewmh_WMStateModal( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (HAS_EWMH_INIT_MODAL_STATE(fw) == EWMH_STATE_HAS_HINT) { return True; } return False; } return IS_EWMH_MODAL(fw); } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf( stderr, "\t Modal %i\n", HAS_EWMH_INIT_MODAL_STATE(fw)); } #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_MODAL_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_MODAL_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_MODAL_STATE(fw, EWMH_STATE_NO_HINT); return 0; } /* the window map or had mapped with a modal hint */ if (IS_TRANSIENT(fw)) { SET_EWMH_MODAL(fw, True); /* the window is a modal transient window so we grab * the focus it will be good to raise it but ... */ FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCF(*style)), 1); FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCM(*style)), 1); FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCC(*style)), 1); SET_HAS_EWMH_INIT_MODAL_STATE( fw, EWMH_STATE_HAS_HINT); } else { SET_EWMH_MODAL(fw, False); if (!FP_DO_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCF(*style)))) { FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCF(*style)), 0); FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCM(*style)), 1); FPS_GRAB_FOCUS_TRANSIENT( S_FOCUS_POLICY(SCC(*style)), 1); } } return 0; } if (ev != NULL && fw != NULL) { /* client message: I do not think we can get such message */ /* java sends this message */ int cmd_arg = ev->xclient.data.l[0]; if ( !IS_EWMH_MODAL(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_ADD)) { /* ON */ } else if ( IS_EWMH_MODAL(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_REMOVE)) { /* OFF */ } /* !MODAL MODAL * CMD * STATE_ADD ON do nothing * STATE_TOGGLE ON OFF * STATE_REMOVE do nothing OFF */ } return 0; } int ewmh_WMStateShaded( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (HAS_EWMH_INIT_SHADED_STATE(fw) == EWMH_STATE_HAS_HINT) { return True; } return False; } return IS_SHADED(fw); } if (ev == NULL && style != NULL) { /* start shaded */ unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf( stderr, "\t Shaded %i\n", HAS_EWMH_INIT_SHADED_STATE(fw)); } #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_SHADED_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_SHADED_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_SHADED_STATE( fw, EWMH_STATE_NO_HINT); return 0; } SET_SHADED(fw, 1); SET_SHADED_DIR(fw, GET_TITLE_DIR(fw)); SET_HAS_EWMH_INIT_SHADED_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* client message */ int cmd_arg = ev->xclient.data.l[0]; if ( !IS_SHADED(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_ADD)) { execute_function_override_window( NULL, NULL, "Windowshade on", 0, fw); } else if ( IS_SHADED(fw) && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_REMOVE)) { execute_function_override_window( NULL, NULL, "Windowshade off", 0, fw); } } return 0; } int ewmh_WMStateSkipPager( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (HAS_EWMH_INIT_SKIP_PAGER_STATE(fw) == EWMH_STATE_HAS_HINT) { return True; } return False; } return DO_SKIP_WINDOW_LIST(fw); } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE /*if (has_hint)*/ fprintf( stderr, "\t Skip_Pager %lu, %i, %i\n", has_hint, HAS_EWMH_INIT_SKIP_PAGER_STATE(fw), DO_EWMH_IGNORE_STATE_HINTS(style)); #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_SKIP_PAGER_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_SKIP_PAGER_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_SKIP_PAGER_STATE( fw, EWMH_STATE_NO_HINT); return 0; } S_SET_DO_WINDOW_LIST_SKIP(SCF(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCM(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*style), 1); SET_HAS_EWMH_INIT_SKIP_PAGER_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* I do not think we can get such client message */ int bool_arg = ev->xclient.data.l[0]; if ((bool_arg == NET_WM_STATE_TOGGLE && !DO_SKIP_WINDOW_LIST(fw)) || bool_arg == NET_WM_STATE_ADD) { } else { } } return 0; } int ewmh_WMStateSkipTaskBar( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (HAS_EWMH_INIT_SKIP_TASKBAR_STATE(fw) == EWMH_STATE_HAS_HINT) { return True; } return False; } return DO_SKIP_WINDOW_LIST(fw); } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE /*if (has_hint)*/ fprintf(stderr,"\t Skip_Taskbar %lu, %i, %i\n", has_hint, HAS_EWMH_INIT_SKIP_TASKBAR_STATE(fw), DO_EWMH_IGNORE_STATE_HINTS(style)); #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_SKIP_TASKBAR_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_SKIP_TASKBAR_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_SKIP_TASKBAR_STATE( fw, EWMH_STATE_NO_HINT); return 0; } S_SET_DO_WINDOW_LIST_SKIP(SCF(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCM(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*style), 1); SET_HAS_EWMH_INIT_SKIP_TASKBAR_STATE( fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* I do not think we can get such client message */ int bool_arg = ev->xclient.data.l[0]; if ((bool_arg == NET_WM_STATE_TOGGLE && !DO_SKIP_WINDOW_LIST(fw)) || bool_arg == NET_WM_STATE_ADD) { } else { } } return 0; } int ewmh_WMStateStaysOnTop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (fw->ewmh_hint_layer == Scr.TopLayer) { return True; } return False; } if (fw->layer >= Scr.TopLayer) { return True; } return False; } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf(stderr,"\tStaysOnTop\n"); } #endif if (!DO_EWMH_USE_STACKING_HINTS(style)) { return 0; } if (!has_hint && fw->ewmh_hint_layer == 0) { fw->ewmh_hint_layer = -1; return 0; } if (fw->ewmh_hint_layer == -1) { return 0; } fw->ewmh_hint_layer = Scr.TopLayer; SSET_LAYER(*style, Scr.TopLayer); style->flags.use_layer = 1; style->flag_mask.use_layer = 1; style->change_mask.use_layer = 1; return 0; } if (ev != NULL) { /* client message */ int cmd_arg = ev->xclient.data.l[0]; if (!DO_EWMH_USE_STACKING_HINTS(fw)) { /* if we don't pay attention to the hints, * I don't think we should honor this request also */ return 0; } if (fw->layer < Scr.TopLayer && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_ADD)) { new_layer(fw, Scr.TopLayer); } else if ( fw->layer == Scr.TopLayer && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_REMOVE)) { new_layer(fw, Scr.DefaultLayer); } /* layer < TopLayer layer == TopLayer * CMD * STATE_ADD new_layer(TOP) do nothing * STATE_TOGGLE new_layer(TOP) new_layer(DEFAULT) * STATE_REMOVE do nothing new_layer(DEFAULT) */ } return 0; } int ewmh_WMStateStaysOnBottom( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (fw->ewmh_hint_layer == Scr.BottomLayer) { return True; } return False; } if (fw->layer <= Scr.BottomLayer) { return True; } return False; } if (ev == NULL && style != NULL) { unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) fprintf(stderr,"\tStaysOnBottom\n"); #endif if (!DO_EWMH_USE_STACKING_HINTS(style)) { return 0; } if (!has_hint && fw->ewmh_hint_layer == 0) { fw->ewmh_hint_layer = -1; return 0; } if (fw->ewmh_hint_layer == -1) { return 0; } fw->ewmh_hint_layer = Scr.BottomLayer; SSET_LAYER(*style, Scr.BottomLayer); style->flags.use_layer = 1; style->flag_mask.use_layer = 1; style->change_mask.use_layer = 1; return 0; } if (ev != NULL) { /* client message */ int cmd_arg = ev->xclient.data.l[0]; if (!DO_EWMH_USE_STACKING_HINTS(fw)) { /* if we don't pay attention to the hints, * I don't think we should honor this request also */ return 0; } if ( fw->layer > Scr.BottomLayer && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_ADD)) { new_layer(fw, Scr.BottomLayer); } else if ( fw->layer == Scr.BottomLayer && (cmd_arg == NET_WM_STATE_TOGGLE || cmd_arg == NET_WM_STATE_REMOVE)) { new_layer(fw, Scr.DefaultLayer); } /* layer > BottomLayer layer == BottomLayer * CMD * STATE_ADD new_layer(BOTTOM) do nothing * STATE_TOGGLE new_layer(BOTTOM) new_layer(DEFAULT) * STATE_REMOVE do nothing new_layer(DEFAULT) */ } return 0; } int ewmh_WMStateSticky( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (ev == NULL && style == NULL) { unsigned long do_restore = any; if (do_restore) { if (HAS_EWMH_INIT_STICKY_STATE(fw) == EWMH_STATE_HAS_HINT) { return True; } return False; } return (IS_STICKY_ACROSS_PAGES(fw) && IS_STICKY_ACROSS_DESKS(fw)); } if (ev == NULL && style != NULL) { /* start sticky */ unsigned long has_hint = any; #if DEBUG_EWMH_INIT_STATE if (has_hint) { fprintf(stderr,"\t Sticky\n"); } #endif if (DO_EWMH_IGNORE_STATE_HINTS(style)) { SET_HAS_EWMH_INIT_STICKY_STATE( fw, EWMH_STATE_UNDEFINED_HINT); return 0; } if (HAS_EWMH_INIT_STICKY_STATE(fw) != EWMH_STATE_UNDEFINED_HINT) { return 0; } if (!has_hint) { SET_HAS_EWMH_INIT_STICKY_STATE( fw, EWMH_STATE_NO_HINT); return 0; } S_SET_IS_STICKY_ACROSS_PAGES(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*style), 1); SET_HAS_EWMH_INIT_STICKY_STATE(fw, EWMH_STATE_HAS_HINT); return 0; } if (ev != NULL) { /* client message */ int bool_arg = ev->xclient.data.l[0]; if ((bool_arg == NET_WM_STATE_TOGGLE && (!IS_STICKY_ACROSS_PAGES(fw) || !IS_STICKY_ACROSS_DESKS(fw))) || bool_arg == NET_WM_STATE_ADD) { execute_function_override_window( NULL, NULL, "Stick on", 0, fw); } else if ((IS_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw)) && (bool_arg == NET_WM_STATE_TOGGLE || bool_arg == NET_WM_STATE_REMOVE)) { execute_function_override_window( NULL, NULL, "Stick off", 1, fw); } } return 0; } /* * Property Notify (_NET_WM_ICON is in ewmh_icon.c, _NET_WM_*NAME are in * ewmh_name) * */ int ewmh_WMIconGeometry( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int size; CARD32 *val; /* FIXME: After a (un)slide of kicker the geometry are wrong (not * because we set the geometry just after the property notify). This * does not happen with kwin */ val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_ICON_GEOMETRY", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); if (val != NULL && size < 4 * sizeof(CARD32)) { fvwm_msg( WARN, "ewmh_WMIconGeometry", "The application window (id %#lx)\n" " \"%s\" tried to set to an icon geometry via EWMH\n" " but provided only %d of the 4 values required.\n" " fvwm is ignoring this request.\n", fw ? FW_W(fw) : 0, fw ? fw->name.name : "(none)", (int)(size / sizeof(CARD32))); fvwm_msg_report_app_and_workers(); free(val); val = NULL; } if (val == NULL) { fw->ewmh_icon_geometry.x = 0; fw->ewmh_icon_geometry.y = 0; fw->ewmh_icon_geometry.width = 0; fw->ewmh_icon_geometry.height = 0; return 0; } fw->ewmh_icon_geometry.x = val[0]; fw->ewmh_icon_geometry.y = val[1]; fw->ewmh_icon_geometry.width = val[2]; fw->ewmh_icon_geometry.height = val[3]; free(val); return 0; } /**** for animation ****/ void EWMH_GetIconGeometry(FvwmWindow *fw, rectangle *icon_rect) { if (!IS_ICON_SUPPRESSED(fw) || (fw->ewmh_icon_geometry.x == 0 && fw->ewmh_icon_geometry.y == 0 && fw->ewmh_icon_geometry.width == 0 && fw->ewmh_icon_geometry.height == 0)) { return; } icon_rect->x = fw->ewmh_icon_geometry.x; icon_rect->y = fw->ewmh_icon_geometry.y; icon_rect->width = fw->ewmh_icon_geometry.width; icon_rect->height = fw->ewmh_icon_geometry.height; return; } int ewmh_WMStrut( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int size = 0; CARD32 *val; if (ev == NULL) { fw->dyn_strut.left = fw->strut.left = 0; fw->dyn_strut.right = fw->strut.right = 0; fw->dyn_strut.top = fw->strut.top = 0; fw->dyn_strut.bottom = fw->strut.bottom = 0; } val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_STRUT", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); if (val == NULL) { return 0; } if ((val[0] > 0 || val[1] > 0 || val[2] > 0 || val[3] > 0) && (val[0] != fw->strut.left || val[1] != fw->strut.right || val[2] != fw->strut.top || val[3] != fw->strut.bottom)) { fw->strut.left = val[0]; fw->strut.right = val[1]; fw->strut.top = val[2]; fw->strut.bottom = val[3]; ewmh_ComputeAndSetWorkArea(); } if (val[0] != fw->dyn_strut.left || val[1] != fw->dyn_strut.right || val[2] != fw->dyn_strut.top || val[3] != fw->dyn_strut.bottom) { fw->dyn_strut.left = val[0]; fw->dyn_strut.right = val[1]; fw->dyn_strut.top = val[2]; fw->dyn_strut.bottom = val[3]; ewmh_HandleDynamicWorkArea(); } free(val); return 0; } Bool EWMH_ProcessClientMessage(const exec_context_t *exc) { ewmh_atom *ewmh_a = NULL; FvwmWindow *fw = exc->w.fw; XEvent *ev = exc->x.elast; if ((ewmh_a = (ewmh_atom *)ewmh_GetEwmhAtomByAtom( ev->xclient.message_type, EWMH_ATOM_LIST_CLIENT_ROOT)) != NULL) { if (ewmh_a->action != None) { ewmh_a->action(fw, ev, NULL, 0); } return True; } if ((ewmh_a = (ewmh_atom *)ewmh_GetEwmhAtomByAtom( ev->xclient.message_type, EWMH_ATOM_LIST_CLIENT_WIN)) == NULL) { return False; } if (ev->xclient.window == None) { return False; } /* these one are special: we can get it on an unamaged window */ if (StrEquals(ewmh_a->name, "_NET_MOVERESIZE_WINDOW") || StrEquals(ewmh_a->name, "_NET_RESTACK_WINDOW")) { ewmh_a->action(fw, ev, NULL, 0); return True; } if (fw == NULL) { return False; } if ((ewmh_a = (ewmh_atom *)ewmh_GetEwmhAtomByAtom( ev->xclient.message_type, EWMH_ATOM_LIST_CLIENT_WIN)) != NULL) { if (ewmh_a->action != None) { ewmh_a->action(fw, ev, NULL, 0); } return True; } return False; } void EWMH_ProcessPropertyNotify(const exec_context_t *exc) { ewmh_atom *ewmh_a = NULL; FvwmWindow *fw = exc->w.fw; XEvent *ev = exc->x.elast; if ((ewmh_a = (ewmh_atom *)ewmh_GetEwmhAtomByAtom( ev->xproperty.atom, EWMH_ATOM_LIST_PROPERTY_NOTIFY)) != NULL) { if (ewmh_a->action != None) { flush_property_notify_stop_at_event_type( ev->xproperty.atom, FW_W(fw), 0, 0); if (XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { /* Window does not exist anymore. */ return; } ewmh_a->action(fw, ev, NULL, 0); } } } fvwm-2.6.7/fvwm/repeat.c0000644000175700017570000001014412773467232012064 00000000000000/* -*-c-*- */ /* Copyright (C) 1999 Dominik Vogt */ /* 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 #include "libs/fvwmlib.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "repeat.h" #include "libs/Parse.h" /* If non-zero we are already repeating a function, so don't record the * command again. */ static int repeat_depth = 0; #if 0 typedef struct { char *start; char *end; } double_ended_string; static struct { double_ended_string string; double_ended_string old; double_ended_string builtin; double_ended_string function; double_ended_string top_function; double_ended_string module; double_ended_string menu; double_ended_string popup; double_ended_string menu_or_popup; int page_x; int page_y; int desk; FvwmWindow *fvwm_window; } last; #endif static struct { char *command_line; char *menu_name; } last = { NULL, NULL }; #if 0 char *repeat_last_function = NULL; char *repeat_last_complex_function = NULL; char *repeat_last_builtin_function = NULL; char *repeat_last_module = NULL; char *repeat_last_top_function = NULL; char *repeat_last_menu = NULL; FvwmWindow *repeat_last_fvwm_window = NULL; #endif /* Stores the contents of the data pointer internally for the repeat command. * The type of data is determined by the 'type' parameter. If this function is * called to set a string value representing an fvwm builtin function the * 'builtin' can be set to the F_... value in the function table in * functions.c. If this value is set certain functions are not recorded. * The 'depth' parameter indicates the recursion depth of the current data * pointer (i.e. the first function call has a depth of one, functions called * from within this function have depth 2 and higher, this may be applicable * to future enhancements like menus). * * TODO: [finish and update description] */ Bool set_repeat_data(void *data, repeat_t type, const func_t *builtin) { /* No history recording during startup. */ if (fFvwmInStartup) { return True; } switch(type) { case REPEAT_COMMAND: if (last.command_line == (char *)data) { /* Already stored, no need to free the data pointer. */ return False; } if (data == NULL || repeat_depth != 0) { /* Ignoring the data, must free it outside of this * call. */ return True; } if (builtin && (builtin->flags & FUNC_DONT_REPEAT)) { /* Dont' record functions that have the * FUNC_DONT_REPEAT flag set. */ return True; } if (last.command_line) { free(last.command_line); } /* Store a backup. */ last.command_line = (char *)data; /* Since we stored the pointer the caller must not free it. */ return False; case REPEAT_MENU: case REPEAT_POPUP: if (last.menu_name) { free(last.menu_name); } last.menu_name = (char *)data; /* Since we stored the pointer the caller must not free it. */ return False; case REPEAT_PAGE: case REPEAT_DESK: case REPEAT_DESK_AND_PAGE: return True; case REPEAT_FVWM_WINDOW: return True; case REPEAT_NONE: default: return True; } } void CMD_Repeat(F_CMD_ARGS) { int index; char *optlist[] = { "command", NULL }; repeat_depth++; /* Replay the backup, we don't want the repeat command recorded. */ GetNextTokenIndex(action, optlist, 0, &index); switch (index) { case 0: /* command */ default: action = last.command_line; execute_function( cond_rc, exc, action, FUNC_DONT_EXPAND_COMMAND); break; } repeat_depth--; return; } fvwm-2.6.7/fvwm/fvwm.h0000644000175700017570000007365213001406607011565 00000000000000/* -*-c-*- */ /* This module is based on Twm, but has been siginificantly modified * by Rob Nation */ /* * Copyright 1988 by Evans & Sutherland Computer Corporation, * Salt Lake City, Utah * Portions Copyright 1989 by the Massachusetts Institute of Technology * Cambridge, 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 permis- * sion notice appear in supporting documentation, and that the * names of Evans & Sutherland and M.I.T. not be used in advertising * in publicity pertaining to distribution of the software without * specific, written prior permission. * * EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- * ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR * M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- * AGES 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 FVWM_H #define FVWM_H /* ---------------------------- included header files ---------------------- */ #include #include #include #include #include "libs/PictureBase.h" #include "libs/Flocale.h" #include "libs/fvwmrect.h" #include "window_flags.h" #include "condrc.h" /* ---------------------------- global definitions ------------------------- */ #ifndef WithdrawnState #define WithdrawnState 0 #endif /* ---------------------------- global macros ------------------------------ */ /* * Fvwm trivia: There were 97 commands in the fvwm command table * when the F_CMD_ARGS macro was written. * dje 12/19/98. */ /* Macro for args passed to fvwm commands... */ #define F_CMD_ARGS \ cond_rc_t *cond_rc, const exec_context_t *exc, char *action #define F_PASS_ARGS cond_rc, exc, action #define FUNC_FLAGS_TYPE unsigned char /* access macros */ #define FW_W_FRAME(fw) ((fw)->wins.frame) #define FW_W_PARENT(fw) ((fw)->wins.parent) #define FW_W_CLIENT(fw) ((fw)->wins.client) #define FW_W(fw) FW_W_CLIENT(fw) #define FW_W_TITLE(fw) ((fw)->wins.title) #define FW_W_BUTTON(fw,i) ((fw)->wins.button_w[(i)]) #define FW_W_SIDE(fw,i) ((fw)->wins.sides[(i)]) #define FW_W_CORNER(fw,i) ((fw)->wins.corners[(i)]) #define FW_W_ICON_TITLE(fw) ((fw)->wins.icon_title_w) #define FW_W_ICON_PIXMAP(fw) ((fw)->wins.icon_pixmap_w) #define FW_W_TRANSIENTFOR(fw) ((fw)->wins.transientfor) /* ---------------------------- forward declarations ----------------------- */ struct size_borders; struct exec_context_t; /* definition in screen.h */ struct FvwmDecor; /* ---------------------------- type definitions --------------------------- */ /* This structure carries information about the initial window state and * placement. This information is gathered at various places: the (re)capture * code, AddToWindow(), HandleMapRequestRaised(), ewmh_events.c and others. * * initial_state * The initial window state. By default it carries the value DontCareState. * Other states can be set if * - an icon is recaptured or restarted with session management * - the StartIconic style is set * - GNOME, EWMH, foobar hints demand that the icon starts iconic * The final value is calculated in HandleMapRequestRaised(). * * do_override_ppos * This flag is used in PlaceWindow(). If it is set, the position requested * by the program is ignored unconditionally. This is used during the * initial capture and later recapture operations. * * is_iconified_by_parent * Preserves the information if the window is a transient window that was * iconified along with its transientfor window. Set when the window is * recaptured and used in HandleMapRequestRaised() to set the according * window state flag. Deleted afterwards. * * is_menu * Set in menus.c or in the recapture code if the new window is a tear off * menu. Such windows get special treatment in AddWindow() and events.c. * * is_recapture * Set for the initial capture and later recaptures. * * default_icon_x/y * The icon position that was requested by the application in the icon * position hint. May be overridden by a style (0/0 then). Set in * HandleMapRequestRaised() and used in the icon placement code. * * initial_icon_x/y * The icon position that is forced during a restart with SM. If set it * overrides all other methods of icon placement. Set by session.c and used * in the icon placement code. * * use_initial_icon_xy * If set, the initial_icon_x/y values are used. Other wise they are * ignored. */ typedef struct { long initial_state; struct { unsigned do_override_ppos : 1; unsigned is_iconified_by_parent : 1; unsigned is_menu : 1; unsigned is_recapture : 1; unsigned use_initial_icon_xy : 1; } flags; int initial_icon_x; int initial_icon_y; int default_icon_x; int default_icon_y; } initial_window_options_t; /* For 1 style statement, there can be any number of IconBoxes. The name list points at the first one in the chain. */ typedef struct icon_boxes_struct { struct icon_boxes_struct *next; /* next icon_boxes or zero */ unsigned int use_count; int IconBox[4]; /* x/y x/y for iconbox */ int IconScreen; /* Xinerama screen */ short IconGrid[2]; /* x incr, y incr */ char IconSign[4]; /* because of -0, need to save */ unsigned is_orphan : 1; unsigned IconFlags : 3; /* some bits */ /* IconFill only takes 3 bits. Defaults are top, left, vert co-ord * first eg: t l = 0,0,0; l t = 0,0,1; b r = 1,1,0 */ #define ICONFILLBOT (1<<0) #define ICONFILLRGT (1<<1) #define ICONFILLHRZ (1<<2) } icon_boxes; typedef struct { Pixel fore; Pixel back; } ColorPair; typedef struct { Pixel fore; Pixel back; Pixel hilight; Pixel shadow; } color_quad; typedef struct { int left; int right; int top; int bottom; } ewmh_strut; typedef struct { /* common flags (former flags in bits 0-12) */ unsigned is_sticky_across_pages : 1; unsigned is_sticky_across_desks : 1; unsigned has_icon_font : 1; unsigned has_no_border : 1; unsigned has_window_font : 1; unsigned title_dir : 2; unsigned user_states : 32; /* static flags that do not change dynamically after the window has * been created */ struct { unsigned do_circulate_skip : 1; unsigned do_circulate_skip_icon : 1; unsigned do_circulate_skip_shaded : 1; unsigned do_ewmh_donate_icon : 1; unsigned do_ewmh_donate_mini_icon : 1; unsigned do_ewmh_ignore_state_hints : 1; unsigned do_ewmh_ignore_strut_hints : 1; unsigned do_ewmh_mini_icon_override : 1; unsigned do_ewmh_use_stacking_hints : 1; unsigned do_ewmh_ignore_window_type : 1; unsigned do_iconify_window_groups : 1; unsigned do_ignore_icon_boxes : 1; unsigned do_ignore_restack : 1; unsigned do_use_window_group_hint : 1; unsigned do_lower_transient : 1; unsigned do_not_show_on_map : 1; unsigned do_raise_transient : 1; unsigned do_resize_opaque : 1; unsigned do_shrink_windowshade : 1; unsigned do_stack_transient_parent : 1; unsigned do_window_list_skip : 1; unsigned ewmh_maximize_mode : 2; /* see ewmh.h */ unsigned has_depressable_border : 1; unsigned has_mwm_border : 1; unsigned has_mwm_buttons : 1; unsigned has_mwm_override : 1; unsigned has_no_icon_title : 1; unsigned has_override_size : 1; unsigned has_stippled_title : 1; unsigned has_stippled_icon_title : 1; /* default has to be 0, therefore no_, not in macros */ unsigned has_no_sticky_stippled_title : 1; unsigned has_no_sticky_stippled_icon_title : 1; unsigned icon_override : 2; #define NO_ACTIVE_ICON_OVERRIDE 0 #define ICON_OVERRIDE 1 #define NO_ICON_OVERRIDE 2 #define ICON_OVERRIDE_MASK 0x3 unsigned is_bottom_title_rotated : 1; unsigned is_fixed : 1; unsigned is_fixed_ppos : 1; unsigned is_uniconifiable : 1; unsigned is_unmaximizable : 1; unsigned is_unclosable : 1; unsigned is_maximize_fixed_size_disallowed : 1; unsigned is_icon_sticky_across_pages : 1; unsigned is_icon_sticky_across_desks : 1; unsigned is_icon_suppressed : 1; unsigned is_left_title_rotated_cw : 1; /* cw = clock wise */ unsigned is_lenient : 1; unsigned is_size_fixed : 1; unsigned is_psize_fixed : 1; unsigned is_right_title_rotated_cw : 1; unsigned is_top_title_rotated : 1; unsigned use_icon_position_hint : 1; unsigned use_indexed_window_name : 1; unsigned use_indexed_icon_name : 1; #define WINDOWSHADE_LAZY 0 #define WINDOWSHADE_ALWAYS_LAZY 1 #define WINDOWSHADE_BUSY 2 #define WINDOWSHADE_LAZY_MASK 0x3 unsigned windowshade_laziness : 2; unsigned use_title_decor_rotation : 1; focus_policy_t focus_policy; } s; } common_flags_t; typedef struct { common_flags_t common; #define CR_MOTION_METHOD_AUTO 0 #define CR_MOTION_METHOD_USE_GRAV 1 #define CR_MOTION_METHOD_STATIC_GRAV 2 #define CR_MOTION_METHOD_MASK 0x3 unsigned cr_motion_method : 2; unsigned was_cr_motion_method_detected : 1; unsigned does_wm_delete_window : 1; unsigned does_wm_take_focus : 1; unsigned do_force_next_cr : 1; unsigned do_force_next_pn : 1; unsigned do_iconify_after_map : 1; unsigned do_disable_constrain_size_fullscreen : 1; /* Reuse this struct, don't free it, when destroying/recapturing * window. */ unsigned do_reuse_destroyed : 1; /* Does it have resize handles? */ unsigned has_handles : 1; /* Icon change is pending */ unsigned has_icon_changed : 1; /* Is this decorated with title */ unsigned has_title : 1; /* wm_normal_hints update is pending? */ unsigned has_new_wm_normal_hints : 1; /* ChangeDecor was used for window */ unsigned is_decor_changed : 1; /* Sent an XUnmapWindow for iconifying, but didn't receive an * UnmapNotify yet.*/ unsigned is_iconify_pending : 1; /* window had the focus when the desk was switched. set if the window * was mapped and got focused but the focus change was not announced * to the modules yet. */ unsigned is_focused_on_other_desk : 1; unsigned is_focus_change_broadcast_pending : 1; /* is the window fully visible */ unsigned is_fully_visible : 1; /* is it an icon now? */ unsigned is_iconified : 1; /* To prevent iconified transients in a parent icon from counting for * Next */ unsigned is_iconified_by_parent : 1; /* is the pointer over the icon? */ unsigned is_icon_entered : 1; unsigned is_icon_font_loaded : 1; /* has the icon been moved by the user? */ unsigned is_icon_moved : 1; /* is the icon window supplied by the app? */ unsigned is_icon_ours : 1; /* is the icon shaped? */ unsigned is_icon_shaped : 1; /* was the icon unmapped, even though the window is still iconified * (Transients) */ unsigned is_icon_unmapped : 1; /* temporary flag used in stack.c */ unsigned is_in_transient_subtree : 1; /* is it mapped? */ unsigned is_mapped : 1; /* Sent an XMapWindow, but didn't receive a MapNotify yet.*/ unsigned is_map_pending : 1; /* is the window maximized? */ unsigned is_maximized : 1; /* Set if the client changes its WM_NAME. The source of twm contains * an explanation why we need this information. */ unsigned is_name_changed : 1; /* is the window partially visible */ unsigned is_partially_visible : 1; /* is the icon pixmap ours to free? */ unsigned is_pixmap_ours : 1; /* fvwm places the window itself */ unsigned is_placed_by_fvwm : 1; /* mark window to be destroyed after last complex func has finished. */ unsigned is_scheduled_for_destroy : 1; /* mark window to be raised after function execution. */ unsigned is_scheduled_for_raise : 1; unsigned is_size_inc_set : 1; unsigned is_style_deleted : 1; /* the window is a torn out fvwm menu */ unsigned is_tear_off_menu : 1; /* is it a transient window? */ unsigned is_transient : 1; unsigned is_window_drawn_once : 1; /* To prevent double move in MoveViewport.*/ unsigned is_viewport_moved : 1; unsigned is_window_being_moved_opaque : 1; unsigned is_window_font_loaded : 1; unsigned is_window_shaded : 1; unsigned used_title_dir_for_shading : 1; unsigned shaded_dir : 3; unsigned using_default_icon_font : 1; unsigned using_default_window_font : 1; #define ICON_HINT_NEVER 0 #define ICON_HINT_ONCE 1 #define ICON_HINT_MULTIPLE 2 unsigned was_icon_hint_provided : 2; unsigned was_icon_name_provided : 1; unsigned was_never_drawn : 1; unsigned has_ewmh_wm_name : 1; unsigned has_ewmh_wm_icon_name : 1; #define EWMH_NO_ICON 0 /* the application does not provide an ewmh icon */ #define EWMH_TRUE_ICON 1 /* the application does provide an ewmh icon */ #define EWMH_FVWM_ICON 2 /* the ewmh icon has been set by fvwm */ unsigned has_ewmh_wm_icon_hint : 2; /* says if the app have an ewmh icon of acceptable size for a mini * icon in its list of icons */ unsigned has_ewmh_mini_icon : 1; unsigned has_ewmh_wm_pid : 1; /* the ewmh icon is used as icon pixmap */ unsigned use_ewmh_icon : 1; unsigned is_ewmh_modal : 1; unsigned is_ewmh_fullscreen : 1; #define EWMH_STATE_UNDEFINED_HINT 0 #define EWMH_STATE_NO_HINT 1 #define EWMH_STATE_HAS_HINT 2 unsigned has_ewmh_init_fullscreen_state : 2; unsigned has_ewmh_init_hidden_state : 2; unsigned has_ewmh_init_maxhoriz_state : 2; unsigned has_ewmh_init_maxvert_state : 2; unsigned has_ewmh_init_modal_state : 2; unsigned has_ewmh_init_shaded_state : 2; unsigned has_ewmh_init_skip_pager_state : 2; unsigned has_ewmh_init_skip_taskbar_state : 2; unsigned has_ewmh_init_sticky_state : 2; unsigned has_ewmh_init_wm_desktop : 2; } window_flags; /* Actions allowed by modules. */ typedef struct action_flags { unsigned is_movable : 1; unsigned is_deletable : 1; unsigned is_destroyable : 1; unsigned is_closable : 1; unsigned is_maximizable : 1; unsigned is_resizable : 1; unsigned is_iconifiable : 1; } action_flags; /* Window name data structure for window conditions: a list of lists of names to match, the boolean operation on the matches being an AND of ORs. */ struct namelist /* matches to names in this list are ORed */ { char *name; struct namelist *next; }; struct name_condition /* matches to namelists in this list are ANDed, after possibly inverting each */ { Bool invert; struct namelist *namelist; struct name_condition *next; }; /* Window mask for Circulate and Direction functions */ typedef struct WindowConditionMask { struct { unsigned do_accept_focus : 1; unsigned do_check_desk : 1; unsigned do_check_screen : 1; unsigned do_check_cond_desk : 1; unsigned do_check_desk_and_global_page : 1; unsigned do_check_desk_and_page : 1; unsigned do_check_global_page : 1; unsigned do_check_overlapped : 1; unsigned do_check_page : 1; unsigned do_not_check_screen : 1; unsigned needs_current_desk : 1; unsigned needs_current_desk_and_global_page : 1; unsigned needs_current_desk_and_page : 1; unsigned needs_current_global_page : 1; unsigned needs_current_page : 1; #define NEEDS_ANY 0 #define NEEDS_TRUE 1 #define NEEDS_FALSE 2 unsigned needs_focus : 2; unsigned needs_overlapped : 2; unsigned needs_pointer : 2; unsigned needs_same_layer : 1; unsigned use_circulate_hit : 1; unsigned use_circulate_hit_icon : 1; unsigned use_circulate_hit_shaded : 1; unsigned use_do_accept_focus : 1; } my_flags; window_flags flags; window_flags flag_mask; struct name_condition *name_condition; int layer; int desk; int screen; int placed_by_button_mask; int placed_by_button_set_mask; } WindowConditionMask; typedef struct pl_penalty_struct { float normal; float ontop; float icon; float sticky; float below; float strut; } pl_penalty_struct; typedef struct pl_percent_penalty_struct { int p99; int p95; int p85; int p75; } pl_percent_penalty_struct; /* only style.c and add_window.c are allowed to access this struct! */ typedef struct style_flags { common_flags_t common; unsigned do_decorate_transient : 1; /* old placement flags */ #define PLACE_DUMB 0x0 #define PLACE_SMART 0x1 #define PLACE_CLEVER 0x2 #define PLACE_CLEVERNESS_MASK 0x3 #define PLACE_RANDOM 0x4 /* new placements value, try to get a minimal backward compatibility * with the old flags: * Dumb+Active = Manual, * Dumb+Random = Cascade, * Smart+Random = TileCascade, * Smart+Active = TileManual, * Random+Smart+Clever = MINOVERLAP which is the original Clever * placement code, * Active+Smart+Clever = MINOVERLAPPERCENT which is the "new" Clever * placement code and was the original Clever placement code. Now the * original placement code said: * Active/Random+Dumb+Clever = Active/Random+Dumb (with Dumb Clever is * ignored); These represent the not use value: 0x2=Active+Dumb+Clever, * 0x6=Random+Dumb+Clever */ #define PLACE_MANUAL 0x0 #define PLACE_TILEMANUAL 0x1 #define PLACE_MANUAL_B 0x2 #define PLACE_MINOVERLAPPERCENT 0x3 #define PLACE_CASCADE 0x4 #define PLACE_TILECASCADE 0x5 #define PLACE_CASCADE_B 0x6 #define PLACE_MINOVERLAP 0x7 #define PLACE_POSITION 0x8 #define PLACE_MASK 0xF unsigned placement_mode : 4; unsigned ewmh_placement_mode : 2; /* see ewmh.h */ #define WS_CR_MOTION_METHOD_AUTO CR_MOTION_METHOD_AUTO #define WS_CR_MOTION_METHOD_USE_GRAV CR_MOTION_METHOD_USE_GRAV #define WS_CR_MOTION_METHOD_STATIC_GRAV CR_MOTION_METHOD_STATIC_GRAV #define WS_CR_MOTION_METHOD_MASK CR_MOTION_METHOD_MASK unsigned ws_cr_motion_method : 2; unsigned do_save_under : 1; unsigned do_start_iconic : 1; unsigned do_start_lowered : 1; unsigned do_start_shaded : 1; unsigned start_shaded_dir : 3; unsigned has_border_width : 1; unsigned has_color_back : 1; unsigned has_color_fore : 1; unsigned has_color_back_hi : 1; unsigned has_color_fore_hi : 1; unsigned has_decor : 1; unsigned has_edge_delay_ms_move : 1; unsigned has_edge_delay_ms_resize : 1; unsigned has_edge_resistance_move : 1; unsigned has_edge_resistance_xinerama_move : 1; unsigned has_handle_width : 1; unsigned has_icon : 1; unsigned has_icon_boxes : 1; unsigned has_icon_size_limits : 1; unsigned has_min_window_size : 1; unsigned has_max_window_size : 1; unsigned has_icon_background_padding : 1; unsigned has_icon_background_relief : 1; unsigned has_icon_title_relief : 1; unsigned has_window_shade_steps : 1; unsigned has_mini_icon : 1; unsigned has_mwm_decor : 1; unsigned has_mwm_functions : 1; unsigned has_no_handles : 1; unsigned has_no_title : 1; unsigned has_ol_decor : 1; unsigned has_snap_grid : 1; unsigned has_snap_attraction : 1; #if 0 unsigned has_condition_mask : 1; #endif unsigned is_button_disabled : NUMBER_OF_TITLE_BUTTONS; unsigned is_unmanaged : 1; #define BACKINGSTORE_DEFAULT 0 #define BACKINGSTORE_ON 1 #define BACKINGSTORE_OFF 2 #define BACKINGSTORE_MASK 0x3 unsigned use_backing_store : 2; unsigned use_parent_relative : 1; unsigned use_colorset : 1; unsigned use_colorset_hi : 1; unsigned use_border_colorset : 1; unsigned use_border_colorset_hi : 1; unsigned use_icon_title_colorset : 1; unsigned use_icon_title_colorset_hi : 1; unsigned use_icon_background_colorset : 1; unsigned use_layer : 1; unsigned use_no_pposition : 1; unsigned use_no_usposition : 1; unsigned use_no_transient_pposition : 1; unsigned use_no_transient_usposition : 1; unsigned use_start_on_desk : 1; unsigned use_start_on_page_for_transient : 1; unsigned use_start_on_screen : 1; unsigned manual_placement_honors_starts_on_page : 1; unsigned um_placement_honors_starts_on_page : 1; unsigned capture_honors_starts_on_page : 1; unsigned recapture_honors_starts_on_page : 1; unsigned has_placement_penalty : 1; unsigned has_placement_percentage_penalty : 1; unsigned has_placement_position_string : 1; unsigned has_initial_map_command_string : 1; unsigned has_title_format_string : 1; unsigned has_icon_title_format_string : 1; } style_flags; typedef struct style_id_t { char *name; XID window_id; struct { unsigned has_name:1; unsigned has_window_id:1; } flags; } style_id_t; typedef struct snap_attraction_t { /* attractiveness of window edges */ int proximity; /* mode of snap attraction */ int mode; /* mode flags to do bit manipulation */ enum { SNAP_NONE = 0x00, SNAP_WINDOWS = 0x01, SNAP_ICONS = 0x02, SNAP_SAME = 0x04, SNAP_SCREEN = 0x08, SNAP_SCREEN_WINDOWS = 0x10, SNAP_SCREEN_ICONS = 0x20, SNAP_SCREEN_ALL = 0x40, } types; } snap_attraction_t; /* only style.c and add_window.c are allowed to access this struct! */ typedef struct window_style { struct window_style *next; struct window_style *prev; style_id_t id; #if 0 WindowConditionMask *condition_mask; #endif char *icon_name; char *mini_icon_name; char *decor_name; unsigned char min_icon_width; unsigned char max_icon_width; unsigned char min_icon_height; unsigned char max_icon_height; #define ICON_RESIZE_TYPE_NONE 0x0 #define ICON_RESIZE_TYPE_STRETCHED 0x1 #define ICON_RESIZE_TYPE_ADJUSTED 0x2 #define ICON_RESIZE_TYPE_SHRUNK 0x3 #define ICON_RESIZE_TYPE_MASK 0x3 unsigned icon_resize_type : 2; unsigned char icon_background_padding; signed char icon_background_relief; signed char icon_title_relief; char *icon_font; char *window_font; char *fore_color_name; char *back_color_name; char *fore_color_name_hi; char *back_color_name_hi; int colorset; int colorset_hi; int border_colorset; int border_colorset_hi; int icon_title_colorset; int icon_title_colorset_hi; int icon_background_colorset; short border_width; /* resize handle width */ short handle_width; int layer; int start_desk; int start_page_x; int start_page_y; int start_screen; int min_window_width; int min_window_height; int max_window_width; int max_window_height; int shade_anim_steps; #if 1 /*!!!*/ snap_attraction_t snap_attraction; /* snap grid size */ int snap_grid_x; int snap_grid_y; int edge_delay_ms_move; int edge_delay_ms_resize; int edge_resistance_move; int edge_resistance_xinerama_move; #endif icon_boxes *icon_boxes; float norm_placement_penalty; pl_penalty_struct pl_penalty; pl_percent_penalty_struct pl_percent_penalty; char *pl_position_string; char *initial_map_command_string; char *title_format_string; char *icon_title_format_string; style_flags flags; style_flags flag_default; style_flags flag_mask; style_flags change_mask; unsigned has_style_changed : 1; unsigned has_title_format_string : 1; unsigned has_icon_title_format_string : 1; } window_style; typedef struct window_g { rectangle frame; /* absolute geometry when not maximized */ rectangle normal; /* maximized window geometry */ rectangle max; /* defect between maximized geometry before and after * constraining size. */ size_rect max_defect; /* original delta between normalized and maximized window, * used to keep unmaximized window at same screen position */ position max_offset; } window_g; /* for each window that is on the display, one of these structures * is allocated and linked into a list */ typedef struct FvwmWindow { /* name of the window */ FlocaleNameString name; /* name of the icon */ FlocaleNameString icon_name; char *visible_name; char *visible_icon_name; /* if non-null: Use this instead of any other names for matching styles */ char *style_name; int name_count; int icon_name_count; /* next fvwm window */ struct FvwmWindow *next; /* prev fvwm window */ struct FvwmWindow *prev; /* next (lower) fvwm window in stacking order*/ struct FvwmWindow *stack_next; /* prev (higher) fvwm window in stacking order */ struct FvwmWindow *stack_prev; /* border width before reparenting */ struct { /* the frame window */ Window frame; /* It looks like you HAVE to reparent the app window into a * window whose size = app window, or else you can't keep xv * and matlab happy at the same time! */ Window parent; /* the child window */ Window client; /* the title bar window and button windows */ Window title; Window button_w[NUMBER_OF_TITLE_BUTTONS]; /* sides of the border */ Window sides[4]; /* corner pieces */ Window corners[4]; /* icon title window */ Window icon_title_w; /* icon picture window */ Window icon_pixmap_w; Window transientfor; } wins; window_flags flags; struct { unsigned buttons_drawn : NUMBER_OF_TITLE_BUTTONS; unsigned buttons_lit : NUMBER_OF_TITLE_BUTTONS; unsigned buttons_inverted : NUMBER_OF_TITLE_BUTTONS; unsigned buttons_toggled : NUMBER_OF_TITLE_BUTTONS; unsigned parts_drawn : 12; unsigned parts_lit : 12; unsigned parts_inverted : 12; } decor_state; int nr_left_buttons; int nr_right_buttons; #define BUTTON_INDEX(b) \ (((b) == 0) ? (NUMBER_OF_TITLE_BUTTONS - 1) : ((b) - 1)) struct FvwmDecor *decor; /* is this a shaped window */ int wShaped; Pixmap title_background_pixmap; /* Note: if the type of this variable is changed, do update the * CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h too! */ short boundary_width; short unshaped_boundary_width; short corner_width; short visual_corner_width; /* title font */ FlocaleFont *title_font; /* /Y coordinate to draw the title name */ short title_text_offset; short title_length; /* Note: if the type of this variable is changed, do update the * CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h and too! */ short title_thickness; rotation_t title_text_rotation; struct { /* geometry of the icon picture window */ rectangle picture_w_g; /* geometry of the icon title window */ rectangle title_w_g; /* width of the text in the icon title */ int title_text_width; } icon_g; short icon_border_width; /* Drawable depth for the icon */ int iconDepth; /* pixmap for the icon */ Pixmap iconPixmap; /* pixmap for the icon mask */ Pixmap icon_maskPixmap; Pixmap icon_alphaPixmap; int icon_nalloc_pixels; Pixel *icon_alloc_pixels; int icon_no_limit; FlocaleFont *icon_font; /* some parts of the window attributes */ struct { int backing_store; int border_width; int depth; int bit_gravity; unsigned is_bit_gravity_stored : 1; Visual *visual; Colormap colormap; } attr_backup; /* normal hints */ XSizeHints hints; struct { int width_inc; int height_inc; } orig_hints; /* WM hints */ XWMHints *wmhints; XClassHint class; /* Tells which desktop this window is on */ /* Note: if the type of this variable is changed, do update the * CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h and too! */ int Desk; /* Where (if at all) was it focused */ int FocusDesk; /* Desk to deiconify to, for StubbornIcons */ int DeIconifyDesk; char *mini_pixmap_file; FvwmPicture *mini_icon; char *icon_bitmap_file; struct window_g g; long *mwm_hints; int ol_hints; int functions; /* Colormap windows property */ Window *cmap_windows; /* Should generally be 0 */ int number_cmap_windows; color_quad colors; color_quad hicolors; color_quad border_colors; color_quad border_hicolors; int cs; int cs_hi; int border_cs; int border_cs_hi; int icon_title_cs; int icon_title_cs_hi; int icon_background_cs; unsigned long buttons; /* zero or more iconboxes */ icon_boxes *IconBoxes; int default_layer; /* Note: if the type of this variable is changed, do update the * CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h and too! */ int layer; unsigned char min_icon_width; unsigned char max_icon_width; unsigned char min_icon_height; unsigned char max_icon_height; unsigned short icon_resize_type; unsigned char icon_background_padding; char icon_background_relief; char icon_title_relief; int min_window_width; int min_window_height; int max_window_width; int max_window_height; int shade_anim_steps; unsigned char grabbed_buttons; #if 1 /*!!!*/ snap_attraction_t snap_attraction; /* snap grid size */ int snap_grid_x; int snap_grid_y; int edge_delay_ms_move; int edge_delay_ms_resize; int edge_resistance_move; int edge_resistance_xinerama_move; #endif #define FM_NO_INPUT 0 #define FM_PASSIVE 1 #define FM_LOCALLY_ACTIVE 2 #define FM_GLOBALLY_ACTIVE 3 unsigned char focus_model; pl_penalty_struct pl_penalty; pl_percent_penalty_struct pl_percent_penalty; unsigned char placed_by_button; #define EWMH_WINDOW_TYPE_NONE_ID 0 #define EWMH_WINDOW_TYPE_DESKTOP_ID 1 #define EWMH_WINDOW_TYPE_DIALOG_ID 2 #define EWMH_WINDOW_TYPE_DOCK_ID 3 #define EWMH_WINDOW_TYPE_MENU_ID 4 #define EWMH_WINDOW_TYPE_NORMAL_ID 5 #define EWMH_WINDOW_TYPE_TOOLBAR_ID 6 #define EWMH_WINDOW_TYPE_NOTIFICATION_ID 7 /* Note: if the type of this variable is changed, do update the * CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h and too! */ int ewmh_window_type; /* icon geometry */ rectangle ewmh_icon_geometry; /* for computing the working area */ ewmh_strut strut; /* for the dynamic working area */ ewmh_strut dyn_strut; /* memories for the icons we set on the */ int ewmh_icon_height; /* _NET_WM_ICON */ int ewmh_icon_width; int ewmh_mini_icon_height; int ewmh_mini_icon_width; /* memory for the initial _NET_WM_STATE */ /* Note: if the type of this variable is changed, do update the * CONFIGARGSNEW macro in module_interface.c, libs/vpacket.h and too! */ int ewmh_hint_layer; int ewmh_normal_layer; /* for restoring non ewmh layer */ /* memory for the initial _NET_WM_STATE */ unsigned long ewmh_hint_desktop; /* For the purposes of restoring attributes before/after a window goes * into fullscreen. */ struct { struct window_g g; int is_iconified; int is_shaded; int was_maximized; } fullscreen; /* multi purpose scratch structure */ struct { void *p; int i; } scratch; } FvwmWindow; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void SetMWM_INFO(Window window); void fvmm_deinstall_signals(void); #endif /* FVWM_H */ fvwm-2.6.7/fvwm/functions.c0000644000175700017570000010006113001406607012572 00000000000000/* -*-c-*- */ /* 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 */ /* This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* * fvwm built-in functions and complex functions */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/Event.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "execcontext.h" #include "functions.h" #include "commands.h" #include "functable.h" #include "events.h" #include "modconf.h" #include "module_list.h" #include "misc.h" #include "screen.h" #include "repeat.h" #include "expand.h" #include "menus.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct FunctionItem { struct FvwmFunction *func; /* the function this item is in */ struct FunctionItem *next_item; /* next function item */ char condition; /* the character string displayed on * left*/ char *action; /* action to be performed */ short type; /* type of built in function */ FUNC_FLAGS_TYPE flags; } FunctionItem; typedef struct FvwmFunction { struct FvwmFunction *next_func; /* next in list of root menus */ FunctionItem *first_item; /* first item in function */ FunctionItem *last_item; /* last item in function */ char *name; /* function name */ int use_depth; } FvwmFunction; /* Types of events for the FUNCTION builtin */ typedef enum { CF_IMMEDIATE = 'i', CF_MOTION = 'm', CF_HOLD = 'h', CF_CLICK = 'c', CF_DOUBLE_CLICK = 'd', CF_TIMEOUT = '-' } cfunc_action_t; /* ---------------------------- forward declarations ----------------------- */ static void execute_complex_function( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, Bool *desperate, Bool has_ref_window_moved); /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static int __context_has_window( const exec_context_t *exc, execute_flags_t flags) { if (exc->w.fw != NULL) { return 1; } else if ((flags & FUNC_ALLOW_UNMANAGED) && exc->w.w != None) { return 1; } return 0; } /* * Defer the execution of a function to the next button press if the context is * C_ROOT * * Inputs: * cursor - the cursor to display while waiting */ static Bool DeferExecution( exec_context_changes_t *ret_ecc, exec_context_change_mask_t *ret_mask, cursor_t cursor, int trigger_evtype, int do_allow_unmanaged) { int done; int finished = 0; int just_waiting_for_finish = 0; Window dummy; Window original_w; static XEvent e; Window w; int wcontext; FvwmWindow *fw; int FinishEvent; fw = ret_ecc->w.fw; w = ret_ecc->w.w; original_w = w; wcontext = ret_ecc->w.wcontext; FinishEvent = ((fw != NULL) ? ButtonRelease : ButtonPress); if (wcontext == C_UNMANAGED && do_allow_unmanaged) { return False; } if (wcontext != C_ROOT && wcontext != C_NO_CONTEXT && fw != NULL && wcontext != C_EWMH_DESKTOP) { if (FinishEvent == ButtonPress || (FinishEvent == ButtonRelease && trigger_evtype != ButtonPress)) { return False; } else if (FinishEvent == ButtonRelease) { /* We are only waiting until the user releases the * button. Do not change the cursor. */ cursor = CRS_NONE; just_waiting_for_finish = 1; } } if (Scr.flags.are_functions_silent) { return True; } if (!GrabEm(cursor, GRAB_NORMAL)) { XBell(dpy, 0); return True; } MyXGrabKeyboard(dpy); while (!finished) { done = 0; /* block until there is an event */ FMaskEvent( dpy, ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyPressMask | VisibilityChangeMask | ButtonMotionMask | PointerMotionMask /* | EnterWindowMask | LeaveWindowMask*/, &e); if (e.type == KeyPress) { KeySym keysym = XLookupKeysym(&e.xkey, 0); if (keysym == XK_Escape) { ret_ecc->x.etrigger = &e; *ret_mask |= ECC_ETRIGGER; UngrabEm(GRAB_NORMAL); MyXUngrabKeyboard(dpy); return True; } Keyboard_shortcuts(&e, NULL, NULL, NULL, FinishEvent); } if (e.type == FinishEvent) { finished = 1; } switch (e.type) { case KeyPress: case ButtonPress: if (e.type != FinishEvent) { original_w = e.xany.window; } done = 1; break; case ButtonRelease: done = 1; break; default: break; } if (!done) { dispatch_event(&e); } } MyXUngrabKeyboard(dpy); UngrabEm(GRAB_NORMAL); if (just_waiting_for_finish) { return False; } w = e.xany.window; ret_ecc->x.etrigger = &e; *ret_mask |= ECC_ETRIGGER | ECC_W | ECC_WCONTEXT; if ((w == Scr.Root || w == Scr.NoFocusWin) && e.xbutton.subwindow != None) { w = e.xbutton.subwindow; e.xany.window = w; } if (w == Scr.Root || IS_EWMH_DESKTOP(w)) { ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } *ret_mask |= ECC_FW; if (XFindContext(dpy, w, FvwmContext, (caddr_t *)&fw) == XCNOENT) { ret_ecc->w.fw = NULL; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return (True); } if (w == FW_W_PARENT(fw)) { w = FW_W(fw); } if (original_w == FW_W_PARENT(fw)) { original_w = FW_W(fw); } /* this ugly mess attempts to ensure that the release and press * are in the same window. */ if (w != original_w && original_w != Scr.Root && original_w != None && original_w != Scr.NoFocusWin && !IS_EWMH_DESKTOP(original_w)) { if (w != FW_W_FRAME(fw) || original_w != FW_W(fw)) { ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } } if (IS_EWMH_DESKTOP(FW_W(fw))) { ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } wcontext = GetContext(NULL, fw, &e, &dummy); ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; return False; } /* ** do binary search on func list */ static int func_comp(const void *a, const void *b) { return (strcmp((char *)a, ((func_t *)b)->keyword)); } static const func_t *find_builtin_function(char *func) { static int nfuncs = 0; func_t *ret_func; char *temp; char *s; if (!func || func[0] == 0) { return NULL; } /* since a lot of lines in a typical rc are probably menu/func * continues: */ if (func[0]=='+' || (func[0] == ' ' && func[1] == '+')) { return &(func_table[0]); } temp = safestrdup(func); for (s = temp; *s != 0; s++) { if (isupper(*s)) { *s = tolower(*s); } } if (nfuncs == 0) { for ( ; (func_table[nfuncs]).action != NULL; nfuncs++) { /* nothing to do here */ } } ret_func = (func_t *)bsearch( temp, func_table, nfuncs, sizeof(func_t), func_comp); free(temp); return ret_func; } static void __execute_function( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, char *args[], Bool has_ref_window_moved) { static int func_depth = 0; cond_rc_t *func_rc = NULL; cond_rc_t dummy_rc; Window w; int j; char *function; char *taction; char *trash; char *trash2; char *expaction = NULL; char *arguments[11]; const func_t *bif; Bool set_silent; Bool must_free_string = False; Bool must_free_function = False; Bool do_keep_rc = False; /* needed to be able to avoid resize to use moved windows for base */ extern Window PressedW; Window dummy_w; if (!action) { return; } /* ignore whitespace at the beginning of all config lines */ action = SkipSpaces(action, NULL, 0); if (!action || action[0] == 0) { /* impossibly short command */ return; } if (action[0] == '#') { /* a comment */ return; } func_depth++; if (func_depth > MAX_FUNCTION_DEPTH) { fvwm_msg( ERR, "__execute_function", "Function '%s' called with a depth of %i, " "stopping function execution!", action, func_depth); func_depth--; return; } if (args) { for (j = 0; j < 11; j++) { arguments[j] = args[j]; } } else { for (j = 0; j < 11; j++) { arguments[j] = NULL; } } if (exc->w.fw == NULL || IS_EWMH_DESKTOP(FW_W(exc->w.fw))) { if (exec_flags & FUNC_IS_UNMANAGED) { w = exc->w.w; } else { w = Scr.Root; } } else { FvwmWindow *tw; w = GetSubwindowFromEvent(dpy, exc->x.elast); if (w == None) { w = exc->x.elast->xany.window; } tw = NULL; if (w != None) { if (XFindContext( dpy, w, FvwmContext, (caddr_t *)&tw) == XCNOENT) { tw = NULL; } } if (w == None || tw != exc->w.fw) { w = FW_W(exc->w.fw); } } set_silent = False; if (action[0] == '-') { exec_flags |= FUNC_DONT_EXPAND_COMMAND; action++; } taction = action; /* parse prefixes */ trash = PeekToken(taction, &trash2); while (trash) { if (StrEquals(trash, PRE_SILENT)) { if (Scr.flags.are_functions_silent == 0) { set_silent = 1; Scr.flags.are_functions_silent = 1; } taction = trash2; trash = PeekToken(taction, &trash2); } else if (StrEquals(trash, PRE_KEEPRC)) { do_keep_rc = True; taction = trash2; trash = PeekToken(taction, &trash2); } else { break; } } if (taction == NULL) { if (set_silent) { Scr.flags.are_functions_silent = 0; } func_depth--; return; } if (cond_rc == NULL || do_keep_rc == True) { condrc_init(&dummy_rc); func_rc = &dummy_rc; } else { func_rc = cond_rc; } GetNextToken(taction, &function); if (function) { char *tmp = function; function = expand_vars( function, arguments, False, False, func_rc, exc); free(tmp); } if (function && function[0] != '*') { #if 1 /* DV: with this piece of code it is impossible to have a * complex function with embedded whitespace that begins with a * builtin function name, e.g. a function "echo hello". */ /* DV: ... and without it some of the complex functions will * fail */ char *tmp = function; while (*tmp && !isspace(*tmp)) { tmp++; } *tmp = 0; #endif bif = find_builtin_function(function); must_free_function = True; } else { bif = NULL; if (function) { free(function); } function = ""; } if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor && (!bif || !(bif->flags & FUNC_DECOR))) { fvwm_msg( ERR, "__execute_function", "Command can not be added to a decor; executing" " command now: '%s'", action); } if (!(exec_flags & FUNC_DONT_EXPAND_COMMAND)) { expaction = expand_vars( taction, arguments, (bif) ? !!(bif->flags & FUNC_ADD_TO) : False, (taction[0] == '*'), func_rc, exc); if (func_depth <= 1) { must_free_string = set_repeat_data( expaction, REPEAT_COMMAND, bif); } else { must_free_string = True; } } else { expaction = taction; } #ifdef FVWM_COMMAND_LOG fvwm_msg(INFO, "LOG", "%c: %s", (char)exc->type, expaction); #endif /* Note: the module config command, "*" can not be handled by the * regular command table because there is no required white space after * the asterisk. */ if (expaction[0] == '*') { if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) { fvwm_msg( WARN, "__execute_function", "Command can not be added to a decor;" " executing command now: '%s'", expaction); } /* process a module config command */ ModuleConfig(expaction); } else { const exec_context_t *exc2; exec_context_changes_t ecc; exec_context_change_mask_t mask; mask = (w != exc->w.w) ? ECC_W : 0; ecc.w.fw = exc->w.fw; ecc.w.w = w; ecc.w.wcontext = exc->w.wcontext; if (bif && bif->func_t != F_FUNCTION) { char *runaction; Bool rc = False; runaction = SkipNTokens(expaction, 1); if ((bif->flags & FUNC_NEEDS_WINDOW) && !(exec_flags & FUNC_DONT_DEFER)) { rc = DeferExecution( &ecc, &mask, bif->cursor, exc->x.elast->type, (bif->flags & FUNC_ALLOW_UNMANAGED)); } else if ((bif->flags & FUNC_NEEDS_WINDOW) && !__context_has_window( exc, bif->flags & FUNC_ALLOW_UNMANAGED)) { /* no context window and not allowed to defer, * skip command */ rc = True; } if (rc == False) { exc2 = exc_clone_context(exc, &ecc, mask); if (has_ref_window_moved && (bif->func_t == F_ANIMATED_MOVE || bif->func_t == F_MOVE || bif->func_t == F_RESIZE || bif->func_t == F_RESIZEMOVE || bif->func_t == F_RESIZE_MAXIMIZE || bif->func_t == F_RESIZEMOVE_MAXIMIZE)) { dummy_w = PressedW; PressedW = None; bif->action(func_rc, exc2, runaction); PressedW = dummy_w; } else { bif->action(func_rc, exc2, runaction); } exc_destroy_context(exc2); } } else { Bool desperate = 1; char *runaction; if (bif) { /* strip "function" command */ runaction = SkipNTokens(expaction, 1); } else { runaction = expaction; } exc2 = exc_clone_context(exc, &ecc, mask); execute_complex_function( func_rc, exc2, runaction, &desperate, has_ref_window_moved); if (!bif && desperate) { if (executeModuleDesperate( func_rc, exc, runaction) == NULL && *function != 0 && !set_silent) { fvwm_msg( ERR, "__execute_function", "No such command '%s'", function); } } exc_destroy_context(exc2); } } if (set_silent) { Scr.flags.are_functions_silent = 0; } if (cond_rc != NULL) { cond_rc->break_levels = func_rc->break_levels; } if (must_free_string) { free(expaction); } if (must_free_function) { free(function); } func_depth--; return; } /* find_complex_function expects a token as the input. Make sure you have used * GetNextToken before passing a function name to remove quotes */ static FvwmFunction *find_complex_function(const char *function_name) { FvwmFunction *func; if (function_name == NULL || *function_name == 0) { return NULL; } func = Scr.functions; while (func != NULL) { if (func->name != NULL) { if (strcasecmp(function_name, func->name) == 0) { return func; } } func = func->next_func; } return NULL; } /* * Builtin which determines if the button press was a click or double click... * Waits Scr.ClickTime, or until it is evident that the user is not * clicking, but is moving the cursor */ static cfunc_action_t CheckActionType( int x, int y, XEvent *d, Bool may_time_out, Bool is_button_pressed, int *ret_button) { int xcurrent,ycurrent,total = 0; Time t0; int dist; Bool do_sleep = False; xcurrent = x; ycurrent = y; t0 = fev_get_evtime(); dist = Scr.MoveThreshold; while ((total < Scr.ClickTime && fev_get_evtime() - t0 < Scr.ClickTime) || !may_time_out) { if (!(x - xcurrent <= dist && xcurrent - x <= dist && y - ycurrent <= dist && ycurrent - y <= dist)) { return (is_button_pressed) ? CF_MOTION : CF_TIMEOUT; } if (do_sleep) { usleep(20000); } else { usleep(1); do_sleep = 1; } total += 20; if (FCheckMaskEvent( dpy, ButtonReleaseMask|ButtonMotionMask| PointerMotionMask|ButtonPressMask|ExposureMask, d)) { do_sleep = 0; switch (d->xany.type) { case ButtonRelease: *ret_button = d->xbutton.button; return CF_CLICK; case MotionNotify: if (d->xmotion.same_screen == False) { break; } if ((d->xmotion.state & DEFAULT_ALL_BUTTONS_MASK) || !is_button_pressed) { xcurrent = d->xmotion.x_root; ycurrent = d->xmotion.y_root; } else { return CF_CLICK; } break; case ButtonPress: *ret_button = d->xbutton.button; if (may_time_out) { is_button_pressed = True; } break; case Expose: /* must handle expose here so that raising a * window with "I" works */ dispatch_event(d); break; default: /* can't happen */ break; } } } return (is_button_pressed) ? CF_HOLD : CF_TIMEOUT; } static void __run_complex_function_items( cond_rc_t *cond_rc, char cond, FvwmFunction *func, const exec_context_t *exc, char *args[], Bool has_ref_window_moved) { char c; FunctionItem *fi; int x0, y0, x, y; extern Window PressedW; if (!(!has_ref_window_moved && PressedW && XTranslateCoordinates( dpy, PressedW , Scr.Root, 0, 0, &x0, &y0, &JunkChild))) { x0 = y0 = 0; } for (fi = func->first_item; fi != NULL && cond_rc->break_levels == 0; ) { /* make lower case */ c = fi->condition; if (isupper(c)) { c = tolower(c); } if (c == cond) { __execute_function( cond_rc, exc, fi->action, FUNC_DONT_DEFER, args, has_ref_window_moved); if (!has_ref_window_moved && PressedW && XTranslateCoordinates( dpy, PressedW , Scr.Root, 0, 0, &x, &y, &JunkChild)) { has_ref_window_moved =(x != x0 || y != y0); } } fi = fi->next_item; } return; } static void __cf_cleanup( int *depth, char **arguments, cond_rc_t *cond_rc) { int i; (*depth)--; if (!(*depth)) { Scr.flags.is_executing_complex_function = 0; } for (i = 0; i < 11; i++) { if (arguments[i] != NULL) { free(arguments[i]); } } if (cond_rc->break_levels > 0) { cond_rc->break_levels--; } return; } static void execute_complex_function( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, Bool *desperate, Bool has_ref_window_moved) { cond_rc_t tmp_rc; cfunc_action_t type = CF_MOTION; char c; FunctionItem *fi; Bool Persist = False; Bool HaveDoubleClick = False; Bool HaveHold = False; Bool NeedsTarget = False; Bool ImmediateNeedsTarget = False; int do_allow_unmanaged = FUNC_ALLOW_UNMANAGED; int do_allow_unmanaged_immediate = FUNC_ALLOW_UNMANAGED; char *arguments[11], *taction; char *func_name; int x, y ,i; XEvent d; FvwmFunction *func; static int depth = 0; const exec_context_t *exc2; exec_context_changes_t ecc; exec_context_change_mask_t mask; int trigger_evtype; int button; XEvent *te; if (cond_rc == NULL) { condrc_init(&tmp_rc); cond_rc = &tmp_rc; } cond_rc->rc = COND_RC_OK; mask = 0; d.type = 0; ecc.w.fw = exc->w.fw; ecc.w.w = exc->w.w; ecc.w.wcontext = exc->w.wcontext; /* find_complex_function expects a token, not just a quoted string */ func_name = PeekToken(action, &taction); if (!func_name) { return; } func = find_complex_function(func_name); if (func == NULL) { if (*desperate == 0) { fvwm_msg( ERR, "ComplexFunction", "No such function %s", action); } return; } if (!depth) { Scr.flags.is_executing_complex_function = 1; } depth++; *desperate = 0; /* duplicate the whole argument list for use as '$*' */ if (taction) { arguments[0] = safestrdup(taction); /* strip trailing newline */ if (arguments[0][0]) { int l= strlen(arguments[0]); if (arguments[0][l - 1] == '\n') { arguments[0][l - 1] = 0; } } /* Get the argument list */ for (i = 1; i < 11; i++) { taction = GetNextToken(taction, &arguments[i]); } } else { for (i = 0; i < 11; i++) { arguments[i] = NULL; } } /* In case we want to perform an action on a button press, we * need to fool other routines */ te = exc->x.elast; if (te->type == ButtonPress) { trigger_evtype = ButtonRelease; } else { trigger_evtype = te->type; } func->use_depth++; for (fi = func->first_item; fi != NULL; fi = fi->next_item) { if (fi->flags & FUNC_NEEDS_WINDOW) { NeedsTarget = True; do_allow_unmanaged &= fi->flags; if (fi->condition == CF_IMMEDIATE) { do_allow_unmanaged_immediate &= fi->flags; ImmediateNeedsTarget = True; break; } } } if (ImmediateNeedsTarget) { if (DeferExecution( &ecc, &mask, CRS_SELECT, trigger_evtype, do_allow_unmanaged_immediate)) { func->use_depth--; __cf_cleanup(&depth, arguments, cond_rc); return; } NeedsTarget = False; } else { ecc.w.w = (ecc.w.fw) ? FW_W_FRAME(ecc.w.fw) : None; mask |= ECC_W; } /* we have to grab buttons before executing immediate actions because * these actions can move the window away from the pointer so that a * button release would go to the application below. */ if (!GrabEm(CRS_NONE, GRAB_NORMAL)) { func->use_depth--; fvwm_msg( ERR, "ComplexFunction", "Grab failed in function %s," " unable to execute immediate action", action); __cf_cleanup(&depth, arguments, cond_rc); return; } exc2 = exc_clone_context(exc, &ecc, mask); __run_complex_function_items( cond_rc, CF_IMMEDIATE, func, exc2, arguments, has_ref_window_moved); exc_destroy_context(exc2); for (fi = func->first_item; fi != NULL && cond_rc->break_levels == 0; fi = fi->next_item) { /* c is already lowercase here */ c = fi->condition; switch (c) { case CF_IMMEDIATE: break; case CF_DOUBLE_CLICK: HaveDoubleClick = True; Persist = True; break; case CF_HOLD: HaveHold = True; Persist = True; break; default: Persist = True; break; } } if (!Persist || cond_rc->break_levels != 0) { func->use_depth--; __cf_cleanup(&depth, arguments, cond_rc); UngrabEm(GRAB_NORMAL); return; } /* Only defer execution if there is a possibility of needing * a window to operate on */ if (NeedsTarget) { if (DeferExecution( &ecc, &mask, CRS_SELECT, trigger_evtype, do_allow_unmanaged)) { func->use_depth--; __cf_cleanup(&depth, arguments, cond_rc); UngrabEm(GRAB_NORMAL); return; } } te = (mask & ECC_ETRIGGER) ? ecc.x.etrigger : exc->x.elast; switch (te->xany.type) { case ButtonPress: case ButtonRelease: x = te->xbutton.x_root; y = te->xbutton.y_root; button = te->xbutton.button; /* Take the click which started this fuction off the * Event queue. -DDN- Dan D Niles dniles@iname.com */ FCheckMaskEvent(dpy, ButtonPressMask, &d); break; default: if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ x = 0; y = 0; } button = 0; break; } /* Wait and see if we have a click, or a move */ /* wait forever, see if the user releases the button */ type = CheckActionType(x, y, &d, HaveHold, True, &button); if (type == CF_CLICK) { int button2; /* If it was a click, wait to see if its a double click */ if (HaveDoubleClick) { type = CheckActionType( x, y, &d, True, False, &button2); switch (type) { case CF_HOLD: case CF_MOTION: case CF_CLICK: if (button == button2) { type = CF_DOUBLE_CLICK; } else { type = CF_CLICK; } break; case CF_TIMEOUT: type = CF_CLICK; break; default: /* can't happen */ break; } } } else if (type == CF_TIMEOUT) { type = CF_HOLD; } /* some functions operate on button release instead of presses. These * gets really weird for complex functions ... */ if (d.type == ButtonPress) { d.type = ButtonRelease; if (d.xbutton.button > 0 && d.xbutton.button <= NUMBER_OF_MOUSE_BUTTONS) { d.xbutton.state &= (~(Button1Mask >> (d.xbutton.button - 1))); } } #ifdef BUGGY_CODE /* domivogt (11-Apr-2000): The pointer ***must not*** be ungrabbed * here. If it is, any window that the mouse enters during the * function will receive MotionNotify events with a button held down! * The results are unpredictable. E.g. rxvt interprets the * ButtonMotion as user input to select text. */ UngrabEm(GRAB_NORMAL); #endif fev_set_evpos(&d, x, y); fev_fake_event(&d); ecc.x.etrigger = &d; ecc.w.w = (ecc.w.fw) ? FW_W_FRAME(ecc.w.fw) : None; mask |= ECC_ETRIGGER | ECC_W; exc2 = exc_clone_context(exc, &ecc, mask); __run_complex_function_items( cond_rc, type, func, exc2, arguments, has_ref_window_moved); exc_destroy_context(exc2); /* This is the right place to ungrab the pointer (see comment above). */ func->use_depth--; __cf_cleanup(&depth, arguments, cond_rc); UngrabEm(GRAB_NORMAL); return; } /* * create a new FvwmFunction */ static FvwmFunction *NewFvwmFunction(const char *name) { FvwmFunction *tmp; tmp = (FvwmFunction *)safemalloc(sizeof(FvwmFunction)); tmp->next_func = Scr.functions; tmp->first_item = NULL; tmp->last_item = NULL; tmp->name = stripcpy(name); tmp->use_depth = 0; Scr.functions = tmp; return tmp; } static void DestroyFunction(FvwmFunction *func) { FunctionItem *fi,*tmp2; FvwmFunction *tmp, *prev; if (func == NULL) { return; } tmp = Scr.functions; prev = NULL; while (tmp && tmp != func) { prev = tmp; tmp = tmp->next_func; } if (tmp != func) { return; } if (func->use_depth != 0) { fvwm_msg( ERR,"DestroyFunction", "Function %s is in use (depth %d)", func->name, func->use_depth); return; } if (prev == NULL) { Scr.functions = func->next_func; } else { prev->next_func = func->next_func; } free(func->name); fi = func->first_item; while (fi != NULL) { tmp2 = fi->next_item; if (fi->action != NULL) { free(fi->action); } free(fi); fi = tmp2; } free(func); return; } /* ---------------------------- interface functions ------------------------ */ Bool functions_is_complex_function(const char *function_name) { if (find_complex_function(function_name) != NULL) { return True; } return False; } void execute_function( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags) { __execute_function(cond_rc, exc, action, exec_flags, NULL, False); return; } void execute_function_override_wcontext( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, int wcontext) { const exec_context_t *exc2; exec_context_changes_t ecc; ecc.w.wcontext = wcontext; exc2 = exc_clone_context(exc, &ecc, ECC_WCONTEXT); execute_function(cond_rc, exc2, action, exec_flags); exc_destroy_context(exc2); return; } void execute_function_override_window( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, FvwmWindow *fw) { const exec_context_t *exc2; exec_context_changes_t ecc; ecc.w.fw = fw; if (fw != NULL) { ecc.w.w = FW_W(fw); ecc.w.wcontext = C_WINDOW; exec_flags |= FUNC_DONT_DEFER; } else { ecc.w.w = None; ecc.w.wcontext = C_ROOT; } if (exc != NULL) { exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); } else { ecc.type = EXCT_NULL; exc2 = exc_create_context( &ecc, ECC_TYPE | ECC_FW | ECC_W | ECC_WCONTEXT); } execute_function(cond_rc, exc2, action, exec_flags); exc_destroy_context(exc2); return; } void find_func_t(char *action, short *func_t, unsigned char *flags) { int j, len = 0; char *endtok = action; Bool matched; int mlen; if (action) { while (*endtok && !isspace((unsigned char)*endtok)) { ++endtok; } len = endtok - action; j=0; matched = False; while (!matched && (mlen = strlen(func_table[j].keyword)) > 0) { if (mlen == len && strncasecmp(action,func_table[j].keyword,mlen) == 0) { matched=True; /* found key word */ if (func_t) { *func_t = func_table[j].func_t; } if (flags) { *flags = func_table[j].flags; } return; } else { j++; } } /* No clue what the function is. Just return "BEEP" */ } if (func_t) { *func_t = F_BEEP; } if (flags) { *flags = 0; } return; } /* * add an item to a FvwmFunction * * Inputs: * func - pointer to the FvwmFunction to add the item * action - the definition string from the config line */ void AddToFunction(FvwmFunction *func, char *action) { FunctionItem *tmp; char *token = NULL; char condition; token = PeekToken(action, &action); if (!token) return; condition = token[0]; if (isupper(condition)) condition = tolower(condition); if (condition != CF_IMMEDIATE && condition != CF_MOTION && condition != CF_HOLD && condition != CF_CLICK && condition != CF_DOUBLE_CLICK) { fvwm_msg( ERR, "AddToFunction", "Got '%s' instead of a valid function specifier", token); return; } if (token[0] != 0 && token[1] != 0 && (find_builtin_function(token) || find_complex_function(token))) { fvwm_msg( WARN, "AddToFunction", "Got the command or function name '%s' instead of a" " function specifier. This may indicate a syntax" " error in the configuration file. Using %c as the" " specifier.", token, token[0]); } if (!action) { return; } while (isspace(*action)) { action++; } if (*action == 0) { return; } tmp = (FunctionItem *)safemalloc(sizeof(FunctionItem)); tmp->next_item = NULL; tmp->func = func; if (func->first_item == NULL) { func->first_item = tmp; func->last_item = tmp; } else { func->last_item->next_item = tmp; func->last_item = tmp; } tmp->condition = condition; tmp->action = stripcpy(action); find_func_t(tmp->action, NULL, &(tmp->flags)); return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_DestroyFunc(F_CMD_ARGS) { FvwmFunction *func; char *token; token = PeekToken(action, NULL); if (!token) { return; } func = find_complex_function(token); if (!func) { return; } if (Scr.last_added_item.type == ADDED_FUNCTION) { set_last_added_item(ADDED_NONE, NULL); } DestroyFunction(func); return; } void CMD_AddToFunc(F_CMD_ARGS) { FvwmFunction *func; char *token; action = GetNextToken(action,&token); if (!token) { return; } func = find_complex_function(token); if (func == NULL) { func = NewFvwmFunction(token); } /* Set + state to last function */ set_last_added_item(ADDED_FUNCTION, func); free(token); AddToFunction(func, action); return; } void CMD_Plus(F_CMD_ARGS) { if (Scr.last_added_item.type == ADDED_MENU) { add_another_menu_item(action); } else if (Scr.last_added_item.type == ADDED_FUNCTION) { AddToFunction(Scr.last_added_item.item, action); } else if (Scr.last_added_item.type == ADDED_DECOR) { FvwmDecor *tmp = &Scr.DefaultDecor; for ( ; tmp && tmp != Scr.last_added_item.item; tmp = tmp->next) { /* nothing to do here */ } if (!tmp) { return; } AddToDecor(F_PASS_ARGS, tmp); } return; } void CMD_EchoFuncDefinition(F_CMD_ARGS) { FvwmFunction *func; const func_t *bif; FunctionItem *fi; char *token; GetNextToken(action, &token); if (!token) { fvwm_msg(ERR, "EchoFuncDefinition", "Missing argument"); return; } bif = find_builtin_function(token); if (bif != NULL) { fvwm_msg( INFO, "EchoFuncDefinition", "function '%s' is a built in command", token); free(token); return; } func = find_complex_function(token); if (!func) { fvwm_msg( INFO, "EchoFuncDefinition", "function '%s' not defined", token); free(token); return; } fvwm_msg( INFO, "EchoFuncDefinition", "definition of function '%s':", token); for (fi = func->first_item; fi != NULL; fi = fi->next_item) { fvwm_msg( INFO, "EchoFuncDefinition", " %c %s", fi->condition, (fi->action == 0) ? "(null)" : fi->action); } fvwm_msg(INFO, "EchoFuncDefinition", "end of definition"); free(token); return; } /* dummy commands */ void CMD_Title(F_CMD_ARGS) { } void CMD_TearMenuOff(F_CMD_ARGS) { } void CMD_KeepRc(F_CMD_ARGS) { } void CMD_Silent(F_CMD_ARGS) { } void CMD_Function(F_CMD_ARGS) { } fvwm-2.6.7/fvwm/menus.h0000644000175700017570000000372412773467232011746 00000000000000/* -*-c-*- */ #ifndef _MENUS_ #define _MENUS_ #define MENU_IS_LEFT 0x01 #define MENU_IS_RIGHT 0x02 #define MENU_IS_UP 0x04 #define MENU_IS_DOWN 0x08 /* * MISCELLANEOUS MENU STUFF */ #define IS_MENU_RETURN(x) \ ((x)==MENU_DONE || (x)==MENU_ABORTED || (x)==MENU_SUBMENU_TORN_OFF) struct MenuRoot; struct MenuStyle; struct MenuReturn; struct MenuParameters; struct MenuOptions; struct MenuItem; struct MenuRepaintTransparentParameters; /* * EXPORTED FUNCTIONS */ void menus_init(void); struct MenuRoot *menus_find_menu(char *name); void menus_remove_style_from_menus(struct MenuStyle *ms); struct MenuRoot *FollowMenuContinuations( struct MenuRoot *mr, struct MenuRoot **pmrPrior); struct MenuRoot *NewMenuRoot(char *name); void AddToMenu(struct MenuRoot *, char *, char *, Bool, Bool, Bool); void menu_enter_tear_off_menu(const exec_context_t *exc); void menu_close_tear_off_menu(FvwmWindow *fw); Bool menu_redraw_transparent_tear_off_menu(FvwmWindow *fw, Bool pr_only); void do_menu(struct MenuParameters *pmp, struct MenuReturn *pret); char *get_menu_options( char *action, Window w, FvwmWindow *fw, XEvent *e, struct MenuRoot *mr, struct MenuItem *mi, struct MenuOptions *pops); Bool DestroyMenu( struct MenuRoot *mr, Bool do_recreate, Bool is_command_request); void add_another_menu_item(char *action); void change_mr_menu_style(struct MenuRoot *mr, char *stylename); void UpdateAllMenuStyles(void); void UpdateMenuColorset(int cset); void SetMenuCursor(Cursor cursor); void update_transparent_menu_bg( struct MenuRepaintTransparentParameters *prtm, int current_x, int current_y, int step_x, int step_y, int end_x, int end_y); void repaint_transparent_menu( struct MenuRepaintTransparentParameters *prtmp, Bool first, int x, int y, int end_x, int end_y, Bool is_bg_set); Bool menu_expose(XEvent *event, FvwmWindow *fw); int menu_binding(Display *dpy, binding_t type, int button, KeySym keysym, int context, int modifier, char *action, char *menuStyle); #endif /* _MENUS_ */ fvwm-2.6.7/fvwm/cursor.c0000644000175700017570000002622712773467232012132 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/ColorUtils.h" #include "libs/Cursor.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "libs/PictureImageLoader.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "cursor.h" #include "menus.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Cursor cursors[CRS_MAX]; static const unsigned int default_cursors[CRS_MAX] = { None, XC_top_left_corner, /* CRS_POSITION */ XC_top_left_arrow, /* CRS_TITLE */ XC_top_left_arrow, /* CRS_DEFAULT */ XC_hand2, /* CRS_SYS */ XC_fleur, /* CRS_MOVE */ XC_sizing, /* CRS_RESIZE */ XC_watch, /* CRS_WAIT */ XC_top_left_arrow, /* CRS_MENU */ XC_crosshair, /* CRS_SELECT */ XC_pirate, /* CRS_DESTROY */ XC_top_side, /* CRS_TOP */ XC_right_side, /* CRS_RIGHT */ XC_bottom_side, /* CRS_BOTTOM */ XC_left_side, /* CRS_LEFT */ XC_top_left_corner, /* CRS_TOP_LEFT */ XC_top_right_corner, /* CRS_TOP_RIGHT */ XC_bottom_left_corner, /* CRS_BOTTOM_LEFT */ XC_bottom_right_corner, /* CRS_BOTTOM_RIGHT */ XC_top_side, /* CRS_TOP_EDGE */ XC_right_side, /* CRS_RIGHT_EDGE */ XC_bottom_side, /* CRS_BOTTOM_EDGE */ XC_left_side, /* CRS_LEFT_EDGE */ XC_left_ptr, /* CRS_ROOT */ XC_plus /* CRS_STROKE */ }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void SafeDefineCursor(Window w, Cursor cursor) { if (w) { XDefineCursor(dpy,w,cursor); } return; } /* ---------------------------- interface functions ------------------------ */ /* CreateCursors - Loads fvwm cursors */ Cursor *CreateCursors(Display *dpy) { int i; /* define cursors */ cursors[0] = None; for (i = 1; i < CRS_MAX; i++) { cursors[i] = XCreateFontCursor(dpy, default_cursors[i]); } return cursors; } /* ---------------------------- builtin commands --------------------------- */ void CMD_CursorStyle(F_CMD_ARGS) { char *cname=NULL; char *newcursor=NULL; char *errpos = NULL; char *fore = NULL; char *back = NULL; XColor colors[2]; int index; int nc; int i; int my_nc; FvwmWindow *fw2; Cursor cursor; cursor = 0; cname = PeekToken(action, &action); if (!cname) { fvwm_msg(ERR, "CursorStyle", "Bad cursor style"); return; } if (StrEquals("POSITION", cname)) { index = CRS_POSITION; } else if (StrEquals("DEFAULT", cname)) { index = CRS_DEFAULT; } else if (StrEquals("SYS", cname)) { index = CRS_SYS; } else if (StrEquals("TITLE", cname)) { index = CRS_TITLE; } else if (StrEquals("MOVE", cname)) { index = CRS_MOVE; } else if (StrEquals("RESIZE", cname)) { index = CRS_RESIZE; } else if (StrEquals("MENU", cname)) { index = CRS_MENU; } else if (StrEquals("WAIT", cname)) { index = CRS_WAIT; } else if (StrEquals("SELECT", cname)) { index = CRS_SELECT; } else if (StrEquals("DESTROY", cname)) { index = CRS_DESTROY; } else if (StrEquals("LEFT", cname)) { index = CRS_LEFT; } else if (StrEquals("RIGHT", cname)) { index = CRS_RIGHT; } else if (StrEquals("TOP", cname)) { index = CRS_TOP; } else if (StrEquals("BOTTOM", cname)) { index = CRS_BOTTOM; } else if (StrEquals("TOP_LEFT", cname)) { index = CRS_TOP_LEFT; } else if (StrEquals("TOP_RIGHT", cname)) { index = CRS_TOP_RIGHT; } else if (StrEquals("BOTTOM_LEFT", cname)) { index = CRS_BOTTOM_LEFT; } else if (StrEquals("BOTTOM_RIGHT", cname)) { index = CRS_BOTTOM_RIGHT; } else if (StrEquals("LEFT_EDGE", cname)) { index = CRS_LEFT_EDGE; } else if (StrEquals("RIGHT_EDGE", cname)) { index = CRS_RIGHT_EDGE; } else if (StrEquals("TOP_EDGE", cname)) { index = CRS_TOP_EDGE; } else if (StrEquals("BOTTOM_EDGE", cname)) { index = CRS_BOTTOM_EDGE; } else if (StrEquals("ROOT", cname)) { index = CRS_ROOT; } else if (StrEquals("STROKE", cname)) { index = CRS_STROKE; } else { fvwm_msg(ERR, "CursorStyle", "Unknown cursor name %s", cname); return; } cname = 0; /* check if the cursor is given by X11 name */ action = GetNextToken(action, &newcursor); if (newcursor) { my_nc = fvwmCursorNameToIndex(newcursor); } else { my_nc = default_cursors[index]; } if (my_nc == -1) { nc = strtol(newcursor, &errpos, 10); if (errpos && *errpos == '\0') { my_nc = 0; } } else { nc = my_nc; } if (my_nc > -1) { /* newcursor was a number or the name of a X11 cursor */ if ((nc < 0) || (nc >= XC_num_glyphs) || ((nc % 2) != 0)) { fvwm_msg( ERR, "CursorStyle", "Bad cursor number %s", newcursor); free(newcursor); return; } cursor = XCreateFontCursor(dpy, nc); } else { /* newcursor was not a number neither a X11 cursor name */ if ( StrEquals("none", newcursor) || StrEquals("tiny", newcursor)) { XColor nccol; XSetForeground( dpy, Scr.MonoGC, (tolower(*newcursor) == 'n') ? 0 : 1); XFillRectangle( dpy, Scr.ScratchMonoPixmap, Scr.MonoGC, 0, 0, 1, 1); cursor = XCreatePixmapCursor( dpy, Scr.ScratchMonoPixmap, Scr.ScratchMonoPixmap, &nccol, &nccol, 0, 0); } else { char *path; char *tmp; int hotspot[2]; hotspot[0] = -1; hotspot[1] = -1; path = PictureFindImageFile(newcursor, NULL, R_OK); if (!path) { fvwm_msg( ERR, "CursorStyle", "Cursor %s not found", newcursor); free(newcursor); return; } if (GetIntegerArguments(action, &tmp, hotspot, 2) == 2) { action = tmp; } cursor = PImageLoadCursorFromFile( dpy, Scr.Root, path, hotspot[0], hotspot[1]); free(path); } } if (!cursor) { fvwm_msg( ERR, "CursorStyle", "Cannot load cursor: %s", newcursor); free(newcursor); return; } free(newcursor); newcursor = 0; /* replace the cursor defn */ if (Scr.FvwmCursors[index]) { XFreeCursor(dpy, Scr.FvwmCursors[index]); } Scr.FvwmCursors[index] = cursor; /* look for optional color arguments */ action = GetNextToken(action, &fore); action = GetNextToken(action, &back); if (fore && back) { colors[0].pixel = GetColor(fore); colors[1].pixel = GetColor(back); XQueryColors (dpy, Pcmap, colors, 2); XRecolorCursor( dpy, Scr.FvwmCursors[index], &(colors[0]), &(colors[1])); } if (fore) { free(fore); } if (back) { free(back); } /* redefine all the windows using cursors */ for (fw2 = Scr.FvwmRoot.next; fw2; fw2 = fw2->next) { if (!HAS_HANDLES(fw2)) { /* Ignore windows without handles */ continue; } for (i = 0; i < 4; i++) { SafeDefineCursor( FW_W_CORNER(fw2, i), Scr.FvwmCursors[CRS_TOP_LEFT + i]); SafeDefineCursor( FW_W_SIDE(fw2, i), Scr.FvwmCursors[CRS_TOP + i]); } for (i = 0; i / 2 < Scr.nr_left_buttons; i += 2) { SafeDefineCursor( FW_W_BUTTON(fw2, i), Scr.FvwmCursors[CRS_SYS]); } for (i = 1; i / 2 < Scr.nr_right_buttons; i += 2) { SafeDefineCursor( FW_W_BUTTON(fw2, i), Scr.FvwmCursors[CRS_SYS]); } SafeDefineCursor(FW_W_TITLE(fw2), Scr.FvwmCursors[CRS_TITLE]); if (index == CRS_DEFAULT) { SafeDefineCursor( FW_W_FRAME(fw2), Scr.FvwmCursors[CRS_DEFAULT]); SafeDefineCursor( FW_W_PARENT(fw2), Scr.FvwmCursors[CRS_DEFAULT]); if (IS_ICONIFIED(fw2)) { if (!HAS_NO_ICON_TITLE(fw2)) { SafeDefineCursor( FW_W_ICON_TITLE(fw2), Scr.FvwmCursors[CRS_DEFAULT]); } if (FW_W_ICON_PIXMAP(fw2) != None) { SafeDefineCursor( FW_W_ICON_PIXMAP(fw2), Scr.FvwmCursors[CRS_DEFAULT]); } } } } /* Do the menus for good measure */ SetMenuCursor(Scr.FvwmCursors[CRS_MENU]); SafeDefineCursor(Scr.PanFrameTop.win, Scr.FvwmCursors[CRS_TOP_EDGE]); SafeDefineCursor( Scr.PanFrameBottom.win, Scr.FvwmCursors[CRS_BOTTOM_EDGE]); SafeDefineCursor(Scr.PanFrameLeft.win, Scr.FvwmCursors[CRS_LEFT_EDGE]); SafeDefineCursor( Scr.PanFrameRight.win, Scr.FvwmCursors[CRS_RIGHT_EDGE]); /* migo (04/Nov/1999): don't annoy users which use xsetroot */ if (index == CRS_ROOT) { SafeDefineCursor(Scr.Root, Scr.FvwmCursors[CRS_ROOT]); } return; } /* Defines in which cases fvwm "grab" the cursor during execution of certain * functions. */ void CMD_BusyCursor(F_CMD_ARGS) { char *option = NULL; char *optstring = NULL; char *args = NULL; int flag = -1; char *optlist[] = { "read", "wait", "modulesynchronous", "dynamicmenu", "*", NULL }; while (action && *action != '\0') { action = GetQuotedString( action, &optstring, ",", NULL, NULL, NULL); if (!optstring) { break; } args = GetNextToken(optstring, &option); if (!option) { free(optstring); break; } flag = ParseToggleArgument(args, NULL, -1, True); free(optstring); if (flag == -1) { fvwm_msg(ERR, "BusyCursor", "error in boolean specification"); free(option); break; } switch (GetTokenIndex(option, optlist, 0, NULL)) { case 0: /* read */ if (flag) { Scr.BusyCursor |= BUSY_READ; } else { Scr.BusyCursor &= ~BUSY_READ; } break; case 1: /* wait */ if (flag) { Scr.BusyCursor |= BUSY_WAIT; } else { Scr.BusyCursor &= ~BUSY_WAIT; } break; case 2: /* modulesynchronous */ if (flag) { Scr.BusyCursor |= BUSY_MODULESYNCHRONOUS; } else { Scr.BusyCursor &= ~BUSY_MODULESYNCHRONOUS; } break; case 3: /* dynamicmenu */ if (flag) { Scr.BusyCursor |= BUSY_DYNAMICMENU; } else { Scr.BusyCursor &= ~BUSY_DYNAMICMENU; } break; case 4: /* "*" */ if (flag) { Scr.BusyCursor |= BUSY_ALL; } else { Scr.BusyCursor &= ~(BUSY_ALL); } break; default: fvwm_msg(ERR, "BusyCursor", "unknown context '%s'", option); break; } free(option); } return; } fvwm-2.6.7/fvwm/module_interface.h0000644000175700017570000000273212773467232014122 00000000000000/* -*-c-*- */ #ifndef FVWM_MODULE_INTERFACE_H #define FVWM_MODULE_INTERFACE_H #include "libs/Module.h" struct fmodule; struct fmodule_input; /* Packet sending functions */ void BroadcastPacket(unsigned long event_type, unsigned long num_datum, ...); void BroadcastConfig(unsigned long event_type, const FvwmWindow *t); void BroadcastName( unsigned long event_type, unsigned long data1, unsigned long data2, unsigned long data3, const char *name); void BroadcastWindowIconNames(FvwmWindow *t, Bool window, Bool icon); void BroadcastFvwmPicture( unsigned long event_type, unsigned long data1, unsigned long data2, unsigned long data3, FvwmPicture *picture, char *name); void BroadcastPropertyChange( unsigned long argument, unsigned long data1, unsigned long data2, char *string); void BroadcastColorset(int n); void BroadcastConfigInfoString(char *string); void broadcast_xinerama_state(void); void broadcast_ignore_modifiers(void); void SendPacket( struct fmodule *module, unsigned long event_type, unsigned long num_datum, ...); void SendConfig( struct fmodule *module, unsigned long event_type, const FvwmWindow *t); void SendName( struct fmodule *module, unsigned long event_type, unsigned long data1, unsigned long data2, unsigned long data3, const char *name); /* command queue - module input */ void module_input_enqueue(struct fmodule_input *input); void module_input_execute(struct fmodule_input *input); void ExecuteCommandQueue(void); #endif /* MODULE_INTERFACE_H */ fvwm-2.6.7/fvwm/colorset.h0000644000175700017570000000143212773467232012443 00000000000000/* -*-c-*- */ #ifndef COLORSET_H #define COLORSET_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void parse_colorset(int n, char *line); void cleanup_colorsets(void); void alloc_colorset(int n); void update_root_transparent_colorset(Atom prop); #endif /* COLORSET_H */ fvwm-2.6.7/fvwm/modconf.c0000644000175700017570000002125213001406607012213 00000000000000/* -*-c-*- */ /* 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 */ /* * * code for processing module configuration commands * * Modification History * * Created 09/23/98 by Dan Espen: * * - Some of this logic used to reside in "read.c", preceeded by a * comment about whether it belonged there. Time tells. * * - Added logic to execute module config commands by passing to the * modules that want "active command pipes". * * ******************************************************************** */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/wild.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "module_list.h" #include "module_interface.h" #include "colorset.h" #include "libs/FScreen.h" extern int nColorsets; /* in libs/Colorset.c */ /* do not send ColorLimit, it is not used anymore but maybe by non * "official" modules */ #define DISABLE_COLORLIMIT_CONFIG_INFO #define MODULE_CONFIG_DELIM ':' struct moduleInfoList { char *data; unsigned char alias_len; struct moduleInfoList *next; }; struct moduleInfoList *modlistroot = NULL; static struct moduleInfoList *AddToModList(char *tline); static void SendConfigToModule( fmodule *module, const struct moduleInfoList *entry, char *match, int match_len); /* * ModuleConfig handles commands starting with "*". * * Each command is added to a list from which modules request playback * thru "sendconfig". * * Some modules request that module config commands be sent to them * as the commands are entered. Send to modules that want it. */ void ModuleConfig(char *action) { int end; fmodule_list_itr moditr; fmodule *module; struct moduleInfoList *new_entry; end = strlen(action) - 1; if (action[end] == '\n') action[end] = '\0'; /* save for config request */ new_entry = AddToModList(action); /* look at all possible pipes */ module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { if (IS_MESSAGE_SELECTED(module, M_SENDCONFIG)) { /* module wants config cmds */ char *name = MOD_NAME(module); if (MOD_ALIAS(module)) { name = MOD_ALIAS(module); } SendConfigToModule( module, new_entry, CatString2("*", name), 0); } } return; } static struct moduleInfoList *AddToModList(char *tline) { struct moduleInfoList *t, *prev, *this; char *rline = tline; char *alias_end = skipModuleAliasToken(tline + 1); /* Find end of list */ t = modlistroot; prev = NULL; while(t != NULL) { prev = t; t = t->next; } this = (struct moduleInfoList *)safemalloc( sizeof(struct moduleInfoList)); this->alias_len = 0; if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM) { /* migo (01-Sep-2000): construct an old-style config line */ char *conf_start = alias_end + 1; while (isspace(*conf_start)) conf_start++; *alias_end = '\0'; rline = CatString2(tline, conf_start); *alias_end = MODULE_CONFIG_DELIM; this->alias_len = alias_end - tline; } this->data = (char *)safemalloc(strlen(rline)+1); strcpy(this->data, rline); this->next = NULL; if(prev == NULL) { modlistroot = this; } else { prev->next = this; } return this; } /* * delete from module configuration */ void CMD_DestroyModuleConfig(F_CMD_ARGS) { struct moduleInfoList *current, *next, *prev; char *info; /* info to be deleted - may contain wildcards */ char *mi; char *alias_end; int alias_len = 0; while (isspace(*action)) { action++; } alias_end = skipModuleAliasToken(action); if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM) { /* migo: construct an old-style config line */ char *conf_start = alias_end + 1; while (isspace(*conf_start)) conf_start++; *alias_end = '\0'; GetNextToken(conf_start, &conf_start); if (conf_start == NULL) { return; } info = stripcpy(CatString2(action, conf_start)); *alias_end = MODULE_CONFIG_DELIM; /* +1 for a leading '*' */ alias_len = alias_end - action + 1; free(conf_start); } else { GetNextToken(action, &info); if (info == NULL) { return; } } current = modlistroot; prev = NULL; while (current != NULL) { GetNextToken(current->data, &mi); next = current->next; if ((!alias_len || !current->alias_len || alias_len == current->alias_len) && matchWildcards(info, mi+1)) { free(current->data); free(current); if( prev ) { prev->next = next; } else { modlistroot = next; } } else { prev = current; } current = next; if (mi) { free(mi); } } free(info); return; } static void send_xinerama_state(fmodule *module) { SendName(module, M_CONFIG_INFO, 0, 0, 0, FScreenGetConfiguration()); return; } static void send_desktop_names(fmodule *module) { DesktopsInfo *d; char *name; for (d = Scr.Desktops->next; d != NULL; d = d->next) { if (d->name != NULL) { name = (char *)safemalloc(strlen(d->name) + 44); sprintf(name,"DesktopName %d %s", d->desk, d->name); SendName(module, M_CONFIG_INFO, 0, 0, 0, name); free(name); } } return; } static void send_desktop_geometry(fmodule *module) { char msg[64]; sprintf(msg, "DesktopSize %d %d\n", Scr.VxMax / Scr.MyDisplayWidth + 1, Scr.VyMax / Scr.MyDisplayHeight + 1); SendName(module, M_CONFIG_INFO, 0, 0, 0, msg); return; } static void send_image_path(fmodule *module) { char *msg; char *ImagePath = PictureGetImagePath(); if (ImagePath && *ImagePath != 0) { msg = safemalloc(strlen(ImagePath) + 12); sprintf(msg, "ImagePath %s\n", ImagePath); SendName(module, M_CONFIG_INFO, 0, 0, 0, msg); free(msg); } return; } static void send_color_limit(fmodule *module) { #ifndef DISABLE_COLORLIMIT_CONFIG_INFO char msg[64]; sprintf(msg, "ColorLimit %d\n", Scr.ColorLimit); SendName(module, M_CONFIG_INFO, 0, 0, 0, msg); #endif return; } static void send_colorsets(fmodule *module) { int n; /* dump the colorsets (0 first as others copy it) */ for (n = 0; n < nColorsets; n++) { SendName( module, M_CONFIG_INFO, 0, 0, 0, DumpColorset(n, &Colorset[n])); } return; } static void send_click_time(fmodule *module) { char msg[64]; /* Dominik Vogt (8-Nov-1998): Scr.ClickTime patch to set ClickTime to * 'not at all' during InitFunction and RestartFunction. */ sprintf(msg,"ClickTime %d\n", (Scr.ClickTime < 0) ? -Scr.ClickTime : Scr.ClickTime); SendName(module, M_CONFIG_INFO, 0, 0, 0, msg); return; } static void send_move_threshold(fmodule *module) { char msg[64]; sprintf(msg, "MoveThreshold %d\n", Scr.MoveThreshold); SendName(module, M_CONFIG_INFO, 0, 0, 0, msg); return; } void send_ignore_modifiers(fmodule *module) { char msg[64]; sprintf(msg, "IgnoreModifiers %d\n", GetUnusedModifiers()); SendName(module, M_CONFIG_INFO, 0, 0, 0, msg); return; } void CMD_Send_ConfigInfo(F_CMD_ARGS) { struct moduleInfoList *t; /* matching criteria for module cmds */ char *match; /* get length once for efficiency */ int match_len = 0; fmodule *mod = exc->m.module; send_desktop_geometry(mod); /* send ImagePath and ColorLimit first */ send_image_path(mod); send_color_limit(mod); send_xinerama_state(mod); send_colorsets(mod); send_click_time(mod); send_move_threshold(mod); match = PeekToken(action, &action); if (match) { match_len = strlen(match); } for (t = modlistroot; t != NULL; t = t->next) { SendConfigToModule(mod, t, match, match_len); } send_desktop_names(mod); send_ignore_modifiers(mod); SendPacket( mod, M_END_CONFIG_INFO, (long)0, (long)0, (long)0, (long)0, (long)0, (long)0, (long)0, (long)0); return; } static void SendConfigToModule( fmodule *module, const struct moduleInfoList *entry, char *match, int match_len) { if (match) { if (match_len == 0) { match_len = strlen(match); } if (entry->alias_len > 0 && entry->alias_len != match_len) { return; } /* migo: this should be strncmp not strncasecmp probably. */ if (strncasecmp(entry->data, match, match_len) != 0) { return; } } SendName(module, M_CONFIG_INFO, 0, 0, 0, entry->data); return; } fvwm-2.6.7/fvwm/menus.c0000644000175700017570000053174413006057357011742 00000000000000/* -*-c-*- */ /* 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 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* IMPORTANT NOTE: Do *not* use any constant numbers in this file. All values * have to be #defined in the section below or in defaults.h to ensure full * control over the menus. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "libs/ftime.h" #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/ColorUtils.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/Graphics.h" #include "libs/PictureGraphics.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "events.h" #include "eventhandler.h" #include "eventmask.h" #include "cursor.h" #include "functions.h" #include "commands.h" #include "misc.h" #include "screen.h" #include "colormaps.h" #include "geometry.h" #include "move_resize.h" #include "menudim.h" #include "menuitem.h" #include "menuroot.h" #include "menustyle.h" #include "bindings.h" #include "menubindings.h" #include "menugeometry.h" #include "menuparameters.h" #include "menus.h" #include "libs/FGettext.h" /* ---------------------------- local definitions -------------------------- */ /* used in float to int arithmetic */ #define ROUNDING_ERROR_TOLERANCE 0.005 /* ---------------------------- local macros ------------------------------- */ #define SCTX_SET_MI(ctx,item) ((ctx).type = SCTX_MENU_ITEM, \ (ctx).menu_item.menu_item = (item)) #define SCTX_GET_MI(ctx) ((ctx).type == SCTX_MENU_ITEM ? \ (ctx).menu_item.menu_item : NULL) #define SCTX_SET_MR(ctx,root) ((ctx).type = SCTX_MENU_ROOT, \ (ctx).menu_root.menu_root = (root)) #define SCTX_GET_MR(ctx) ((ctx).type == SCTX_MENU_ROOT ? \ (ctx).menu_root.menu_root : NULL) /* ---------------------------- imports ------------------------------------ */ /* This external is safe. It's written only during startup. */ extern XContext MenuContext; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* patch to pass the last popups position hints to popup_func */ typedef struct { struct { unsigned is_last_menu_pos_hints_valid : 1; unsigned do_ignore_pos_hints : 1; unsigned do_warp_title : 1; } flags; struct MenuPosHints pos_hints; } saved_pos_hints; typedef struct MenuInfo { MenuRoot *all; int n_destroyed_menus; } MenuInfo; typedef struct MenuSizingParameters { MenuRoot *menu; /* number of item labels present in the item format */ int used_item_labels; /* same for mini icons */ int used_mini_icons; struct { int sidepic_width; MenuItemPartSizesT i; } max; struct { unsigned is_popup_indicator_used : 1; } flags; } MenuSizingParameters; typedef enum { SCTX_MENU_ROOT, SCTX_MENU_ITEM } string_context_type_t; typedef union { string_context_type_t type; struct { string_context_type_t type; MenuRoot *menu_root; } menu_root; struct { string_context_type_t type; MenuItem *menu_item; } menu_item; } string_context_t; typedef struct { char delimiter; Bool (*string_handler)( char *string, char delimiter, string_context_t *user_data); } string_def_t; /* ---------------------------- menu loop types ---------------------------- */ typedef enum { MENU_MLOOP_RET_NORMAL, MENU_MLOOP_RET_LOOP, MENU_MLOOP_RET_END } mloop_ret_code_t; typedef struct { unsigned do_popup_immediately : 1; /* used for delay popups, to just popup the menu */ unsigned do_popup_now : 1; unsigned do_popdown_now : 1; /* used for keystrokes, to popup and move to that menu */ unsigned do_popup_and_warp : 1; unsigned do_force_reposition : 1; unsigned do_force_popup : 1; unsigned do_popdown : 1; unsigned do_popup : 1; unsigned do_menu : 1; unsigned do_recycle_event : 1; unsigned do_propagate_event_into_submenu : 1; unsigned has_mouse_moved : 1; unsigned is_off_menu_allowed : 1; unsigned is_key_press : 1; unsigned is_item_entered_by_key_press : 1; unsigned is_motion_faked : 1; unsigned is_popped_up_by_timeout : 1; unsigned is_pointer_in_active_item_area : 1; unsigned is_motion_first : 1; unsigned is_release_first : 1; unsigned is_submenu_mapped : 1; unsigned was_item_unposted : 1; unsigned is_button_release : 1; } mloop_flags_t; typedef struct { MenuItem *mi; MenuRoot *mrMi; int x_offset; int popdown_delay_10ms; int popup_delay_10ms; } mloop_evh_data_t; typedef struct { MenuRoot *mrPopup; MenuRoot *mrPopdown; mloop_flags_t mif; /* used to reduce network traffic with delayed popup/popdown */ MenuItem *mi_with_popup; MenuItem *mi_wants_popup; MenuItem *miRemovedSubmenu; } mloop_evh_input_t; /* values that are set once when the menu loop is entered */ typedef struct mloop_static_info_t { int x_init; int y_init; Time t0; unsigned int event_mask; } mloop_static_info_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* This global is saved and restored every time a function is called that * might modify them, so we can safely let it live outside a function. */ static saved_pos_hints last_saved_pos_hints; /* structures for menus */ static MenuInfo Menus; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void __menu_execute_function(const exec_context_t **pexc, char *action) { const exec_context_t *exc; exec_context_changes_t ecc; int old_emf; ecc.w.w = ((*pexc)->w.fw) ? FW_W((*pexc)->w.fw) : None; exc = exc_clone_context(*pexc, &ecc, ECC_W); old_emf = Scr.flags.is_executing_menu_function; Scr.flags.is_executing_menu_function = 1; execute_function(NULL, exc, action, FUNC_DONT_EXPAND_COMMAND); Scr.flags.is_executing_menu_function = old_emf; exc_destroy_context(exc); /* See if the window has been deleted */ if (!check_if_fvwm_window_exists((*pexc)->w.fw)) { ecc.w.fw = NULL; ecc.w.w = None; ecc.w.wcontext = 0; exc = exc_clone_context( *pexc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); exc_destroy_context(*pexc); *pexc = exc; } return; } static Bool pointer_in_active_item_area(int x_offset, MenuRoot *mr) { float ratio = (float)MST_ACTIVE_AREA_PERCENT(mr) / 100.0; if (MST_ACTIVE_AREA_PERCENT(mr) >= 100) { return False; } if (MST_USE_LEFT_SUBMENUS(mr)) { return (x_offset <= MR_ITEM_X_OFFSET(mr) + MR_ITEM_WIDTH(mr) - MR_ITEM_WIDTH(mr) * ratio); } else { return (x_offset >= MR_ITEM_X_OFFSET(mr) + MR_ITEM_WIDTH(mr) * ratio); } } static Bool pointer_in_passive_item_area(int x_offset, MenuRoot *mr) { float ratio = (float)MST_ACTIVE_AREA_PERCENT(mr) / 100.0; if (MST_ACTIVE_AREA_PERCENT(mr) >= 100) { return False; } if (MST_USE_LEFT_SUBMENUS(mr)) { return (x_offset >= MR_ITEM_X_OFFSET(mr) + MR_ITEM_WIDTH(mr) * ratio); } else { return (x_offset <= MR_ITEM_X_OFFSET(mr) + MR_ITEM_WIDTH(mr) - MR_ITEM_WIDTH(mr) * ratio); } } /* * warping functions */ static void warp_pointer_to_title(MenuRoot *mr) { FWarpPointer( dpy, 0, MR_WINDOW(mr), 0, 0, 0, 0, menudim_middle_x_offset(&MR_DIM(mr)), menuitem_middle_y_offset(MR_FIRST_ITEM(mr), MR_STYLE(mr))); } static MenuItem *warp_pointer_to_item( MenuRoot *mr, MenuItem *mi, Bool do_skip_title) { if (do_skip_title) { while (MI_NEXT_ITEM(mi) != NULL && (!MI_IS_SELECTABLE(mi) || MI_IS_TEAR_OFF_BAR(mi))) { /* skip separators, titles and tear off bars until the * first 'real' item is found */ mi = MI_NEXT_ITEM(mi); } } if (mi == NULL) { mi = MR_LAST_ITEM(mr); } if (mi == NULL) { return mi; } FWarpPointer( dpy, 0, MR_WINDOW(mr), 0, 0, 0, 0, menudim_middle_x_offset(&MR_DIM(mr)), menuitem_middle_y_offset(mi, MR_STYLE(mr))); return mi; } /* * menu animation functions */ /* prepares the parameters to be passed to AnimatedMoveOfWindow * mr - the menu instance that holds the menu item * fw - the FvwmWindow structure to check against allowed functions */ static void get_menu_repaint_transparent_parameters( MenuRepaintTransparentParameters *pmrtp, MenuRoot *mr, FvwmWindow *fw) { pmrtp->mr = mr; pmrtp->fw = fw; return; } /* Undo the animation of a menu */ static void animated_move_back( MenuRoot *mr, Bool do_warp_pointer, FvwmWindow *fw) { MenuRepaintTransparentParameters mrtp; int act_x; int act_y; if (MR_XANIMATION(mr) == 0) { return; } if (menu_get_geometry( mr, &JunkRoot, &act_x, &act_y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { Bool transparent_bg = False; /* move it back */ if (ST_HAS_MENU_CSET(MR_STYLE(mr)) && CSET_IS_TRANSPARENT(ST_CSET_MENU(MR_STYLE(mr)))) { transparent_bg = True; get_menu_repaint_transparent_parameters( &mrtp, mr, fw); } AnimatedMoveOfWindow( MR_WINDOW(mr), act_x, act_y, act_x - MR_XANIMATION(mr), act_y, do_warp_pointer, -1, NULL, (transparent_bg)? &mrtp:NULL); MR_XANIMATION(mr) = 0; } return; } /* move a menu or a tear-off menu preserving transparency. * tear-off menus are moved with their frame coordinates. */ static void move_any_menu( MenuRoot *mr, MenuParameters *pmp, int endX, int endY) { if (MR_IS_TEAR_OFF_MENU(mr)) { float fFull = 1.0; /* this moves the tearoff menu, updating of transparency * will not be as good as if menu repaint parameters * are used. */ AnimatedMoveFvwmWindow( pmp->tear_off_root_menu_window, FW_W_FRAME(pmp->tear_off_root_menu_window), -1, -1, endX, endY, False, 0, &fFull); } else { int x; int y; int JunkDept; menu_get_geometry(mr, &JunkRoot, &x, &y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDept); if (x == endX && y == endY) { return; } if (ST_HAS_MENU_CSET(MR_STYLE(mr)) && CSET_IS_TRANSPARENT(ST_CSET_MENU(MR_STYLE(mr)))) { MenuRepaintTransparentParameters mrtp; get_menu_repaint_transparent_parameters( &mrtp, mr, (*pmp->pexc)->w.fw); update_transparent_menu_bg( &mrtp, x, y, endX, endY, endX, endY); XMoveWindow(dpy, MR_WINDOW(mr), endX, endY); repaint_transparent_menu( &mrtp, False, endX,endY, endX, endY, True); } else { XMoveWindow(dpy, MR_WINDOW(mr), endX, endY); } } } /* ---------------------------- submenu function --------------------------- */ /* Search for a submenu that was popped up by the given item in the given * instance of the menu. */ static MenuRoot *seek_submenu_instance( MenuRoot *parent_menu, MenuItem *parent_item) { MenuRoot *mr; for (mr = Menus.all; mr != NULL; mr = MR_NEXT_MENU(mr)) { if (MR_PARENT_MENU(mr) == parent_menu && MR_PARENT_ITEM(mr) == parent_item) { /* here it is */ break; } } return mr; } static Bool is_submenu_mapped(MenuRoot *parent_menu, MenuItem *parent_item) { XWindowAttributes win_attribs; MenuRoot *mr; mr = seek_submenu_instance(parent_menu, parent_item); if (mr == NULL) { return False; } if (MR_WINDOW(mr) == None) { return False; } if (!XGetWindowAttributes(dpy, MR_WINDOW(mr), &win_attribs)) { return False; } return (win_attribs.map_state == IsViewable); } /* Returns the menu root that a given menu item pops up */ static MenuRoot *mr_popup_for_mi(MenuRoot *mr, MenuItem *mi) { char *menu_name; MenuRoot *menu = NULL; /* This checks if mi is != NULL too */ if (!mi || !MI_IS_POPUP(mi)) { return NULL; } /* first look for a menu that is aleady mapped */ menu = seek_submenu_instance(mr, mi); if (menu) { return menu; } /* just look past "Popup " in the action, and find that menu root */ menu_name = PeekToken(SkipNTokens(MI_ACTION(mi), 1), NULL); menu = menus_find_menu(menu_name); return menu; } /* ---------------------------- item handling ------------------------------ */ /* * find_entry() * * Returns the menu item the pointer is over and optionally the offset * from the left side of the menu entry (if px_offset is != NULL) and * the MenuRoot the pointer is over (if pmr is != NULL). */ static MenuItem *find_entry( MenuParameters *pmp, int *px_offset /*NULL means don't return this value */, MenuRoot **pmr /*NULL means don't return this value */, /* values passed in from caller it FQueryPointer was already called * there */ Window p_child, int p_rx, int p_ry) { MenuItem *mi; MenuRoot *mr; int root_x, root_y; int x, y; Window Child; int r; /* x_offset returns the x offset of the pointer in the found menu item */ if (px_offset) { *px_offset = 0; } if (pmr) { *pmr = NULL; } /* get the pointer position */ if (p_rx < 0) { if (!FQueryPointer( dpy, Scr.Root, &JunkRoot, &Child, &root_x, &root_y, &JunkX, &JunkY, &JunkMask)) { /* pointer is on a different screen */ return NULL; } } else { root_x = p_rx; root_y = p_ry; Child = p_child; } /* find out the menu the pointer is in */ if (pmp->tear_off_root_menu_window != NULL && Child == FW_W_FRAME(pmp->tear_off_root_menu_window)) { /* we're in the top level torn off menu */ Child = FW_W(pmp->tear_off_root_menu_window); } if (XFindContext(dpy, Child, MenuContext, (caddr_t *)&mr) == XCNOENT) { return NULL; } /* get position in that child window */ if (!XTranslateCoordinates( dpy, Scr.Root, MR_WINDOW(mr), root_x, root_y, &x, &y, &JunkChild)) { return NULL; } if (x < 0 || y < 0 || x >= MR_WIDTH(mr) || y >= MR_HEIGHT(mr)) { return NULL; } if (pmr) { *pmr = mr; } r = MST_RELIEF_THICKNESS(mr); /* look for the entry that the mouse is in */ for (mi = MR_FIRST_ITEM(mr); mi; mi = MI_NEXT_ITEM(mi)) { int a; int b; a = (MI_PREV_ITEM(mi) && MI_IS_SELECTABLE(MI_PREV_ITEM(mi))) ? r / 2 : 0; if (!MI_IS_SELECTABLE(mi)) { b = 0; } else if (MI_NEXT_ITEM(mi) && MI_IS_SELECTABLE(MI_NEXT_ITEM(mi))) { b = r / 2; } else { b = r; } if (y >= MI_Y_OFFSET(mi) - a && y < MI_Y_OFFSET(mi) + MI_HEIGHT(mi) + b) { break; } } if (x < MR_ITEM_X_OFFSET(mr) || x >= MR_ITEM_X_OFFSET(mr) + MR_ITEM_WIDTH(mr) - 1) { mi = NULL; } if (mi && px_offset) { *px_offset = x; } return mi; } /* ---------------------------- keyboard shortcuts ------------------------- */ static Bool is_double_click( Time t0, MenuItem *mi, MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, Bool has_mouse_moved) { if ((*pmp->pexc)->x.elast->type == KeyPress) { return False; } if (fev_get_evtime() - t0 >= MST_DOUBLE_CLICK_TIME(pmp->menu)) { return False; } if (has_mouse_moved) { return False; } if (!pmp->flags.has_default_action && (mi && mi == MR_FIRST_ITEM(pmp->menu) && MI_IS_SELECTABLE(mi))) { return False; } if (pmp->flags.is_submenu) { return False; } if (pmp->flags.is_invoked_by_key_press && pdkp->timestamp == 0) { return False; } return True; } /* ---------------------------- item label parsing ------------------------- */ /* * Procedure: * scanForHotkeys - Look for hotkey markers in a MenuItem * (pete@tecc.co.uk) * * Inputs: * it - MenuItem to scan * column - The column number in which to look for a hotkey. * */ static void scanForHotkeys( MenuItem *it, int column) { char *start; char *s; char *t; /* Get start of string */ start = MI_LABEL(it)[column]; /* Scan whole string */ for (s = start; *s != '\0'; s++) { if (*s != '&') { continue; } if (s[1] != '&') { /* found a hotkey - only one hotkey per item */ break; } /* Just an escaped '&'; copy the string down over it */ for (t = s; *t != '\0'; t++) { t[0] = t[1]; } } if (*s != 0) { /* It's a hot key marker - work out the offset value */ MI_HOTKEY_COFFSET(it) = s - start; MI_HOTKEY_COLUMN(it) = column; MI_HAS_HOTKEY(it) = (s[1] != '\0'); MI_IS_HOTKEY_AUTOMATIC(it) = 0; for ( ; *s != '\0'; s++) { /* Copy down.. */ s[0] = s[1]; } } return; } static void __copy_down(char *remove_from, char *remove_to) { char *t1; char *t2; for (t1 = remove_from, t2 = remove_to; *t2 != '\0'; t2++, t1++) { *t1 = *t2; } *t1 = '\0'; return; } static int __check_for_delimiter(char *s, const string_def_t *string_defs) { int type; for (type = 0; string_defs[type].delimiter != '\0'; type++) { if (s[0] == string_defs[type].delimiter) { if (s[1] != string_defs[type].delimiter) { return type; } else { /* escaped delimiter, copy the * string down over it */ __copy_down(s, s+1); return -1; } } } return -1; } /* This scans for strings within delimiters and calls a callback based * on the delimiter found for each found string */ static void scanForStrings( char *instring, const string_def_t *string_defs, string_context_t *context) { char *s; int type; char *string; type = -1; /* string is set whenever type >= 0, and unused otherwise * set to NULL to supress compiler warning */ string = NULL; for (s = instring; *s != '\0'; s++) { if (type < 0) { /* look for starting delimiters */ type = __check_for_delimiter(s, string_defs); if (type >= 0) { /* start of a string */ string = s + 1; } } else if ( s[0] == string_defs[type].delimiter && s[1] != string_defs[type].delimiter) { /* found ending delimiter */ Bool is_valid; /* terminate the string pointer */ s[0] = '\0'; is_valid = string_defs[type].string_handler( string, string_defs[type].delimiter, context); /* restore the string */ s[0] = string_defs[type].delimiter; if (is_valid) { /* the string was OK, remove it from * instring */ __copy_down(string - 1, s + 1); /* continue next iteration at the * first character after the string */ s = string - 2; } type = -1; } else if (s[0] == string_defs[type].delimiter) { /* escaped delimiter, copy the string down over * it */ __copy_down(s, s + 1); } } } /* Side picture support: this scans for a color int the menu name for colorization */ static Bool __scan_for_color( char *name, char type, string_context_t *context) { if (type != '^' || SCTX_GET_MR(*context) == NULL) { abort(); } if (MR_HAS_SIDECOLOR(SCTX_GET_MR(*context))) { return False; } MR_SIDECOLOR(SCTX_GET_MR(*context)) = GetColor(name); MR_HAS_SIDECOLOR(SCTX_GET_MR(*context)) = True; return True; } static Bool __scan_for_pixmap( char *name, char type, string_context_t *context) { FvwmPicture *p; FvwmPictureAttributes fpa; int current_mini_icon; /* check that more pictures are allowed before trying to load the * picture */ current_mini_icon = -999999999; switch (type) { case '@': if (SCTX_GET_MR(*context) == NULL) { abort(); } if (MR_SIDEPIC(SCTX_GET_MR(*context))) { return False; } break; case '*': /* menu item picture, requires menu item */ if (SCTX_GET_MI(*context) == NULL) { abort(); } if (MI_PICTURE(SCTX_GET_MI(*context))) { return False; } break; case '%': /* mini icon - look for next free spot */ if (SCTX_GET_MI(*context) == NULL) { abort(); } current_mini_icon = 0; while (current_mini_icon < MAX_MENU_ITEM_MINI_ICONS) { if ( MI_MINI_ICON(SCTX_GET_MI(*context)) [current_mini_icon]) { current_mini_icon++; } else { break; } } if (current_mini_icon == MAX_MENU_ITEM_MINI_ICONS) { return False; } break; default: abort(); } fpa.mask = 0; p = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, name, fpa); if (!p) { fvwm_msg(WARN, "scanForPixmap", "Couldn't load image from %s", name); fvwm_msg(WARN, "scanForPixmap", "Check that FVWM has support for the filetype it's " "being asked to load."); /* return true to make missing pictures not appear in the * label/name */ return True; } switch (type) { case '@': MR_SIDEPIC(SCTX_GET_MR(*context)) = p; break; case '*': MI_PICTURE(SCTX_GET_MI(*context)) = p; MI_HAS_PICTURE(SCTX_GET_MI(*context)) = True; break; case '%': MI_MINI_ICON(SCTX_GET_MI(*context))[current_mini_icon] = p; MI_HAS_PICTURE(SCTX_GET_MI(*context)) = True; break; } return True; } /* ---------------------------- item list handling ------------------------- */ static void unlink_item_from_menu( MenuRoot *mr, MenuItem *mi) { MenuItem *next; MenuItem *prev; next = MI_NEXT_ITEM(mi); prev = MI_PREV_ITEM(mi); if (next != NULL) { MI_PREV_ITEM(next) = prev; } else { MR_LAST_ITEM(mr) = prev; } if (prev != NULL) { MI_NEXT_ITEM(prev) = next; } else { MR_FIRST_ITEM(mr) = next; } MI_NEXT_ITEM(mi) = NULL; MI_PREV_ITEM(mi) = NULL; MR_ITEMS(mr)--; return; } /* Add the given menu item to the menu. If the first item of the menu is a * title, and the do_replace_title flag is True, the old title is deleted and * replaced by the new item. Otherwise the item is appended at the end of the * menu. */ static void append_item_to_menu( MenuRoot *mr, MenuItem *mi, Bool do_replace_title) { if (MR_FIRST_ITEM(mr) == NULL) { MR_FIRST_ITEM(mr) = mi; MR_LAST_ITEM(mr) = mi; MI_NEXT_ITEM(mi) = NULL; MI_PREV_ITEM(mi) = NULL; } else if (do_replace_title) { if (MI_IS_TITLE(MR_FIRST_ITEM(mr))) { if (MR_FIRST_ITEM(mr) == MR_LAST_ITEM(mr)) { MR_LAST_ITEM(mr) = mi; } if (MI_NEXT_ITEM(MR_FIRST_ITEM(mr)) != NULL) { MI_PREV_ITEM(MI_NEXT_ITEM( MR_FIRST_ITEM(mr))) = mi; } MI_NEXT_ITEM(mi) = MI_NEXT_ITEM(MR_FIRST_ITEM(mr)); menuitem_free(MR_FIRST_ITEM(mr)); } else { MI_PREV_ITEM(MR_FIRST_ITEM(mr)) = mi; MI_NEXT_ITEM(mi) = MR_FIRST_ITEM(mr); } MI_PREV_ITEM(mi) = NULL; MR_FIRST_ITEM(mr) = mi; } else { MI_NEXT_ITEM(MR_LAST_ITEM(mr)) = mi; MI_PREV_ITEM(mi) = MR_LAST_ITEM(mr); MR_LAST_ITEM(mr) = mi; } return; } static void clone_menu_item_list( MenuRoot *dest_mr, MenuRoot *src_mr) { MenuItem *mi; MenuItem *cloned_mi; MenuRoot *mr; MR_FIRST_ITEM(dest_mr) = NULL; MR_LAST_ITEM(dest_mr) = NULL; /* traverse the menu and all its continuations */ for (mr = src_mr; mr != NULL; mr = MR_CONTINUATION_MENU(mr)) { /* duplicate all items in the current menu */ for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi)) { if (MI_IS_CONTINUATION(mi)) { /* skip this item */ continue; } cloned_mi = menuitem_clone(mi); append_item_to_menu(dest_mr, cloned_mi, False); } } return; } /* ---------------------------- MenuRoot maintenance functions ------------- */ /* Extract interesting values from the item format string that are needed by * the size_menu_... functions. */ static void calculate_item_sizes(MenuSizingParameters *msp) { MenuItem *mi; MenuItemPartSizesT mipst; int i; Bool do_reverse_icon_order = (MST_USE_LEFT_SUBMENUS(msp->menu)) ? True : False; memset(&(msp->max), 0, sizeof(msp->max)); /* Calculate the widths for all columns of all items. */ for (mi = MR_FIRST_ITEM(msp->menu); mi != NULL; mi = MI_NEXT_ITEM(mi)) { if (MI_IS_TITLE(mi)) { menuitem_get_size( mi, &mipst, MST_PTITLEFONT(msp->menu), do_reverse_icon_order); } else { menuitem_get_size( mi, &mipst, MST_PSTDFONT(msp->menu), do_reverse_icon_order); } /* adjust maximums */ if (msp->max.i.triangle_width < mipst.triangle_width) { msp->max.i.triangle_width = mipst.triangle_width; } if (msp->max.i.title_width < mipst.title_width) { msp->max.i.title_width = mipst.title_width; } for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (msp->max.i.label_width[i] < mipst.label_width[i]) { msp->max.i.label_width[i] = mipst.label_width[i]; } } if (msp->max.i.picture_width < mipst.picture_width) { msp->max.i.picture_width = mipst.picture_width; } for (i = 0; i < MAX_MENU_ITEM_MINI_ICONS; i++) { if (msp->max.i.icon_width[i] < mipst.icon_width[i]) { msp->max.i.icon_width[i] = mipst.icon_width[i]; } } } if (MR_SIDEPIC(msp->menu)) { msp->max.sidepic_width = MR_SIDEPIC(msp->menu)->width; } else if (MST_SIDEPIC(msp->menu)) { msp->max.sidepic_width = MST_SIDEPIC(msp->menu)->width; } return; } /* * * Calculate the positions of the columns in the menu. * Called by make_menu(). * */ static void size_menu_horizontally(MenuSizingParameters *msp) { MenuItem *mi; Bool sidepic_is_left = True; int total_width; int sidepic_space = 0; int label_offset[MAX_MENU_ITEM_LABELS]; char lcr_column[MAX_MENU_ITEM_LABELS]; int i; int d; int relief_thickness = MST_RELIEF_THICKNESS(msp->menu); int *item_order[ MAX_MENU_ITEM_LABELS + MAX_MENU_ITEM_MINI_ICONS + 1 /* triangle */ + 2 /* relief markers */]; int used_objects = 0; int left_objects = 0; int right_objects = 0; int x; unsigned char icons_placed = 0; Bool sidepic_placed = False; Bool triangle_placed = False; Bool relief_begin_placed = False; Bool relief_end_placed = False; char *format; Bool first = True; Bool done = False; Bool is_last_object_left = True; unsigned char columns_placed = 0; int relief_gap = 0; int gap_left; int gap_right; int chars; memset(item_order, 0, sizeof(item_order)); for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { lcr_column[i] = 'l'; } /* Now calculate the offsets for the columns. */ format = MST_ITEM_FORMAT(msp->menu); if (!format) { format = (MST_USE_LEFT_SUBMENUS(msp->menu)) ? DEFAULT_LEFT_MENU_ITEM_FORMAT : DEFAULT_MENU_ITEM_FORMAT; } /* Place the individual items off the menu in case they are not * set in the format string. */ for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { label_offset[i] = 2 * Scr.MyDisplayWidth; } x = MST_BORDER_WIDTH(msp->menu); while (*format && !done) { switch (*format) { case '%': format++; chars = 0; gap_left = 0; gap_right = 0; /* Insert a gap of %d pixels. */ if (sscanf(format, "%d.%d%n", &gap_left, &gap_right, &chars) >= 2 || (sscanf(format, "%d.%n", &gap_left, &chars) >= 1 && chars > 0) || sscanf(format, "%d%n", &gap_left, &chars) >= 1 || sscanf(format, ".%d%n", &gap_right, &chars) >= 1) { if (gap_left > MR_SCREEN_WIDTH(msp->menu) || gap_left < -MR_SCREEN_WIDTH(msp->menu)) { gap_left = 0; } if (gap_right > MR_SCREEN_HEIGHT(msp->menu) || gap_right < -MR_SCREEN_HEIGHT(msp->menu)) { gap_right = 0; } /* Skip the number. */ format += chars; } else if (*format == '.') { /* Skip a dot without values */ format++; } if (!*format) { break; } switch (*format) { case 'l': case 'c': case 'r': /* A left, center or right aligned column. */ if (columns_placed >= MAX_MENU_ITEM_LABELS) { break; } if ( msp->max.i.label_width[columns_placed] <= 0) { columns_placed++; break; } lcr_column[columns_placed] = *format; x += gap_left; label_offset[columns_placed] = x; x += msp->max.i.label_width[columns_placed] + gap_right; item_order[used_objects++] = &(label_offset[columns_placed]); if (is_last_object_left && (*format == 'l')) { left_objects++; } else { is_last_object_left = False; if (*format == 'r') { right_objects++; } else { right_objects = 0; } } columns_placed++; break; case 's': /* the sidepic */ if (sidepic_placed) { break; } sidepic_placed = True; if (msp->max.sidepic_width <= 0) { break; } x += gap_left; MR_SIDEPIC_X_OFFSET(msp->menu) = x; sidepic_is_left = first; sidepic_space = msp->max.sidepic_width + ((sidepic_is_left) ? gap_left : gap_right); x += msp->max.sidepic_width + gap_right; break; case 'i': /* a mini icon */ if (icons_placed >= MAX_MENU_ITEM_MINI_ICONS) { break; } if (msp->max.i.icon_width[icons_placed] > 0) { x += gap_left; MR_ICON_X_OFFSET(msp->menu) [icons_placed] = x; x += msp->max.i.icon_width [icons_placed] + gap_right; item_order[used_objects++] = &(MR_ICON_X_OFFSET(msp->menu) [icons_placed]); if (is_last_object_left) { left_objects++; } else { right_objects++; } } icons_placed++; break; case '|': if (!relief_begin_placed) { relief_begin_placed = True; x += gap_left; MR_HILIGHT_X_OFFSET(msp->menu) = x; x += relief_thickness + gap_right; relief_gap += gap_right; item_order[used_objects++] = &(MR_HILIGHT_X_OFFSET( msp->menu)); if (is_last_object_left) { left_objects++; } else { right_objects = 0; } } else if (!relief_end_placed) { relief_end_placed = True; x += relief_thickness + gap_left; /* This is a hack: for now we record * the x coordinate of the end of the * hilight area, but later we'll place * the width in here. */ MR_HILIGHT_WIDTH(msp->menu) = x; x += gap_right; relief_gap += gap_left; item_order[used_objects++] = &(MR_HILIGHT_WIDTH(msp->menu)); right_objects++; } break; case '>': case '<': /* the triangle for popup menus */ if (triangle_placed) { break; } triangle_placed = True; if (msp->max.i.triangle_width > 0) { x += gap_left; MR_TRIANGLE_X_OFFSET( msp->menu) = x; MR_IS_LEFT_TRIANGLE(msp->menu) = (*format == '<'); x += msp->max.i.triangle_width + gap_right; item_order[used_objects++] = &(MR_TRIANGLE_X_OFFSET( msp->menu)); if (is_last_object_left && *format == '<') { left_objects++; } else { is_last_object_left = False; right_objects++; } } break; case 'p': /* Simply add a gap. */ x += gap_right + gap_left; break; case '\t': x += MENU_TAB_WIDTH * FlocaleTextWidth( MST_PSTDFONT( msp->menu), " ", 1); break; case ' ': /* Advance the x position. */ x += FlocaleTextWidth( MST_PSTDFONT(msp->menu), format, 1); break; default: /* Ignore unknown characters. */ break; } /* switch (*format) */ break; case '\t': x += MENU_TAB_WIDTH * FlocaleTextWidth( MST_PSTDFONT(msp->menu), " ", 1); break; case ' ': /* Advance the x position. */ x += FlocaleTextWidth( MST_PSTDFONT(msp->menu), format, 1); break; default: /* Ignore unknown characters. */ break; } /* switch (*format) */ format++; first = False; } /* while (*format) */ /* stored for vertical sizing */ msp->used_item_labels = columns_placed; msp->used_mini_icons = icons_placed; /* Hide unplaced parts of the menu. */ if (!sidepic_placed) { MR_SIDEPIC_X_OFFSET(msp->menu) = 2 * MR_SCREEN_WIDTH(msp->menu); } for (i = icons_placed; i < MAX_MENU_ITEM_MINI_ICONS; i++) { MR_ICON_X_OFFSET(msp->menu)[i] = 2 * MR_SCREEN_WIDTH(msp->menu); } if (!triangle_placed) { MR_TRIANGLE_X_OFFSET(msp->menu) = 2 * MR_SCREEN_WIDTH(msp->menu); } msp->flags.is_popup_indicator_used = triangle_placed; total_width = x - MST_BORDER_WIDTH(msp->menu); d = (sidepic_space + 2 * relief_thickness + max(msp->max.i.title_width, msp->max.i.picture_width)) - total_width; if (d > 0) { int m = 1 - left_objects; int n = 1 + used_objects - left_objects - right_objects; /* The title is larger than all menu items. Stretch the * gaps between the items up to the total width of the * title. */ for (i = 0; i < used_objects; i++) { if (i < left_objects) { continue; } if (i >= used_objects - right_objects) { /* Right aligned item. */ *(item_order[i]) += d; } else { /* Neither left nor right aligned item. * Divide the overhead gap evenly * between the items. */ *(item_order[i]) += d * (m + i) / n; } } total_width += d; if (!sidepic_is_left) { MR_SIDEPIC_X_OFFSET(msp->menu) += d; } } /* if (d > 0) */ MR_WIDTH(msp->menu) = total_width + 2 * MST_BORDER_WIDTH(msp->menu); MR_ITEM_WIDTH(msp->menu) = total_width - sidepic_space; MR_ITEM_X_OFFSET(msp->menu) = MST_BORDER_WIDTH(msp->menu); if (sidepic_is_left) { MR_ITEM_X_OFFSET(msp->menu) += sidepic_space; } if (!relief_begin_placed) { MR_HILIGHT_X_OFFSET(msp->menu) = MR_ITEM_X_OFFSET(msp->menu); } if (relief_end_placed) { MR_HILIGHT_WIDTH(msp->menu) = MR_HILIGHT_WIDTH(msp->menu) - MR_HILIGHT_X_OFFSET(msp->menu); } else { MR_HILIGHT_WIDTH(msp->menu) = MR_ITEM_WIDTH(msp->menu) + MR_ITEM_X_OFFSET(msp->menu) - MR_HILIGHT_X_OFFSET(msp->menu); } /* Now calculate the offsets for the individual labels. */ for (mi = MR_FIRST_ITEM(msp->menu); mi != NULL; mi = MI_NEXT_ITEM(mi)) { for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i] == NULL) { continue; } if (!MI_IS_TITLE(mi) || !MI_IS_TITLE_CENTERED(mi)) { switch (lcr_column[i]) { case 'l': MI_LABEL_OFFSET(mi)[i] = label_offset[i]; break; case 'c': MI_LABEL_OFFSET(mi)[i] = label_offset[i] + (msp->max.i.label_width[i] - MI_LABEL_OFFSET(mi)[i]) / 2; break; case 'r': MI_LABEL_OFFSET(mi)[i] = label_offset[i] + msp->max.i.label_width[i] - MI_LABEL_OFFSET(mi)[i]; break; } } else { /* This is a centered title item (indicated by * negative width). */ MI_LABEL_OFFSET(mi)[i] = menudim_middle_x_offset( &MR_DIM(msp->menu)) - MI_LABEL_OFFSET(mi)[i] / 2; } } /* for */ } /* for */ return; } static int calc_more_item_height(MenuSizingParameters *msp) { int height; height = MST_PSTDFONT(msp->menu)->height + MST_ITEM_GAP_ABOVE(msp->menu) + MST_ITEM_GAP_BELOW(msp->menu) + MST_RELIEF_THICKNESS(msp->menu); return height; } static int calc_normal_item_height(MenuSizingParameters *msp, MenuItem *mi) { int height; height = MST_ITEM_GAP_ABOVE(msp->menu) + MST_ITEM_GAP_BELOW(msp->menu) + MST_RELIEF_THICKNESS(msp->menu); /* Normal text entry or an entry with a sub menu triangle */ if ( (MI_HAS_TEXT(mi) && msp->used_item_labels) || (MI_IS_POPUP(mi) && msp->flags.is_popup_indicator_used)) { height += MST_PSTDFONT(msp->menu)->height; } return height; } /* * * Calculate the positions of the columns in the menu. * Called by make_menu(). * */ static Bool size_menu_vertically(MenuSizingParameters *msp) { MenuItem *mi; int y; int cItems; int relief_thickness = MST_RELIEF_THICKNESS(msp->menu); int i; Bool has_continuation_menu = False; MR_ITEM_TEXT_Y_OFFSET(msp->menu) = MST_PSTDFONT(msp->menu)->ascent + relief_thickness + MST_ITEM_GAP_ABOVE(msp->menu); /* mi_prev trails one behind mi, since we need to move that into a newly-made menu if we run out of space */ y = MST_BORDER_WIDTH(msp->menu) + MST_VERTICAL_MARGIN_TOP(msp->menu); for ( cItems = 0, mi = MR_FIRST_ITEM(msp->menu); mi != NULL; mi = MI_NEXT_ITEM(mi), cItems++) { Bool last_item_has_relief = (MI_PREV_ITEM(mi)) ? MI_IS_SELECTABLE(MI_PREV_ITEM(mi)) : False; Bool has_mini_icon = False; int separator_height; int menu_height; separator_height = (last_item_has_relief) ? MENU_SEPARATOR_HEIGHT + relief_thickness : MENU_SEPARATOR_TOTAL_HEIGHT; MI_Y_OFFSET(mi) = y; if (MI_IS_TITLE(mi)) { MI_HEIGHT(mi) = MST_PTITLEFONT(msp->menu)->height + MST_TITLE_GAP_ABOVE(msp->menu) + MST_TITLE_GAP_BELOW(msp->menu); } else if (MI_IS_SEPARATOR(mi)) { /* Separator */ MI_HEIGHT(mi) = separator_height; } else if (MI_IS_TEAR_OFF_BAR(mi)) { /* Tear off bar */ MI_HEIGHT(mi) = relief_thickness + MENU_TEAR_OFF_BAR_HEIGHT; } else { MI_HEIGHT(mi) = calc_normal_item_height(msp, mi); } if (MI_IS_TITLE(mi)) { /* add space for the underlines */ switch (MST_TITLE_UNDERLINES(msp->menu)) { case 0: if (last_item_has_relief) MI_HEIGHT(mi) += relief_thickness; break; case 1: if (mi != MR_FIRST_ITEM(msp->menu)) { /* Space to draw the separator plus a * gap above */ MI_HEIGHT(mi) += separator_height; } if (MI_NEXT_ITEM(mi) != NULL) { /* Space to draw the separator */ MI_HEIGHT(mi) += MENU_SEPARATOR_HEIGHT; } break; default: /* Space to draw n underlines. */ MI_HEIGHT(mi) += MENU_UNDERLINE_HEIGHT * MST_TITLE_UNDERLINES(msp->menu); if (last_item_has_relief) MI_HEIGHT(mi) += relief_thickness; break; } } for (i = 0; i < msp->used_mini_icons; i++) { if (MI_MINI_ICON(mi)[i]) { has_mini_icon = True; } if (MI_MINI_ICON(mi)[i] && MI_HEIGHT(mi) < MI_MINI_ICON(mi)[i]->height + relief_thickness) { MI_HEIGHT(mi) = MI_MINI_ICON(mi)[i]->height + relief_thickness; } } if (MI_PICTURE(mi)) { if ((MI_HAS_TEXT(mi) && msp->used_item_labels) || has_mini_icon) { MI_HEIGHT(mi) += MI_PICTURE(mi)->height; } else { MI_HEIGHT(mi) = MI_PICTURE(mi)->height + relief_thickness; } } y += MI_HEIGHT(mi); /* this item would have to be the last item, or else * we need to add a "More..." entry pointing to a new menu */ menu_height = y + MST_BORDER_WIDTH(msp->menu) + MST_VERTICAL_MARGIN_BOTTOM(msp->menu) + ((MI_IS_SELECTABLE(mi)) ? relief_thickness : 0); if (menu_height > MR_SCREEN_HEIGHT(msp->menu)) { /* Item does not fit on screen anymore. */ char *t; char *tempname; const char *gt_name; char *name; MenuRoot *menuContinuation; int more_item_height; more_item_height = calc_more_item_height(msp); /* Remove items form the menu until it fits (plus a * 'More' entry). */ while ( MI_PREV_ITEM(mi) != NULL && menu_height > MR_SCREEN_HEIGHT(msp->menu)) { /* Remove current item. */ y -= MI_HEIGHT(mi); mi = MI_PREV_ITEM(mi); cItems--; menu_height = y + MST_BORDER_WIDTH(msp->menu) + more_item_height + relief_thickness + MST_VERTICAL_MARGIN_BOTTOM(msp->menu); } if ( MI_PREV_ITEM(mi) == NULL || menu_height > MR_SCREEN_HEIGHT(msp->menu)) { fvwm_msg(ERR, "size_menu_vertically", "Menu entry does not fit on screen"); /* leave a coredump */ abort(); exit(1); } t = EscapeString(MR_NAME(msp->menu), "\"", '\\'); tempname = (char *)safemalloc( (10 + strlen(t)) * sizeof(char)); strcpy(tempname, "Popup \""); strcat(tempname, t); strcat(tempname, "$\""); free(t); /* NewMenuRoot inserts at the head of the list of menus but, we need it at the end. (Give it just the name, * which is 6 chars past the action since * strlen("Popup ")==6 ) */ t = (char *)safemalloc(strlen(MR_NAME(msp->menu)) + 2); strcpy(t, MR_NAME(msp->menu)); strcat(t, "$"); menuContinuation = NewMenuRoot(t); free(t); MR_CONTINUATION_MENU(msp->menu) = menuContinuation; /* Now move this item and the remaining items into the * new menu */ MR_FIRST_ITEM(menuContinuation) = MI_NEXT_ITEM(mi); MR_LAST_ITEM(menuContinuation) = MR_LAST_ITEM(msp->menu); MR_ITEMS(menuContinuation) = MR_ITEMS(msp->menu) - cItems; MI_PREV_ITEM(MI_NEXT_ITEM(mi)) = NULL; /* mi_prev is now the last item in the parent menu */ MR_LAST_ITEM(msp->menu) = mi; MR_ITEMS(msp->menu) = cItems; MI_NEXT_ITEM(mi) = NULL; /* use the same style for the submenu */ MR_STYLE(menuContinuation) = MR_STYLE(msp->menu); MR_IS_LEFT_TRIANGLE(menuContinuation) = MR_IS_LEFT_TRIANGLE(msp->menu); /* migo: propagate missing_submenu_func */ if (MR_MISSING_SUBMENU_FUNC(msp->menu)) { MR_MISSING_SUBMENU_FUNC(menuContinuation) = safestrdup(MR_MISSING_SUBMENU_FUNC( msp->menu)); } /* don't propagate sidepic, sidecolor, popup and * popdown actions */ /* And add the entry pointing to the new menu */ gt_name = gettext("More&..."); name = safestrdup(gt_name); AddToMenu( msp->menu, name, tempname, False /* no pixmap scan */, False, True); free(name); free(tempname); has_continuation_menu = True; } } /* for */ /* The menu may be empty here! */ if (MR_LAST_ITEM(msp->menu) != NULL && MI_IS_SELECTABLE(MR_LAST_ITEM(msp->menu))) { y += relief_thickness; } MR_HEIGHT(msp->menu) = y + MST_BORDER_WIDTH(msp->menu) + MST_VERTICAL_MARGIN_BOTTOM(msp->menu); return has_continuation_menu; } /* * * Merge menu continuations back into the original menu. * Called by make_menu(). * */ static void merge_continuation_menus(MenuRoot *mr) { /* merge menu continuations into one menu again - needed when changing * the font size of a long menu. */ while (MR_CONTINUATION_MENU(mr) != NULL) { MenuRoot *cont = MR_CONTINUATION_MENU(mr); /* link first item of continuation to item before 'more...' */ MI_NEXT_ITEM(MI_PREV_ITEM(MR_LAST_ITEM(mr))) = MR_FIRST_ITEM(cont); MI_PREV_ITEM(MR_FIRST_ITEM(cont)) = MI_PREV_ITEM(MR_LAST_ITEM(mr)); menuitem_free(MR_LAST_ITEM(mr)); MR_LAST_ITEM(mr) = MR_LAST_ITEM(cont); MR_CONTINUATION_MENU(mr) = MR_CONTINUATION_MENU(cont); /* fake an empty menu so that DestroyMenu does not destroy the * items. */ MR_FIRST_ITEM(cont) = NULL; DestroyMenu(cont, False, False); } return; } /* * * Creates the window for the menu. * */ static void make_menu_window(MenuRoot *mr, Bool is_tear_off) { unsigned long valuemask; XSetWindowAttributes attributes; int w; int h; unsigned int evmask; w = MR_WIDTH(mr); if (w == 0) { w = 1; } h = MR_HEIGHT(mr); if (h == 0) { h = 1; } attributes.background_pixel = (MST_HAS_MENU_CSET(mr)) ? Colorset[MST_CSET_MENU(mr)].bg : MST_MENU_COLORS(mr).back; if (MR_WINDOW(mr) != None) { /* just resize the existing window */ XResizeWindow(dpy, MR_WINDOW(mr), w, h); /* and change the background color */ valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, MR_WINDOW(mr), valuemask, &attributes); } else { /* create a new window */ valuemask = CWBackPixel | CWEventMask | CWCursor | CWColormap | CWBorderPixel | CWSaveUnder; attributes.border_pixel = 0; attributes.colormap = Pcmap; evmask = XEVMASK_MENUW; attributes.event_mask = 0; attributes.cursor = Scr.FvwmCursors[CRS_MENU]; attributes.save_under = True; /* Create a display used to create the window. Can't use the * normal display because 'xkill' would kill the window * manager if used on a tear off menu. The display can't be * deleted right now because that would either destroy the new * window or leave it as an orphan if fvwm dies or is * restarted. */ if (is_tear_off) { MR_CREATE_DPY(mr) = XOpenDisplay(display_name); if (MR_CREATE_DPY(mr) == NULL) { /* Doh. Use the standard display instead. */ MR_CREATE_DPY(mr) = dpy; } } else { MR_CREATE_DPY(mr) = dpy; } MR_WINDOW(mr) = XCreateWindow( MR_CREATE_DPY(mr), Scr.Root, 0, 0, w, h, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); if (MR_CREATE_DPY(mr) != dpy) { /* We *must* synchronize the display here. Otherwise * the request will never be processed. */ XSync(MR_CREATE_DPY(mr), 1); } if (MR_WINDOW(mr) != None) { /* select events for the window from the standard * display */ XSelectInput(dpy, MR_WINDOW(mr), evmask); } XSaveContext(dpy, MR_WINDOW(mr), MenuContext,(caddr_t)mr); } return; } /* * * Generates the window for a menu * */ static void make_menu(MenuRoot *mr, Bool is_tear_off) { MenuSizingParameters msp; Bool has_continuation_menu = False; if (MR_MAPPED_COPIES(mr) > 0) { return; } merge_continuation_menus(mr); do { memset(&msp, 0, sizeof(MenuSizingParameters)); msp.menu = mr; calculate_item_sizes(&msp); /* Call size_menu_horizontally first because it calculated * some values used by size_menu_vertically. */ size_menu_horizontally(&msp); has_continuation_menu = size_menu_vertically(&msp); /* repeat this step if the menu was split */ } while (has_continuation_menu); MR_USED_MINI_ICONS(mr) = msp.used_mini_icons; MR_XANIMATION(mr) = 0; memset(&(MR_DYNAMIC_FLAGS(mr)), 0, sizeof(MR_DYNAMIC_FLAGS(mr))); /* create a new window for the menu */ make_menu_window(mr, is_tear_off); MR_IS_UPDATED(mr) = 0; return; } /* Make sure the menu is properly rebuilt when the style or the menu has * changed. */ static void update_menu(MenuRoot *mr, MenuParameters *pmp) { int sw; int sh; Bool has_screen_size_changed = False; fscreen_scr_arg fscr; if (MST_IS_UPDATED(mr)) { /* The menu style has changed. */ MenuRoot *menu; for (menu = Menus.all; menu; menu = MR_NEXT_MENU(menu)) { if (MR_STYLE(menu) == MR_STYLE(mr)) { /* Mark all other menus with the same style as * changed. */ MR_IS_UPDATED(menu) = 1; } } MST_IS_UPDATED(mr) = 0; } fscr.xypos.x = pmp->screen_origin_x; fscr.xypos.y = pmp->screen_origin_y; FScreenGetScrRect(&fscr, FSCREEN_XYPOS, &JunkX, &JunkY, &sw, &sh); if (sw != MR_SCREEN_WIDTH(mr) || sh != MR_SCREEN_HEIGHT(mr)) { has_screen_size_changed = True; MR_SCREEN_WIDTH(mr) = sw; MR_SCREEN_HEIGHT(mr) = sh; } if (MR_IS_UPDATED(mr) || has_screen_size_changed) { /* The menu or the screen dimensions have changed. We have to * re-make it. */ make_menu(mr, False); } return; } /* * * Procedure: * copy_menu_root - creates a new instance of an existing menu * * Returned Value: * (MenuRoot *) * * Inputs: * mr - the MenuRoot structure of the existing menu * */ static MenuRoot *copy_menu_root(MenuRoot *mr) { MenuRoot *tmp; if (!mr || MR_COPIES(mr) >= MAX_MENU_COPIES) { return NULL; } tmp = (MenuRoot *)safemalloc(sizeof(MenuRoot)); tmp->d = (MenuRootDynamic *)safemalloc(sizeof(MenuRootDynamic)); memset(tmp->d, 0, sizeof(MenuRootDynamic)); tmp->s = mr->s; MR_COPIES(mr)++; MR_ORIGINAL_MENU(tmp) = MR_ORIGINAL_MENU(mr); MR_CONTINUATION_MENU(tmp) = MR_CONTINUATION_MENU(mr); MR_NEXT_MENU(tmp) = MR_NEXT_MENU(mr); MR_NEXT_MENU(mr) = tmp; MR_WINDOW(tmp) = None; memset(&(MR_DYNAMIC_FLAGS(tmp)), 0, sizeof(MR_DYNAMIC_FLAGS(tmp))); return tmp; } /* * * Procedure: * clone_menu - duplicates an existing menu in newly allocated memory. The new menu is independent of the original. * * Returned Value: * (MenuRoot *) * * Inputs: * mr - the MenuRoot structure of the existing menu * */ static void clone_menu_root_static( MenuRoot *dest_mr, MenuRoot *src_mr) { dest_mr->s = (MenuRootStatic *)safemalloc(sizeof(MenuRootStatic)); /* copy everything */ memcpy(dest_mr->s, src_mr->s, sizeof(MenuRootStatic)); /* special treatment for a few parts */ if (MR_NAME(src_mr) != NULL) { MR_NAME(dest_mr) = safestrdup(MR_NAME(src_mr)); } MR_COPIES(dest_mr) = 1; MR_MAPPED_COPIES(dest_mr) = 0; MR_POPUP_ACTION(dest_mr) = NULL; MR_POPDOWN_ACTION(dest_mr) = NULL; if (MR_MISSING_SUBMENU_FUNC(src_mr)) { MR_MISSING_SUBMENU_FUNC(dest_mr) = safestrdup(MR_MISSING_SUBMENU_FUNC(src_mr)); } if (MR_HAS_SIDECOLOR(src_mr)) { MR_SIDECOLOR(dest_mr) = fvwmlib_clone_color(MR_SIDECOLOR(src_mr)); } MR_SIDEPIC(dest_mr) = PCloneFvwmPicture(MR_SIDEPIC(src_mr)); clone_menu_item_list(dest_mr, src_mr); return; } static MenuRoot *clone_menu(MenuRoot *mr) { MenuRoot *new_mr; new_mr = (MenuRoot *)safemalloc(sizeof(MenuRoot)); new_mr->d = (MenuRootDynamic *)safemalloc(sizeof(MenuRootDynamic)); memset(new_mr->d, 0, sizeof(MenuRootDynamic)); clone_menu_root_static(new_mr, mr); return new_mr; } /* ---------------------------- position hints ----------------------------- */ static int float_to_int_with_tolerance(float f) { int low; if (f < 0) { low = (int)(f - ROUNDING_ERROR_TOLERANCE); } else { low = (int)(f + ROUNDING_ERROR_TOLERANCE); } if ((int)f != low) { return low; } else { return (int)(f); } } static void get_xy_from_position_hints( struct MenuPosHints *ph, int width, int height, int context_width, Bool do_reverse_x, int *ret_x, int *ret_y) { float x_add; float y_add; *ret_x = ph->x; *ret_y = ph->y; if (ph->is_menu_relative) { if (do_reverse_x) { *ret_x -= ph->x_offset; x_add = width * (-1.0 - ph->x_factor) + ph->menu_width * (1.0 - ph->context_x_factor); } else { *ret_x += ph->x_offset; x_add = width * ph->x_factor + ph->menu_width * ph->context_x_factor; } y_add = height * ph->y_factor; } else { x_add = width * ph->x_factor; y_add = height * ph->y_factor; } *ret_x += float_to_int_with_tolerance(x_add); *ret_y += float_to_int_with_tolerance(y_add); return; } /* * Used by get_menu_options * * The vars are named for the x-direction, but this is used for both x and y */ static char *get_one_menu_position_argument( char *action, int x, int w, int *pFinalX, int *x_offset, float *width_factor, float *context_width_factor, Bool *is_menu_relative) { char *token, *orgtoken, *naction; char c; int val; int chars; float fval; float factor = (float)w/100; float x_add = 0; naction = GetNextToken(action, &token); if (token == NULL) { return action; } orgtoken = token; *pFinalX = x; *x_offset = 0; *width_factor = 0.0; *context_width_factor = 0.0; if (sscanf(token,"o%d%n", &val, &chars) >= 1) { fval = val; token += chars; x_add += fval*factor; *width_factor -= fval / 100.0; *context_width_factor += fval / 100.0; } else if (token[0] == 'c') { token++; x_add += ((float)w) / 2.0; *width_factor -= 0.5; *context_width_factor += 0.5; } while (*token != 0) { if (sscanf(token,"%d%n", &val, &chars) < 1) { naction = action; break; } fval = (float)val; token += chars; if (sscanf(token,"%c", &c) == 1) { switch (c) { case 'm': token++; *width_factor += fval / 100.0; *is_menu_relative = True; break; case 'p': token++; x_add += val; *x_offset += val; break; default: x_add += fval * factor; *context_width_factor += fval / 100.0; break; } } else { x_add += fval * factor; *context_width_factor += fval / 100.0; } } *pFinalX += float_to_int_with_tolerance(x_add); free(orgtoken); return naction; } /* Returns the menu options for the menu that a given menu item pops up */ static void get_popup_options( MenuParameters *pmp, MenuItem *mi, MenuOptions *pops) { if (!mi) { return; } pops->flags.has_poshints = 0; pops->pos_hints.has_screen_origin = True; pops->pos_hints.screen_origin_x = pmp->screen_origin_x; pops->pos_hints.screen_origin_y = pmp->screen_origin_y; /* just look past "Popup " in the action */ get_menu_options( SkipNTokens(MI_ACTION(mi), 2), MR_WINDOW(pmp->menu), NULL, NULL, pmp->menu, mi, pops); return; } /* ---------------------------- menu painting functions --------------------- */ static void clear_expose_menu_area(Window win, XEvent *e) { if (e == NULL) { XClearWindow(dpy, win); } else { XClearArea( dpy, win, e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height, False); } return; } /* * * Draws a picture on the left side of the menu * What about a SidePic Colorset ? (olicha 2002-08-21) * */ static void paint_side_pic(MenuRoot *mr, XEvent *pevent) { GC gc; FvwmPicture *sidePic; int ys; int yt; int h; int bw = MST_BORDER_WIDTH(mr); if (MR_SIDEPIC(mr)) { sidePic = MR_SIDEPIC(mr); } else if (MST_SIDEPIC(mr)) { sidePic = MST_SIDEPIC(mr); } else { return; } if (Pdepth < 2) { /* ? */ gc = SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)); } else { gc = FORE_GC(MST_MENU_INACTIVE_GCS(mr)); } if (sidePic->height > MR_HEIGHT(mr) - 2 * bw) { h = MR_HEIGHT(mr) - 2 * bw; ys = sidePic->height - h; yt = bw; } else { h = sidePic->height; ys = 0; yt = MR_HEIGHT(mr) - bw - sidePic->height; } if (pevent != NULL && pevent->type == Expose) { if ( pevent->xexpose.x + pevent->xexpose.width < MR_SIDEPIC_X_OFFSET(mr) || pevent->xexpose.x >= MR_SIDEPIC_X_OFFSET(mr) + sidePic->width) { /* out of x-range for side bar */ return; } if ( pevent->xexpose.y + pevent->xexpose.height < bw || pevent->xexpose.y >= bw + MR_HEIGHT(mr)) { /* in the border */ return; } if ( !(MR_HAS_SIDECOLOR(mr) || MST_HAS_SIDE_COLOR(mr)) && pevent->xexpose.y + pevent->xexpose.height < yt) { /* outside picture and no background */ return; } } if (MR_HAS_SIDECOLOR(mr)) { Globalgcv.foreground = MR_SIDECOLOR(mr); } else if (MST_HAS_SIDE_COLOR(mr)) { Globalgcv.foreground = MST_SIDE_COLOR(mr); } if (MR_HAS_SIDECOLOR(mr) || MST_HAS_SIDE_COLOR(mr)) { Globalgcm = GCForeground; XChangeGC(dpy, Scr.ScratchGC1, Globalgcm, &Globalgcv); XFillRectangle( dpy, MR_WINDOW(mr), Scr.ScratchGC1, MR_SIDEPIC_X_OFFSET(mr), bw, sidePic->width, MR_HEIGHT(mr) - 2 * bw); } else if (sidePic->alpha != None) { XClearArea( dpy, MR_WINDOW(mr), MR_SIDEPIC_X_OFFSET(mr), yt, sidePic->width, h, False); } PGraphicsRenderPicture( dpy, MR_WINDOW(mr), sidePic, 0, MR_WINDOW(mr), gc, Scr.MonoGC, Scr.AlphaGC, 0, ys, sidePic->width, h, MR_SIDEPIC_X_OFFSET(mr), yt, sidePic->width, h, False); return; } static Bool paint_menu_gradient_background( MenuRoot *mr, XEvent *pevent) { MenuStyle *ms = MR_STYLE(mr); int bw = MST_BORDER_WIDTH(mr); XRectangle bounds; Pixmap pmap; GC pmapgc; XGCValues gcv; unsigned long gcm = GCLineWidth; int switcher = -1; Bool do_clear = False; gcv.line_width = 1; bounds.x = bw; bounds.y = bw; bounds.width = MR_WIDTH(mr) - bw; bounds.height = MR_HEIGHT(mr) - bw; /* H, V, D and B gradients are optimized and have * their own code here. (if no dither) */ if (!ST_FACE(ms).u.grad.do_dither) { switcher = ST_FACE(ms).gradient_type; } switch (switcher) { case H_GRADIENT: if (MR_IS_BACKGROUND_SET(mr) == False) { register int i; register int dw; pmap = XCreatePixmap( dpy, MR_WINDOW(mr), MR_WIDTH(mr), DEFAULT_MENU_GRADIENT_PIXMAP_THICKNESS, Pdepth); pmapgc = fvwmlib_XCreateGC(dpy, pmap, gcm, &gcv); dw = (float) (bounds.width / ST_FACE(ms).u.grad.npixels) + 1; for (i = 0; i < ST_FACE(ms).u.grad.npixels; i++) { int x; x = i * bounds.width / ST_FACE(ms).u.grad.npixels; XSetForeground( dpy, pmapgc, ST_FACE(ms).u.grad.xcs[i].pixel); XFillRectangle( dpy, pmap, pmapgc, x, 0, dw, DEFAULT_MENU_GRADIENT_PIXMAP_THICKNESS); } XSetWindowBackgroundPixmap(dpy, MR_WINDOW(mr), pmap); XFreeGC(dpy,pmapgc); XFreePixmap(dpy,pmap); MR_IS_BACKGROUND_SET(mr) = True; } do_clear = True; break; case V_GRADIENT: if (MR_IS_BACKGROUND_SET(mr) == False) { register int i; register int dh; static int best_tile_width = 0; int junk; if (best_tile_width == 0) { int tw = DEFAULT_MENU_GRADIENT_PIXMAP_THICKNESS; if (!XQueryBestTile( dpy, Scr.screen, tw, tw, (unsigned int*)&best_tile_width, (unsigned int*)&junk)) { /* call failed, use default and risk a * screwed up tile */ best_tile_width = tw; } } pmap = XCreatePixmap( dpy, MR_WINDOW(mr), best_tile_width, MR_HEIGHT(mr), Pdepth); pmapgc = fvwmlib_XCreateGC(dpy, pmap, gcm, &gcv); dh = (float) (bounds.height / ST_FACE(ms).u.grad.npixels) + 1; for (i = 0; i < ST_FACE(ms).u.grad.npixels; i++) { int y; y = i * bounds.height / ST_FACE(ms).u.grad.npixels; XSetForeground( dpy, pmapgc, ST_FACE(ms).u.grad.xcs[i].pixel); XFillRectangle( dpy, pmap, pmapgc, 0, y, best_tile_width, dh); } XSetWindowBackgroundPixmap(dpy, MR_WINDOW(mr), pmap); XFreeGC(dpy,pmapgc); XFreePixmap(dpy,pmap); MR_IS_BACKGROUND_SET(mr) = True; } do_clear = True; break; case D_GRADIENT: case B_GRADIENT: { register int i = 0, numLines; int cindex = -1; XRectangle r; if (pevent) { r.x = pevent->xexpose.x; r.y = pevent->xexpose.y; r.width = pevent->xexpose.width; r.height = pevent->xexpose.height; } else { r.x = bw; r.y = bw; r.width = MR_WIDTH(mr) - 2 * bw; r.height = MR_HEIGHT(mr) - 2 * bw; } XSetClipRectangles( dpy, Scr.TransMaskGC, 0, 0, &r, 1, Unsorted); numLines = MR_WIDTH(mr) + MR_HEIGHT(mr) - 2 * bw; for (i = 0; i < numLines; i++) { if ((int)(i * ST_FACE(ms).u.grad.npixels / numLines) > cindex) { /* pick the next colour (skip if necc.) */ cindex = i * ST_FACE(ms).u.grad.npixels / numLines; XSetForeground( dpy, Scr.TransMaskGC, ST_FACE(ms).u.grad.xcs[cindex].pixel); } if (ST_FACE(ms).gradient_type == D_GRADIENT) { XDrawLine(dpy, MR_WINDOW(mr), Scr.TransMaskGC, 0, i, i, 0); } else /* B_GRADIENT */ { XDrawLine(dpy, MR_WINDOW(mr), Scr.TransMaskGC, 0, MR_HEIGHT(mr) - 1 - i, i, MR_HEIGHT(mr) - 1); } } } XSetClipMask(dpy, Scr.TransMaskGC, None); break; default: if (MR_IS_BACKGROUND_SET(mr) == False) { int g_width; int g_height; /* let library take care of all other gradients */ pmap = XCreatePixmap( dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr), Pdepth); pmapgc = fvwmlib_XCreateGC(dpy, pmap, gcm, &gcv); /* find out the size the pixmap should be */ CalculateGradientDimensions( dpy, MR_WINDOW(mr), ST_FACE(ms).u.grad.npixels, ST_FACE(ms).gradient_type, ST_FACE(ms).u.grad.do_dither, &g_width, &g_height); /* draw the gradient directly into the window */ CreateGradientPixmap( dpy, MR_WINDOW(mr), pmapgc, ST_FACE(ms).gradient_type, g_width, g_height, ST_FACE(ms).u.grad.npixels, ST_FACE(ms).u.grad.xcs, ST_FACE(ms).u.grad.do_dither, &(MR_STORED_PIXELS(mr).d_pixels), &(MR_STORED_PIXELS(mr).d_npixels), pmap, bw, bw, MR_WIDTH(mr) - bw, MR_HEIGHT(mr) - bw, NULL); XSetWindowBackgroundPixmap(dpy, MR_WINDOW(mr), pmap); XFreeGC(dpy, pmapgc); XFreePixmap(dpy, pmap); MR_IS_BACKGROUND_SET(mr) = True; } do_clear = True; break; } return do_clear; } static Bool paint_menu_pixmap_background( MenuRoot *mr, XEvent *pevent) { MenuStyle *ms = MR_STYLE(mr); int width, height, x, y; int bw = MST_BORDER_WIDTH(mr); FvwmPicture *p; p = ST_FACE(ms).u.p; width = MR_WIDTH(mr) - 2 * bw; height = MR_HEIGHT(mr) - 2 * bw; y = (int)(height - p->height) / 2; x = (int)(width - p->width) / 2; if (x < bw) { x = bw; } if (y < bw) { y = bw; } if (width > p->width) { width = p->width; } if (height > p->height) { height = p->height; } if (width > MR_WIDTH(mr) - x - bw) { width = MR_WIDTH(mr) - x - bw; } if (height > MR_HEIGHT(mr) - y - bw) { height = MR_HEIGHT(mr) - y - bw; } XSetClipMask(dpy, Scr.TransMaskGC, p->mask); XSetClipOrigin(dpy, Scr.TransMaskGC, x, y); XCopyArea( dpy, p->picture, MR_WINDOW(mr), Scr.TransMaskGC, bw, bw, width, height, x, y); return False; } /* * * Procedure: * get_menu_paint_item_parameters - prepares the parameters to be * passed to menuitem_paint(). * * mr - the menu instance that holds the menu item * mi - the menu item to redraw * fw - the FvwmWindow structure to check against allowed functions * */ static void get_menu_paint_item_parameters( MenuPaintItemParameters *mpip, MenuRoot *mr, MenuItem *mi, FvwmWindow *fw, XEvent *pevent, Bool do_redraw_menu_border) { mpip->ms = MR_STYLE(mr); mpip->w = MR_WINDOW(mr); mpip->selected_item = MR_SELECTED_ITEM(mr); mpip->dim = &MR_DIM(mr); mpip->fw = fw; mpip->used_mini_icons = MR_USED_MINI_ICONS(mr); mpip->cb_mr = mr; mpip->cb_reset_bg = paint_menu_gradient_background; mpip->flags.is_first_item = (MR_FIRST_ITEM(mr) == mi); mpip->flags.is_left_triangle = MR_IS_LEFT_TRIANGLE(mr); mpip->ev = pevent; return; } /* * * Procedure: * paint_menu - draws the entire menu * */ static void paint_menu( MenuRoot *mr, XEvent *pevent, FvwmWindow *fw) { MenuItem *mi; MenuStyle *ms = MR_STYLE(mr); int bw = MST_BORDER_WIDTH(mr); int relief_thickness = ST_RELIEF_THICKNESS(MR_STYLE(mr)); if (fw && !check_if_fvwm_window_exists(fw)) { fw = NULL; } if (MR_IS_PAINTED(mr) && pevent && (pevent->xexpose.x >= MR_WIDTH(mr) - bw || pevent->xexpose.x + pevent->xexpose.width <= bw || pevent->xexpose.y >= MR_HEIGHT(mr) - bw || pevent->xexpose.y + pevent->xexpose.height <= bw)) { /* Only the border was obscured. Redraw it centrally instead of * redrawing several menu items. */ RelieveRectangle( dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1, MR_HEIGHT(mr) - 1, (Pdepth < 2) ? SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) : HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)), SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw); { return; } } MR_IS_PAINTED(mr) = 1; /* paint the menu background */ if (ms && ST_HAS_MENU_CSET(ms)) { if (MR_IS_BACKGROUND_SET(mr) == False) { SetWindowBackground( dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr), &Colorset[ST_CSET_MENU(ms)], Pdepth, FORE_GC(ST_MENU_INACTIVE_GCS(ms)), True); MR_IS_BACKGROUND_SET(mr) = True; } } else if (ms) { int type; Bool do_clear = False; type = ST_FACE(ms).type; switch(type) { case SolidMenu: XSetWindowBackground( dpy, MR_WINDOW(mr), MST_FACE(mr).u.back); do_clear = True; break; case GradientMenu: do_clear = paint_menu_gradient_background(mr, pevent); break; case PixmapMenu: do_clear = paint_menu_pixmap_background(mr, pevent); break; case TiledPixmapMenu: XSetWindowBackgroundPixmap( dpy, MR_WINDOW(mr), ST_FACE(ms).u.p->picture); do_clear = True; break; } /* switch(type) */ if (do_clear == True) { clear_expose_menu_area(MR_WINDOW(mr), pevent); } } /* if (ms) */ /* draw the relief */ RelieveRectangle(dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1, MR_HEIGHT(mr) - 1, (Pdepth < 2) ? SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) : HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)), SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw); /* paint the menu items */ for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi)) { int do_draw = 0; /* be smart about handling the expose, redraw only the entries * that we need to */ if (pevent == NULL) { do_draw = True; } else { register int b_offset; b_offset = MI_Y_OFFSET(mi) + MI_HEIGHT(mi); if (MR_SELECTED_ITEM(mr) == mi) { b_offset += relief_thickness; } if (pevent->xexpose.y < b_offset && (pevent->xexpose.y + pevent->xexpose.height) > MI_Y_OFFSET(mi)) { do_draw = True; } } if (do_draw) { MenuPaintItemParameters mpip; get_menu_paint_item_parameters( &mpip, mr, NULL, fw, pevent, True); mpip.flags.is_first_item = (MR_FIRST_ITEM(mr) == mi); menuitem_paint(mi, &mpip); } } paint_side_pic(mr, pevent); XFlush(dpy); return; } /* Set the selected-ness state of the menuitem passed in */ static void select_menu_item( MenuRoot *mr, MenuItem *mi, Bool select, FvwmWindow *fw) { if (select == True && MR_SELECTED_ITEM(mr) != NULL && MR_SELECTED_ITEM(mr) != mi) { select_menu_item(mr, MR_SELECTED_ITEM(mr), False, fw); } else if (select == False && MR_SELECTED_ITEM(mr) == NULL) { return; } else if (select == True && MR_SELECTED_ITEM(mr) == mi) { return; } if (!MI_IS_SELECTABLE(mi)) { return; } if (select == False) { MI_WAS_DESELECTED(mi) = True; } if (!MST_HAS_MENU_CSET(mr)) { switch (MST_FACE(mr).type) { case GradientMenu: if (select == True) { int iy; int ih; int mw; XEvent e; if (!MR_IS_PAINTED(mr)) { FCheckWeedTypedWindowEvents( dpy, MR_WINDOW(mr), Expose, NULL); paint_menu(mr, NULL, fw); } iy = MI_Y_OFFSET(mi); ih = MI_HEIGHT(mi) + (MI_IS_SELECTABLE(mi) ? MST_RELIEF_THICKNESS(mr) : 0); if (iy < 0) { ih += iy; iy = 0; } mw = MR_WIDTH(mr) - 2 * MST_BORDER_WIDTH(mr); if (iy + ih > MR_HEIGHT(mr)) ih = MR_HEIGHT(mr) - iy; /* grab image */ MR_STORED_ITEM(mr).stored = XCreatePixmap( dpy, Scr.NoFocusWin, mw, ih, Pdepth); XSetGraphicsExposures( dpy, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), True); XSync(dpy, 0); while (FCheckTypedEvent(dpy, NoExpose, &e)) { /* nothing to do here */ } XCopyArea( dpy, MR_WINDOW(mr), MR_STORED_ITEM(mr).stored, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), MST_BORDER_WIDTH(mr), iy, mw, ih, 0, 0); XSync(dpy, 0); if (FCheckTypedEvent(dpy, NoExpose, &e)) { MR_STORED_ITEM(mr).y = iy; MR_STORED_ITEM(mr).width = mw; MR_STORED_ITEM(mr).height = ih; } else { XFreePixmap( dpy, MR_STORED_ITEM(mr).stored); MR_STORED_ITEM(mr).stored = None; MR_STORED_ITEM(mr).width = 0; MR_STORED_ITEM(mr).height = 0; MR_STORED_ITEM(mr).y = 0; } XSetGraphicsExposures( dpy, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False); } else if (select == False && MR_STORED_ITEM(mr).width != 0) { /* ungrab image */ XCopyArea( dpy, MR_STORED_ITEM(mr).stored, MR_WINDOW(mr), FORE_GC(MST_MENU_INACTIVE_GCS(mr)), 0, 0, MR_STORED_ITEM(mr).width, MR_STORED_ITEM(mr).height, MST_BORDER_WIDTH(mr), MR_STORED_ITEM(mr).y); if (MR_STORED_ITEM(mr).stored != None) { XFreePixmap( dpy, MR_STORED_ITEM(mr).stored); } MR_STORED_ITEM(mr).stored = None; MR_STORED_ITEM(mr).width = 0; MR_STORED_ITEM(mr).height = 0; MR_STORED_ITEM(mr).y = 0; } else if (select == False) { XEvent e; FvwmPicture *sidePic = NULL; e.type = Expose; e.xexpose.x = MST_BORDER_WIDTH(mr); e.xexpose.y = MI_Y_OFFSET(mi); e.xexpose.width = MR_WIDTH(mr) - 2 * MST_BORDER_WIDTH(mr); e.xexpose.height = MI_HEIGHT(mi) + (MI_IS_SELECTABLE(mi) ? MST_RELIEF_THICKNESS(mr) : 0); if (MR_SIDEPIC(mr)) { sidePic = MR_SIDEPIC(mr); } else if (MST_SIDEPIC(mr)) { sidePic = MST_SIDEPIC(mr); } if (sidePic) { e.xexpose.width -= sidePic->width; if (MR_SIDEPIC_X_OFFSET(mr) == MST_BORDER_WIDTH(mr)) { e.xexpose.x += sidePic->width; } } MR_SELECTED_ITEM(mr) = (select) ? mi : NULL; paint_menu(mr, &e, fw); } break; default: if (MR_STORED_ITEM(mr).width != 0) { if (MR_STORED_ITEM(mr).stored != None) { XFreePixmap( dpy, MR_STORED_ITEM(mr).stored); } MR_STORED_ITEM(mr).stored = None; MR_STORED_ITEM(mr).width = 0; MR_STORED_ITEM(mr).height = 0; MR_STORED_ITEM(mr).y = 0; } break; } /* switch */ } /* if */ if (fw && !check_if_fvwm_window_exists(fw)) { fw = NULL; } MR_SELECTED_ITEM(mr) = (select) ? mi : NULL; if (MR_IS_PAINTED(mr)) { MenuPaintItemParameters mpip; get_menu_paint_item_parameters(&mpip, mr, mi, fw, NULL, False); menuitem_paint(mi, &mpip); } return; } /* ---------------------------- popping menu up or down -------------------- */ static int get_left_popup_x_position(MenuRoot *mr, MenuRoot *submenu, int x) { if (MST_USE_LEFT_SUBMENUS(mr)) { return (x - MST_POPUP_OFFSET_ADD(mr) - MR_WIDTH(submenu) + MR_WIDTH(mr) * (100 - MST_POPUP_OFFSET_PERCENT(mr)) / 100); } else { return (x - MR_WIDTH(submenu) + MST_BORDER_WIDTH(mr)); } } static int get_right_popup_x_position(MenuRoot *mr, MenuRoot *submenu, int x) { if (MST_USE_LEFT_SUBMENUS(mr)) { return (x + MR_WIDTH(mr) - MST_BORDER_WIDTH(mr)); } else { return (x + MR_WIDTH(mr) * MST_POPUP_OFFSET_PERCENT(mr) / 100 + MST_POPUP_OFFSET_ADD(mr)); } } static void get_prefered_popup_position( MenuRoot *mr, MenuRoot *submenu, int *px, int *py, Bool *pprefer_left_submenus) { int menu_x, menu_y; MenuItem *mi = NULL; if (!menu_get_geometry( mr, &JunkRoot, &menu_x, &menu_y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { *px = 0; *py = 0; *pprefer_left_submenus = False; fvwm_msg(ERR, "get_prefered_popup_position", "can't get geometry of menu %s", MR_NAME(mr)); return; } /* set the direction flag */ *pprefer_left_submenus = (MR_HAS_POPPED_UP_LEFT(mr) || (MST_USE_LEFT_SUBMENUS(mr) && !MR_HAS_POPPED_UP_RIGHT(mr))); /* get the x position */ if (*pprefer_left_submenus) { *px = get_left_popup_x_position(mr, submenu, menu_x); } else { *px = get_right_popup_x_position(mr, submenu, menu_x); } /* get the y position */ if (MR_SELECTED_ITEM(mr)) { mi = MR_SELECTED_ITEM(mr); } if (mi) { *py = menu_y + MI_Y_OFFSET(mi) - MST_BORDER_WIDTH(mr) + MST_RELIEF_THICKNESS(mr); } else { *py = menu_y; } } static int do_menus_overlap( MenuRoot *mr, int x, int y, int width, int height, int h_tolerance, int v_tolerance, int s_tolerance, Bool allow_popup_offset_tolerance) { int prior_x, prior_y, x_overlap; int prior_width, prior_height; if (mr == NULL) { return 0; } if (!menu_get_geometry( mr, &JunkRoot,&prior_x,&prior_y, &prior_width, &prior_height, &JunkBW, &JunkDepth)) { return 0; } x_overlap = 0; if (allow_popup_offset_tolerance) { if (MST_POPUP_OFFSET_ADD(mr) < 0) { s_tolerance = -MST_POPUP_OFFSET_ADD(mr); } if (MST_USE_LEFT_SUBMENUS(mr)) { prior_x += (100 - MST_POPUP_OFFSET_PERCENT(mr)) / 100; } else { prior_width *= (float)(MST_POPUP_OFFSET_PERCENT(mr)) / 100.0; } } if (MST_USE_LEFT_SUBMENUS(mr)) { int t = s_tolerance; s_tolerance = h_tolerance; h_tolerance = t; } if (y < prior_y + prior_height - v_tolerance && prior_y < y + height - v_tolerance && x < prior_x + prior_width - s_tolerance && prior_x < x + width - h_tolerance) { x_overlap = x - prior_x; if (x <= prior_x) { x_overlap--; } } return x_overlap; } /* * * Procedure: * pop_menu_up - pop up a pull down menu * * Inputs: * x, y - location of upper left of menu * do_warp_to_item - warp pointer to the first item after title * pops - pointer to the menu options for new menu * */ static int pop_menu_up( MenuRoot **pmenu, MenuParameters *pmp, MenuRoot *parent_menu, MenuItem *parent_item, const exec_context_t **pexc, int x, int y, Bool prefer_left_submenu, Bool do_warp_to_item, MenuOptions *pops, Bool *ret_overlap, Window popdown_window) { Bool do_warp_to_title = False; int x_overlap = 0; int x_clipped_overlap; MenuRoot *mrMi; MenuRoot *mr; FvwmWindow *fw; int context; int bw = 0; int bwp = 0; int prev_x; int prev_y; int prev_width; int prev_height; unsigned int event_mask; int scr_x, scr_y; int scr_w, scr_h; mr = *pmenu; if (!mr || (MR_MAPPED_COPIES(mr) > 0 && MR_COPIES(mr) >= MAX_MENU_COPIES)) { return False; } /* * handle dynamic menu actions */ /* First of all, execute the popup action (if defined). */ if (MR_POPUP_ACTION(mr)) { char *menu_name; saved_pos_hints pos_hints; Bool is_busy_grabbed = False; int mapped_copies = MR_MAPPED_COPIES(mr); /* save variables that we still need but that may be * overwritten */ menu_name = safestrdup(MR_NAME(mr)); pos_hints = last_saved_pos_hints; if (Scr.BusyCursor & BUSY_DYNAMICMENU) { is_busy_grabbed = GrabEm(CRS_WAIT, GRAB_BUSYMENU); } /* Execute the action */ __menu_execute_function(pmp->pexc, MR_POPUP_ACTION(mr)); if (is_busy_grabbed) { UngrabEm(GRAB_BUSYMENU); } /* restore the stuff we saved */ last_saved_pos_hints = pos_hints; if (mapped_copies == 0) { /* Now let's see if the menu still exists. It may have * been destroyed and recreated, so we have to look for * a menu with the saved name. menus_find_menu() always * returns the original menu, not one of its copies, so * below logic would fail miserably if used with a menu * copy. On the other hand, menu copies can't be * deleted within a dynamic popup action, so just * ignore this case. */ *pmenu = menus_find_menu(menu_name); if (menu_name) { free(menu_name); } mr = *pmenu; } } if (mr) { update_menu(mr, pmp); } if (mr == NULL || MR_FIRST_ITEM(mr) == NULL || MR_ITEMS(mr) == 0) { /* The menu deleted itself or all its items or it has been * empty from the start. */ return False; } fw = (*pexc)->w.fw; if (fw && !check_if_fvwm_window_exists(fw)) { fw = NULL; } context = (*pexc)->w.wcontext; /* * Create a new menu instance (if necessary) */ if (MR_MAPPED_COPIES(mr) > 0) { /* create a new instance of the menu */ *pmenu = copy_menu_root(*pmenu); if (!*pmenu) { return False; } make_menu_window(*pmenu, False); mr = *pmenu; } /* * Evaluate position hints */ /* calculate position from position hints if available */ if (pops->flags.has_poshints && !last_saved_pos_hints.flags.do_ignore_pos_hints) { get_xy_from_position_hints( &(pops->pos_hints), MR_WIDTH(mr), MR_HEIGHT(mr), (parent_menu) ? MR_WIDTH(parent_menu) : 0, prefer_left_submenu, &x, &y); } /* * Initialise new menu */ MR_PARENT_MENU(mr) = parent_menu; MR_PARENT_ITEM(mr) = parent_item; MR_IS_PAINTED(mr) = 0; MR_IS_LEFT(mr) = 0; MR_IS_RIGHT(mr) = 0; MR_IS_UP(mr) = 0; MR_IS_DOWN(mr) = 0; MR_XANIMATION(mr) = 0; InstallFvwmColormap(); /* * Handle popups from button clicks on buttons in the title bar, * or the title bar itself. Position hints override this. */ if (!pops->flags.has_poshints && fw && parent_menu == NULL && pmp->flags.is_first_root_menu) { int cx; int cy; int gx; int gy; Bool has_context; rectangle button_g; has_context = get_title_button_geometry( fw, &button_g, context); if (has_context) { fscreen_scr_arg fscr; get_title_gravity_factors(fw, &gx, &gy); cx = button_g.x + button_g.width / 2; cy = button_g.y + button_g.height / 2; if (gx != 0) { x = button_g.x + (gx == 1) * button_g.width - (gx == -1) * MR_WIDTH(mr); } if (gy != 0) { y = button_g.y + (gy == 1) * button_g.height - (gy == -1) * MR_HEIGHT(mr); } if (gx == 0 && x < button_g.x) { x = button_g.x; } else if (gx == 0 && x + MR_WIDTH(mr) >= button_g.x + button_g.width) { x = button_g.x + button_g.width - MR_WIDTH(mr); } if (gy == 0 && y < button_g.y) { y = button_g.y; } else if (gy == 0 && y + MR_HEIGHT(mr) >= button_g.y + button_g.height) { y = button_g.y + button_g.height - MR_HEIGHT(mr); } pops->pos_hints.has_screen_origin = True; fscr.xypos.x = cx; fscr.xypos.y = cy; if (FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &JunkX, &JunkY, &JunkWidth, &JunkHeight)) { /* use current cx/cy */ } else if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &cx, &cy, &JunkX, &JunkY, &JunkMask)) { /* use pointer's position */ } else { cx = -1; cy = -1; } pops->pos_hints.screen_origin_x = cx; pops->pos_hints.screen_origin_y = cy; } } /* if (pops->flags.has_poshints) */ /* * Clip to screen */ { fscreen_scr_arg fscr; fscr.xypos.x = pops->pos_hints.screen_origin_x; fscr.xypos.y = pops->pos_hints.screen_origin_y; /* clip to screen */ FScreenClipToScreen( &fscr, FSCREEN_XYPOS, &x, &y, MR_WIDTH(mr), MR_HEIGHT(mr)); /* "this" screen is defined -- so get its coords for future * reference */ FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &scr_x, &scr_y, &scr_w, &scr_h); } if (parent_menu) { bw = MST_BORDER_WIDTH(mr); bwp = MST_BORDER_WIDTH(parent_menu); x_overlap = do_menus_overlap( parent_menu, x, y, MR_WIDTH(mr), MR_HEIGHT(mr), bwp, bwp, bwp, True); } /* * Calculate position and animate menus */ if (parent_menu == NULL || !menu_get_geometry( parent_menu, &JunkRoot, &prev_x, &prev_y, &prev_width, &prev_height, &JunkBW, &JunkDepth)) { MR_HAS_POPPED_UP_LEFT(mr) = 0; MR_HAS_POPPED_UP_RIGHT(mr) = 0; } else { int left_x; int right_x; Bool use_left_submenus = MST_USE_LEFT_SUBMENUS(mr); MenuRepaintTransparentParameters mrtp; Bool transparent_bg = False; /* check if menus overlap */ x_clipped_overlap = do_menus_overlap( parent_menu, x, y, MR_WIDTH(mr), MR_HEIGHT(mr), bwp, bwp, bwp, True); if (x_clipped_overlap && (!pops->flags.has_poshints || pops->pos_hints.is_relative == False || x_overlap == 0)) { /* menus do overlap, but do not reposition if overlap * was caused by relative positioning hints */ left_x = get_left_popup_x_position( parent_menu, mr, prev_x); right_x = get_right_popup_x_position( parent_menu, mr, prev_x); if (use_left_submenus) { if (left_x + MR_WIDTH(mr) < prev_x + bwp) { left_x = prev_x + bwp - MR_WIDTH(mr); } } else { if (right_x > prev_x + prev_width - bwp) { right_x = prev_x + prev_width - bwp; } } /* * Animate parent menu */ if (MST_IS_ANIMATED(mr)) { /* animate previous out of the way */ int a_left_x; int a_right_x; int end_x; Window w; if (use_left_submenus) { if (prev_x - left_x < MR_WIDTH(mr)) { a_right_x = x + (prev_x - left_x); } else { a_right_x = x + MR_WIDTH(mr) - bw; } a_left_x = x - MR_WIDTH(parent_menu); } else { if (right_x - prev_x < prev_width) { a_left_x = x + (prev_x - right_x); } else { a_left_x = x - prev_width + bw; } a_right_x = x + MR_WIDTH(mr); } if (prefer_left_submenu) { /* popup menu is left of old menu, try * to move prior menu right */ if (a_right_x + prev_width <= scr_x + scr_w) { end_x = a_right_x; } else if (a_left_x >= scr_x) { end_x = a_left_x; } else { end_x = scr_x + scr_w - prev_width; } } else { /* popup menu is right of old menu, try * to move prior menu left */ if (a_left_x >= scr_x) { end_x = a_left_x; } else if (a_right_x + prev_width <= scr_x + scr_w) { end_x = a_right_x; } else { end_x = scr_x; } } if (end_x == a_left_x || end_x == 0) { MR_HAS_POPPED_UP_LEFT(mr) = 0; MR_HAS_POPPED_UP_RIGHT(mr) = 1; } else { MR_HAS_POPPED_UP_LEFT(mr) = 1; MR_HAS_POPPED_UP_RIGHT(mr) = 0; } MR_XANIMATION(parent_menu) += end_x - prev_x; if (ST_HAS_MENU_CSET(MR_STYLE(parent_menu)) && CSET_IS_TRANSPARENT( ST_CSET_MENU( MR_STYLE(parent_menu)))) { transparent_bg = True; get_menu_repaint_transparent_parameters( &mrtp, parent_menu, fw); } if (MR_IS_TEAR_OFF_MENU(parent_menu)) { int cx; int cy; w = FW_W_FRAME( pmp->tear_off_root_menu_window ); if (XGetGeometry( dpy, w, &JunkRoot, &cx, &cy, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { end_x += (cx - prev_x ); prev_x = cx; prev_y = cy; } } else { w = MR_WINDOW(parent_menu); } AnimatedMoveOfWindow( w, prev_x, prev_y, end_x, prev_y, True, -1, NULL, (transparent_bg)? &mrtp:NULL); } /* if (MST_IS_ANIMATED(mr)) */ /* * Try the other side of the parent menu */ else if (!pops->flags.is_fixed) { Bool may_use_left; Bool may_use_right; Bool do_use_left; Bool use_left_as_last_resort; use_left_as_last_resort = (left_x > scr_x + scr_w - right_x - MR_WIDTH(mr)); may_use_left = (left_x >= scr_x); may_use_right = (right_x + MR_WIDTH(mr) <= scr_x + scr_w); if (!may_use_left && !may_use_right) { /* If everything goes wrong, put the * submenu on the side with more free * space. */ do_use_left = use_left_as_last_resort; } else if (may_use_left && (prefer_left_submenu || !may_use_right)) { do_use_left = True; } else { do_use_left = False; } x = (do_use_left) ? left_x : right_x; MR_HAS_POPPED_UP_LEFT(mr) = do_use_left; MR_HAS_POPPED_UP_RIGHT(mr) = !do_use_left; /* Force the menu onto the screen, but leave at * least PARENT_MENU_FORCE_VISIBLE_WIDTH pixels * of the parent menu visible */ if (x + MR_WIDTH(mr) > scr_x + scr_w) { int d = x + MR_WIDTH(mr) - (scr_x + scr_w); int c; if (prev_width >= PARENT_MENU_FORCE_VISIBLE_WIDTH) { c = PARENT_MENU_FORCE_VISIBLE_WIDTH + prev_x; } else { c = prev_x + prev_width; } if (x - c >= d || x <= prev_x) { x -= d; } else if (x > c) { x = c; } } if (x < scr_x) { int c = prev_width - PARENT_MENU_FORCE_VISIBLE_WIDTH; if (c < 0) { c = 0; } if (scr_x - x > c) { x += c; } else { x = scr_x; } } } /* else if (non-overlapping menu style) */ } /* if (x_clipped_overlap && ...) */ else { MR_HAS_POPPED_UP_LEFT(mr) = prefer_left_submenu; MR_HAS_POPPED_UP_RIGHT(mr) = !prefer_left_submenu; } if (x < prev_x) { MR_IS_LEFT(mr) = 1; } if (x + MR_WIDTH(mr) > prev_x + prev_width) { MR_IS_RIGHT(mr) = 1; } if (y < prev_y) { MR_IS_UP(mr) = 1; } if (y + MR_HEIGHT(mr) > prev_y + prev_height) { MR_IS_DOWN(mr) = 1; } if (!MR_IS_LEFT(mr) && !MR_IS_RIGHT(mr)) { MR_IS_LEFT(mr) = 1; MR_IS_RIGHT(mr) = 1; } } /* if (parent_menu) */ /* * Make sure we have the correct events selected */ if (pmp->tear_off_root_menu_window == NULL) { /* normal menus and sub menus */ event_mask = XEVMASK_MENUW; } else if (parent_menu == NULL) { /* tear off menu needs more events */ event_mask = XEVMASK_TEAR_OFF_MENUW; } else { /* sub menus of tear off menus need LeaveNotify */ event_mask = XEVMASK_TEAR_OFF_SUBMENUW; } /* * Pop up the menu */ XMoveWindow(dpy, MR_WINDOW(mr), x, y); XSelectInput(dpy, MR_WINDOW(mr), event_mask); XMapRaised(dpy, MR_WINDOW(mr)); if (popdown_window) XUnmapWindow(dpy, popdown_window); XFlush(dpy); MR_MAPPED_COPIES(mr)++; MST_USAGE_COUNT(mr)++; if (ret_overlap) { *ret_overlap = do_menus_overlap( parent_menu, x, y, MR_WIDTH(mr), MR_HEIGHT(mr), 0, 0, 0, False) ? True : False; } /* * Warp the pointer */ if (!do_warp_to_item && parent_menu != NULL) { MenuItem *mi; mi = find_entry(pmp, NULL, &mrMi, None, -1, -1); if (mi && mrMi == mr && mi != MR_FIRST_ITEM(mrMi)) { /* pointer is on an item of the popup */ if (MST_DO_WARP_TO_TITLE(mr)) { /* warp pointer if not on a root menu */ do_warp_to_title = True; } } } /* if (!do_warp_to_item) */ if (pops->flags.do_not_warp) { do_warp_to_title = False; } else if (pops->flags.do_warp_title) { do_warp_to_title = True; } if (pops->flags.has_poshints && !last_saved_pos_hints.flags.do_ignore_pos_hints && pops->flags.do_warp_title) { do_warp_to_title = True; } if (do_warp_to_item) { /* also warp */ MR_SELECTED_ITEM(mr) = NULL; warp_pointer_to_item( mr, MR_FIRST_ITEM(mr), True /* skip Title */); select_menu_item(mr, MR_SELECTED_ITEM(mr), True, fw); } else if (do_warp_to_title) { /* Warp pointer to middle of top line, since we don't * want the user to come up directly on an option */ warp_pointer_to_title(mr); } return True; } /* * * Procedure: * pop_menu_down - unhighlight the current menu selection and * take down the menus * * mr - menu to pop down; this pointer is invalid after the function * returns. Don't use it anymore! * parent - the menu that has spawned mr (may be NULL). this is * used to see if mr was spawned by itself on some level. * this is a hack to allow specifying 'Popup foo' within * menu foo. You must use the MenuRoot that is currently * being processed here. DO NOT USE MR_PARENT_MENU(mr) here! * */ static void pop_menu_down(MenuRoot **pmr, MenuParameters *pmp) { MenuItem *mi; assert(*pmr); memset(&(MR_DYNAMIC_FLAGS(*pmr)), 0, sizeof(MR_DYNAMIC_FLAGS(*pmr))); XUnmapWindow(dpy, MR_WINDOW(*pmr)); MR_MAPPED_COPIES(*pmr)--; MST_USAGE_COUNT(*pmr)--; UninstallFvwmColormap(); XFlush(dpy); if ((mi = MR_SELECTED_ITEM(*pmr)) != NULL) { select_menu_item(*pmr, mi, False, (*pmp->pexc)->w.fw); } if (MR_STORED_PIXELS(*pmr).d_pixels != NULL) { PictureFreeColors( dpy, Pcmap, MR_STORED_PIXELS(*pmr).d_pixels, MR_STORED_PIXELS(*pmr).d_npixels, 0, False); free(MR_STORED_PIXELS(*pmr).d_pixels); MR_STORED_PIXELS(*pmr).d_pixels = NULL; } if (MR_COPIES(*pmr) > 1) { /* delete this instance of the menu */ DestroyMenu(*pmr, False, False); } else if (MR_POPDOWN_ACTION(*pmr)) { /* Finally execute the popdown action (if defined). */ saved_pos_hints pos_hints; /* save variables that we still need but that may be * overwritten */ pos_hints = last_saved_pos_hints; /* Execute the action */ __menu_execute_function(pmp->pexc, MR_POPDOWN_ACTION(*pmr)); /* restore the stuff we saved */ last_saved_pos_hints = pos_hints; } return; } /* * * Procedure: * pop_menu_down_and_repaint_parent - Pops down a menu and repaints the * overlapped portions of the parent menu. This is done only if * *fSubmenuOverlaps is True. *fSubmenuOverlaps is set to False * afterwards. * */ static void pop_menu_down_and_repaint_parent( MenuRoot **pmr, Bool *fSubmenuOverlaps, MenuParameters *pmp) { MenuRoot *parent = MR_PARENT_MENU(*pmr); XEvent event; int mr_x; int mr_y; int mr_width; int mr_height; int parent_x; int parent_y; int parent_width; int parent_height; if (*fSubmenuOverlaps && parent) { /* popping down the menu may destroy the menu via the dynamic * popdown action! Thus we must not access *pmr afterwards. */ /* Create a fake event to pass into paint_menu */ event.type = Expose; if (!menu_get_geometry( *pmr, &JunkRoot, &mr_x, &mr_y, &mr_width, &mr_height, &JunkBW, &JunkDepth) || !menu_get_geometry( parent, &JunkRoot, &parent_x, &parent_y, &parent_width, &parent_height, &JunkBW, &JunkDepth)) { pop_menu_down(pmr, pmp); paint_menu(parent, NULL, (*pmp->pexc)->w.fw); } else { pop_menu_down(pmr, pmp); event.xexpose.x = mr_x - parent_x; event.xexpose.width = mr_width; if (event.xexpose.x < 0) { event.xexpose.width += event.xexpose.x; event.xexpose.x = 0; } if (event.xexpose.x + event.xexpose.width > parent_width) { event.xexpose.width = parent_width - event.xexpose.x; } event.xexpose.y = mr_y - parent_y; event.xexpose.height = mr_height; if (event.xexpose.y < 0) { event.xexpose.height += event.xexpose.y; event.xexpose.y = 0; } if (event.xexpose.y + event.xexpose.height > parent_height) { event.xexpose.height = parent_height - event.xexpose.y; } flush_accumulate_expose(MR_WINDOW(parent), &event); paint_menu(parent, &event, (*pmp->pexc)->w.fw); } } else { /* popping down the menu may destroy the menu via the dynamic * popdown action! Thus we must not access *pmr afterwards. */ pop_menu_down(pmr, pmp); } *fSubmenuOverlaps = False; return; } /* ---------------------------- menu main loop ------------------------------ */ static void __mloop_init( MenuParameters *pmp, MenuReturn *pmret, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi, MenuOptions *pops) { memset(in, 0, sizeof(*in)); in->mif.do_force_reposition = 1; memset(med, 0, sizeof(*med)); msi->t0 = fev_get_evtime(); pmret->rc = MENU_NOP; memset(pops, 0, sizeof(*pops)); /* remember where the pointer was so we can tell if it has moved */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &(msi->x_init), &(msi->y_init), &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ msi->x_init = 0; msi->y_init = 0; } /* get the event mask right */ msi->event_mask = (pmp->tear_off_root_menu_window == NULL) ? XEVMASK_MENU : XEVMASK_TEAR_OFF_MENU; return; } static void __mloop_get_event_timeout_loop( MenuParameters *pmp, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi) { XEvent e = *(*pmp->pexc)->x.elast; while (!FPending(dpy) || !FCheckMaskEvent(dpy, msi->event_mask, &e)) { Bool is_popup_timed_out = (MST_POPUP_DELAY(pmp->menu) > 0 && med->popup_delay_10ms++ >= MST_POPUP_DELAY(pmp->menu) + 1); Bool is_popdown_timed_out = (MST_POPDOWN_DELAY(pmp->menu) > 0 && in->mrPopdown && med->popdown_delay_10ms++ >= MST_POPDOWN_DELAY(pmp->menu) + 1); Bool do_fake_motion = False; if (is_popup_timed_out) { med->popup_delay_10ms = MST_POPUP_DELAY(pmp->menu); } if (is_popdown_timed_out) { med->popdown_delay_10ms = MST_POPDOWN_DELAY(pmp->menu); } if ( in->mif.do_force_popup || (is_popup_timed_out && (is_popdown_timed_out || in->mif.is_item_entered_by_key_press || !in->mrPopdown || MST_DO_POPDOWN_IMMEDIATELY(pmp->menu)))) { in->mif.do_popup_now = True; in->mif.do_force_popup = False; do_fake_motion = True; in->mif.is_popped_up_by_timeout = True; is_popdown_timed_out = True; } if ((in->mrPopdown || in->mrPopup) && (is_popdown_timed_out || MST_DO_POPDOWN_IMMEDIATELY(pmp->menu))) { MenuRoot *m = (in->mrPopdown) ? in->mrPopdown : in->mrPopup; if (!m || med->mi != MR_PARENT_ITEM(m)) { in->mif.do_popdown_now = True; do_fake_motion = True; if (MST_DO_POPUP_IMMEDIATELY(pmp->menu)) { in->mif.do_popup_now = True; in->mif.is_popped_up_by_timeout = True; } else if ( !MST_DO_POPUP_IMMEDIATELY(pmp->menu) && in->mif.is_pointer_in_active_item_area) { in->mif.do_popup_now = True; in->mif.is_popped_up_by_timeout = True; } else if ( !MST_DO_POPUP_IMMEDIATELY(pmp->menu) && !MST_DO_POPDOWN_IMMEDIATELY(pmp->menu) && MST_POPUP_DELAY(pmp->menu) <= MST_POPDOWN_DELAY(pmp->menu) && med->popup_delay_10ms == med->popdown_delay_10ms) { in->mif.do_popup_now = True; in->mif.is_popped_up_by_timeout = True; } } } if (in->mif.do_popup_now && med->mi == in->miRemovedSubmenu && !in->mif.is_key_press) { /* prevent popping up the menu again with * RemoveSubemenus */ in->mif.do_popup_now = False; in->mif.do_force_popup = False; do_fake_motion = in->mif.do_popdown_now; in->mif.is_popped_up_by_timeout = False; } if (do_fake_motion) { /* fake a motion event, and set in->mif.do_popup_now */ e.type = MotionNotify; e.xmotion.time = fev_get_evtime(); fev_fake_event(&e); in->mif.is_motion_faked = True; break; } usleep(10000 /* 10 ms*/); } return; } static mloop_ret_code_t __mloop_get_event( MenuParameters *pmp, MenuReturn *pmret, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi) { XEvent e = *(*pmp->pexc)->x.elast; in->mif.do_popup_and_warp = False; in->mif.do_popup_now = False; in->mif.do_popdown_now = False; in->mif.do_propagate_event_into_submenu = False; in->mif.is_key_press = False; in->mif.is_button_release = 0; if (pmp->event_propagate_to_submenu) { /* handle an event that was passed in from the parent menu */ fev_fake_event(pmp->event_propagate_to_submenu); pmp->event_propagate_to_submenu = NULL; } else if (in->mif.do_recycle_event) { in->mif.is_popped_up_by_timeout = False; in->mif.do_recycle_event = 0; if (pmp->menu != pmret->target_menu) { /* the event is for a previous menu, just close this * one */ pmret->rc = MENU_PROPAGATE_EVENT; return MENU_MLOOP_RET_END; } if ((*pmp->pexc)->x.elast->type == KeyPress) { /* since the pointer has been warped since the key was * pressed, fake a different key press position */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &e.xkey.x_root, &e.xkey.y_root, &JunkX, &JunkY, &e.xkey.state) == False) { /* pointer is on a different screen */ e.xkey.x_root = 0; e.xkey.y_root = 0; } fev_fake_event(&e); med->mi = MR_SELECTED_ITEM(pmp->menu); } } else if (pmp->tear_off_root_menu_window != NULL && FCheckTypedWindowEvent( dpy, FW_W_PARENT(pmp->tear_off_root_menu_window), ClientMessage, &e)) { /* Got a ClientMessage for the tear out menu */ } else { if (in->mif.do_force_reposition) { e.type = MotionNotify; e.xmotion.time = fev_get_evtime(); in->mif.is_motion_faked = True; in->mif.do_force_reposition = False; in->mif.is_popped_up_by_timeout = False; fev_fake_event(&e); } else if (!FCheckMaskEvent(dpy, ExposureMask, &e)) { Bool is_popdown_timer_active = False; Bool is_popup_timer_active = False; if (MST_POPDOWN_DELAY(pmp->menu) > 0 && in->mi_with_popup != NULL && in->mi_with_popup != MR_SELECTED_ITEM(pmp->menu)) { is_popdown_timer_active = True; } if (MST_POPUP_DELAY(pmp->menu) > 0 && !in->mif.is_popped_up_by_timeout && in->mi_wants_popup != NULL) { is_popup_timer_active = True; } /* handle exposure events first */ if (in->mif.do_force_popup || in->mif.is_pointer_in_active_item_area || is_popdown_timer_active || is_popup_timer_active) { __mloop_get_event_timeout_loop( pmp, in, med, msi); } else { /* block until there is an event */ FMaskEvent(dpy, msi->event_mask, &e); in->mif.is_popped_up_by_timeout = False; } } else { in->mif.is_popped_up_by_timeout = False; } } in->mif.is_pointer_in_active_item_area = False; if (e.type == MotionNotify) { /* discard any extra motion events before a release */ while (FCheckMaskEvent( dpy, ButtonMotionMask | ButtonReleaseMask, &e) && (e.type != ButtonRelease)) { /* nothing */ } } return MENU_MLOOP_RET_NORMAL; } static mloop_ret_code_t __mloop_handle_event( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi) { MenuRoot *tmrMi; Bool rc; pmret->rc = MENU_NOP; switch ((*pmp->pexc)->x.elast->type) { case ButtonRelease: in->mif.is_button_release = 1; med->mi = find_entry( pmp, &med->x_offset, &med->mrMi, (*pmp->pexc)->x.elast->xbutton.subwindow, (*pmp->pexc)->x.elast->xbutton.x_root, (*pmp->pexc)->x.elast->xbutton.y_root); /* hold the menu up when the button is released * for the first time if released OFF of the menu */ if (pmp->flags.is_sticky && !in->mif.is_motion_first) { in->mif.is_release_first = True; pmp->flags.is_sticky = False; return MENU_MLOOP_RET_LOOP; } if (med->mrMi != NULL) { int menu_x; int menu_y; menu_shortcuts( med->mrMi, pmp, pmret, (*pmp->pexc)->x.elast, &med->mi, pdkp, &menu_x, &menu_y); if (pmret->rc == MENU_NEWITEM_MOVEMENU) { move_any_menu(med->mrMi, pmp, menu_x, menu_y); pmret->rc = MENU_NEWITEM; } else if (pmret->rc == MENU_NEWITEM_FIND) { med->mi = find_entry( pmp, NULL, NULL, None, -1, -1); pmret->rc = MENU_NEWITEM; } } else { pmret->rc = MENU_SELECTED; } switch (pmret->rc) { case MENU_NOP: return MENU_MLOOP_RET_LOOP; case MENU_POPDOWN: case MENU_ABORTED: case MENU_DOUBLE_CLICKED: case MENU_TEAR_OFF: case MENU_KILL_TEAR_OFF_MENU: case MENU_EXEC_CMD: return MENU_MLOOP_RET_END; case MENU_POPUP: /* Allow for MoveLeft/MoveRight action to work with * Mouse */ in->mif.do_popup_and_warp = True; case MENU_NEWITEM: /* unpost the menu if posted */ pmret->flags.is_menu_posted = 0; return MENU_MLOOP_RET_NORMAL; case MENU_SELECTED: in->mif.was_item_unposted = 0; if (pmret->flags.is_menu_posted && med->mrMi != NULL) { if (pmret->flags.do_unpost_submenu) { pmret->flags.do_unpost_submenu = 0; pmret->flags.is_menu_posted = 0; /* just ignore the event */ return MENU_MLOOP_RET_LOOP; } else if (med->mi && MI_IS_POPUP(med->mi) && med->mrMi == pmp->menu) { /* post menu - done below */ } else if (MR_PARENT_ITEM(pmp->menu) && med->mi == MR_PARENT_ITEM(pmp->menu)) { /* propagate back to parent menu * and unpost current menu */ pmret->flags.do_unpost_submenu = 1; pmret->rc = MENU_PROPAGATE_EVENT; pmret->target_menu = med->mrMi; return MENU_MLOOP_RET_END; } else if (med->mrMi != pmp->menu && med->mrMi != in->mrPopup) { /* unpost and propagate back to * ancestor */ pmret->flags.is_menu_posted = 0; pmret->rc = MENU_PROPAGATE_EVENT; pmret->target_menu = med->mrMi; return MENU_MLOOP_RET_END; } else if (in->mrPopup && med->mrMi == in->mrPopup) { /* unpost and propagate into * submenu */ in->mif.was_item_unposted = 1; in->mif.do_propagate_event_into_submenu = True; break; } else { /* simply unpost the menu */ pmret->flags.is_menu_posted = 0; } } if (is_double_click( msi->t0, med->mi, pmp, pmret, pdkp, in->mif.has_mouse_moved)) { pmret->rc = MENU_DOUBLE_CLICKED; return MENU_MLOOP_RET_END; } if (med->mi == NULL) { pmret->rc = MENU_ABORTED; } else if (MI_IS_POPUP(med->mi)) { switch (MST_DO_POPUP_AS(pmp->menu)) { case MDP_POST_MENU: if (in->mif.was_item_unposted) { pmret->flags.is_menu_posted = 0; pmret->rc = MENU_UNPOST; pmret->target_menu = NULL; in->mif.do_popup_now = False; } else { pmret->flags.is_menu_posted = 1; pmret->rc = MENU_POST; pmret->target_menu = NULL; in->mif.do_popup_now = True; if ((in->mrPopup || in->mrPopdown) && med->mi != MR_SELECTED_ITEM( pmp->menu)) { in->mif.do_popdown_now = True; } } return MENU_MLOOP_RET_NORMAL; case MDP_IGNORE: pmret->rc = MENU_NOP; return MENU_MLOOP_RET_NORMAL; case MDP_CLOSE: pmret->rc = MENU_ABORTED; break; case MDP_ROOT_MENU: default: break; } } break; default: break; } pdkp->timestamp = 0; return MENU_MLOOP_RET_END; case ButtonPress: /* if the first event is a button press allow the release to * select something */ pmp->flags.is_sticky = False; return MENU_MLOOP_RET_LOOP; case VisibilityNotify: return MENU_MLOOP_RET_LOOP; case KeyRelease: if ((*pmp->pexc)->x.elast->xkey.keycode != MST_SELECT_ON_RELEASE_KEY(pmp->menu)) { return MENU_MLOOP_RET_LOOP; } /* fall through to KeyPress */ case KeyPress: /* Handle a key press events to allow mouseless operation */ in->mif.is_key_press = True; med->x_offset = menudim_middle_x_offset(&MR_DIM(pmp->menu)); /* if there is a posted menu we may have to move back into a * previous menu or possibly ignore the mouse position */ if (pmret->flags.is_menu_posted) { MenuRoot *l_mrMi; int l_x_offset; XEvent e; pmret->flags.is_menu_posted = 0; (void)find_entry( pmp, &l_x_offset, &l_mrMi, None, -1, -1); if (l_mrMi != NULL) { if (pmp->menu != l_mrMi) { /* unpost the menu and propagate the * event to the correct menu */ pmret->rc = MENU_PROPAGATE_EVENT; pmret->target_menu = l_mrMi; return MENU_MLOOP_RET_END; } } med->mi = MR_SELECTED_ITEM(pmp->menu); e = *(*pmp->pexc)->x.elast; e.xkey.x_root = med->x_offset; e.xkey.y_root = menuitem_middle_y_offset( med->mi, MR_STYLE(pmp->menu)); fev_fake_event(&e); } /* now handle the actual key press */ { int menu_x; int menu_y; menu_shortcuts( pmp->menu, pmp, pmret, (*pmp->pexc)->x.elast, &med->mi, pdkp, &menu_x, &menu_y); if (pmret->rc == MENU_NEWITEM_MOVEMENU) { move_any_menu(pmp->menu, pmp, menu_x, menu_y); pmret->rc = MENU_NEWITEM; } else if (pmret->rc == MENU_NEWITEM_FIND) { med->mi = find_entry( pmp, NULL, NULL, None, -1, -1); pmret->rc = MENU_NEWITEM; } } if (pmret->rc != MENU_NOP) { /* using a key 'unposts' the posted menu */ pmret->flags.is_menu_posted = 0; } switch (pmret->rc) { case MENU_SELECTED: if (med->mi && MI_IS_POPUP(med->mi)) { switch (MST_DO_POPUP_AS(pmp->menu)) { case MDP_POST_MENU: pmret->rc = MENU_POPUP; break; case MDP_IGNORE: pmret->rc = MENU_NOP; return MENU_MLOOP_RET_NORMAL; case MDP_CLOSE: pmret->rc = MENU_ABORTED; return MENU_MLOOP_RET_END; case MDP_ROOT_MENU: default: return MENU_MLOOP_RET_END; } break; } return MENU_MLOOP_RET_END; case MENU_POPDOWN: case MENU_ABORTED: case MENU_DOUBLE_CLICKED: case MENU_TEAR_OFF: case MENU_KILL_TEAR_OFF_MENU: case MENU_EXEC_CMD: return MENU_MLOOP_RET_END; case MENU_NEWITEM: case MENU_POPUP: if (med->mrMi == NULL) { /* Set the MenuRoot of the current item in case * we have just warped to the menu from the * void or unposted a popup menu. */ med->mrMi = pmp->menu; } /*tmrMi = med->mrMi;*/ break; default: break; } /* now warp to the new menu item, if any */ if (pmret->rc == MENU_NEWITEM && med->mi) { warp_pointer_to_item(med->mrMi, med->mi, False); } if (pmret->rc == MENU_POPUP && med->mi && MI_IS_POPUP(med->mi)) { in->mif.do_popup_and_warp = True; break; } break; case MotionNotify: { int p_rx = -1; int p_ry = -1; Window p_child = None; if (in->mif.has_mouse_moved == False) { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &p_child, &p_rx, &p_ry, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ p_rx = 0; p_ry = 0; } if (p_rx - msi->x_init > Scr.MoveThreshold || msi->x_init - p_rx > Scr.MoveThreshold || p_ry - msi->y_init > Scr.MoveThreshold || msi->y_init - p_ry > Scr.MoveThreshold) { /* remember that this isn't just a click any * more since the pointer moved */ in->mif.has_mouse_moved = True; } } med->mi = find_entry( pmp, &med->x_offset, &med->mrMi, p_child, p_rx, p_ry); if (pmret->flags.is_menu_posted && med->mrMi != pmret->target_menu) { /* ignore mouse movement outside a posted menu */ med->mrMi = NULL; med->mi = NULL; } if (!in->mif.is_release_first && !in->mif.is_motion_faked && in->mif.has_mouse_moved) { in->mif.is_motion_first = True; } in->mif.is_motion_faked = False; break; } case Expose: /* grab our expose events, let the rest go through */ XFlush(dpy); rc = menu_expose((*pmp->pexc)->x.elast, (*pmp->pexc)->w.fw); /* we want to dispatch this too so that icons and maybe tear * off get redrawn after being obscured by menus. */ if (rc == False) { dispatch_event((*pmp->pexc)->x.elast); } return MENU_MLOOP_RET_LOOP; case ClientMessage: if ((*pmp->pexc)->x.elast->xclient.format == 32 && (*pmp->pexc)->x.elast->xclient.data.l[0] == _XA_WM_DELETE_WINDOW && pmp->tear_off_root_menu_window != NULL && (*pmp->pexc)->x.elast->xclient.window == FW_W_PARENT( pmp->tear_off_root_menu_window)) { /* handle deletion of tear out menus */ pmret->rc = MENU_KILL_TEAR_OFF_MENU; return MENU_MLOOP_RET_END; } break; case EnterNotify: /* ignore EnterNotify events */ break; case LeaveNotify: if (pmp->tear_off_root_menu_window != NULL && find_entry(pmp, NULL, &tmrMi, None, -1, -1) == NULL && tmrMi == NULL) { /* handle deletion of tear out menus */ pmret->rc = MENU_ABORTED; return MENU_MLOOP_RET_END; } /* ignore it */ return MENU_MLOOP_RET_LOOP; case UnmapNotify: /* should never happen, but does not hurt */ if (pmp->tear_off_root_menu_window != NULL && (*pmp->pexc)->x.elast->xunmap.window == FW_W(pmp->tear_off_root_menu_window)) { /* handle deletion of tear out menus */ pmret->rc = MENU_KILL_TEAR_OFF_MENU; /* extra safety: pass event back to main event loop to * make sure the window is destroyed */ FPutBackEvent(dpy, (*pmp->pexc)->x.elast); return MENU_MLOOP_RET_END; } break; default: /* We must not dispatch events here. There is no guarantee * that dispatch_event doesn't destroy a window stored in the * menu structures. Anyway, no events should ever get here * except to tear off menus and these must be handled * individually. */ #if 0 dispatch_event((*pmp->pexc)->x.elast); #endif break; } return MENU_MLOOP_RET_NORMAL; } static void __mloop_select_item( MenuParameters *pmp, mloop_evh_input_t *in, mloop_evh_data_t *med, Bool does_submenu_overlap, Bool *pdoes_popdown_submenu_overlap) { in->mif.is_item_entered_by_key_press = in->mif.is_key_press; med->popup_delay_10ms = 0; /* we're on the same menu, but a different item, so we need to unselect * the old item */ if (MR_SELECTED_ITEM(pmp->menu)) { /* something else was already selected on this menu. We have * to pop down the menu before unselecting the item in case we * are using gradient menus. The recalled image would paint * over the submenu. */ if (in->mrPopup && in->mrPopup != in->mrPopdown) { in->mrPopdown = in->mrPopup; med->popdown_delay_10ms = 0; *pdoes_popdown_submenu_overlap = does_submenu_overlap; in->mrPopup = NULL; } select_menu_item( pmp->menu, MR_SELECTED_ITEM(pmp->menu), False, (*pmp->pexc)->w.fw); } /* highlight the new item; sets MR_SELECTED_ITEM(pmp->menu) too */ select_menu_item(pmp->menu, med->mi, True, (*pmp->pexc)->w.fw); return; } static void __mloop_wants_popup( MenuParameters *pmp, mloop_evh_input_t *in, mloop_evh_data_t *med, MenuRoot *mrMiPopup) { Bool do_it_now = False; in->mi_wants_popup = med->mi; if (in->mif.do_popup_now) { do_it_now = True; } else if (MST_DO_POPUP_IMMEDIATELY(pmp->menu) && med->mi != in->miRemovedSubmenu) { if (in->mif.is_key_press || MST_DO_POPDOWN_IMMEDIATELY(pmp->menu) || !in->mrPopdown) { do_it_now = True; } } else if (pointer_in_active_item_area(med->x_offset, med->mrMi)) { if (in->mif.is_key_press || med->mi == in->miRemovedSubmenu || MST_DO_POPDOWN_IMMEDIATELY(pmp->menu) || !in->mrPopdown) { do_it_now = True; } else { in->mif.is_pointer_in_active_item_area = 1; } } if (do_it_now) { in->miRemovedSubmenu = NULL; /* must create a new menu or popup */ if (in->mrPopup == NULL || in->mrPopup != mrMiPopup) { if (in->mif.do_popup_now) { in->mif.do_popup = True; } else { /* pop up in next pass through loop */ in->mif.do_force_popup = True; } } else if (in->mif.do_popup_and_warp) { warp_pointer_to_item( in->mrPopup, MR_FIRST_ITEM(in->mrPopup), True); } } return; } static mloop_ret_code_t __mloop_make_popup( MenuParameters *pmp, MenuReturn *pmret, mloop_evh_input_t *in, mloop_evh_data_t *med, MenuOptions *pops, Bool *pdoes_submenu_overlap) { /* create a popup menu */ if (!is_submenu_mapped(pmp->menu, med->mi)) { /* We want to pop prepop menus so it doesn't *have* to be unpopped; do_menu pops down any menus it pops up, but we want to be able to popdown w/o actually removing the menu */ int x; int y; Bool prefer_left_submenus; /* Make sure we are using the latest style and menu layout. */ update_menu(in->mrPopup, pmp); get_prefered_popup_position( pmp->menu, in->mrPopup, &x, &y, &prefer_left_submenus); /* Note that we don't care if popping up the menu works. If it * doesn't we'll catch it below. */ pop_menu_up( &in->mrPopup, pmp, pmp->menu, med->mi, pmp->pexc, x, y, prefer_left_submenus, in->mif.do_popup_and_warp, pops, pdoes_submenu_overlap, (in->mrPopdown) ? MR_WINDOW(in->mrPopdown) : None); in->mi_with_popup = med->mi; in->mi_wants_popup = NULL; if (in->mrPopup == NULL) { /* the menu deleted itself when execution the dynamic * popup * action */ pmret->rc = MENU_ERROR; return MENU_MLOOP_RET_END; } MR_SUBMENU_ITEM(pmp->menu) = med->mi; } return MENU_MLOOP_RET_NORMAL; } static mloop_ret_code_t __mloop_get_mi_actions( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi, MenuRoot *mrMiPopup, Bool *pdoes_submenu_overlap, Bool *pdoes_popdown_submenu_overlap) { in->mif.do_popdown = False; in->mif.do_popup = False; in->mif.do_menu = False; in->mif.is_submenu_mapped = False; if (!in->mrPopup && in->mrPopdown && med->mi == MR_PARENT_ITEM(in->mrPopdown)) { /* We're again on the item that we left before. * Deschedule popping it down. */ in->mrPopup = in->mrPopdown; in->mrPopdown = NULL; } if (med->mrMi == in->mrPopup) { /* must make current popup menu a real menu */ in->mif.do_menu = True; in->mif.is_submenu_mapped = True; } else if (pmret->rc == MENU_POST) { /* must create a real menu and warp into it */ if (in->mrPopup == NULL || in->mrPopup != mrMiPopup) { in->mif.do_popup = True; } in->mif.do_menu = True; in->mif.is_submenu_mapped = True; } else if (in->mif.do_popup_and_warp) { /* must create a real menu and warp into it */ if (in->mrPopup == NULL || in->mrPopup != mrMiPopup) { in->mif.do_popup = True; } else { XRaiseWindow(dpy, MR_WINDOW(in->mrPopup)); warp_pointer_to_item( in->mrPopup, MR_FIRST_ITEM(in->mrPopup), True); in->mif.do_menu = True; in->mif.is_submenu_mapped = True; } } else if (med->mi && MI_IS_POPUP(med->mi)) { if ((*pmp->pexc)->x.elast->type == ButtonPress && is_double_click( msi->t0, med->mi, pmp, pmret, pdkp, in->mif.has_mouse_moved)) { pmret->rc = MENU_DOUBLE_CLICKED; return MENU_MLOOP_RET_END; } else if (!in->mrPopup || in->mrPopup != mrMiPopup || in->mif.do_popup_and_warp) { __mloop_wants_popup(pmp, in, med, mrMiPopup); } } if (in->mif.do_popdown_now) { in->mif.do_popdown = True; in->mif.do_popdown_now = False; } else if (in->mif.do_popup) { if (in->mrPopup && in->mrPopup != mrMiPopup) { in->mif.do_popdown = True; in->mrPopdown = in->mrPopup; med->popdown_delay_10ms = 0; *pdoes_popdown_submenu_overlap = *pdoes_submenu_overlap; } else if (in->mrPopdown && in->mrPopdown != mrMiPopup) { in->mif.do_popdown = True; } else if (in->mrPopdown && in->mrPopdown == mrMiPopup) { in->mrPopup = in->mrPopdown; *pdoes_submenu_overlap = *pdoes_popdown_submenu_overlap; in->mrPopdown = NULL; in->mif.do_popup = False; in->mif.do_popdown = False; } } return MENU_MLOOP_RET_NORMAL; } static void __mloop_do_popdown( MenuParameters *pmp, mloop_evh_input_t *in, Bool *pdoes_popdown_submenu_overlap) { if (in->mrPopdown) { pop_menu_down_and_repaint_parent( &in->mrPopdown, pdoes_popdown_submenu_overlap, pmp); in->mi_with_popup = NULL; MR_SUBMENU_ITEM(pmp->menu) = NULL; if (in->mrPopup == in->mrPopdown) { in->mrPopup = NULL; } in->mrPopdown = NULL; } in->mif.do_popdown = False; return; } static mloop_ret_code_t __mloop_do_popup( MenuParameters *pmp, MenuReturn *pmret, mloop_evh_input_t *in, mloop_evh_data_t *med, MenuOptions *pops, MenuRoot *mrMiPopup, Bool *pdoes_submenu_overlap, Bool *pdoes_popdown_submenu_overlap) { if (!MR_IS_PAINTED(pmp->menu)) { /* draw the parent menu if it is not already drawn */ FCheckWeedTypedWindowEvents( dpy, MR_WINDOW(pmp->menu), Expose, NULL); paint_menu(pmp->menu, NULL, (*pmp->pexc)->w.fw); } /* get pos hints for item's action */ get_popup_options(pmp, med->mi, pops); if (med->mrMi == pmp->menu && mrMiPopup == NULL && MI_IS_POPUP(med->mi) && MR_MISSING_SUBMENU_FUNC(pmp->menu)) { /* We're on a submenu item, but the submenu does not exist. * The user defined missing_submenu_action may create it. */ Bool is_complex_function; Bool is_busy_grabbed = False; char *menu_name; char *action; char *missing_action = MR_MISSING_SUBMENU_FUNC(pmp->menu); menu_name = PeekToken( SkipNTokens(MI_ACTION(med->mi), 1), NULL); if (!menu_name) { menu_name = ""; } is_complex_function = functions_is_complex_function(missing_action); if (is_complex_function) { char *action_ptr; action = safemalloc( strlen("Function") + 3 + strlen(missing_action) * 2 + 3 + strlen(menu_name) * 2 + 1); strcpy(action, "Function "); action_ptr = action + strlen(action); action_ptr = QuoteString(action_ptr, missing_action); *action_ptr++ = ' '; action_ptr = QuoteString(action_ptr, menu_name); } else { action = MR_MISSING_SUBMENU_FUNC(pmp->menu); } if (Scr.BusyCursor & BUSY_DYNAMICMENU) { is_busy_grabbed = GrabEm(CRS_WAIT, GRAB_BUSYMENU); } /* Execute the action */ __menu_execute_function(pmp->pexc, action); if (is_complex_function) { free(action); } if (is_busy_grabbed) { UngrabEm(GRAB_BUSYMENU); } /* Let's see if the menu exists now. */ mrMiPopup = mr_popup_for_mi(pmp->menu, med->mi); } /* run MISSING_SUBMENU_FUNCTION */ in->mrPopup = mrMiPopup; if (!in->mrPopup) { in->mif.do_menu = False; pmret->flags.is_menu_posted = 0; } else { if (__mloop_make_popup( pmp, pmret, in, med, pops, pdoes_submenu_overlap) == MENU_MLOOP_RET_END) { return MENU_MLOOP_RET_END; } } /* else (in->mrPopup) */ if (in->mif.do_popdown) { if (in->mrPopdown) { if (in->mrPopdown != in->mrPopup) { if (in->mi_with_popup == MR_PARENT_ITEM(in->mrPopdown)) { in->mi_with_popup = NULL; } pop_menu_down_and_repaint_parent( &in->mrPopdown, pdoes_popdown_submenu_overlap, pmp); } in->mrPopdown = NULL; } in->mif.do_popdown = False; } if (in->mrPopup) { if (MR_PARENT_MENU(in->mrPopup) == pmp->menu) { med->mi = find_entry( pmp, NULL, &med->mrMi, None, -1, -1); if (med->mi && med->mrMi == in->mrPopup) { in->mif.do_menu = True; in->mif.is_submenu_mapped = True; } } else { /* This menu must be already mapped somewhere else, so * ignore it completely. This can only happen if we * have reached the maximum allowed number of menu * copies. */ in->mif.do_menu = False; in->mif.do_popdown = False; in->mrPopup = NULL; } } return MENU_MLOOP_RET_NORMAL; } static mloop_ret_code_t __mloop_do_menu( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, mloop_evh_input_t *in, mloop_evh_data_t *med, MenuOptions *pops, Bool *pdoes_submenu_overlap) { MenuParameters mp; XEvent e; memset(&mp, 0, sizeof(mp)); mp.menu = in->mrPopup; mp.pexc = pmp->pexc; mp.parent_menu = pmp->menu; mp.parent_item = med->mi; mp.tear_off_root_menu_window = pmp->tear_off_root_menu_window; MR_IS_TEAR_OFF_MENU(in->mrPopup) = 0; mp.flags.has_default_action = False; mp.flags.is_already_mapped = in->mif.is_submenu_mapped; mp.flags.is_sticky = False; mp.flags.is_submenu = True; mp.flags.is_triggered_by_keypress = !!in->mif.do_popup_and_warp; mp.pops = pops; mp.ret_paction = pmp->ret_paction; mp.screen_origin_x = pmp->screen_origin_x; mp.screen_origin_y = pmp->screen_origin_y; if (in->mif.do_propagate_event_into_submenu) { e = *(*pmp->pexc)->x.elast; mp.event_propagate_to_submenu = &e; } else { mp.event_propagate_to_submenu = NULL; } /* recursively do the new menu we've moved into */ do_menu(&mp, pmret); in->mif.do_propagate_event_into_submenu = False; if (pmret->rc == MENU_PROPAGATE_EVENT) { in->mif.do_recycle_event = 1; return MENU_MLOOP_RET_LOOP; } if (IS_MENU_RETURN(pmret->rc)) { pdkp->timestamp = 0; return MENU_MLOOP_RET_END; } if (MST_DO_UNMAP_SUBMENU_ON_POPDOWN(pmp->menu) && pmret->flags.is_key_press) { in->miRemovedSubmenu = MR_PARENT_ITEM(in->mrPopup); pop_menu_down_and_repaint_parent( &in->mrPopup, pdoes_submenu_overlap, pmp); in->mi_with_popup = NULL; MR_SUBMENU_ITEM(pmp->menu) = NULL; if (in->mrPopup == in->mrPopdown) { in->mrPopdown = NULL; } in->mrPopup = NULL; } if (pmret->rc == MENU_POPDOWN) { med->popup_delay_10ms = 0; in->mif.do_force_reposition = True; } return MENU_MLOOP_RET_NORMAL; } static mloop_ret_code_t __mloop_handle_action_with_mi( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi, MenuOptions *pops, Bool *pdoes_submenu_overlap, Bool *pdoes_popdown_submenu_overlap) { MenuItem *tmi; MenuRoot *tmrMi; MenuRoot *mrMiPopup = NULL; pmret->flags.do_unpost_submenu = 0; /* we're on a menu item */ in->mif.is_off_menu_allowed = False; if (med->mrMi == pmp->menu && med->mi != in->miRemovedSubmenu) { in->miRemovedSubmenu = NULL; } if (med->mrMi != pmp->menu && med->mrMi != in->mrPopup && med->mrMi != in->mrPopdown) { /* we're on an item from a prior menu */ if (med->mrMi != MR_PARENT_MENU(pmp->menu)) { /* the event is for a previous menu, just close * this one */ pmret->rc = MENU_PROPAGATE_EVENT; pmret->target_menu = med->mrMi; } else { pmret->rc = MENU_POPDOWN; } pdkp->timestamp = 0; return MENU_MLOOP_RET_END; } if (med->mi != MR_SELECTED_ITEM(pmp->menu) && med->mrMi == pmp->menu) { /* new item of the same menu */ __mloop_select_item( pmp, in, med, *pdoes_submenu_overlap, pdoes_popdown_submenu_overlap); } else if (med->mi != MR_SELECTED_ITEM(pmp->menu) && med->mrMi && med->mrMi == in->mrPopdown) { /* we're on the popup menu of a different menu item of this * menu */ med->mi = MR_PARENT_ITEM(in->mrPopdown); in->mrPopup = in->mrPopdown; in->mrPopdown = NULL; *pdoes_submenu_overlap = *pdoes_popdown_submenu_overlap; select_menu_item(pmp->menu, med->mi, True, (*pmp->pexc)->w.fw); } mrMiPopup = mr_popup_for_mi(pmp->menu, med->mi); /* check what has to be done with the item */ if (__mloop_get_mi_actions( pmp, pmret, pdkp, in, med, msi, mrMiPopup, pdoes_submenu_overlap, pdoes_popdown_submenu_overlap) == MENU_MLOOP_RET_END) { return MENU_MLOOP_RET_END; } /* do what needs to be done */ if (in->mif.do_popdown && !in->mif.do_popup) { /* popdown previous popup */ __mloop_do_popdown(pmp, in, pdoes_popdown_submenu_overlap); } if (in->mif.do_popup) { if (__mloop_do_popup( pmp, pmret, in, med, pops, mrMiPopup, pdoes_submenu_overlap, pdoes_popdown_submenu_overlap) == MENU_MLOOP_RET_END) { return MENU_MLOOP_RET_END; } } /* remember the 'posted' menu */ if (pmret->flags.is_menu_posted && in->mrPopup != NULL && pmret->target_menu == NULL) { pmret->target_menu = in->mrPopup; } else if (pmret->flags.is_menu_posted && in->mrPopup == NULL) { pmret->flags.is_menu_posted = 0; } if (in->mif.do_menu) { mloop_ret_code_t rc; rc = __mloop_do_menu( pmp, pmret, pdkp, in, med, pops, pdoes_submenu_overlap); if (rc != MENU_MLOOP_RET_NORMAL) { return rc; } } /* Now check whether we can animate the current popup menu back to the * original place to unobscure the current menu; this happens only * when using animation */ if (in->mrPopup && MR_XANIMATION(in->mrPopup) && (tmi = find_entry(pmp, NULL, &tmrMi, None, -1, -1)) && (tmi == MR_SELECTED_ITEM(pmp->menu) || tmrMi != pmp->menu)) { animated_move_back(in->mrPopup, False, (*pmp->pexc)->w.fw); } /* now check whether we should animate the current real menu * over to the right to unobscure the prior menu; only a very * limited case where this might be helpful and not too disruptive */ /* but this cause terrible back-and-forth under certain circonstance, * I think we should disable this ... 2002-09-17 olicha */ if (in->mrPopup == NULL && pmp->parent_menu != NULL && MR_XANIMATION(pmp->menu) != 0 && pointer_in_passive_item_area(med->x_offset, med->mrMi)) { /* we have to see if we need menu to be moved */ animated_move_back(pmp->menu, True, (*pmp->pexc)->w.fw); if (in->mrPopdown) { if (in->mrPopdown != in->mrPopup) { pop_menu_down_and_repaint_parent( &in->mrPopdown, pdoes_popdown_submenu_overlap, pmp); in->mi_with_popup = NULL; } in->mrPopdown = NULL; } in->mif.do_popdown = False; } return MENU_MLOOP_RET_NORMAL; } static mloop_ret_code_t __mloop_handle_action_without_mi( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi, MenuOptions *pops, Bool *pdoes_submenu_overlap, Bool *pdoes_popdown_submenu_overlap) { pmret->flags.do_unpost_submenu = 0; /* moved off menu, deselect selected item... */ if (!MR_SELECTED_ITEM(pmp->menu) || in->mif.is_off_menu_allowed == True || pmret->flags.is_menu_posted) { /* nothing to do */ return MENU_MLOOP_RET_NORMAL; } if (in->mrPopup) { int x, y, mx, my; int mw, mh; if (FQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ x = 0; y = 0; } if (menu_get_geometry( pmp->menu, &JunkRoot, &mx, &my, &mw, &mh, &JunkBW, &JunkDepth) && ((!MR_IS_LEFT(in->mrPopup) && x < mx) || (!MR_IS_RIGHT(in->mrPopup) && x > mx + mw) || (!MR_IS_UP(in->mrPopup) && y < my) || (!MR_IS_DOWN(in->mrPopup) && y > my + mh))) { select_menu_item( pmp->menu, MR_SELECTED_ITEM(pmp->menu), False, (*pmp->pexc)->w.fw); pop_menu_down_and_repaint_parent( &in->mrPopup, pdoes_submenu_overlap, pmp); in->mi_with_popup = NULL; MR_SUBMENU_ITEM(pmp->menu) = NULL; if (in->mrPopup == in->mrPopdown) { in->mrPopdown = NULL; } in->mrPopup = NULL; } else if (x < mx || x >= mx + mw || y < my || y >= my + mh) { /* pointer is outside the menu but do not pop down */ in->mif.is_off_menu_allowed = True; } else { /* Pointer is still in the menu. Postpone the decision * if we have to pop down. */ } } /* if (in->mrPopup) */ else { select_menu_item( pmp->menu, MR_SELECTED_ITEM(pmp->menu), False, (*pmp->pexc)->w.fw); } return MENU_MLOOP_RET_NORMAL; } static void __mloop_exit_warp_back(MenuParameters *pmp) { MenuRoot *tmrMi; if (pmp->parent_menu && MR_SELECTED_ITEM(pmp->parent_menu)) { warp_pointer_to_item( pmp->parent_menu, MR_SELECTED_ITEM(pmp->parent_menu), False); (void)find_entry(pmp, NULL, &tmrMi, None, -1, -1); if (pmp->parent_menu != tmrMi && MR_XANIMATION(pmp->menu) == 0) { /* Warping didn't take us to the correct menu, i.e. the * spot we want to warp to is obscured. So raise our * window first. */ XRaiseWindow(dpy, MR_WINDOW(pmp->parent_menu)); } } return; } static void __mloop_exit_select_in_place( MenuParameters *pmp, mloop_evh_data_t *med, MenuOptions *pops) { MenuRoot *submenu; XWindowAttributes win_attribs; last_saved_pos_hints.flags.is_last_menu_pos_hints_valid = True; last_saved_pos_hints.pos_hints.x_offset = 0; last_saved_pos_hints.pos_hints.x_factor = 0; last_saved_pos_hints.pos_hints.context_x_factor = 0; last_saved_pos_hints.pos_hints.y_factor = 0; last_saved_pos_hints.pos_hints.is_relative = False; last_saved_pos_hints.pos_hints.is_menu_relative = False; submenu = mr_popup_for_mi(pmp->menu, med->mi); if (submenu && MR_WINDOW(submenu) != None && XGetWindowAttributes(dpy, MR_WINDOW(submenu), &win_attribs) && win_attribs.map_state == IsViewable && menu_get_geometry( submenu, &JunkRoot, &last_saved_pos_hints.pos_hints.x, &last_saved_pos_hints.pos_hints.y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { /* The submenu is mapped, just take its position and put it in * the position hints. */ } else if (pops->flags.has_poshints) { last_saved_pos_hints.pos_hints = pops->pos_hints; } else { Bool dummy; get_prefered_popup_position( pmp->menu, submenu, &last_saved_pos_hints. pos_hints.x, &last_saved_pos_hints. pos_hints.y, &dummy); } if (pops->flags.do_warp_on_select) { last_saved_pos_hints.flags.do_warp_title = 1; } return; } static void __mloop_exit_selected( MenuParameters *pmp, MenuReturn *pmret, mloop_evh_data_t *med, MenuOptions *pops) { /* save action to execute so that the menu may be destroyed now */ if (pmp->ret_paction) { if (pmret->rc == MENU_EXEC_CMD) { *pmp->ret_paction = safestrdup(*pmp->ret_paction); } else { if (*pmp->ret_paction) { free(*pmp->ret_paction); } *pmp->ret_paction = (med->mi) ? safestrdup(MI_ACTION(med->mi)) : NULL; } } if ( pmp->ret_paction && *pmp->ret_paction && med->mi && MI_IS_POPUP(med->mi)) { get_popup_options(pmp, med->mi, pops); if (pops->flags.do_select_in_place) { __mloop_exit_select_in_place(pmp, med, pops); } else { last_saved_pos_hints.flags.do_ignore_pos_hints = True; } /* pops->flags.do_select_in_place */ last_saved_pos_hints.pos_hints.screen_origin_x = pmp->screen_origin_x; last_saved_pos_hints.pos_hints.screen_origin_y = pmp->screen_origin_y; } return; } static void __mloop_exit( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp, mloop_evh_input_t *in, mloop_evh_data_t *med, mloop_static_info_t *msi, MenuOptions *pops) { Bool no = False; Bool do_deselect = False; if (in->mrPopdown) { pop_menu_down_and_repaint_parent(&in->mrPopdown, &no, pmp); MR_SUBMENU_ITEM(pmp->menu) = NULL; } if ( pmret->rc == MENU_SELECTED && is_double_click( msi->t0, med->mi, pmp, pmret, pdkp, in->mif.has_mouse_moved)) { pmret->rc = MENU_DOUBLE_CLICKED; } if ( pmret->rc == MENU_SELECTED && med->mi && MI_FUNC_TYPE(med->mi) == F_TEARMENUOFF) { pmret->rc = (MR_IS_TEAR_OFF_MENU(pmp->menu)) ? MENU_KILL_TEAR_OFF_MENU : MENU_TEAR_OFF; } switch (pmret->rc) { case MENU_POPDOWN: case MENU_PROPAGATE_EVENT: case MENU_DOUBLE_CLICKED: do_deselect = True; /* Allow popdown to warp back pointer to main menu with mouse button control. (MoveLeft/MoveRight on a mouse binding) */ if (((pmret->rc == MENU_POPDOWN && in->mif.is_button_release) || in->mif.is_key_press) && pmret->rc != MENU_DOUBLE_CLICKED) { if (!pmp->flags.is_submenu) { /* abort a root menu rather than pop it down */ pmret->rc = MENU_ABORTED; } __mloop_exit_warp_back(pmp); } break; case MENU_ABORTED: case MENU_TEAR_OFF: case MENU_KILL_TEAR_OFF_MENU: do_deselect = True; break; case MENU_SELECTED: case MENU_EXEC_CMD: __mloop_exit_selected(pmp, pmret, med, pops); pmret->rc = MENU_DONE; break; default: break; } if (do_deselect && MR_SELECTED_ITEM(pmp->menu)) { select_menu_item( pmp->menu, MR_SELECTED_ITEM(pmp->menu), False, (*pmp->pexc)->w.fw); } if (pmret->rc == MENU_SUBMENU_TORN_OFF) { in->mrPopup = NULL; MR_SUBMENU_ITEM(pmp->menu) = NULL; } if (in->mrPopup) { pop_menu_down_and_repaint_parent(&in->mrPopup, &no, pmp); MR_SUBMENU_ITEM(pmp->menu) = NULL; } pmret->flags.is_key_press = in->mif.is_key_press; return; } static void __menu_loop( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp) { mloop_evh_input_t mei; mloop_ret_code_t mloop_ret; mloop_evh_data_t med; mloop_static_info_t msi; MenuOptions mops; Bool is_finished; Bool does_submenu_overlap = False; Bool does_popdown_submenu_overlap = False; __mloop_init(pmp, pmret, &mei, &med, &msi, &mops); for (is_finished = False; !is_finished; ) { mloop_ret = __mloop_get_event(pmp, pmret, &mei, &med, &msi); switch (mloop_ret) { case MENU_MLOOP_RET_END: is_finished = True; case MENU_MLOOP_RET_LOOP: continue; default: break; } mloop_ret = __mloop_handle_event( pmp, pmret, pdkp, &mei, &med, &msi); switch (mloop_ret) { case MENU_MLOOP_RET_END: is_finished = True; continue; case MENU_MLOOP_RET_LOOP: continue; default: break; } /* Now handle new menu items, whether it is from a keypress or * a pointer motion event. */ if (med.mi != NULL) { mloop_ret = __mloop_handle_action_with_mi( pmp, pmret, pdkp, &mei, &med, &msi, &mops, &does_submenu_overlap, &does_popdown_submenu_overlap); } else { mloop_ret = __mloop_handle_action_without_mi( pmp, pmret, pdkp, &mei, &med, &msi, &mops, &does_submenu_overlap, &does_popdown_submenu_overlap); } if (mloop_ret == MENU_MLOOP_RET_END) { is_finished = True; } XFlush(dpy); } __mloop_exit(pmp, pmret, pdkp, &mei, &med, &msi, &mops); return; } /* * Functions dealing with tear off menus */ static char *menu_strip_tear_off_title(MenuRoot *mr) { MenuItem *mi; int i; int len; char *name; for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi)) { if (MI_IS_TITLE(mi)) { break; } else if (!MI_IS_SEPARATOR(mi) && !MI_IS_TEAR_OFF_BAR(mi)) { /* a normal item, no title found */ return NULL; } /* skip separators and tear off bars */ } if (mi == NULL || !MI_HAS_TEXT(mi) || MI_NEXT_ITEM(mi) == NULL) { return NULL; } /* extract the window title from the labels */ for (i = 0, len = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i] != 0) { len += strlen(MI_LABEL(mi)[i]) + 1; } } if (len == 0) { return NULL; } name = safemalloc(len + 1); *name = 0; for (i = 0; i < MAX_MENU_ITEM_LABELS; i++) { if (MI_LABEL(mi)[i] != 0) { strcat(name, MI_LABEL(mi)[i]); strcat(name, " "); } } /* strip the last space */ name[len - 1] = 0; /* unlink and destroy the item */ unlink_item_from_menu(mr, mi); menuitem_free(mi); return name; } static int _pred_menu_window_weed_events( Display *display, XEvent *event, XPointer arg) { switch (event->type) { case CirculateNotify: case ConfigureNotify: case CreateNotify: case DestroyNotify: case GravityNotify: case MapNotify: case ReparentNotify: case UnmapNotify: /* events in SubstructureNotifyMask */ return 1; default: return 0; } } static void menu_tear_off(MenuRoot *mr_to_copy) { MenuRoot *mr; MenuStyle *ms; XEvent ev; XSizeHints menusizehints; XClassHint menuclasshints; XTextProperty menunametext; XWMHints menuwmhints; char *list[] ={ NULL, NULL }; char *t; char *name = NULL; Atom protocols[1]; int x = 0; int y = 0; unsigned int add_mask = 0; initial_window_options_t win_opts; evh_args_t ea; exec_context_changes_t ecc; char *buffer; char *action; cond_rc_t *cond_rc = NULL; const exec_context_t *exc = NULL; /* keep the menu open */ if (MR_WINDOW(mr_to_copy) != None) { XSync(dpy, 0); FWeedIfWindowEvents( dpy, MR_WINDOW(mr_to_copy), _pred_menu_window_weed_events, NULL); } mr = clone_menu(mr_to_copy); /* also dump the menu style */ buffer = (char *)safemalloc(23); sprintf(buffer,"%lu",(unsigned long)mr); action = buffer; ms = menustyle_parse_style(F_PASS_ARGS); if (!ms) { /* this must never happen */ fvwm_msg( ERR, "menu_tear_off", "impossible to create %s menu style", buffer); free(buffer); DestroyMenu(mr, False, False); return; } free(buffer); menustyle_copy(MR_STYLE(mr_to_copy),ms); MR_STYLE(mr) = ms; MST_USAGE_COUNT(mr) = 0; name = menu_strip_tear_off_title(mr); /* create the menu window and size the menu */ make_menu(mr, True); /* set position */ if (menu_get_geometry( mr_to_copy, &JunkRoot, &x, &y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { add_mask = PPosition; XMoveWindow(dpy, MR_WINDOW(mr), x, y); } else { add_mask = 0; } /* focus policy */ menuwmhints.flags = InputHint; menuwmhints.input = False; /* size hints */ menusizehints.flags = PBaseSize | PMinSize | PMaxSize | add_mask; menusizehints.base_width = 0; menusizehints.base_height = 0; menusizehints.min_width = MR_WIDTH(mr); menusizehints.min_height = MR_HEIGHT(mr); menusizehints.max_width = MR_WIDTH(mr); menusizehints.max_height = MR_HEIGHT(mr); /* class, resource and names */ menuclasshints.res_name = (name != NULL) ? name : safestrdup(MR_NAME(mr)); menuclasshints.res_class = safestrdup("fvwm_menu"); for (t = menuclasshints.res_name; t != NULL && *t != 0; t++) { /* replace tabs in the title with spaces */ if (*t == '\t') { *t = ' '; } } list[0] = menuclasshints.res_name; menunametext.value = NULL; XStringListToTextProperty(list, 1, &menunametext); /* set all properties and hints */ XSetWMProperties( dpy, MR_WINDOW(mr), &menunametext, &menunametext, NULL, 0, &menusizehints, NULL, &menuclasshints); XSetWMHints(dpy, MR_WINDOW(mr), &menuwmhints); protocols[0] = _XA_WM_DELETE_WINDOW; XSetWMProtocols(dpy, MR_WINDOW(mr), &(protocols[0]), 1); /* free memory */ if (menunametext.value != NULL) { XFree(menunametext.value); } free(menuclasshints.res_class); free(menuclasshints.res_name); /* manage the window */ memset(&win_opts, 0, sizeof(win_opts)); win_opts.flags.is_menu = True; ev.type = MapRequest; ev.xmaprequest.send_event = True; ev.xmaprequest.display = dpy; ev.xmaprequest.parent = Scr.Root; ev.xmaprequest.window = MR_WINDOW(mr); fev_fake_event(&ev); ecc.type = EXCT_NULL; ecc.x.etrigger = &ev; ecc.w.w = MR_WINDOW(mr); ecc.w.wcontext = C_ROOT; ea.exc = exc_create_context( &ecc, ECC_TYPE | ECC_ETRIGGER | ECC_W | ECC_WCONTEXT); HandleMapRequestKeepRaised(&ea, None, NULL, &win_opts); exc_destroy_context(ea.exc); return; } static void do_menu_close_tear_off_menu(MenuRoot *mr, MenuParameters mp) { pop_menu_down(&mr, &mp); menustyle_free(MR_STYLE(mr)); DestroyMenu(mr, False, False); } /* ---------------------------- interface functions ------------------------- */ void menus_init(void) { memset((&Menus), 0, sizeof(MenuInfo)); return; } /* menus_find_menu expects a token as the input. Make sure you have used * GetNextToken before passing a menu name to remove quotes (if necessary) */ MenuRoot *menus_find_menu(char *name) { MenuRoot *mr; if (name == NULL) { return NULL; } for (mr = Menus.all; mr != NULL; mr = MR_NEXT_MENU(mr)) { if (!MR_IS_DESTROYED(mr) && mr == MR_ORIGINAL_MENU(mr) && MR_NAME(mr) != NULL && StrEquals(name, MR_NAME(mr))) { break; } } return mr; } void menus_remove_style_from_menus(MenuStyle *ms) { MenuRoot *mr; for (mr = Menus.all; mr; mr = MR_NEXT_MENU(mr)) { if (MR_STYLE(mr) == ms) { MR_STYLE(mr) = menustyle_get_default_style(); MR_IS_UPDATED(mr) = 1; } } return; } /* * Functions dealing with tear off menus */ void menu_enter_tear_off_menu(const exec_context_t *exc) { MenuRoot *mr; char *ret_action = NULL; MenuOptions mops; MenuParameters mp; MenuReturn mret; const exec_context_t *exc2; exec_context_changes_t ecc; if (XFindContext( dpy, FW_W(exc->w.fw), MenuContext, (caddr_t *)&mr) == XCNOENT) { return; } ecc.w.fw = NULL; ecc.w.w = None; ecc.w.wcontext = C_ROOT; exc2 = exc_clone_context(exc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); memset(&mops, 0, sizeof(mops)); memset(&mret, 0, sizeof(MenuReturn)); memset(&mp, 0, sizeof(mp)); mp.menu = mr; mp.pexc = &exc2; mp.tear_off_root_menu_window = exc->w.fw; MR_IS_TEAR_OFF_MENU(mr) = 1; mp.flags.has_default_action = 0; mp.flags.is_already_mapped = True; mp.flags.is_sticky = False; mp.flags.is_submenu = False; mp.pops = &mops; mp.ret_paction = &ret_action; do_menu(&mp, &mret); exc_destroy_context(exc2); return; } void menu_close_tear_off_menu(FvwmWindow *fw) { MenuRoot *mr; MenuParameters mp; const exec_context_t *exc; exec_context_changes_t ecc; if (XFindContext( dpy, FW_W(fw), MenuContext, (caddr_t *)&mr) == XCNOENT) { return; } memset(&mp, 0, sizeof(mp)); mp.menu = mr; ecc.w.fw = NULL; ecc.w.w = None; ecc.w.wcontext = C_ROOT; exc = exc_create_context(&ecc, ECC_FW | ECC_W | ECC_WCONTEXT); mp.pexc = &exc; do_menu_close_tear_off_menu(mr, mp); exc_destroy_context(exc); return; } Bool menu_redraw_transparent_tear_off_menu(FvwmWindow *fw, Bool pr_only) { MenuRoot *mr; MenuStyle *ms = NULL; int cs; if (!(IS_TEAR_OFF_MENU(fw) && XFindContext(dpy, FW_W(fw), MenuContext,(caddr_t *)&mr) != XCNOENT && (ms = MR_STYLE(mr)) && ST_HAS_MENU_CSET(ms))) { return False; } cs = ST_CSET_MENU(ms); if (!CSET_IS_TRANSPARENT(cs) || (pr_only && !CSET_IS_TRANSPARENT_PR(cs))) { return False; } return UpdateBackgroundTransparency( dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr), &Colorset[ST_CSET_MENU(ms)], Pdepth, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), True); } /* * * Initiates a menu pop-up * * fStick = True = sticky menu, stays up on initial button release. * fStick = False = transient menu, drops on initial release. * * eventp = 0: menu opened by mouse, do not warp * eventp > 1: root menu opened by keypress with 'Menu', warp pointer and * allow 'double-keypress'. * eventp = 1: menu opened by keypress, warp but forbid 'double-keypress' * this should always be used except in the call in 'staysup_func' * in builtin.c * * Returns one of MENU_NOP, MENU_ERROR, MENU_ABORTED, MENU_DONE * do_menu() may destroy the *pmp->pexec member and replace it with a new * copy. Be sure not to rely on the original structure being kept intact * when calling do_menu(). */ void do_menu(MenuParameters *pmp, MenuReturn *pmret) { int x; int y; Bool fWasAlreadyPopped = False; Bool key_press; Bool is_pointer_grabbed = False; Bool is_pointer_ungrabbed = False; Bool do_menu_interaction; Bool do_check_pop_down; Bool do_warp; Time t0 = fev_get_evtime(); XEvent tmpevent; double_keypress dkp; /* don't save these ones, we want them to work even within recursive * menus popped up by dynamic actions. */ static int indirect_depth = 0; static int x_start; static int y_start; int scr_x, scr_y; int scr_w, scr_h; pmret->rc = MENU_NOP; if (pmp->flags.is_sticky && !pmp->flags.is_submenu) { FCheckTypedEvent(dpy, ButtonPressMask, &tmpevent); } if (pmp->menu == NULL) { pmret->rc = MENU_ERROR; return; } key_press = pmp->flags.is_triggered_by_keypress; /* Try to pick a root-relative optimal x,y to * put the mouse right on the title w/o warping */ if (FQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ x = 0; y = 0; } /* Save these - we want to warp back here if this is a top level * menu brought up by a keystroke */ if (!pmp->flags.is_submenu) { pmp->flags.is_invoked_by_key_press = key_press; pmp->flags.is_first_root_menu = !indirect_depth; } else { pmp->flags.is_first_root_menu = 0; } if (!pmp->flags.is_submenu && indirect_depth == 0) { if (key_press) { x_start = x; y_start = y; } else { x_start = -1; y_start = -1; } pmp->screen_origin_x = pmp->pops->pos_hints.screen_origin_x; pmp->screen_origin_y = pmp->pops->pos_hints.screen_origin_y; } if (pmp->pops->flags.do_warp_title) { do_warp = True; } else if (pmp->pops->flags.do_not_warp) { do_warp = False; } else if (key_press) { do_warp = True; } else { do_warp = False; } /* Figure out where we should popup, if possible */ if (!pmp->flags.is_already_mapped) { Bool prefer_left_submenus = False; /* Make sure we are using the latest style and menu layout. */ update_menu(pmp->menu, pmp); if (pmp->flags.is_submenu) { /* this is a submenu popup */ get_prefered_popup_position( pmp->parent_menu, pmp->menu, &x, &y, &prefer_left_submenus); } else { fscreen_scr_arg fscr; /* we're a top level menu */ if (!GrabEm(CRS_MENU, GRAB_MENU)) { /* GrabEm specifies the cursor to use */ XBell(dpy, 0); pmret->rc = MENU_ABORTED; return; } is_pointer_grabbed = True; /* Make the menu appear under the pointer rather than * warping */ fscr.xypos.x = x; fscr.xypos.y = y; FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &scr_x, &scr_y, &scr_w, &scr_h); x -= menudim_middle_x_offset(&MR_DIM(pmp->menu)); y -= menuitem_middle_y_offset( MR_FIRST_ITEM(pmp->menu), MR_STYLE(pmp->menu)); if (x < scr_x) { x = scr_x; } if (y < scr_y) { y = scr_y; } } /* pop_menu_up may move the x,y to make it fit on screen more * nicely. It might also move parent_menu out of the way. */ if (!pop_menu_up( &(pmp->menu), pmp, pmp->parent_menu, NULL, pmp->pexc, x, y, prefer_left_submenus, do_warp, pmp->pops, NULL, None)) { XBell(dpy, 0); UngrabEm(GRAB_MENU); pmret->rc = MENU_ERROR; return; } } else { fWasAlreadyPopped = True; if (pmp->tear_off_root_menu_window != NULL) { if (!GrabEm(CRS_MENU, GRAB_MENU)) { /* GrabEm specifies the cursor to use */ XBell(dpy, 0); pmret->rc = MENU_ABORTED; return; } is_pointer_grabbed = True; } if (key_press) { warp_pointer_to_item( pmp->menu, MR_FIRST_ITEM(pmp->menu), True /* skip Title */); } } /* Remember the key that popped up the root menu. */ if (pmp->flags.is_submenu) { dkp.timestamp = 0; } else { if (pmp->flags.is_triggered_by_keypress) { /* we have a real key event */ dkp.keystate = (*pmp->pexc)->x.etrigger->xkey.state; dkp.keycode = (*pmp->pexc)->x.etrigger->xkey.keycode; } dkp.timestamp = (key_press && pmp->flags.has_default_action) ? t0 : 0; } if (!pmp->flags.is_submenu && indirect_depth == 0) { /* we need to grab the keyboard so we are sure no key presses * are lost */ MyXGrabKeyboard(dpy); } /* This may loop for tear off menus */ for (do_menu_interaction = True; do_menu_interaction == True; ) { if (is_pointer_ungrabbed && !GrabEm(CRS_MENU, GRAB_MENU)) { /* re-grab the pointer in this cycle */ XBell(dpy, 0); pmret->rc = MENU_ABORTED; break; } do_menu_interaction = False; if (pmp->pops->flags.do_tear_off_immediately == 1) { pmret->rc = MENU_TEAR_OFF; } else { if (!pmp->flags.is_submenu) { XSelectInput( dpy, Scr.NoFocusWin, XEVMASK_MENUNFW); XFlush(dpy); } __menu_loop(pmp, pmret, &dkp); if (!pmp->flags.is_submenu) { XSelectInput( dpy, Scr.NoFocusWin, XEVMASK_NOFOCUSW); XFlush(dpy); } } do_check_pop_down = False; switch (pmret->rc) { case MENU_TEAR_OFF: menu_tear_off(pmp->menu); pop_menu_down(&pmp->menu, pmp); break; case MENU_KILL_TEAR_OFF_MENU: if (MR_IS_TEAR_OFF_MENU(pmp->menu)) { /* kill the menu */ do_menu_close_tear_off_menu(pmp->menu, *pmp); pmret->rc = MENU_ABORTED; } else { /* pass return code up to the torn off menu */ } break; case MENU_DOUBLE_CLICKED: case MENU_DONE: if (MR_IS_TEAR_OFF_MENU(pmp->menu)) { do_menu_interaction = True; } else { do_check_pop_down = True; } break; case MENU_SUBMENU_TORN_OFF: pmret->rc = MENU_ABORTED; do_check_pop_down = True; break; default: do_check_pop_down = True; break; } if (do_check_pop_down == True) { /* popping down may destroy the menu via the dynamic * popdown action! */ if (!MR_IS_TEAR_OFF_MENU(pmp->menu) && fWasAlreadyPopped == False) { pop_menu_down(&pmp->menu, pmp); } } XFlush(dpy); if (!pmp->flags.is_submenu && x_start >= 0 && y_start >= 0 && pmret->flags.is_key_press && pmret->rc != MENU_TEAR_OFF) { /* warp pointer back to where invoked if this was * brought up with a keypress and we're returning from * a top level menu, and a button release event didn't * end it */ FWarpPointer( dpy, 0, Scr.Root, 0, 0, Scr.MyDisplayWidth, Scr.MyDisplayHeight, x_start, y_start); if ((*pmp->pexc)->x.elast->type == KeyPress) { XEvent e = *(*pmp->pexc)->x.elast; e.xkey.x_root = x_start; e.xkey.y_root = y_start; fev_fake_event(&e); } } if (pmret->rc == MENU_TEAR_OFF) { pmret->rc = MENU_SUBMENU_TORN_OFF; } dkp.timestamp = 0; if (is_pointer_grabbed) { UngrabEm(GRAB_MENU); WaitForButtonsUp(True); is_pointer_ungrabbed = True; } if (!pmp->flags.is_submenu) { if (pmret->rc == MENU_DONE) { if (pmp->ret_paction && *pmp->ret_paction) { indirect_depth++; /* Execute the action */ __menu_execute_function( pmp->pexc, *pmp->ret_paction); indirect_depth--; free(*pmp->ret_paction); *pmp->ret_paction = NULL; } last_saved_pos_hints.flags. do_ignore_pos_hints = False; last_saved_pos_hints.flags. is_last_menu_pos_hints_valid = False; } if (indirect_depth == 0) { last_saved_pos_hints.flags. do_ignore_pos_hints = False; last_saved_pos_hints.flags. is_last_menu_pos_hints_valid = False; } } } if (!pmp->flags.is_submenu && indirect_depth == 0) { /* release the keyboard when the last menu closes */ MyXUngrabKeyboard(dpy); } return; } Bool menu_expose(XEvent *event, FvwmWindow *fw) { MenuRoot *mr = NULL; if ((XFindContext( dpy, event->xany.window, MenuContext, (caddr_t *)&mr) != XCNOENT)) { flush_accumulate_expose(event->xany.window, event); paint_menu(mr, event, fw); return True; } else { return False; } } /* * * Procedure: * update_transparent_menu_bg - set the background of the menu to * match a forseen move of a menu. If the background is updated * for the target position before the move is done, and repainted * after the move, the move will look more seamless. * * This method should be folleowd by a call to repaint_transparent_menu * with the same step_x, stey_y, end_x and any_y, with is_bg_set True */ void update_transparent_menu_bg( MenuRepaintTransparentParameters *prtm, int current_x, int current_y, int step_x, int step_y, int end_x, int end_y) { MenuRoot *mr; MenuStyle *ms; Bool last = False; mr = prtm->mr; ms = MR_STYLE(mr); if (step_x == end_x && step_y == end_y) { last = True; } if (!last && CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms))) { /* too slow ... */ return; } SetWindowBackgroundWithOffset( dpy, MR_WINDOW(mr), step_x - current_x, step_y - current_y, MR_WIDTH(mr), MR_HEIGHT(mr), &Colorset[ST_CSET_MENU(ms)], Pdepth, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False); } /* * * Procedure: * repaint_transparent_menu - repaint the menu background if it is * tranparent during an animated move. Called in move_resize.c * (AnimatedMoveAnyWindow). Performance improvement Welcome! * ideas: - write the foreground into a pixmap and a mask the first time * this function is called. Then use these pixmaps to draw * the items * - Use a Buffer if !IS_TRANSPARENT_PR_PURE and if we do not have one * already */ void repaint_transparent_menu( MenuRepaintTransparentParameters *prtm, Bool first, int x, int y, int end_x, int end_y, Bool is_bg_set) { MenuItem *mi; MenuRoot *mr; MenuStyle *ms; int h = 0; int s_h = 0; int e_h = 0; Bool last = False; mr = prtm->mr; ms = MR_STYLE(mr); if (x == end_x && y == end_y) { last = True; } if (!last && CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms))) { /* too slow ... */ return; } if (!is_bg_set) { SetWindowBackground( dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr), &Colorset[ST_CSET_MENU(ms)], Pdepth, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False); } /* redraw the background of non active item */ for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi)) { if (mi == MR_SELECTED_ITEM(mr) && MST_DO_HILIGHT_BACK(mr)) { int left; left = MR_HILIGHT_X_OFFSET(mr) - MR_ITEM_X_OFFSET(mr); if (left > 0) { XClearArea( dpy, MR_WINDOW(mr), MR_ITEM_X_OFFSET(mr), MI_Y_OFFSET(mi), left, MI_HEIGHT(mi) + MST_RELIEF_THICKNESS(mr), 0); } h = MI_HEIGHT(mi); continue; } if (h == 0) { s_h += MI_HEIGHT(mi); } else { e_h += MI_HEIGHT(mi); } } XClearArea( dpy, MR_WINDOW(mr), MR_ITEM_X_OFFSET(mr), MST_BORDER_WIDTH(mr), MR_ITEM_WIDTH(mr), s_h, 0); if (e_h != 0) { XClearArea( dpy, MR_WINDOW(mr), MR_ITEM_X_OFFSET(mr), s_h + h + MST_RELIEF_THICKNESS(mr) + MST_BORDER_WIDTH(mr), MR_ITEM_WIDTH(mr), e_h, 0); } /* now redraw the items */ for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi)) { MenuPaintItemParameters mpip; if (mi == MR_SELECTED_ITEM(mr) && MST_DO_HILIGHT_BACK(mr) && !CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms))) { continue; } get_menu_paint_item_parameters( &mpip, mr, NULL, prtm->fw, NULL, True); mpip.flags.is_first_item = (MR_FIRST_ITEM(mr) == mi); menuitem_paint(mi, &mpip); } /* if we have a side pic and no side colors we shound repaint the side * pic */ if ((MR_SIDEPIC(mr) || MST_SIDEPIC(mr)) && !MR_HAS_SIDECOLOR(mr) && !MST_HAS_SIDE_COLOR(mr)) { FvwmPicture *sidePic; if (MR_SIDEPIC(mr)) { sidePic = MR_SIDEPIC(mr); } else if (MST_SIDEPIC(mr)) { sidePic = MST_SIDEPIC(mr); } else { return; } XClearArea( dpy, MR_WINDOW(mr), MR_SIDEPIC_X_OFFSET(mr), MST_BORDER_WIDTH(mr), sidePic->width, MR_HEIGHT(mr) - 2 * MST_BORDER_WIDTH(mr), 0); paint_side_pic(mr, NULL); } } Bool DestroyMenu(MenuRoot *mr, Bool do_recreate, Bool is_command_request) { MenuItem *mi,*tmp2; MenuRoot *tmp, *prev; Bool in_list = True; if (mr == NULL) { return False; } /* seek menu in master list */ tmp = Menus.all; prev = NULL; while (tmp && tmp != mr) { prev = tmp; tmp = MR_NEXT_MENU(tmp); } if (tmp != mr) { /* no such menu */ in_list = False; } if (MR_MAPPED_COPIES(mr) > 0 && (is_command_request || MR_COPIES(mr) == 1)) { /* can't destroy a menu while in use */ fvwm_msg(ERR, "DestroyMenu", "Menu %s is in use", MR_NAME(mr)); return False; } if (in_list && MR_COPIES(mr) > 1 && MR_ORIGINAL_MENU(mr) == mr) { MenuRoot *m; MenuRoot *new_orig; /* find a new 'original' menu */ for (m = Menus.all, new_orig = NULL; m; m = MR_NEXT_MENU(m)) { if (m != mr && MR_ORIGINAL_MENU(m) == mr) { if (new_orig == NULL) { new_orig = m; } MR_ORIGINAL_MENU(m) = new_orig; } } MR_ORIGINAL_MENU(mr) = new_orig; /* now dump old original menu */ } MR_COPIES(mr)--; if (MR_STORED_ITEM(mr).stored) { XFreePixmap(dpy, MR_STORED_ITEM(mr).stored); } if (MR_COPIES(mr) > 0) { do_recreate = False; } else { /* free all items */ mi = MR_FIRST_ITEM(mr); while (mi != NULL) { tmp2 = MI_NEXT_ITEM(mi); menuitem_free(mi); mi = tmp2; } if (do_recreate) { /* just dump the menu items but keep the menu itself */ MR_COPIES(mr)++; MR_FIRST_ITEM(mr) = NULL; MR_LAST_ITEM(mr) = NULL; MR_SELECTED_ITEM(mr) = NULL; MR_CONTINUATION_MENU(mr) = NULL; MR_PARENT_MENU(mr) = NULL; MR_ITEMS(mr) = 0; memset(&(MR_STORED_ITEM(mr)), 0 , sizeof(MR_STORED_ITEM(mr))); MR_IS_UPDATED(mr) = 1; return True; } } /* unlink menu from list */ if (in_list) { if (prev == NULL) { Menus.all = MR_NEXT_MENU(mr); } else { MR_NEXT_MENU(prev) = MR_NEXT_MENU(mr); } } /* destroy the window and the display */ if (MR_WINDOW(mr) != None) { XDeleteContext(dpy, MR_WINDOW(mr), MenuContext); XFlush(dpy); XDestroyWindow(MR_CREATE_DPY(mr), MR_WINDOW(mr)); MR_WINDOW(mr) = None; XFlush(MR_CREATE_DPY(mr)); } if (MR_CREATE_DPY(mr) != NULL && MR_CREATE_DPY(mr) != dpy) { XCloseDisplay(MR_CREATE_DPY(mr)); MR_CREATE_DPY(mr) = NULL; } if (MR_COPIES(mr) == 0) { if (MR_POPUP_ACTION(mr)) { free(MR_POPUP_ACTION(mr)); } if (MR_POPDOWN_ACTION(mr)) { free(MR_POPDOWN_ACTION(mr)); } if (MR_MISSING_SUBMENU_FUNC(mr)) { free(MR_MISSING_SUBMENU_FUNC(mr)); } free(MR_NAME(mr)); if (MR_SIDEPIC(mr)) { PDestroyFvwmPicture(dpy, MR_SIDEPIC(mr)); } memset(mr->s, 0, sizeof(*(mr->s))); free(mr->s); } memset(mr->d, 0, sizeof(*(mr->d))); free(mr->d); memset(mr, 0, sizeof(*mr)); free(mr); return True; } /* FollowMenuContinuations * Given an menu root, return the menu root to add to by * following continuation links until there are no more */ MenuRoot *FollowMenuContinuations(MenuRoot *mr, MenuRoot **pmrPrior ) { *pmrPrior = NULL; while ((mr != NULL) && (MR_CONTINUATION_MENU(mr) != NULL)) { *pmrPrior = mr; mr = MR_CONTINUATION_MENU(mr); } return mr; } /* * * Procedure: * AddToMenu - add an item to a root menu * * Returned Value: * (MenuItem *) * * Inputs: * menu - pointer to the root menu to add the item * item - the text to appear in the menu * action - the string to possibly execute * * ckh - need to add boolean to say whether or not to expand for pixmaps, * so built in window list can handle windows w/ * and % in title. * */ void AddToMenu( MenuRoot *mr, char *item, char *action, Bool fPixmapsOk, Bool fNoPlus, Bool is_continuation_item) { MenuItem *tmp; char *start; char *end; char *token = NULL; char *option = NULL; int i; int is_empty; Bool do_replace_title; if (MR_MAPPED_COPIES(mr) > 0) { /* whoa, we can't handle *everything* */ return; } if ((item == NULL || *item == 0) && (action == NULL || *action == 0) && fNoPlus) { return; } /* empty items screw up our menu when painted, so we replace them with * a separator */ if (item == NULL) item = ""; /* * Handle dynamic actions */ if (StrEquals(item, "DynamicPopupAction")) { if (MR_POPUP_ACTION(mr)) { free(MR_POPUP_ACTION(mr)); } if (!action || *action == 0) { MR_POPUP_ACTION(mr) = NULL; } else { MR_POPUP_ACTION(mr) = stripcpy(action); } return; } else if (StrEquals(item, "DynamicPopdownAction")) { if (MR_POPDOWN_ACTION(mr)) { free(MR_POPDOWN_ACTION(mr)); } if (!action || *action == 0) { MR_POPDOWN_ACTION(mr) = NULL; } else { MR_POPDOWN_ACTION(mr) = stripcpy(action); } return; } else if (StrEquals(item, "MissingSubmenuFunction")) { if (MR_MISSING_SUBMENU_FUNC(mr)) { free(MR_MISSING_SUBMENU_FUNC(mr)); } if (!action || *action == 0) { MR_MISSING_SUBMENU_FUNC(mr) = NULL; } else { MR_MISSING_SUBMENU_FUNC(mr) = stripcpy(action); } return; } /* * Parse the action */ if (action == NULL || *action == 0) { action = "Nop"; } GetNextToken(GetNextToken(action, &token), &option); tmp = menuitem_create(); if (MR_FIRST_ITEM(mr) != NULL && StrEquals(token, "title") && option != NULL && StrEquals(option, "top")) { do_replace_title = True; } else { do_replace_title = False; } append_item_to_menu(mr, tmp, do_replace_title); if (token) { free(token); } if (option) { free(option); } MI_ACTION(tmp) = stripcpy(action); /* * Parse the labels */ start = item; end = item; for (i = 0; i < MAX_MENU_ITEM_LABELS; i++, start = end) { /* Read label up to next tab. */ if (*end) { if (i < MAX_MENU_ITEM_LABELS - 1) { while (*end && *end != '\t') { /* seek next tab or end of string */ end++; } } else { /* remove all tabs in last label */ while (*end) { if (*end == '\t') { *end = ' '; } end++; } } /* Copy the label. */ MI_LABEL(tmp)[i] = safemalloc(end - start + 1); strncpy(MI_LABEL(tmp)[i], start, end - start); (MI_LABEL(tmp)[i])[end - start] = 0; if (*end == '\t') { /* skip the tab */ end++; } } else { MI_LABEL(tmp)[i] = NULL; } /* Parse the label. */ if (MI_LABEL(tmp)[i] != NULL) { if (fPixmapsOk) { string_def_t item_pixmaps[] = { {'*', __scan_for_pixmap}, {'%', __scan_for_pixmap}, {'\0', NULL}}; string_context_t ctx; SCTX_SET_MI(ctx,tmp); scanForStrings( MI_LABEL(tmp)[i], item_pixmaps, &ctx); } if (!MI_HAS_HOTKEY(tmp)) { /* pete@tecc.co.uk */ scanForHotkeys(tmp, i); if (!MI_HAS_HOTKEY(tmp) && *MI_LABEL(tmp)[i] != 0) { MI_HOTKEY_COFFSET(tmp) = 0; MI_HOTKEY_COLUMN(tmp) = i; MI_HAS_HOTKEY(tmp) = 1; MI_IS_HOTKEY_AUTOMATIC(tmp) = 1; } } if (*(MI_LABEL(tmp)[i])) { MI_HAS_TEXT(tmp) = True; } else { free(MI_LABEL(tmp)[i]); MI_LABEL(tmp)[i] = NULL; } } MI_LABEL_STRLEN(tmp)[i] = (MI_LABEL(tmp)[i]) ? strlen(MI_LABEL(tmp)[i]) : 0; } /* for */ /* * Set the type flags */ if (is_continuation_item) { MI_IS_CONTINUATION(tmp) = True; } find_func_t(MI_ACTION(tmp), &(MI_FUNC_TYPE(tmp)), NULL); switch (MI_FUNC_TYPE(tmp)) { case F_POPUP: MI_IS_POPUP(tmp) = True; case F_WINDOWLIST: case F_STAYSUP: MI_IS_MENU(tmp) = True; break; case F_TITLE: MI_IS_TITLE(tmp) = True; break; default: break; } is_empty = (!MI_HAS_TEXT(tmp) && !MI_HAS_PICTURE(tmp)); if (is_empty) { if (MI_FUNC_TYPE(tmp) == F_TEARMENUOFF) { MI_IS_TEAR_OFF_BAR(tmp) = 1; MI_IS_SEPARATOR(tmp) = 0; } else { MI_IS_TEAR_OFF_BAR(tmp) = 0; MI_IS_SEPARATOR(tmp) = 1; } } if (MI_IS_SEPARATOR(tmp)) { /* An empty title is handled like a separator. */ MI_IS_TITLE(tmp) = False; } MI_IS_SELECTABLE(tmp) = ((MI_HAS_TEXT(tmp) || MI_HAS_PICTURE(tmp) || MI_IS_TEAR_OFF_BAR(tmp)) && !MI_IS_TITLE(tmp)); /* * misc stuff */ MR_ITEMS(mr)++; MR_IS_UPDATED(mr) = 1; return; } /* * * Procedure: * NewMenuRoot - create a new menu root * * Returned Value: * (MenuRoot *) * * Inputs: * name - the name of the menu root * */ MenuRoot *NewMenuRoot(char *name) { MenuRoot *mr; string_def_t root_strings[] = { {'@', __scan_for_pixmap}, {'^', __scan_for_color}, {'\0', NULL}}; string_context_t ctx; mr = (MenuRoot *)safemalloc(sizeof(MenuRoot)); mr->s = (MenuRootStatic *)safemalloc(sizeof(MenuRootStatic)); mr->d = (MenuRootDynamic *)safemalloc(sizeof(MenuRootDynamic)); memset(mr->s, 0, sizeof(MenuRootStatic)); memset(mr->d, 0, sizeof(MenuRootDynamic)); MR_NEXT_MENU(mr) = Menus.all; MR_NAME(mr) = safestrdup(name); MR_WINDOW(mr) = None; SCTX_SET_MR(ctx,mr); MR_HAS_SIDECOLOR(mr) = False; scanForStrings( MR_NAME(mr), root_strings, &ctx); MR_STYLE(mr) = menustyle_get_default_style(); MR_ORIGINAL_MENU(mr) = mr; MR_COPIES(mr) = 1; MR_IS_UPDATED(mr) = 1; Menus.all = mr; return mr; } void SetMenuCursor(Cursor cursor) { MenuRoot *mr; mr = Menus.all; for (mr = Menus.all; mr; mr = MR_NEXT_MENU(mr)) { if (MR_WINDOW(mr)) { XDefineCursor(dpy, MR_WINDOW(mr), cursor); } } return; } void UpdateAllMenuStyles(void) { MenuStyle *ms; for (ms = menustyle_get_default_style(); ms; ms = ST_NEXT_STYLE(ms)) { menustyle_update(ms); } return; } void UpdateMenuColorset(int cset) { MenuStyle *ms; FvwmWindow *t; for (ms = menustyle_get_default_style(); ms; ms = ST_NEXT_STYLE(ms)) { if ((ST_HAS_MENU_CSET(ms) && ST_CSET_MENU(ms) == cset) || (ST_HAS_ACTIVE_CSET(ms) && ST_CSET_ACTIVE(ms) == cset) || (ST_HAS_GREYED_CSET(ms) && ST_CSET_GREYED(ms) == cset) || (ST_HAS_TITLE_CSET(ms) && ST_CSET_TITLE(ms) == cset)) { menustyle_update(ms); } } for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { MenuRoot *mr = NULL; MenuStyle *ms = NULL; if (IS_TEAR_OFF_MENU(t) && XFindContext(dpy, FW_W(t), MenuContext, (caddr_t *)&mr) != XCNOENT && (ms = MR_STYLE(mr))) { if (ST_HAS_MENU_CSET(ms) && ST_CSET_MENU(ms) == cset) { SetWindowBackground( dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr), &Colorset[ST_CSET_MENU(ms)], Pdepth, FORE_GC(MST_MENU_INACTIVE_GCS(mr)), True); } else if ((ST_HAS_ACTIVE_CSET(ms) && ST_CSET_ACTIVE(ms) == cset) || (ST_HAS_GREYED_CSET(ms) && ST_CSET_GREYED(ms) == cset)) { paint_menu(mr, NULL, NULL); } } } return; } /* This is called by the window list function */ void change_mr_menu_style(MenuRoot *mr, char *stylename) { MenuStyle *ms = NULL; ms = menustyle_find(stylename); if (ms == NULL) { return; } if (MR_MAPPED_COPIES(mr) != 0) { fvwm_msg(ERR,"ChangeMenuStyle", "menu %s is in use", MR_NAME(mr)); } else { MR_STYLE(mr) = ms; MR_IS_UPDATED(mr) = 1; } return; } void add_another_menu_item(char *action) { MenuRoot *mr; MenuRoot *mrPrior; char *rest,*item; mr = FollowMenuContinuations(Scr.last_added_item.item, &mrPrior); if (mr == NULL) { return; } if (MR_MAPPED_COPIES(mr) != 0) { fvwm_msg(ERR,"add_another_menu_item", "menu is in use"); return; } rest = GetNextToken(action,&item); AddToMenu(mr, item, rest, True /* pixmap scan */, False, False); if (item) { free(item); } return; } /* * get_menu_options is used for Menu, Popup and WindowList * It parses strings matching * * [ [context-rectangle] x y ] [special-options] [other arguments] * * and returns a pointer to the first part of the input string that doesn't * match this syntax. * * See documentation for a detailed description. */ char *get_menu_options( char *action, Window w, FvwmWindow *fw, XEvent *e, MenuRoot *mr, MenuItem *mi, MenuOptions *pops) { char *tok = NULL; char *naction = action; char *taction; int x; int y; int button; int width; int height; int dummy_int; float dummy_float; Bool dummy_flag; Window context_window = None; Bool fHasContext, fUseItemOffset, fRectangleContext, fXineramaRoot; Bool fValidPosHints = last_saved_pos_hints.flags.is_last_menu_pos_hints_valid; Bool is_action_empty = False; Bool once_more = True; Bool is_icon_context; rectangle icon_g; /* If this is set we may want to reverse the position hints, so don't * sum up the totals right now. This is useful for the SubmenusLeft * style. */ fXineramaRoot = False; last_saved_pos_hints.flags.is_last_menu_pos_hints_valid = False; if (pops == NULL) { fvwm_msg(ERR, "get_menu_options","no MenuOptions pointer passed"); return action; } taction = action; memset(&(pops->flags), 0, sizeof(pops->flags)); pops->flags.has_poshints = 0; if (!action || *action == 0) { is_action_empty = True; } while (action != NULL && *action != 0 && once_more) { /* ^ just to be able to jump to end of loop without 'goto' */ pops->pos_hints.is_relative = False; pops->pos_hints.menu_width = 0; pops->pos_hints.is_menu_relative = False; /* parse context argument (if present) */ naction = GetNextToken(taction, &tok); if (!tok) { /* no context string */ fHasContext = False; is_action_empty = True; break; } /* set to False for absolute hints! */ pops->pos_hints.is_relative = True; fUseItemOffset = False; fHasContext = True; fRectangleContext = False; is_icon_context = False; if (StrEquals(tok, "context")) { if (mi && mr) { context_window = MR_WINDOW(mr); } else if (fw) { if (IS_ICONIFIED(fw)) { is_icon_context = True; get_icon_geometry(fw, &icon_g); context_window = None; } else { context_window = FW_W_FRAME(fw); } } else { context_window = w; } } else if (StrEquals(tok,"menu")) { if (mr) { context_window = MR_WINDOW(mr); pops->pos_hints.is_menu_relative = True; pops->pos_hints.menu_width = MR_WIDTH(mr); } } else if (StrEquals(tok,"item")) { if (mi && mr) { context_window = MR_WINDOW(mr); fUseItemOffset = True; pops->pos_hints.is_menu_relative = True; pops->pos_hints.menu_width = MR_WIDTH(mr); } } else if (StrEquals(tok,"icon")) { if (fw && IS_ICONIFIED(fw)) { is_icon_context = True; get_icon_geometry(fw, &icon_g); context_window = None; } } else if (StrEquals(tok,"window")) { if (fw && !IS_ICONIFIED(fw)) { context_window = FW_W_FRAME(fw); } } else if (StrEquals(tok,"interior")) { if (fw && !IS_ICONIFIED(fw)) { context_window = FW_W(fw); } } else if (StrEquals(tok,"title")) { if (fw) { if (IS_ICONIFIED(fw)) { context_window = FW_W_ICON_TITLE(fw); } else { context_window = FW_W_TITLE(fw); } } } else if (strncasecmp(tok,"button",6) == 0) { if (sscanf(&(tok[6]),"%d",&button) != 1 || tok[6] == '+' || tok[6] == '-' || button < 0 || button > 9) { fHasContext = False; } else if (fw && !IS_ICONIFIED(fw)) { button = BUTTON_INDEX(button); context_window = FW_W_BUTTON(fw, button); } } else if (StrEquals(tok,"root")) { context_window = Scr.Root; pops->pos_hints.is_relative = False; } else if (StrEquals(tok,"xineramaroot")) { context_window = Scr.Root; pops->pos_hints.is_relative = False; fXineramaRoot = True; } else if (StrEquals(tok,"mouse")) { context_window = None; } else if (StrEquals(tok,"rectangle")) { int flags; int screen; int sx; int sy; int sw; int sh; /* parse the rectangle */ free(tok); naction = GetNextToken(naction, &tok); if (tok == NULL) { fvwm_msg(ERR, "get_menu_options", "missing rectangle geometry"); if (!pops->pos_hints.has_screen_origin) { /* xinerama: emergency fallback */ pops->pos_hints.has_screen_origin = 1; pops->pos_hints.screen_origin_x = 0; pops->pos_hints.screen_origin_y = 0; } return action; } flags = FScreenParseGeometryWithScreen( tok, &x, &y, (unsigned int*)&width, (unsigned int*)&height, &screen); if ((flags & (XValue | YValue)) != (XValue | YValue)) { free(tok); fvwm_msg(ERR, "get_menu_options", "invalid rectangle geometry"); if (!pops->pos_hints.has_screen_origin) { /* xinerama: emergency fallback */ pops->pos_hints.has_screen_origin = 1; pops->pos_hints.screen_origin_x = 0; pops->pos_hints.screen_origin_y = 0; } return action; } pops->pos_hints.has_screen_origin = 1; FScreenGetScrRect(NULL, screen, &sx, &sy, &sw, &sh); pops->pos_hints.screen_origin_x = sx; pops->pos_hints.screen_origin_y = sy; if (!(flags & WidthValue)) { width = 1; } if (!(flags & HeightValue)) { height = 1; } x += sx; y += sy; if (flags & XNegative) { /* x is negative */ x = sx + sw + x; } if (flags & YNegative) { /* y is negative */ y = sy + sh + y; } pops->pos_hints.is_relative = False; fRectangleContext = True; } else if (StrEquals(tok,"this")) { MenuRoot *dummy_mr; context_window = w; if (XFindContext( dpy, w, MenuContext, (caddr_t *)&dummy_mr) != XCNOENT) { if (mr) { /* the parent menu */ pops->pos_hints.is_menu_relative = True; pops->pos_hints.menu_width = MR_WIDTH(mr); } } } else { /* no context string */ fHasContext = False; } if (tok) { free(tok); } if (fHasContext) { taction = naction; } else { naction = action; } if (fRectangleContext) { if (!pops->pos_hints.has_screen_origin) { /* xinerama: use global screen as reference */ pops->pos_hints.has_screen_origin = 1; pops->pos_hints.screen_origin_x = -1; pops->pos_hints.screen_origin_y = -1; } /* nothing else to do */ } else if (!is_icon_context && (!fHasContext || !context_window || !XGetGeometry( dpy, context_window, &JunkRoot, &JunkX, &JunkY, (unsigned int*)&width, (unsigned int*)&height, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) || !XTranslateCoordinates( dpy, context_window, Scr.Root, 0, 0, &x, &y, &JunkChild))) { /* no window or could not get geometry */ if (FQueryPointer( dpy,Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen - that's * okay here */ x = 0; y = 0; } width = height = 1; if (!pops->pos_hints.has_screen_origin) { /* xinerama: use screen with pinter as * reference */ pops->pos_hints.has_screen_origin = 1; pops->pos_hints.screen_origin_x = x; pops->pos_hints.screen_origin_y = y; } } else { if (is_icon_context) { x = icon_g.x; y = icon_g.y; width = icon_g.width; height = icon_g.height; } /* we have a context window */ if (fUseItemOffset) { y += MI_Y_OFFSET(mi); height = MI_HEIGHT(mi); } if (!pops->pos_hints.has_screen_origin) { pops->pos_hints.has_screen_origin = 1; if (fXineramaRoot) { /* use whole screen */ pops->pos_hints.screen_origin_x = -1; pops->pos_hints.screen_origin_y = -1; } else if (context_window == Scr.Root) { /* xinerama: use screen that contains * the window center as reference */ if (!fev_get_evpos_or_query( dpy, context_window, e, &pops->pos_hints. screen_origin_x, &pops->pos_hints. screen_origin_y)) { pops->pos_hints. screen_origin_x = 0; pops->pos_hints. screen_origin_y = 0; } else { fscreen_scr_arg fscr; fscr.xypos.x = pops->pos_hints. screen_origin_x; fscr.xypos.y = pops->pos_hints. screen_origin_y; FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &x, &y, &width, &height); } } else { /* xinerama: use screen that contains * the window center as reference */ pops->pos_hints.screen_origin_x = JunkX + width / 2; pops->pos_hints.screen_origin_y = JunkY + height / 2; } } } /* parse position arguments */ taction = get_one_menu_position_argument( naction, x, width, &(pops->pos_hints.x), &(pops->pos_hints.x_offset), &(pops->pos_hints.x_factor), &(pops->pos_hints.context_x_factor), &pops->pos_hints.is_menu_relative); if (pops->pos_hints.is_menu_relative) { pops->pos_hints.x = x; if (pops->pos_hints.menu_width == 0 && mr) { pops->pos_hints.menu_width = MR_WIDTH(mr); } } naction = get_one_menu_position_argument( taction, y, height, &(pops->pos_hints.y), &dummy_int, &(pops->pos_hints.y_factor), &dummy_float, &dummy_flag); if (naction == taction) { /* argument is missing or invalid */ if (fHasContext) { fvwm_msg(ERR, "get_menu_options", "invalid position arguments"); } naction = action; taction = action; break; } taction = naction; pops->flags.has_poshints = 1; if (fValidPosHints == True && pops->pos_hints.is_relative == True) { pops->pos_hints = last_saved_pos_hints.pos_hints; } /* we want to do this only once */ once_more = False; } /* while */ if (is_action_empty) { if (!pops->pos_hints.has_screen_origin) { pops->pos_hints.has_screen_origin = 1; if (!fev_get_evpos_or_query( dpy, Scr.Root, e, &pops->pos_hints.screen_origin_x, &pops->pos_hints.screen_origin_y)) { pops->pos_hints.screen_origin_x = 0; pops->pos_hints.screen_origin_y = 0; } } } if (!pops->flags.has_poshints && fValidPosHints) { pops->flags.has_poshints = 1; pops->pos_hints = last_saved_pos_hints.pos_hints; pops->pos_hints.is_relative = False; } action = naction; /* to keep Purify silent */ pops->flags.do_select_in_place = 0; /* parse additional options */ while (naction && *naction) { naction = GetNextToken(action, &tok); if (!tok) { break; } if (StrEquals(tok, "WarpTitle")) { pops->flags.do_warp_title = 1; pops->flags.do_not_warp = 0; } else if (StrEquals(tok, "NoWarp")) { pops->flags.do_warp_title = 0; pops->flags.do_not_warp = 1; } else if (StrEquals(tok, "Fixed")) { pops->flags.is_fixed = 1; } else if (StrEquals(tok, "SelectInPlace")) { pops->flags.do_select_in_place = 1; } else if (StrEquals(tok, "SelectWarp")) { pops->flags.do_warp_on_select = 1; } else if (StrEquals(tok, "TearOffImmediately")) { pops->flags.do_tear_off_immediately = 1; } else { free (tok); break; } action = naction; free (tok); } if (!pops->flags.do_select_in_place) { pops->flags.do_warp_on_select = 0; } return action; } /* ---------------------------- new menu loop code ------------------------- */ #if 0 /*!!!*/ typedef enum { MTR_XEVENT = 0x1, MTR_FAKE_ENTER_ITEM = 0x2, MTR_PROPAGATE_XEVENT_UP = 0x4, MTR_PROPAGATE_XEVENT_DOWN = 0x8, MTR_POPUP_TIMEOUT = 0x10, MTR_POPDOWN_TIMEOUT = 0x20 } mloop_trigger_type_t; typedef_struct { mloop_trigger_type_t type; XEvent trigger_ev; int ticks_passed; } mloop_trigger_t; typedef_struct { int popup_10ms; int popdown_10ms; } mloop_timeouts_t; typedef struct { MenuRoot *current_menu; XEvent *in_ev; struct { unsigned do_fake_enter_item : 1; unsigned do_propagete_event_up : 1; unsigned do_propagete_event_down : 1; } flags; } mloop_get_trigger_input_t; /*!!!static*/ mloop_trigger_type_t __mloop_get_trigger( mloop_trigger_t *ret_trigger, mloop_timeouts_t *io_timeouts, const mloop_get_trigger_input_t * const in, { if (in_out->in_flags->do_propagate_event_down) { return MTR_PROPAGATE_XEVENT_DOWN; } else if (in_out->in_flags->do_propagate_event_up) { if (a != b) { return MTR_PROPAGATE_XEVENT_UP; } else { } /*!!!return propagate up*/ /*!!!*/ } /*!!!read event or wait for timeout*/ while (0/*!!!not finished*/) { /*!!!rc = 0*/ if (0/*!!!wait for tiomeout*/) { /*!!!check for event*/ } else { /*!!!block for event*/ } if (0/*got event*/) { /*!!!rc = MTR_XEVENT*/ } if (0/*!!!popup timed out;break*/) { /*!!!rc = MTR_POPUP;break*/ } if (0/*!!!popdown timed out;break*/) { /*!!!rc = MTR_POPDOWN;break*/ } /*!!!sleep*/ } if (0/*!!!rc == MTR_XEVENT && evtype == MotionNotify*/) { /*!!!eat up further MotionNotify events*/ } return 0/*!!!rc*/; } /*!!!static*/ void __menu_loop_new( MenuParameters *pmp, MenuReturn *pmret, double_keypress *pdkp) { mloop_evh_input_t mei; #if 0 mloop_ret_code_t mloop_ret; #endif mloop_evh_data_t med; mloop_static_info_t msi; MenuOptions mops; Bool is_finished; /*!!!init menu loop*/ __mloop_init(pmp, pmret, &mei, &med, &msi, &mops); for (is_finished = False; !is_finished; ) { mloop_trigger_type_t mtr; mtr = __mloop_get_trigger( pmp, pmret, &mei, &med, &msi); switch (mtr) { case MTR_XEVENT: /*!!!handle event*/ break; case MTR_FAKE_ENTER_ITEM: /*!!!fake enter item*/ break; case MTR_PROPAGATE_XEVENT_UP: /*!!!handle propagation*/ break; case MTR_PROPAGATE_XEVENT_DOWN: /*!!!handle propagation*/ break; case MTR_POPUP_TIMEOUT: /*!!!handle popup*/ break; case MTR_POPDOWN_TIMEOUT: /*!!!handle popdown*/ break; } #if 0 mloop_ret = __mloop_handle_event( pmp, pmret, pdkp, &mei, &med, &msi); switch (mloop_ret) { case MENU_MLOOP_RET_LOOP: continue; case MENU_MLOOP_RET_END: is_finished = True; break; default: break; } /* Now handle new menu items, whether it is from a * keypress or a pointer motion event. */ if (med.mi != NULL) { mloop_ret = __mloop_handle_action_with_mi( pmp, pmret, pdkp, &mei, &med, &msi, &mops); } else { mloop_ret = __mloop_handle_action_without_mi( pmp, pmret, pdkp, &mei, &med, &msi, &mops); } if (mloop_ret == MENU_MLOOP_RET_END) { is_finished = True; } XFlush(dpy); #endif } __mloop_exit(pmp, pmret, pdkp, &mei, &med, &msi, &mops); return; } #endif fvwm-2.6.7/fvwm/condrc.h0000644000175700017570000000153312773467232012063 00000000000000/* -*-c-*- */ #ifndef CONDRC_H #define CONDRC_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { COND_RC_BREAK = -2, COND_RC_ERROR = -1, COND_RC_NO_MATCH = 0, COND_RC_OK = 1 } cond_rc_enum; typedef struct { cond_rc_enum rc; int break_levels; } cond_rc_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void condrc_init(cond_rc_t *cond_rc); #endif /* CONDRC_H */ fvwm-2.6.7/fvwm/screen.h0000644000175700017570000003361212773467232012075 00000000000000/* -*-c-*- */ /* This module is based on Twm, but has been siginificantly modified * by Rob Nation */ /* Copyright 1989 Massachusetts Institute of Technology * * 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 M.I.T. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. * 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. */ /* * * fvwm per-screen data include file * */ #ifndef _SCREEN_ #define _SCREEN_ #include "libs/flist.h" #include "libs/Bindings.h" #define SIZE_HINDENT 5 #define SIZE_VINDENT 3 /* colormap focus styes */ #define COLORMAP_FOLLOWS_MOUSE 1 /* default */ #define COLORMAP_FOLLOWS_FOCUS 2 /* title bar multi pixmap parts */ /* those which can be used as UseTitleStyle should be enum first */ typedef enum { TBMP_NONE = -1, TBMP_MAIN, TBMP_LEFT_MAIN, TBMP_RIGHT_MAIN, TBMP_LEFT_BUTTONS, TBMP_RIGHT_BUTTONS, TBMP_UNDER_TEXT, TBMP_LEFT_OF_TEXT, TBMP_RIGHT_OF_TEXT, TBMP_LEFT_END, TBMP_RIGHT_END, TBMP_BUTTONS, TBMP_NUM_PIXMAPS } TbmpParts; /* title bar multi pixmap parts which can be use for UseTitleStyle */ typedef enum { UTS_TBMP_NONE = -1, UTS_TBMP_MAIN, UTS_TBMP_LEFT_MAIN, UTS_TBMP_RIGHT_MAIN, UTS_TBMP_LEFT_BUTTONS, UTS_TBMP_RIGHT_BUTTONS, UTS_TBMP_NUM_PIXMAPS } UtsTbmpParts; typedef struct { int cs; int alpha_percent; } FvwmAcs; typedef struct { Window win; int isMapped; /* command which is executed when the pan frame is entered */ char *command; /* command which is executed when the pan frame is left*/ char *command_leave; } PanFrame; typedef enum { /* button types */ DefaultVectorButton, VectorButton, SimpleButton, GradientButton, PixmapButton, TiledPixmapButton, StretchedPixmapButton, AdjustedPixmapButton, ShrunkPixmapButton, MultiPixmap, MiniIconButton, SolidButton, ColorsetButton } DecorFaceType; typedef enum { JUST_CENTER = 0, JUST_LEFT = 1, JUST_TOP = 1, JUST_RIGHT = 2, JUST_BOTTOM = 2, JUST_MASK = 3 } JustificationType; typedef struct { unsigned face_type : 4; struct { unsigned h_justification : 2; unsigned v_justification : 2; #define DFS_BUTTON_IS_UP 0 #define DFS_BUTTON_IS_FLAT 1 #define DFS_BUTTON_IS_SUNK 2 #define DFS_BUTTON_MASK 3 unsigned int button_relief : 2; /* not used in border styles */ unsigned int use_title_style : 1; unsigned int use_border_style : 1; /* only used in border styles */ unsigned int has_hidden_handles : 1; unsigned int has_no_inset : 1; } flags; } DecorFaceStyle; #define DFS_FACE_TYPE(dfs) ((dfs).face_type) #define DFS_FLAGS(dfs) ((dfs).flags) #define DFS_H_JUSTIFICATION(dfs) ((dfs).flags.h_justification) #define DFS_V_JUSTIFICATION(dfs) ((dfs).flags.v_justification) #define DFS_BUTTON_RELIEF(dfs) ((dfs).flags.button_relief) #define DFS_USE_TITLE_STYLE(dfs) ((dfs).flags.use_title_style) #define DFS_USE_BORDER_STYLE(dfs) ((dfs).flags.use_border_style) #define DFS_HAS_HIDDEN_HANDLES(dfs) ((dfs).flags.has_hidden_handles) #define DFS_HAS_NO_INSET(dfs) ((dfs).flags.has_no_inset) typedef struct DecorFace { DecorFaceStyle style; struct { FvwmPicture *p; struct { FvwmPicture **pixmaps; unsigned short stretch_flags; FvwmAcs *acs; Pixel *pixels; unsigned short solid_flags; } mp; struct { int cs; int alpha_percent; } acs; Pixel back; struct { int npixels; XColor *xcs; int do_dither; Pixel *d_pixels; int d_npixels; char gradient_type; } grad; struct vector_coords { int num; signed char *x; signed char *y; signed char *xoff; signed char *yoff; signed char *c; unsigned use_fgbg : 1; } vector; } u; struct DecorFace *next; struct { unsigned has_changed : 1; } flags; } DecorFace; typedef enum { BS_All = -1, BS_ActiveUp, BS_ActiveDown, BS_InactiveUp, BS_InactiveDown, BS_ToggledActiveUp, BS_ToggledActiveDown, BS_ToggledInactiveUp, BS_ToggledInactiveDown, BS_MaxButtonState, BS_MaxButtonStateMask = BS_MaxButtonState - 1, BS_Active, BS_Inactive, BS_ToggledActive, BS_ToggledInactive, BS_AllNormal, BS_AllToggled, BS_AllActive, BS_AllInactive, BS_AllUp, BS_AllDown, BS_AllActiveUp, BS_AllActiveDown, BS_AllInactiveUp, BS_AllInactiveDown, BS_MaxButtonStateName } ButtonState; #define BS_MASK_DOWN (1 << 0) #define BS_MASK_INACTIVE (1 << 1) #define BS_MASK_TOGGLED (1 << 2) typedef enum { /* The first five are used in title buttons. These can't be * renumbered without extending the mwm_decor_flags member below and * adapting the style structure. */ MWM_DECOR_MENU = 0x1, MWM_DECOR_MINIMIZE = 0x2, MWM_DECOR_MAXIMIZE = 0x4, MWM_DECOR_SHADE = 0x8, MWM_DECOR_STICK = 0x10, /* --- */ MWM_DECOR_BORDER = 0x20, MWM_DECOR_RESIZEH = 0x40, MWM_DECOR_TITLE = 0x80, MWM_DECOR_ALL = 0x100, MWM_DECOR_EVERYTHING = 0xff } mwm_flags; typedef struct { unsigned just : 2; /* was JustificationType : 2 */ int layer; struct { unsigned has_changed : 1; mwm_flags mwm_decor_flags : 9; /* Support {ButtonStyle - Layer 4} construction, so * button can be rendered 'pressed in' when the window is * assigned to a particular layer. */ unsigned has_layer : 1; } flags; DecorFace state[BS_MaxButtonState]; } TitleButton; #define TB_FLAGS(tb) ((tb).flags) #define TB_STATE(tb) ((tb).state) #define TB_JUSTIFICATION(tb) ((tb).just) #define TB_LAYER(tb) ((tb).layer) #define TB_MWM_DECOR_FLAGS(tb) ((tb).flags.mwm_decor_flags) #define TB_HAS_CHANGED(tb) \ (!!((tb).flags.has_changed)) #define TB_HAS_MWM_DECOR_MENU(tb) \ (!!((tb).flags.mwm_decor_flags & MWM_DECOR_MENU)) #define TB_HAS_MWM_DECOR_MINIMIZE(tb) \ (!!((tb).flags.mwm_decor_flags & MWM_DECOR_MINIMIZE)) #define TB_HAS_MWM_DECOR_MAXIMIZE(tb) \ (!!((tb).flags.mwm_decor_flags & MWM_DECOR_MAXIMIZE)) #define TB_HAS_MWM_DECOR_SHADE(tb) \ (!!((tb).flags.mwm_decor_flags & MWM_DECOR_SHADE)) #define TB_HAS_MWM_DECOR_STICK(tb) \ (!!((tb).flags.mwm_decor_flags & MWM_DECOR_STICK)) typedef struct FvwmDecor { char *tag; /* general style tag */ int title_height; /* explicitly specified title bar height */ int min_title_height; /* titlebar buttons */ TitleButton buttons[NUMBER_OF_TITLE_BUTTONS]; TitleButton titlebar; struct BorderStyle { DecorFace active, inactive; } BorderStyle; struct FvwmDecor *next; /* additional user-defined styles */ struct { unsigned has_changed : 1; unsigned has_title_height_changed : 1; } flags; } FvwmDecor; typedef struct DesktopsInfo { int desk; char *name; struct { int x; int y; int width; int height; } ewmh_working_area; struct { int x; int y; int width; int height; } ewmh_dyn_working_area; struct DesktopsInfo *next; } DesktopsInfo; typedef struct ScreenInfo { unsigned long screen; Screen *pscreen; /* number of screens on display */ int NumberOfScreens; /* my copy of DisplayWidth(dpy, screen) */ int MyDisplayWidth; /* my copy of DisplayHeight(dpy, screen) */ int MyDisplayHeight; /* the head of the fvwm window list */ FvwmWindow FvwmRoot; /* the root window */ Window Root; /* the resize dimensions window */ Window SizeWindow; /* Window which will own focus when no other windows have it */ Window NoFocusWin; flist *FWScheduledForDestroy; PanFrame PanFrameTop; PanFrame PanFrameLeft; PanFrame PanFrameRight; PanFrame PanFrameBottom; /*dark gray pattern for shaded out menu items*/ Pixmap gray_bitmap; /* dark gray pattern for inactive borders */ Pixmap gray_pixmap; /* light gray pattern for inactive borders */ Pixmap light_gray_pixmap; /* light gray pattern for sticky borders */ Pixmap sticky_gray_pixmap; Binding *AllBindings; /* current push level to install root colormap windows */ int root_pushes; /* current push level to install fvwm colormap windows */ int fvwm_pushes; /* saved window to install when pushes drops to zero */ const FvwmWindow *pushed_window; Cursor *FvwmCursors; /* context where we display the busy cursor */ int BusyCursor; /* Icon to use when no other icons are found */ char *DefaultIcon; int TopLayer; int DefaultLayer; int BottomLayer; struct FvwmFunction *functions; /* font structure */ FlocaleFont *DefaultFont; /* GC for transparency masks */ GC TransMaskGC; /* don't change the order */ Pixel StdFore, StdBack, StdHilite, StdShadow; GC StdGC; GC StdReliefGC; GC StdShadowGC; /* A scratch 1x1x1 pixmap */ Pixmap ScratchMonoPixmap; /* GC for drawing into depth 1 drawables */ GC MonoGC; /* A scratch 1x1xalpha_depth pixmap */ Pixmap ScratchAlphaPixmap; /* GC for drawing into depth alpha_depth drawables */ GC AlphaGC; /* GC to draw lines for move and resize */ GC XorGC; GC ScratchGC1; GC ScratchGC2; GC ScratchGC3; GC ScratchGC4; GC TitleGC; GC BordersGC; /* minimum width of size window */ int SizeStringWidth; /* decoration style(s) */ FvwmDecor DefaultDecor; FvwmDecor *cur_decor; /* number of left-side title-bar buttons */ int nr_left_buttons; /* number of right-side title-bar buttons */ int nr_right_buttons; /* the fvwm window that is highlighted except for networking delays, * this is the window which REALLY has the focus */ FvwmWindow *Hilite; /* None, if the focus is nowhere or on an fvwm managed window. Set to * id of otherwindow with focus otherwise */ Window UnknownWinFocused; /* The window that the UnknownWinFocused window stole the focus from. */ Window StolenFocusWin; FvwmWindow *StolenFocusFvwmWin; FvwmWindow *focus_in_pending_window; FvwmWindow *focus_in_requested_window; /* #pixels to scroll on screen edge */ int EdgeScrollX; /* #pixels to scroll on screen edge */ int EdgeScrollY; /* buttons to grab in click to focus mode */ unsigned short buttons2grab; int NumBoxes; /* values used for CascadePlacement */ int cascade_x; int cascade_y; FvwmWindow *cascade_window; /* Max location for top left of virt desk*/ int VxMax; int VyMax; /* Current loc for top left of virt desk */ int Vx; int Vy; /*Max button-click delay for Function built-in*/ int ClickTime; /* resistance to scrolling in desktop */ int ScrollDelay; int MoveThreshold; int OpaqueSize; /* The current desktop number */ int CurrentDesk; /* colormap focus style */ int ColormapFocus; /* Limit on colors used in pixmaps */ int ColorLimit; /* Default Colorset used by feedback window */ int DefaultColorset; int use_backing_store; /* some additional global options which will probably become window * specific options later on: */ struct { unsigned do_debug_cr_motion_method : 1; unsigned do_disable_configure_notify : 1; unsigned do_display_new_window_names : 1; unsigned do_enable_ewmh_iconic_state_workaround : 1; unsigned do_enable_flickering_qt_dialogs_workaround : 1; unsigned do_enable_qt_drag_n_drop_workaround : 1; unsigned do_explain_window_placement : 1; unsigned do_install_root_cmap : 1; unsigned do_raise_over_unmanaged : 1; unsigned is_modality_evil : 1; unsigned is_raise_hack_needed : 1; } bo; /* bug workaround control options */ struct { unsigned do_emulate_mwm : 1; unsigned do_emulate_win : 1; unsigned do_hide_position_window : 1; unsigned do_hide_resize_window : 1; unsigned use_active_down_buttons : 1; unsigned use_inactive_buttons : 1; unsigned use_inactive_down_buttons : 1; } gs; /* global style structure */ struct { unsigned are_functions_silent : 1; unsigned are_windows_captured : 1; unsigned do_edge_wrap_x : 1; unsigned do_edge_wrap_y : 1; unsigned do_need_style_list_update : 1; unsigned do_need_window_update : 1; unsigned do_save_under : 1; unsigned has_default_color_changed : 1; unsigned has_default_font_changed : 1; unsigned has_mouse_binding_changed : 1; unsigned has_nr_buttons_changed : 1; unsigned has_xinerama_state_changed : 1; unsigned is_executing_complex_function : 1; unsigned is_executing_menu_function : 1; unsigned is_map_desk_in_progress : 1; unsigned is_pointer_on_this_screen : 1; unsigned is_single_screen : 1; unsigned is_window_scheduled_for_destroy : 1; unsigned is_wire_frame_displayed : 1; } flags; /* info for some desktops; the first entries should be generic info * correct for any desktop not in the list */ DesktopsInfo *Desktops; /* the window of desktop type if any */ FvwmWindow *EwmhDesktop; struct { last_added_item_t type; void *item; } last_added_item; } ScreenInfo; /* A macro to to simplify he "ewmh desktop code" */ #define IS_EWMH_DESKTOP(win) \ (Scr.EwmhDesktop && win == Scr.EwmhDesktop->wins.client) #define IS_EWMH_DESKTOP_FW(fwin) \ (fwin && Scr.EwmhDesktop && Scr.EwmhDesktop == fwin) /* Macro which gets specific decor or default decor. * This saves an indirection in case you don't want * the UseDecor mechanism. */ #define GetDecor(window,part) ((window)->decor->part) /* some protos for the decoration structures */ void LoadDefaultButton(DecorFace *bf, int i); void ResetAllButtons(FvwmDecor *decor); void DestroyAllButtons(FvwmDecor *decor); void simplify_style_list(void); /* * Diverts a style definition to an FvwmDecor structure (veliaa@rpi.edu) */ void AddToDecor(F_CMD_ARGS, FvwmDecor *decor); extern ScreenInfo Scr; #endif /* _SCREEN_ */ fvwm-2.6.7/fvwm/decorations.c0000644000175700017570000004616312773467232013130 00000000000000/* -*-c-*- */ /* 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 */ /* * * This is all original code by Robert Nation * which reads motif mwm window manager * hints from a window, and makes necessary adjustments for fvwm. * */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/Parse.h" #include "libs/lang-strings.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "commands.h" #include "misc.h" #include "screen.h" #include "update.h" #include "style.h" #include "geometry.h" #include "decorations.h" /* ---------------------------- local definitions -------------------------- */ /* Motif window hints */ #define MWM_HINTS_FUNCTIONS (1L << 0) #define MWM_HINTS_DECORATIONS (1L << 1) /* bit definitions for MwmHints.functions */ #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) /* bit definitions for MwmHints.decorations */ #if 0 #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) #endif #define PROP_MOTIF_WM_HINTS_ELEMENTS 4 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS /* bit definitions for OL hints; I just * made these up, OL stores hints as atoms */ #define OL_DECOR_CLOSE (1L << 0) #define OL_DECOR_RESIZEH (1L << 1) #define OL_DECOR_HEADER (1L << 2) #define OL_DECOR_ICON_NAME (1L << 3) #define OL_DECOR_ALL \ (OL_DECOR_CLOSE | OL_DECOR_RESIZEH | OL_DECOR_HEADER | OL_DECOR_ICON_NAME) /* indicates if there are any OL hints */ #define OL_ANY_HINTS (1L << 7) /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ extern Atom _XA_MwmAtom; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* Motif window hints */ typedef struct { long flags; long functions; long decorations; long inputMode; } PropMotifWmHints; typedef PropMotifWmHints PropMwmHints; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* * * Reads the property MOTIF_WM_HINTS * */ void GetMwmHints(FvwmWindow *t) { int actual_format; Atom actual_type; unsigned long nitems, bytesafter; if (t->mwm_hints) { XFree((char *)t->mwm_hints); t->mwm_hints = NULL; } if (XGetWindowProperty( dpy, FW_W(t), _XA_MwmAtom, 0L, 32L, False, _XA_MwmAtom, &actual_type, &actual_format, &nitems, &bytesafter,(unsigned char **)&t->mwm_hints)==Success) { if (nitems >= PROP_MOTIF_WM_HINTS_ELEMENTS) { return; } } t->mwm_hints = NULL; return; } /* * * Reads the openlook properties _OL_WIN_ATTR, _OL_DECOR_ADD, _OL_DECOR_DEL * * _OL_WIN_ATTR - the win_type field is the either the first atom if the * property has length three or the second atom if the property has * length five. It can be any of: * _OL_WT_BASE (no changes) * _OL_WT_CMD (no minimize decoration) * _OL_WT_HELP (no minimize, maximize or resize handle decorations) * _OL_WT_NOTICE (no minimize, maximize, system menu, resize handle * or titlebar decorations) * _OL_WT_OTHER (no minimize, maximize, system menu, resize handle * or titlebar decorations) * In addition, if the _OL_WIN_ATTR property is in the three atom format * or if the type is _OL_WT_OTHER, then the icon name is not displayed * (same behavior as olvwm). * * _OL_DECOR_ADD or _OL_DECOR_DEL - indivdually add or remove minimize * button (_OL_DECOR_CLOSE), resize handles (_OL_DECOR_RESIZE), title bar * (_OL_DECOR_HEADER), or icon name (_OL_DECOR_ICON_NAME). * * The documentation for the Open Look hints was taken from "Advanced X * Window Application Programming", Eric F. Johnson and Kevin Reichard * (M&T Books), and the olvwm source code (available at ftp.x.org in * /R5contrib). */ void GetOlHints(FvwmWindow *t) { int actual_format; Atom actual_type; unsigned long nitems, bytesafter; Atom *hints; int i; Atom win_type; t->ol_hints = OL_DECOR_ALL; if (XGetWindowProperty( dpy, FW_W(t), _XA_OL_WIN_ATTR, 0L, 32L, False, _XA_OL_WIN_ATTR, &actual_type, &actual_format, &nitems, &bytesafter, (unsigned char **)&hints) == Success) { if (nitems > 0) { t->ol_hints |= OL_ANY_HINTS; if (nitems == 3) { win_type = hints[0]; } else { win_type = hints[1]; } /* got this from olvwm and sort of mapped it to * fvwm/MWM hints */ if (win_type == _XA_OL_WT_BASE) { t->ol_hints = OL_DECOR_ALL; } else if (win_type == _XA_OL_WT_CMD) { t->ol_hints = OL_DECOR_ALL & ~OL_DECOR_CLOSE; } else if (win_type == _XA_OL_WT_HELP) { t->ol_hints = OL_DECOR_ALL & ~(OL_DECOR_CLOSE | OL_DECOR_RESIZEH); } else if (win_type == _XA_OL_WT_NOTICE) { t->ol_hints = OL_DECOR_ALL & ~(OL_DECOR_CLOSE | OL_DECOR_RESIZEH | OL_DECOR_HEADER | OL_DECOR_ICON_NAME); } else if (win_type == _XA_OL_WT_OTHER) { t->ol_hints = 0; } else { t->ol_hints = OL_DECOR_ALL; } if (nitems == 3) { t->ol_hints &= ~OL_DECOR_ICON_NAME; } } if (hints) { XFree (hints); } } if (XGetWindowProperty( dpy, FW_W(t), _XA_OL_DECOR_ADD, 0L, 32L, False, XA_ATOM, &actual_type, &actual_format, &nitems, &bytesafter,(unsigned char **)&hints)==Success) { for (i = 0; i < nitems; i++) { t->ol_hints |= OL_ANY_HINTS; if (hints[i] == _XA_OL_DECOR_CLOSE) { t->ol_hints |= OL_DECOR_CLOSE; } else if (hints[i] == _XA_OL_DECOR_RESIZE) { t->ol_hints |= OL_DECOR_RESIZEH; } else if (hints[i] == _XA_OL_DECOR_HEADER) { t->ol_hints |= OL_DECOR_HEADER; } else if (hints[i] == _XA_OL_DECOR_ICON_NAME) { t->ol_hints |= OL_DECOR_ICON_NAME; } } if (hints) { XFree (hints); } } if (XGetWindowProperty( dpy, FW_W(t), _XA_OL_DECOR_DEL, 0L, 32L, False, XA_ATOM, &actual_type, &actual_format, &nitems, &bytesafter,(unsigned char **)&hints)==Success) { for (i = 0; i < nitems; i++) { t->ol_hints |= OL_ANY_HINTS; if (hints[i] == _XA_OL_DECOR_CLOSE) { t->ol_hints &= ~OL_DECOR_CLOSE; } else if (hints[i] == _XA_OL_DECOR_RESIZE) { t->ol_hints &= ~OL_DECOR_RESIZEH; } else if (hints[i] == _XA_OL_DECOR_HEADER) { t->ol_hints &= ~OL_DECOR_HEADER; } else if (hints[i] == _XA_OL_DECOR_ICON_NAME) { t->ol_hints &= ~OL_DECOR_ICON_NAME; } } if (hints) { XFree (hints); } } return; } /* * * Interprets the property MOTIF_WM_HINTS, sets decoration and functions * accordingly * */ void SelectDecor(FvwmWindow *t, window_style *pstyle, short *buttons) { int decor; int i; int border_width; int handle_width; int used_width; PropMwmHints *prop; style_flags *sflags = &(pstyle->flags); border_width = (SHAS_BORDER_WIDTH(sflags)) ? SGET_BORDER_WIDTH(*pstyle) : DEFAULT_BORDER_WIDTH; if (border_width > MAX_BORDER_WIDTH) { border_width = MAX_BORDER_WIDTH; } handle_width = (SHAS_HANDLE_WIDTH(sflags)) ? SGET_HANDLE_WIDTH(*pstyle) : DEFAULT_HANDLE_WIDTH; if (handle_width > MAX_HANDLE_WIDTH) { handle_width = MAX_HANDLE_WIDTH; } *buttons = (1 << NUMBER_OF_TITLE_BUTTONS) - 1; decor = MWM_DECOR_ALL; t->functions = MWM_FUNC_ALL; if (t->mwm_hints) { prop = (PropMwmHints *)t->mwm_hints; if (SHAS_MWM_DECOR(sflags)) { if (prop->flags & MWM_HINTS_DECORATIONS) { decor = 0; if (prop->decorations & 0x1) { decor |= MWM_DECOR_ALL; } if (prop->decorations & 0x2) { decor |= MWM_DECOR_BORDER; } if (prop->decorations & 0x4) { decor |= MWM_DECOR_RESIZEH; } if (prop->decorations & 0x8) { decor |= MWM_DECOR_TITLE; } if (prop->decorations & 0x10) { decor |= MWM_DECOR_MENU; } if (prop->decorations & 0x20) { decor |= MWM_DECOR_MINIMIZE; } if (prop->decorations & 0x40) { decor |= MWM_DECOR_MAXIMIZE; } } } if (SHAS_MWM_FUNCTIONS(sflags)) { if (prop->flags & MWM_HINTS_FUNCTIONS) { t->functions = prop->functions; } } } /* functions affect the decorations! if the user says * no iconify function, then the iconify button doesn't show * up. */ if (t->functions & MWM_FUNC_ALL) { /* If we get ALL + some other things, that means to use * ALL except the other things... */ t->functions &= ~MWM_FUNC_ALL; t->functions = (MWM_FUNC_RESIZE | MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE) & (~(t->functions)); } if (SHAS_MWM_FUNCTIONS(sflags) && IS_TRANSIENT(t)) { t->functions &= ~(MWM_FUNC_MAXIMIZE|MWM_FUNC_MINIMIZE); } if (decor & MWM_DECOR_ALL) { /* If we get ALL + some other things, that means to use * ALL except the other things... */ decor &= ~MWM_DECOR_ALL; decor = MWM_DECOR_EVERYTHING & (~decor); } /* now add/remove any functions specified in the OL hints */ if (SHAS_OL_DECOR(sflags) && (t->ol_hints & OL_ANY_HINTS)) { if (t->ol_hints & OL_DECOR_CLOSE) { t->functions |= MWM_FUNC_MINIMIZE; decor |= MWM_FUNC_MINIMIZE; } else { t->functions &= ~MWM_FUNC_MINIMIZE; decor &= ~MWM_FUNC_MINIMIZE; } if (t->ol_hints & OL_DECOR_RESIZEH) { t->functions |= (MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); decor |= (MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } else { t->functions &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); decor &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } if (t->ol_hints & OL_DECOR_HEADER) { t->functions |= (MWM_DECOR_MENU | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_DECOR_TITLE); decor |= (MWM_DECOR_MENU | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_DECOR_TITLE); } else { t->functions &= ~(MWM_DECOR_MENU | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_DECOR_TITLE); decor &= ~(MWM_DECOR_MENU | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_DECOR_TITLE); } if (t->ol_hints & OL_DECOR_ICON_NAME) { SET_HAS_NO_ICON_TITLE(t, 0); } else { SET_HAS_NO_ICON_TITLE(t, 1); } } /* Now I have the un-altered decor and functions, but with the * ALL attribute cleared and interpreted. I need to modify the * decorations that are affected by the functions */ if (!(t->functions & MWM_FUNC_RESIZE)) { decor &= ~MWM_DECOR_RESIZEH; } /* MWM_FUNC_MOVE has no impact on decorations. */ if (!(t->functions & MWM_FUNC_MINIMIZE)) { decor &= ~MWM_DECOR_MINIMIZE; } if (!(t->functions & MWM_FUNC_MAXIMIZE)) { decor &= ~MWM_DECOR_MAXIMIZE; } /* MWM_FUNC_CLOSE has no impact on decorations. */ /* This rule is implicit, but its easier to deal with if * I take care of it now */ if (decor & (MWM_DECOR_MENU| MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE)) { decor |= MWM_DECOR_TITLE; } /* Selected the mwm-decor field, now trim down, based on * .fvwmrc entries */ if (SHAS_NO_TITLE(sflags) || (!SDO_DECORATE_TRANSIENT(sflags) && IS_TRANSIENT(t))) { decor &= ~MWM_DECOR_TITLE; } if (SHAS_NO_HANDLES(sflags) || (!SDO_DECORATE_TRANSIENT(sflags) && IS_TRANSIENT(t))) { decor &= ~MWM_DECOR_RESIZEH; } if (SHAS_MWM_DECOR(sflags) && IS_TRANSIENT(t)) { decor &= ~(MWM_DECOR_MAXIMIZE|MWM_DECOR_MINIMIZE); } if (FShapesSupported) { if (t->wShaped) { decor &= ~(MWM_DECOR_BORDER|MWM_DECOR_RESIZEH); } } if (IS_EWMH_FULLSCREEN(t)) { decor &=~(MWM_DECOR_BORDER|MWM_DECOR_RESIZEH|MWM_DECOR_TITLE); } /* Assume no decorations, and build up */ SET_HAS_TITLE(t, 0); SET_HAS_HANDLES(t, 0); used_width = 0; if (decor & MWM_DECOR_BORDER) { /* A narrow border is displayed (5 pixels - 2 relief, 1 top, * (2 shadow) */ used_width = border_width; } if (decor & MWM_DECOR_TITLE) { /* A title bar with no buttons in it * window gets a 1 pixel wide black border. */ SET_HAS_TITLE(t, 1); } if (decor & MWM_DECOR_RESIZEH) { /* A wide border, with corner tiles is desplayed * (10 pixels - 2 relief, 2 shadow) */ SET_HAS_HANDLES(t, 1); used_width = handle_width; } SET_HAS_NO_BORDER(t, S_HAS_NO_BORDER(SFC(*sflags)) || used_width <= 0); if (HAS_NO_BORDER(t)) { used_width = 0; } SET_HAS_HANDLES(t, (!HAS_NO_BORDER(t) && HAS_HANDLES(t))); set_window_border_size(t, used_width); if (!(decor & MWM_DECOR_MENU)) { /* title-bar menu button omitted * window gets 1 pixel wide black border */ /* disable any buttons with the MWMDecorMenu flag */ int i; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { if (TB_HAS_MWM_DECOR_MENU(GetDecor(t, buttons[i]))) { *buttons &= ~(1 << i); } } } if (!(decor & MWM_DECOR_MINIMIZE)) { /* title-bar + iconify button, no menu button. * window gets 1 pixel wide black border */ /* disable any buttons with the MWMDecorMinimize/MWMDecorShaded * flag */ int i; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { if (TB_HAS_MWM_DECOR_MINIMIZE(GetDecor(t, buttons[i]))) { *buttons &= ~(1 << i); } } } if (!(decor & MWM_DECOR_MAXIMIZE)) { /* title-bar + maximize button, no menu button, no iconify. * window has 1 pixel wide black border */ /* disable any buttons with the MWMDecorMaximize flag */ int i; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; ++i) { if (TB_HAS_MWM_DECOR_MAXIMIZE(GetDecor(t, buttons[i]))) { *buttons &= ~(1 << i); } } } for (i = (1 << (NUMBER_OF_TITLE_BUTTONS - 1)); i; i >>= 1) { if (t->buttons & i) *buttons &= ~i; } t->nr_left_buttons = Scr.nr_left_buttons; t->nr_right_buttons = Scr.nr_right_buttons; for (i = 0; i / 2 < Scr.nr_left_buttons; i += 2) { if ((*buttons & (1 << i)) == 0) t->nr_left_buttons--; } for (i = 1; i / 2 < Scr.nr_right_buttons; i += 2) { if ((*buttons & (1 << i)) == 0) t->nr_right_buttons--; } return; } static Bool __is_resize_allowed( const FvwmWindow *t, int functions, request_origin_t request_origin) { if (!HAS_OVERRIDE_SIZE_HINTS(t) && t->hints.min_width == t->hints.max_width && t->hints.min_height == t->hints.max_height) { return False; } if (request_origin && IS_SIZE_FIXED(t)) { return False; } else if (!request_origin && IS_PSIZE_FIXED(t)) { return False; } if (request_origin && !(functions & MWM_FUNC_RESIZE)) { return False; } return True; } /* ** seemed kind of silly to have check_allowed_function and ** check_allowed_function2 partially overlapping in their checks, so I ** combined them here and made them wrapper functions instead. */ Bool is_function_allowed( int function, char *action_string, const FvwmWindow *t, request_origin_t request_origin, Bool do_allow_override_mwm_hints) { unsigned int functions; char *functionlist[] = { MOVE_STRING, RESIZE_STRING1, RESIZE_STRING2, MINIMIZE_STRING, MINIMIZE_STRING2, MAXIMIZE_STRING, CLOSE_STRING1, CLOSE_STRING2, CLOSE_STRING3, CLOSE_STRING4, NULL }; if (t == NULL) { return True; /* this logic come from animated menu */ } if (do_allow_override_mwm_hints && HAS_MWM_OVERRIDE_HINTS(t)) { /* allow everything */ functions = ~0; } else { /* restrict by mwm hints */ functions = t->functions; } /* Hate to do it, but for lack of a better idea, check based on the * menu entry name */ /* Complex functions are a little tricky, ignore them if no menu item*/ if (function == F_FUNCTION && action_string != NULL) { int i; /* remap to regular actions */ i = GetTokenIndex(action_string, functionlist, -1, NULL); switch (i) { case 0: function = F_MOVE; break; case 1: function = F_RESIZE; break; case 2: function = F_RESIZE; break; case 3: function = F_ICONIFY; break; case 4: function = F_ICONIFY; break; case 5: function = F_MAXIMIZE; break; case 6: function = F_CLOSE; break; case 7: function = F_DELETE; break; case 8: function = F_DESTROY; break; case 9: function = F_QUIT; break; default: break; } } /* now do the real checks */ switch(function) { case F_DELETE: if (IS_UNCLOSABLE(t)) { return False; } if (IS_TEAR_OFF_MENU(t)) { /* always allow this on tear off menus */ break; } if (!WM_DELETES_WINDOW(t)) { return False; } /* fall through to close clause */ case F_CLOSE: if (IS_UNCLOSABLE(t)) { return False; } if (IS_TEAR_OFF_MENU(t)) { /* always allow this on tear off menus */ break; } if (!(functions & MWM_FUNC_CLOSE)) { return False; } break; case F_DESTROY: /* shouldn't destroy always be allowed??? */ if (IS_UNCLOSABLE(t)) { return False; } if (IS_TEAR_OFF_MENU(t)) { /* always allow this on tear off menus */ break; } if (!(functions & MWM_FUNC_CLOSE)) { return False; } break; case F_RESIZE: if(!__is_resize_allowed(t, functions, request_origin)) { return False; } break; case F_ICONIFY: if ((!IS_ICONIFIED(t) && !(functions & MWM_FUNC_MINIMIZE)) || IS_UNICONIFIABLE(t)) { return False; } break; case F_MAXIMIZE: if (IS_MAXIMIZE_FIXED_SIZE_DISALLOWED(t) && !__is_resize_allowed(t, functions, request_origin)) { return False; } if ((request_origin && !(functions & MWM_FUNC_MAXIMIZE)) || IS_UNMAXIMIZABLE(t)) { return False; } break; case F_MOVE: /* Move is a funny hint. Keeps it out of the menu, but you're * still allowed to move. */ if (request_origin && IS_FIXED(t)) { return False; } else if (!request_origin && IS_FIXED_PPOS(t)) { return False; } if (request_origin && !(functions & MWM_FUNC_MOVE)) { return False; } break; case F_FUNCTION: default: break; } /* end of switch */ /* if we fell through, just return True */ return True; } fvwm-2.6.7/fvwm/geometry.h0000644000175700017570000000635012773467232012450 00000000000000/* -*-c-*- */ #ifndef GEOMETRY_H #define GEOMETRY_H #define CS_ROUND_UP 0x01 #define CS_UPDATE_MAX_DEFECT 0x02 void gravity_get_naked_geometry( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g); void gravity_add_decoration( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g); void get_relative_geometry(rectangle *rel_g, rectangle *abs_g); void get_absolute_geometry(rectangle *abs_g, rectangle *rel_g); void gravity_translate_to_northwest_geometry( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g); void gravity_translate_to_northwest_geometry_no_bw( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g); void get_title_geometry( FvwmWindow *fw, rectangle *ret_g); int get_title_gravity( FvwmWindow *fw); void get_title_gravity_factors( FvwmWindow *fw, int *ret_fx, int *ret_fy); Bool get_title_button_geometry( FvwmWindow *fw, rectangle *ret_g, int context); void get_title_font_size_and_offset( FvwmWindow *fw, direction_t title_dir, Bool is_left_title_rotated_cw, Bool is_right_title_rotated_cw, Bool is_top_title_rotated, Bool is_bottom_title_rotated, int *size, int *offset); void get_icon_corner( FvwmWindow *fw, rectangle *ret_g); void get_shaded_geometry( FvwmWindow *fw, rectangle *small_g, rectangle *big_g); void get_shaded_geometry_with_dir( FvwmWindow *fw, rectangle *small_g, rectangle *big_g, direction_t shade_dir); void get_unshaded_geometry( FvwmWindow *fw, rectangle *ret_g); void get_shaded_client_window_pos( FvwmWindow *fw, rectangle *ret_g); void get_client_geometry( FvwmWindow *fw, rectangle *ret_g); void get_window_borders( const FvwmWindow *fw, size_borders *borders); void get_window_borders_no_title( const FvwmWindow *fw, size_borders *borders); void set_window_border_size( FvwmWindow *fw, int used_width); Bool is_window_border_minimal( FvwmWindow *fw); void update_relative_geometry(FvwmWindow *fw); void update_absolute_geometry(FvwmWindow *fw); void maximize_adjust_offset(FvwmWindow *fw); void constrain_size( FvwmWindow *fw, const XEvent *e, int *widthp, int *heightp, int xmotion, int ymotion, int flags); void gravity_constrain_size( int gravity, FvwmWindow *t, rectangle *rect, int flags); Bool get_visible_window_or_icon_geometry( FvwmWindow *fw, rectangle *ret_g); Bool get_visible_icon_geometry( FvwmWindow *fw, rectangle *ret_g); void get_icon_geometry( FvwmWindow *fw, rectangle *ret_g); Bool get_visible_icon_title_geometry( FvwmWindow *fw, rectangle *ret_g); Bool get_icon_title_geometry( FvwmWindow *fw, rectangle *ret_g); Bool get_visible_icon_picture_geometry( FvwmWindow *fw, rectangle *ret_g); Bool get_icon_picture_geometry( FvwmWindow *fw, rectangle *ret_g); void broadcast_icon_geometry(FvwmWindow *fw, Bool do_force); void move_icon_to_position(FvwmWindow *fw); void modify_icon_position(FvwmWindow *fw, int dx, int dy); void set_icon_position(FvwmWindow *fw, int x, int y); void set_icon_picture_size(FvwmWindow *fw, int w, int h); void resize_icon_title_height(FvwmWindow *fw, int dh); void get_page_offset_rectangle( int *ret_page_x, int *ret_page_y, rectangle *r); void get_page_offset( int *ret_page_x, int *ret_page_y, FvwmWindow *fw); void get_page_offset_check_visible( int *ret_page_x, int *ret_page_y, FvwmWindow *fw); #endif fvwm-2.6.7/fvwm/icccm2.c0000644000175700017570000001506612773467232011754 00000000000000/* -*-c-*- */ /* 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 #ifdef HAVE_FCNTL_H #include #endif #include #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "misc.h" #include "screen.h" #include "eventmask.h" Time managing_since; Atom _XA_WM_SX; Atom _XA_MANAGER; Atom _XA_ATOM_PAIR; Atom _XA_WM_COLORMAP_NOTIFY; #define _XA_TARGETS conversion_targets[0] #define _XA_MULTIPLE conversion_targets[1] #define _XA_TIMESTAMP conversion_targets[2] #define _XA_VERSION conversion_targets[3] #define MAX_TARGETS 4 long conversion_targets[MAX_TARGETS]; long icccm_version[] = { 2, 0 }; void SetupICCCM2(Bool replace_wm) { Window running_wm_win; XSetWindowAttributes attr; XEvent xev; XClientMessageEvent ev; char wm_sx[20]; sprintf(wm_sx, "WM_S%lu", Scr.screen); _XA_WM_SX = XInternAtom(dpy, wm_sx, False); _XA_MANAGER = XInternAtom(dpy, "MANAGER", False); _XA_ATOM_PAIR = XInternAtom(dpy, "ATOM_PAIR", False); _XA_TARGETS = XInternAtom(dpy, "TARGETS", False); _XA_MULTIPLE = XInternAtom(dpy, "MULTIPLE", False); _XA_TIMESTAMP = XInternAtom(dpy, "TIMESTAMP", False); _XA_VERSION = XInternAtom(dpy, "VERSION", False); _XA_WM_COLORMAP_NOTIFY = XInternAtom(dpy, "WM_COLORMAP_NOTIFY", False); /* Check for a running ICCCM 2.0 compliant WM */ running_wm_win = XGetSelectionOwner(dpy, _XA_WM_SX); if (running_wm_win != None) { DBUG( "SetupICCCM2", "another ICCCM 2.0 compliant WM is running"); if (!replace_wm) { fvwm_msg( ERR, "SetupICCCM2", "another ICCCM 2.0 compliant WM is running," " try -replace"); exit(1); } /* We need to know when the old manager is gone. Thus we wait until it destroys running_wm_win. */ attr.event_mask = StructureNotifyMask; XChangeWindowAttributes( dpy, running_wm_win, CWEventMask, &attr); } /* We are not yet in the event loop, thus fev_get_evtime() will not * be ready. Have to get a timestamp manually by provoking a * PropertyNotify. */ managing_since = get_server_time(); XSetSelectionOwner(dpy, _XA_WM_SX, Scr.NoFocusWin, managing_since); if (XGetSelectionOwner(dpy, _XA_WM_SX) != Scr.NoFocusWin) { fvwm_msg( ERR, "SetupICCCM2", "failed to acquire selection ownership"); exit(1); } /* Announce ourself as the new wm */ ev.type = ClientMessage; ev.window = Scr.Root; ev.message_type = _XA_MANAGER; ev.format = 32; ev.data.l[0] = managing_since; ev.data.l[1] = _XA_WM_SX; FSendEvent(dpy, Scr.Root, False, StructureNotifyMask,(XEvent*)&ev); if (running_wm_win != None) { /* Wait for the old wm to finish. */ /* FIXME: need a timeout here. */ DBUG("SetupICCCM2", "waiting for WM to give up"); do { FWindowEvent( dpy, running_wm_win, StructureNotifyMask, &xev); } while (xev.type != DestroyNotify); } /* restore NoFocusWin event mask */ attr.event_mask = XEVMASK_NOFOCUSW; XChangeWindowAttributes(dpy, Scr.NoFocusWin, CWEventMask, &attr); return; } /* We must make sure that we have released SubstructureRedirect before we destroy manager_win, so that another wm can start successfully. */ void CloseICCCM2(void) { DBUG("CloseICCCM2", "good luck, new wm"); XSelectInput(dpy, Scr.Root, NoEventMask); XFlush(dpy); return; } /* FIXME: property change actually succeeded */ static Bool convertProperty(Window w, Atom target, Atom property) { if (target == _XA_TARGETS) { XChangeProperty( dpy, w, property, XA_ATOM, 32, PropModeReplace, (unsigned char *)conversion_targets, MAX_TARGETS); } else if (target == _XA_TIMESTAMP) { long local_managing_since; local_managing_since = managing_since; XChangeProperty( dpy, w, property, XA_INTEGER, 32, PropModeReplace, (unsigned char *)&local_managing_since, 1); } else if (target == _XA_VERSION) { XChangeProperty( dpy, w, property, XA_INTEGER, 32, PropModeReplace, (unsigned char *)icccm_version, 2); } else { return False; } /* FIXME: This is ugly. We should rather select for PropertyNotify on the window, return to the main loop, and send the SelectionNotify once we are sure the property has arrived. Problem: this needs a list of pending SelectionNotifys. */ XFlush(dpy); return True; } void icccm2_handle_selection_request(const XEvent *e) { Atom type; unsigned long *adata; int i, format; unsigned long num, rest; unsigned char *data; XSelectionRequestEvent ev = e->xselectionrequest; XSelectionEvent reply; reply.type = SelectionNotify; reply.display = dpy; reply.requestor = ev.requestor; reply.selection = ev.selection; reply.target = ev.target; reply.property = None; reply.time = ev.time; if (ev.target == _XA_MULTIPLE) { if (ev.property != None) { XGetWindowProperty( dpy, ev.requestor, ev.property, 0L, 256L, False, _XA_ATOM_PAIR, &type, &format, &num, &rest, &data); /* 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 = (unsigned long *)data; for(i = 0; i < num; i += 2) { if (!convertProperty( ev.requestor, adata[i], adata[i+1])) { adata[i+1] = None; } } XChangeProperty( dpy, ev.requestor, ev.property, _XA_ATOM_PAIR, 32, PropModeReplace, data, num); XFree(data); } } else { if (ev.property == None) { ev.property = ev.target; } if (convertProperty(ev.requestor, ev.target, ev.property)) { reply.property = ev.property; } } FSendEvent(dpy, ev.requestor, False, 0L,(XEvent*)&reply); XFlush(dpy); return; } /* If another wm is requesting ownership of the selection, we receive a SelectionClear event. In that case, we have to release all resources and destroy manager_win. Done() calls CloseICCCM2() after undecorating all windows. */ void icccm2_handle_selection_clear(void) { DBUG("HandleSelectionClear", "I lost my selection!"); Done(0, NULL); return; } fvwm-2.6.7/fvwm/geometry.c0000644000175700017570000007300012773467232012437 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "misc.h" #include "screen.h" #include "geometry.h" #include "module_interface.h" #include "borders.h" #include "icons.h" #include "add_window.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Removes decorations from the source rectangle and moves it according to the * gravity specification. */ void gravity_get_naked_geometry( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g) { int xoff; int yoff; size_borders b; get_window_borders(t, &b); gravity_get_offsets(gravity, &xoff, &yoff); dest_g->x = orig_g->x + ((xoff + 1) * (orig_g->width - 1)) / 2; dest_g->y = orig_g->y + ((yoff + 1) * (orig_g->height - 1)) / 2; dest_g->width = orig_g->width - b.total_size.width; dest_g->height = orig_g->height - b.total_size.height; return; } /* Decorate the rectangle. Resize and shift it according to gravity. */ void gravity_add_decoration( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g) { size_borders b; get_window_borders(t, &b); *dest_g = *orig_g; gravity_resize( gravity, dest_g, b.total_size.width, b.total_size.height); return; } void get_relative_geometry(rectangle *rel_g, rectangle *abs_g) { rel_g->x = abs_g->x - Scr.Vx; rel_g->y = abs_g->y - Scr.Vy; rel_g->width = abs_g->width; rel_g->height = abs_g->height; return; } void get_absolute_geometry(rectangle *abs_g, rectangle *rel_g) { abs_g->x = rel_g->x + Scr.Vx; abs_g->y = rel_g->y + Scr.Vy; abs_g->width = rel_g->width; abs_g->height = rel_g->height; return; } void gravity_translate_to_northwest_geometry( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g) { int xoff; int yoff; gravity_get_offsets(gravity, &xoff, &yoff); dest_g->x = orig_g->x - ((xoff + 1) * (orig_g->width - 1 + 2 * t->attr_backup.border_width)) / 2; dest_g->y = orig_g->y - ((yoff + 1) * (orig_g->height - 1 + 2 * t->attr_backup.border_width)) / 2; dest_g->width = orig_g->width; dest_g->height = orig_g->height; return; } void gravity_translate_to_northwest_geometry_no_bw( int gravity, FvwmWindow *t, rectangle *dest_g, rectangle *orig_g) { int bw = t->attr_backup.border_width; t->attr_backup.border_width = 0; gravity_translate_to_northwest_geometry(gravity, t, dest_g, orig_g); t->attr_backup.border_width = bw; return; } void get_title_geometry( FvwmWindow *fw, rectangle *ret_g) { size_borders b; size_borders nt; int w; int h; get_window_borders(fw, &b); get_window_borders_no_title(fw, &nt); w = (ret_g->width > 0) ? ret_g->width : fw->g.frame.width; h = (ret_g->height > 0) ? ret_g->height : fw->g.frame.height; ret_g->x = nt.top_left.width; ret_g->y = nt.top_left.height; switch (GET_TITLE_DIR(fw)) { case DIR_S: ret_g->y = h - b.bottom_right.height; /* fall through */ case DIR_N: ret_g->width = w - b.total_size.width; ret_g->height = fw->title_thickness; break; case DIR_E: ret_g->x = w - b.bottom_right.width; /* fall through */ case DIR_W: ret_g->width = fw->title_thickness; ret_g->height = h - b.total_size.height; break; default: break; } return; } void get_title_gravity_factors( FvwmWindow *fw, int *ret_fx, int *ret_fy) { switch (GET_TITLE_DIR(fw)) { case DIR_N: *ret_fx = 0; *ret_fy = 1; break; case DIR_S: *ret_fx = 0; *ret_fy = -1; break; case DIR_W: *ret_fx = 1; *ret_fy = 0; break; case DIR_E: *ret_fx = -1; *ret_fy = 0; break; } return; } Bool get_title_button_geometry( FvwmWindow *fw, rectangle *ret_g, int context) { int bnum; if (context & C_TITLE) { ret_g->width = 0; ret_g->height = 0; get_title_geometry(fw, ret_g); ret_g->x += fw->g.frame.x; ret_g->y += fw->g.frame.y; return True; } bnum = get_button_number(context); if (bnum < 0 || FW_W_BUTTON(fw, bnum) == None) { return False; } if (XGetGeometry( dpy, FW_W_BUTTON(fw, bnum), &JunkRoot, &ret_g->x, &ret_g->y, (unsigned int*)&ret_g->width, (unsigned int*)&ret_g->height, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { return False; } XTranslateCoordinates( dpy, FW_W_FRAME(fw), Scr.Root, ret_g->x, ret_g->y, &ret_g->x, &ret_g->y, &JunkChild); return True; } void get_title_font_size_and_offset( FvwmWindow *fw, direction_t title_dir, Bool is_left_title_rotated_cw, Bool is_right_title_rotated_cw, Bool is_top_title_rotated, Bool is_bottom_title_rotated, int *size, int *offset) { int decor_size; int extra_size; int font_size; int min_offset; Bool is_rotated_cw, is_rotated; rotation_t draw_rotation; /* adjust font offset according to height specified in title style */ decor_size = fw->decor->title_height; font_size = fw->title_font->height + EXTRA_TITLE_FONT_HEIGHT; switch (title_dir) { case DIR_W: case DIR_E: is_rotated_cw = (title_dir == DIR_W) ? is_left_title_rotated_cw : is_right_title_rotated_cw; if (is_rotated_cw) { fw->title_text_rotation = ROTATION_90; } else { fw->title_text_rotation = ROTATION_270; } break; case DIR_N: case DIR_S: default: is_rotated = (title_dir == DIR_N) ? is_top_title_rotated : is_bottom_title_rotated; if (is_rotated) { fw->title_text_rotation = ROTATION_180; } else { fw->title_text_rotation = ROTATION_0; } break; } if (USE_TITLE_DECOR_ROTATION(fw)) { draw_rotation = ROTATION_0; } else { draw_rotation = fw->title_text_rotation; } min_offset = FlocaleGetMinOffset( fw->title_font, draw_rotation); extra_size = (decor_size > 0) ? decor_size - font_size : 0; *offset = min_offset; if (fw->decor->min_title_height > 0 && font_size + extra_size < fw->decor->min_title_height) { extra_size = fw->decor->min_title_height - font_size; } if (extra_size > 0) { *offset += extra_size / 2; } *size = font_size + extra_size; return; } void get_icon_corner( FvwmWindow *fw, rectangle *ret_g) { switch (GET_TITLE_DIR(fw)) { case DIR_N: case DIR_W: ret_g->x = fw->g.frame.x; ret_g->y = fw->g.frame.y; break; case DIR_S: ret_g->x = fw->g.frame.x; ret_g->y = fw->g.frame.y + fw->g.frame.height - ret_g->height; break; case DIR_E: ret_g->x = fw->g.frame.x + fw->g.frame.width - ret_g->width; ret_g->y = fw->g.frame.y; break; } return; } void get_shaded_geometry( FvwmWindow *fw, rectangle *small_g, rectangle *big_g) { size_borders b; /* this variable is necessary so the function can be called with * small_g == big_g */ int big_width = big_g->width; int big_height = big_g->height; int d; switch (SHADED_DIR(fw)) { case DIR_SW: case DIR_SE: case DIR_NW: case DIR_NE: get_window_borders_no_title(fw, &b); break; default: get_window_borders(fw, &b); break; } *small_g = *big_g; d = 0; switch (SHADED_DIR(fw)) { case DIR_S: case DIR_SW: case DIR_SE: small_g->y = big_g->y + big_height - b.total_size.height; d = 1; /* fall through */ case DIR_N: case DIR_NW: case DIR_NE: small_g->height = b.total_size.height; if (small_g->height == 0) { small_g->height = 1; small_g->y -= d; } break; default: break; } d = 0; switch (SHADED_DIR(fw)) { case DIR_E: case DIR_NE: case DIR_SE: small_g->x = big_g->x + big_width - b.total_size.width; d = 1; /* fall through */ case DIR_W: case DIR_NW: case DIR_SW: small_g->width = b.total_size.width; if (small_g->width == 0) { small_g->width = 1; small_g->x -= d; } break; default: break; } return; } void get_shaded_geometry_with_dir( FvwmWindow *fw, rectangle *small_g, rectangle *big_g, direction_t shade_dir) { direction_t old_shade_dir; old_shade_dir = SHADED_DIR(fw); SET_SHADED_DIR(fw, shade_dir); get_shaded_geometry(fw, small_g, big_g); SET_SHADED_DIR(fw, old_shade_dir); return; } void get_unshaded_geometry( FvwmWindow *fw, rectangle *ret_g) { if (IS_SHADED(fw)) { if (IS_MAXIMIZED(fw)) { *ret_g = fw->g.max; } else { *ret_g = fw->g.normal; } get_relative_geometry(ret_g, ret_g); } else { *ret_g = fw->g.frame; } return; } void get_shaded_client_window_pos( FvwmWindow *fw, rectangle *ret_g) { rectangle big_g; size_borders b; get_window_borders(fw, &b); big_g = (IS_MAXIMIZED(fw)) ? fw->g.max : fw->g.normal; get_relative_geometry(&big_g, &big_g); switch (SHADED_DIR(fw)) { case DIR_S: case DIR_SW: case DIR_SE: ret_g->y = 1 - big_g.height + b.total_size.height; break; default: ret_g->y = 0; break; } switch (SHADED_DIR(fw)) { case DIR_E: case DIR_NE: case DIR_SE: ret_g->x = 1 - big_g.width + b.total_size.width; break; default: ret_g->x = 0; break; } return; } /* returns the dimensions of the borders */ void get_window_borders( const FvwmWindow *fw, size_borders *borders) { borders->top_left.width = fw->boundary_width; borders->bottom_right.width = fw->boundary_width; borders->top_left.height = fw->boundary_width; borders->bottom_right.height = fw->boundary_width; switch (GET_TITLE_DIR(fw)) { case DIR_N: borders->top_left.height += fw->title_thickness; break; case DIR_S: borders->bottom_right.height += fw->title_thickness; break; case DIR_W: borders->top_left.width += fw->title_thickness; break; case DIR_E: borders->bottom_right.width += fw->title_thickness; break; } borders->total_size.width = borders->top_left.width + borders->bottom_right.width; borders->total_size.height = borders->top_left.height + borders->bottom_right.height; return; } /* returns the dimensions of the borders without the title */ void get_window_borders_no_title( const FvwmWindow *fw, size_borders *borders) { borders->top_left.width = fw->boundary_width; borders->bottom_right.width = fw->boundary_width; borders->top_left.height = fw->boundary_width; borders->bottom_right.height = fw->boundary_width; borders->total_size.width = borders->top_left.width + borders->bottom_right.width; borders->total_size.height = borders->top_left.height + borders->bottom_right.height; return; } void set_window_border_size( FvwmWindow *fw, int used_width) { if (used_width <= 0) { fw->boundary_width = 0; fw->unshaped_boundary_width = 0; } else { fw->unshaped_boundary_width = used_width; fw->boundary_width = (fw->wShaped) ? 0 : used_width; } return; } /* Returns True if all window borders are only 1 pixel thick (or less). */ Bool is_window_border_minimal( FvwmWindow *fw) { size_borders nt; get_window_borders_no_title(fw, &nt); if (nt.top_left.width > 1 || nt.top_left.height > 1 || nt.bottom_right.width > 1 || nt.bottom_right.height > 1) { return False; } return True; } /* This function returns the geometry of the client window. If the window is * shaded, the unshaded geometry is used instead. */ void get_client_geometry( FvwmWindow *fw, rectangle *ret_g) { size_borders borders; get_unshaded_geometry(fw, ret_g); get_window_borders(fw, &borders); ret_g->x += borders.top_left.width; ret_g->y += borders.top_left.height; ret_g->width -= borders.total_size.width; ret_g->height -= borders.total_size.height; return; } /* update the frame_g according to the window's g.normal or g.max and shaded * state */ void update_relative_geometry(FvwmWindow *fw) { get_relative_geometry( &fw->g.frame, (IS_MAXIMIZED(fw)) ? &fw->g.max : &fw->g.normal); if (IS_SHADED(fw)) { get_shaded_geometry( fw, &fw->g.frame, &fw->g.frame); } return; } /* update the g.normal or g.max according to the window's current position */ void update_absolute_geometry(FvwmWindow *fw) { rectangle *dest_g; rectangle frame_g; /* store orig values in absolute coords */ dest_g = (IS_MAXIMIZED(fw)) ? &fw->g.max : &fw->g.normal; frame_g = *dest_g; dest_g->x = fw->g.frame.x + Scr.Vx; dest_g->y = fw->g.frame.y + Scr.Vy; dest_g->width = fw->g.frame.width; dest_g->height = fw->g.frame.height; if (IS_SHADED(fw)) { switch (SHADED_DIR(fw)) { case DIR_SW: case DIR_S: case DIR_SE: dest_g->y += fw->g.frame.height - frame_g.height; /* fall through */ case DIR_NW: case DIR_N: case DIR_NE: dest_g->height = frame_g.height; break; } switch (SHADED_DIR(fw)) { case DIR_NE: case DIR_E: case DIR_SE: dest_g->x += fw->g.frame.width - frame_g.width; /* fall through */ case DIR_NW: case DIR_W: case DIR_SW: dest_g->width = frame_g.width; break; } } return; } /* make sure a maximized window and it's normal version are never a page or * more apart. */ void maximize_adjust_offset(FvwmWindow *fw) { int off_x; int off_y; int dh; int dw; if (!IS_MAXIMIZED(fw)) { /* otherwise we might corrupt the g.normal */ return; } off_x = fw->g.normal.x - fw->g.max.x - fw->g.max_offset.x; off_y = fw->g.normal.y - fw->g.max.y - fw->g.max_offset.y; dw = Scr.MyDisplayWidth; dh = Scr.MyDisplayHeight; if (off_x >= dw) { fw->g.normal.x -= (off_x / dw) * dw; } else if (off_x <= -dw) { fw->g.normal.x += (-off_x / dw) * dw; } if (off_y >= dh) { fw->g.normal.y -= (off_y / dh) * dh; } else if (off_y <= -dh) { fw->g.normal.y += (-off_y / dh) * dh; } return; } #define MAKEMULT(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) static void __cs_handle_aspect_ratio( size_rect *ret_s, FvwmWindow *fw, size_rect s, const size_rect base, const size_rect inc, size_rect min, size_rect max, int xmotion, int ymotion, int flags) { volatile double odefect; volatile double defect; volatile double rmax; volatile double rmin; volatile int delta; volatile int ow; volatile int oh; if (fw->hints.flags & PBaseSize) { /* * ICCCM 2 demands that aspect ratio should apply to width - * base_width. To prevent funny results, we reset PBaseSize in * GetWindowSizeHints, if base is not smaller than min. */ s.width -= base.width; max.width -= base.width; min.width -= base.width; s.height -= base.height; max.height -= base.height; min.height -= base.height; } rmin = (double)fw->hints.min_aspect.x / (double)fw->hints.min_aspect.y; rmax = (double)fw->hints.max_aspect.x / (double)fw->hints.max_aspect.y; do { double r; r = (double)s.width / (double)s.height; ow = s.width; oh = s.height; odefect = 0; if (r < rmin) { odefect = rmin - r; } else if (r > rmax) { odefect = r - rmax; } if (r < rmin && (flags & CS_ROUND_UP) && xmotion == 0) { /* change width to match */ delta = MAKEMULT(s.height * rmin - s.width, inc.width); if (s.width + delta <= max.width) { s.width += delta; } r = (double)s.width / (double)s.height; } if (r < rmin) { /* change height to match */ delta = MAKEMULT( s.height - s.width / rmin, inc.height); if (s.height - delta >= min.height) { s.height -= delta; } else { delta = MAKEMULT( s.height * rmin - s.width, inc.width); if (s.width + delta <= max.width) { s.width += delta; } } r = (double)s.width / (double)s.height; } if (r > rmax && (flags & CS_ROUND_UP) && ymotion == 0) { /* change height to match */ delta = MAKEMULT(s.width /rmax - s.height, inc.height); if (s.height + delta <= max.height) { s.height += delta; } r = (double)s.width / (double)s.height; } if (r > rmax) { /* change width to match */ delta = MAKEMULT(s.width - s.height * rmax, inc.width); if (s.width - delta >= min.width) { s.width -= delta; } else { delta = MAKEMULT( s.width / rmax - s.height, inc.height); if (s.height + delta <= max.height) { s.height += delta; } } r = (double)s.width / (double)s.height; } defect = 0; if (r < rmin) { defect = rmin - r; } else if (r > rmax) { defect = r - rmax; } } while (odefect > defect); if (fw->hints.flags & PBaseSize) { ow += base.width; oh += base.height; } ret_s->width = ow; ret_s->height = oh; return; } /* * * Procedure: * constrain_size - adjust the given width and height to account for the * constraints imposed by size hints */ void constrain_size( FvwmWindow *fw, const XEvent *e, int *widthp, int *heightp, int xmotion, int ymotion, int flags) { size_rect min; size_rect max; size_rect inc; size_rect base; size_rect round_up; size_rect d; size_rect old; size_borders b; if (DO_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw) == 1) { return; } if (HAS_NEW_WM_NORMAL_HINTS(fw)) { /* get the latest size hints */ XSync(dpy, 0); GetWindowSizeHints(fw); SET_HAS_NEW_WM_NORMAL_HINTS(fw, 0); } if (IS_MAXIMIZED(fw) && (flags & CS_UPDATE_MAX_DEFECT)) { *widthp += fw->g.max_defect.width; *heightp += fw->g.max_defect.height; } /* gcc 4.1.1 warns about these not being initialized at the end, * but the conditions for the use are the same...*/ old.width = *widthp; old.height = *heightp; d.width = *widthp; d.height = *heightp; get_window_borders(fw, &b); d.width -= b.total_size.width; d.height -= b.total_size.height; min.width = fw->hints.min_width; min.height = fw->hints.min_height; if (min.width < fw->min_window_width - b.total_size.width) { min.width = fw->min_window_width - b.total_size.width; } if (min.height < fw->min_window_height - b.total_size.height) { min.height = fw->min_window_height - b.total_size.height; } max.width = fw->hints.max_width; max.height = fw->hints.max_height; if (max.width > fw->max_window_width - b.total_size.width) { max.width = fw->max_window_width - b.total_size.width; } if (max.height > fw->max_window_height - b.total_size.height) { max.height = fw->max_window_height - b.total_size.height; } if (min.width > max.width) { min.width = max.width; } if (min.height > max.height) { min.height = max.height; } base.width = fw->hints.base_width; base.height = fw->hints.base_height; inc.width = fw->hints.width_inc; inc.height = fw->hints.height_inc; /* * First, clamp to min and max values */ if (d.width < min.width) { d.width = min.width; } if (d.height < min.height) { d.height = min.height; } if (d.width > max.width) { d.width = max.width; } if (d.height > max.height) { d.height = max.height; } /* * Second, round to base + N * inc (up or down depending on resize * type) if rounding up store amount */ if (!(flags & CS_ROUND_UP)) { d.width = ((d.width - base.width) / inc.width) * inc.width + base.width; d.height = ((d.height - base.height) / inc.height) * inc.height + base.height; } else { round_up.width = d.width; round_up.height = d.height; d.width = ((d.width - base.width + inc.width - 1) / inc.width) * inc.width + base.width; d.height = ((d.height - base.height + inc.height - 1) / inc.height) * inc.height + base.height; round_up.width = d.width - round_up.width; round_up.height = d.height - round_up.height; } /* * Step 2a: check we didn't move the edge off screen in interactive * moves */ if ((flags & CS_ROUND_UP) && e != NULL && e->type == MotionNotify) { if (xmotion > 0 && e->xmotion.x_root < round_up.width) { d.width -= inc.width; } else if ( xmotion < 0 && e->xmotion.x_root >= Scr.MyDisplayWidth - round_up.width) { d.width -= inc.width; } if (ymotion > 0 && e->xmotion.y_root < round_up.height) { d.height -= inc.height; } else if ( ymotion < 0 && e->xmotion.y_root >= Scr.MyDisplayHeight - round_up.height) { d.height -= inc.height; } } /* * Step 2b: Check that we didn't violate min and max. */ if (d.width < min.width) { d.width += inc.width; } if (d.height < min.height) { d.height += inc.height; } if (d.width > max.width) { d.width -= inc.width; } if (d.height > max.height) { d.height -= inc.height; } /* * Third, adjust for aspect ratio */ if (fw->hints.flags & PAspect) { __cs_handle_aspect_ratio( &d, fw, d, base, inc, min, max, xmotion, ymotion, flags); } /* * Fourth, account for border width and title height */ *widthp = d.width + b.total_size.width; *heightp = d.height + b.total_size.height; if (IS_MAXIMIZED(fw) && (flags & CS_UPDATE_MAX_DEFECT)) { /* update size defect for maximized window */ fw->g.max_defect.width = old.width - *widthp; fw->g.max_defect.height = old.height - *heightp; } return; } /* This function does roughly the same as constrain_size, but takes into account * that the window shifts according to gravity if constrain_size actually * changes the width or height. The frame_g of the window is not changed. The * target geometry is expected to be in *rect and will be retured through rect. */ void gravity_constrain_size( int gravity, FvwmWindow *t, rectangle *rect, int flags) { int new_width = rect->width; int new_height = rect->height; if (IS_MAXIMIZED(t) && (flags & CS_UPDATE_MAX_DEFECT)) { gravity_resize( gravity, rect, t->g.max_defect.width, t->g.max_defect.height); t->g.max_defect.width = 0; t->g.max_defect.height = 0; new_width = rect->width; new_height = rect->height; } constrain_size( t, NULL, &new_width, &new_height, 0, 0, flags); if (rect->width != new_width || rect->height != new_height) { gravity_resize( gravity, rect, new_width - rect->width, new_height - rect->height); } return; } /* returns the icon title geometry if it is visible */ Bool get_visible_icon_title_geometry( FvwmWindow *fw, rectangle *ret_g) { if (HAS_NO_ICON_TITLE(fw) || IS_ICON_UNMAPPED(fw) || !IS_ICONIFIED(fw)) { memset(ret_g, 0, sizeof(*ret_g)); return False; } *ret_g = fw->icon_g.title_w_g; return True; } /* returns the icon title geometry if it the icon title window exists */ Bool get_icon_title_geometry( FvwmWindow *fw, rectangle *ret_g) { if (HAS_NO_ICON_TITLE(fw)) { memset(ret_g, 0, sizeof(*ret_g)); return False; } *ret_g = fw->icon_g.title_w_g; return True; } /* returns the icon picture geometry if it is visible */ Bool get_visible_icon_picture_geometry( FvwmWindow *fw, rectangle *ret_g) { if (fw->icon_g.picture_w_g.width == 0 || IS_ICON_UNMAPPED(fw) || !IS_ICONIFIED(fw)) { memset(ret_g, 0, sizeof(*ret_g)); return False; } *ret_g = fw->icon_g.picture_w_g; return True; } /* returns the icon picture geometry if it is exists */ Bool get_icon_picture_geometry( FvwmWindow *fw, rectangle *ret_g) { if (fw->icon_g.picture_w_g.width == 0) { memset(ret_g, 0, sizeof(*ret_g)); return False; } *ret_g = fw->icon_g.picture_w_g; return True; } /* returns the icon geometry (unexpanded title plus pixmap) if it is visible */ Bool get_visible_icon_geometry( FvwmWindow *fw, rectangle *ret_g) { if (IS_ICON_UNMAPPED(fw) || !IS_ICONIFIED(fw)) { memset(ret_g, 0, sizeof(*ret_g)); return False; } if (fw->icon_g.picture_w_g.width > 0) { *ret_g = fw->icon_g.picture_w_g; if (!HAS_NO_ICON_TITLE(fw)) { ret_g->height += fw->icon_g.title_w_g.height; } } else if (!HAS_NO_ICON_TITLE(fw)) { *ret_g = fw->icon_g.title_w_g; } else { memset(ret_g, 0, sizeof(*ret_g)); return False; } return True; } /* returns the icon geometry (unexpanded title plus pixmap) if it exists */ void get_icon_geometry( FvwmWindow *fw, rectangle *ret_g) { /* valid geometry? */ if (fw->icon_g.picture_w_g.width > 0) { *ret_g = fw->icon_g.picture_w_g; if (!HAS_NO_ICON_TITLE(fw)) { ret_g->height += fw->icon_g.title_w_g.height; } } else if (fw->icon_g.title_w_g.width > 0) { *ret_g = fw->icon_g.title_w_g; } /* valid position? */ else if (fw->icon_g.picture_w_g.x != 0 || fw->icon_g.picture_w_g.y != 0) { *ret_g = fw->icon_g.picture_w_g; } else if (fw->icon_g.title_w_g.x != 0 || fw->icon_g.title_w_g.y != 0) { *ret_g = fw->icon_g.title_w_g; } else { memset(ret_g, 0, sizeof(*ret_g)); } return; } /* Returns the visible geometry of a window or icon. This can be used to test * if this region overlaps other windows. */ Bool get_visible_window_or_icon_geometry( FvwmWindow *fw, rectangle *ret_g) { if (IS_ICONIFIED(fw)) { return get_visible_icon_geometry(fw, ret_g); } *ret_g = fw->g.frame; return True; } void move_icon_to_position( FvwmWindow *fw) { Bool draw_picture_w = False; Bool draw_title_w = False; if (fw->icon_g.picture_w_g.width > 0) { int cs; if (Scr.Hilite == fw) { cs = fw->cs_hi; } else { cs = fw->cs; } XMoveWindow( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y); if (fw->icon_alphaPixmap || (cs >= 0 && Colorset[cs].icon_alpha_percent < 100) || CSET_IS_TRANSPARENT(fw->icon_background_cs) || (!IS_ICON_SHAPED(fw) && fw->icon_background_padding > 0)) { draw_picture_w = True; } } if (!HAS_NO_ICON_TITLE(fw)) { int cs; rectangle dummy; if (Scr.Hilite == fw) { cs = fw->icon_title_cs_hi; } else { cs = fw->icon_title_cs; } XMoveWindow( dpy, FW_W_ICON_TITLE(fw), fw->icon_g.title_w_g.x, fw->icon_g.title_w_g.y); if (CSET_IS_TRANSPARENT(cs) && !get_visible_icon_picture_geometry(fw, &dummy) && get_visible_icon_title_geometry(fw, &dummy)) { draw_title_w = True; } } if (draw_title_w || draw_picture_w) { DrawIconWindow( fw, draw_title_w, draw_picture_w, False, draw_picture_w, NULL); } return; } void broadcast_icon_geometry( FvwmWindow *fw, Bool do_force) { rectangle g; Bool rc; rc = get_visible_icon_geometry(fw, &g); if (rc == True && (!IS_ICON_UNMAPPED(fw) || do_force == True)) { BroadcastPacket( M_ICON_LOCATION, 7, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw, (long)g.x, (long)g.y, (long)g.width, (long)g.height); } return; } void modify_icon_position( FvwmWindow *fw, int dx, int dy) { if (fw->icon_g.picture_w_g.width > 0 || HAS_NO_ICON_TITLE(fw)) { /* picture position is also valid if there is neither a picture * nor a title */ fw->icon_g.picture_w_g.x += dx; fw->icon_g.picture_w_g.y += dy; } if (!HAS_NO_ICON_TITLE(fw)) { fw->icon_g.title_w_g.x += dx; fw->icon_g.title_w_g.y += dy; } return; } /* set the icon position to the specified value. take care of the actual icon * layout */ void set_icon_position( FvwmWindow *fw, int x, int y) { if (fw->icon_g.picture_w_g.width > 0) { fw->icon_g.picture_w_g.x = x; fw->icon_g.picture_w_g.y = y; } else { fw->icon_g.picture_w_g.x = 0; fw->icon_g.picture_w_g.y = 0; } if (!HAS_NO_ICON_TITLE(fw)) { fw->icon_g.title_w_g.x = x; fw->icon_g.title_w_g.y = y; } else { fw->icon_g.title_w_g.x = 0; fw->icon_g.title_w_g.y = 0; } if (fw->icon_g.picture_w_g.width > 0 && !HAS_NO_ICON_TITLE(fw)) { fw->icon_g.title_w_g.x -= (fw->icon_g.title_w_g.width - fw->icon_g.picture_w_g.width) / 2; fw->icon_g.title_w_g.y += fw->icon_g.picture_w_g.height; } else if (fw->icon_g.picture_w_g.width <= 0 && HAS_NO_ICON_TITLE(fw)) { /* In case there is no icon, fake the icon position so the * modules know where its window was iconified. */ fw->icon_g.picture_w_g.x = x; fw->icon_g.picture_w_g.y = y; } return; } void set_icon_picture_size( FvwmWindow *fw, int w, int h) { if (fw->icon_g.picture_w_g.width > 0) { fw->icon_g.picture_w_g.width = w; fw->icon_g.picture_w_g.height = h; } else { fw->icon_g.picture_w_g.width = 0; fw->icon_g.picture_w_g.height = 0; } return; } void resize_icon_title_height(FvwmWindow *fw, int dh) { if (!HAS_NO_ICON_TITLE(fw)) { fw->icon_g.title_w_g.height += dh; } return; } void get_page_offset_rectangle( int *ret_page_x, int *ret_page_y, rectangle *r) { int xoff = Scr.Vx % Scr.MyDisplayWidth; int yoff = Scr.Vy % Scr.MyDisplayHeight; /* maximize on the page where the center of the window is */ *ret_page_x = truncate_to_multiple( r->x + r->width / 2 + xoff, Scr.MyDisplayWidth) - xoff; *ret_page_y = truncate_to_multiple( r->y + r->height / 2 + yoff, Scr.MyDisplayHeight) - yoff; return; } void get_page_offset( int *ret_page_x, int *ret_page_y, FvwmWindow *fw) { rectangle r; r.x = fw->g.frame.x; r.y = fw->g.frame.y; r.width = fw->g.frame.width; r.height = fw->g.frame.height; get_page_offset_rectangle(ret_page_x, ret_page_y, &r); return; } void get_page_offset_check_visible( int *ret_page_x, int *ret_page_y, FvwmWindow *fw) { if (IsRectangleOnThisPage(&fw->g.frame, fw->Desk)) { /* maximize on visible page if any part of the window is * visible */ *ret_page_x = 0; *ret_page_y = 0; } else { get_page_offset(ret_page_x, ret_page_y, fw); } return; } /* ---------------------------- builtin commands --------------------------- */ fvwm-2.6.7/fvwm/session.c0000644000175700017570000012442113003342500012244 00000000000000/* -*-c-*- */ /* 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 */ /* This file is strongly based on the corresponding files from twm and enlightenment. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #ifdef HAVE_GETPWUID #include #endif #include #include #include #include "libs/fvwmlib.h" #include "libs/FSMlib.h" #include "libs/Strings.h" #include "libs/System.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "add_window.h" #include "misc.h" #include "screen.h" #include "session.h" #include "module_list.h" #include "module_interface.h" #include "stack.h" #include "icccm2.h" #include "virtual.h" #include "geometry.h" #include "move_resize.h" #include "infostore.h" /* ---------------------------- local definitions -------------------------- */ /*#define FVWM_SM_DEBUG_PROTO*/ /*#define FVWM_SM_DEBUG_WINMATCH*/ #define FVWM_SM_DEBUG_FILES /* ---------------------------- local macros ------------------------------- */ #define xstreq(a,b) ((!a && !b) || (a && b && (strcmp(a,b)==0))) /* ---------------------------- imports ------------------------------------ */ extern Bool Restarting; extern int master_pid; extern char **g_argv; extern int g_argc; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct _match { unsigned long win; char *client_id; char *res_name; char *res_class; char *window_role; char *wm_name; int wm_command_count; char **wm_command; int x, y, w, h, icon_x, icon_y; int x_max, y_max, w_max, h_max; int width_defect_max, height_defect_max; int max_x_offset, max_y_offset; int desktop; int layer; int default_layer; int placed_by_button; int used; int gravity; unsigned long ewmh_hint_desktop; window_flags flags; } Match; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static char *previous_sm_client_id = NULL; static char *sm_client_id = NULL; static Bool sent_save_done = 0; static char *real_state_filename = NULL; static Bool going_to_restart = False; static FIceIOErrorHandler prev_handler; static FSmcConn sm_conn = NULL; static int num_match = 0; static Match *matches = NULL; static Bool does_file_version_match = False; static Bool do_preserve_state = True; /* ---------------------------- exported variables (globals) --------------- */ int sm_fd = -1; /* ---------------------------- local functions ---------------------------- */ static char *duplicate(const char *s) { int l; char *r; if (!s) return NULL; l = strlen(s); r = (char *) safemalloc (sizeof(char)*(l+1)); strncpy(r, s, l+1); return r; } static char *get_version_string(void) { /* migo (14-Mar-2001): it is better to manually update a version string * in the stable branch, otherwise saving sessions becomes useless */ return CatString3(VERSION, ", ", __DATE__); /* return "2.6-0"; */ } static char *unspace_string(const char *str) { static const char *spaces = " \t\n"; char *tr_str = CatString2(str, NULL); int i; if (!tr_str) { return NULL; } for (i = 0; i < strlen(spaces); i++) { char *ptr = tr_str; while ((ptr = strchr(ptr, spaces[i])) != NULL) { *(ptr++) = '_'; } } return tr_str; } /* * It is a bit ugly to have a separate file format for * config files and session save files. The proper way * to do this may be to extend the config file format * to allow the specification of everything we need * to save here. Then the option "-restore xyz" could * be replaced by "-f xyz". */ static int SaveGlobalState(FILE *f) { fprintf(f, "[GLOBAL]\n"); fprintf(f, " [DESKTOP] %i\n", Scr.CurrentDesk); fprintf(f, " [VIEWPORT] %i %i %i %i\n", Scr.Vx, Scr.Vy, Scr.VxMax, Scr.VyMax); fprintf(f, " [SCROLL] %i %i %i %i %i\n", Scr.EdgeScrollX, Scr.EdgeScrollY, Scr.ScrollDelay, !!(Scr.flags.do_edge_wrap_x), !!(Scr.flags.do_edge_wrap_y)); fprintf(f, " [MISC] %i %i %i\n", Scr.ClickTime, Scr.ColormapFocus, Scr.ColorLimit); fprintf( f, " [STYLE] %i %i\n", Scr.gs.do_emulate_mwm, Scr.gs.do_emulate_win); if (get_metainfo_length() > 0) { MetaInfo *mi = get_metainfo(), *mi_i; fprintf(f, " [INFOSTORE]\n"); for (mi_i = mi; mi_i; mi_i = mi_i->next) { fprintf(f, " [KEY] %s\n", mi_i->key); fprintf(f, " [VALUE] %s\n", mi_i->value); } } return 1; } static void set_real_state_filename(char *filename) { if (!SessionSupport) { return; } if (real_state_filename) { free(real_state_filename); } real_state_filename = safestrdup(filename); return; } static char *get_unique_state_filename(void) { const char *path = getenv("SM_SAVE_DIR"); char *filename; int fd; if (!SessionSupport) { return NULL; } if (!path) { path = getenv ("HOME"); } #ifdef HAVE_GETPWUID if (!path) { struct passwd *pwd; pwd = getpwuid(getuid()); if (pwd) { path = pwd->pw_dir; } } #endif if (!path) { return NULL; } filename = safestrdup(CatString2(path, "/.fs-XXXXXX")); fd = fvwm_mkstemp(filename); if (fd == -1) { free (filename); filename = NULL; } else { close (fd); } return filename; } static char * GetWindowRole(Window window) { XTextProperty tp; if (XGetTextProperty (dpy, window, &tp, _XA_WM_WINDOW_ROLE)) { if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0) { return ((char *) tp.value); } } if (XGetTextProperty (dpy, window, &tp, _XA_WINDOW_ROLE)) { if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0) { return ((char *) tp.value); } } return NULL; } static char * GetClientID(FvwmWindow *fw) { char *client_id = NULL; Window client_leader = None; Window window; XTextProperty tp; Atom actual_type; int actual_format; unsigned long nitems; unsigned long bytes_after; unsigned char *prop = NULL; window = FW_W(fw); if (XGetWindowProperty( dpy, window, _XA_WM_CLIENT_LEADER, 0L, 1L, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success) { if (actual_type == XA_WINDOW && actual_format == 32 && nitems == 1 && bytes_after == 0) { client_leader = (Window)(*(long *)prop); } } if (!client_leader && fw->wmhints && (fw->wmhints->flags & WindowGroupHint)) { client_leader = fw->wmhints->window_group; } if (client_leader) { if ( XGetTextProperty( dpy, client_leader, &tp, _XA_SM_CLIENT_ID)) { if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0) { client_id = (char *) tp.value; } } } if (prop) { XFree (prop); } return client_id; } /* ** Verify the current fvwm version with the version that stroed the state file. ** No state will be restored if versions don't match. */ static Bool VerifyVersionInfo(char *filename) { FILE *f; char s[4096], s1[4096]; if (!filename || !*filename) { return False; } if ((f = fopen(filename, "r")) == NULL) { return False; } while (fgets(s, sizeof(s), f)) { sscanf(s, "%4000s", s1); if (!strcmp(s1, "[FVWM_VERSION]")) { char *current_v = get_version_string(); sscanf(s, "%*s %[^\n]", s1); if (strcmp(s1, current_v) == 0) { does_file_version_match = True; } else { fvwm_msg( ERR, "VerifyVersionInfo", "State file version (%s) does not" " match the current version (%s), " "state file is ignored.", s1, current_v); break; } } } fclose(f); return does_file_version_match; } static int SaveVersionInfo(FILE *f) { fprintf(f, "[FVWM_VERSION] %s\n", get_version_string()); return 1; } static int SaveWindowStates(FILE *f) { char *client_id; char *window_role; char **wm_command; int wm_command_count; FvwmWindow *ewin; rectangle save_g; rectangle ig; int i; int layer; for (ewin = get_next_window_in_stack_ring(&Scr.FvwmRoot); ewin != &Scr.FvwmRoot; ewin = get_next_window_in_stack_ring(ewin)) { Bool is_icon_sticky_across_pages; if (!XGetGeometry( dpy, FW_W(ewin), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { /* Don't save the state of windows that already died * (i.e. modules)! */ continue; } is_icon_sticky_across_pages = is_window_sticky_across_pages(ewin); wm_command = NULL; wm_command_count = 0; client_id = GetClientID(ewin); if (!client_id) { /* no client id, some session manager do not manage * such client ... this can cause problem */ if (XGetCommand( dpy, FW_W(ewin), &wm_command, &wm_command_count) && wm_command && wm_command_count > 0) { /* ok */ } else { /* No client id and no WM_COMMAND, the client * cannot be managed by the sessiom manager * skip it! */ /* TA: 20110611 - But actually, this breaks * those applications which don't set the * WM_COMMAND XAtom anymore. The ICCCM * deprecated this at version 2.0 -- and its * lack of existence here shouldn't be a * problem. Let newer session managers handle * the error if it even matters. */ if (!Restarting) { if (wm_command) { XFreeStringList(wm_command); wm_command = NULL; } /* TA: 20110611 - But see above. We * no longer skip clients who don't * set this legacy field. */ /* continue; */ } } } fprintf(f, "[CLIENT] %lx\n", FW_W(ewin)); if (client_id) { fprintf(f, " [CLIENT_ID] %s\n", client_id); XFree(client_id); } window_role = GetWindowRole(FW_W(ewin)); if (window_role) { fprintf(f, " [WINDOW_ROLE] %s\n", window_role); XFree(window_role); } if (client_id && window_role) { /* we have enough information */ } else { if (ewin->class.res_class) { fprintf(f, " [RES_NAME] %s\n", ewin->class.res_name); } if (ewin->class.res_name) { fprintf(f, " [RES_CLASS] %s\n", ewin->class.res_class); } if (ewin->name.name) { fprintf(f, " [WM_NAME] %s\n", ewin->name.name); } if (wm_command && wm_command_count > 0) { fprintf(f, " [WM_COMMAND] %i", wm_command_count); for (i = 0; i < wm_command_count; i++) { fprintf(f, " %s", unspace_string(wm_command[i])); } fprintf(f, "\n"); } } /* !window_role */ if (wm_command) { XFreeStringList(wm_command); wm_command = NULL; } gravity_get_naked_geometry( ewin->hints.win_gravity, ewin, &save_g, &ewin->g.normal); if (IS_STICKY_ACROSS_PAGES(ewin)) { save_g.x -= Scr.Vx; save_g.y -= Scr.Vy; } get_visible_icon_geometry(ewin, &ig); fprintf( f, " [GEOMETRY] %i %i %i %i %i %i %i %i %i %i %i %i" " %i %i %i\n", save_g.x, save_g.y, save_g.width, save_g.height, ewin->g.max.x, ewin->g.max.y, ewin->g.max.width, ewin->g.max.height, ewin->g.max_defect.width, ewin->g.max_defect.height, ig.x + ((!is_icon_sticky_across_pages) ? Scr.Vx : 0), ig.y + ((!is_icon_sticky_across_pages) ? Scr.Vy : 0), ewin->hints.win_gravity, ewin->g.max_offset.x, ewin->g.max_offset.y); fprintf(f, " [DESK] %i\n", ewin->Desk); /* set the layer to the default layer if the layer has been * set by an ewmh hint */ layer = get_layer(ewin); if (layer == ewin->ewmh_hint_layer && layer > 0) { layer = Scr.DefaultLayer; } fprintf(f, " [LAYER] %i %i\n", layer, ewin->default_layer); fprintf(f, " [PLACED_BY_BUTTON] %i\n", ewin->placed_by_button); fprintf(f, " [EWMH_DESKTOP] %lu\n", ewin->ewmh_hint_desktop); fprintf(f, " [FLAGS] "); for (i = 0; i < sizeof(window_flags); i++) { fprintf(f, "%02x ", (int)(((unsigned char *)&(ewin->flags))[i])); } fprintf(f, "\n"); } return 1; } /* This complicated logic is from twm, where it is explained */ static Bool matchWin(FvwmWindow *w, Match *m) { char *client_id = NULL; char *window_role = NULL; char **wm_command = NULL; int wm_command_count = 0, i; int found; found = 0; client_id = GetClientID(w); if (Restarting) { if (FW_W(w) == m->win) { found = 1; } } else if (xstreq(client_id, m->client_id)) { /* client_id's match */ window_role = GetWindowRole(FW_W(w)); if (client_id && (window_role || m->window_role)) { /* We have or had a window role, base decision on it */ found = xstreq(window_role, m->window_role); } else if (xstreq(w->class.res_name, m->res_name) && xstreq(w->class.res_class, m->res_class) && (IS_NAME_CHANGED(w) || IS_NAME_CHANGED(m) || xstreq(w->name.name, m->wm_name))) { if (client_id) { /* If we have a client_id, we don't * compare WM_COMMAND, since it will be * different. */ found = 1; } else { /* for non-SM-aware clients we also * compare WM_COMMAND */ if (!XGetCommand( dpy, FW_W(w), &wm_command, &wm_command_count)) { wm_command = NULL; wm_command_count = 0; } if (wm_command_count == m->wm_command_count) { for (i = 0; i < wm_command_count; i++) { if (strcmp(unspace_string( wm_command[i]), m->wm_command[i])!=0) { break; } } if (i == wm_command_count) { /* migo (21/Oct/1999): * on restarts compare * window ids too */ /* But if we restart we only need * to compare window ids * olicha (2005-01-06) */ found = 1; } } /* if (wm_command_count ==... */ } /* else if res_class, res_name and wm_name agree */ } /* else no window roles */ } /* if client_id's agree */ #ifdef FVWM_SM_DEBUG_WINMATCH fprintf(stderr, "\twin(%s, %s, %s, %s, %s,", w->class.res_name, w->class.res_class, w->name.name, (client_id)? client_id:"(null)", (window_role)? window_role:"(null)"); if (wm_command) { for (i = 0; i < wm_command_count; i++) { fprintf(stderr," %s", wm_command[i]); } fprintf(stderr,","); } else { fprintf(stderr," no_wmc,"); } fprintf(stderr," %d)", IS_NAME_CHANGED(w)); fprintf(stderr,"\n[%d]", found); fprintf(stderr, "\tmat(%s, %s, %s, %s, %s,", m->res_name, m->res_class, m->wm_name, (m->client_id)?m->client_id:"(null)", (m->window_role)?m->window_role:"(null)"); if (m->wm_command) { for (i = 0; i < m->wm_command_count; i++) { fprintf(stderr," %s", m->wm_command[i]); } fprintf(stderr,","); } else { fprintf(stderr," no_wmc,"); } fprintf(stderr," %d)\n\n", IS_NAME_CHANGED(m)); #endif if (client_id) { XFree(client_id); } if (window_role) { XFree(window_role); } if (wm_command) { XFreeStringList (wm_command); } return found; } static int save_state_file(char *filename) { FILE *f; int success; if (!filename || !*filename) { return 0; } if ((f = fopen(filename, "w")) == NULL) { return 0; } fprintf(f, "# This file is generated by fvwm." " It stores global and window states.\n"); fprintf(f, "# Normally, you must never delete this file," " it will be auto-deleted.\n\n"); if (SessionSupport && going_to_restart) { fprintf(f, "[REAL_STATE_FILENAME] %s\n", real_state_filename); going_to_restart = False; /* not needed */ } success = do_preserve_state ? SaveVersionInfo(f) && SaveWindowStates(f) && SaveGlobalState(f) : 1; do_preserve_state = True; if (fclose(f) != 0) return 0; #ifdef FVWM_SM_DEBUG_FILES system(CatString3( "mkdir -p /tmp/fs-save; cp ", filename, " /tmp/fs-save")); #endif #if defined(FVWM_SM_DEBUG_PROTO) || defined(FVWM_SM_DEBUG_FILES) fprintf(stderr, "[FVWM_SMDEBUG] Saving %s\n", filename); #endif return success; } static void set_sm_properties(FSmcConn sm_conn, char *filename, char hint) { FSmProp prop1, prop2, prop3, prop4, prop5, prop6, prop7, *props[7]; FSmPropValue prop1val, prop2val, prop3val, prop4val, prop7val; struct passwd *pwd; char *user_id; char screen_num[32]; int numVals, i, priority = 30; Bool is_xsm_detected = False; if (!SessionSupport) { return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][set_sm_properties] state filename: %s%s\n", filename ? filename : "(null)", sm_conn ? "" : " - not connected"); #endif if (!sm_conn) { return; } pwd = getpwuid (getuid()); user_id = pwd->pw_name; prop1.name = FSmProgram; prop1.type = FSmARRAY8; prop1.num_vals = 1; prop1.vals = &prop1val; prop1val.value = g_argv[0]; prop1val.length = strlen (g_argv[0]); prop2.name = FSmUserID; prop2.type = FSmARRAY8; prop2.num_vals = 1; prop2.vals = &prop2val; prop2val.value = (FSmPointer) user_id; prop2val.length = strlen (user_id); prop3.name = FSmRestartStyleHint; prop3.type = FSmCARD8; prop3.num_vals = 1; prop3.vals = &prop3val; prop3val.value = (FSmPointer) &hint; prop3val.length = 1; prop4.name = "_GSM_Priority"; prop4.type = FSmCARD8; prop4.num_vals = 1; prop4.vals = &prop4val; prop4val.value = (FSmPointer) &priority; prop4val.length = 1; sprintf(screen_num, "%d", (int)Scr.screen); prop5.name = FSmCloneCommand; prop5.type = FSmLISTofARRAY8; prop5.vals = (FSmPropValue *)malloc((g_argc + 2) * sizeof (FSmPropValue)); numVals = 0; for (i = 0; i < g_argc; i++) { if (strcmp (g_argv[i], "-clientId") == 0 || strcmp (g_argv[i], "-restore") == 0 || strcmp (g_argv[i], "-d") == 0 || (strcmp (g_argv[i], "-s") == 0 && i+1 < g_argc && g_argv[i+1][0] != '-')) { i++; } else if (strcmp (g_argv[i], "-s") != 0) { prop5.vals[numVals].value = (FSmPointer) g_argv[i]; prop5.vals[numVals++].length = strlen (g_argv[i]); } } prop5.vals[numVals].value = (FSmPointer) "-s"; prop5.vals[numVals++].length = 2; prop5.vals[numVals].value = (FSmPointer) screen_num; prop5.vals[numVals++].length = strlen (screen_num); prop5.num_vals = numVals; if (filename) { prop6.name = FSmRestartCommand; prop6.type = FSmLISTofARRAY8; prop6.vals = (FSmPropValue *)malloc( (g_argc + 6) * sizeof (FSmPropValue)); numVals = 0; for (i = 0; i < g_argc; i++) { if (strcmp (g_argv[i], "-clientId") == 0 || strcmp (g_argv[i], "-restore") == 0 || strcmp (g_argv[i], "-d") == 0 || (strcmp (g_argv[i], "-s") == 0 && i+1 < g_argc && g_argv[i+1][0] != '-')) { i++; } else if (strcmp (g_argv[i], "-s") != 0) { prop6.vals[numVals].value = (FSmPointer) g_argv[i]; prop6.vals[numVals++].length = strlen (g_argv[i]); } } prop6.vals[numVals].value = (FSmPointer) "-s"; prop6.vals[numVals++].length = 2; prop6.vals[numVals].value = (FSmPointer) screen_num; prop6.vals[numVals++].length = strlen (screen_num); prop6.vals[numVals].value = (FSmPointer) "-clientId"; prop6.vals[numVals++].length = 9; prop6.vals[numVals].value = (FSmPointer) sm_client_id; prop6.vals[numVals++].length = strlen (sm_client_id); prop6.vals[numVals].value = (FSmPointer) "-restore"; prop6.vals[numVals++].length = 8; prop6.vals[numVals].value = (FSmPointer) filename; prop6.vals[numVals++].length = strlen (filename); prop6.num_vals = numVals; prop7.name = FSmDiscardCommand; is_xsm_detected = StrEquals(getenv("SESSION_MANAGER_NAME"), "xsm"); if (is_xsm_detected) { /* the protocol spec says that the discard command should be LISTofARRAY8 on posix systems, but xsm demands that it be ARRAY8. */ char *discardCommand = alloca( (10 + strlen(filename)) * sizeof(char)); sprintf (discardCommand, "rm -f '%s'", filename); prop7.type = FSmARRAY8; prop7.num_vals = 1; prop7.vals = &prop7val; prop7val.value = (FSmPointer) discardCommand; prop7val.length = strlen (discardCommand); } else { prop7.type = FSmLISTofARRAY8; prop7.num_vals = 3; prop7.vals = (FSmPropValue *) malloc ( 3 * sizeof (FSmPropValue)); prop7.vals[0].value = "rm"; prop7.vals[0].length = 2; prop7.vals[1].value = "-f"; prop7.vals[1].length = 2; prop7.vals[2].value = filename; prop7.vals[2].length = strlen (filename); } } props[0] = &prop1; props[1] = &prop2; props[2] = &prop3; props[3] = &prop4; props[4] = &prop5; SUPPRESS_UNUSED_VAR_WARNING(props); if (filename) { props[5] = &prop6; props[6] = &prop7; FSmcSetProperties (sm_conn, 7, props); free ((char *) prop6.vals); if (!is_xsm_detected) { free ((char *) prop7.vals); } } else { FSmcSetProperties (sm_conn, 5, props); } free ((char *) prop5.vals); } static void callback_save_yourself2(FSmcConn sm_conn, FSmPointer client_data) { Bool success = 0; char *filename; if (!SessionSupport) { return; } filename = get_unique_state_filename(); #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_save_yourself2]\n"); #endif success = save_state_file(filename); if (success) { set_sm_properties(sm_conn, filename, FSmRestartIfRunning); set_real_state_filename(filename); } free(filename); FSmcSaveYourselfDone (sm_conn, success); sent_save_done = 1; } static void callback_save_yourself(FSmcConn sm_conn, FSmPointer client_data, int save_style, Bool shutdown, int interact_style, Bool fast) { if (!SessionSupport) { return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_save_yourself] " "(save=%d, shut=%d, intr=%d, fast=%d)\n", save_style, shutdown, interact_style, fast); #endif if (save_style == FSmSaveGlobal) { /* nothing to do */ #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_save_yourself] " "Global Save type ... do nothing\n"); #endif FSmcSaveYourselfDone (sm_conn, True); sent_save_done = 1; return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_save_yourself] " "Both or Local save type, going to phase 2 ..."); #endif if (!FSmcRequestSaveYourselfPhase2( sm_conn, callback_save_yourself2, NULL)) { FSmcSaveYourselfDone (sm_conn, False); sent_save_done = 1; #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, " failed!\n"); #endif } else { #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, " OK\n"); #endif sent_save_done = 0; } return; } static void callback_die(FSmcConn sm_conn, FSmPointer client_data) { if (!SessionSupport) { return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_die]\n"); #endif if (FSmcCloseConnection(sm_conn, 0, NULL) != FSmcClosedNow) { /* go a head any way ? */ } sm_fd = -1; if (master_pid != getpid()) { kill(master_pid, SIGTERM); } Done(0, NULL); } static void callback_save_complete(FSmcConn sm_conn, FSmPointer client_data) { if (!SessionSupport) { return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_save_complete]\n"); #endif return; } static void callback_shutdown_cancelled(FSmcConn sm_conn, FSmPointer client_data) { if (!SessionSupport) { return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG][callback_shutdown_cancelled]\n"); #endif if (!sent_save_done) { FSmcSaveYourselfDone(sm_conn, False); sent_save_done = 1; } return; } /* the following is taken from xsm */ static void MyIoErrorHandler(FIceConn ice_conn) { if (!SessionSupport) { return; } if (prev_handler) { (*prev_handler) (ice_conn); } return; } static void InstallIOErrorHandler(void) { FIceIOErrorHandler default_handler; if (!SessionSupport) { return; } prev_handler = FIceSetIOErrorHandler (NULL); default_handler = FIceSetIOErrorHandler (MyIoErrorHandler); if (prev_handler == default_handler) { prev_handler = NULL; } return; } /* ---------------------------- interface functions ------------------------ */ void LoadGlobalState(char *filename) { FILE *f; char s[4096], s1[4096]; /* char s2[256]; */ char *is_key = NULL, *is_value = NULL; int n, i1, i2, i3, i4; if (!does_file_version_match) { return; } if (!filename || !*filename) { return; } if ((f = fopen(filename, "r")) == NULL) { return; } while (fgets(s, sizeof(s), f)) { n = 0; i1 = 0; i2 = 0; i3 = 0; i4 = 0; sscanf(s, "%4000s%n", s1, &n); /* If we are restarting, [REAL_STATE_FILENAME] points * to the file containing the true session state. */ if (SessionSupport && !strcmp(s1, "[REAL_STATE_FILENAME]")) { /* migo: temporarily (?) moved to LoadWindowStates (trick for gnome-session) sscanf(s, "%*s %s", s2); set_sm_properties(sm_conn, s2, FSmRestartIfRunning); set_real_state_filename(s2); */ } else if (!strcmp(s1, "[DESKTOP]")) { sscanf(s, "%*s %i", &i1); goto_desk(i1); } else if (!strcmp(s1, "[VIEWPORT]")) { sscanf(s, "%*s %i %i %i %i", &i1, &i2, &i3, &i4); /* migo: we don't want to lose DeskTopSize in * configurations, and it does not work well * anyways - Gnome is not updated Scr.VxMax = i3; Scr.VyMax = i4; */ MoveViewport(i1, i2, True); } else if (!strcmp(s1, "[KEY]")) { char *s2; s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); is_key = safestrdup(s1); } else if (!strcmp(s1, "[VALUE]")) { char *s2; s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); is_value = safestrdup(s1); fprintf(stderr, "GOT: %s -> %s\n", is_key, is_value); if (is_key != NULL && is_value != NULL) { fprintf(stderr, "INSERTING: %s -> %s\n", is_key, is_value); insert_metainfo(is_key, is_value); } free(is_key); free(is_value); is_key = is_value = NULL; } #if 0 /* migo (08-Dec-1999): we don't want to eliminate config yet */ else if (/*!Restarting*/ 0) { /* Matthias: We don't want to restore too much * state if we are restarting, since that * would make restarting useless for rereading * changed rc files. */ if (!strcmp(s1, "[SCROLL]")) { sscanf(s, "%*s %i %i %i %i ", &i1, &i2, &i3, &i4); Scr.EdgeScrollX = i1; Scr.EdgeScrollY = i2; Scr.ScrollDelay = i3; if (i4) { Scr.flags.edge_wrap_x = 1; } else { Scr.flags.edge_wrap_x = 0; } if (i3) { Scr.flags.edge_wrap_y = 1; } else { Scr.flags.edge_wrap_y = 0; } } else if (!strcmp(s1, "[MISC]")) { sscanf(s, "%*s %i %i %i", &i1, &i2, &i3); Scr.ClickTime = i1; Scr.ColormapFocus = i2; Scr.ColorLimit = i3; } else if (!strcmp(s1, "[STYLE]")) { sscanf(s, "%*s %i %i", &i1, &i2); Scr.gs.EmulateMWM = i1; Scr.gs.EmulateWIN = i2; } } #endif } fclose(f); return; } void DisableRestoringState(void) { num_match = 0; return; } void LoadWindowStates(char *filename) { FILE *f; char s[4096], s1[4096]; char *s2; int i, pos, pos1; unsigned long w; int n; if (!VerifyVersionInfo(filename)) { return; } if (!filename || !*filename) { return; } set_real_state_filename(filename); if ((f = fopen(filename, "r")) == NULL) { return; } #if defined(FVWM_SM_DEBUG_PROTO) || defined(FVWM_SM_DEBUG_FILES) fprintf(stderr, "[FVWM_SMDEBUG] Loading %s\n", filename); #endif #ifdef FVWM_SM_DEBUG_FILES system(CatString3( "mkdir -p /tmp/fs-load; cp ", filename, " /tmp/fs-load")); #endif while (fgets(s, sizeof(s), f)) { n = 0; sscanf(s, "%4000s%n", s1, &n); if (!SessionSupport /* migo: temporarily */ && !strcmp(s1, "[REAL_STATE_FILENAME]")) { sscanf(s, "%*s %s", s1); set_sm_properties(sm_conn, s1, FSmRestartIfRunning); set_real_state_filename(s1); } else if (!strcmp(s1, "[CLIENT]")) { sscanf(s, "%*s %lx", &w); num_match++; matches = (Match *)saferealloc( (void *)matches, sizeof(Match) * num_match); matches[num_match - 1].win = w; matches[num_match - 1].client_id = NULL; matches[num_match - 1].res_name = NULL; matches[num_match - 1].res_class = NULL; matches[num_match - 1].window_role = NULL; matches[num_match - 1].wm_name = NULL; matches[num_match - 1].wm_command_count = 0; matches[num_match - 1].wm_command = NULL; matches[num_match - 1].x = 0; matches[num_match - 1].y = 0; matches[num_match - 1].w = 100; matches[num_match - 1].h = 100; matches[num_match - 1].x_max = 0; matches[num_match - 1].y_max = 0; matches[num_match - 1].w_max = Scr.MyDisplayWidth; matches[num_match - 1].h_max = Scr.MyDisplayHeight; matches[num_match - 1].width_defect_max = 0; matches[num_match - 1].height_defect_max = 0; matches[num_match - 1].icon_x = 0; matches[num_match - 1].icon_y = 0; matches[num_match - 1].desktop = 0; matches[num_match - 1].layer = 0; matches[num_match - 1].default_layer = 0; memset(&(matches[num_match - 1].flags), 0, sizeof(window_flags)); matches[num_match - 1].used = 0; } else if (!strcmp(s1, "[GEOMETRY]")) { sscanf(s, "%*s %i %i %i %i %i %i %i %i %i %i %i %i" " %i %i %i", &(matches[num_match - 1].x), &(matches[num_match - 1].y), &(matches[num_match - 1].w), &(matches[num_match - 1].h), &(matches[num_match - 1].x_max), &(matches[num_match - 1].y_max), &(matches[num_match - 1].w_max), &(matches[num_match - 1].h_max), &(matches[num_match - 1].width_defect_max), &(matches[num_match - 1].height_defect_max), &(matches[num_match - 1].icon_x), &(matches[num_match - 1].icon_y), &(matches[num_match - 1].gravity), &(matches[num_match - 1].max_x_offset), &(matches[num_match - 1].max_y_offset)); } else if (!strcmp(s1, "[DESK]")) { sscanf(s, "%*s %i", &(matches[num_match - 1].desktop)); } else if (!strcmp(s1, "[LAYER]")) { sscanf(s, "%*s %i %i", &(matches[num_match - 1].layer), &(matches[num_match - 1].default_layer)); } else if (!strcmp(s1, "[PLACED_BY_BUTTON]")) { sscanf(s, "%*s %i", &(matches[num_match - 1].placed_by_button)); } else if (!strcmp(s1, "[EWMH_DESKTOP]")) { sscanf(s, "%*s %lu", &(matches[num_match - 1].ewmh_hint_desktop)); } else if (!strcmp(s1, "[FLAGS]")) { char *ts = s; /* skip [FLAGS] */ while (*ts != ']') { ts++; } ts++; for (i = 0; i < sizeof(window_flags); i++) { unsigned int f; sscanf(ts, "%02x ", &f); ((unsigned char *)& (matches[num_match-1].flags))[i] = f; ts += 3; } } else if (!strcmp(s1, "[CLIENT_ID]")) { s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); matches[num_match - 1].client_id = duplicate(s1); } else if (!strcmp(s1, "[WINDOW_ROLE]")) { s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); matches[num_match - 1].window_role = duplicate(s1); } else if (!strcmp(s1, "[RES_NAME]")) { s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); matches[num_match - 1].res_name = duplicate(s1); } else if (!strcmp(s1, "[RES_CLASS]")) { s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); matches[num_match - 1].res_class = duplicate(s1); } else if (!strcmp(s1, "[WM_NAME]")) { s2 = s + n; if (*s2 != 0) { s2++; } sscanf(s2, "%[^\n]", s1); matches[num_match - 1].wm_name = duplicate(s1); } else if (!strcmp(s1, "[WM_COMMAND]")) { sscanf(s, "%*s %i%n", &matches[num_match - 1].wm_command_count, &pos); matches[num_match - 1].wm_command = (char **) safemalloc( matches[num_match - 1]. wm_command_count * sizeof (char *)); for (i = 0; i < matches[num_match - 1].wm_command_count; i++) { sscanf (s+pos, "%s%n", s1, &pos1); pos += pos1; matches[num_match - 1].wm_command[i] = duplicate (s1); } } } fclose(f); return; } /* This routine (potentially) changes the flags STARTICONIC, MAXIMIZED, WSHADE and STICKY and the Desk and attr.x, .y, .width, .height entries. It also changes the stack_before pointer to return information about the desired stacking order. It expects the stacking order to be set up correctly beforehand! */ Bool MatchWinToSM( FvwmWindow *ewin, mwtsm_state_args *ret_state_args, initial_window_options_t *win_opts) { int i; if (!does_file_version_match) { return False; } for (i = 0; i < num_match; i++) { if (!matches[i].used && matchWin(ewin, &matches[i])) { matches[i].used = 1; if (!Restarting) { /* We don't want to restore too much state if we are restarting, since that would make * restarting useless for rereading changed * rc files. */ SET_DO_SKIP_WINDOW_LIST( ewin, DO_SKIP_WINDOW_LIST(&(matches[i]))); SET_ICON_SUPPRESSED( ewin, IS_ICON_SUPPRESSED(&(matches[i]))); SET_HAS_NO_ICON_TITLE( ewin, HAS_NO_ICON_TITLE(&(matches[i]))); FPS_LENIENT( FW_FOCUS_POLICY(ewin), FP_IS_LENIENT(FW_FOCUS_POLICY( &(matches[i])))); SET_ICON_STICKY_ACROSS_PAGES( ewin, IS_ICON_STICKY_ACROSS_PAGES( &(matches[i]))); SET_ICON_STICKY_ACROSS_DESKS( ewin, IS_ICON_STICKY_ACROSS_DESKS( &(matches[i]))); SET_DO_SKIP_ICON_CIRCULATE( ewin, DO_SKIP_ICON_CIRCULATE( &(matches[i]))); SET_DO_SKIP_SHADED_CIRCULATE( ewin, DO_SKIP_SHADED_CIRCULATE( &(matches[i]))); SET_DO_SKIP_CIRCULATE( ewin, DO_SKIP_CIRCULATE(&(matches[i]))); memcpy( &FW_FOCUS_POLICY(ewin), &FW_FOCUS_POLICY(&matches[i]), sizeof(focus_policy_t)); if (matches[i].wm_name) { free_window_names(ewin, True, False); ewin->name.name = matches[i].wm_name; setup_visible_name(ewin, False); } } SET_NAME_CHANGED(ewin,IS_NAME_CHANGED(&(matches[i]))); SET_PLACED_BY_FVWM( ewin, IS_PLACED_BY_FVWM(&(matches[i]))); ret_state_args->do_shade = IS_SHADED(&(matches[i])); ret_state_args->used_title_dir_for_shading = USED_TITLE_DIR_FOR_SHADING(&(matches[i])); ret_state_args->shade_dir = SHADED_DIR(&(matches[i])); ret_state_args->do_max = IS_MAXIMIZED(&(matches[i])); SET_USER_STATES(ewin, GET_USER_STATES(&(matches[i]))); SET_ICON_MOVED(ewin, IS_ICON_MOVED(&(matches[i]))); if (IS_ICONIFIED(&(matches[i]))) { /* ICON_MOVED is necessary to make fvwm use icon_[xy]_loc for icon placement */ win_opts->initial_state = IconicState; win_opts->flags.use_initial_icon_xy = 1; win_opts->initial_icon_x = matches[i].icon_x; win_opts->initial_icon_y = matches[i].icon_y; if (!IS_STICKY_ACROSS_PAGES(&(matches[i])) && !(IS_ICONIFIED(&(matches[i])) && IS_ICON_STICKY_ACROSS_PAGES( &(matches[i])))) { win_opts->initial_icon_x -= Scr.Vx; win_opts->initial_icon_y -= Scr.Vy; } } ewin->g.normal.x = matches[i].x; ewin->g.normal.y = matches[i].y; ewin->g.normal.width = matches[i].w; ewin->g.normal.height = matches[i].h; ewin->g.max.x = matches[i].x_max; ewin->g.max.y = matches[i].y_max; ewin->g.max.width = matches[i].w_max; ewin->g.max.height = matches[i].h_max; ewin->g.max_defect.width = matches[i].width_defect_max; ewin->g.max_defect.height = matches[i].height_defect_max; ewin->g.max_offset.x = matches[i].max_x_offset; ewin->g.max_offset.y = matches[i].max_y_offset; SET_STICKY_ACROSS_PAGES( ewin, IS_STICKY_ACROSS_PAGES(&(matches[i]))); SET_STICKY_ACROSS_DESKS( ewin, IS_STICKY_ACROSS_DESKS(&(matches[i]))); ewin->Desk = (IS_STICKY_ACROSS_DESKS(ewin)) ? Scr.CurrentDesk : matches[i].desktop; set_layer(ewin, matches[i].layer); set_default_layer(ewin, matches[i].default_layer); ewin->placed_by_button = matches[i].placed_by_button; /* Note: the Modal, skip pager, skip taskbar and * "stacking order" state are not restored here: there * are restored in EWMH_ExitStuff */ ewin->ewmh_hint_desktop = matches[i].ewmh_hint_desktop; SET_HAS_EWMH_INIT_WM_DESKTOP( ewin, HAS_EWMH_INIT_WM_DESKTOP(&(matches[i]))); SET_HAS_EWMH_INIT_HIDDEN_STATE( ewin, HAS_EWMH_INIT_HIDDEN_STATE( &(matches[i]))); SET_HAS_EWMH_INIT_MAXHORIZ_STATE( ewin, HAS_EWMH_INIT_MAXHORIZ_STATE( &(matches[i]))); SET_HAS_EWMH_INIT_MAXVERT_STATE( ewin, HAS_EWMH_INIT_MAXVERT_STATE( &(matches[i]))); SET_HAS_EWMH_INIT_SHADED_STATE( ewin, HAS_EWMH_INIT_SHADED_STATE( &(matches[i]))); SET_HAS_EWMH_INIT_STICKY_STATE( ewin, HAS_EWMH_INIT_STICKY_STATE( &(matches[i]))); return True; } } return False; } void RestartInSession (char *filename, Bool is_native, Bool _do_preserve_state) { do_preserve_state = _do_preserve_state; if (SessionSupport && sm_conn && is_native) { going_to_restart = True; save_state_file(filename); set_sm_properties(sm_conn, filename, FSmRestartImmediately); MoveViewport(0, 0, False); Reborder(); CloseICCCM2(); XCloseDisplay(dpy); if ((!FSmcCloseConnection(sm_conn, 0, NULL)) != FSmcClosedNow) { /* go a head any way ? */ } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr, "[FVWM_SMDEBUG]: Exiting, now SM must " "restart us.\n"); #endif /* Close all my pipes */ module_kill_all(); exit(0); /* let the SM restart us */ } save_state_file(filename); /* return and let Done restart us */ return; } void SetClientID(char *client_id) { if (!SessionSupport) { return; } previous_sm_client_id = client_id; return; } void SessionInit(void) { char error_string_ret[4096] = ""; FSmPointer context; FSmcCallbacks callbacks; if (!SessionSupport) { /* -Wall fixes */ MyIoErrorHandler(NULL); callback_save_yourself2(NULL, NULL); return; } InstallIOErrorHandler(); callbacks.save_yourself.callback = callback_save_yourself; callbacks.die.callback = callback_die; callbacks.save_complete.callback = callback_save_complete; callbacks.shutdown_cancelled.callback = callback_shutdown_cancelled; callbacks.save_yourself.client_data = callbacks.die.client_data = callbacks.save_complete.client_data = callbacks.shutdown_cancelled.client_data = (FSmPointer) NULL; SUPPRESS_UNUSED_VAR_WARNING(context); sm_conn = FSmcOpenConnection( NULL, &context, FSmProtoMajor, FSmProtoMinor, FSmcSaveYourselfProcMask | FSmcDieProcMask | FSmcSaveCompleteProcMask | FSmcShutdownCancelledProcMask, &callbacks, previous_sm_client_id, &sm_client_id, 4096, error_string_ret); if (!sm_conn) { /* Don't annoy users which don't use a session manager */ if (previous_sm_client_id) { fvwm_msg( ERR, "SessionInit", "While connecting to session manager:\n%s.", error_string_ret); } sm_fd = -1; #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr,"[FVWM_SMDEBUG] No SM connection\n"); #endif } else { sm_fd = FIceConnectionNumber(FSmcGetIceConnection(sm_conn)); #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr,"[FVWM_SMDEBUG] Connectecd to a SM\n"); #endif set_init_function_name(0, "SessionInitFunction"); set_init_function_name(1, "SessionRestartFunction"); set_init_function_name(2, "SessionExitFunction"); /* basically to restet our restart style hint after a * restart */ set_sm_properties(sm_conn, NULL, FSmRestartIfRunning); } return; } void ProcessICEMsgs(void) { FIceProcessMessagesStatus status; if (!SessionSupport) { return; } #ifdef FVWM_SM_DEBUG_PROTO fprintf(stderr,"[FVWM_SMDEBUG][ProcessICEMsgs] %i\n", (int)sm_fd); #endif if (sm_fd < 0) { return; } status = FIceProcessMessages(FSmcGetIceConnection(sm_conn), NULL, NULL); if (status == FIceProcessMessagesIOError) { fvwm_msg(ERR, "ProcessICEMSGS", "Connection to session manager lost\n"); sm_conn = NULL; sm_fd = -1; } return; } /* * Fvwm Function implementation: QuitSession, SaveSession, SaveQuitSession. * migo (15-Jun-1999): I am not sure this is right. * The session mabager must implement SmsSaveYourselfRequest (xsm doesn't?). * Alternative implementation may use unix signals, but this does not work * with all session managers (also must suppose that SM runs locally). */ int get_sm_pid(void) { const char *session_manager_var = getenv("SESSION_MANAGER"); const char *sm_pid_str_ptr; int sm_pid = 0; if (!SessionSupport) { return 0; } if (!session_manager_var) { return 0; } sm_pid_str_ptr = strchr(session_manager_var, ','); if (!sm_pid_str_ptr) { return 0; } while (sm_pid_str_ptr > session_manager_var && isdigit(*(--sm_pid_str_ptr))) { /* nothing */ } while (isdigit(*(++sm_pid_str_ptr))) { sm_pid = sm_pid * 10 + *sm_pid_str_ptr - '0'; } return sm_pid; } /* * quit_session - hopefully shutdowns the session */ Bool quit_session(void) { if (!SessionSupport) { return False; } if (!sm_conn) { return False; } FSmcRequestSaveYourself( sm_conn, FSmSaveLocal, True /* shutdown */, FSmInteractStyleAny, False /* fast */, True /* global */); return True; /* migo: xsm does not support RequestSaveYourself, but supports * signals: */ /* int sm_pid = get_sm_pid(); if (!sm_pid) return False; return kill(sm_pid, SIGTERM) == 0 ? True : False; */ } /* * save_session - hopefully saves the session */ Bool save_session(void) { if (!SessionSupport) { return False; } if (!sm_conn) { return False; } FSmcRequestSaveYourself( sm_conn, FSmSaveBoth, False /* shutdown */, FSmInteractStyleAny, False /* fast */, True /* global */); return True; /* migo: xsm does not support RequestSaveYourself, but supports * signals: */ /* int sm_pid = get_sm_pid(); if (!sm_pid) return False; return kill(sm_pid, SIGUSR1) == 0 ? True : False; */ } /* * save_quit_session - hopefully saves and shutdowns the session */ Bool save_quit_session(void) { if (!SessionSupport) { return False; } if (!sm_conn) { return False; } FSmcRequestSaveYourself( sm_conn, FSmSaveBoth, True /* shutdown */, FSmInteractStyleAny, False /* fast */, True /* global */); return True; /* migo: xsm does not support RequestSaveYourself, but supports * signals: */ /* if (save_session() == False) return False; sleep(3); / * doesn't work anyway * / if (quit_session() == False) return False; return True; */ } /* ---------------------------- builtin commands --------------------------- */ void CMD_QuitSession(F_CMD_ARGS) { quit_session(); return; } void CMD_SaveSession(F_CMD_ARGS) { save_session(); return; } void CMD_SaveQuitSession(F_CMD_ARGS) { save_quit_session(); return; } fvwm-2.6.7/fvwm/icons.c0000644000175700017570000020663013006057357011717 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is mostly all new * by Rob Nation * A little of it is borrowed from ctwm. * Copyright 1993 Robert Nation. No restrictions are placed on this code, * as long as the copyright notice is preserved */ /* * * fvwm icon code * */ #include "config.h" #include #ifdef HAVE_FCNTL_H #include #endif #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/FShape.h" #include "libs/Parse.h" #include "libs/Picture.h" #include "libs/Graphics.h" #include "libs/PictureGraphics.h" #include "libs/FRenderInit.h" #include "libs/Rectangles.c" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "execcontext.h" #include "commands.h" #include "bindings.h" #include "events.h" #include "eventmask.h" #include "eventhandler.h" #include "misc.h" #include "screen.h" #include "icons.h" #include "borders.h" #include "frame.h" #include "focus.h" #include "colormaps.h" #include "stack.h" #include "virtual.h" #include "decorations.h" #include "module_interface.h" #include "ewmh.h" #include "geometry.h" static int do_all_iconboxes(FvwmWindow *t, icon_boxes **icon_boxes_ptr); static void GetIconFromFile(FvwmWindow *fw); static void GetIconWindow(FvwmWindow *fw); static void GetIconBitmap(FvwmWindow *fw); static void clear_icon_dimensions(FvwmWindow *fw) { int px; int py; int tx; int ty; px = fw->icon_g.picture_w_g.x; py = fw->icon_g.picture_w_g.y; tx = fw->icon_g.title_w_g.x; ty = fw->icon_g.title_w_g.y; memset(&fw->icon_g, 0, sizeof(fw->icon_g)); fw->icon_g.picture_w_g.x = px; fw->icon_g.picture_w_g.y = py; fw->icon_g.title_w_g.x = tx; fw->icon_g.title_w_g.y = ty; return; } /* erase all traces of the last used icon in the window structure */ void clear_icon(FvwmWindow *fw) { FW_W_ICON_PIXMAP(fw) = None; fw->iconPixmap = None; fw->icon_maskPixmap = None; fw->icon_alphaPixmap = None; fw->icon_nalloc_pixels = 0; fw->icon_alloc_pixels = NULL; fw->icon_no_limit = 0; if (IS_ICON_MOVED(fw)) { clear_icon_dimensions(fw); } else { memset(&fw->icon_g, 0, sizeof(fw->icon_g)); } return; } int get_visible_icon_window_count(FvwmWindow *fw) { int count = 0; if (fw == NULL || !IS_ICONIFIED(fw) || IS_ICON_SUPPRESSED(fw)) { return 0; } if (FW_W_ICON_PIXMAP(fw) != None) { count++; } if (FW_W_ICON_TITLE(fw) != None) { count++; } return count; } void setup_icon_title_size(FvwmWindow *fw) { if (HAS_NO_ICON_TITLE(fw)) { fw->icon_g.title_text_width = 0; fw->icon_g.title_w_g.width = 0; fw->icon_g.title_w_g.height = 0; } else { fw->icon_g.title_text_width = FlocaleTextWidth( fw->icon_font, fw->visible_icon_name, strlen(fw->visible_icon_name)); fw->icon_g.title_w_g.height = ICON_HEIGHT(fw); if (fw->icon_g.picture_w_g.width == 0) { fw->icon_g.title_w_g.width = fw->icon_g.title_text_width + 2 * (ICON_TITLE_TEXT_GAP_COLLAPSED + abs(fw->icon_title_relief)); if (IS_STICKY_ACROSS_PAGES(fw) || IS_ICON_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw) || IS_ICON_STICKY_ACROSS_DESKS(fw)) { fw->icon_g.title_w_g.width += 2 * (ICON_TITLE_TO_STICK_EXTRA_GAP + ICON_TITLE_STICK_MIN_WIDTH); } } else { fw->icon_g.title_w_g.width = fw->icon_g.picture_w_g.width; } } return; } /* * * Resizes the given icon Pixmap. * */ static void SetIconPixmapSize( Pixmap *icon, int width, int height, int depth, int newWidth, int newHeight, Bool force_centering, int resize_type, int *nrx, int *nry, int freeOldPixmap) { Pixmap oldPixmap; Pixmap resizedPixmap = None; int r_w,r_h; GC gc; XGCValues gc_init; *nrx = 0; *nry = 0; /* Check for invalid dimensions */ if (newWidth == 0 || newHeight == 0) { return; } /* Save the existing Pixmap */ oldPixmap = *icon; gc = XCreateGC(dpy, oldPixmap, 0, &gc_init); switch(resize_type) { case ICON_RESIZE_TYPE_ADJUSTED: if (newWidth != width || newHeight != height) { *icon = CreateStretchPixmap( dpy, oldPixmap, width, height, depth, newWidth, newHeight, gc); } break; case ICON_RESIZE_TYPE_STRETCHED: if (width < newWidth || height < newHeight) { r_w = max(newWidth, width); r_h = max(newHeight, height); resizedPixmap = CreateStretchPixmap( dpy, oldPixmap, width, height, depth, r_w, r_h, gc); width = r_w; height = r_h; } break; case ICON_RESIZE_TYPE_SHRUNK: if (width > newWidth || height > newHeight) { r_w = min(newWidth, width); r_h = min(newHeight, height); resizedPixmap = CreateStretchPixmap( dpy, oldPixmap, width, height, depth, r_w, r_h, gc); width = r_w; height = r_h; } break; default: break; } if (resize_type != ICON_RESIZE_TYPE_ADJUSTED) { *icon = XCreatePixmap( dpy, oldPixmap, newWidth, newHeight, depth); XSetForeground(dpy, gc, 0); XFillRectangle(dpy, *icon, gc, 0, 0, newWidth, newHeight); /* * Copy old Pixmap onto new. Center horizontally. Center * vertically if the new height is smaller than the old. * Otherwise, place the icon on the bottom, along the title bar. */ *nrx = (newWidth - width) / 2; *nry = (newHeight > height && !force_centering) ? newHeight - height : (newHeight - height) / 2; XCopyArea( dpy, (resizedPixmap)? resizedPixmap:oldPixmap, *icon, gc, 0, 0, width, height, *nrx, *nry); } XFreeGC(dpy, gc); if (freeOldPixmap) { XFreePixmap(dpy, oldPixmap); } } /* Move the icon of a window by dx/dy pixels */ /* * * Get the Icon for the icon window (also used by ewmh_icon) * */ void GetIconPicture(FvwmWindow *fw, Bool no_icon_window) { char icon_order[4]; int i; /* First, see if it was specified in the .fvwmrc */ if (ICON_OVERRIDE_MODE(fw) == ICON_OVERRIDE) { /* try fvwm provided icons before application provided icons */ icon_order[0] = 0; icon_order[1] = 1; icon_order[2] = 2; icon_order[3] = 3; ICON_DBG((stderr,"ciw: hint order: file iwh iph '%s'\n", fw->name.name)); } else if (ICON_OVERRIDE_MODE(fw) == NO_ACTIVE_ICON_OVERRIDE) { if (fw->wmhints && (fw->wmhints->flags & IconPixmapHint) && WAS_ICON_HINT_PROVIDED(fw) == ICON_HINT_MULTIPLE) { /* use application provided icon window or pixmap * first, then fvwm provided icons. */ icon_order[0] = 1; icon_order[1] = 2; icon_order[2] = 3; icon_order[3] = 0; ICON_DBG((stderr,"ciw: hint order: iwh iph file '%s'\n", fw->name.name)); } else if (Scr.DefaultIcon && fw->icon_bitmap_file == Scr.DefaultIcon) { /* use application provided icon window/pixmap first, * then fvwm provided default icon */ icon_order[0] = 1; icon_order[1] = 2; icon_order[2] = 3; icon_order[3] = 0; ICON_DBG((stderr,"ciw: hint order: iwh iph file '%s'\n", fw->name.name)); } else { /* use application provided icon window or ewmh icon * first, then fvwm provided icons and then application * provided icon pixmap */ icon_order[0] = 1; icon_order[1] = 2; icon_order[2] = 0; icon_order[3] = 3; ICON_DBG((stderr,"ciw: hint order: iwh file iph '%s'\n", fw->name.name)); } } else { /* use application provided icon rather than fvwm provided * icon */ icon_order[0] = 1; icon_order[1] = 2; icon_order[2] = 3; icon_order[3] = 0; ICON_DBG((stderr,"ciw: hint order: iwh iph file '%s'\n", fw->name.name)); } fw->icon_g.picture_w_g.width = 0; fw->icon_g.picture_w_g.height = 0; fw->iconPixmap = None; fw->icon_maskPixmap = None; fw->icon_alphaPixmap= None; FW_W_ICON_PIXMAP(fw) = None; for (i = 0; i < 4 && fw->icon_g.picture_w_g.width == 0 && fw->icon_g.picture_w_g.height == 0; i++) { switch (icon_order[i]) { case 0: /* Next, check for a color pixmap */ if (fw->icon_bitmap_file) { GetIconFromFile(fw); } ICON_DBG((stderr,"ciw: file%s used '%s'\n", (fw->icon_g.picture_w_g.height)?"":" not", fw->name.name)); break; case 1: /* Next, See if the app supplies its own icon window */ if (no_icon_window) { break; } if (fw->wmhints && (fw->wmhints->flags & IconWindowHint)) { GetIconWindow(fw); } ICON_DBG((stderr,"ciw: iwh%s used '%s'\n", (fw->icon_g.picture_w_g.height)?"":" not",fw->name.name)); break; case 2: /* try an ewmh icon */ if (HAS_EWMH_WM_ICON_HINT(fw) == EWMH_TRUE_ICON) { if (EWMH_SetIconFromWMIcon(fw, NULL, 0, False)) { SET_USE_EWMH_ICON(fw, True); } } ICON_DBG((stderr,"ciw: inh%s used '%s'\n", (fw->icon_g.picture_w_g.height)?"":" not",fw->name.name)); break; case 3: /* Finally, try to get icon bitmap from the * application */ if (fw->wmhints && (fw->wmhints->flags & IconPixmapHint)) { GetIconBitmap(fw); } ICON_DBG((stderr,"ciw: iph%s used '%s'\n", (fw->icon_g.picture_w_g.height)?"":" not",fw->name.name)); break; default: /* can't happen */ break; } } /* Resize icon if necessary */ if ((IS_ICON_OURS(fw)) && fw->icon_g.picture_w_g.height > 0 && fw->icon_g.picture_w_g.height > 0) { int newWidth = fw->icon_g.picture_w_g.width; int newHeight = fw->icon_g.picture_w_g.height; Boolean resize = False; if (newWidth < fw->min_icon_width) { newWidth = fw->min_icon_width; resize = True; } else { if (newWidth > fw->max_icon_width) { newWidth = fw->max_icon_width; resize = True; } } if (newHeight < fw->min_icon_height) { newHeight = fw->min_icon_height; resize = True; } else { if (newHeight > fw->max_icon_height) { newHeight = fw->max_icon_height; resize = True; } } if (resize) { /* Resize the icon Pixmap */ int force_centering = False; int nrx, nry; ICON_DBG((stderr, "ciw: Changing icon (%s) from %dx%d to" " %dx%d\n", fw->name.name, fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, newWidth, newHeight)); /* Resize the icon Pixmap */ /* force to center if the icon has a bg */ if (fw->icon_background_cs >= 0 || fw->icon_maskPixmap == None) { force_centering = True; } SetIconPixmapSize( &(fw->iconPixmap), fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, fw->iconDepth, newWidth, newHeight, force_centering, fw->icon_resize_type, &nrx, &nry, IS_PIXMAP_OURS(fw)); /* Resize the icon mask Pixmap if one was defined */ if (fw->icon_maskPixmap) { SetIconPixmapSize( &(fw->icon_maskPixmap), fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, 1, newWidth, newHeight, force_centering, fw->icon_resize_type, &nrx, &nry, IS_PIXMAP_OURS(fw)); } else if ((nrx > 0 || nry > 0) && fw->iconDepth > 1) { fw->icon_maskPixmap = XCreatePixmap( dpy, fw->iconPixmap, newWidth, newHeight, 1); XSetForeground(dpy, Scr.MonoGC, 0); XFillRectangle( dpy, fw->icon_maskPixmap, Scr.MonoGC, 0, 0, newWidth, newHeight); XSetForeground(dpy, Scr.MonoGC, 1); XFillRectangle( dpy, fw->icon_maskPixmap, Scr.MonoGC, nrx, nry, fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height); XSetForeground(dpy, Scr.MonoGC, 0); /* set it shaped ? YES */ SET_ICON_SHAPED(fw, 1); } /* Resize the icon alpha Pixmap if one was defined */ if (fw->icon_alphaPixmap) { SetIconPixmapSize( &(fw->icon_alphaPixmap), fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, FRenderGetAlphaDepth(), newWidth, newHeight, force_centering, fw->icon_resize_type, &nrx, &nry, IS_PIXMAP_OURS(fw)); } /* Set the new dimensions of the icon window */ fw->icon_g.picture_w_g.width = newWidth; fw->icon_g.picture_w_g.height = newHeight; } } return; } /* * * set the icon pixmap window background * */ static void set_icon_pixmap_background(FvwmWindow *fw) { if (fw->iconPixmap != None && (Pdefault || fw->iconDepth == 1 || fw->iconDepth == Pdepth || IS_PIXMAP_OURS(fw))) { if (fw->icon_background_cs >= 0) { SetWindowBackground( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, &Colorset[fw->icon_background_cs], Pdepth, Scr.StdGC, False); } else if (FShapesSupported && Pdepth == DefaultDepth(dpy, (DefaultScreen(dpy)))) { XSetWindowBackgroundPixmap( dpy, FW_W_ICON_PIXMAP(fw), ParentRelative); } else if (Scr.DefaultColorset >= 0) { SetWindowBackground( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, &Colorset[Scr.DefaultColorset], Pdepth, Scr.StdGC, False); } } } /* * * Creates an icon window as needed * */ void CreateIconWindow(FvwmWindow *fw, int def_x, int def_y) { /* mask for create windows */ unsigned long valuemask; /* attributes for create windows */ XSetWindowAttributes attributes; XWindowChanges xwc; Window old_icon_pixmap_w; Window old_icon_w; Bool is_old_icon_shaped = IS_ICON_SHAPED(fw); old_icon_w = FW_W_ICON_TITLE(fw); old_icon_pixmap_w = (IS_ICON_OURS(fw)) ? FW_W_ICON_PIXMAP(fw) : None; if (!IS_ICON_OURS(fw) && FW_W_ICON_PIXMAP(fw)) { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } SET_ICON_OURS(fw, 1); SET_PIXMAP_OURS(fw, 0); SET_ICON_SHAPED(fw, 0); FW_W_ICON_PIXMAP(fw) = None; fw->iconPixmap = None; fw->iconDepth = 0; if (IS_ICON_SUPPRESSED(fw)) { return; } /* * set up the icon picture */ GetIconPicture(fw, False); /* make space for relief to be drawn outside the icon */ /* this does not happen if fvwm is using a non-default visual (with * private colormap) and the client has supplied a pixmap (not a * bitmap) */ if ((IS_ICON_OURS(fw)) && (fw->icon_g.picture_w_g.height > 0) && (Pdefault || fw->iconDepth == 1 || fw->iconDepth == Pdepth || IS_PIXMAP_OURS(fw))) { fw->icon_g.picture_w_g.width += 2 * abs(fw->icon_background_relief) + 2 * fw->icon_background_padding; fw->icon_g.picture_w_g.height += 2 * abs(fw->icon_background_relief) + 2 * fw->icon_background_padding; } /* * set up the icon title geometry */ setup_icon_title_size(fw); /* * set up icon position */ set_icon_position(fw, def_x, def_y); /* * create the icon title window */ valuemask = CWColormap | CWBorderPixel | CWBackPixel | CWCursor | CWEventMask; attributes.colormap = Pcmap; attributes.background_pixel = Scr.StdBack; attributes.cursor = Scr.FvwmCursors[CRS_DEFAULT]; attributes.border_pixel = 0; attributes.event_mask = XEVMASK_ICONW; if (HAS_NO_ICON_TITLE(fw)) { if (FW_W_ICON_TITLE(fw)) { XDeleteContext(dpy, FW_W_ICON_TITLE(fw), FvwmContext); XDestroyWindow(dpy, FW_W_ICON_TITLE(fw)); XFlush(dpy); FW_W_ICON_TITLE(fw) = None; } } else { if (FW_W_ICON_TITLE(fw) == None) { FW_W_ICON_TITLE(fw) = XCreateWindow( dpy, Scr.Root, fw->icon_g.title_w_g.x, fw->icon_g.title_w_g.y, fw->icon_g.title_w_g.width, fw->icon_g.title_w_g.height, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); } else { XMoveResizeWindow( dpy, FW_W_ICON_TITLE(fw), fw->icon_g.title_w_g.x, fw->icon_g.title_w_g.y, fw->icon_g.title_w_g.width, fw->icon_g.title_w_g.height); } } if (Scr.DefaultColorset >= 0) { SetWindowBackground( dpy, FW_W_ICON_TITLE(fw), fw->icon_g.title_w_g.width, fw->icon_g.title_w_g.height, &Colorset[Scr.DefaultColorset], Pdepth, Scr.StdGC, False); } /* * create the icon picture window */ if (IS_ICON_OURS(fw) && fw->icon_g.picture_w_g.width > 0 && fw->icon_g.picture_w_g.height > 0) { /* use fvwm's visuals in these cases */ if (Pdefault || fw->iconDepth == 1 || fw->iconDepth == Pdepth || IS_PIXMAP_OURS(fw)) { if (!old_icon_pixmap_w) { FW_W_ICON_PIXMAP(fw) = XCreateWindow( dpy, Scr.Root, fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y, fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); } else { FW_W_ICON_PIXMAP(fw) = old_icon_pixmap_w; XMoveResizeWindow( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y, fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height); } set_icon_pixmap_background(fw); } else { /* client supplied icon pixmap and fvwm is using * another visual. * use it as the background pixmap, don't try to put * relief on it because fvwm will not have the correct * colors the Exceed server has problems maintaining * the icon window, it usually fails to refresh the * icon leaving it black so ask for expose events */ attributes.background_pixmap = fw->iconPixmap; attributes.colormap = DefaultColormap(dpy, Scr.screen); valuemask &= ~CWBackPixel; valuemask |= CWBackPixmap; FW_W_ICON_PIXMAP(fw) = XCreateWindow( dpy, Scr.Root, fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y, fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, 0, DefaultDepth(dpy, Scr.screen), InputOutput, DefaultVisual(dpy, Scr.screen), valuemask, &attributes); } } else if (FW_W_ICON_PIXMAP(fw) != None) { /* client supplied icon window: select events on it */ attributes.event_mask = XEVMASK_ICONPW; valuemask = CWEventMask; XChangeWindowAttributes( dpy, FW_W_ICON_PIXMAP(fw), valuemask,&attributes); if (!IS_ICON_OURS(fw)) { XMoveWindow( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y); } } if (old_icon_pixmap_w != None && old_icon_pixmap_w != FW_W_ICON_PIXMAP(fw)) { /* destroy the old window */ XDestroyWindow(dpy, old_icon_pixmap_w); XDeleteContext(dpy, old_icon_pixmap_w, FvwmContext); XFlush(dpy); is_old_icon_shaped = False; } if (FShapesSupported) { if (IS_ICON_SHAPED(fw) && fw->icon_background_cs < 0) { /* when fvwm is using the non-default visual client * supplied icon pixmaps are drawn in a window with no * relief */ int off = 0; if (Pdefault || fw->iconDepth == 1 || fw->iconDepth == Pdepth || IS_PIXMAP_OURS(fw)) { off = abs(fw->icon_background_relief) + fw->icon_background_padding; } SUPPRESS_UNUSED_VAR_WARNING(off); FShapeCombineMask( dpy, FW_W_ICON_PIXMAP(fw), FShapeBounding, off, off, fw->icon_maskPixmap, FShapeSet); } else if (is_old_icon_shaped && FW_W_ICON_PIXMAP(fw) == old_icon_pixmap_w) { /* remove the shape */ XRectangle r; r.x = 0; r.y = 0; r.width = fw->icon_g.picture_w_g.width; r.height = fw->icon_g.picture_w_g.height; SUPPRESS_UNUSED_VAR_WARNING(r); FShapeCombineRectangles( dpy, FW_W_ICON_PIXMAP(fw), FShapeBounding, 0, 0, &r, 1, FShapeSet, 0); } } if (FW_W_ICON_TITLE(fw) != None && FW_W_ICON_TITLE(fw) != old_icon_w) { XSaveContext( dpy, FW_W_ICON_TITLE(fw), FvwmContext, (caddr_t)fw); XDefineCursor( dpy, FW_W_ICON_TITLE(fw), Scr.FvwmCursors[CRS_DEFAULT]); GrabAllWindowKeysAndButtons( dpy, FW_W_ICON_TITLE(fw), Scr.AllBindings, C_ICON, GetUnusedModifiers(), Scr.FvwmCursors[CRS_DEFAULT], True); xwc.sibling = FW_W_FRAME(fw); xwc.stack_mode = Below; XConfigureWindow( dpy, FW_W_ICON_TITLE(fw), CWSibling|CWStackMode, &xwc); } if (FW_W_ICON_PIXMAP(fw) != None && FW_W_ICON_PIXMAP(fw) != old_icon_pixmap_w) { XSaveContext( dpy, FW_W_ICON_PIXMAP(fw), FvwmContext, (caddr_t)fw); XDefineCursor( dpy, FW_W_ICON_PIXMAP(fw), Scr.FvwmCursors[CRS_DEFAULT]); GrabAllWindowKeysAndButtons( dpy, FW_W_ICON_PIXMAP(fw), Scr.AllBindings, C_ICON, GetUnusedModifiers(), Scr.FvwmCursors[CRS_DEFAULT], True); xwc.sibling = FW_W_FRAME(fw); xwc.stack_mode = Below; XConfigureWindow( dpy,FW_W_ICON_PIXMAP(fw),CWSibling|CWStackMode,&xwc); } return; } /* * * Draws the icon window * */ static void DrawIconTitleWindow( FvwmWindow *fw, XEvent *pev, Pixel BackColor, GC Shadow, GC Relief, int cs, int title_cs) { int is_expanded = IS_ICON_ENTERED(fw); FlocaleWinString fstr; Region region = None; XRectangle clip, r; int relief = abs(fw->icon_title_relief); int x_title; int x_title_min = 0; int w_title = fw->icon_g.title_text_width; int x_title_w = fw->icon_g.picture_w_g.x; int w_title_w = fw->icon_g.picture_w_g.width; int x_stipple = relief; int w_title_text_gap = 0; int w_stipple = 0; int is_sticky; int is_stippled; int use_unexpanded_size = 1; Bool draw_string = True; is_sticky = (IS_STICKY_ACROSS_PAGES(fw) || IS_ICON_STICKY_ACROSS_PAGES(fw)); is_sticky |= (IS_STICKY_ACROSS_DESKS(fw) || IS_ICON_STICKY_ACROSS_DESKS(fw)); is_stippled = ((is_sticky && HAS_STICKY_STIPPLED_ICON_TITLE(fw)) || HAS_STIPPLED_ICON_TITLE(fw)); if (is_expanded && FW_W_ICON_PIXMAP(fw) != None) { int sx; int sy; int sw; int sh; use_unexpanded_size = 0; w_title_text_gap = ICON_TITLE_TEXT_GAP_EXPANDED; x_title_min = w_title_text_gap + relief; if (is_stippled) { w_stipple = ICON_TITLE_STICK_MIN_WIDTH; x_title_min += w_stipple + ICON_TITLE_TO_STICK_EXTRA_GAP; } /* resize the icon name window */ w_title_w = w_title + 2 * x_title_min; if (w_title_w <= fw->icon_g.picture_w_g.width) { /* the expanded title is smaller, so do not * expand at all */ is_expanded = 1; w_stipple = 0; use_unexpanded_size = 1; } else { x_title_w = fw->icon_g.picture_w_g.x - (w_title_w - fw->icon_g.picture_w_g.width) / 2; FScreenGetScrRect( NULL, FSCREEN_CURRENT, &sx, &sy, &sw, &sh); /* start keep label on screen. dje 8/7/97 */ if (x_title_w < sx) { /* if new loc neg (off left edge) */ x_title_w = sx; /* move to edge */ } else { /* if not on left edge */ /* if (new loc + width) > screen width * (off edge on right) */ if ((x_title_w + w_title_w) >sx + sw) { /* off right */ /* position up against right * edge */ x_title_w = sx + sw - w_title_w; } /* end keep label on screen. dje * 8/7/97 */ } } } if (use_unexpanded_size) { w_title_text_gap = ICON_TITLE_TEXT_GAP_COLLAPSED; x_title_min = w_title_text_gap + relief; /* resize the icon name window */ if (FW_W_ICON_PIXMAP(fw) != None) { w_title_w = fw->icon_g.picture_w_g.width; x_title_w = fw->icon_g.picture_w_g.x; } else { w_title_w = fw->icon_g.title_w_g.width; x_title_w = fw->icon_g.title_w_g.x; } } if (fw->icon_g.title_w_g.width != w_title_w || fw->icon_g.title_w_g.x != x_title_w || fw->icon_g.title_w_g.height != ICON_HEIGHT(fw)) { fw->icon_g.title_w_g.width = w_title_w; fw->icon_g.title_w_g.x = x_title_w; fw->icon_g.title_w_g.height = ICON_HEIGHT(fw); pev = NULL; /* resize && redraw all */ } if (!pev) { XMoveResizeWindow( dpy, FW_W_ICON_TITLE(fw), fw->icon_g.title_w_g.x, fw->icon_g.title_w_g.y, w_title_w, ICON_HEIGHT(fw)); } if (title_cs >= 0) { SetWindowBackground( dpy, FW_W_ICON_TITLE(fw), w_title_w, ICON_HEIGHT(fw), &Colorset[title_cs], Pdepth, Scr.TitleGC, False); } else { XSetWindowBackground( dpy, FW_W_ICON_TITLE(fw), BackColor); } /* text position */ x_title = (w_title_w - w_title) / 2; if (x_title < x_title_min) x_title = x_title_min; /* text rectangle */ r.x = x_title; r.y = relief; r.width = w_title_w - x_title - relief; r.height = ICON_HEIGHT(fw) - 2*relief; if (is_stippled) { if (w_stipple == 0) { w_stipple = ((w_title_w - 2 * (x_stipple + w_title_text_gap) - w_title) + 1) / 2; } if (w_stipple < ICON_TITLE_STICK_MIN_WIDTH) { w_stipple = ICON_TITLE_STICK_MIN_WIDTH; } if (x_title < x_stipple + w_stipple + w_title_text_gap) { x_title = x_stipple + w_stipple + w_title_text_gap; } r.x = x_title; r.width = w_title_w - 2 * x_title; if (r.width < 1) r.width = 1; } memset(&fstr, 0, sizeof(fstr)); if (pev || is_stippled) { if (pev) { if (!frect_get_intersection( pev->xexpose.x, pev->xexpose.y, pev->xexpose.width, pev->xexpose.height, r.x, r.y, r.width, r.height, &clip)) { draw_string = False; } } else { clip.x = r.x; clip.y = r.y; clip.width = r.width; clip.height = r.height; } if (draw_string) { XSetClipRectangles( dpy, Scr.TitleGC, 0, 0, &clip, 1, Unsorted); region = XCreateRegion(); XUnionRectWithRegion (&clip, region, region); fstr.flags.has_clip_region = True; fstr.clip_region = region; } } if (!pev) { clip.x = relief; clip.y = relief; clip.width = w_title_w - 2*relief; clip.height = ICON_HEIGHT(fw) - 2*relief; XClearWindow(dpy, FW_W_ICON_TITLE(fw)); } else { /* needed for first drawing */ if (x_title - relief >= 1) { /* clear before the text */ XClearArea( dpy, FW_W_ICON_TITLE(fw), relief, relief, x_title - relief, ICON_HEIGHT(fw) - 2*relief, False); } if (is_stippled) { /* clear the stippled area after the text */ XClearArea( dpy, FW_W_ICON_TITLE(fw), w_title_w - x_stipple - w_stipple -1, relief, w_stipple + 2, ICON_HEIGHT(fw) - 2*relief, False); } } if (draw_string) { if (pev) { /* needed by xft font and at first drawing */ XClearArea( dpy, FW_W_ICON_TITLE(fw), clip.x, clip.y, clip.width, clip.height, False); } fstr.str = fw->visible_icon_name; fstr.win = FW_W_ICON_TITLE(fw); fstr.gc = Scr.TitleGC; if (title_cs >= 0) { fstr.colorset = &Colorset[title_cs]; fstr.flags.has_colorset = 1; } else if (cs >= 0) { fstr.colorset = &Colorset[cs]; fstr.flags.has_colorset = 1; } fstr.x = x_title; fstr.y = fw->icon_g.title_w_g.height - relief - fw->icon_font->height + fw->icon_font->ascent; FlocaleDrawString(dpy, fw->icon_font, &fstr, 0); if (pev || is_stippled) { XSetClipMask(dpy, Scr.TitleGC, None); if (region) { XDestroyRegion(region); } } } RelieveRectangle( dpy, FW_W_ICON_TITLE(fw), 0, 0, w_title_w - 1, ICON_HEIGHT(fw) - 1, (fw->icon_title_relief > 0)? Relief:Shadow, (fw->icon_title_relief > 0)? Shadow:Relief, relief); if (is_stippled) { /* an odd number of lines every 4 pixels */ int pseudo_height = ICON_HEIGHT(fw)- 2*relief + 2; int num = (pseudo_height / ICON_TITLE_STICK_VERT_DIST / 2) * 2 - 1; int min = ICON_HEIGHT(fw) / 2 - num * 2 + 1; int max = ICON_HEIGHT(fw) / 2 + num * 2 - ICON_TITLE_STICK_VERT_DIST + 1; int i; for(i = min; w_stipple > 0 && i <= max; i += ICON_TITLE_STICK_VERT_DIST) { RelieveRectangle( dpy, FW_W_ICON_TITLE(fw), x_stipple, i, w_stipple - 1, 1, Shadow, Relief, ICON_TITLE_STICK_HEIGHT); RelieveRectangle( dpy, FW_W_ICON_TITLE(fw), w_title_w - x_stipple - w_stipple, i, w_stipple - 1, 1, Shadow, Relief, ICON_TITLE_STICK_HEIGHT); } } return; } static void DrawIconPixmapWindow( FvwmWindow *fw, Bool reset_bg, XEvent *pev, GC Shadow, GC Relief, int cs) { XRectangle r,clip; Bool cleared = False; if (!pev) { XMoveWindow( dpy, FW_W_ICON_PIXMAP(fw), fw->icon_g.picture_w_g.x, fw->icon_g.picture_w_g.y); if (reset_bg && (fw->iconDepth == 1 || fw->iconDepth == Pdepth || Pdefault || IS_PIXMAP_OURS(fw))) { set_icon_pixmap_background(fw); XClearArea(dpy, FW_W_ICON_PIXMAP(fw), 0, 0, 0, 0, False); cleared = True; } } /* need to locate the icon pixmap */ if (fw->iconPixmap != None) { if (fw->iconDepth == 1 || fw->iconDepth == Pdepth || Pdefault || IS_PIXMAP_OURS(fw)) { FvwmRenderAttributes fra; Bool draw_icon = True; memset(&fra, 0, sizeof(fra)); fra.mask = FRAM_DEST_IS_A_WINDOW; if (cs >= 0) { fra.mask |= FRAM_HAVE_ICON_CSET; fra.colorset = &Colorset[cs]; } r.x = r.y = abs(fw->icon_background_relief) + fw->icon_background_padding; r.width = fw->icon_g.picture_w_g.width - 2 * (abs(fw->icon_background_relief) + fw->icon_background_padding); r.height = fw->icon_g.picture_w_g.height - 2 * (abs(fw->icon_background_relief) + fw->icon_background_padding); if (pev) { if (!frect_get_intersection( pev->xexpose.x, pev->xexpose.y, pev->xexpose.width, pev->xexpose.height, r.x, r.y, r.width, r.height, &clip)) { draw_icon = False; } } else { clip.x = r.x; clip.y = r.y; clip.width = r.width; clip.height = r.height; } if (draw_icon) { if (!cleared && (fw->icon_alphaPixmap || (cs >= 0 && Colorset[cs].icon_alpha_percent < 100))) { XClearArea( dpy, FW_W_ICON_PIXMAP(fw), clip.x, clip.y, clip.width, clip.height, False); } PGraphicsRenderPixmaps( dpy, FW_W_ICON_PIXMAP(fw), fw->iconPixmap, fw->icon_maskPixmap, fw->icon_alphaPixmap, fw->iconDepth, &fra, FW_W_ICON_PIXMAP(fw), Scr.TitleGC, Scr.MonoGC, Scr.AlphaGC, clip.x - r.x, clip.y - r.y, clip.width, clip.height, clip.x, clip.y, clip.width, clip.height, False); } } else { /* it's a client pixmap and fvwm is not using * the root visual The icon window has no 3d * border so copy to (0,0) install the root * colormap temporarily to help the Exceed * server */ if (Scr.bo.do_install_root_cmap) InstallRootColormap(); XCopyArea( dpy, fw->iconPixmap, FW_W_ICON_PIXMAP(fw), DefaultGC(dpy, Scr.screen), 0, 0, fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height, 0, 0); if (Scr.bo.do_install_root_cmap) UninstallRootColormap(); } } /* only relieve unshaped icons or icons with a bg that share fvwm's * visual */ if ((fw->iconPixmap != None) && (!IS_ICON_SHAPED(fw) || fw->icon_background_cs >= 0) && (Pdefault || fw->iconDepth == 1 || fw->iconDepth == Pdepth || IS_PIXMAP_OURS(fw))) { RelieveRectangle( dpy, FW_W_ICON_PIXMAP(fw), 0, 0, fw->icon_g.picture_w_g.width - 1, fw->icon_g.picture_w_g.height - 1, (fw->icon_background_relief > 0)? Relief:Shadow, (fw->icon_background_relief > 0)? Shadow:Relief, abs(fw->icon_background_relief)); } } void DrawIconWindow( FvwmWindow *fw, Bool draw_title, Bool draw_pixmap, Bool focus_change, Bool reset_bg, XEvent *pev) { GC Shadow; GC Relief; Pixel TextColor; Pixel BackColor; color_quad draw_colors; color_quad co_draw_colors; int cs, co_cs; int title_cs = -1; int co_title_cs = -1; int is_expanded = IS_ICON_ENTERED(fw); if (IS_ICON_SUPPRESSED(fw) || (pev && fw->Desk != Scr.CurrentDesk)) { return; } if (Scr.Hilite == fw) { if (fw->icon_title_cs_hi >= 0) { title_cs = fw->icon_title_cs_hi; draw_colors.hilight = Colorset[title_cs].hilite; draw_colors.shadow = Colorset[title_cs].shadow; draw_colors.back = Colorset[title_cs].bg; draw_colors.fore = Colorset[title_cs].fg; } else { draw_colors.hilight = fw->hicolors.hilight; draw_colors.shadow = fw->hicolors.shadow; draw_colors.back = fw->hicolors.back; draw_colors.fore = fw->hicolors.fore; } if (fw->icon_title_cs >= 0) { co_title_cs = fw->icon_title_cs; co_draw_colors.hilight = Colorset[co_title_cs].hilite; co_draw_colors.shadow = Colorset[co_title_cs].shadow; co_draw_colors.back = Colorset[co_title_cs].bg; co_draw_colors.fore = Colorset[co_title_cs].fg; } else { co_draw_colors.hilight = fw->colors.hilight; co_draw_colors.shadow = fw->colors.shadow; co_draw_colors.back = fw->colors.back; co_draw_colors.fore = fw->colors.fore; } cs = fw->cs_hi; co_cs = fw->cs; } else { if (fw->icon_title_cs >= 0) { title_cs = fw->icon_title_cs; draw_colors.hilight = Colorset[title_cs].hilite; draw_colors.shadow = Colorset[title_cs].shadow; draw_colors.back = Colorset[title_cs].bg; draw_colors.fore = Colorset[title_cs].fg; } else { draw_colors.hilight = fw->colors.hilight; draw_colors.shadow = fw->colors.shadow; draw_colors.back = fw->colors.back; draw_colors.fore = fw->colors.fore; } if (fw->icon_title_cs_hi >= 0) { co_title_cs = fw->icon_title_cs_hi; co_draw_colors.hilight = Colorset[co_title_cs].hilite; co_draw_colors.shadow = Colorset[co_title_cs].shadow; co_draw_colors.back = Colorset[co_title_cs].bg; co_draw_colors.fore = Colorset[co_title_cs].fg; } else { co_draw_colors.hilight = fw->hicolors.hilight; co_draw_colors.shadow = fw->hicolors.shadow; co_draw_colors.back = fw->hicolors.back; co_draw_colors.fore = fw->hicolors.fore; } cs = fw->cs; co_cs = fw->cs_hi; } if (Pdepth < 2 && Scr.Hilite != fw) { Relief = Scr.StdReliefGC; Shadow = Scr.StdShadowGC; } else { if (Pdepth < 2 && Scr.Hilite == fw) { Relief = Scr.ScratchGC2; } else { Globalgcv.foreground = draw_colors.hilight; Globalgcm = GCForeground; XChangeGC(dpy,Scr.ScratchGC1,Globalgcm,&Globalgcv); Relief = Scr.ScratchGC1; } Globalgcv.foreground = draw_colors.shadow; XChangeGC(dpy,Scr.ScratchGC2, Globalgcm, &Globalgcv); Shadow = Scr.ScratchGC2; } TextColor = draw_colors.fore; BackColor = draw_colors.back; /* set up TitleGC for drawing the icon label */ if (fw->icon_font != NULL) { NewFontAndColor(fw->icon_font, TextColor, BackColor); } if (draw_title && FW_W_ICON_TITLE(fw) != None) { if (pev && pev->xexpose.window != FW_W_ICON_TITLE(fw)) { XEvent e; if (FCheckTypedWindowEvent( dpy, FW_W_ICON_TITLE(fw), Expose, &e)) { flush_accumulate_expose( FW_W_ICON_TITLE(fw), &e); DrawIconTitleWindow( fw, &e, BackColor, Shadow, Relief, cs, title_cs); } } else { if (!pev) { FCheckWeedTypedWindowEvents( dpy, FW_W_ICON_TITLE(fw), Expose, NULL); } DrawIconTitleWindow( fw, pev, BackColor, Shadow, Relief, cs, title_cs); } } if (draw_pixmap) { int bg_cs = fw->icon_background_cs; if (bg_cs >= 0 && (fw->iconDepth != 1 || fw->icon_background_padding > 0 || fw->icon_maskPixmap != None || fw->icon_alphaPixmap != None)) { if (Pdepth < 2 && Scr.Hilite == fw) { Relief = Scr.ScratchGC2; } else { Globalgcv.foreground = Colorset[bg_cs].hilite; Globalgcm = GCForeground; XChangeGC( dpy,Scr.ScratchGC1,Globalgcm,&Globalgcv); Relief = Scr.ScratchGC1; } Globalgcv.foreground = Colorset[bg_cs].shadow; XChangeGC(dpy,Scr.ScratchGC2, Globalgcm, &Globalgcv); Shadow = Scr.ScratchGC2; } } if (focus_change && draw_pixmap) { Bool alpha_change = False; Bool tint_change = False; Bool relief_change = False; Bool color_change = False; draw_pixmap = False; /* check if we have to draw the icons */ if (Pdepth < 2) { relief_change = True; } else if (fw->iconDepth == 1) { color_change = (draw_colors.fore != co_draw_colors.back) || (draw_colors.fore != co_draw_colors.back); } if (!relief_change && (fw->iconPixmap != None) && !IS_ICON_SHAPED(fw) && (Pdefault || fw->iconDepth == Pdepth || fw->iconDepth == 1 || IS_PIXMAP_OURS(fw))) { relief_change = (draw_colors.hilight != co_draw_colors.hilight) || (draw_colors.shadow != co_draw_colors.shadow); } if (cs >= 0 && co_cs >= 0) { alpha_change = (Colorset[cs].icon_alpha_percent != Colorset[co_cs].icon_alpha_percent); tint_change = (Colorset[cs].icon_tint_percent != Colorset[co_cs].icon_tint_percent) || (Colorset[cs].icon_tint_percent > 0 && Colorset[cs].icon_tint != Colorset[co_cs].icon_tint); } else if (cs >= 0 && co_cs < 0) { alpha_change = (Colorset[cs].icon_alpha_percent < 100); tint_change = (Colorset[cs].icon_tint_percent > 0); } else if (cs < 0 && co_cs >= 0) { alpha_change = (Colorset[co_cs].icon_alpha_percent < 100); tint_change = (Colorset[co_cs].icon_tint_percent > 0); } if (alpha_change || tint_change || relief_change || color_change) { draw_pixmap = True; } } if (draw_pixmap && FW_W_ICON_PIXMAP(fw) != None) { if (pev && pev->xexpose.window != FW_W_ICON_PIXMAP(fw)) { XEvent e; if (FCheckTypedWindowEvent( dpy, FW_W_ICON_PIXMAP(fw), Expose, &e)) { flush_accumulate_expose( FW_W_ICON_PIXMAP(fw), &e); DrawIconPixmapWindow( fw, reset_bg, &e, Shadow, Relief, cs); } } else { if (!pev) { FCheckWeedTypedWindowEvents( dpy, FW_W_ICON_PIXMAP(fw), Expose, NULL); } DrawIconPixmapWindow( fw, reset_bg, pev, Shadow, Relief, cs); } } if (is_expanded) { if (FW_W_ICON_TITLE(fw) != None) { XRaiseWindow(dpy, FW_W_ICON_TITLE(fw)); raisePanFrames(); } } else { XWindowChanges xwc; int mask; xwc.sibling = FW_W_FRAME(fw); xwc.stack_mode = Below; mask = CWSibling|CWStackMode; if (FW_W_ICON_TITLE(fw) != None) { XConfigureWindow(dpy, FW_W_ICON_TITLE(fw), mask, &xwc); } if (FW_W_ICON_PIXMAP(fw) != None) { XConfigureWindow(dpy, FW_W_ICON_PIXMAP(fw), mask, &xwc); } } /* wait for pending EnterNotify/LeaveNotify events to suppress race * condition w/ expanding/collapsing icon titles */ XFlush(dpy); } /* * * Procedure: * ChangeIconPixmap - procedure change the icon pixmap or "pixmap" * window. Called in events.c and ewmh_events.c * */ void ChangeIconPixmap(FvwmWindow *fw) { rectangle g; if (!IS_ICONIFIED(fw)) { ICON_DBG((stderr,"hpn: postpone icon change '%s'\n", fw->name.name)); /* update the icon later when application is iconified */ SET_HAS_ICON_CHANGED(fw, 1); } else if (IS_ICONIFIED(fw)) { ICON_DBG((stderr,"hpn: applying new icon '%s'\n", fw->name.name)); SET_ICONIFIED(fw, 0); SET_ICON_UNMAPPED(fw, 0); get_icon_geometry(fw, &g); CreateIconWindow(fw, g.x, g.y); broadcast_icon_geometry(fw, False); /* domivogt (15-Sep-1999): BroadcastConfig informs modules of * the configuration change including the iconified flag. So * this flag must be set here. I'm not sure if the two calls of * the SET_ICONIFIED macro after BroadcastConfig are necessary, * but since it's only minimal overhead I prefer to be on the * safe side. */ SET_ICONIFIED(fw, 1); BroadcastConfig(M_CONFIGURE_WINDOW, fw); SET_ICONIFIED(fw, 0); if (!IS_ICON_SUPPRESSED(fw)) { LowerWindow(fw, False); AutoPlaceIcon(fw, NULL, True); if (fw->Desk == Scr.CurrentDesk) { if (FW_W_ICON_TITLE(fw)) { XMapWindow(dpy, FW_W_ICON_TITLE(fw)); } if (FW_W_ICON_PIXMAP(fw) != None) { XMapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } } } SET_ICONIFIED(fw, 1); DrawIconWindow(fw, False, True, False, False, NULL); } return; } /* * * Procedure: * RedoIconName - procedure to re-position the icon window and name * */ void RedoIconName(FvwmWindow *fw) { if (IS_ICON_SUPPRESSED(fw)) { return; } if (FW_W_ICON_TITLE(fw) == None) { return; } setup_icon_title_size(fw); /* clear the icon window, and trigger a re-draw via an expose event */ if (IS_ICONIFIED(fw)) { DrawIconWindow(fw, True, False, False, False, NULL); XClearArea(dpy, FW_W_ICON_TITLE(fw), 0, 0, 0, 0, True); } return; } /* * * Procedure: * AutoPlace - Find a home for an icon * */ void AutoPlaceIcon( FvwmWindow *t, initial_window_options_t *win_opts, Bool do_move_immediately) { int base_x, base_y; int width,height; FvwmWindow *test_fw; Bool loc_ok; Bool loc_ok_wrong_screen; Bool loc_ok_wrong_screen2; int real_x=10, real_y=10; int new_x, new_y; Bool do_move_icon = False; #if 0 /* dv (16-Mar-2003): We need to place the icon even if there is no icon so * the 'position' can be communicated to the modules to decide whether to show * the icon or not. */ if (FW_W_ICON_PIXMAP(t) == None && FW_W_ICON_TITLE(t) == None) { return; } #endif /* New! Put icon in same page as the center of the window */ /* Not a good idea for StickyIcons. Neither for icons of windows that are * visible on the current page. */ if (IS_ICON_STICKY_ACROSS_DESKS(t) || IS_STICKY_ACROSS_DESKS(t)) { t->Desk = Scr.CurrentDesk; } if (IS_ICON_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_PAGES(t)) { base_x = 0; base_y = 0; /*Also, if its a stickyWindow, put it on the current page! */ new_x = t->g.frame.x % Scr.MyDisplayWidth; new_y = t->g.frame.y % Scr.MyDisplayHeight; if (new_x + t->g.frame.width <= 0) new_x += Scr.MyDisplayWidth; if (new_y + t->g.frame.height <= 0) new_y += Scr.MyDisplayHeight; frame_setup_window( t, new_x, new_y, t->g.frame.width, t->g.frame.height, False); } else if (IsRectangleOnThisPage(&(t->g.frame), t->Desk)) { base_x = 0; base_y = 0; } else { base_x = ((t->g.frame.x + Scr.Vx + (t->g.frame.width >> 1)) / Scr.MyDisplayWidth) * Scr.MyDisplayWidth; base_y= ((t->g.frame.y + Scr.Vy + (t->g.frame.height >> 1)) / Scr.MyDisplayHeight) * Scr.MyDisplayHeight; /* limit icon position to desktop */ if (base_x > Scr.VxMax) base_x = Scr.VxMax; if (base_x < 0) base_x = 0; if (base_y > Scr.VyMax) base_y = Scr.VyMax; if (base_y < 0) base_y = 0; base_x -= Scr.Vx; base_y -= Scr.Vy; } if (IS_ICON_MOVED(t) || (win_opts != NULL && win_opts->flags.use_initial_icon_xy)) { rectangle g; int dx; int dy; get_icon_geometry(t, &g); if (win_opts != NULL && win_opts->flags.use_initial_icon_xy) { g.x = win_opts->initial_icon_x; g.y = win_opts->initial_icon_y; } dx = g.x; dy = g.y; /* just make sure the icon is on this page */ g.x = g.x % Scr.MyDisplayWidth + base_x; g.y = g.y % Scr.MyDisplayHeight + base_y; if (g.x < 0) { g.x += Scr.MyDisplayWidth; } if (g.y < 0) { g.y += Scr.MyDisplayHeight; } dx = g.x - dx; dy = g.y - dy; modify_icon_position(t, dx, dy); do_move_icon = True; } else if (USE_ICON_POSITION_HINT(t) && t->wmhints && t->wmhints->flags & IconPositionHint) { set_icon_position(t, t->wmhints->icon_x, t->wmhints->icon_y); do_move_icon = True; } /* dje 10/12/97: Look thru chain of icon boxes assigned to window. Add logic for grids and fill direction. */ else if (DO_IGNORE_ICON_BOXES(t)) { int sx; int sy; int sw; int sh; fscreen_scr_arg fscr; rectangle g; get_icon_geometry(t, &g); get_icon_corner(t, &g); fscr.xypos.x = g.x + g.width / 2; fscr.xypos.y = g.y + g.height / 2; FScreenGetScrRect(&fscr, FSCREEN_XYPOS, &sx, &sy, &sw, &sh); if (g.x < sx) g.x = sx; else if (g.x + g.width > sx + sw) g.x = sx + sw - g.width; if (g.y < sy) g.y = sy; else if (g.y + g.height > sy + sh) g.y = sy + sh - g.height; set_icon_position(t, g.x, g.y); do_move_icon = True; } else { /* A place to hold inner and outer loop variables. */ typedef struct dimension_struct { int step; /* grid size (may be negative) */ int start_at; /* starting edge */ int real_start; /* on screen starting edge */ int end_at; /* ending edge */ int base; /* base for screen */ int icon_dimension; /* height or width */ int nom_dimension; /* nonminal height or width */ int screen_dimension; /* screen height or width */ int screen_offset; /* screen offset */ } dimension; dimension dim[3]; /* space for work, 1st, 2nd dimen */ icon_boxes *icon_boxes_ptr; /* current icon box */ int i; /* index for inner/outer loop data */ fscreen_scr_arg fscr; rectangle ref; rectangle g; /* Hopefully this makes the following more readable. */ #define ICONBOX_LFT icon_boxes_ptr->IconBox[0] #define ICONBOX_TOP icon_boxes_ptr->IconBox[1] #define ICONBOX_RGT icon_boxes_ptr->IconBox[2] #define ICONBOX_BOT icon_boxes_ptr->IconBox[3] #define BOT_FILL icon_boxes_ptr->IconFlags & ICONFILLBOT #define RGT_FILL icon_boxes_ptr->IconFlags & ICONFILLRGT #define HRZ_FILL icon_boxes_ptr->IconFlags & ICONFILLHRZ /* needed later */ fscr.xypos.x = t->g.frame.x + (t->g.frame.width / 2) - base_x; fscr.xypos.y = t->g.frame.y + (t->g.frame.height / 2) - base_y; get_icon_geometry(t, &g); /* unnecessary copy of width */ width = g.width; /* total height */ height = g.height; /* no slot found yet */ loc_ok = False; loc_ok_wrong_screen = False; /* check all boxes in order */ icon_boxes_ptr = NULL; /* init */ while(do_all_iconboxes(t, &icon_boxes_ptr)) { if (loc_ok == True) { /* leave for loop */ break; } /* get the screen dimensions for the icon box */ if (icon_boxes_ptr->IconScreen == FSCREEN_CURRENT) fscr.mouse_ev = NULL; FScreenGetScrRect( &fscr, icon_boxes_ptr->IconScreen, &ref.x, &ref.y, &ref.width, &ref.height); dim[1].screen_offset = ref.y; dim[1].screen_dimension = ref.height; dim[2].screen_offset = ref.x; dim[2].screen_dimension = ref.width; /* y amount */ dim[1].step = icon_boxes_ptr->IconGrid[1]; /* init start from */ dim[1].start_at = ICONBOX_TOP + dim[1].screen_offset; if (icon_boxes_ptr->IconSign[1] == '-') { dim[1].start_at += dim[1].screen_dimension; } /* init end at */ dim[1].end_at = ICONBOX_BOT + dim[1].screen_offset; if (icon_boxes_ptr->IconSign[3] == '-') { dim[1].end_at += dim[1].screen_dimension; } /* save base */ dim[1].base = base_y; /* save dimension */ dim[1].icon_dimension = height; if (BOT_FILL) { /* fill from bottom */ /* reverse step */ dim[1].step = 0 - dim[1].step; } /* end fill from bottom */ /* x amount */ dim[2].step = icon_boxes_ptr->IconGrid[0]; /* init start from */ dim[2].start_at = ICONBOX_LFT + dim[2].screen_offset; if (icon_boxes_ptr->IconSign[0] == '-') { dim[2].start_at += dim[2].screen_dimension; } /* init end at */ dim[2].end_at = ICONBOX_RGT + dim[2].screen_offset; if (icon_boxes_ptr->IconSign[2] == '-') { dim[2].end_at += dim[2].screen_dimension; } /* save base */ dim[2].base = base_x; /* save dimension */ dim[2].icon_dimension = width; if (RGT_FILL) { /* fill from right */ /* reverse step */ dim[2].step = 0 - dim[2].step; } /* end fill from right */ for (i=1;i<=2;i++) { /* for dimensions 1 and 2 */ /* If the window is taller than the icon box, ignore the icon height * when figuring where to put it. Same goes for the width * This should permit reasonably graceful handling of big icons. */ dim[i].nom_dimension = dim[i].icon_dimension; if (dim[i].icon_dimension >= dim[i].end_at - dim[i].start_at) { dim[i].nom_dimension = dim[i].end_at - dim[i].start_at - 1; } if (dim[i].step < 0) { /* if moving backwards */ /* save */ dim[0].start_at = dim[i].start_at; /* swap one */ dim[i].start_at = dim[i].end_at; /* swap the other */ dim[i].end_at = dim[0].start_at; dim[i].start_at -= dim[i].icon_dimension; } /* end moving backwards */ /* adjust both to base */ dim[i].start_at += dim[i].base; dim[i].end_at += dim[i].base; } /* end 2 dimensions */ if (HRZ_FILL) { /* if hrz first */ /* save */ memcpy(&dim[0],&dim[1],sizeof(dimension)); /* switch one */ memcpy(&dim[1],&dim[2],sizeof(dimension)); /* switch the other */ memcpy(&dim[2],&dim[0],sizeof(dimension)); } /* end horizontal dimension first */ /* save for reseting inner loop */ dim[0].start_at = dim[2].start_at; loc_ok_wrong_screen2 = False; while((dim[1].step < 0 /* filling reversed */ ? (dim[1].start_at + dim[1].icon_dimension - dim[1].nom_dimension > dim[1].end_at) /* check back edge */ : (dim[1].start_at + dim[1].nom_dimension < dim[1].end_at)) /* check front edge */ && (!loc_ok) && (!loc_ok_wrong_screen2)) { /* nothing found yet */ dim[1].real_start = dim[1].start_at; /* init */ if (dim[1].start_at + dim[1].icon_dimension > dim[1].screen_offset + dim[1].screen_dimension - 2 + dim[1].base) { /* off screen, move on screen */ dim[1].real_start = dim[1].screen_offset + dim[1].screen_dimension - dim[1].icon_dimension + dim[1].base; } /* end off screen */ if (dim[1].start_at < dim[1].screen_offset + dim[1].base) { /* if off other edge, move on screen */ dim[1].real_start = dim[1].screen_offset + dim[1].base; } /* end off other edge */ /* reset inner loop */ dim[2].start_at = dim[0].start_at; while((dim[2].step < 0 /* filling reversed */ ? (dim[2].start_at + dim[2].icon_dimension-dim[2].nom_dimension > dim[2].end_at) /* check back edge */ : (dim[2].start_at + dim[2].nom_dimension < dim[2].end_at)) /* check front edge */ && (!loc_ok) && (!loc_ok_wrong_screen2)) { /* nothing found yet */ dim[2].real_start = dim[2].start_at; /* init */ if (dim[2].start_at + dim[2].icon_dimension > dim[2].screen_offset + dim[2].screen_dimension - 2 + dim[2].base) { /* if off screen, move on screen */ dim[2].real_start = dim[2].screen_offset + dim[2].screen_dimension - dim[2].icon_dimension + dim[2].base; } /* end off screen */ if (dim[2].start_at < dim[2].screen_offset + dim[2].base) { /* if off other edge, move on screen */ dim[2].real_start = dim[2].screen_offset + dim[2].base; } /* end off other edge */ if (HRZ_FILL) { /* hrz first */ /* unreverse them */ real_x = dim[1].real_start; real_y = dim[2].real_start; } else { /* reverse them */ real_x = dim[2].real_start; real_y = dim[1].real_start; } /* this may be a good location */ if (FScreenIsRectangleOnScreen(&fscr, FSCREEN_XYPOS, &ref)) { loc_ok = True; } else { loc_ok_wrong_screen2 = True; } test_fw = Scr.FvwmRoot.next; while((test_fw != (FvwmWindow *)0) &&(loc_ok == True || loc_ok_wrong_screen2)) { /* test overlap */ if (test_fw->Desk == t->Desk) { rectangle g; if ((IS_ICONIFIED(test_fw)) && (!IS_TRANSIENT(test_fw) || !IS_ICONIFIED_BY_PARENT(test_fw)) && (FW_W_ICON_TITLE(test_fw)||FW_W_ICON_PIXMAP(test_fw)) && (test_fw != t)) { get_icon_geometry(test_fw, &g); if ((g.x<(real_x+width+MIN_ICON_BOX_DIST))&& ((g.x+g.width+MIN_ICON_BOX_DIST) > real_x)&& (g.y<(real_y+height+MIN_ICON_BOX_DIST))&& ((g.y+g.height + MIN_ICON_BOX_DIST)>real_y)) { /* don't accept this location */ loc_ok = False; loc_ok_wrong_screen2 = False; } /* end if icons overlap */ } /* end if its an icon */ } /* end if same desk */ test_fw = test_fw->next; } /* end while icons that may overlap */ if (loc_ok_wrong_screen2) { loc_ok_wrong_screen = True; } /* Grid inner value & direction */ dim[2].start_at += dim[2].step; } /* end while room inner dimension */ /* Grid outer value & direction */ dim[1].start_at += dim[1].step; } /* end while room outer dimension */ } /* end for all icon boxes, or found space */ if (!loc_ok && !loc_ok_wrong_screen) /* If icon never found a home just leave it */ return; set_icon_position(t, real_x, real_y); broadcast_icon_geometry(t, True); do_move_icon = True; } if (do_move_icon && do_move_immediately) { move_icon_to_position(t); } return; } static icon_boxes *global_icon_box_ptr; /* Find next icon box to try to place icon in. Goes thru chain that the window got thru style matching, then the global icon box. Create the global icon box on first call. Return code indicates when the boxes are used up. The boxes could only get completely used up when you fill the screen with them. */ static int do_all_iconboxes(FvwmWindow *t, icon_boxes **icon_boxes_ptr) { if (global_icon_box_ptr == 0) { /* if first time */ int sx; int sy; int sw; int sh; /* Right now, the global box is hard-coded, fills the primary * screen, uses an 80x80 grid, and fills top-bottom, * left-right */ FScreenGetScrRect(NULL, FSCREEN_PRIMARY, &sx, &sy, &sw, &sh); global_icon_box_ptr = calloc(1, sizeof(icon_boxes)); global_icon_box_ptr->IconBox[0] = sx; global_icon_box_ptr->IconBox[1] = sy; global_icon_box_ptr->IconBox[2] = sx + sw; global_icon_box_ptr->IconBox[3] = sy + sh; global_icon_box_ptr->IconGrid[0] = 80; global_icon_box_ptr->IconGrid[1] = 80; global_icon_box_ptr->IconFlags = ICONFILLHRZ; } if (*icon_boxes_ptr == NULL) { /* first time? */ /* start at windows box */ *icon_boxes_ptr = t->IconBoxes; if (!*icon_boxes_ptr) { /* if window has no box */ /* use global box */ *icon_boxes_ptr = global_icon_box_ptr; } /* use box */ return (1); } /* Here its not the first call, we are either on the chain or at * the global box */ if (*icon_boxes_ptr == global_icon_box_ptr) { /* if the global box */ /* completely out of boxes (unlikely) */ return (0); } /* move to next one on chain */ *icon_boxes_ptr = (*icon_boxes_ptr)->next; if (*icon_boxes_ptr) { /* if there is a next one */ /* return it */ return (1); } /* global box */ *icon_boxes_ptr = global_icon_box_ptr; /* use it */ return (1); } /* * * Looks for icon from a file * */ static void GetIconFromFile(FvwmWindow *fw) { char *path = NULL; FvwmPictureAttributes fpa; fpa.mask = 0; if (fw->cs >= 0 && Colorset[fw->cs].do_dither_icon) { fpa.mask |= FPAM_DITHER; } fw->icon_g.picture_w_g.width = 0; fw->icon_g.picture_w_g.height = 0; path = PictureFindImageFile(fw->icon_bitmap_file, NULL, R_OK); if (path == NULL) { return; } if (!PImageLoadPixmapFromFile( dpy, Scr.NoFocusWin, path, &fw->iconPixmap, &fw->icon_maskPixmap, &fw->icon_alphaPixmap, &fw->icon_g.picture_w_g.width, &fw->icon_g.picture_w_g.height, &fw->iconDepth, &fw->icon_nalloc_pixels, &fw->icon_alloc_pixels, &fw->icon_no_limit, fpa)) { fvwm_msg(ERR, "GetIconFromFile", "Failed to load %s", path); free(path); return; } SET_PIXMAP_OURS(fw, 1); free(path); if (FShapesSupported && fw->icon_maskPixmap) { SET_ICON_SHAPED(fw, 1); } return; } /* * * Looks for an application supplied icon window * */ static void GetIconWindow(FvwmWindow *fw) { int w; int h; int bw; fw->icon_g.picture_w_g.width = 0; fw->icon_g.picture_w_g.height = 0; /* We are guaranteed that wmhints is non-null when calling this * routine */ if (XGetGeometry( dpy, fw->wmhints->icon_window, &JunkRoot, &JunkX, &JunkY, (unsigned int*)&w, (unsigned int*)&h,(unsigned int*)&bw, (unsigned int*)&JunkDepth) == 0) { fvwm_msg( ERR,"GetIconWindow", "Window '%s' has a bad icon window! Ignoring icon" " window.", fw->name.name); /* disable the icon window hint */ fw->wmhints->icon_window = None; fw->wmhints->flags &= ~IconWindowHint; return; } fw->icon_border_width = bw; fw->icon_g.picture_w_g.width = w + 2 * bw; fw->icon_g.picture_w_g.height = h + 2 * bw; /* * Now make the new window the icon window for this window, * and set it up to work as such (select for key presses * and button presses/releases, set up the contexts for it, * and define the cursor for it). */ FW_W_ICON_PIXMAP(fw) = fw->wmhints->icon_window; if (FShapesSupported) { if (fw->wmhints->flags & IconMaskHint) { SET_ICON_SHAPED(fw, 1); fw->icon_maskPixmap = fw->wmhints->icon_mask; } } /* Make sure that the window is a child of the root window ! */ /* Olwais screws this up, maybe others do too! */ XReparentWindow(dpy, FW_W_ICON_PIXMAP(fw), Scr.Root, 0,0); SET_ICON_OURS(fw, 0); return; } /* * * Looks for an application supplied bitmap or pixmap * */ static void GetIconBitmap(FvwmWindow *fw) { int width, height, depth; fw->icon_g.picture_w_g.width = 0; fw->icon_g.picture_w_g.height = 0; /* We are guaranteed that wmhints is non-null when calling this routine */ if (!XGetGeometry( dpy, fw->wmhints->icon_pixmap, &JunkRoot, &JunkX, &JunkY, (unsigned int*)&width, (unsigned int*)&height, (unsigned int*)&JunkBW, (unsigned int*)&depth)) { fvwm_msg( ERR,"GetIconBitmap", "Window '%s' has a bad icon pixmap! Ignoring icon.", fw->name.name); /* disable icon pixmap hint */ fw->wmhints->icon_pixmap = None; fw->wmhints->flags &= ~IconPixmapHint; return; } /* sanity check the pixmap depth, it must be the same as the root or 1 */ if (depth != 1 && depth != Pdepth && depth != DefaultDepth(dpy,Scr.screen)) { fvwm_msg( ERR, "GetIconBitmap", "Window '%s' has a bad icon bitmap depth %d (should" " be 1, %d or %d)! Ignoring icon bitmap.", fw->name.name, depth, Pdepth, DefaultDepth(dpy,Scr.screen)); /* disable icon pixmap hint */ fw->wmhints->icon_pixmap = None; fw->wmhints->flags &= ~IconPixmapHint; return; } fw->iconPixmap = fw->wmhints->icon_pixmap; fw->icon_g.picture_w_g.width = width; fw->icon_g.picture_w_g.height = height; fw->iconDepth = depth; if (FShapesSupported) { if (fw->wmhints->flags & IconMaskHint) { SET_ICON_SHAPED(fw, 1); fw->icon_maskPixmap = fw->wmhints->icon_mask; } } SET_PIXMAP_OURS(fw, 0); return; } /* * * Procedure: * DeIconify a window * */ void DeIconify(FvwmWindow *fw) { FvwmWindow *t, *tmp, *ofw; FvwmWindow *sf = get_focus_window(); rectangle icon_rect; XWindowAttributes winattrs = {0}; if (!fw) { return; } if (!XGetWindowAttributes(dpy, FW_W(fw), &winattrs)) { return; } /* make sure fw->flags.is_map_pending is OK */ if (winattrs.map_state == IsViewable && IS_MAP_PENDING(fw)) { SET_MAP_PENDING(fw, 0); } else if (IS_MAP_PENDING(fw)) { /* final state: de-iconified */ SET_ICONIFY_AFTER_MAP(fw, 0); return; } for (ofw = NULL; fw != ofw && IS_ICONIFIED_BY_PARENT(fw); ) { t = get_transientfor_fvwmwindow(fw); if (t == NULL) { break; } ofw = fw; fw = t; } if (IS_ICONIFIED_BY_PARENT(fw)) { SET_ICONIFIED_BY_PARENT(fw, 0); } /* AS dje RaiseWindow(fw); */ if (fw == sf) { /* take away the focus before mapping */ DeleteFocus(True); } /* Note: DeleteFocus may delete the flags set by * mark_transient_subtree(), so do it later. */ mark_transient_subtree(fw, MARK_ALL_LAYERS, MARK_ALL, False, True); /* now de-iconify transients */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (t == fw || IS_IN_TRANSIENT_SUBTREE(t)) { SET_IN_TRANSIENT_SUBTREE(t, 0); SET_MAPPED(t, 1); SET_ICONIFIED_BY_PARENT(t, 0); if (Scr.Hilite == t) { border_draw_decorations( t, PART_ALL, False, True, CLEAR_ALL, NULL, NULL); } /* AS stuff starts here dje */ if (FW_W_ICON_PIXMAP(t)) { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(t)); } if (FW_W_ICON_TITLE(t)) { XUnmapWindow(dpy, FW_W_ICON_TITLE(t)); } XFlush(dpy); /* End AS */ XMapWindow(dpy, FW_W(t)); if (t->Desk == Scr.CurrentDesk) { rectangle r; get_icon_geometry(t, &r); /* update absoluthe geometry in case the icon * was moved over a page boundary; the move * code already takes care of keeping the frame * geometry up to date */ update_absolute_geometry(t); if (IsRectangleOnThisPage(&r, t->Desk) && !IsRectangleOnThisPage( &(t->g.frame), t->Desk)) { /* Make sure we keep it on screen when * de-iconifying. */ t->g.frame.x -= truncate_to_multiple( t->g.frame.x, Scr.MyDisplayWidth); t->g.frame.y -= truncate_to_multiple( t->g.frame.y, Scr.MyDisplayHeight); XMoveWindow( dpy, FW_W_FRAME(t), t->g.frame.x, t->g.frame.y); update_absolute_geometry(t); maximize_adjust_offset(t); } } /* domivogt (1-Mar-2000): The next block is a hack to * prevent animation if the window has an icon, but * neither a pixmap nor a title. */ if (HAS_NO_ICON_TITLE(t) && FW_W_ICON_PIXMAP(t) == None) { memset(&fw->icon_g, 0, sizeof(fw->icon_g)); } get_icon_geometry(t, &icon_rect); /* if this fails it does not overwrite icon_rect */ EWMH_GetIconGeometry(t, &icon_rect); if (t == fw) { BroadcastPacket( M_DEICONIFY, 11, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t, (long)icon_rect.x, (long)icon_rect.y, (long)icon_rect.width, (long)icon_rect.height, (long)t->g.frame.x, (long)t->g.frame.y, (long)t->g.frame.width, (long)t->g.frame.height); } else { BroadcastPacket( M_DEICONIFY, 7, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t, (long)icon_rect.x, (long)icon_rect.y, (long)icon_rect.width, (long)icon_rect.height); } XMapWindow(dpy, FW_W_PARENT(t)); if (t->Desk == Scr.CurrentDesk) { XMapWindow(dpy, FW_W_FRAME(t)); SET_MAP_PENDING(t, 1); } SetMapStateProp(t, NormalState); SET_ICONIFIED(t, 0); SET_ICON_UNMAPPED(t, 0); SET_ICON_ENTERED(t, 0); /* Need to make sure the border is colored correctly, * in case it was stuck or unstuck while iconified. */ tmp = Scr.Hilite; Scr.Hilite = t; border_draw_decorations( t, PART_ALL, (sf == t) ? True : False, True, CLEAR_ALL, NULL, NULL); Scr.Hilite = tmp; } } #if 1 RaiseWindow(fw, False); /* moved dje */ #endif if (sf == fw) { /* update the focus to make sure the application knows its * state */ if (!FP_DO_UNFOCUS_LEAVE(FW_FOCUS_POLICY(fw))) { SetFocusWindow(fw, True, FOCUS_SET_FORCE); } } else if (FP_DO_SORT_WINDOWLIST_BY(FW_FOCUS_POLICY(fw)) == FPOL_SORT_WL_BY_OPEN) { SetFocusWindow(fw, True, FOCUS_SET_FORCE); } focus_grab_buttons_on_layer(fw->layer); return; } /* * * Iconifies the selected window * */ void Iconify(FvwmWindow *fw, initial_window_options_t *win_opts) { FvwmWindow *t; FvwmWindow *sf; XWindowAttributes winattrs = {0}; unsigned long eventMask; rectangle icon_rect; if (!fw) { return; } if (!XGetWindowAttributes(dpy, FW_W(fw), &winattrs)) { return; } /* make sure fw->flags.is_map_pending is OK */ if ((winattrs.map_state == IsViewable) && IS_MAP_PENDING(fw)) { SET_MAP_PENDING(fw, 0); } if (IS_MAP_PENDING(fw)) { /* final state: iconified */ SET_ICONIFY_AFTER_MAP(fw, 1); return; } eventMask = winattrs.your_event_mask; mark_transient_subtree(fw, MARK_ALL_LAYERS, MARK_ALL, False, True); sf = get_focus_window(); if (sf && IS_IN_TRANSIENT_SUBTREE(sf)) { restore_focus_after_unmap(sf, True); /* restore_focus_after_unmap() destorys the flags set by * mark_transient_subtree(), so we have to unfortunately call * it again. */ mark_transient_subtree( fw, MARK_ALL_LAYERS, MARK_ALL, False, True); } /* iconify transients first */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (t == fw || IS_IN_TRANSIENT_SUBTREE(t)) { SET_IN_TRANSIENT_SUBTREE(t, 0); SET_ICON_ENTERED(t, 0); /* Prevent the receipt of an UnmapNotify, since that * would cause a transition to the Withdrawn state. */ SET_MAPPED(t, 0); XSelectInput( dpy, FW_W(t), eventMask & ~StructureNotifyMask); XUnmapWindow(dpy, FW_W(t)); XSelectInput(dpy, FW_W(t), eventMask); XUnmapWindow(dpy, FW_W_FRAME(t)); border_undraw_decorations(t); t->DeIconifyDesk = t->Desk; if (FW_W_ICON_TITLE(t)) { XUnmapWindow(dpy, FW_W_ICON_TITLE(t)); } if (FW_W_ICON_PIXMAP(t)) { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(t)); } SetMapStateProp(t, IconicState); border_draw_decorations( t, PART_ALL, False, False, CLEAR_ALL, NULL, NULL); if (t == fw && !IS_ICONIFIED_BY_PARENT(fw)) { SET_ICONIFY_PENDING(t, 1); } else { rectangle g; SET_ICONIFIED(t, 1); SET_ICON_UNMAPPED(t, 1); SET_ICONIFIED_BY_PARENT(t, 1); get_icon_geometry(t, &g); BroadcastPacket( M_ICONIFY, 7, (long)FW_W(t), (long)FW_W_FRAME(t), (unsigned long)t, (long)-32768, (long)-32768, (long)g.width, (long)g.height); BroadcastConfig(M_CONFIGURE_WINDOW,t); } } /* if */ } /* for */ /* necessary during a recapture */ if (IS_ICONIFIED_BY_PARENT(fw)) { return; } if (FW_W_ICON_TITLE(fw) == None || HAS_ICON_CHANGED(fw)) { if (IS_ICON_MOVED(fw) || win_opts->flags.use_initial_icon_xy) { rectangle g; get_icon_geometry(fw, &g); if (win_opts->flags.use_initial_icon_xy) { g.x = win_opts->initial_icon_x; g.y = win_opts->initial_icon_y; } CreateIconWindow(fw, g.x, g.y); } else { CreateIconWindow( fw, win_opts->default_icon_x, win_opts->default_icon_y); } SET_HAS_ICON_CHANGED(fw, 0); } else if (FW_W_ICON_TITLE(fw) && !FW_W_ICON_PIXMAP(fw)) { /* if no pixmap we want icon width to change to text width * every iconify; not necessary if the icon was created above */ setup_icon_title_size(fw); } /* this condition will be true unless we restore a window to * iconified state from a saved session. */ if (win_opts->initial_state != IconicState || (!IS_ICON_MOVED(fw) && !win_opts->flags.use_initial_icon_xy)) { AutoPlaceIcon(fw, win_opts, True); } /* domivogt (12-Mar-2003): Clean out the icon geometry if there is no * icon. Necessary to initialise the values and to suppress animation * if there is no icon. */ if (HAS_NO_ICON_TITLE(fw) && FW_W_ICON_PIXMAP(fw) == None) { clear_icon_dimensions(fw); } SET_ICONIFIED(fw, 1); SET_ICON_UNMAPPED(fw, 0); get_icon_geometry(fw, &icon_rect); /* if this fails it does not overwrite icon_rect */ EWMH_GetIconGeometry(fw, &icon_rect); BroadcastPacket( M_ICONIFY, 11, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw, (long)icon_rect.x, (long)icon_rect.y, (long)icon_rect.width, (long)icon_rect.height, /* next 4 added for Animate module */ (long)fw->g.frame.x, (long)fw->g.frame.y, (long)fw->g.frame.width, (long)fw->g.frame.height); BroadcastConfig(M_CONFIGURE_WINDOW,fw); if (win_opts->initial_state != IconicState || (!IS_ICON_MOVED(fw) && !win_opts->flags.use_initial_icon_xy)) { LowerWindow(fw, False); } if (IS_ICON_STICKY_ACROSS_DESKS(fw) || IS_STICKY_ACROSS_DESKS(fw)) { fw->Desk = Scr.CurrentDesk; } if (fw->Desk == Scr.CurrentDesk) { if (FW_W_ICON_TITLE(fw) != None) { XMapWindow(dpy, FW_W_ICON_TITLE(fw)); } if (FW_W_ICON_PIXMAP(fw) != None) { XMapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } } focus_grab_buttons_on_layer(fw->layer); return; } /* * * This is used to tell applications which windows on the screen are * top level appication windows, and which windows are the icon windows * that go with them. * */ void SetMapStateProp(const FvwmWindow *fw, int state) { /* "suggested" by ICCCM version 1 */ unsigned long data[2]; data[0] = (unsigned long) state; data[1] = (unsigned long) FW_W_ICON_TITLE(fw); /* data[2] = (unsigned long) FW_W_ICON_PIXMAP(fw);*/ XChangeProperty( dpy, FW_W(fw), _XA_WM_STATE, _XA_WM_STATE, 32, PropModeReplace, (unsigned char *) data, 2); return; } void CMD_Iconify(F_CMD_ARGS) { int toggle; FvwmWindow * const fw = exc->w.fw; toggle = ParseToggleArgument(action, NULL, -1, 0); if (toggle == -1) { if (GetIntegerArguments(action, NULL, &toggle, 1) > 0) { if (toggle > 0) { toggle = 1; } else if (toggle < 0) { toggle = 0; } else { toggle = -1; } } } if (toggle == -1) { toggle = (IS_ICONIFIED(fw)) ? 0 : 1; } if (IS_ICONIFIED(fw)) { if (toggle == 0) { DeIconify(fw); EWMH_SetWMState(fw, False); } } else { if (toggle == 1) { initial_window_options_t win_opts; if ( !is_function_allowed( F_ICONIFY, NULL, fw, RQORIG_PROGRAM, True)) { XBell(dpy, 0); return; } memset(&win_opts, 0, sizeof(win_opts)); fev_get_evpos_or_query( dpy, Scr.Root, NULL, &win_opts.default_icon_x, &win_opts.default_icon_y); Iconify(fw, &win_opts); EWMH_SetWMState(fw, False); } } return; } fvwm-2.6.7/fvwm/ewmh_icons.c0000644000175700017570000004302313001406607012721 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ /* 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 #include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/PictureBase.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/PictureImageLoader.h" #include "libs/FRenderInit.h" #include "libs/Graphics.h" #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" #include "window_flags.h" #include "cursor.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "module_interface.h" #include "borders.h" #include "icons.h" #include "ewmh.h" #include "ewmh_intern.h" /* * net icon handler */ int ewmh_WMIcon( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { CARD32 *list = NULL; CARD32 *new_list = NULL; CARD32 *dummy = NULL; int size = 0; if (ev != NULL && HAS_EWMH_WM_ICON_HINT(fw) == EWMH_FVWM_ICON) { /* this event has been produced by fvwm itself */ return 0; } list = ewmh_AtomGetByName(FW_W(fw),"_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); if (list != NULL && HAS_EWMH_WM_ICON_HINT(fw) == EWMH_NO_ICON) { /* the application have a true _NET_WM_ICON */ SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_TRUE_ICON); } if (list == NULL || HAS_EWMH_WM_ICON_HINT(fw) != EWMH_TRUE_ICON) { /* No net icon or we have set the net icon */ if (DO_EWMH_DONATE_ICON(fw) && (new_list = ewmh_SetWmIconFromPixmap( fw, list, &size, False)) != NULL) { SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_FVWM_ICON); } } else if (ev != NULL && USE_EWMH_ICON(fw)) { /* client message. the application change its net icon */ ChangeIconPixmap(fw); } if (FMiniIconsSupported) { if (list == NULL || HAS_EWMH_WM_ICON_HINT(fw) != EWMH_TRUE_ICON) { /* No net icon or we have set the net icon */ if (DO_EWMH_DONATE_MINI_ICON(fw) && (dummy = ewmh_SetWmIconFromPixmap( fw, (new_list != NULL)? new_list : list, &size, True)) != NULL) { SET_HAS_EWMH_WM_ICON_HINT( fw, EWMH_FVWM_ICON); free(dummy); } } else { /* the application has a true ewmh icon */ if (EWMH_SetIconFromWMIcon(fw, list, size, True)) { SET_HAS_EWMH_MINI_ICON(fw, True); } } } if (list != NULL) { free(list); } if (new_list != NULL) { free(new_list); } return 0; } /* * update */ void EWMH_DoUpdateWmIcon(FvwmWindow *fw, Bool mini_icon, Bool icon) { CARD32 *list = NULL; CARD32 *new_list = NULL; CARD32 *dummy = NULL; int size = 0; Bool icon_too = False; if (HAS_EWMH_WM_ICON_HINT(fw) == EWMH_TRUE_ICON) { return; } /* first see if we have to delete */ if (FMiniIconsSupported && mini_icon && !DO_EWMH_DONATE_MINI_ICON(fw)) { if (icon && !DO_EWMH_DONATE_ICON(fw)) { icon_too = True; } EWMH_DeleteWmIcon(fw, True, icon_too); } if (!icon_too && icon && !DO_EWMH_DONATE_ICON(fw)) { EWMH_DeleteWmIcon(fw, False, True); } /* now set if needed */ if ((mini_icon && DO_EWMH_DONATE_MINI_ICON(fw)) || (icon && DO_EWMH_DONATE_ICON(fw))) { list = ewmh_AtomGetByName( FW_W(fw),"_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); } else { return; } /* we have to reset */ if (icon && DO_EWMH_DONATE_ICON(fw)) { if ((new_list = ewmh_SetWmIconFromPixmap( fw, list, &size, False)) != NULL) { SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_FVWM_ICON); } } if (FMiniIconsSupported && mini_icon && DO_EWMH_DONATE_MINI_ICON(fw)) { if ((dummy = ewmh_SetWmIconFromPixmap( fw, (new_list != NULL)? new_list : list, &size, True)) != NULL) { SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_FVWM_ICON); free(dummy); } } if (list != NULL) { free(list); } if (new_list != NULL) { free(new_list); } } /* * build and set a net icon from a pixmap */ CARD32 *ewmh_SetWmIconFromPixmap( FvwmWindow *fw, CARD32 *orig_icon, int *orig_size, Bool is_mini_icon) { CARD32 *new_icon = NULL; int keep_start = 0, keep_length = 0; int width = 0, height = 0; int i,j,k,l,m; int s; Pixmap pixmap = None; Pixmap mask = None; Pixmap alpha = None; XImage *image; XImage *m_image = NULL; XImage *a_image = NULL; int save_picture_w_g_width = 0; int save_picture_w_g_height = 0; int save_icon_depth = 0; Pixmap save_icon_pixmap = None; Pixmap save_icon_mask = None; Pixmap save_icon_alpha = None; int save_icon_nalloc_pixels = 0; Pixel *save_icon_alloc_pixels = NULL; int save_icon_no_limit = 0; Window save_icon_pixmap_w = None; Bool is_pixmap_ours = False; Bool is_icon_ours = False; Bool is_icon_shaped = False; Bool destroy_icon_pix = False; s = *orig_size / sizeof(CARD32); *orig_size = 0; if (is_mini_icon) { if (FMiniIconsSupported && fw->mini_icon != NULL) { pixmap = fw->mini_icon->picture; mask = fw->mini_icon->mask; alpha = fw->mini_icon->alpha; width = fw->mini_icon->width; height = fw->mini_icon->height; } } else { /* should save and restore any iformation modified by * a call to GetIconPicture */ save_picture_w_g_width = fw->icon_g.picture_w_g.width; save_picture_w_g_height = fw->icon_g.picture_w_g.height; save_icon_depth = fw->iconDepth; save_icon_pixmap = fw->iconPixmap; save_icon_mask = fw->icon_maskPixmap; save_icon_alpha = fw->icon_alphaPixmap; save_icon_nalloc_pixels = fw->icon_nalloc_pixels; save_icon_alloc_pixels = fw->icon_alloc_pixels; save_icon_no_limit = fw->icon_no_limit; save_icon_pixmap_w = FW_W_ICON_PIXMAP(fw); is_pixmap_ours = IS_PIXMAP_OURS(fw); is_icon_ours = IS_ICON_OURS(fw); is_icon_shaped = IS_ICON_SHAPED(fw); GetIconPicture(fw, True); if (IS_PIXMAP_OURS(fw)) { destroy_icon_pix = True; } pixmap = fw->iconPixmap; mask = fw->icon_maskPixmap; alpha = fw->icon_alphaPixmap; width = fw->icon_g.picture_w_g.width; height = fw->icon_g.picture_w_g.height; if (fw->icon_alloc_pixels != NULL) { if (fw->icon_nalloc_pixels != 0) { PictureFreeColors( dpy, Pcmap, fw->icon_alloc_pixels, fw->icon_nalloc_pixels, 0, fw->icon_no_limit); } free(fw->icon_alloc_pixels); } fw->icon_g.picture_w_g.width = save_picture_w_g_width; fw->icon_g.picture_w_g.height = save_picture_w_g_height; fw->iconDepth = save_icon_depth; fw->iconPixmap = save_icon_pixmap; fw->icon_maskPixmap = save_icon_mask; fw->icon_alphaPixmap = save_icon_alpha; fw->icon_nalloc_pixels = save_icon_nalloc_pixels; fw->icon_alloc_pixels = save_icon_alloc_pixels; fw->icon_no_limit = save_icon_no_limit; FW_W_ICON_PIXMAP(fw) = save_icon_pixmap_w; SET_ICON_OURS(fw, is_icon_ours); SET_PIXMAP_OURS(fw, is_pixmap_ours); SET_ICON_SHAPED(fw, is_icon_shaped); } if (pixmap == None) { return NULL; } if (FMiniIconsSupported && orig_icon != NULL) { int k_width = (is_mini_icon)? fw->ewmh_icon_width : fw->ewmh_mini_icon_width; int k_height = (is_mini_icon)? fw->ewmh_icon_height : fw->ewmh_mini_icon_height; for (i = 0; i < s - 1 && i >= 0; ) { if (i + 1 + orig_icon[i]*orig_icon[i+1] < s) { if (orig_icon[i] == k_width && orig_icon[i+1] == k_height) { keep_start = i; keep_length = 2 + orig_icon[i] * orig_icon[i+1]; i = s; } } if (i != s && orig_icon[i]*orig_icon[i+1] > 0) { i = i + 2 + orig_icon[i]*orig_icon[i+1]; } else { i = s; } } } image = XGetImage( dpy, pixmap, 0, 0, width, height, AllPlanes, ZPixmap); if (image == NULL) { fvwm_msg( ERR, "EWMH_SetWmIconFromPixmap", "cannot create XImage\n"); if (destroy_icon_pix) { XFreePixmap(dpy, pixmap); if (mask != None) { XFreePixmap(dpy, mask); } if (alpha != None) { XFreePixmap(dpy, alpha); } } return NULL; } if (mask != None) { m_image = XGetImage(dpy, mask, 0, 0, width, height, AllPlanes, ZPixmap); } if (alpha != None) { a_image = XGetImage(dpy, alpha, 0, 0, width, height, AllPlanes, ZPixmap); } *orig_size = (height*width + 2 + keep_length) * sizeof(CARD32); new_icon = (CARD32 *)safemalloc(*orig_size); if (keep_length > 0) { memcpy(new_icon, &orig_icon[keep_start], keep_length * sizeof(CARD32)); } new_icon[keep_length] = width; new_icon[1+keep_length] = height; k = 0; l = (2 + keep_length); m = 0; switch(image->depth) { case 1: { XColor colors[2]; CARD32 fg, bg; colors[0].pixel = fw->colors.fore; colors[1].pixel = fw->colors.back; XQueryColors(dpy, Pcmap, colors, 2); fg = 0xff000000 + (((colors[0].red >> 8) & 0xff) << 16) + (((colors[0].green >> 8) & 0xff) << 8) + ((colors[0].blue >> 8) & 0xff); bg = 0xff000000 + (((colors[1].red >> 8) & 0xff) << 16) + (((colors[1].green >> 8) & 0xff) << 8) + ((colors[1].blue >> 8) & 0xff); for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { if (m_image != NULL && (XGetPixel(m_image, i, j) == 0)) { new_icon[l++] = 0; } else if (XGetPixel(image, i, j) == 0) { new_icon[l++] = bg; } else { new_icon[l++] = fg; } } } break; } default: /* depth = Pdepth */ { unsigned char *cm; XColor *colors; colors = (XColor *)safemalloc(width * height * sizeof(XColor)); cm = (unsigned char *)safemalloc( width * height * sizeof(char)); for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { if (m_image != NULL && (XGetPixel(m_image, i, j) == 0)) { cm[m++] = 0; } else if (a_image != NULL) { cm[m++] = (unsigned char)XGetPixel( a_image, i, j); colors[k++].pixel = XGetPixel( image, i, j); } else { cm[m++] = 255; colors[k++].pixel = XGetPixel( image, i, j); } } } for (i = 0; i < k; i += 256) XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256)); k = 0;m = 0; for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { if (cm[m] > 0) { new_icon[l++] = ((cm[m] & 0xff) << 24) + (((colors[k].red >> 8) & 0xff) << 16) + (((colors[k].green >> 8) & 0xff) << 8) + ((colors[k].blue >> 8) & 0xff); k++; } else { new_icon[l++] = 0; } m++; } } free(colors); free(cm); break; } } /* switch */ if (is_mini_icon) { fw->ewmh_mini_icon_width = width; fw->ewmh_mini_icon_height = height; } else { fw->ewmh_icon_width = width; fw->ewmh_icon_height = height; } ewmh_ChangeProperty( FW_W(fw), "_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, (unsigned char *)new_icon, height*width + 2 + keep_length); if (destroy_icon_pix) { XFreePixmap(dpy, pixmap); if (mask != None) { XFreePixmap(dpy, mask); } if (alpha != None) { XFreePixmap(dpy, alpha); } } XDestroyImage(image); if (m_image != None) { XDestroyImage(m_image); } if (a_image != None) { XDestroyImage(a_image); } return new_icon; } /* * delete the mini icon and/or the icon from a ewmh icon */ void EWMH_DeleteWmIcon(FvwmWindow *fw, Bool mini_icon, Bool icon) { CARD32 *list; CARD32 *new_list = NULL; int keep_start = 0, keep_length = 0; int s; int i; if (mini_icon && icon) { ewmh_DeleteProperty( FW_W(fw), "_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY); fw->ewmh_mini_icon_width = 0; fw->ewmh_mini_icon_height = 0; fw->ewmh_icon_width = 0; fw->ewmh_icon_height = 0; /*SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_NO_ICON);*/ return; } list = ewmh_AtomGetByName( FW_W(fw),"_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &s); if (list == NULL) { return; } s = s / sizeof(CARD32); if (FMiniIconsSupported && list != NULL) { int k_width = (mini_icon) ? fw->ewmh_icon_width : fw->ewmh_mini_icon_width; int k_height = (mini_icon) ? fw->ewmh_icon_height : fw->ewmh_mini_icon_height; for (i = 0; i < s - 1; ) { if (i + 1 + list[i]*list[i+1] < s) { if (list[i] == k_width && list[i+1] == k_height) { keep_start = i; keep_length = 2 + list[i]*list[i+1]; i = s; } } if (i != s && list[i]*list[i+1] > 0) { i = i + 2 + list[i]*list[i+1]; } else { i = s; } } } if (keep_length > 0) { new_list = (CARD32 *)safemalloc(keep_length * sizeof(CARD32)); memcpy( new_list, &list[keep_start], keep_length * sizeof(CARD32)); } if (new_list != NULL) { ewmh_ChangeProperty( FW_W(fw),"_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, (unsigned char *)new_list, keep_length); } else { /*SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_NO_ICON);*/ ewmh_DeleteProperty( FW_W(fw), "_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY); } if (mini_icon) { fw->ewmh_mini_icon_width = 0; fw->ewmh_mini_icon_height = 0; } if (icon) { fw->ewmh_icon_width = 0; fw->ewmh_icon_height = 0; } if (new_list != NULL) { free(new_list); } free(list); } /* * Create an x image from a NET icon */ #define SQUARE(X) ((X)*(X)) static void extract_wm_icon( CARD32 *list, int size, int wanted_w, int wanted_h, int *start_best, int *best_w, int *best_h) { int i; int dist = 0; *start_best = 0; *best_w = 0; *best_h = 0; size = size / (sizeof(CARD32)); for (i = 0; i < size - 1; ) { if (i + 1 + list[i]*list[i+1] < size) { if (*best_w == 0 && *best_h == 0) { *start_best = i+2; *best_w = list[i]; *best_h = list[i+1]; dist = SQUARE( list[i]-wanted_w) + SQUARE(list[i+1]-wanted_h); } else if (SQUARE(list[i]-wanted_w) + SQUARE(list[i+1]-wanted_h) < dist) { *start_best = i+2; *best_w = list[i]; *best_h = list[i+1]; dist = SQUARE( list[i]-wanted_w) + SQUARE(list[i+1]-wanted_h); } } if (list[i]*list[i+1] > 0) { i = i + 2 + list[i]*list[i+1]; } else { i = size; } } return; } #define MINI_ICON_WANTED_WIDTH 16 #define MINI_ICON_WANTED_HEIGHT 16 #define MINI_ICON_MAX_WIDTH 22 #define MINI_ICON_MAX_HEIGHT 22 #define ICON_WANTED_WIDTH 56 #define ICON_WANTED_HEIGHT 56 #define ICON_MAX_WIDTH 100 #define ICON_MAX_HEIGHT 100 int EWMH_SetIconFromWMIcon( FvwmWindow *fw, CARD32 *list, int size, Bool is_mini_icon) { int start, width, height; int wanted_w, wanted_h; int max_w, max_h; Pixmap pixmap = None; Pixmap mask = None; Pixmap alpha = None; Bool free_list = False; int nalloc_pixels; Pixel *alloc_pixels; int no_limit; FvwmPictureAttributes fpa; if (list == NULL) { /* we are called from icons.c or update.c */ list = ewmh_AtomGetByName( FW_W(fw),"_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); free_list = True; if (list == NULL) { return 0; } } if (is_mini_icon) { wanted_w = MINI_ICON_WANTED_WIDTH; wanted_h = MINI_ICON_WANTED_HEIGHT; max_w = MINI_ICON_MAX_WIDTH; max_h = ICON_MAX_HEIGHT; fpa.mask = 0; } else { wanted_w = ICON_WANTED_WIDTH; wanted_h = ICON_WANTED_HEIGHT; max_w = ICON_MAX_WIDTH; max_h = ICON_MAX_HEIGHT; if (fw->cs >= 0 && Colorset[fw->cs].do_dither_icon) { fpa.mask = FPAM_DITHER; } else { fpa.mask = 0; } } extract_wm_icon( list, size, wanted_w, wanted_h, &start, &width, &height); if (width == 0 || height == 0) { if (free_list) { free(list); } return 0; } if (!PImageCreatePixmapFromArgbData( dpy, Scr.NoFocusWin, list, start, width, height, &pixmap, &mask, &alpha, &nalloc_pixels, &alloc_pixels, &no_limit, fpa)) { fvwm_msg(ERR, "EWMH_SetIconFromWMIcon", "fail to create a pixmap\n"); if (free_list) { free(list); } return 0; } if (width > max_w || height > max_h) { Pixmap np = None,nm =None, na = None; if (pixmap) { np = CreateStretchPixmap( dpy, pixmap, width, height, Pdepth, wanted_w, wanted_h, Scr.TitleGC); XFreePixmap(dpy, pixmap); pixmap = np; } if (mask) { nm = CreateStretchPixmap( dpy, mask, width, height, 1, wanted_w, wanted_h, Scr.MonoGC); XFreePixmap(dpy, mask); mask = nm; } if (alpha) { na = CreateStretchPixmap( dpy, alpha, width, height, FRenderGetAlphaDepth(), wanted_w, wanted_h, Scr.AlphaGC); XFreePixmap(dpy, alpha); alpha = na; } width = wanted_w; height = wanted_h; } if (FMiniIconsSupported && is_mini_icon && !DO_EWMH_MINI_ICON_OVERRIDE(fw)) { char *name = NULL; CopyString(&name,"ewmh_mini_icon"); if (fw->mini_icon) { PDestroyFvwmPicture(dpy,fw->mini_icon); fw->mini_icon = 0; } fw->mini_icon = PCacheFvwmPictureFromPixmap( dpy, Scr.NoFocusWin, name, pixmap,mask,alpha, width, height, nalloc_pixels, alloc_pixels, no_limit); if (fw->mini_icon != NULL) { fw->mini_pixmap_file = name; BroadcastFvwmPicture( M_MINI_ICON, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, fw->mini_icon, fw->mini_pixmap_file); border_redraw_decorations(fw); } } if (!is_mini_icon) { fw->iconPixmap = pixmap; fw->icon_maskPixmap = mask; fw->icon_alphaPixmap = alpha; fw->icon_nalloc_pixels = nalloc_pixels; fw->icon_alloc_pixels = alloc_pixels; fw->icon_no_limit = no_limit; fw->icon_g.picture_w_g.width = width; fw->icon_g.picture_w_g.height = height; fw->iconDepth = Pdepth; SET_PIXMAP_OURS(fw, 1); if (FShapesSupported && mask) { SET_ICON_SHAPED(fw, 1); } } if (free_list) { free(list); } return 1; } fvwm-2.6.7/fvwm/menuroot.h0000644000175700017570000001435212773467232012466 00000000000000/* -*-c-*- */ #ifndef MENU_ROOT_H #define MENU_ROOT_H /* ---------------------------- included header files ---------------------- */ /* Do not #include any files - the file including this file has to take care of * it. */ /* ---------------------------- forward declarations ----------------------- */ struct MenuItem; struct MenuStyle; /* ---------------------------- type definitions --------------------------- */ /* * MENU ROOT STRUCTURES */ /* This struct contains the parts of a root menu that are shared among all * copies of the menu */ typedef struct MenuRootStatic { /* first item in menu */ struct MenuItem *first; /* last item in menu */ struct MenuItem *last; /* # of copies, 0 if none except this one */ int copies; /* # of mapped instances */ int usage_count; /* name of root */ char *name; struct MenuDimensions dim; int items; FvwmPicture *sidePic; Pixel sideColor; int used_mini_icons; /* Menu Face */ struct MenuStyle *ms; /* permanent flags */ struct { unsigned has_side_color : 1; unsigned is_left_triangle : 1; unsigned is_updated : 1; } flags; struct { char *popup_action; char *popdown_action; char *missing_submenu_func; } dynamic; } MenuRootStatic; /* access macros to static menu members */ #define MR_FIRST_ITEM(m) ((m)->s->first) #define MR_LAST_ITEM(m) ((m)->s->last) #define MR_COPIES(m) ((m)->s->copies) #define MR_MAPPED_COPIES(m) ((m)->s->usage_count) #define MR_NAME(m) ((m)->s->name) #define MR_DIM(m) ((m)->s->dim) #define MR_WIDTH(m) MDIM_WIDTH((m)->s->dim) #define MR_HEIGHT(m) MDIM_HEIGHT((m)->s->dim) #define MR_ITEM_WIDTH(m) MDIM_ITEM_WIDTH((m)->s->dim) #define MR_SIDEPIC_X_OFFSET(m) MDIM_SIDEPIC_X_OFFSET((m)->s->dim) #define MR_ICON_X_OFFSET(m) MDIM_ICON_X_OFFSET((m)->s->dim) #define MR_TRIANGLE_X_OFFSET(m) MDIM_TRIANGLE_X_OFFSET((m)->s->dim) #define MR_ITEM_X_OFFSET(m) MDIM_ITEM_X_OFFSET((m)->s->dim) #define MR_ITEM_TEXT_Y_OFFSET(m) MDIM_ITEM_TEXT_Y_OFFSET((m)->s->dim) #define MR_HILIGHT_X_OFFSET(m) MDIM_HILIGHT_X_OFFSET((m)->s->dim) #define MR_HILIGHT_WIDTH(m) MDIM_HILIGHT_WIDTH((m)->s->dim) #define MR_SCREEN_WIDTH(m) MDIM_SCREEN_WIDTH((m)->s->dim) #define MR_SCREEN_HEIGHT(m) MDIM_SCREEN_HEIGHT((m)->s->dim) #define MR_ITEMS(m) ((m)->s->items) #define MR_SIDEPIC(m) ((m)->s->sidePic) #define MR_SIDECOLOR(m) ((m)->s->sideColor) #define MR_USED_MINI_ICONS(m) ((m)->s->used_mini_icons) #define MR_STYLE(m) ((m)->s->ms) /* flags */ #define MR_FLAGS(m) ((m)->s->flags) #define MR_POPUP_ACTION(m) ((m)->s->dynamic.popup_action) #define MR_POPDOWN_ACTION(m) ((m)->s->dynamic.popdown_action) #define MR_MISSING_SUBMENU_FUNC(m) ((m)->s->dynamic.missing_submenu_func) #define MR_HAS_SIDECOLOR(m) ((m)->s->flags.has_side_color) #define MR_IS_LEFT_TRIANGLE(m) ((m)->s->flags.is_left_triangle) #define MR_IS_UPDATED(m) ((m)->s->flags.is_updated) /* This struct contains the parts of a root menu that differ in all copies of * the menu */ typedef struct MenuRootDynamic { /* the first copy of the current menu */ struct MenuRoot *original_menu; /* next in list of root menus */ struct MenuRoot *next_menu; /* continuation of this menu (too tall for screen) */ struct MenuRoot *continuation_menu; /* can get the menu that this popped up through selected_item->mr when * selected is a popup menu item */ /* the menu that popped this up, if any */ struct MenuRoot *parent_menu; /* the menu item that popped this up, if any */ struct MenuItem *parent_item; /* the display used to create the menu. Can't use the normal display * because 'xkill' would kill the window manager if used on a tear off * menu. */ Display *create_dpy; /* the window of the menu */ Window window; /* the selected item in menu */ struct MenuItem *selected_item; /* item that has it's submenu mapped */ struct MenuItem *submenu_item; /* x distance window was moved by animation */ int xanimation; /* dynamic temp flags */ struct { /* is win background set? */ unsigned is_background_set : 1; unsigned is_destroyed : 1; /* menu direction relative to parent menu */ unsigned is_left : 1; unsigned is_right : 1; unsigned is_up : 1; unsigned is_down : 1; unsigned is_painted : 1; unsigned is_tear_off_menu : 1; unsigned has_popped_up_left : 1; unsigned has_popped_up_right : 1; } dflags; struct { Pixmap stored; int width; int height; int y; } stored_item; struct { Pixel *d_pixels; int d_npixels; } stored_pixels; /* alloc pixels when dithering is used for gradients */ } MenuRootDynamic; /* access macros to dynamic menu members */ #define MR_ORIGINAL_MENU(m) ((m)->d->original_menu) #define MR_NEXT_MENU(m) ((m)->d->next_menu) #define MR_CONTINUATION_MENU(m) ((m)->d->continuation_menu) #define MR_PARENT_MENU(m) ((m)->d->parent_menu) #define MR_PARENT_ITEM(m) ((m)->d->parent_item) #define MR_CREATE_DPY(m) ((m)->d->create_dpy) #define MR_WINDOW(m) ((m)->d->window) #define MR_SELECTED_ITEM(m) ((m)->d->selected_item) #define MR_SUBMENU_ITEM(m) ((m)->d->submenu_item) #define MR_XANIMATION(m) ((m)->d->xanimation) #define MR_STORED_ITEM(m) ((m)->d->stored_item) #define MR_STORED_PIXELS(m) ((m)->d->stored_pixels) /* flags */ #define MR_DYNAMIC_FLAGS(m) ((m)->d->dflags) #define MR_IS_BACKGROUND_SET(m) ((m)->d->dflags.is_background_set) #define MR_IS_DESTROYED(m) ((m)->d->dflags.is_destroyed) #define MR_IS_LEFT(m) ((m)->d->dflags.is_left) #define MR_IS_RIGHT(m) ((m)->d->dflags.is_right) #define MR_IS_UP(m) ((m)->d->dflags.is_up) #define MR_IS_DOWN(m) ((m)->d->dflags.is_down) #define MR_IS_PAINTED(m) ((m)->d->dflags.is_painted) #define MR_IS_TEAR_OFF_MENU(m) ((m)->d->dflags.is_tear_off_menu) #define MR_HAS_POPPED_UP_LEFT(m) ((m)->d->dflags.has_popped_up_left) #define MR_HAS_POPPED_UP_RIGHT(m) ((m)->d->dflags.has_popped_up_right) typedef struct MenuRoot { MenuRootStatic *s; MenuRootDynamic *d; } MenuRoot; /* don't forget to initialise new members in NewMenuRoot()! */ #endif /* MENU_ROOT_H */ fvwm-2.6.7/fvwm/menustyle.h0000644000175700017570000003347712773467232012654 00000000000000/* -*-c-*- */ #ifndef MENUSTYLE_H #define MENUSTYLE_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ #define ST_NAME(s) ((s)->name) #define MST_NAME(m) ((m)->s->ms->name) #define ST_NEXT_STYLE(s) ((s)->next_style) #define MST_NEXT_STYLE(m) ((m)->s->ms->next_style) #define ST_USAGE_COUNT(s) ((s)->usage_count) #define MST_USAGE_COUNT(m) ((m)->s->ms->usage_count) /* flags */ #define ST_IS_UPDATED(s) ((s)->flags.is_updated) #define MST_IS_UPDATED(m) ((m)->s->ms->flags.is_updated) /* look */ #define ST_FACE(s) ((s)->look.face) #define MST_FACE(m) ((m)->s->ms->look.face) #define ST_DO_HILIGHT_BACK(s) ((s)->look.flags.do_hilight_back) #define MST_DO_HILIGHT_BACK(m) ((m)->s->ms->look.flags.do_hilight_back) #define ST_DO_HILIGHT_FORE(s) ((s)->look.flags.do_hilight_fore) #define MST_DO_HILIGHT_FORE(m) ((m)->s->ms->look.flags.do_hilight_fore) #define ST_DO_HILIGHT_TITLE_BACK(s) ((s)->look.flags.do_hilight_title_back) #define MST_DO_HILIGHT_TITLE_BACK(m) \ ((m)->s->ms->look.flags.do_hilight_title_back) #define ST_HAS_ACTIVE_FORE(s) ((s)->look.flags.has_active_fore) #define MST_HAS_ACTIVE_FORE(m) ((m)->s->ms->look.flags.has_active_fore) #define ST_HAS_ACTIVE_BACK(s) ((s)->look.flags.has_active_back) #define MST_HAS_ACTIVE_BACK(m) ((m)->s->ms->look.flags.has_active_back) #define ST_HAS_STIPPLE_FORE(s) ((s)->look.flags.has_stipple_fore) #define MST_HAS_STIPPLE_FORE(m) ((m)->s->ms->look.flags.has_stipple_fore) #define ST_HAS_LONG_SEPARATORS(s) ((s)->look.flags.has_long_separators) #define MST_HAS_LONG_SEPARATORS(m) \ ((m)->s->ms->look.flags.has_long_separators) #define ST_HAS_TRIANGLE_RELIEF(s) ((s)->look.flags.has_triangle_relief) #define MST_HAS_TRIANGLE_RELIEF(m) \ ((m)->s->ms->look.flags.has_triangle_relief) #define ST_HAS_SIDE_COLOR(s) ((s)->look.flags.has_side_color) #define MST_HAS_SIDE_COLOR(m) ((m)->s->ms->look.flags.has_side_color) #define ST_HAS_MENU_CSET(s) ((s)->look.flags.has_menu_cset) #define MST_HAS_MENU_CSET(m) ((m)->s->ms->look.flags.has_menu_cset) #define ST_HAS_ACTIVE_CSET(s) ((s)->look.flags.has_active_cset) #define MST_HAS_ACTIVE_CSET(m) ((m)->s->ms->look.flags.has_active_cset) #define ST_HAS_GREYED_CSET(s) ((s)->look.flags.has_greyed_cset) #define MST_HAS_GREYED_CSET(m) ((m)->s->ms->look.flags.has_greyed_cset) #define ST_HAS_TITLE_CSET(s) ((s)->look.flags.has_title_cset) #define MST_HAS_TITLE_CSET(m) ((m)->s->ms->look.flags.has_title_cset) #define ST_IS_ITEM_RELIEF_REVERSED(s) ((s)->look.flags.is_item_relief_reversed) #define MST_IS_ITEM_RELIEF_REVERSED(m) \ ((m)->s->ms->look.flags.is_item_relief_reversed) #define ST_USING_DEFAULT_FONT(s) ((s)->look.flags.using_default_font) #define MST_USING_DEFAULT_FONT(m) \ ((m)->s->ms->look.flags.using_default_font) #define ST_USING_DEFAULT_TITLEFONT(s) ((s)->look.flags.using_default_titlefont) #define MST_USING_DEFAULT_TITLEFONT(m) \ ((m)->s->ms->look.flags.using_default_titlefont) #define ST_TRIANGLES_USE_FORE(s) ((s)->look.flags.triangles_use_fore) #define MST_TRIANGLES_USE_FORE(m) \ ((m)->s->ms->look.flags.triangles_use_fore) #define ST_RELIEF_THICKNESS(s) ((s)->look.ReliefThickness) #define MST_RELIEF_THICKNESS(m) ((m)->s->ms->look.ReliefThickness) #define ST_TITLE_UNDERLINES(s) ((s)->look.TitleUnderlines) #define MST_TITLE_UNDERLINES(m) ((m)->s->ms->look.TitleUnderlines) #define ST_BORDER_WIDTH(s) ((s)->look.BorderWidth) #define MST_BORDER_WIDTH(m) ((m)->s->ms->look.BorderWidth) #define ST_ITEM_GAP_ABOVE(s) ((s)->look.vertical_spacing.item_above) #define MST_ITEM_GAP_ABOVE(m) \ ((m)->s->ms->look.vertical_spacing.item_above) #define ST_ITEM_GAP_BELOW(s) ((s)->look.vertical_spacing.item_below) #define MST_ITEM_GAP_BELOW(m) \ ((m)->s->ms->look.vertical_spacing.item_below) #define ST_TITLE_GAP_ABOVE(s) ((s)->look.vertical_spacing.title_above) #define MST_TITLE_GAP_ABOVE(m) \ ((m)->s->ms->look.vertical_spacing.title_above) #define ST_TITLE_GAP_BELOW(s) ((s)->look.vertical_spacing.title_below) #define MST_TITLE_GAP_BELOW(m) \ ((m)->s->ms->look.vertical_spacing.title_below) #define ST_SEPARATOR_GAP_ABOVE(s) \ ((s)->look.vertical_spacing.separator_above) #define MST_SEPARATOR_GAP_ABOVE(m) \ ((m)->s->ms->look.vertical_spacing.separator_above) #define ST_SEPARATOR_GAP_BELOW(s) \ ((s)->look.vertical_spacing.separator_below) #define MST_SEPARATOR_GAP_BELOW(m) \ ((m)->s->ms->look.vertical_spacing.separator_below) #define ST_CSET_MENU(s) ((s)->look.cset.menu) #define MST_CSET_MENU(m) ((m)->s->ms->look.cset.menu) #define ST_CSET_ACTIVE(s) ((s)->look.cset.active) #define MST_CSET_ACTIVE(m) ((m)->s->ms->look.cset.active) #define ST_CSET_TITLE(s) ((s)->look.cset.title) #define MST_CSET_TITLE(m) ((m)->s->ms->look.cset.title) #define ST_CSET_GREYED(s) ((s)->look.cset.greyed) #define MST_CSET_GREYED(m) ((m)->s->ms->look.cset.greyed) #define ST_SIDEPIC(s) ((s)->look.side_picture) #define MST_SIDEPIC(m) ((m)->s->ms->look.side_picture) #define ST_SIDE_COLOR(s) ((s)->look.side_color) #define MST_SIDE_COLOR(m) ((m)->s->ms->look.side_color) #define ST_MENU_ACTIVE_GCS(s) ((s)->look.active_gcs) #define MST_MENU_ACTIVE_GCS(m) ((m)->s->ms->look.active_gcs) #define ST_MENU_INACTIVE_GCS(s) ((s)->look.inactive_gcs) #define MST_MENU_INACTIVE_GCS(m) ((m)->s->ms->look.inactive_gcs) #define ST_MENU_STIPPLE_GCS(s) ((s)->look.stipple_gcs) #define MST_MENU_STIPPLE_GCS(m) ((m)->s->ms->look.stipple_gcs) #define ST_MENU_TITLE_GCS(s) ((s)->look.title_gcs) #define MST_MENU_TITLE_GCS(m) ((m)->s->ms->look.title_gcs) #define FORE_GC(g) ((g).fore_gc) #define BACK_GC(g) ((g).back_gc) #define HILIGHT_GC(g) ((g).hilight_gc) #define SHADOW_GC(g) ((g).shadow_gc) #define ST_MENU_STIPPLE_GC(s) ((s)->look.MenuStippleGC) #define MST_MENU_STIPPLE_GC(m) ((m)->s->ms->look.MenuStippleGC) #define ST_MENU_COLORS(s) ((s)->look.MenuColors) #define MST_MENU_COLORS(m) ((m)->s->ms->look.MenuColors) #define ST_MENU_ACTIVE_COLORS(s) ((s)->look.MenuActiveColors) #define MST_MENU_ACTIVE_COLORS(m) ((m)->s->ms->look.MenuActiveColors) #define ST_MENU_STIPPLE_COLORS(s) ((s)->look.MenuStippleColors) #define MST_MENU_STIPPLE_COLORS(m) ((m)->s->ms->look.MenuStippleColors) #define ST_PSTDFONT(s) ((s)->look.pStdFont) #define MST_PSTDFONT(m) ((m)->s->ms->look.pStdFont) #define ST_PTITLEFONT(s) ((s)->look.pTitleFont) #define MST_PTITLEFONT(m) ((m)->s->ms->look.pTitleFont) #define ST_FONT_HEIGHT(s) ((s)->look.FontHeight) #define MST_FONT_HEIGHT(m) ((m)->s->ms->look.FontHeight) /* feel */ #define ST_IS_ANIMATED(s) ((s)->feel.flags.is_animated) #define MST_IS_ANIMATED(m) ((m)->s->ms->feel.flags.is_animated) #define ST_DO_POPUP_IMMEDIATELY(s) ((s)->feel.flags.do_popup_immediately) #define MST_DO_POPUP_IMMEDIATELY(m) \ ((m)->s->ms->feel.flags.do_popup_immediately) #define ST_DO_POPDOWN_IMMEDIATELY(s) ((s)->feel.flags.do_popdown_immediately) #define MST_DO_POPDOWN_IMMEDIATELY(m) \ ((m)->s->ms->feel.flags.do_popdown_immediately) #define ST_DO_WARP_TO_TITLE(s) ((s)->feel.flags.do_warp_to_title) #define MST_DO_WARP_TO_TITLE(m) ((m)->s->ms->feel.flags.do_warp_to_title) #define ST_DO_POPUP_AS(s) ((s)->feel.flags.do_popup_as) #define MST_DO_POPUP_AS(m) ((m)->s->ms->feel.flags.do_popup_as) #define ST_DO_UNMAP_SUBMENU_ON_POPDOWN(s) \ ((s)->feel.flags.do_unmap_submenu_on_popdown) #define MST_DO_UNMAP_SUBMENU_ON_POPDOWN(m) \ ((m)->s->ms->feel.flags.do_unmap_submenu_on_popdown) #define ST_USE_LEFT_SUBMENUS(s) ((s)->feel.flags.use_left_submenus) #define MST_USE_LEFT_SUBMENUS(m) \ ((m)->s->ms->feel.flags.use_left_submenus) #define ST_USE_AUTOMATIC_HOTKEYS(s) ((s)->feel.flags.use_automatic_hotkeys) #define MST_USE_AUTOMATIC_HOTKEYS(m) \ ((m)->s->ms->feel.flags.use_automatic_hotkeys) #define ST_MOUSE_WHEEL(s) ((s)->feel.flags.mouse_wheel) #define MST_MOUSE_WHEEL(m) ((m)->s->ms->feel.flags.mouse_wheel) #define ST_SCROLL_OFF_PAGE(s) ((s)->feel.flags.scroll_off_page) #define MST_SCROLL_OFF_PAGE(m) ((m)->s->ms->feel.flags.scroll_off_page) #define ST_FLAGS(s) ((s)->feel.flags) #define MST_FLAGS(m) ((m)->s->ms->feel.flags) #define ST_POPUP_OFFSET_PERCENT(s) ((s)->feel.PopupOffsetPercent) #define MST_POPUP_OFFSET_PERCENT(m) ((m)->s->ms->feel.PopupOffsetPercent) #define ST_POPUP_OFFSET_ADD(s) ((s)->feel.PopupOffsetAdd) #define MST_POPUP_OFFSET_ADD(m) ((m)->s->ms->feel.PopupOffsetAdd) #define ST_ACTIVE_AREA_PERCENT(s) \ ((s)->feel.ActiveAreaPercent) #define MST_ACTIVE_AREA_PERCENT(m) \ ((m)->s->ms->feel.ActiveAreaPercent) #define ST_POPDOWN_DELAY(s) ((s)->feel.PopdownDelay10ms) #define MST_POPDOWN_DELAY(m) ((m)->s->ms->feel.PopdownDelay10ms) #define ST_POPUP_DELAY(s) ((s)->feel.PopupDelay10ms) #define MST_POPUP_DELAY(m) ((m)->s->ms->feel.PopupDelay10ms) #define ST_DOUBLE_CLICK_TIME(s) ((s)->feel.DoubleClickTime) #define MST_DOUBLE_CLICK_TIME(m) ((m)->s->ms->feel.DoubleClickTime) #define ST_ITEM_FORMAT(s) ((s)->feel.item_format) #define MST_ITEM_FORMAT(m) ((m)->s->ms->feel.item_format) #define ST_SELECT_ON_RELEASE_KEY(s) ((s)->feel.select_on_release_key) #define MST_SELECT_ON_RELEASE_KEY(m) ((m)->s->ms->feel.select_on_release_key) #define ST_VERTICAL_MARGIN_TOP(s) ((s)->look.vertical_margins.top) #define MST_VERTICAL_MARGIN_TOP(m) ((m)->s->ms->look.vertical_margins.top) #define ST_VERTICAL_MARGIN_BOTTOM(s) ((s)->look.vertical_margins.bottom) #define MST_VERTICAL_MARGIN_BOTTOM(m) ((m)->s->ms->look.vertical_margins.bottom) #define ST_HOTKEY_ACTIVATES_IMMEDIATE(s) ((s)->feel.flags.hotkey_activates_immediate) #define MST_HOTKEY_ACTIVATES_IMMEDIATE(m) ((m)->s->ms->feel.flags.hotkey_activates_immediate) /* ---------------------------- type definitions --------------------------- */ typedef enum { /* menu types */ SimpleMenu = 0, GradientMenu, PixmapMenu, TiledPixmapMenu, SolidMenu /* max button is 8 (0x8) */ } MenuFaceType; typedef enum { MDP_POST_MENU = 0, MDP_ROOT_MENU = 1, MDP_IGNORE = 2, MDP_CLOSE = 3 } ms_do_popup_as_t; typedef enum { MMW_OFF = 0, MMW_MENU_BACKWARDS = 1, MMW_MENU = 2, MMW_POINTER = 3 } ms_mouse_wheel_t; typedef struct MenuFeel { struct { unsigned is_animated : 1; unsigned do_popdown_immediately : 1; unsigned do_popup_immediately : 1; unsigned do_popup_as : 2; unsigned do_warp_to_title : 1; unsigned do_unmap_submenu_on_popdown : 1; unsigned use_left_submenus : 1; unsigned use_automatic_hotkeys : 1; unsigned mouse_wheel : 2; unsigned scroll_off_page : 1; unsigned hotkey_activates_immediate : 1; } flags; int PopdownDelay10ms; int PopupOffsetPercent; int ActiveAreaPercent; int PopupOffsetAdd; int PopupDelay10ms; int DoubleClickTime; char *item_format; KeyCode select_on_release_key; } MenuFeel; typedef struct MenuFace { union { FvwmPicture *p; Pixel back; struct { int npixels; XColor *xcs; Bool do_dither; } grad; } u; MenuFaceType type; char gradient_type; } MenuFace; typedef struct { GC fore_gc; GC back_gc; GC hilight_gc; GC shadow_gc; } gc_quad_t; typedef struct MenuLook { MenuFace face; struct { unsigned do_hilight_back : 1; unsigned do_hilight_fore : 1; unsigned has_active_fore : 1; unsigned has_active_back : 1; unsigned has_stipple_fore : 1; unsigned has_long_separators : 1; unsigned has_triangle_relief : 1; unsigned has_side_color : 1; unsigned has_menu_cset : 1; unsigned has_active_cset : 1; unsigned has_greyed_cset : 1; unsigned is_item_relief_reversed : 1; unsigned using_default_font : 1; unsigned triangles_use_fore : 1; unsigned has_title_cset : 1; unsigned do_hilight_title_back : 1; unsigned using_default_titlefont : 1; } flags; unsigned char ReliefThickness; unsigned char TitleUnderlines; unsigned char BorderWidth; struct { signed char item_above; signed char item_below; signed char title_above; signed char title_below; signed char separator_above; signed char separator_below; } vertical_spacing; struct { unsigned char top; unsigned char bottom; } vertical_margins; struct { int menu; int active; int greyed; int title; } cset; FvwmPicture *side_picture; Pixel side_color; gc_quad_t inactive_gcs; gc_quad_t active_gcs; gc_quad_t stipple_gcs; gc_quad_t title_gcs; ColorPair MenuColors; ColorPair MenuActiveColors; ColorPair MenuStippleColors; FlocaleFont *pStdFont; FlocaleFont *pTitleFont; int FontHeight; } MenuLook; typedef struct MenuStyle { char *name; struct MenuStyle *next_style; int usage_count; MenuLook look; MenuFeel feel; struct { unsigned is_updated : 1; } flags; } MenuStyle; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void menustyle_free(MenuStyle *ms); MenuStyle *menustyle_find(char *name); void menustyle_update(MenuStyle *ms); MenuStyle *menustyle_parse_style(F_CMD_ARGS); MenuStyle *menustyle_get_default_style(void); void menustyle_copy(MenuStyle *origms, MenuStyle *destms); #endif /* MENUSTYLE_H */ fvwm-2.6.7/fvwm/cursor.h0000644000175700017570000000326712773467232012136 00000000000000/* -*-c-*- */ #ifndef CURSOR_H #define CURSOR_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* Cursor types */ typedef enum { CRS_NONE = 0, CRS_POSITION, /* upper Left corner cursor */ CRS_TITLE, /* title-bar cursor */ CRS_DEFAULT, /* cursor for apps to inherit */ CRS_SYS, /* sys-menu and iconify boxes cursor */ CRS_MOVE, /* move cursor */ CRS_RESIZE, /* resize cursor */ CRS_WAIT, /* wait a while cursor */ CRS_MENU, /* menu cursor */ CRS_SELECT, /* dot cursor for selecting windows */ CRS_DESTROY, /* skull and cross bones */ CRS_TOP, CRS_RIGHT, CRS_BOTTOM, CRS_LEFT, CRS_TOP_LEFT, CRS_TOP_RIGHT, CRS_BOTTOM_LEFT, CRS_BOTTOM_RIGHT, CRS_TOP_EDGE, CRS_RIGHT_EDGE, CRS_BOTTOM_EDGE, CRS_LEFT_EDGE, CRS_ROOT, CRS_STROKE, CRS_MAX } cursor_t; typedef enum { /* busy cursor bits */ BUSY_NONE = 0, BUSY_READ = (1<<0), BUSY_WAIT = (1<<1), BUSY_MODULESYNCHRONOUS = (1<<2), BUSY_DYNAMICMENU = (1<<3), BUSY_ALL = (BUSY_READ|BUSY_WAIT|BUSY_MODULESYNCHRONOUS|BUSY_DYNAMICMENU) } busy_cursor_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ Cursor *CreateCursors(Display *dpy); #endif /* CURSOR_H */ fvwm-2.6.7/fvwm/functable.h0000644000175700017570000000130112773467232012547 00000000000000/* -*-c-*- */ #ifndef FUNCTABLE_H #define FUNCTABLE_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define PRE_KEEPRC "keeprc" #define PRE_REPEAT "repeat" #define PRE_SILENT "silent" /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ extern const func_t func_table[]; /* ---------------------------- interface functions ------------------------ */ #endif /* FUNCTABLE_H */ fvwm-2.6.7/fvwm/events.c0000644000175700017570000035535013006057357012114 00000000000000/* -*-c-*- */ /* 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 */ /* This module is based on Twm, but has been siginificantly modified * by Rob Nation */ /* * Copyright 1988 by Evans & Sutherland Computer Corporation, * Salt Lake City, Utah * Portions Copyright 1989 by the Massachusetts Institute of Technology * Cambridge, 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 permis- * sion notice appear in supporting documentation, and that the * names of Evans & Sutherland and M.I.T. not be used in advertising * in publicity pertaining to distribution of the software without * specific, written prior permission. * * EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- * ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR * M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- * AGES 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. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #if HAVE_SYS_BSDTYPES_H #include #endif #include #include #include #include #include "libs/ftime.h" #include "libs/fvwmlib.h" #include "libs/System.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/ColorUtils.h" #include "libs/FShape.h" #include "libs/PictureBase.h" #include "libs/Colorset.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "commands.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "events.h" #include "eventhandler.h" #include "eventmask.h" #include "libs/fvwmsignal.h" #include "module_list.h" #include "module_interface.h" #include "session.h" #include "borders.h" #include "frame.h" #include "add_window.h" #include "icccm2.h" #include "icons.h" #include "ewmh.h" #include "update.h" #include "style.h" #include "stack.h" #include "geometry.h" #include "focus.h" #include "virtual.h" #include "decorations.h" #include "schedule.h" #include "menus.h" #include "colormaps.h" #include "colorset.h" #ifdef HAVE_STROKE #include "stroke.h" #endif /* HAVE_STROKE */ /* ---------------------------- local definitions -------------------------- */ #ifndef XUrgencyHint #define XUrgencyHint (1L << 8) #endif #define CR_MOVERESIZE_MASK (CWX | CWY | CWWidth | CWHeight | CWBorderWidth) #define DEBUG_GLOBALLY_ACTIVE 1 #define MAX_NUM_WEED_EVENT_TYPES 40 /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ extern void StartupStuff(void); /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef void (*PFEH)(const evh_args_t *ea); typedef struct { Window w; Bool do_return_true; Bool do_return_true_cr; unsigned long cr_value_mask; Bool ret_does_match; unsigned long ret_type; } check_if_event_args; typedef struct { unsigned do_forbid_function : 1; unsigned do_focus : 1; unsigned do_swallow_click : 1; unsigned do_raise : 1; } hfrc_ret_t; typedef struct event_group { int base; int count; PFEH *jump_table; struct event_group *next; } event_group_t; typedef struct { int num_event_types; int event_types[MAX_NUM_WEED_EVENT_TYPES]; } _weed_event_type_arg; typedef struct { long event_mask; } _weed_window_mask_events_arg; typedef struct { Window w; XEvent *last_cr_event; int count; } _merge_cr_args; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static int Button = 0; static const FvwmWindow *xcrossing_last_grab_window = NULL; STROKE_CODE(static int send_motion); STROKE_CODE(static char sequence[STROKE_MAX_SEQUENCE + 1]); static event_group_t *base_event_group = NULL; /* ---------------------------- exported variables (globals) --------------- */ int last_event_type = 0; Window PressedW = None; /* ---------------------------- local functions ---------------------------- */ static void fake_map_unmap_notify(const FvwmWindow *fw, int event_type) { XEvent client_event; XWindowAttributes winattrs = {0}; if (!XGetWindowAttributes(dpy, FW_W(fw), &winattrs)) { return; } XSelectInput( dpy, FW_W(fw), winattrs.your_event_mask & ~StructureNotifyMask); client_event.type = event_type; client_event.xmap.display = dpy; client_event.xmap.event = FW_W(fw); client_event.xmap.window = FW_W(fw); switch (event_type) { case MapNotify: client_event.xmap.override_redirect = False; break; case UnmapNotify: client_event.xunmap.from_configure = False; break; default: /* not possible if called correctly */ break; } FSendEvent( dpy, FW_W(fw), False, StructureNotifyMask, &client_event); XSelectInput(dpy, FW_W(fw), winattrs.your_event_mask); XFlush(dpy); return; } static Bool test_map_request( Display *display, XEvent *event, XPointer arg) { check_if_event_args *cie_args; Bool rc; cie_args = (check_if_event_args *)arg; cie_args->ret_does_match = False; if (event->type == MapRequest && event->xmaprequest.window == cie_args->w) { cie_args->ret_type = MapRequest; cie_args->ret_does_match = True; rc = cie_args->do_return_true; } else { cie_args->ret_type = 0; rc = False; } /* Yes, it is correct that this function always returns False. */ return rc; } /* Test for ICCCM2 withdraw requests by syntetic events on the root window */ static Bool test_withdraw_request( Display *display, XEvent *event, XPointer arg) { check_if_event_args *cie_args; Bool rc; cie_args = (check_if_event_args *)arg; cie_args->ret_does_match = False; if (event->type == UnmapNotify && event->xunmap.window == cie_args->w && event->xany.send_event == True && event->xunmap.event == FW_W(&Scr.FvwmRoot)) { cie_args->ret_type = UnmapNotify; cie_args->ret_does_match = True; rc = cie_args->do_return_true; } else { cie_args->ret_type = 0; rc = False; } return rc; } static int _pred_weed_accumulate_expose( Display *display, XEvent *ev, XPointer arg) { XEvent *em = (XEvent *)arg; if (ev->type != Expose) { return 0; } { int x0; int x1; x1 = max( ev->xexpose.x + ev->xexpose.width, em->xexpose.x + em->xexpose.width); x0 = min(em->xexpose.x, ev->xexpose.x); em->xexpose.x = x0; em->xexpose.width = x1 - x0; } { int y0; int y1; y1 = max( ev->xexpose.y + ev->xexpose.height, em->xexpose.y + em->xexpose.height); y0 = min(em->xexpose.y, ev->xexpose.y); em->xexpose.y = y0; em->xexpose.height = y1 - y0; } return 1; } static int _pred_weed_handle_expose( Display *display, XEvent *event, XPointer arg) { if (event->type == Expose) { dispatch_event(event); return 1; } else { return 0; } } static int _pred_weed_event_type( Display *display, XEvent *event, XPointer arg) { _weed_event_type_arg *args = (_weed_event_type_arg *)arg; int i; for (i = 0; i < args->num_event_types; i++) { if (event->type == args->event_types[i]) { /* invalidate event and continue weeding */ return 1; } } /* keep event and continue weeding */ return 0; } static int _pred_flush_property_notify_weed( Display *display, XEvent *event, XPointer arg) { flush_property_notify_args *args = (flush_property_notify_args *)arg; int does_match_window; does_match_window = ( FEV_HAS_EVENT_WINDOW(event->type) && event->xany.window == args->w) ? 1 : 0; if ( does_match_window && event->type == args->event_type && event->xproperty.atom == args->atom) { /* invalidate event and continue weeding */ return 1; } else if ( args->do_stop_at_event_type && event->type == args->stop_at_event_type && ( !FEV_HAS_EVENT_WINDOW(args->stop_at_event_type) || does_match_window)) { /* keep event and stop weeding */ return 2; } /* keep event and continue weeding */ return 0; } static Bool test_resizing_event( Display *display, XEvent *event, XPointer arg) { check_if_event_args *cie_args; Bool rc; cie_args = (check_if_event_args *)arg; cie_args->ret_does_match = False; if (event->xany.window != cie_args->w) { return False; } rc = False; switch (event->type) { case ConfigureRequest: if ((event->xconfigurerequest.value_mask & cie_args->cr_value_mask) != 0) { cie_args->ret_type = ConfigureRequest; cie_args->ret_does_match = True; rc = cie_args->do_return_true_cr; } break; case PropertyNotify: if (event->xproperty.atom == XA_WM_NORMAL_HINTS) { cie_args->ret_type = PropertyNotify; cie_args->ret_does_match = True; rc = cie_args->do_return_true; } default: break; } /* Yes, it is correct that this function may always returns False. */ return rc; } static inline void _handle_cr_on_unmanaged(XEvent *e) { XConfigureRequestEvent *cre = &e->xconfigurerequest; XWindowChanges xwc; unsigned long xwcm; xwcm = (cre->value_mask & CR_MOVERESIZE_MASK); xwc.x = cre->x; xwc.y = cre->y; xwc.width = cre->width; xwc.height = cre->height; xwc.border_width = cre->border_width; XConfigureWindow(dpy, cre->window, xwcm, &xwc); return; } static inline void _handle_cr_on_icon(XEvent *e, FvwmWindow *fw) { XConfigureRequestEvent *cre = &e->xconfigurerequest; XWindowChanges xwc; unsigned long xwcm; xwcm = (cre->value_mask & CR_MOVERESIZE_MASK); xwc.x = cre->x; xwc.y = cre->y; xwc.width = cre->width; xwc.height = cre->height; xwc.border_width = cre->border_width; if (FW_W_ICON_PIXMAP(fw) == cre->window) { int bw; if (cre->value_mask & CWBorderWidth) { fw->icon_border_width = cre->border_width; } bw = fw->icon_border_width; if ((cre->value_mask & (CWWidth | CWHeight)) == (CWWidth | CWHeight)) { set_icon_picture_size( fw, cre->width + 2 * bw, cre->height + 2 * bw); } } set_icon_position(fw, cre->x, cre->y); broadcast_icon_geometry(fw, False); XConfigureWindow(dpy, cre->window, xwcm, &xwc); if (cre->window != FW_W_ICON_PIXMAP(fw) && FW_W_ICON_PIXMAP(fw) != None) { rectangle g; get_icon_picture_geometry(fw, &g); xwc.x = g.x; xwc.y = g.y; xwcm = cre->value_mask & (CWX | CWY); XConfigureWindow( dpy, FW_W_ICON_PIXMAP(fw), xwcm, &xwc); } if (FW_W_ICON_TITLE(fw) != None) { rectangle g; get_icon_title_geometry(fw, &g); xwc.x = g.x; xwc.y = g.y; xwcm = cre->value_mask & (CWX | CWY); XConfigureWindow( dpy, FW_W_ICON_TITLE(fw), xwcm, &xwc); } return; } static inline void _handle_cr_on_shaped(FvwmWindow *fw) { /* suppress compiler warnings w/o shape extension */ int i; unsigned int u; Bool b; int boundingShaped; SUPPRESS_UNUSED_VAR_WARNING(i); SUPPRESS_UNUSED_VAR_WARNING(u); SUPPRESS_UNUSED_VAR_WARNING(b); if (FShapeQueryExtents( dpy, FW_W(fw), &boundingShaped, &i, &i, &u, &u, &b, &i, &i, &u, &u)) { fw->wShaped = boundingShaped; } else { fw->wShaped = 0; } return; } static inline void _handle_cr_restack( int *ret_do_send_event, XEvent *e, FvwmWindow *fw) { XConfigureRequestEvent *cre = &e->xconfigurerequest; XWindowChanges xwc; unsigned long xwcm; FvwmWindow *fw2 = NULL; if (cre->value_mask & CWSibling) { if (XFindContext( dpy, cre->above, FvwmContext, (caddr_t *)&fw2) == XCNOENT) { fw2 = NULL; } if (fw2 == fw) { fw2 = NULL; } } if (cre->detail != Above && cre->detail != Below) { HandleUnusualStackmodes( cre->detail, fw, cre->window, fw2, cre->above); } /* only allow clients to restack windows within their layer */ else if (fw2 == NULL || compare_window_layers(fw2, fw) != 0) { switch (cre->detail) { case Above: RaiseWindow(fw, True); break; case Below: LowerWindow(fw, True); break; } } else { xwc.sibling = FW_W_FRAME(fw2); xwc.stack_mode = cre->detail; xwcm = CWSibling | CWStackMode; XConfigureWindow(dpy, FW_W_FRAME(fw), xwcm, &xwc); /* Maintain the condition that icon windows are stacked * immediately below their frame * 1. for fw */ xwc.sibling = FW_W_FRAME(fw); xwc.stack_mode = Below; xwcm = CWSibling | CWStackMode; if (FW_W_ICON_TITLE(fw) != None) { XConfigureWindow( dpy, FW_W_ICON_TITLE(fw), xwcm, &xwc); } if (FW_W_ICON_PIXMAP(fw) != None) { XConfigureWindow( dpy, FW_W_ICON_PIXMAP(fw), xwcm, &xwc); } /* 2. for fw2 */ if (cre->detail == Below) { xwc.sibling = FW_W_FRAME(fw2); xwc.stack_mode = Below; xwcm = CWSibling | CWStackMode; if (FW_W_ICON_TITLE(fw2) != None) { XConfigureWindow( dpy, FW_W_ICON_TITLE(fw2), xwcm, &xwc); } if (FW_W_ICON_PIXMAP(fw2) != None) { XConfigureWindow( dpy, FW_W_ICON_PIXMAP(fw2), xwcm, &xwc); } } /* Maintain the stacking order ring */ if (cre->detail == Above) { remove_window_from_stack_ring(fw); add_window_to_stack_ring_after( fw, get_prev_window_in_stack_ring(fw2)); } else /* cre->detail == Below */ { remove_window_from_stack_ring(fw); add_window_to_stack_ring_after(fw, fw2); } BroadcastRestackThisWindow(fw); } /* srt (28-Apr-2001): Tk needs a ConfigureNotify event after a * raise, otherwise it would hang for two seconds */ *ret_do_send_event = 1; return; } static inline void _cr_get_static_position( rectangle *ret_g, FvwmWindow *fw, XEvent *e, size_borders *b) { XConfigureRequestEvent *cre = &e->xconfigurerequest; if (cre->value_mask & CWX) { ret_g->x = cre->x - b->top_left.width; } else { ret_g->x = fw->g.frame.x; } if (cre->value_mask & CWY) { ret_g->y = cre->y - b->top_left.height; } else { ret_g->y = fw->g.frame.y; } return; } static inline void _cr_get_grav_position( rectangle *ret_g, FvwmWindow *fw, XEvent *e, size_borders *b) { XConfigureRequestEvent *cre = &e->xconfigurerequest; int grav_x; int grav_y; gravity_get_offsets(fw->hints.win_gravity, &grav_x, &grav_y); if (cre->value_mask & CWX) { ret_g->x = cre->x - ((grav_x + 1) * b->total_size.width) / 2; } else { ret_g->x = fw->g.frame.x; } if (cre->value_mask & CWY) { ret_g->y = cre->y - ((grav_y + 1) * b->total_size.height) / 2; } else { ret_g->y = fw->g.frame.y; } return; } /* Try to detect whether the application uses the ICCCM way of moving its * window or the traditional way, always assuming StaticGravity. */ static inline void _cr_detect_icccm_move( FvwmWindow *fw, XEvent *e, size_borders *b) { XConfigureRequestEvent *cre = &e->xconfigurerequest; rectangle grav_g; rectangle static_g; rectangle dg_g; rectangle ds_g; int mx; int my; int m; int w; int h; int has_x; int has_y; if (CR_MOTION_METHOD(fw) != CR_MOTION_METHOD_AUTO) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "_cdim: --- already detected (pid %d) %p" " '%s'\n", HAS_EWMH_WM_PID(fw), fw, fw->visible_name); } return; } if (HAS_EWMH_WM_PID(fw)) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr,"_cdim: +++ has ewmh_wm_pid: icccm" " %p '%s'\n", fw, fw->visible_name); } SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_USE_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); return; } if (fw->ewmh_window_type != EWMH_WINDOW_TYPE_NONE_ID) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "_cdim: +++ has ewmh_window_type:" " icccm %p '%s'\n", fw, fw->visible_name); } SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_USE_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); return; } if (FShapesSupported && fw->wShaped) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "_cdim: --- shaped window %p " "'%s'\n", fw, fw->visible_name); } /* no detection for shaped windows */ return; } if (fw->hints.win_gravity == StaticGravity) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "_cdim: --- using StaticGravity" " %p '%s'\n", fw, fw->visible_name); } return; } has_x = (cre->value_mask & CWX); has_y = (cre->value_mask & CWY); if (!has_x && !has_y) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "_cdim: --- not moved %p '%s'\n", fw, fw->visible_name); } return; } _cr_get_grav_position(&grav_g, fw, e, b); _cr_get_static_position(&static_g, fw, e, b); if (static_g.x == grav_g.x) { /* both methods have the same result; ignore */ has_x = 0; } if (static_g.y == grav_g.y) { /* both methods have the same result; ignore */ has_y = 0; } if (!has_x && !has_y) { if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "_cdim: --- not moved %p '%s'\n", fw, fw->visible_name); } return; } dg_g.x = grav_g.x - fw->g.frame.x; dg_g.y = grav_g.y - fw->g.frame.y; ds_g.x = static_g.x - fw->g.frame.x; ds_g.y = static_g.y - fw->g.frame.y; if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "s %3d/%3d %2d/%2d, g %3d/%3d %2d/%2d: ", static_g.x, static_g.y, ds_g.x, ds_g.y, grav_g.x, grav_g.y, dg_g.x, dg_g.y); } /* check full screen */ if ((cre->value_mask & (CWX | CWY)) == (CWX | CWY) && (has_x || has_y) && cre->width == Scr.MyDisplayWidth && cre->height == Scr.MyDisplayHeight) { if (grav_g.x == -b->top_left.width && grav_g.y == -b->top_left.height) { /* Window is fullscreen using the ICCCM way. */ SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_USE_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "+++ fullscreen icccm %p" " '%s'\n", fw, fw->visible_name); } return; } else if (static_g.x == -b->top_left.width && static_g.y == -b->top_left.height) { /* Window is fullscreen using the traditional way. */ SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_STATIC_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "+++ fullscreen traditional" " %p '%s'\n", fw, fw->visible_name); } return; } } /* check travelling across the screen */ if (has_x && dg_g.x == 0 && ds_g.x != 0 && has_y && dg_g.y == 0 && ds_g.y != 0) { /* The traditional way causes a shift by the border width or * height. Use ICCCM way. */ SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_USE_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "+++ travelling icccm %p '%s'\n", fw, fw->visible_name); } return; } if (has_x && dg_g.x != 0 && ds_g.x == 0 && has_y && dg_g.y != 0 && ds_g.y == 0) { /* The ICCCM way causes a shift by the border width or height. * Use traditional way. */ SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_STATIC_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "+++ travelling traditional %p" " '%s'\n", fw, fw->visible_name); } return; } /* check placement near border */ w = (cre->value_mask & CWWidth) ? cre->width + b->total_size.width : fw->g.frame.width; h = (cre->value_mask & CWHeight) ? cre->height + b->total_size.height : fw->g.frame.height; if (!has_x) { mx = CR_MOTION_METHOD_AUTO; } else if (static_g.x == 0 || static_g.x + w == Scr.MyDisplayWidth) { mx = CR_MOTION_METHOD_STATIC_GRAV; } else if (grav_g.x == 0 || grav_g.x + w == Scr.MyDisplayWidth) { mx = CR_MOTION_METHOD_USE_GRAV; } else { mx = CR_MOTION_METHOD_AUTO; } if (!has_y) { my = CR_MOTION_METHOD_AUTO; } else if (static_g.y == 0 || static_g.y + h == Scr.MyDisplayHeight) { my = CR_MOTION_METHOD_STATIC_GRAV; } else if (grav_g.y == 0 || grav_g.y + h == Scr.MyDisplayHeight) { my = CR_MOTION_METHOD_USE_GRAV; } else { my = CR_MOTION_METHOD_AUTO; } m = (mx != CR_MOTION_METHOD_AUTO) ? mx : my; if (m != CR_MOTION_METHOD_AUTO) { /* Window was placed next to the display border. */ if (m == my || my == CR_MOTION_METHOD_AUTO) { SET_CR_MOTION_METHOD(fw, m); SET_CR_MOTION_METHOD_DETECTED(fw, 1); if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "+++ near border %s %p " "'%s'\n", (m == CR_MOTION_METHOD_USE_GRAV) ? "icccm" : "traditional", fw, fw->visible_name); } return; } } if (Scr.bo.do_debug_cr_motion_method == 1) { fprintf( stderr, "--- not detected %p '%s'\n", fw, fw->visible_name); } return; } /* This is not a good idea because this interferes with changes in the size * hints of the window. However, it is impossible to be completely safe here. * For example, if the client changes the size inc, then resizes the size of * its window and then changes the size inc again - all in one batch - then * the WM will read the *second* size inc upon the *first* event and use the * wrong one in the ConfigureRequest calculations. */ /* dv (31 Mar 2002): The code now handles these situations, so enable it * again. */ static int _pred_merge_cr(Display *display, XEvent *event, XPointer arg) { _merge_cr_args *args = (_merge_cr_args *)arg; switch (event->type) { case ConfigureRequest: { XConfigureRequestEvent *ecr = &event->xconfigurerequest; XConfigureRequestEvent *lcr = &args->last_cr_event->xconfigurerequest; if (event->xconfigurerequest.window != args->w) { /* no match, keep looking */ return 0; } /* collect the size/position changes */ if (lcr->value_mask & CWX) { ecr->x = lcr->x; } if (lcr->value_mask & CWY) { ecr->y = lcr->y; } if (lcr->value_mask & CWWidth) { ecr->width = lcr->width; } if (lcr->value_mask & CWHeight) { ecr->height = lcr->height; } if (lcr->value_mask & CWBorderWidth) { ecr->border_width = lcr->border_width; } /* add to new event and remove from old event */ ecr->value_mask |= (lcr->value_mask & CR_MOVERESIZE_MASK); lcr->value_mask &= ~CR_MOVERESIZE_MASK; if (lcr->value_mask == 0) { /* The event has no useful contents anymore. */ FEV_INVALIDATE_EVENT(args->last_cr_event); } args->last_cr_event = event; args->count++; /* don't drop the current event and continue weeding */ return 0; } case PropertyNotify: if ( event->xproperty.window == args->w && event->xproperty.atom != XA_WM_NORMAL_HINTS) { /* ConfigureRequest events cannot be merged past * changes of the size hints. */ /* don't merge and stop weeding */ return 2; } else { /* PropertyNotify for another window, or the changed * property does not interfere with merging. */ /* keep looking */ return 0; } default: /* Other events do not interfer with merging. */ /* keep looking */ return 0; } } static inline int _merge_cr_moveresize( const evh_args_t *ea, XEvent *ev, FvwmWindow *fw, size_borders *b) { _merge_cr_args args; memset(&args, 0, sizeof(args)); args.w = ev->xconfigurerequest.window; args.last_cr_event = ev; FWeedIfEvents(dpy, _pred_merge_cr, (XPointer)&args); #if 1 /*!!!*/ if (args.count > 0) { fprintf(stderr, "%s: merged %d cr events\n", __func__, args.count); } #endif /* use the count from the structure, not the return value of * FWeedIfEvents() because the predicate has a different way of weeding * and the return value is always zero. */ return args.count; } static inline int _handle_cr_on_client( int *ret_do_send_event, XEvent *e, const evh_args_t *ea, FvwmWindow *fw, Bool force, int force_gravity) { XConfigureRequestEvent *cre = &e->xconfigurerequest; rectangle current_g; rectangle new_g; rectangle d_g; size_rect constr_dim; size_rect oldnew_dim; size_borders b; int gravity; if (ea) { cre = &ea->exc->x.etrigger->xconfigurerequest; } if (cre->value_mask & CWBorderWidth) { /* for restoring */ fw->attr_backup.border_width = cre->border_width; } if ((cre->value_mask & (CWWidth | CWHeight | CWX | CWY)) == 0) { return 0; } get_window_borders(fw, &b); /* Merge all pending ConfigureRequests for the window into a single * event. However, we can not do this if the window uses the motion * method autodetection because the merged event might confuse the * detection code. */ if (ea && CR_MOTION_METHOD(fw) != CR_MOTION_METHOD_AUTO) { int count; count = _merge_cr_moveresize(ea, e, fw, &b); if (count > 0) { /* the event has been merged into a later one, do * nothing */ return 0; } } #if 0 fprintf(stderr, "cre: %d(%d) %d(%d) %d(%d)x%d(%d) fw 0x%08x w 0x%08x " "ew 0x%08x '%s'\n", cre->x, (int)(cre->value_mask & CWX), cre->y, (int)(cre->value_mask & CWY), cre->width, (int)(cre->value_mask & CWWidth), cre->height, (int)(cre->value_mask & CWHeight), (int)FW_W_FRAME(fw), (int)FW_W(fw), (int)cre->window, (fw->name.name) ? fw->name.name : ""); #endif /* Don't modify frame_g fields before calling SetupWindow! */ memset(&d_g, 0, sizeof(d_g)); if (HAS_NEW_WM_NORMAL_HINTS(fw)) { /* get the latest size hints */ XSync(dpy, 0); GetWindowSizeHints(fw); SET_HAS_NEW_WM_NORMAL_HINTS(fw, 0); } if (!HAS_OVERRIDE_SIZE_HINTS(fw) && (fw->hints.flags & PMaxSize)) { /* Java workaround */ if (cre->height > fw->hints.max_height && fw->hints.max_height <= BROKEN_MAXSIZE_LIMIT) { fw->hints.max_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT; cre->value_mask |= CWHeight; } if (cre->width > fw->hints.max_width && fw->hints.max_width <= BROKEN_MAXSIZE_LIMIT) { fw->hints.max_width = DEFAULT_MAX_MAX_WINDOW_WIDTH; cre->value_mask |= CWWidth; } } if (!HAS_OVERRIDE_SIZE_HINTS(fw) && (fw->hints.flags & PMinSize)) { if (cre->width < fw->hints.min_width && fw->hints.min_width >= BROKEN_MINSIZE_LIMIT) { fw->hints.min_width = 1; cre->value_mask |= CWWidth; } if (cre->height < fw->hints.min_height && fw->hints.min_height >= BROKEN_MINSIZE_LIMIT) { fw->hints.min_height = 1; cre->value_mask |= CWHeight; } } if (IS_SHADED(fw) || !is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM, False)) { /* forbid shaded applications to move their windows */ cre->value_mask &= ~(CWX | CWY); /* resend the old geometry */ *ret_do_send_event = 1; } if (IS_MAXIMIZED(fw)) { /* dont allow clients to resize maximized windows */ cre->value_mask &= ~(CWWidth | CWHeight); /* resend the old geometry */ *ret_do_send_event = 1; d_g.width = 0; d_g.height = 0; } else if ( !is_function_allowed( F_RESIZE, NULL, fw, RQORIG_PROGRAM, False)) { cre->value_mask &= ~(CWWidth | CWHeight); *ret_do_send_event = 1; } if (!force && CR_MOTION_METHOD(fw) == CR_MOTION_METHOD_AUTO) { _cr_detect_icccm_move(fw, e, &b); } if (force_gravity > ForgetGravity && force_gravity <= StaticGravity) { gravity = force_gravity; } else { gravity = fw->hints.win_gravity; } if (IS_SHADED(fw)) { direction_t gravity_dir; get_unshaded_geometry(fw, ¤t_g); /* the shade direction overrides the window's gravity */ gravity_dir = gravity_grav_to_dir(gravity); gravity_dir = gravity_override_dir( gravity_dir, SHADED_DIR(fw)); gravity = gravity_dir_to_grav(gravity_dir); } else { current_g = fw->g.frame; } if (!(cre->value_mask & (CWX | CWY))) { /* nothing */ } else if ((force || CR_MOTION_METHOD(fw) == CR_MOTION_METHOD_USE_GRAV) && gravity != StaticGravity) { int ref_x; int ref_y; int grav_x; int grav_y; gravity_get_offsets(gravity, &grav_x, &grav_y); if (cre->value_mask & CWX) { ref_x = cre->x - ((grav_x + 1) * b.total_size.width) / 2; d_g.x = ref_x - current_g.x; } if (cre->value_mask & CWY) { ref_y = cre->y - ((grav_y + 1) * b.total_size.height) / 2; d_g.y = ref_y - current_g.y; } } else /* ..._USE_GRAV or ..._AUTO */ { /* default: traditional cr handling */ if (cre->value_mask & CWX) { d_g.x = cre->x - current_g.x - b.top_left.width; } if (cre->value_mask & CWY) { d_g.y = cre->y - current_g.y - b.top_left.height; } } if (cre->value_mask & CWHeight) { if (cre->height < (WINDOW_FREAKED_OUT_SIZE - b.total_size.height)) { d_g.height = cre->height - (current_g.height - b.total_size.height); } else { /* Ignore height changes to astronomically large * windows (needed for XEmacs 20.4); don't care if the * window is shaded here - we won't use 'height' in * this case anyway. * Inform the buggy app about the size that *we* want */ d_g.height = 0; *ret_do_send_event = 1; } } if (cre->value_mask & CWWidth) { if (cre->width < (WINDOW_FREAKED_OUT_SIZE - b.total_size.width)) { d_g.width = cre->width - (current_g.width - b.total_size.width); } else { d_g.width = 0; *ret_do_send_event = 1; } } /* SetupWindow (x,y) are the location of the upper-left outer corner * and are passed directly to XMoveResizeWindow (frame). The * (width,height) are the inner size of the frame. The inner width is * the same as the requested client window width; the inner height is * the same as the requested client window height plus any title bar * slop. */ new_g = current_g; oldnew_dim.width = new_g.width + d_g.width; oldnew_dim.height = new_g.height + d_g.height; constr_dim.width = oldnew_dim.width; constr_dim.height = oldnew_dim.height; constrain_size( fw, NULL, &constr_dim.width, &constr_dim.height, 0, 0, CS_UPDATE_MAX_DEFECT); d_g.width += (constr_dim.width - oldnew_dim.width); d_g.height += (constr_dim.height - oldnew_dim.height); if ((cre->value_mask & CWX) && d_g.width) { new_g.x = current_g.x + d_g.x; new_g.width = current_g.width + d_g.width; } else if ((cre->value_mask & CWX) && !d_g.width) { new_g.x = current_g.x + d_g.x; } else if (!(cre->value_mask & CWX) && d_g.width) { gravity_resize(gravity, &new_g, d_g.width, 0); } if ((cre->value_mask & CWY) && d_g.height) { new_g.y = current_g.y + d_g.y; new_g.height = current_g.height + d_g.height; } else if ((cre->value_mask & CWY) && !d_g.height) { new_g.y = current_g.y + d_g.y; } else if (!(cre->value_mask & CWY) && d_g.height) { gravity_resize(gravity, &new_g, 0, d_g.height); } if (new_g.x == current_g.x && new_g.y == current_g.y && new_g.width == current_g.width && new_g.height == current_g.height) { /* Window will not be moved or resized; send a synthetic * ConfigureNotify. */ *ret_do_send_event = 1; } else if ((cre->value_mask & CWX) || (cre->value_mask & CWY) || d_g.width || d_g.height) { if (IS_SHADED(fw)) { fw->g.normal = new_g; get_shaded_geometry(fw, &new_g, &new_g); } frame_setup_window_app_request( fw, new_g.x, new_g.y, new_g.width, new_g.height, False); /* make sure the window structure has the new position */ update_absolute_geometry(fw); maximize_adjust_offset(fw); } else if (DO_FORCE_NEXT_CR(fw)) { *ret_do_send_event = 1; } SET_FORCE_NEXT_CR(fw, 0); SET_FORCE_NEXT_PN(fw, 0); return 1; } void _handle_configure_request( XEvent *e, const evh_args_t *ea, FvwmWindow *fw, Bool force, int force_gravity) { XConfigureRequestEvent *cre = &e->xconfigurerequest; int do_send_event = 0; int cn_count = 0; fev_sanitise_configure_request(cre); /* 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 (fw == NULL) { _handle_cr_on_unmanaged(e); return; } if (cre->window == FW_W_ICON_TITLE(fw) || cre->window == FW_W_ICON_PIXMAP(fw)) { _handle_cr_on_icon(e, fw); } if (FShapesSupported) { _handle_cr_on_shaped(fw); } if (fw != NULL && cre->window == FW_W(fw)) { cn_count = _handle_cr_on_client( &do_send_event, e, ea, fw, force, force_gravity); } /* Stacking order change requested. Handle this *after* geometry * changes, since we need the new geometry in occlusion calculations */ if ((cre->value_mask & CWStackMode) && (!DO_IGNORE_RESTACK(fw) || force)) { _handle_cr_restack(&do_send_event, e, fw); } #if 1 /* This causes some ddd windows not to be drawn properly. Reverted back * to the old method in frame_setup_window. */ /* domivogt (15-Oct-1999): enabled this to work around buggy apps that * ask for a nonsense height and expect that they really get it. */ if (cn_count == 0 && do_send_event) { cn_count = 1; } else if (cn_count > 0) { do_send_event = 1; } for ( ; cn_count > 0; cn_count--) { SendConfigureNotify( fw, fw->g.frame.x, fw->g.frame.y, fw->g.frame.width, fw->g.frame.height, 0, True); } if (do_send_event) { XFlush(dpy); } #endif return; } static Bool _pred_button_click( Display *display, XEvent *event, XPointer arg) { if (event->type == ButtonPress || event->type == ButtonRelease) { return True; } return False; } /* Helper function for __handle_focus_raise_click(). */ static Bool __test_for_motion(int x0, int y0) { int x; int y; unsigned int mask; XEvent e; /* Query the pointer to do this. We can't check for events here since * the events are still needed if the pointer moves. */ /* However, some special mouse (e.g., a touchpad with the * synaptic driver) may handle a double click in a special way * (for dragging through short touching and holding down the * finger on the touchpad). Bascially, when you execute a * double click the first button release is queued after the * second _physical_ mouse release happen. It seems that * FQueryPointer may not work as expected: it does not see * that the button is released on a double click. So, we need * to check for a button press in the future to avoid a fvwm * lockup! (olicha 2004-01-31) */ for (x = x0, y = y0; FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &x, &y, &mask) == True; usleep(20000)) { if ((mask & DEFAULT_ALL_BUTTONS_MASK) == 0) { /* all buttons are released */ return False; } else if (abs(x - x0) >= Scr.MoveThreshold || abs(y - y0) >= Scr.MoveThreshold) { /* the pointer has moved */ return True; } if (FCheckPeekIfEvent(dpy, &e, _pred_button_click, NULL)) { /* click in the future */ return False; } else { /* The predicate procedure finds no match, no event * has been removed from the queue and XFlush was * called. Nothing to do */ } } /* pointer has moved off screen */ return True; } /* Helper function for __handle_focus_raise_click(). */ static void __check_click_to_focus_or_raise( hfrc_ret_t *ret_args, const exec_context_t *exc) { FvwmWindow * const fw = exc->w.fw; const XEvent *te = exc->x.etrigger; struct { unsigned is_client_click : 1; unsigned is_focused : 1; } f; f.is_focused = !!focus_is_focused(fw); f.is_client_click = (exc->w.wcontext == C_WINDOW || exc->w.wcontext == C_EWMH_DESKTOP); /* check if we need to raise and/or focus the window */ ret_args->do_focus = focus_query_click_to_focus(fw, exc->w.wcontext); if (f.is_client_click && !ret_args->do_focus && !f.is_focused && FP_DO_FOCUS_BY_PROGRAM(FW_FOCUS_POLICY(fw)) && !fpol_query_allow_user_focus(&FW_FOCUS_POLICY(fw))) { /* Give the window a chance to to take focus itself */ ret_args->do_focus = 1; } if (ret_args->do_focus && focus_is_focused(fw)) { ret_args->do_focus = 0; } ret_args->do_raise = focus_query_click_to_raise(fw, f.is_focused, exc->w.wcontext); #define EXPERIMENTAL_ROU_HANDLING_V2 #ifdef EXPERIMENTAL_ROU_HANDLING_V2 /* RBW -- Dang! This works without the one in HandleEnterNotify! */ if (ret_args->do_raise && is_on_top_of_layer_and_above_unmanaged(fw)) #else if (ret_args->do_raise && is_on_top_of_layer(fw)) #endif { ret_args->do_raise = 0; } if ((ret_args->do_focus && FP_DO_IGNORE_FOCUS_CLICK_MOTION(FW_FOCUS_POLICY(fw))) || (ret_args->do_raise && FP_DO_IGNORE_RAISE_CLICK_MOTION(FW_FOCUS_POLICY(fw)))) { /* Pass further events to the application and check if a button * release or motion event occurs next. If we don't do this * here, the pointer will seem to be frozen in * __test_for_motion(). */ XAllowEvents(dpy, ReplayPointer, CurrentTime); if (__test_for_motion(te->xbutton.x_root, te->xbutton.y_root)) { /* the pointer was moved, process event normally */ ret_args->do_focus = 0; ret_args->do_raise = 0; } } if (ret_args->do_focus || ret_args->do_raise) { if (!((ret_args->do_focus && FP_DO_ALLOW_FUNC_FOCUS_CLICK(FW_FOCUS_POLICY(fw))) || (ret_args->do_raise && FP_DO_ALLOW_FUNC_RAISE_CLICK(FW_FOCUS_POLICY(fw))))) { ret_args->do_forbid_function = 1; } if (!((ret_args->do_focus && FP_DO_PASS_FOCUS_CLICK(FW_FOCUS_POLICY(fw))) || (ret_args->do_raise && FP_DO_PASS_RAISE_CLICK(FW_FOCUS_POLICY(fw))))) { ret_args->do_swallow_click = 1; } } return; } /* Finds out if the click on a window must be used to focus or raise it. */ static void __handle_focus_raise_click( hfrc_ret_t *ret_args, const exec_context_t *exc) { memset(ret_args, 0, sizeof(*ret_args)); if (exc->w.fw == NULL) { return; } /* check for proper click button and modifiers*/ if (FP_USE_MOUSE_BUTTONS(FW_FOCUS_POLICY(exc->w.fw)) != 0 && !(FP_USE_MOUSE_BUTTONS(FW_FOCUS_POLICY(exc->w.fw)) & (1 << (exc->x.etrigger->xbutton.button - 1)))) { /* wrong button, handle click normally */ return; } else if (FP_USE_MODIFIERS(FW_FOCUS_POLICY(exc->w.fw)) != FPOL_ANY_MODIFIER && MaskUsedModifiers( FP_USE_MODIFIERS(FW_FOCUS_POLICY(exc->w.fw))) != MaskUsedModifiers(exc->x.etrigger->xbutton.state)) { /* right button but wrong modifiers, handle click normally */ return; } else { __check_click_to_focus_or_raise(ret_args, exc); } return; } /* Helper function for HandleButtonPress */ static Bool __is_bpress_window_handled(const exec_context_t *exc) { Window eventw; const XEvent *te = exc->x.etrigger; if (exc->w.fw == NULL) { if ((te->xbutton.window != Scr.Root || te->xbutton.subwindow != None) && !is_pan_frame(te->xbutton.window)) { /* Ignore events in unmanaged windows or subwindows of * a client */ return False; } else { return True; } } eventw = (te->xbutton.subwindow != None && te->xany.window != FW_W(exc->w.fw)) ? te->xbutton.subwindow : te->xany.window; if (is_frame_hide_window(eventw) || eventw == FW_W_FRAME(exc->w.fw)) { return False; } if (!XGetGeometry( dpy, eventw, &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { /* The window has already died. */ return False; } return True; } /* Helper function for __handle_bpress_on_managed */ static Bool __handle_click_to_focus(const exec_context_t *exc) { fpol_set_focus_by_t set_by; switch (exc->w.wcontext) { case C_WINDOW: case C_EWMH_DESKTOP: set_by = FOCUS_SET_BY_CLICK_CLIENT; break; case C_ICON: set_by = FOCUS_SET_BY_CLICK_ICON; break; default: set_by = FOCUS_SET_BY_CLICK_DECOR; break; } SetFocusWindow(exc->w.fw, True, set_by); focus_grab_buttons(exc->w.fw); if (focus_is_focused(exc->w.fw) && !IS_ICONIFIED(exc->w.fw)) { border_draw_decorations( exc->w.fw, PART_ALL, True, True, CLEAR_ALL, NULL, NULL); } return focus_is_focused(exc->w.fw); } /* Helper function for __handle_bpress_on_managed */ static Bool __handle_click_to_raise(const exec_context_t *exc) { Bool rc = False; int is_focused; is_focused = focus_is_focused(exc->w.fw); if (focus_query_click_to_raise(exc->w.fw, is_focused, True)) { rc = True; } return rc; } /* Helper function for HandleButtonPress */ static void __handle_bpress_stroke(void) { STROKE_CODE(stroke_init()); STROKE_CODE(send_motion = True); return; } /* Helper function for __handle_bpress_on_managed */ static Bool __handle_bpress_action( const exec_context_t *exc, char *action) { window_parts part; Bool do_force; Bool rc = False; if (!action || *action == 0) { PressedW = None; return False; } /* draw pressed in decorations */ part = border_context_to_parts(exc->w.wcontext); do_force = (part & PART_TITLEBAR) ? True : False; border_draw_decorations( exc->w.fw, part, (Scr.Hilite == exc->w.fw), do_force, CLEAR_ALL, NULL, NULL); /* execute the action */ if (IS_ICONIFIED(exc->w.fw)) { /* release the pointer since it can't do harm over an icon */ XAllowEvents(dpy, AsyncPointer, CurrentTime); } execute_function(NULL, exc, action, 0); if (exc->w.wcontext != C_WINDOW && exc->w.wcontext != C_NO_CONTEXT) { WaitForButtonsUp(True); rc = True; } /* redraw decorations */ PressedW = None; if (check_if_fvwm_window_exists(exc->w.fw)) { part = border_context_to_parts(exc->w.wcontext); do_force = (part & PART_TITLEBAR) ? True : False; border_draw_decorations( exc->w.fw, part, (Scr.Hilite == exc->w.fw), do_force, CLEAR_ALL, NULL, NULL); } return rc; } /* Handles button presses on the root window. */ static void __handle_bpress_on_root(const exec_context_t *exc) { char *action; PressedW = None; __handle_bpress_stroke(); /* search for an appropriate mouse binding */ action = CheckBinding( Scr.AllBindings, STROKE_ARG(0) exc->x.etrigger->xbutton.button, exc->x.etrigger->xbutton.state, GetUnusedModifiers(), C_ROOT, BIND_BUTTONPRESS, NULL, NULL); if (action && *action) { const exec_context_t *exc2; exec_context_changes_t ecc; ecc.w.wcontext = C_ROOT; exc2 = exc_clone_context(exc, &ecc, ECC_WCONTEXT); execute_function(NULL, exc2, action, 0); exc_destroy_context(exc2); WaitForButtonsUp(True); } return; } /* Handles button presses on unmanaged windows */ static void __handle_bpress_on_unmanaged(const exec_context_t *exc) { /* Pass the event to the application. */ XAllowEvents(dpy, ReplayPointer, CurrentTime); XFlush(dpy); return; } /* Handles button presses on managed windows */ static void __handle_bpress_on_managed(const exec_context_t *exc) { char *action; hfrc_ret_t f; FvwmWindow * const fw = exc->w.fw; XEvent *e; e = exc->x.etrigger; /* Now handle click to focus and click to raise. */ __handle_focus_raise_click(&f, exc); PressedW = (f.do_forbid_function) ? None : exc->w.w; if (f.do_focus) { if (!__handle_click_to_focus(exc)) { /* Window didn't accept the focus; pass the click to * the application. */ f.do_swallow_click = 0; } } if (f.do_raise) { if (__handle_click_to_raise(exc) == True) { /* We can't raise the window immediately because the * action bound to the click might be "Lower" or * "RaiseLower". So mark the window as scheduled to be * raised after the binding is executed. Functions that * modify the stacking order will reset this flag. */ SET_SCHEDULED_FOR_RAISE(fw, 1); } } /* handle bindings */ if (!f.do_forbid_function) { /* stroke bindings */ __handle_bpress_stroke(); /* mouse bindings */ action = CheckBinding( Scr.AllBindings, STROKE_ARG(0) e->xbutton.button, e->xbutton.state, GetUnusedModifiers(), exc->w.wcontext, BIND_BUTTONPRESS, &fw->class, fw->name.name); if (__handle_bpress_action(exc, action)) { f.do_swallow_click = 1; } } /* raise the window */ if (IS_SCHEDULED_FOR_RAISE(fw)) { /* Now that we know the action did not restack the window we * can raise it. * dv (10-Aug-2002): We can safely raise the window after * redrawing it since all the decorations are drawn in the * window background and no Expose event is generated. */ RaiseWindow(fw, False); SET_SCHEDULED_FOR_RAISE(fw, 0); } /* clean up */ if (!f.do_swallow_click) { /* pass the click to the application */ XAllowEvents(dpy, ReplayPointer, CurrentTime); XFlush(dpy); } else if (f.do_focus || f.do_raise) { WaitForButtonsUp(True); } return; } /* restore focus stolen by unmanaged */ static void __refocus_stolen_focus_win(const evh_args_t *ea) { FOCUS_SET(Scr.StolenFocusWin, Scr.StolenFocusFvwmWin); ea->exc->x.etrigger->xfocus.window = Scr.StolenFocusWin; ea->exc->x.etrigger->type = FocusIn; Scr.UnknownWinFocused = None; Scr.StolenFocusWin = None; Scr.StolenFocusFvwmWin = NULL; dispatch_event(ea->exc->x.etrigger); return; } /* ---------------------------- event handlers ----------------------------- */ void HandleButtonPress(const evh_args_t *ea) { DBUG("HandleButtonPress", "Routine Entered"); GrabEm(CRS_NONE, GRAB_PASSIVE); if (__is_bpress_window_handled(ea->exc) == False) { __handle_bpress_on_unmanaged(ea->exc); } else if (ea->exc->w.fw != NULL) { __handle_bpress_on_managed(ea->exc); } else { __handle_bpress_on_root(ea->exc); } UngrabEm(GRAB_PASSIVE); return; } #ifdef HAVE_STROKE void HandleButtonRelease(const evh_args_t *ea) { char *action; char *name; int real_modifier; const XEvent *te = ea->exc->x.etrigger; XClassHint *class; DBUG("HandleButtonRelease", "Routine Entered"); send_motion = False; stroke_trans (sequence); DBUG("HandleButtonRelease",sequence); /* Allows modifier to work (Only R context works here). */ real_modifier = te->xbutton.state - (1 << (7 + te->xbutton.button)); if (ea->exc->w.fw == NULL) { class = NULL; name = NULL; } else { class = &ea->exc->w.fw->class; name = ea->exc->w.fw->name.name; } /* need to search for an appropriate stroke binding */ action = CheckBinding( Scr.AllBindings, sequence, te->xbutton.button, real_modifier, GetUnusedModifiers(), ea->exc->w.wcontext, BIND_STROKE, class, name); /* got a match, now process it */ if (action != NULL && (action[0] != 0)) { execute_function(NULL, ea->exc, action, 0); WaitForButtonsUp(True); } return; } #endif /* HAVE_STROKE */ void HandleClientMessage(const evh_args_t *ea) { const XEvent *te = ea->exc->x.etrigger; FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandleClientMessage", "Routine Entered"); if (EWMH_ProcessClientMessage(ea->exc)) { return; } /* handle deletion of tear out menus */ if (fw && IS_TEAR_OFF_MENU(fw) && te->xclient.format == 32 && te->xclient.data.l[0] == _XA_WM_DELETE_WINDOW) { menu_close_tear_off_menu(fw); return; } if (te->xclient.message_type == _XA_WM_CHANGE_STATE && fw && te->xclient.data.l[0] == IconicState && !IS_ICONIFIED(fw)) { const exec_context_t *exc; exec_context_changes_t ecc; ecc.w.wcontext = C_WINDOW; exc = exc_clone_context(ea->exc, &ecc, ECC_WCONTEXT); execute_function(NULL, exc, "Iconify", 0); exc_destroy_context(exc); return; } /* FIXME: Is this safe enough ? I guess if clients behave * according to ICCCM and send these messages only if they * grabbed the pointer, it is OK */ { extern Atom _XA_WM_COLORMAP_NOTIFY; if (te->xclient.message_type == _XA_WM_COLORMAP_NOTIFY) { set_client_controls_colormaps(te->xclient.data.l[1]); return; } } /* CKH - if we get here, it was an unknown client message, so send * it to the client if it was in a window we know about. I'm not so * sure this should be done or not, since every other window manager * I've looked at doesn't. But it might be handy for a free drag and * drop setup being developed for Linux. */ /* TA: 20091231 - But this confuses QT Drag and Drop since it handles * processing XSendEvents in an odd order. For now, workaround this * by using a BugOpts option. */ if (fw) { if ((!Scr.bo.do_enable_qt_drag_n_drop_workaround) && (te->xclient.window != FW_W(fw))) { XEvent e; e = *te; e.xclient.window = FW_W(fw); FSendEvent(dpy, FW_W(fw), False, NoEventMask, &e); } } } void HandleColormapNotify(const evh_args_t *ea) { colormap_handle_colormap_notify(ea); return; } void HandleConfigureRequest(const evh_args_t *ea) { XEvent *te = ea->exc->x.etrigger; XConfigureRequestEvent *cre; FvwmWindow *fw = ea->exc->w.fw; DBUG("HandleConfigureRequest", "Routine Entered"); cre = &te->xconfigurerequest; /* te->xany.window is te->.xconfigurerequest.parent, so the context * window may be wrong. */ if (XFindContext(dpy, cre->window, FvwmContext, (caddr_t *)&fw) == XCNOENT) { fw = NULL; } _handle_configure_request(te, ea, fw, False, ForgetGravity); return; } void HandleDestroyNotify(const evh_args_t *ea) { DBUG("HandleDestroyNotify", "Routine Entered"); destroy_window(ea->exc->w.fw); EWMH_ManageKdeSysTray( ea->exc->x.etrigger->xdestroywindow.window, ea->exc->x.etrigger->type); EWMH_WindowDestroyed(); return; } #define DEBUG_ENTERNOTIFY 0 #if DEBUG_ENTERNOTIFY static int ecount=0; #define ENTER_DBG(x) fprintf x; #else #define ENTER_DBG(x) #endif void HandleEnterNotify(const evh_args_t *ea) { const XEnterWindowEvent *ewp; XEvent d; FvwmWindow *sf; static Bool is_initial_ungrab_pending = True; Bool is_tear_off_menu; const XEvent *te = ea->exc->x.etrigger; FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandleEnterNotify", "Routine Entered"); ewp = &te->xcrossing; ENTER_DBG((stderr, "++++++++ en (%d): fw %p w 0x%08x sw 0x%08x mode 0x%x detail 0x%x '%s'\n", ++ecount, fw, (int)ewp->window, (int)ewp->subwindow, ewp->mode, ewp->detail, fw?fw->visible_name:"(none)")); if ( ewp->window == Scr.Root && ewp->detail == NotifyInferior && ewp->mode == NotifyNormal) { /* pointer left subwindow */ BroadcastPacket( MX_ENTER_WINDOW, 3, (long)Scr.Root, (long)NULL, (long)NULL); } else if ( ewp->window == Scr.Root && ewp->detail == NotifyNonlinearVirtual) { /* pointer entered screen */ BroadcastPacket( MX_ENTER_WINDOW, 3, (long)Scr.Root, (long)NULL, (long)NULL); } if (Scr.ColormapFocus == COLORMAP_FOLLOWS_MOUSE) { if (fw && !IS_ICONIFIED(fw) && ewp->window == FW_W(fw)) { InstallWindowColormaps(fw); } else { /* make sure its for one of our windows */ /* handle a subwindow cmap */ InstallWindowColormaps(NULL); } } else if (!fw) { EnterSubWindowColormap(ewp->window); } if (Scr.flags.is_wire_frame_displayed) { ENTER_DBG((stderr, "en: exit: iwfd\n")); /* Ignore EnterNotify events while a window is resized or moved * as a wire frame; otherwise the window list may be screwed * up. */ return; } if (fw) { if (ewp->window != FW_W_FRAME(fw) && ewp->window != FW_W_PARENT(fw) && ewp->window != FW_W(fw) && ewp->window != FW_W_ICON_TITLE(fw) && ewp->window != FW_W_ICON_PIXMAP(fw)) { /* Ignore EnterNotify that received by any of the sub * windows that don't handle this event. unclutter * triggers these events sometimes, re focusing an * unfocused window under the pointer */ ENTER_DBG((stderr, "en: exit: funny window\n")); return; } } if (Scr.focus_in_pending_window != NULL) { ENTER_DBG((stderr, "en: exit: fipw\n")); /* Ignore EnterNotify event while we are waiting for a window to * receive focus via Focus or FlipFocus commands. */ focus_grab_buttons(fw); return; } if (ewp->mode == NotifyGrab) { ENTER_DBG((stderr, "en: exit: NotifyGrab\n")); return; } else if (ewp->mode == NotifyNormal) { ENTER_DBG((stderr, "en: NotifyNormal\n")); if (ewp->detail == NotifyNonlinearVirtual && ewp->focus == False && ewp->subwindow != None) { /* This takes care of some buggy apps that forget that * one of their dialog subwindows has the focus after * popping up a selection list several times (ddd, * netscape). I'm not convinced that this does not * break something else. */ ENTER_DBG((stderr, "en: NN: refreshing focus\n")); refresh_focus(fw); } } else if (ewp->mode == NotifyUngrab) { ENTER_DBG((stderr, "en: NotifyUngrab\n")); /* Ignore events generated by grabbing or ungrabbing the * pointer. However, there is no way to prevent the client * application from handling this event and, for example, * grabbing the focus. This will interfere with functions that * transferred the focus to a different window. */ if (is_initial_ungrab_pending) { ENTER_DBG((stderr, "en: NU: initial ungrab pending (lgw = NULL)\n")); is_initial_ungrab_pending = False; xcrossing_last_grab_window = NULL; } else { if (ewp->detail == NotifyNonlinearVirtual && ewp->focus == False && ewp->subwindow != None) { /* see comment above */ ENTER_DBG((stderr, "en: NU: refreshing focus\n")); refresh_focus(fw); } if (fw && fw == xcrossing_last_grab_window) { ENTER_DBG((stderr, "en: exit: NU: is last grab window\n")); if (ewp->window == FW_W_FRAME(fw) || ewp->window == FW_W_ICON_TITLE(fw) || ewp->window == FW_W_ICON_PIXMAP(fw)) { ENTER_DBG((stderr, "en: exit: NU: last grab window = NULL\n")); xcrossing_last_grab_window = NULL; } focus_grab_buttons(fw); return; } else if (fw) { if (ewp->window != FW_W_FRAME(fw) && ewp->window != FW_W_ICON_TITLE(fw) && ewp->window != FW_W_ICON_PIXMAP(fw)) { ENTER_DBG((stderr, "en: exit: NU: not frame window\n")); focus_grab_buttons(fw); return; } } } } if (fw) { is_initial_ungrab_pending = False; } /* look for a matching leaveNotify which would nullify this EnterNotify */ /* * RBW - if we're in startup, this is a coerced focus, so we don't * want to save the event time, or exit prematurely. * * Ignore LeaveNotify events for tear out menus - handled by menu code */ is_tear_off_menu = (fw && IS_TEAR_OFF_MENU(fw) && ewp->window == FW_W(fw)); if (!fFvwmInStartup && !is_tear_off_menu && FCheckTypedWindowEvent(dpy, ewp->window, LeaveNotify, &d)) { if (d.xcrossing.mode == NotifyNormal && d.xcrossing.detail != NotifyInferior) { ENTER_DBG((stderr, "en: exit: found LeaveNotify\n")); return; } } if (ewp->window == Scr.Root) { FvwmWindow *lf = get_last_screen_focus_window(); if (!Scr.flags.is_pointer_on_this_screen) { Scr.flags.is_pointer_on_this_screen = 1; if (lf && lf != &Scr.FvwmRoot && !FP_DO_UNFOCUS_LEAVE(FW_FOCUS_POLICY(lf))) { SetFocusWindow(lf, True, FOCUS_SET_FORCE); } else if (lf != &Scr.FvwmRoot) { ForceDeleteFocus(); } else { /* This was the first EnterNotify event for the * root window - ignore */ } set_last_screen_focus_window(NULL); } else if (!(sf = get_focus_window()) || FP_DO_UNFOCUS_LEAVE(FW_FOCUS_POLICY(sf))) { DeleteFocus(True); } else if ( Scr.UnknownWinFocused != None && sf != NULL && sf == Scr.StolenFocusFvwmWin) { __refocus_stolen_focus_win(ea); } if (Scr.ColormapFocus == COLORMAP_FOLLOWS_MOUSE) { InstallWindowColormaps(NULL); } focus_grab_buttons(lf); return; } else { Scr.flags.is_pointer_on_this_screen = 1; } /* An EnterEvent in one of the PanFrameWindows activates the Paging or an EdgeCommand. */ if (is_pan_frame(ewp->window)) { char *edge_command = NULL; if ( Scr.UnknownWinFocused != None && (sf = get_focus_window()) != NULL && sf == Scr.StolenFocusFvwmWin) { __refocus_stolen_focus_win(ea); } /* check for edge commands */ if (ewp->window == Scr.PanFrameTop.win) { edge_command = Scr.PanFrameTop.command; } else if (ewp->window == Scr.PanFrameBottom.win) { edge_command = Scr.PanFrameBottom.command; } else if (ewp->window == Scr.PanFrameLeft.win) { edge_command = Scr.PanFrameLeft.command; } else if (ewp->window == Scr.PanFrameRight.win) { edge_command = Scr.PanFrameRight.command; } if (edge_command && ewp->mode == NotifyUngrab && ewp->detail == NotifyAncestor) { /* nothing */ } else if (edge_command) { execute_function(NULL, ea->exc, edge_command, 0); } else { /* no edge command for this pan frame - so we do * HandlePaging */ int delta_x = 0; int delta_y = 0; XEvent e; /* this was in the HandleMotionNotify before, HEDU */ Scr.flags.is_pointer_on_this_screen = 1; e = *te; HandlePaging( &e, Scr.EdgeScrollX, Scr.EdgeScrollY, &JunkX, &JunkY, &delta_x, &delta_y, True, True, False, Scr.ScrollDelay); return; } } if (!fw) { return; } if (IS_EWMH_DESKTOP(FW_W(fw))) { BroadcastPacket( MX_ENTER_WINDOW, 3, (long)Scr.Root, (long)NULL, (long)NULL); return; } if (ewp->window == FW_W_FRAME(fw) || ewp->window == FW_W_ICON_TITLE(fw) || ewp->window == FW_W_ICON_PIXMAP(fw)) { BroadcastPacket( MX_ENTER_WINDOW, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); } sf = get_focus_window(); if (sf && fw != sf && FP_DO_UNFOCUS_LEAVE(FW_FOCUS_POLICY(sf))) { ENTER_DBG((stderr, "en: delete focus\n")); DeleteFocus(True); } focus_grab_buttons(fw); if (FP_DO_FOCUS_ENTER(FW_FOCUS_POLICY(fw))) { ENTER_DBG((stderr, "en: set mousey focus\n")); if (ewp->window == FW_W(fw)) { /* Event is for the client window...*/ #ifndef EXPERIMENTAL_ROU_HANDLING_V2 /* RBW -- This may still be needed at times, I'm not *sure yet. */ SetFocusWindowClientEntered( fw, True, FOCUS_SET_BY_ENTER); #else SetFocusWindow(fw, True, FOCUS_SET_BY_ENTER); #endif } else { /* Event is for the frame...*/ SetFocusWindow(fw, True, FOCUS_SET_BY_ENTER); } } else if (focus_is_focused(fw) && focus_does_accept_input_focus(fw)) { /* We have to refresh the focus window here in case we left the * focused fvwm window. Motif apps may lose the input focus * otherwise. But do not try to refresh the focus of * applications that want to handle it themselves. */ focus_force_refresh_focus(fw); } else if (sf != fw) { /* Give the window a chance to grab the buttons needed for * raise-on-click */ focus_grab_buttons(sf); } if ( Scr.UnknownWinFocused != None && sf != NULL && sf == Scr.StolenFocusFvwmWin) { __refocus_stolen_focus_win(ea); } /* We get an EnterNotify with mode == UnGrab when fvwm releases the * grab held during iconification. We have to ignore this, or icon * title will be initially raised. */ if (IS_ICONIFIED(fw) && (ewp->mode == NotifyNormal) && (ewp->window == FW_W_ICON_PIXMAP(fw) || ewp->window == FW_W_ICON_TITLE(fw)) && FW_W_ICON_PIXMAP(fw) != None) { SET_ICON_ENTERED(fw, 1); DrawIconWindow(fw, True, False, False, False, NULL); } /* Check for tear off menus */ if (is_tear_off_menu) { menu_enter_tear_off_menu(ea->exc); } return; } void HandleExpose(const evh_args_t *ea) { XEvent e; FvwmWindow * const fw = ea->exc->w.fw; e = *ea->exc->x.etrigger; #if 0 /* This doesn't work well. Sometimes, the expose count is zero although * dozens of expose events are pending. This happens all the time * during a shading animation. Simply flush expose events * unconditionally. */ if (e.xexpose.count != 0) { flush_accumulate_expose(e.xexpose.window, &e); } #else flush_accumulate_expose(e.xexpose.window, &e); #endif if (fw == NULL) { return; } if (e.xany.window == FW_W_ICON_TITLE(fw) || e.xany.window == FW_W_ICON_PIXMAP(fw)) { DrawIconWindow(fw, True, True, False, False, &e); return; } else if (IS_TEAR_OFF_MENU(fw) && e.xany.window == FW_W(fw)) { /* refresh the contents of the torn out menu */ menu_expose(&e, NULL); } return; } void HandleFocusIn(const evh_args_t *ea) { XEvent d; Window w = None; Window focus_w = None; Window focus_fw = None; Pixel fc = 0; Pixel bc = 0; FvwmWindow *ffw_old = get_focus_window(); FvwmWindow *sf; Bool do_force_broadcast = False; Bool is_unmanaged_focused = False; static Window last_focus_w = None; static Window last_focus_fw = None; static Bool was_nothing_ever_focused = True; FvwmWindow *fw = ea->exc->w.fw; DBUG("HandleFocusIn", "Routine Entered"); Scr.focus_in_pending_window = NULL; /* This is a hack to make the PointerKey command work */ if (ea->exc->x.etrigger->xfocus.detail != NotifyPointer) { /**/ w = ea->exc->x.etrigger->xany.window; } while (FCheckTypedEvent(dpy, FocusIn, &d)) { /* dito */ if (d.xfocus.detail != NotifyPointer) { /**/ w = d.xany.window; } } /* dito */ if (w == None) { return; } /**/ if (XFindContext(dpy, w, FvwmContext, (caddr_t *) &fw) == XCNOENT) { fw = NULL; } Scr.UnknownWinFocused = None; if ( fw && Scr.focus_in_requested_window != fw && !FP_DO_FOCUS_BY_PROGRAM(FW_FOCUS_POLICY(fw)) && fw->focus_model == FM_GLOBALLY_ACTIVE) { if (DEBUG_GLOBALLY_ACTIVE) { fprintf( stderr, "prevented globally active fw %p (%s)" " from stealing the focus\n", fw, fw->name.name); fprintf( stderr, "window was %p (%s)\n", Scr.focus_in_pending_window, Scr.focus_in_pending_window ? Scr.focus_in_pending_window->name.name : ""); } Scr.focus_in_requested_window = NULL; __refocus_stolen_focus_win(ea); return; } Scr.focus_in_pending_window = NULL; if (!fw) { if (w != Scr.NoFocusWin) { Scr.UnknownWinFocused = w; Scr.StolenFocusWin = (ffw_old != NULL) ? FW_W(ffw_old) : None; Scr.StolenFocusFvwmWin = ffw_old; focus_w = w; is_unmanaged_focused = True; } /* Only show a non-focused window as focused, * if the focus is on unmanaged and flickering qt dialogs * workaround is on. */ if (!Scr.bo.do_enable_flickering_qt_dialogs_workaround || !is_unmanaged_focused) { border_draw_decorations( Scr.Hilite, PART_ALL, False, True, CLEAR_ALL, NULL, NULL); if (Scr.ColormapFocus == COLORMAP_FOLLOWS_FOCUS) { if ((Scr.Hilite)&&(!IS_ICONIFIED(Scr.Hilite))) { InstallWindowColormaps(Scr.Hilite); } else { InstallWindowColormaps(NULL); } } } /* Not very useful if no window that fvwm and its modules know * about has the focus. */ fc = GetColor(DEFAULT_FORE_COLOR); bc = GetColor(DEFAULT_BACK_COLOR); } else if (fw != Scr.Hilite || /* domivogt (16-May-2000): This check is necessary to force * sending a M_FOCUS_CHANGE packet after an unmanaged window * was focused. Otherwise fvwm would believe that Scr.Hilite * was still focused and not send any info to the modules. */ last_focus_fw == None || IS_FOCUS_CHANGE_BROADCAST_PENDING(fw) || fpol_query_allow_user_focus(&FW_FOCUS_POLICY(fw))) { if (w != Scr.NoFocusWin) { Scr.StolenFocusWin = (ffw_old != NULL) ? FW_W(ffw_old) : None; Scr.StolenFocusFvwmWin = ffw_old; } do_force_broadcast = IS_FOCUS_CHANGE_BROADCAST_PENDING(fw); SET_FOCUS_CHANGE_BROADCAST_PENDING(fw, 0); if (fw != Scr.Hilite && fpol_query_allow_user_focus(&FW_FOCUS_POLICY(fw))) { border_draw_decorations( fw, PART_ALL, True, True, CLEAR_ALL, NULL, NULL); } focus_w = FW_W(fw); focus_fw = FW_W_FRAME(fw); fc = fw->hicolors.fore; bc = fw->hicolors.back; set_focus_window(fw); if (Scr.ColormapFocus == COLORMAP_FOLLOWS_FOCUS) { if ((Scr.Hilite)&&(!IS_ICONIFIED(Scr.Hilite))) { InstallWindowColormaps(Scr.Hilite); } else { InstallWindowColormaps(NULL); } } } else { return; } if (was_nothing_ever_focused || last_focus_fw == None || focus_w != last_focus_w || focus_fw != last_focus_fw || do_force_broadcast) { if (!Scr.bo.do_enable_flickering_qt_dialogs_workaround || !is_unmanaged_focused) { BroadcastPacket( M_FOCUS_CHANGE, 5, (long)focus_w, (long)focus_fw, (unsigned long)IsLastFocusSetByMouse(), (long)fc, (long)bc); EWMH_SetActiveWindow(focus_w); } last_focus_w = focus_w; last_focus_fw = focus_fw; was_nothing_ever_focused = False; } if ((sf = get_focus_window()) != ffw_old) { focus_grab_buttons(sf); focus_grab_buttons(ffw_old); } return; } void HandleFocusOut(const evh_args_t *ea) { if (Scr.UnknownWinFocused != None && Scr.StolenFocusWin != None && ea->exc->x.etrigger->xfocus.window == Scr.UnknownWinFocused) { __refocus_stolen_focus_win(ea); } return; } void __handle_key(const evh_args_t *ea, Bool is_press) { char *action; FvwmWindow *sf; KeyCode kc; int kcontext; const XEvent *te = ea->exc->x.etrigger; const FvwmWindow * const fw = ea->exc->w.fw; Bool is_second_binding; const XClassHint *winClass1, *winClass2; XClassHint tmp; char *name1, *name2; const exec_context_t *exc; exec_context_changes_t ecc; PressedW = None; /* Here's a real hack - some systems have two keys with the * same keysym and different keycodes. This converts all * the cases to one keycode. */ kc = XKeysymToKeycode(dpy, fvwm_KeycodeToKeysym(dpy, te->xkey.keycode, 0, 0)); /* Check if there is something bound to the key */ sf = get_focus_window(); if (sf == NULL) { tmp.res_name = tmp.res_class = name1 = "root"; winClass1 = &tmp; kcontext = C_ROOT; } else { winClass1 = &sf->class; name1 = sf->name.name; kcontext = (sf == fw ? ea->exc->w.wcontext : C_WINDOW); } if (fw == NULL) { tmp.res_name = tmp.res_class = name2 = "root"; winClass2 = &tmp; } else { winClass2 = &fw->class; name2 = fw->name.name; } /* Searching the binding list with a different 'type' value * (ie. BIND_KEYPRESS vs BIND_PKEYPRESS) doesn't make a difference. * The different context value does though. */ action = CheckTwoBindings( &is_second_binding, Scr.AllBindings, STROKE_ARG(0) kc, te->xkey.state, GetUnusedModifiers(), kcontext, BIND_KEYPRESS, winClass1, name1, ea->exc->w.wcontext, BIND_PKEYPRESS, winClass2, name2); if (action != NULL) { if (!is_press) { XAllowEvents(dpy, AsyncKeyboard, CurrentTime); return; } exc = ea->exc; if (is_second_binding == False) { ecc.w.fw = sf; ecc.w.wcontext = kcontext; exc = exc_clone_context( ea->exc, &ecc, ECC_FW | ECC_WCONTEXT); } execute_function(NULL, exc, action, 0); if (is_second_binding == False) { exc_destroy_context(exc); } XAllowEvents(dpy, AsyncKeyboard, CurrentTime); return; } /* if we get here, no function key was bound to the key. Send it * to the client if it was in a window we know about. */ sf = get_focus_window(); if (sf && te->xkey.window != FW_W(sf)) { XEvent e; e = *te; e.xkey.window = FW_W(sf); FSendEvent( dpy, e.xkey.window, False, (is_press)? KeyPressMask:KeyReleaseMask, &e); } else if (fw && te->xkey.window != FW_W(fw)) { XEvent e; e = *te; e.xkey.window = FW_W(fw); FSendEvent( dpy, e.xkey.window, False, (is_press)? KeyPressMask:KeyReleaseMask, &e); } XAllowEvents(dpy, AsyncKeyboard, CurrentTime); return; } void HandleKeyPress(const evh_args_t *ea) { __handle_key(ea, True); } void HandleKeyRelease(const evh_args_t *ea) { __handle_key(ea, False); } void HandleLeaveNotify(const evh_args_t *ea) { const XLeaveWindowEvent *lwp; const XEvent *te = ea->exc->x.etrigger; FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandleLeaveNotify", "Routine Entered"); ENTER_DBG((stderr, "-------- ln (%d): fw %p w 0x%08x sw 0x%08x mode 0x%x detail 0x%x '%s'\n", ++ecount, fw, (int)te->xcrossing.window, (int)te->xcrossing.subwindow, te->xcrossing.mode, te->xcrossing.detail, fw?fw->visible_name:"(none)")); lwp = &te->xcrossing; if ( lwp->window == Scr.Root && lwp->detail == NotifyInferior && lwp->mode == NotifyNormal) { /* pointer entered subwindow */ BroadcastPacket( MX_LEAVE_WINDOW, 3, (long)Scr.Root, (long)NULL, (long)NULL); } else if ( lwp->window == Scr.Root && lwp->detail == NotifyNonlinearVirtual) { /* pointer left screen */ BroadcastPacket( MX_LEAVE_WINDOW, 3, (long)Scr.Root, (long)NULL, (long)NULL); } /* Ignore LeaveNotify events while a window is resized or moved as a * wire frame; otherwise the window list may be screwed up. */ if (Scr.flags.is_wire_frame_displayed) { return; } if (lwp->mode != NotifyNormal) { /* Ignore events generated by grabbing or ungrabbing the * pointer. However, there is no way to prevent the client * application from handling this event and, for example, * grabbing the focus. This will interfere with functions that * transferred the focus to a different window. It is * necessary to check for LeaveNotify events on the client * window too in case buttons are not grabbed on it. */ if (lwp->mode == NotifyGrab && fw && (lwp->window == FW_W_FRAME(fw) || lwp->window == FW_W(fw) || lwp->window == FW_W_ICON_TITLE(fw) || lwp->window == FW_W_ICON_PIXMAP(fw))) { ENTER_DBG((stderr, "ln: *** lgw = %p\n", fw)); xcrossing_last_grab_window = fw; } #ifdef FOCUS_EXPANDS_TITLE if (fw && IS_ICONIFIED(fw)) { SET_ICON_ENTERED(fw, 0); DrawIconWindow( fw, True, False, False, False, NULL); } #endif return; } /* CDE-like behaviour of raising the icon title if the icon gets the focus (in particular if the cursor is over the icon) */ if (fw && IS_ICONIFIED(fw)) { SET_ICON_ENTERED(fw,0); DrawIconWindow(fw, True, False, False, False, NULL); } /* An LeaveEvent in one of the PanFrameWindows activates an EdgeLeaveCommand. */ if (is_pan_frame(lwp->window)) { char *edge_command_leave = NULL; /* check for edge commands */ if (lwp->window == Scr.PanFrameTop.win) { edge_command_leave = Scr.PanFrameTop.command_leave; } else if (lwp->window == Scr.PanFrameBottom.win) { edge_command_leave = Scr.PanFrameBottom.command_leave; } else if (lwp->window == Scr.PanFrameLeft.win) { edge_command_leave = Scr.PanFrameLeft.command_leave; } else if (lwp->window == Scr.PanFrameRight.win) { edge_command_leave = Scr.PanFrameRight.command_leave; } if (edge_command_leave && lwp->mode == NotifyUngrab && lwp->detail == NotifyAncestor) { /* nothing */ } else if (edge_command_leave) { execute_function(NULL, ea->exc, edge_command_leave, 0); } } /* If we leave the root window, then we're really moving * another screen on a multiple screen display, and we * need to de-focus and unhighlight to make sure that we * don't end up with more than one highlighted window at a time */ if (lwp->window == Scr.Root && /* domivogt (16-May-2000): added this test because somehow fvwm * sometimes gets a LeaveNotify on the root window although it is * single screen. */ Scr.NumberOfScreens > 1) { if (lwp->mode == NotifyNormal) { if (lwp->detail != NotifyInferior) { FvwmWindow *sf = get_focus_window(); Scr.flags.is_pointer_on_this_screen = 0; set_last_screen_focus_window(sf); if (sf != NULL) { DeleteFocus(True); } if (Scr.Hilite != NULL) { border_draw_decorations( Scr.Hilite, PART_ALL, False, True, CLEAR_ALL, NULL, NULL); } } } } else { /* handle a subwindow cmap */ LeaveSubWindowColormap(te->xany.window); } if (fw != NULL && (lwp->window == FW_W_FRAME(fw) || lwp->window == FW_W_ICON_TITLE(fw) || lwp->window == FW_W_ICON_PIXMAP(fw))) { BroadcastPacket( MX_LEAVE_WINDOW, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); } return; } void HandleMapNotify(const evh_args_t *ea) { Bool is_on_this_page = False; const XEvent *te = ea->exc->x.etrigger; FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandleMapNotify", "Routine Entered"); if (!fw) { if (te->xmap.override_redirect == True && te->xmap.window != Scr.NoFocusWin) { XSelectInput(dpy, te->xmap.window, XEVMASK_ORW); XFlush(dpy); Scr.UnknownWinFocused = te->xmap.window; } return; } if (te->xmap.window == FW_W_FRAME(fw)) { /* Now that we know the frame is mapped after capturing the * window we do not need StructureNotifyMask events anymore. */ XSelectInput(dpy, FW_W_FRAME(fw), XEVMASK_FRAMEW); XFlush(dpy); } /* Except for identifying over-ride redirect window mappings, we * don't need or want windows associated with the * SubstructureNotifyMask */ if (te->xmap.event != te->xmap.window) { return; } SET_MAP_PENDING(fw, 0); /* don't map if the event was caused by a de-iconify */ if (IS_ICONIFY_PENDING(fw)) { return; } /* Make sure at least part of window is on this page before giving it * focus... */ is_on_this_page = IsRectangleOnThisPage(&(fw->g.frame), fw->Desk); /* * Need to do the grab to avoid race condition of having server send * MapNotify to client before the frame gets mapped; this is bad because * the client would think that the window has a chance of being viewable * when it really isn't. */ MyXGrabServer (dpy); if (FW_W_ICON_TITLE(fw)) { XUnmapWindow(dpy, FW_W_ICON_TITLE(fw)); } if (FW_W_ICON_PIXMAP(fw) != None) { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } XMapSubwindows(dpy, FW_W_FRAME(fw)); if (fw->Desk == Scr.CurrentDesk) { XMapWindow(dpy, FW_W_FRAME(fw)); } if (IS_ICONIFIED(fw)) { BroadcastPacket( M_DEICONIFY, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); } else { BroadcastPacket( M_MAP, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); } if (is_on_this_page && focus_query_open_grab_focus(fw, get_focus_window()) == True) { SetFocusWindow(fw, True, FOCUS_SET_FORCE); } border_draw_decorations( fw, PART_ALL, (fw == get_focus_window()) ? True : False, True, CLEAR_ALL, NULL, NULL); MyXUngrabServer (dpy); SET_MAPPED(fw, 1); SET_ICONIFIED(fw, 0); SET_ICON_UNMAPPED(fw, 0); if (DO_ICONIFY_AFTER_MAP(fw)) { initial_window_options_t win_opts; /* finally, if iconification was requested before the window * was mapped, request it now. */ memset(&win_opts, 0, sizeof(win_opts)); Iconify(fw, &win_opts); SET_ICONIFY_AFTER_MAP(fw, 0); } focus_grab_buttons_on_layer(fw->layer); return; } void HandleMappingNotify(const evh_args_t *ea) { XRefreshKeyboardMapping(&ea->exc->x.etrigger->xmapping); return; } void HandleMapRequest(const evh_args_t *ea) { DBUG("HandleMapRequest", "Routine Entered"); if (fFvwmInStartup) { /* Just map the damn thing, decorations are added later * in CaptureAllWindows. */ XMapWindow(dpy, ea->exc->x.etrigger->xmaprequest.window); return; } HandleMapRequestKeepRaised(ea, None, NULL, NULL); return; } void HandleMapRequestKeepRaised( const evh_args_t *ea, Window KeepRaised, FvwmWindow *ReuseWin, initial_window_options_t *win_opts) { Bool is_on_this_page = False; Bool is_new_window = False; FvwmWindow *tmp; FvwmWindow *sf; initial_window_options_t win_opts_bak; Window ew; FvwmWindow *fw; extern Bool Restarting; const char *initial_map_command; initial_map_command = NULL; if (win_opts == NULL) { memset(&win_opts_bak, 0, sizeof(win_opts_bak)); win_opts = &win_opts_bak; } ew = ea->exc->w.w; if (ReuseWin == NULL) { if (XFindContext(dpy, ew, FvwmContext, (caddr_t *)&fw) == XCNOENT) { fw = NULL; } if (fw != NULL && IS_MAP_PENDING(fw)) { /* The window is already going to be mapped, no need to * do that twice */ return; } } else { fw = ReuseWin; } if (fw == NULL && EWMH_IsKdeSysTrayWindow(ew)) { /* This means that the window is swallowed by kicker and that * kicker restart or exit. As we should assume that kicker * restart we should return here, if not we go into trouble * ... */ return; } if (!win_opts->flags.do_override_ppos) { XFlush(dpy); } /* If the window has never been mapped before ... */ if (!fw || (fw && DO_REUSE_DESTROYED(fw))) { check_if_event_args args; XEvent dummy; args.w = ew; args.do_return_true = True; args.do_return_true_cr = False; if ( FCheckIfEvent( dpy, &dummy, test_withdraw_request, (XPointer)&args)) { /* The window is moved back to the WithdrawnState * immideately. Don't map it. * * However, send make sure that a WM_STATE * PropertyNotify event is sent to the window. * QT needs this. */ Atom atype; int aformat; unsigned long nitems, bytes_remain; unsigned char *prop; if ( XGetWindowProperty( dpy, ew, _XA_WM_STATE, 0L, 3L, False, _XA_WM_STATE, &atype, &aformat, &nitems,&bytes_remain,&prop) == Success) { if (prop != NULL) { XFree(prop); XDeleteProperty(dpy, ew, _XA_WM_STATE); } else { XPropertyEvent ev; ev.type = PropertyNotify; ev.display = dpy; ev.window = ew; ev.atom = _XA_WM_STATE; ev.time = fev_get_evtime(); ev.state = PropertyDelete; FSendEvent( dpy, ew, True, PropertyChangeMask, (XEvent*)&ev); } } return; } /* Add decorations. */ fw = AddWindow( &initial_map_command, ea->exc, ReuseWin, win_opts); if (fw == AW_NO_WINDOW) { return; } else if (fw == AW_UNMANAGED) { XMapWindow(dpy, ew); return; } is_new_window = True; } /* * Make sure at least part of window is on this page * before giving it focus... */ is_on_this_page = IsRectangleOnThisPage(&(fw->g.frame), fw->Desk); if (KeepRaised != None) { XRaiseWindow(dpy, KeepRaised); } /* If it's not merely iconified, and we have hints, use them. */ if (IS_ICONIFIED(fw)) { /* If no hints, or currently an icon, just "deiconify" */ DeIconify(fw); } else if (IS_MAPPED(fw)) { /* the window is already mapped - fake a MapNotify event */ fake_map_unmap_notify(fw, MapNotify); } else { int state; if (fw->wmhints && (fw->wmhints->flags & StateHint)) { state = fw->wmhints->initial_state; } else { state = NormalState; } if (win_opts->initial_state != DontCareState) { state = win_opts->initial_state; } switch (state) { case DontCareState: case NormalState: case InactiveState: default: MyXGrabServer(dpy); if (fw->Desk == Scr.CurrentDesk) { Bool do_grab_focus; SET_MAP_PENDING(fw, 1); XMapWindow(dpy, FW_W_FRAME(fw)); XMapWindow(dpy, FW_W(fw)); SetMapStateProp(fw, NormalState); if (Scr.flags.is_map_desk_in_progress) { do_grab_focus = False; } else if (!is_on_this_page) { do_grab_focus = False; } else if (focus_query_open_grab_focus( fw, get_focus_window()) == True) { do_grab_focus = True; } else { do_grab_focus = False; } if (do_grab_focus) { SetFocusWindow( fw, True, FOCUS_SET_FORCE); } else { /* make sure the old focused window * still has grabbed all necessary * buttons. */ focus_grab_buttons( get_focus_window()); } } else { #ifndef ICCCM2_UNMAP_WINDOW_PATCH /* nope, this is forbidden by the ICCCM2 */ XMapWindow(dpy, FW_W(fw)); SetMapStateProp(fw, NormalState); #else /* Since we will not get a MapNotify, set the * IS_MAPPED flag manually. */ SET_MAPPED(fw, 1); SetMapStateProp(fw, IconicState); /* fake that the window was mapped to allow * modules to swallow it */ BroadcastPacket( M_MAP, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); #endif } /* TA: 20090125: We *have* to handle * InitialMapCommand here and not in AddWindow() to * allow for correct timings when the window is truly * mapped. (c.f. things like Iconify.) */ /* TA: 20091212: But only do this when we're *not* * restarting -- the window is still mapped, but gets * recaptured -- we don't want to trigger this event * again. Otherwise we end up toggling the state of * the window in situations where the * InitialMapCommand is Iconify or Maximize, for * instance. */ if ((initial_map_command != NULL) && (!Restarting && Scr.flags.are_windows_captured)) { execute_function_override_window( NULL, ea->exc, (char *)initial_map_command, 0, fw); } MyXUngrabServer(dpy); break; case IconicState: if (is_new_window) { /* the window will not be mapped - fake a * MapNotify and an UnmapNotify event. Can't * remember exactly why this is necessary, but * probably something w/ (de)iconify state * confusion. */ fake_map_unmap_notify(fw, MapNotify); fake_map_unmap_notify(fw, UnmapNotify); } if (win_opts->flags.is_iconified_by_parent || ((tmp = get_transientfor_fvwmwindow(fw)) && IS_ICONIFIED(tmp))) { win_opts->flags.is_iconified_by_parent = 0; SET_ICONIFIED_BY_PARENT(fw, 1); } if (USE_ICON_POSITION_HINT(fw) && fw->wmhints && (fw->wmhints->flags & IconPositionHint)) { win_opts->default_icon_x = fw->wmhints->icon_x; win_opts->default_icon_y = fw->wmhints->icon_y; } Iconify(fw, win_opts); break; } } if (IS_SHADED(fw)) { BroadcastPacket( M_WINDOWSHADE, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); } /* If the newly mapped window overlaps the focused window, make sure * ClickToFocusRaises and MouseFocusClickRaises work again. */ sf = get_focus_window(); if (sf != NULL) { focus_grab_buttons(sf); } if (win_opts->flags.is_menu) { SET_MAPPED(fw, 1); SET_MAP_PENDING(fw, 0); } EWMH_SetClientList(); EWMH_SetClientListStacking(); return; } #ifdef HAVE_STROKE void HandleMotionNotify(const evh_args_t *ea) { DBUG("HandleMotionNotify", "Routine Entered"); if (send_motion == True) { stroke_record( ea->exc->x.etrigger->xmotion.x, ea->exc->x.etrigger->xmotion.y); } return; } #endif /* HAVE_STROKE */ void HandlePropertyNotify(const evh_args_t *ea) { Bool has_icon_changed = False; Bool has_icon_pixmap_hint_changed = False; Bool has_icon_window_hint_changed = False; /* NoName is an extern pointer to a constant "Untitled". See lib/Flocale.c FlocaleFreeNameProperty to see how this initialization causes a problem: */ FlocaleNameString new_name = { NoName, NULL }; int old_wmhints_flags; const XEvent *te = ea->exc->x.etrigger; char *urgency_action = NULL; FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandlePropertyNotify", "Routine Entered"); if (te->xproperty.window == Scr.Root && te->xproperty.state == PropertyNewValue && (te->xproperty.atom == _XA_XSETROOT_ID || te->xproperty.atom == _XA_XROOTPMAP_ID)) { /* background change */ /* _XA_XSETROOT_ID is used by fvwm-root, xli and more (xv sends * no property notify?). _XA_XROOTPMAP_ID is used by Esetroot * compatible program: the problem here is that with some * Esetroot compatible program we get the message _before_ the * background change. This is fixed with Esetroot 9.2 (not yet * released, 2002-01-14) */ /* update icon window with some alpha and tear-off menu */ FvwmWindow *t; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { int cs; int t_cs = -1; int b_cs = t->icon_background_cs; Bool draw_picture = False; Bool draw_title = False; /* redraw ParentRelative tear-off menu */ menu_redraw_transparent_tear_off_menu(t, True); if (!IS_ICONIFIED(t) || IS_ICON_SUPPRESSED(t)) { continue; } if (Scr.Hilite == t) { if (t->icon_title_cs_hi >= 0) { t_cs = cs = t->icon_title_cs_hi; } else { cs = t->cs_hi; } } else { if (t->icon_title_cs >= 0) { t_cs = cs = t->icon_title_cs; } else { cs = t->cs; } } if (t->icon_alphaPixmap != None || (cs >= 0 && Colorset[cs].icon_alpha_percent < 100) || CSET_IS_TRANSPARENT_PR(b_cs) || (!IS_ICON_SHAPED(t) && t->icon_background_padding > 0)) { draw_picture = True; } if (CSET_IS_TRANSPARENT_PR(t_cs)) { draw_title = True; } if (draw_title || draw_picture) { DrawIconWindow( t, draw_title, draw_picture, False, draw_picture, NULL); } } if (te->xproperty.atom == _XA_XROOTPMAP_ID) { update_root_transparent_colorset(te->xproperty.atom); } BroadcastPropertyChange( MX_PROPERTY_CHANGE_BACKGROUND, 0, 0, ""); return; } if (!fw) { return; } switch (te->xproperty.atom) { case XA_WM_TRANSIENT_FOR: { if (setup_transientfor(fw) == True) { RaiseWindow(fw, False); } break; } case XA_WM_NAME: { flush_property_notify_stop_at_event_type( te->xproperty.atom, FW_W(fw), 0, 0); if (XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { /* Window does not exist anymore. */ return; } if (HAS_EWMH_WM_NAME(fw)) { return; } FlocaleGetNameProperty(XGetWMName, dpy, FW_W(fw), &new_name); if (new_name.name == NULL) { FlocaleFreeNameProperty(&new_name); return; } if (strlen(new_name.name) > MAX_WINDOW_NAME_LEN) { /* limit to prevent hanging X server */ (new_name.name)[MAX_WINDOW_NAME_LEN] = 0; } if (fw->name.name && strcmp(new_name.name, fw->name.name) == 0) { /* migo: some apps update their names every second */ /* griph: make sure we don't free the property if it is THE same name */ if (new_name.name != fw->name.name) { FlocaleFreeNameProperty(&new_name); } return; } free_window_names(fw, True, False); fw->name = new_name; SET_NAME_CHANGED(fw, 1); if (fw->name.name == NULL) { fw->name.name = NoName; /* must not happen */ } setup_visible_name(fw, False); BroadcastWindowIconNames(fw, True, False); /* fix the name in the title bar */ if (!IS_ICONIFIED(fw)) { border_draw_decorations( fw, PART_TITLE, (Scr.Hilite == fw), True, CLEAR_ALL, NULL, NULL); } EWMH_SetVisibleName(fw, False); /* * if the icon name is NoName, set the name of the icon to be * the same as the window */ if (!WAS_ICON_NAME_PROVIDED(fw) #if 0 /* dje, reported as causing various dumps. I tried to debug, but so far haven't even figured out how to exercise this logic. Mov 9, 2013. */ || (fw->icon_name.name && (fw->icon_name.name != fw->name.name)) #endif ) { fw->icon_name = fw->name; setup_visible_name(fw, True); BroadcastWindowIconNames(fw, False, True); RedoIconName(fw); } break; } case XA_WM_ICON_NAME: { flush_property_notify_stop_at_event_type( te->xproperty.atom, FW_W(fw), 0, 0); if (XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { /* Window does not exist anymore. */ return; } if (HAS_EWMH_WM_ICON_NAME(fw)) { return; } FlocaleGetNameProperty( XGetWMIconName, dpy, FW_W(fw), &new_name); if (new_name.name == NULL) { FlocaleFreeNameProperty(&new_name); return; } if (new_name.name && strlen(new_name.name) > MAX_ICON_NAME_LEN) { /* limit to prevent hanging X server */ (new_name.name)[MAX_ICON_NAME_LEN] = 0; } if (fw->icon_name.name && strcmp(new_name.name, fw->icon_name.name) == 0) { /* migo: some apps update their names every second */ /* griph: make sure we don't free the property if it is THE same name */ if (new_name.name != fw->icon_name.name) { FlocaleFreeNameProperty(&new_name); } return; } free_window_names(fw, False, True); fw->icon_name = new_name; SET_WAS_ICON_NAME_PROVIDED(fw, 1); if (fw->icon_name.name == NULL) { /* currently never happens */ fw->icon_name.name = fw->name.name; SET_WAS_ICON_NAME_PROVIDED(fw, 0); } setup_visible_name(fw, True); BroadcastWindowIconNames(fw, False, True); RedoIconName(fw); EWMH_SetVisibleName(fw, True); break; } case XA_WM_HINTS: { flush_property_notify_stop_at_event_type( te->xproperty.atom, FW_W(fw), 0, 0); if (XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { /* Window does not exist anymore. */ return; } /* clasen@mathematik.uni-freiburg.de - 02/01/1998 - new - * the urgency flag is an ICCCM 2.0 addition to the WM_HINTS. */ old_wmhints_flags = 0; if (fw->wmhints) { old_wmhints_flags = fw->wmhints->flags; XFree ((char *) fw->wmhints); } setup_wm_hints(fw); if (fw->wmhints == NULL) { return; } /* * rebuild icon if the client either provides an icon * pixmap or window or has reset the hints to `no icon'. */ if ((fw->wmhints->flags & IconPixmapHint) || (old_wmhints_flags & IconPixmapHint)) { ICON_DBG((stderr, "hpn: iph changed (%d) '%s'\n", !!(int)(fw->wmhints->flags & IconPixmapHint), fw->name.name)); has_icon_pixmap_hint_changed = True; } if ((fw->wmhints->flags & IconWindowHint) || (old_wmhints_flags & IconWindowHint)) { ICON_DBG((stderr, "hpn: iwh changed (%d) '%s'\n", !!(int)(fw->wmhints->flags & IconWindowHint), fw->name.name)); has_icon_window_hint_changed = True; SET_USE_EWMH_ICON(fw, False); } increase_icon_hint_count(fw); if (has_icon_window_hint_changed || has_icon_pixmap_hint_changed) { if (ICON_OVERRIDE_MODE(fw) == ICON_OVERRIDE) { ICON_DBG((stderr, "hpn: icon override '%s'\n", fw->name.name)); has_icon_changed = False; } else if (ICON_OVERRIDE_MODE(fw) == NO_ACTIVE_ICON_OVERRIDE) { if (has_icon_pixmap_hint_changed) { if (WAS_ICON_HINT_PROVIDED(fw) == ICON_HINT_MULTIPLE) { ICON_DBG((stderr, "hpn: using further iph '%s'\n", fw->name.name)); has_icon_changed = True; } else if (fw->icon_bitmap_file == NULL || fw->icon_bitmap_file == Scr.DefaultIcon) { ICON_DBG((stderr, "hpn: using first iph '%s'\n", fw->name.name)); has_icon_changed = True; } else { /* ignore the first icon pixmap * hint if the application did * not provide it from the * start */ ICON_DBG((stderr, "hpn: first iph ignored '%s'\n", fw->name.name)); has_icon_changed = False; } } else if (has_icon_window_hint_changed) { ICON_DBG((stderr, "hpn: using iwh '%s'\n", fw->name.name)); has_icon_changed = True; } else { ICON_DBG((stderr, "hpn: iwh not changed, hint ignored '%s'\n", fw->name.name)); has_icon_changed = False; } } else /* NO_ICON_OVERRIDE */ { ICON_DBG((stderr, "hpn: using hint '%s'\n", fw->name.name)); has_icon_changed = True; } if (USE_EWMH_ICON(fw)) { has_icon_changed = False; } if (has_icon_changed) { ICON_DBG((stderr, "hpn: icon changed '%s'\n", fw->name.name)); /* Okay, the icon hint has changed and style * options tell us to honour this change. Now * let's see if we have to use the application * provided pixmap or window (if any), the icon * file provided by the window's style or the * default style's icon. */ if (fw->icon_bitmap_file == Scr.DefaultIcon) { fw->icon_bitmap_file = NULL; } if (!fw->icon_bitmap_file && !(fw->wmhints->flags & (IconPixmapHint|IconWindowHint))) { fw->icon_bitmap_file = (Scr.DefaultIcon) ? Scr.DefaultIcon : NULL; } fw->iconPixmap = (Window)NULL; ChangeIconPixmap(fw); } } /* clasen@mathematik.uni-freiburg.de - 02/01/1998 - new - * the urgency flag is an ICCCM 2.0 addition to the WM_HINTS. * Treat urgency changes by calling user-settable functions. * These could e.g. deiconify and raise the window or * temporarily change the decor. */ if (!(old_wmhints_flags & XUrgencyHint) && (fw->wmhints->flags & XUrgencyHint)) { urgency_action = "Function UrgencyFunc"; } if ((old_wmhints_flags & XUrgencyHint) && !(fw->wmhints->flags & XUrgencyHint)) { urgency_action = "Function UrgencyDoneFunc"; } if (urgency_action) { const exec_context_t *exc; exec_context_changes_t ecc; ecc.w.fw = fw; ecc.w.wcontext = C_WINDOW; exc = exc_clone_context( ea->exc, &ecc, ECC_FW | ECC_WCONTEXT); execute_function(NULL, exc, urgency_action, 0); exc_destroy_context(exc); } break; } case XA_WM_NORMAL_HINTS: /* just mark wm normal hints as changed and look them up when * the next ConfigureRequest w/ x, y, width or height set * arrives. */ SET_HAS_NEW_WM_NORMAL_HINTS(fw, 1); /* TA: 20120317: Always set the size hints here, regardless * of them possibly being modified by a ConfigureNotify * request, due to XSizeHints disallowing resize -- FVWM would * always use old values if the application decided to toggle * such things, and FVWM would then never resize the window. * * Note that SET_HAS_NEW_WM_NORMAL_HINTS being set here to * true is still valid. */ GetWindowSizeHintsWithCheck(fw, 1); break; default: if (te->xproperty.atom == _XA_WM_PROTOCOLS) { FetchWmProtocols (fw); } else if (te->xproperty.atom == _XA_WM_COLORMAP_WINDOWS) { FetchWmColormapWindows (fw); /* frees old data */ ReInstallActiveColormap(); } else if (te->xproperty.atom == _XA_WM_STATE) { /* * Make sure at least part of window is on this page * before giving it focus... */ Bool is_on_this_page; is_on_this_page = IsRectangleOnThisPage( &(fw->g.frame), fw->Desk); if (fw && is_on_this_page == True && focus_is_focused(fw) && FP_DO_FOCUS_ENTER(FW_FOCUS_POLICY(fw))) { /* refresh the focus - why? */ focus_force_refresh_focus(fw); } } else { EWMH_ProcessPropertyNotify(ea->exc); } break; } } void HandleReparentNotify(const evh_args_t *ea) { const XEvent *te = ea->exc->x.etrigger; FvwmWindow * const fw = ea->exc->w.fw; if (!fw) { return; } if (te->xreparent.parent == Scr.Root) { /* Ignore reparenting to the root window. In some cases these * events are selected although the window is no longer * managed. */ return; } if (te->xreparent.parent != FW_W_FRAME(fw)) { /* window was reparented by someone else, destroy the frame */ SetMapStateProp(fw, WithdrawnState); EWMH_RestoreInitialStates(fw, te->type); if (!IS_TEAR_OFF_MENU(fw)) { XRemoveFromSaveSet(dpy, te->xreparent.window); XSelectInput(dpy, te->xreparent.window, NoEventMask); } else { XSelectInput(dpy, te->xreparent.window, XEVMASK_MENUW); } XSync(dpy, 0); FWeedIfWindowEvents(dpy, FW_W_FRAME(fw), NULL, NULL); destroy_window(fw); EWMH_ManageKdeSysTray(te->xreparent.window, te->type); EWMH_WindowDestroyed(); } return; } void HandleSelectionRequest(const evh_args_t *ea) { icccm2_handle_selection_request(ea->exc->x.etrigger); return; } void HandleSelectionClear(const evh_args_t *ea) { icccm2_handle_selection_clear(); return; } void HandleShapeNotify(const evh_args_t *ea) { FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandleShapeNotify", "Routine Entered"); if (FShapesSupported) { const FShapeEvent *sev = (const FShapeEvent *)(ea->exc->x.etrigger); if (!fw) { return; } if (sev->kind != FShapeBounding) { return; } frame_setup_shape( fw, fw->g.frame.width, fw->g.frame.height, sev->shaped); EWMH_SetFrameStrut(fw); if (!IS_ICONIFIED(fw)) { border_redraw_decorations(fw); } } return; } void HandleUnmapNotify(const evh_args_t *ea) { int dstx, dsty; Window dumwin; XEvent dummy; XEvent map_event; const XEvent *te = ea->exc->x.etrigger; int weMustUnmap; Bool focus_grabbed; Bool must_return = False; Bool do_map = False; FvwmWindow * const fw = ea->exc->w.fw; Window pw; Window cw; DBUG("HandleUnmapNotify", "Routine Entered"); /* Don't ignore events as described below. */ if (te->xunmap.event != te->xunmap.window && (te->xunmap.event != Scr.Root || !te->xunmap.send_event)) { must_return = True; } /* * The July 27, 1988 ICCCM spec states that a client wishing to switch * to WithdrawnState should send a synthetic UnmapNotify with the * event field set to (pseudo-)root, in case the window is already * unmapped (which is the case for fvwm for IconicState). * Unfortunately, we looked for the FvwmContext using that field, so * try the window field also. */ weMustUnmap = 0; if (!fw) { weMustUnmap = 1; if (XFindContext( dpy, te->xunmap.window, FvwmContext, (caddr_t *)&fw) == XCNOENT) { return; } } cw = FW_W(fw); pw = FW_W_PARENT(fw); if (te->xunmap.window == FW_W_FRAME(fw)) { SET_ICONIFY_PENDING(fw , 0); return; } if (must_return) { return; } if (weMustUnmap) { Bool is_map_request_pending; check_if_event_args args; args.w = te->xunmap.window; args.do_return_true = False; args.do_return_true_cr = False; /* Using FCheckTypedWindowEvent() does not work here. I don't * have the slightest idea why, but using FCheckIfEvent() with * the appropriate predicate procedure works fine. */ FCheckIfEvent(dpy, &dummy, test_map_request, (XPointer)&args); /* Unfortunately, there is no procedure in X that simply tests * if an event of a certain type in on the queue without * waiting and without removing it from the queue. * XCheck...Event() does not wait but removes the event while * XPeek...() does not remove the event but waits. To solve * this, the predicate procedure sets a flag in the passed in * structure and returns False unconditionally. */ is_map_request_pending = (args.ret_does_match == True); if (!is_map_request_pending) { XUnmapWindow(dpy, te->xunmap.window); } } if (fw == Scr.Hilite) { Scr.Hilite = NULL; } focus_grabbed = focus_query_close_release_focus(fw); restore_focus_after_unmap(fw, False); if (!IS_MAPPED(fw) && !IS_ICONIFIED(fw)) { return; } /* * The program may have unmapped the client window, from either * NormalState or IconicState. Handle the transition to WithdrawnState. * * We need to reparent the window back to the root (so that fvwm exiting * won't cause it to get mapped) and then throw away all state (pretend * that we've received a DestroyNotify). */ if (!FCheckTypedWindowEvent( dpy, te->xunmap.window, DestroyNotify, &dummy) && XTranslateCoordinates( dpy, te->xunmap.window, Scr.Root, 0, 0, &dstx, &dsty, &dumwin)) { MyXGrabServer(dpy); SetMapStateProp(fw, WithdrawnState); EWMH_RestoreInitialStates(fw, te->type); if (FCheckTypedWindowEvent( dpy, te->xunmap.window, ReparentNotify, &dummy)) { if (fw->attr_backup.border_width) { XSetWindowBorderWidth( dpy, te->xunmap.window, fw->attr_backup.border_width); } if ((!IS_ICON_SUPPRESSED(fw))&& (fw->wmhints && (fw->wmhints->flags & IconWindowHint))) { XUnmapWindow(dpy, fw->wmhints->icon_window); } } else { RestoreWithdrawnLocation(fw, False, Scr.Root); } if (!IS_TEAR_OFF_MENU(fw)) { XRemoveFromSaveSet(dpy, te->xunmap.window); XSelectInput(dpy, te->xunmap.window, NoEventMask); } XSync(dpy, 0); MyXUngrabServer(dpy); if (FCheckTypedWindowEvent(dpy, pw, MapRequest, &map_event)) { /* the client tried to map the window again while it * was still inside the decoration windows */ do_map = True; } } destroy_window(fw); if (focus_grabbed == True) { CoerceEnterNotifyOnCurrentWindow(); } EWMH_ManageKdeSysTray(te->xunmap.window, te->type); EWMH_WindowDestroyed(); if (do_map == True) { map_event.xmaprequest.window = cw; map_event.xmaprequest.parent = Scr.Root; dispatch_event(&map_event); /* note: we really should handle all map and unmap notify * events for that window in a loop here */ } return; } void HandleVisibilityNotify(const evh_args_t *ea) { FvwmWindow * const fw = ea->exc->w.fw; DBUG("HandleVisibilityNotify", "Routine Entered"); if (fw && ea->exc->x.etrigger->xvisibility.window == FW_W_FRAME(fw)) { switch (ea->exc->x.etrigger->xvisibility.state) { case VisibilityUnobscured: SET_FULLY_VISIBLE(fw, 1); SET_PARTIALLY_VISIBLE(fw, 1); break; case VisibilityPartiallyObscured: SET_FULLY_VISIBLE(fw, 0); SET_PARTIALLY_VISIBLE(fw, 1); break; default: SET_FULLY_VISIBLE(fw, 0); SET_PARTIALLY_VISIBLE(fw, 0); break; } /* Make sure the button grabs are up to date */ focus_grab_buttons(fw); } return; } /* ---------------------------- interface functions ------------------------ */ /* Inform a client window of its geometry. * * The input (frame) geometry will be translated to client geometry * before sending. */ void SendConfigureNotify( FvwmWindow *fw, int x, int y, int w, int h, int bw, Bool send_for_frame_too) { XEvent client_event; size_borders b; if (!fw || IS_SHADED(fw)) { return; } client_event.type = ConfigureNotify; client_event.xconfigure.display = dpy; client_event.xconfigure.event = FW_W(fw); client_event.xconfigure.window = FW_W(fw); get_window_borders(fw, &b); client_event.xconfigure.x = x + b.top_left.width; client_event.xconfigure.y = y + b.top_left.height; client_event.xconfigure.width = w - b.total_size.width; client_event.xconfigure.height = h - b.total_size.height; client_event.xconfigure.border_width = bw; client_event.xconfigure.above = FW_W_FRAME(fw); client_event.xconfigure.override_redirect = False; #if 0 fprintf(stderr, "send cn: %d %d %dx%d fw 0x%08x w 0x%08x ew 0x%08x '%s'\n", client_event.xconfigure.x, client_event.xconfigure.y, client_event.xconfigure.width, client_event.xconfigure.height, (int)FW_W_FRAME(fw), (int)FW_W(fw), (int)client_event.xconfigure.window, (fw->name.name) ? fw->name.name : ""); #endif fev_sanitise_configure_notify(&client_event.xconfigure); FSendEvent( dpy, FW_W(fw), False, StructureNotifyMask, &client_event); if (send_for_frame_too) { /* This is for buggy tk, which waits for the real * ConfigureNotify on frame instead of the synthetic one on w. * The geometry data in the event will not be correct for the * frame, but tk doesn't look at that data anyway. */ client_event.xconfigure.event = FW_W_FRAME(fw); client_event.xconfigure.window = FW_W_FRAME(fw); FSendEvent( dpy, FW_W_FRAME(fw), False, StructureNotifyMask, &client_event); } return; } /* Add an event group to the event handler */ int register_event_group(int event_base, int event_count, PFEH *jump_table) { /* insert into the list */ event_group_t *group; event_group_t *position = base_event_group; event_group_t *prev_position = NULL; while ( position != NULL && position->base + position->count < event_base) { prev_position = position; position = position->next; } if ((position != NULL && position->base < event_base + event_count)) { /* there is already an event group registered at the specified * event range, or the base is before the base X events */ return 1; } /* create the group structure (these are not freed until fvwm exits) */ group = (event_group_t*)safemalloc(sizeof(event_group_t)); group->base = event_base; group->count = event_count; group->jump_table = jump_table; group->next = position; if (prev_position != NULL) { prev_position->next = group; } else { base_event_group = group; } return 0; } /* ** Procedure: ** InitEventHandlerJumpTable */ void InitEventHandlerJumpTable(void) { static PFEH EventHandlerJumpTable[LASTEvent]; int i; for (i=0; ixany.window; FvwmWindow *fw; event_group_t *event_group; DBUG("dispatch_event", "Routine Entered"); XFlush(dpy); if (w == Scr.Root) { switch (e->type) { case ButtonPress: case ButtonRelease: if (e->xbutton.subwindow != None) { w = e->xbutton.subwindow; } case MapRequest: w = e->xmaprequest.window; break; default: break; } } if (w == Scr.Root || XFindContext(dpy, w, FvwmContext, (caddr_t *)&fw) == XCNOENT) { fw = NULL; } if ( fw != NULL && IS_SCHEDULED_FOR_DESTROY(fw) && e->type != DestroyNotify) { return; } last_event_type = e->type; event_group = base_event_group; while ( event_group != NULL && event_group->base + event_group->count < e->type) { event_group = event_group->next; } if ( event_group != NULL && e->type - event_group->base < event_group->count && event_group->jump_table[e->type - event_group->base] != NULL) { evh_args_t ea; exec_context_changes_t ecc; Window dummyw; ecc.type = EXCT_EVENT; ecc.x.etrigger = e; ecc.w.wcontext = GetContext(&fw, fw, e, &dummyw); ecc.w.w = w; ecc.w.fw = fw; ea.exc = exc_create_context( &ecc, ECC_TYPE | ECC_ETRIGGER | ECC_FW | ECC_W | ECC_WCONTEXT); (*event_group->jump_table[e->type - event_group->base])(&ea); exc_destroy_context(ea.exc); } #ifdef C_ALLOCA /* If we're using the C version of alloca, see if anything needs to be * freed up. */ alloca(0); #endif DBUG("dispatch_event", "Leaving Routine"); return; } /* ewmh configure request */ void events_handle_configure_request( XEvent *cre, FvwmWindow *fw, Bool force, int force_gravity) { _handle_configure_request(cre, NULL, fw, force, force_gravity); return; } void HandleEvents(void) { XEvent ev; DBUG("HandleEvents", "Routine Entered"); STROKE_CODE(send_motion = False); while (!isTerminated) { last_event_type = 0; if (Scr.flags.is_window_scheduled_for_destroy) { destroy_scheduled_windows(); } if (Scr.flags.do_need_window_update) { flush_window_updates(); } if (My_XNextEvent(dpy, &ev)) { /* DV (19-Sep-2014): We mark events as invalid by * setting the send_event field to a bogus value in a * predicate procedure. It's unsure whether this works * reliably. */ if (FEV_IS_EVENT_INVALID(ev)) { continue; } dispatch_event(&ev); } if (Scr.flags.do_need_style_list_update) { simplify_style_list(); } } return; } /* * * Waits for next X or module event, fires off startup routines when startup * modules have finished or after a timeout if the user has specified a * command line module that doesn't quit or gets stuck. * */ int My_XNextEvent(Display *dpy, XEvent *event) { fd_set in_fdset, out_fdset; int num_fd; fmodule_list_itr moditr; fmodule *module; fmodule_input *input; static struct timeval timeout; static struct timeval *timeoutP = &timeout; DBUG("My_XNextEvent", "Routine Entered"); /* check for any X events already queued up. * Side effect: this does an XFlush if no events are queued * Make sure nothing between here and the select causes further * X requests to be sent or the select may block even though * there are events in the queue */ if (FPending(dpy)) { DBUG( "My_XNextEvent", "taking care of queued up events" " & returning (1)"); FNextEvent(dpy, event); return 1; } /* check for termination of all startup modules */ if (fFvwmInStartup) { module_list_itr_init(&moditr); module = module_list_itr_next(&moditr); for (; module != NULL; module = module_list_itr_next(&moditr)) { if (MOD_IS_CMDLINE(module) == 1) { break; } } module_cleanup(); if (module == NULL) { /* last module */ DBUG( "My_XNextEvent", "Starting up after command lines modules"); /* set an infinite timeout to stop ticking */ timeoutP = NULL; /* This may cause X requests to be sent */ StartupStuff(); return 0; /* so return without select()ing */ } } /* Some signals can interrupt us while we wait for any action * on our descriptors. While some of these signals may be asking * fvwm to die, some might be harmless. Harmless interruptions * mean we have to start waiting all over again ... */ do { int ms; Bool is_waiting_for_scheduled_command = False; static struct timeval *old_timeoutP = NULL; /* The timeouts become undefined whenever the select returns, * and so we have to reinitialise them */ ms = squeue_get_next_ms(); if (ms == 0) { /* run scheduled commands */ squeue_execute(); ms = squeue_get_next_ms(); /* should not happen anyway. * get_next_schedule_queue_ms() can't return 0 after a * call to execute_schedule_queue(). */ if (ms == 0) { ms = 1; } } if (ms < 0) { timeout.tv_sec = 42; timeout.tv_usec = 0; } else { /* scheduled commands are pending - don't wait too * long */ timeout.tv_sec = ms / 1000; timeout.tv_usec = 1000 * (ms % 1000); old_timeoutP = timeoutP; timeoutP = &timeout; is_waiting_for_scheduled_command = True; } FD_ZERO(&in_fdset); FD_ZERO(&out_fdset); FD_SET(x_fd, &in_fdset); /* nothing is done here if fvwm was compiled without session * support */ if (sm_fd >= 0) { FD_SET(sm_fd, &in_fdset); } module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { FD_SET(MOD_READFD(module), &in_fdset); if (!FQUEUE_IS_EMPTY(&MOD_PIPEQUEUE(module))) { FD_SET(MOD_WRITEFD(module), &out_fdset); } } DBUG("My_XNextEvent", "waiting for module input/output"); num_fd = fvwmSelect( fvwmlib_max_fd, &in_fdset, &out_fdset, 0, timeoutP); if (is_waiting_for_scheduled_command) { timeoutP = old_timeoutP; } /* Express route out of fvwm ... */ if (isTerminated) { return 0; } } while (num_fd < 0); if (num_fd > 0) { /* Check for module input. */ module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { if (FD_ISSET(MOD_READFD(module), &in_fdset)) { input = module_receive(module); /* enqueue the received command */ module_input_enqueue(input); } if ( MOD_WRITEFD(module) >= 0 && FD_ISSET(MOD_WRITEFD(module), &out_fdset)) { DBUG("My_XNextEvent", "calling FlushMessageQueue"); FlushMessageQueue(module); } } /* execute any commands queued up */ DBUG("My_XNextEvent", "executing module comand queue"); ExecuteCommandQueue(); /* cleanup dead modules */ module_cleanup(); /* nothing is done here if fvwm was compiled without session * support */ if ((sm_fd >= 0) && (FD_ISSET(sm_fd, &in_fdset))) { ProcessICEMsgs(); } } else { /* select has timed out, things must have calmed down so let's * decorate */ if (fFvwmInStartup) { fvwm_msg(ERR, "My_XNextEvent", "Some command line modules have not quit, " "Starting up after timeout.\n"); StartupStuff(); timeoutP = NULL; /* set an infinite timeout to stop * ticking */ reset_style_changes(); Scr.flags.do_need_window_update = 0; } /* run scheduled commands if necessary */ squeue_execute(); } /* check for X events again, rather than return 0 and get called again */ if (FPending(dpy)) { DBUG("My_XNextEvent", "taking care of queued up events & returning (2)"); FNextEvent(dpy,event); return 1; } DBUG("My_XNextEvent", "leaving My_XNextEvent"); return 0; } /* * * Procedure: * Find the Fvwm context for the event. * */ int GetContext(FvwmWindow **ret_fw, FvwmWindow *t, const XEvent *e, Window *w) { int context; Window win; Window subw = None; int x = 0; int y = 0; Bool is_key_event = False; win = e->xany.window; context = C_NO_CONTEXT; switch (e->type) { case KeyPress: case KeyRelease: x = e->xkey.x; y = e->xkey.y; subw = e->xkey.subwindow; if (win == Scr.Root && subw != None) { /* Translate root coordinates into subwindow * coordinates. Necessary for key bindings that work * over unfocused windows. */ win = subw; XTranslateCoordinates( dpy, Scr.Root, subw, x, y, &x, &y, &subw); XFindContext(dpy, win, FvwmContext, (caddr_t *) &t); } is_key_event = True; /* fall through */ case ButtonPress: case ButtonRelease: if (!is_key_event) { x = e->xbutton.x; y = e->xbutton.y; subw = e->xbutton.subwindow; } if (t && win == FW_W_FRAME(t) && subw != None) { /* Translate frame coordinates into subwindow * coordinates. */ win = subw; XTranslateCoordinates( dpy, FW_W_FRAME(t), subw, x, y, &x, &y, &subw); if (win == FW_W_PARENT(t)) { win = subw; XTranslateCoordinates( dpy, FW_W_PARENT(t), subw, x, y, &x, &y, &subw); } } break; default: XFindContext(dpy, win, FvwmContext, (caddr_t *)&t); break; } if (ret_fw != NULL) { *ret_fw = t; } if (!t) { return C_ROOT; } *w = win; if (*w == Scr.NoFocusWin) { return C_ROOT; } if (subw != None) { if (win == FW_W_PARENT(t)) { *w = subw; } } if (*w == Scr.Root) { return C_ROOT; } context = frame_window_id_to_context(t, *w, &Button); return context; } /* Drops all expose events for the given window from the input queue and merges * the expose rectangles into a single big one (*e). */ void flush_accumulate_expose(Window w, XEvent *e) { FWeedIfWindowEvents(dpy, w, _pred_weed_accumulate_expose, (XPointer)e); return; } /* * * Removes all expose events from the queue and does the necessary redraws * */ void handle_all_expose(void) { void *saved_event; saved_event = fev_save_event(); FPending(dpy); FWeedIfEvents(dpy, _pred_weed_handle_expose, NULL); fev_restore_event(saved_event); return; } /* CoerceEnterNotifyOnCurrentWindow() * Pretends to get a HandleEnterNotify on the window that the pointer * currently is in so that the focus gets set correctly from the beginning. * Note that this presently only works if the current window is not * click_to_focus; I think that that behaviour is correct and desirable. * --11/08/97 gjb */ void CoerceEnterNotifyOnCurrentWindow(void) { Window child; Window root; Bool f; evh_args_t ea; exec_context_changes_t ecc; XEvent e; FvwmWindow *fw; f = FQueryPointer( dpy, Scr.Root, &root, &child, &e.xcrossing.x_root, &e.xcrossing.y_root, &e.xcrossing.x, &e.xcrossing.y, &JunkMask); if (f == False || child == None) { return; } e.xcrossing.type = EnterNotify; e.xcrossing.window = child; e.xcrossing.subwindow = None; e.xcrossing.mode = NotifyNormal; e.xcrossing.detail = NotifyAncestor; e.xcrossing.same_screen = True; if (XFindContext(dpy, child, FvwmContext, (caddr_t *)&fw) == XCNOENT) { fw = NULL; } else { XTranslateCoordinates( dpy, Scr.Root, child, e.xcrossing.x_root, e.xcrossing.y_root, &JunkX, &JunkY, &child); if (child == FW_W_PARENT(fw)) { child = FW_W(fw); } if (child != None) { e.xany.window = child; } } e.xcrossing.focus = (fw == get_focus_window()) ? True : False; ecc.type = EXCT_NULL; ecc.x.etrigger = &e; ea.exc = exc_create_context(&ecc, ECC_TYPE | ECC_ETRIGGER); HandleEnterNotify(&ea); exc_destroy_context(ea.exc); return; } /* This function discards all queued up events selected by the mask. */ int discard_typed_events(int num_event_types, int *event_types) { _weed_event_type_arg args; int count; int i; XSync(dpy, 0); assert(num_event_types <= MAX_NUM_WEED_EVENT_TYPES); args.num_event_types = num_event_types; for (i = 0; i < num_event_types; i++) { args.event_types[i] = event_types[i]; } count = FWeedIfEvents(dpy, _pred_weed_event_type, (XPointer)&args); return count; } /* Similar function for certain types of PropertyNotify. */ int flush_property_notify_stop_at_event_type( Atom atom, Window w, char do_stop_at_event_type, int stop_at_event_type) { flush_property_notify_args args; XSync(dpy, 0); args.w = w; args.atom = atom; args.event_type = PropertyNotify; args.stop_at_event_type = stop_at_event_type; args.do_stop_at_event_type = do_stop_at_event_type; FWeedIfEvents( dpy, _pred_flush_property_notify_weed, (XPointer)&args); return 0; } /* Wait for all mouse buttons to be released * This can ease some confusion on the part of the user sometimes * * Discard superflous button events during this wait period. */ void WaitForButtonsUp(Bool do_handle_expose) { unsigned int mask; unsigned int bmask; long evmask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| KeyPressMask|KeyReleaseMask; int count; int use_wait_cursor; XEvent e; if (FQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &JunkX, &JunkY, &mask) == False) { /* pointer is on a different screen - that's okay here */ } mask &= DEFAULT_ALL_BUTTONS_MASK; if (mask == 0) { return; } if (do_handle_expose) { evmask |= ExposureMask; } GrabEm(None, GRAB_NORMAL); for (count = 0, use_wait_cursor = 0; mask != 0; count++) { /* handle expose events */ XAllowEvents(dpy, SyncPointer, CurrentTime); if (FCheckMaskEvent(dpy, evmask, &e)) { switch (e.type) { case ButtonRelease: if (e.xbutton.button <= NUMBER_OF_MOUSE_BUTTONS) { bmask = (Button1Mask << (e.xbutton.button - 1)); mask = e.xbutton.state & ~bmask; } break; case Expose: dispatch_event(&e); break; default: break; } } else { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &JunkX, &JunkY, &mask) == False) { /* pointer is on a different screen - that's * okay here */ } mask &= DEFAULT_ALL_BUTTONS_MASK; usleep(1); } if (use_wait_cursor == 0 && count == 20) { GrabEm(CRS_WAIT, GRAB_NORMAL); use_wait_cursor = 1; } } UngrabEm(GRAB_NORMAL); if (use_wait_cursor) { UngrabEm(GRAB_NORMAL); XFlush(dpy); } return; } void sync_server(int toggle) { static Bool synced = False; if (toggle == -1) { toggle = (synced == False); } if (toggle == 1) { synced = True; } else { synced = False; } XSynchronize(dpy, synced); XFlush(dpy); return; } Bool is_resizing_event_pending(FvwmWindow *fw) { XEvent e; check_if_event_args args; args.w = FW_W(fw); args.do_return_true = False; args.do_return_true_cr = False; args.cr_value_mask = 0; args.ret_does_match = False; args.ret_type = 0; FCheckIfEvent(dpy, &e, test_resizing_event, (XPointer)&args); return args.ret_does_match; } /* ---------------------------- builtin commands --------------------------- */ void CMD_XSynchronize(F_CMD_ARGS) { int toggle; toggle = ParseToggleArgument(action, NULL, -1, 0); sync_server(toggle); return; } void CMD_XSync(F_CMD_ARGS) { XSync(dpy, 0); return; } fvwm-2.6.7/fvwm/move_resize.c0000644000175700017570000032535613001406607013131 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* * * code for moving and resizing windows * */ #include "config.h" #include #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/Picture.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/Graphics.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "execcontext.h" #include "commands.h" #include "misc.h" #include "screen.h" #include "menus.h" #include "menuparameters.h" #include "module_list.h" #include "module_interface.h" #include "focus.h" #include "borders.h" #include "frame.h" #include "geometry.h" #include "ewmh.h" #include "virtual.h" #include "decorations.h" #include "events.h" #include "eventhandler.h" #include "eventmask.h" #include "colormaps.h" #include "update.h" #include "stack.h" #include "move_resize.h" #include "functions.h" #include "style.h" /* ----- move globals ----- */ #define MOVE_NORMAL 0x00 #define MOVE_PAGE 0x01 #define MOVE_SCREEN 0x02 /* Animated move stuff added by Greg J. Badros, gjb@cs.washington.edu */ float rgpctMovementDefault[32] = { -.01, 0, .01, .03,.08,.18,.3,.45,.60,.75,.85,.90,.94,.97,.99,1.0 /* must end in 1.0 */ }; int cmsDelayDefault = 10; /* milliseconds */ /* current geometry of size window */ static rectangle sizew_g = { -1, -1, -1, -1 }; static int move_interactive_finish_button_mask = ((1<<(NUMBER_OF_EXTENDED_MOUSE_BUTTONS))-1) & ~0x2; static int move_drag_finish_button_mask = ((1<<(NUMBER_OF_EXTENDED_MOUSE_BUTTONS))-1) & ~0x3; /* ----- end of move globals ----- */ /* ----- resize globals ----- */ /* DO NOT USE (STATIC) GLOBALS IN THIS MODULE! * Since some functions are called from other modules unwanted side effects * (i.e. bugs.) would be created */ extern Window PressedW; static void draw_move_resize_grid(int x, int y, int width, int height); /* ----- end of resize globals ----- */ /* * * Procedure: * draw_move_resize_grid - move a window outline * * Inputs: * root - the window we are outlining * x - upper left x coordinate * y - upper left y coordinate * width - the width of the rectangle * height - the height of the rectangle * */ static int get_outline_rects( XRectangle *rects, int x, int y, int width, int height) { int i; int n; int m; n = 3; m = (width - 5) / 2; if (m < n) { n = m; } m = (height - 5) / 2; if (m < n) { n = m; } if (n < 1) { n = 1; } for (i = 0; i < n; i++) { rects[i].x = x + i; rects[i].y = y + i; rects[i].width = width - (i << 1); rects[i].height = height - (i << 1); } if (width - (n << 1) >= 5 && height - (n << 1) >= 5) { if (width - (n << 1) >= 10) { int off = (width - (n << 1)) / 3 + n; rects[i].x = x + off; rects[i].y = y + n; rects[i].width = width - (off << 1); rects[i].height = height - (n << 1); i++; } if (height - (n << 1) >= 10) { int off = (height - (n << 1)) / 3 + n; rects[i].x = x + n; rects[i].y = y + off; rects[i].width = width - (n << 1); rects[i].height = height - (off << 1); i++; } } return i; } struct { rectangle geom; struct { unsigned is_enabled : 1; } flags; } move_resize_grid = { { 0, 0, 0, 0 }, { 0 } }; static void draw_move_resize_grid(int x, int y, int width, int height) { int nrects = 0; XRectangle rects[10]; if (move_resize_grid.flags.is_enabled && x == move_resize_grid.geom.x && y == move_resize_grid.geom.y && width == move_resize_grid.geom.width && height == move_resize_grid.geom.height) { return; } memset(rects, 0, 10 * sizeof(XRectangle)); /* place the resize rectangle into the array of rectangles */ /* interleave them for best visual look */ /* draw the new one, if any */ if (move_resize_grid.flags.is_enabled /*move_resize_grid.geom.width && move_resize_grid.geom.height*/) { move_resize_grid.flags.is_enabled = 0; nrects += get_outline_rects( &(rects[0]), move_resize_grid.geom.x, move_resize_grid.geom.y, move_resize_grid.geom.width, move_resize_grid.geom.height); } if (width && height) { move_resize_grid.flags.is_enabled = 1; move_resize_grid.geom.x = x; move_resize_grid.geom.y = y; move_resize_grid.geom.width = width; move_resize_grid.geom.height = height; nrects += get_outline_rects( &(rects[nrects]), x, y, width, height); } if (nrects > 0) { XDrawRectangles(dpy, Scr.Root, Scr.XorGC, rects, nrects); XFlush(dpy); } return; } void switch_move_resize_grid(Bool state) { if (state == False) { if (move_resize_grid.flags.is_enabled) { draw_move_resize_grid(0, 0, 0, 0); } else { move_resize_grid.geom.x = 0; move_resize_grid.geom.y = 0; move_resize_grid.geom.width = 0; move_resize_grid.geom.height = 0; } } else if (!move_resize_grid.flags.is_enabled) { if (move_resize_grid.geom.width && move_resize_grid.geom.height) { draw_move_resize_grid( move_resize_grid.geom.x, move_resize_grid.geom.y, move_resize_grid.geom.width, move_resize_grid.geom.height); } } return; } static int ParsePositionArgumentSuffix( float *ret_factor, char *suffix, float wfactor, float sfactor) { int n; switch (*suffix) { case 'p': case 'P': *ret_factor = 1.0; n = 1; break; case 'w': case 'W': *ret_factor = wfactor; n = 1; break; default: *ret_factor = sfactor; n = 0; break; } return n; } static int __get_shift(int val, float factor) { int shift; if (val >= 0) { shift = (int)(val * factor + 0.5); } else { shift = (int)(val * factor - 0.5); } return shift; } /* The vars are named for the x-direction, but this is used for both x and y */ static int GetOnePositionArgument( char *s1, int window_pos, int window_size, int *pFinalPos, float sfactor, int screen_size, int screen_pos, Bool is_x) { int final_pos; float wfactor; if (s1 == 0 || *s1 == 0) { return 0; } wfactor = (float)window_size / 100; /* get start position */ switch (*s1) { case 'w': case 'W': final_pos = window_pos; s1++; break; case 'm': case 'M': { int x; int y; if ( FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ final_pos = 0; } else { final_pos = (is_x) ? x : y; } s1++; break; } default: final_pos = screen_pos; if (*s1 != 0) { int val; int n; float f; /* parse value */ if (sscanf(s1, "-%d%n", &val, &n) >= 1) { /* i.e. -1, -+1 or --1 */ final_pos += (screen_size - window_size); val = -val; } else if ( sscanf(s1, "+%d%n", &val, &n) >= 1 || sscanf(s1, "%d%n", &val, &n) >= 1) { /* i.e. 1, +1, ++1 or +-1 */ } else { /* syntax error, ignore rest of string */ break; } s1 += n; /* parse suffix */ n = ParsePositionArgumentSuffix( &f, s1, wfactor, sfactor); s1 += n; final_pos += __get_shift(val, f); } break; } /* loop over shift arguments */ while (*s1 != 0) { int val; int n; float f; /* parse value */ if (sscanf(s1, "-%d%n", &val, &n) >= 1) { /* i.e. -1, -+1 or --1 */ val = -val; } else if ( sscanf(s1, "+%d%n", &val, &n) >= 1 || sscanf(s1, "%d%n", &val, &n) >= 1) { /* i.e. 1, +1, ++1 or +-1 */ } else { /* syntax error, ignore rest of string */ break; } s1 += n; /* parse suffix */ n = ParsePositionArgumentSuffix(&f, s1, wfactor, sfactor); s1 += n; final_pos += __get_shift(val, f); } *pFinalPos = final_pos; return 1; } /* GetMoveArguments is used for Move & AnimatedMove * It lets you specify in all the following ways * 20 30 Absolute percent position, from left edge and top * -50 50 Absolute percent position, from right edge and top * 10p 5p Absolute pixel position * 10p -0p Absolute pixel position, from bottom * w+5 w-10p Relative position, right 5%, up ten pixels * m+5 m-10p Pointer relative position, right 5%, up ten pixels * Returns 2 when x & y have parsed without error, 0 otherwise */ int GetMoveArguments( char **paction, int w, int h, int *pFinalX, int *pFinalY, Bool *fWarp, Bool *fPointer, Bool fKeep) { char *s1 = NULL; char *s2 = NULL; char *token = NULL; char *action; char *naction; int scr_x = 0; int scr_y = 0; int scr_w = Scr.MyDisplayWidth; int scr_h = Scr.MyDisplayHeight; Bool use_working_area = True; Bool global_flag_parsed = False; int retval = 0; if (!paction) { return 0; } action = *paction; action = GetNextToken(action, &s1); if (s1 && fPointer && StrEquals(s1, "pointer")) { *fPointer = True; *paction = action; free(s1); return 0; } if (s1 && StrEquals(s1, "screen")) { char *token; int scr; fscreen_scr_arg arg; fscreen_scr_arg* parg; free(s1); token = PeekToken(action, &action); scr = FScreenGetScreenArgument(token, FSCREEN_SPEC_PRIMARY); if (scr == FSCREEN_XYPOS) { arg.xypos.x = *pFinalX; arg.xypos.y = *pFinalY; parg = &arg; } else { parg = NULL; } FScreenGetScrRect(parg, scr, &scr_x, &scr_y, &scr_w, &scr_h); action = GetNextToken(action, &s1); } action = GetNextToken(action, &s2); while (!global_flag_parsed) { token = PeekToken(action, &naction); if (!token) { global_flag_parsed = True; break; } if (StrEquals(token, "Warp")) { action = naction; if (fWarp) { *fWarp = True; } } else if (StrEquals(token, "ewmhiwa")) { use_working_area = False; action = naction; } else { global_flag_parsed = True; } } if (use_working_area) { EWMH_GetWorkAreaIntersection( NULL, &scr_x, &scr_y, &scr_w, &scr_h, EWMH_USE_WORKING_AREA); } if (s1 != NULL && s2 != NULL) { retval = 0; if (fKeep == True && StrEquals(s1, "keep")) { retval++; } else if ( GetOnePositionArgument( s1, *pFinalX, w, pFinalX, (float)scr_w / 100, scr_w, scr_x, True)) { retval++; } if (fKeep == True && StrEquals(s2, "keep")) { retval++; } else if ( GetOnePositionArgument( s2, *pFinalY, h, pFinalY, (float)scr_h / 100, scr_h, scr_y, False)) { retval++; } if (retval == 0) { /* make sure warping is off for interactive moves */ *fWarp = False; } } else { /* not enough arguments, switch to current page. */ while (*pFinalX < 0) { *pFinalX = Scr.MyDisplayWidth + *pFinalX; } while (*pFinalY < 0) { *pFinalY = Scr.MyDisplayHeight + *pFinalY; } } if (s1) { free(s1); } if (s2) { free(s2); } *paction = action; return retval; } static int ParseOneResizeArgument( char *arg, int scr_size, int wa_size, int dwa_size, int base_size, int size_inc, int add_size, int *ret_size) { float factor; int val; int add_base_size = 0; int cch = strlen(arg); int tmp_size; if (cch == 0) { return 0; } if (StrEquals(arg, "keep")) { /* do not change size */ return 1; } if (cch > 1 && arg[cch-2] == 'w' && arg[cch-1] == 'a') { /* ewmh working area */ factor = (float)wa_size / 100.0; arg[cch-1] = '\0'; } else if (cch > 1 && arg[cch-2] == 'd' && arg[cch-1] == 'a') { /* ewmh dynamic working area */ factor = (float)dwa_size / 100.0; arg[cch-1] = '\0'; } else if (arg[cch-1] == 'p') { factor = 1; arg[cch-1] = '\0'; } else if (arg[cch-1] == 'c') { factor = size_inc; add_base_size = base_size; arg[cch-1] = '\0'; } else { factor = (float)scr_size / 100.0; } if (strcmp(arg,"w") == 0) { /* do not change size */ } else if (sscanf(arg,"w-%d",&val) == 1) { tmp_size = (int)(val * factor + 0.5); if (tmp_size < *ret_size) { *ret_size -= tmp_size; } else { *ret_size = 0; } } else if (sscanf(arg,"w+%d",&val) == 1 || sscanf(arg,"w%d",&val) == 1) { tmp_size = (int)(val * factor + 0.5); if (-tmp_size < *ret_size) { *ret_size += tmp_size; } else { *ret_size = 0; } } else if (sscanf(arg,"-%d",&val) == 1) { tmp_size = (int)(val * factor + 0.5); if (tmp_size < scr_size + add_size) { *ret_size = scr_size - tmp_size + add_size; } else { *ret_size = 0; } } else if (sscanf(arg,"+%d",&val) == 1 || sscanf(arg,"%d",&val) == 1) { tmp_size = (int)(val * factor + 0.5); if (-tmp_size < add_size + add_base_size) { *ret_size = tmp_size + add_size + add_base_size; } else { *ret_size = 0; } } else { return 0; } return 1; } static int GetResizeArguments( char **paction, int x, int y, int w_base, int h_base, int w_inc, int h_inc, size_borders *sb, int *pFinalW, int *pFinalH, direction_t *ret_dir, Bool *is_direction_fixed, Bool *do_warp_to_border, Bool *automatic_border_direction, Bool *detect_automatic_direction) { int n; char *naction; char *token; char *tmp_token; char *s1; char *s2; int w_add; int h_add; int has_frame_option; *ret_dir = DIR_NONE; *is_direction_fixed = False; *do_warp_to_border = False; *automatic_border_direction = False; *detect_automatic_direction = False; if (!paction) { return 0; } token = PeekToken(*paction, &naction); if (!token) { return 0; } if (StrEquals(token, "bottomright") || StrEquals(token, "br")) { int nx = x + *pFinalW - 1; int ny = y + *pFinalH - 1; n = GetMoveArguments( &naction, 0, 0, &nx, &ny, NULL, NULL, True); if (n < 2) { return 0; } *pFinalW = nx - x + 1; *pFinalH = ny - y + 1; *paction = naction; return n; } has_frame_option = 0; for ( ; ; token = PeekToken(naction, &naction)) { if (StrEquals(token, "frame")) { has_frame_option = 1; } else if (StrEquals(token, "direction")) { *ret_dir = gravity_parse_dir_argument( naction, &naction, DIR_NONE); if (*ret_dir != DIR_NONE) { *is_direction_fixed = True; } else if (*ret_dir == DIR_NONE) { tmp_token = PeekToken(naction, &naction); if (tmp_token != NULL && StrEquals(tmp_token, "automatic")) { *detect_automatic_direction = True; *is_direction_fixed = True; } } } else if (StrEquals(token, "fixeddirection")) { *is_direction_fixed = True; } else if (StrEquals(token, "warptoborder")) { tmp_token = PeekToken(naction, &naction); if (tmp_token != NULL && StrEquals(tmp_token, "automatic")) { *automatic_border_direction = True; } *do_warp_to_border = True; } else { break; } } if (has_frame_option) { w_add = 0; h_add = 0; } else { w_add = sb->total_size.width; h_add = sb->total_size.height; } s1 = NULL; if (token != NULL) { s1 = safestrdup(token); } naction = GetNextToken(naction, &s2); if (!s2) { free(s1); return 0; } *paction = naction; n = 0; n += ParseOneResizeArgument( s1, Scr.MyDisplayWidth, Scr.Desktops->ewmh_working_area.width, Scr.Desktops->ewmh_dyn_working_area.width, w_base, w_inc, w_add, pFinalW); n += ParseOneResizeArgument( s2, Scr.MyDisplayHeight, Scr.Desktops->ewmh_working_area.height, Scr.Desktops->ewmh_dyn_working_area.height, h_base, h_inc, h_add, pFinalH); free(s1); free(s2); if (n < 2) { n = 0; } return n; } static int GetResizeMoveArguments( char **paction, int w_base, int h_base, int w_inc, int h_inc, size_borders *sb, int *pFinalX, int *pFinalY, int *pFinalW, int *pFinalH, Bool *fWarp, Bool *fPointer) { char *action = *paction; direction_t dir; Bool dummy; if (!paction) { return 0; } if (GetResizeArguments( &action, *pFinalX, *pFinalY, w_base, h_base, w_inc, h_inc, sb, pFinalW, pFinalH, &dir, &dummy, &dummy, &dummy, &dummy) < 2) { return 0; } if (GetMoveArguments( &action, *pFinalW, *pFinalH, pFinalX, pFinalY, fWarp, NULL, True) < 2) { return 0; } *paction = action; return 4; } /* Positions the SizeWindow on the current ("moused") xinerama-screen */ static void position_geometry_window(const XEvent *eventp) { int x; int y; fscreen_scr_arg fscr; fscr.mouse_ev = (XEvent *)eventp; /* Probably should remove this positioning code from {builtins,fvwm}.c? */ if (Scr.gs.do_emulate_mwm) { FScreenCenterOnScreen( &fscr, FSCREEN_CURRENT, &x, &y, sizew_g.width, sizew_g.height); } else { FScreenGetScrRect(&fscr, FSCREEN_CURRENT, &x, &y, NULL, NULL); } if (x != sizew_g.x || y != sizew_g.y) { switch_move_resize_grid(False); XMoveWindow(dpy, Scr.SizeWindow, x, y); switch_move_resize_grid(True); sizew_g.x = x; sizew_g.y = y; } return; } void resize_geometry_window(void) { int w; int h; int cset = Scr.DefaultColorset; Scr.SizeStringWidth = FlocaleTextWidth(Scr.DefaultFont, GEOMETRY_WINDOW_STRING, sizeof(GEOMETRY_WINDOW_STRING) - 1); w = Scr.SizeStringWidth + 2 * GEOMETRY_WINDOW_BW; h = Scr.DefaultFont->height + 2 * GEOMETRY_WINDOW_BW; if (w != sizew_g.width || h != sizew_g.height) { XResizeWindow(dpy, Scr.SizeWindow, w, h); sizew_g.width = w; sizew_g.height = h; } if (cset >= 0) { SetWindowBackground( dpy, Scr.SizeWindow, w, h, &Colorset[cset], Pdepth, Scr.StdGC, False); } else { XSetWindowBackground(dpy, Scr.SizeWindow, Scr.StdBack); } return; } /* * * Procedure: * DisplayPosition - display the position in the dimensions window * * Inputs: * tmp_win - the current fvwm window * x, y - position of the window * */ static void DisplayPosition( const FvwmWindow *tmp_win, const XEvent *eventp, int x, int y,int Init) { char str[100]; int offset; fscreen_scr_arg fscr; FlocaleWinString fstr; if (Scr.gs.do_hide_position_window) { return; } position_geometry_window(eventp); /* Translate x,y into local screen coordinates, * in case Xinerama is used. */ fscr.xypos.x = x; fscr.xypos.y = y; FScreenTranslateCoordinates( NULL, FSCREEN_GLOBAL, &fscr, FSCREEN_XYPOS, &x, &y); (void)sprintf(str, GEOMETRY_WINDOW_POS_STRING, x, y); if (Init) { XClearWindow(dpy, Scr.SizeWindow); } else { /* just clear indside the relief lines to reduce flicker */ XClearArea(dpy, Scr.SizeWindow, GEOMETRY_WINDOW_BW, GEOMETRY_WINDOW_BW, Scr.SizeStringWidth, Scr.DefaultFont->height, False); } if (Pdepth >= 2) { RelieveRectangle( dpy, Scr.SizeWindow, 0, 0, Scr.SizeStringWidth + GEOMETRY_WINDOW_BW * 2 - 1, Scr.DefaultFont->height + GEOMETRY_WINDOW_BW * 2 - 1, Scr.StdReliefGC, Scr.StdShadowGC, GEOMETRY_WINDOW_BW); } offset = (Scr.SizeStringWidth - FlocaleTextWidth(Scr.DefaultFont, str, strlen(str))) / 2; offset += GEOMETRY_WINDOW_BW; memset(&fstr, 0, sizeof(fstr)); if (Scr.DefaultColorset >= 0) { fstr.colorset = &Colorset[Scr.DefaultColorset]; fstr.flags.has_colorset = True; } fstr.str = str; fstr.win = Scr.SizeWindow; fstr.gc = Scr.StdGC; fstr.x = offset; fstr.y = Scr.DefaultFont->ascent + GEOMETRY_WINDOW_BW; FlocaleDrawString(dpy, Scr.DefaultFont, &fstr, 0); return; } /* * * Procedure: * DisplaySize - display the size in the dimensions window * * Inputs: * tmp_win - the current fvwm window * width - the width of the rubber band * height - the height of the rubber band * */ static void DisplaySize( const FvwmWindow *tmp_win, const XEvent *eventp, int width, int height, Bool Init, Bool resetLast) { char str[100]; int dwidth,dheight,offset; size_borders b; static int last_width = 0; static int last_height = 0; FlocaleWinString fstr; if (Scr.gs.do_hide_resize_window) { return; } position_geometry_window(eventp); if (resetLast) { last_width = 0; last_height = 0; } if (last_width == width && last_height == height) { return; } last_width = width; last_height = height; get_window_borders(tmp_win, &b); dheight = height - b.total_size.height; dwidth = width - b.total_size.width; dwidth -= tmp_win->hints.base_width; dheight -= tmp_win->hints.base_height; dwidth /= tmp_win->hints.width_inc; dheight /= tmp_win->hints.height_inc; (void)sprintf(str, GEOMETRY_WINDOW_SIZE_STRING, dwidth, dheight); if (Init) { XClearWindow(dpy,Scr.SizeWindow); } else { /* just clear indside the relief lines to reduce flicker */ XClearArea( dpy, Scr.SizeWindow, GEOMETRY_WINDOW_BW, GEOMETRY_WINDOW_BW, Scr.SizeStringWidth, Scr.DefaultFont->height, False); } if (Pdepth >= 2) { RelieveRectangle( dpy, Scr.SizeWindow, 0, 0, Scr.SizeStringWidth + GEOMETRY_WINDOW_BW * 2 - 1, Scr.DefaultFont->height + GEOMETRY_WINDOW_BW*2 - 1, Scr.StdReliefGC, Scr.StdShadowGC, GEOMETRY_WINDOW_BW); } offset = (Scr.SizeStringWidth - FlocaleTextWidth(Scr.DefaultFont, str, strlen(str))) / 2; offset += GEOMETRY_WINDOW_BW; memset(&fstr, 0, sizeof(fstr)); if (Scr.DefaultColorset >= 0) { fstr.colorset = &Colorset[Scr.DefaultColorset]; fstr.flags.has_colorset = True; } fstr.str = str; fstr.win = Scr.SizeWindow; fstr.gc = Scr.StdGC; fstr.x = offset; fstr.y = Scr.DefaultFont->ascent + GEOMETRY_WINDOW_BW; FlocaleDrawString(dpy, Scr.DefaultFont, &fstr, 0); return; } static Bool resize_move_window(F_CMD_ARGS) { int FinalX = 0; int FinalY = 0; int FinalW = 0; int FinalH = 0; int n; int x,y; Bool fWarp = False; Bool fPointer = False; int dx; int dy; size_borders b; FvwmWindow *fw = exc->w.fw; Window w = exc->w.w; if (!is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if (!is_function_allowed(F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, True)) { return False; } /* gotta have a window */ w = FW_W_FRAME(fw); if (!XGetGeometry( dpy, w, &JunkRoot, &x, &y, (unsigned int*)&FinalW, (unsigned int*)&FinalH, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { XBell(dpy, 0); return False; } FinalX = x; FinalY = y; get_window_borders(fw, &b); n = GetResizeMoveArguments( &action, fw->hints.base_width, fw->hints.base_height, fw->hints.width_inc, fw->hints.height_inc, &b, &FinalX, &FinalY, &FinalW, &FinalH, &fWarp, &fPointer); if (n < 4) { return False; } if (IS_MAXIMIZED(fw)) { /* must redraw the buttons now so that the 'maximize' button * does not stay depressed. */ SET_MAXIMIZED(fw, 0); border_draw_decorations( fw, PART_BUTTONS, (fw == Scr.Hilite), True, CLEAR_ALL, NULL, NULL); } dx = FinalX - fw->g.frame.x; dy = FinalY - fw->g.frame.y; /* size will be less or equal to requested */ constrain_size(fw, NULL, &FinalW, &FinalH, 0, 0, 0); if (IS_SHADED(fw)) { frame_setup_window( fw, FinalX, FinalY, FinalW, fw->g.frame.height, False); } else { frame_setup_window(fw, FinalX, FinalY, FinalW, FinalH, True); } if (fWarp) { FWarpPointer( dpy, None, None, 0, 0, 0, 0, FinalX - x, FinalY - y); } if (IS_MAXIMIZED(fw)) { fw->g.max.x += dx; fw->g.max.y += dy; } else { fw->g.normal.x += dx; fw->g.normal.y += dy; } update_absolute_geometry(fw); maximize_adjust_offset(fw); XFlush(dpy); return True; } void CMD_ResizeMove(F_CMD_ARGS) { FvwmWindow *fw = exc->w.fw; if (IS_EWMH_FULLSCREEN(fw)) { /* do not unmaximize ! */ CMD_ResizeMoveMaximize(F_PASS_ARGS); return; } resize_move_window(F_PASS_ARGS); return; } static void InteractiveMove( Window *win, const exec_context_t *exc, int *FinalX, int *FinalY, Bool do_start_at_pointer) { int origDragX,origDragY,DragX, DragY, DragWidth, DragHeight; int XOffset, YOffset; Window w; Bool do_move_opaque = False; w = *win; if (Scr.bo.do_install_root_cmap) { InstallRootColormap(); } else { InstallFvwmColormap(); } /* warp the pointer to the cursor position from before menu appeared */ /* domivogt (17-May-1999): an XFlush should not hurt anyway, so do it * unconditionally to remove the external */ XFlush(dpy); if (do_start_at_pointer) { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &DragX, &DragY, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ DragX = 0; DragY = 0; } } else { /* Although a move is usually done with a button depressed we * have to check for ButtonRelease too since the event may be * faked. */ fev_get_evpos_or_query( dpy, Scr.Root, exc->x.elast, &DragX, &DragY); } MyXGrabServer(dpy); if (!XGetGeometry( dpy, w, &JunkRoot, &origDragX, &origDragY, (unsigned int*)&DragWidth, (unsigned int*)&DragHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { MyXUngrabServer(dpy); return; } MyXGrabKeyboard(dpy); if (do_start_at_pointer) { origDragX = DragX; origDragY = DragY; } if (IS_ICONIFIED(exc->w.fw)) { do_move_opaque = True; } else if (IS_MAPPED(exc->w.fw)) { float areapct; areapct = 100.0; areapct *= ((float)DragWidth / (float)Scr.MyDisplayWidth); areapct *= ((float)DragHeight / (float)Scr.MyDisplayHeight); /* round up */ areapct += 0.1; if (Scr.OpaqueSize < 0 || (float)areapct <= (float)Scr.OpaqueSize) { do_move_opaque = True; } } if (do_move_opaque) { MyXUngrabServer(dpy); } else { Scr.flags.is_wire_frame_displayed = True; } if (!do_move_opaque && IS_ICONIFIED(exc->w.fw)) { XUnmapWindow(dpy,w); } XOffset = origDragX - DragX; YOffset = origDragY - DragY; if (!Scr.gs.do_hide_position_window) { position_geometry_window(NULL); XMapRaised(dpy,Scr.SizeWindow); } __move_loop( exc, XOffset, YOffset, DragWidth, DragHeight, FinalX, FinalY, do_move_opaque, CRS_MOVE); if (!Scr.gs.do_hide_position_window) { XUnmapWindow(dpy,Scr.SizeWindow); } if (Scr.bo.do_install_root_cmap) { UninstallRootColormap(); } else { UninstallFvwmColormap(); } if (!do_move_opaque) { int event_types[2] = { EnterNotify, LeaveNotify }; /* Throw away some events that dont interest us right now. */ discard_typed_events(2, event_types); Scr.flags.is_wire_frame_displayed = False; MyXUngrabServer(dpy); } MyXUngrabKeyboard(dpy); return; } /* Perform the movement of the window. ppctMovement *must* have a 1.0 entry * somewhere in ins list of floats, and movement will stop when it hits a 1.0 * entry */ static void AnimatedMoveAnyWindow( FvwmWindow *fw, Window w, int startX, int startY, int endX, int endY, Bool fWarpPointerToo, int cmsDelay, float *ppctMovement, MenuRepaintTransparentParameters *pmrtp) { int pointerX, pointerY; int currentX, currentY; int lastX, lastY; int deltaX, deltaY; Bool first = True; XEvent evdummy; unsigned int draw_parts = PART_NONE; if (!is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False)) { return; } /* set our defaults */ if (ppctMovement == NULL) { ppctMovement = rgpctMovementDefault; } if (cmsDelay < 0) { cmsDelay = cmsDelayDefault; } if (startX < 0 || startY < 0) { if ( !XGetGeometry( dpy, w, &JunkRoot, ¤tX, ¤tY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { XBell(dpy, 0); return; } if (startX < 0) { startX = currentX; } if (startY < 0) { startY = currentY; } } deltaX = endX - startX; deltaY = endY - startY; lastX = startX; lastY = startY; if (deltaX == 0 && deltaY == 0) { /* go nowhere fast */ return; } if (fw && w == FW_W_FRAME(fw)) { draw_parts = border_get_transparent_decorations_part(fw); } /* Needed for aborting */ MyXGrabKeyboard(dpy); do { currentX = startX + deltaX * (*ppctMovement); currentY = startY + deltaY * (*ppctMovement); if (lastX == currentX && lastY == currentY) { /* don't waste time in the same spot */ continue; } if (pmrtp != NULL) { update_transparent_menu_bg( pmrtp, lastX, lastY, currentX, currentY, endX, endY); } XMoveWindow(dpy,w,currentX,currentY); if (pmrtp != NULL) { repaint_transparent_menu( pmrtp, first, currentX, currentY, endX, endY, True); } else if (draw_parts != PART_NONE) { border_draw_decorations( fw, draw_parts, ((fw == get_focus_window())) ? True : False, True, CLEAR_ALL, NULL, NULL); } if (fw && pmrtp == NULL && IS_TEAR_OFF_MENU(fw)) { menu_redraw_transparent_tear_off_menu(fw, False); } if (fWarpPointerToo == True) { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &pointerX, &pointerY, &JunkMask) == False) { /* pointer is on a different screen */ pointerX = currentX; pointerY = currentY; } else { pointerX += currentX - lastX; pointerY += currentY - lastY; } FWarpPointer( dpy, None, Scr.Root, 0, 0, 0, 0, pointerX, pointerY); } if (fw && !IS_SHADED(fw) && !Scr.bo.do_disable_configure_notify) { /* send configure notify event for windows that care * about their location */ SendConfigureNotify( fw, currentX, currentY, fw->g.frame.width, fw->g.frame.height, 0, False); #ifdef FVWM_DEBUG_MSGS fvwm_msg(DBG,"AnimatedMoveAnyWindow", "Sent ConfigureNotify (w == %d, h == %d)", fw->g.frame.width, fw->g.frame.height); #endif } XFlush(dpy); if (fw) { fw->g.frame.x = currentX; fw->g.frame.y = currentY; update_absolute_geometry(fw); maximize_adjust_offset(fw); BroadcastConfig(M_CONFIGURE_WINDOW, fw); FlushAllMessageQueues(); } usleep(cmsDelay * 1000); /* usleep takes microseconds */ /* this didn't work for me -- maybe no longer necessary since * we warn the user when they use > .5 seconds as a * between-frame delay time. * * domivogt (28-apr-1999): That is because the keyboard was not * grabbed. works nicely now. */ if (FCheckMaskEvent( dpy, ButtonPressMask|ButtonReleaseMask|KeyPressMask, &evdummy)) { /* finish the move immediately */ if (pmrtp != NULL) { update_transparent_menu_bg( pmrtp, lastX, lastY, currentX, currentY, endX, endY); } XMoveWindow(dpy,w,endX,endY); if (pmrtp != NULL) { repaint_transparent_menu( pmrtp, first, endX, endY, endX, endY, True); } break; } lastX = currentX; lastY = currentY; first = False; } while (*ppctMovement != 1.0 && ppctMovement++); MyXUngrabKeyboard(dpy); XFlush(dpy); return; } /* used for moving menus, not a client window */ void AnimatedMoveOfWindow( Window w, int startX, int startY, int endX, int endY, Bool fWarpPointerToo, int cmsDelay, float *ppctMovement, MenuRepaintTransparentParameters *pmrtp) { AnimatedMoveAnyWindow( NULL, w, startX, startY, endX, endY, fWarpPointerToo, cmsDelay, ppctMovement, pmrtp); return; } /* used for moving client windows */ void AnimatedMoveFvwmWindow( FvwmWindow *fw, Window w, int startX, int startY, int endX, int endY, Bool fWarpPointerToo, int cmsDelay, float *ppctMovement) { AnimatedMoveAnyWindow( fw, w, startX, startY, endX, endY, fWarpPointerToo, cmsDelay, ppctMovement, NULL); return; } int placement_binding(int button, KeySym keysym, int modifier, char *action) { if (keysym != 0) { /* fixme */ fvwm_msg( ERR, "placement_binding", "sorry, placement keybindings not allowed. yet."); return 1; } if (modifier != 0) { /* fixme */ fvwm_msg( ERR, "placement_binding", "sorry, placement binding modifiers not allowed. yet."); return 1; } if (strcmp(action,"-") == 0 || strcasecmp(action,"CancelPlacement") == 0) { if (keysym == 0) /* must be button binding */ { if (button == 0) { move_drag_finish_button_mask = 0; move_interactive_finish_button_mask = 0; } else if (button > 0 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { move_drag_finish_button_mask &= ~(1<<(button-1)); move_interactive_finish_button_mask &= ~(1<<(button-1)); } } } else if (strcasecmp(action,"CancelPlacementDrag") == 0) { if (keysym == 0) /* must be button binding */ { if (button == 0) { move_drag_finish_button_mask = 0; } else if (button > 0 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { move_drag_finish_button_mask &= ~(1<<(button-1)); } } } else if (strcasecmp(action,"CancelPlacementInteractive") == 0) { if (keysym == 0) /* must be button binding */ { if (button == 0) { move_interactive_finish_button_mask = 0; } else if (button > 0 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { move_interactive_finish_button_mask &= ~(1<<(button-1)); } } } else if (strcasecmp(action,"PlaceWindow") == 0) { if (keysym == 0) /* must be button binding */ { if (button == 0) { move_interactive_finish_button_mask = move_drag_finish_button_mask = (1< 0 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { move_drag_finish_button_mask |= (1<<(button-1)); move_interactive_finish_button_mask |= (1<<(button-1)); } } } else if (strcasecmp(action,"PlaceWindowDrag") == 0) { if (keysym == 0) /* must be button binding */ { if (button == 0) { move_drag_finish_button_mask = (1< 0 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { move_drag_finish_button_mask |= (1<<(button-1)); } } } else if (strcasecmp(action,"PlaceWindowInteractive") == 0) { if (keysym == 0) /* must be button binding */ { if (button == 0) { move_interactive_finish_button_mask = (1< 0 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS) { move_interactive_finish_button_mask |= (1<<(button-1)); } } } else { fvwm_msg( ERR, "placement_binding", "invalid action %s", action); } return 0; } /* * * Start a window move operation * */ void __move_icon( FvwmWindow *fw, int x, int y, int old_x, int old_y, Bool do_move_animated, Bool do_warp_pointer) { rectangle gt; rectangle gp; Bool has_icon_title; Bool has_icon_picture; Window tw; int tx; int ty; set_icon_position(fw, x, y); broadcast_icon_geometry(fw, False); has_icon_title = get_visible_icon_title_geometry(fw, >); has_icon_picture = get_visible_icon_picture_geometry(fw, &gp); if (has_icon_picture) { tw = FW_W_ICON_PIXMAP(fw); tx = gp.x; ty = gp.y; } else if (has_icon_title) { tw = FW_W_ICON_TITLE(fw); tx = gt.x; ty = gt.y; } else { return; } if (do_move_animated) { AnimatedMoveOfWindow( tw, -1, -1, tx, ty, do_warp_pointer, -1, NULL, NULL); do_warp_pointer = 0; } if (has_icon_title) { XMoveWindow(dpy, FW_W_ICON_TITLE(fw), gt.x, gt.y); } if (has_icon_picture) { XMoveWindow(dpy, FW_W_ICON_PIXMAP(fw), gp.x, gp.y); if (fw->Desk == Scr.CurrentDesk) { XMapWindow(dpy, FW_W_ICON_PIXMAP(fw)); if (has_icon_title) { XMapWindow(dpy, FW_W_ICON_TITLE(fw)); } } } if (do_warp_pointer) { FWarpPointer(dpy, None, None, 0, 0, 0, 0, x - old_x, y - old_y); } return; } static void __move_window(F_CMD_ARGS, Bool do_animate, int mode) { int FinalX = 0; int FinalY = 0; int n; int x; int y; int width, height; int page_x, page_y; Bool fWarp = False; Bool fPointer = False; int dx; int dy; FvwmWindow *fw = exc->w.fw; Window w; if (!is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False)) { return; } /* gotta have a window */ w = FW_W_FRAME(fw); if (IS_ICONIFIED(fw)) { if (FW_W_ICON_PIXMAP(fw) != None) { w = FW_W_ICON_PIXMAP(fw); XUnmapWindow(dpy,FW_W_ICON_TITLE(fw)); } else { w = FW_W_ICON_TITLE(fw); } if (w == None && (mode == MOVE_PAGE || mode == MOVE_SCREEN)) { w = FW_W_FRAME(fw); } } if ( !XGetGeometry( dpy, w, &JunkRoot, &x, &y, (unsigned int*)&width, (unsigned int*)&height, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { return; } if (mode == MOVE_PAGE && IS_STICKY_ACROSS_PAGES(fw)) { return; } if (mode == MOVE_PAGE) { rectangle r; rectangle s; rectangle t; do_animate = False; r.x = x; r.y = y; r.width = width; r.height = height; get_absolute_geometry(&t, &r); get_page_offset_rectangle(&page_x, &page_y, &t); if (!get_page_arguments(action, &page_x, &page_y)) { page_x = Scr.Vx; page_y = Scr.Vy; } s.x = page_x - Scr.Vx; s.y = page_y - Scr.Vy; s.width = Scr.MyDisplayWidth; s.height = Scr.MyDisplayHeight; fvwmrect_move_into_rectangle(&r, &s); FinalX = r.x; FinalY = r.y; } else if (mode == MOVE_SCREEN) { rectangle r; rectangle s; rectangle p; int fscreen; do_animate = False; fscreen = FScreenGetScreenArgument( action, FSCREEN_SPEC_CURRENT); FScreenGetScrRect( NULL, fscreen, &s.x, &s.y, &s.width, &s.height); page_x = Scr.Vx; page_y = Scr.Vy; r.x = x; r.y = y; r.width = width; r.height = height; p.x = page_x - Scr.Vx; p.y = page_y - Scr.Vy; p.width = Scr.MyDisplayWidth; p.height = Scr.MyDisplayHeight; /* move to page first */ fvwmrect_move_into_rectangle(&r, &p); /* then move to screen */ fvwmrect_move_into_rectangle(&r, &s); FinalX = r.x; FinalY = r.y; } else { FinalX = x; FinalY = y; n = GetMoveArguments( &action, width, height, &FinalX, &FinalY, &fWarp, &fPointer, True); if (n != 2 || fPointer) { InteractiveMove(&w, exc, &FinalX, &FinalY, fPointer); } else if (IS_ICONIFIED(fw)) { SET_ICON_MOVED(fw, 1); } } if (w == FW_W_FRAME(fw)) { dx = FinalX - fw->g.frame.x; dy = FinalY - fw->g.frame.y; if (do_animate) { AnimatedMoveFvwmWindow( fw, w, -1, -1, FinalX, FinalY, fWarp, -1, NULL); } frame_setup_window( fw, FinalX, FinalY, fw->g.frame.width, fw->g.frame.height, True); if (fWarp & !do_animate) { FWarpPointer( dpy, None, None, 0, 0, 0, 0, FinalX - x, FinalY - y); } if (IS_MAXIMIZED(fw)) { fw->g.max.x += dx; fw->g.max.y += dy; } else { fw->g.normal.x += dx; fw->g.normal.y += dy; } update_absolute_geometry(fw); maximize_adjust_offset(fw); XFlush(dpy); } else /* icon window */ { __move_icon(fw, FinalX, FinalY, x, y, do_animate, fWarp); XFlush(dpy); } focus_grab_buttons_on_layer(fw->layer); return; } void CMD_Move(F_CMD_ARGS) { __move_window(F_PASS_ARGS, False, MOVE_NORMAL); return; } void CMD_AnimatedMove(F_CMD_ARGS) { __move_window(F_PASS_ARGS, True, MOVE_NORMAL); return; } void CMD_MoveToPage(F_CMD_ARGS) { __move_window(F_PASS_ARGS, False, MOVE_PAGE); return; } void CMD_MoveToScreen(F_CMD_ARGS) { __move_window(F_PASS_ARGS, False, MOVE_SCREEN); return; } static void update_pos( int *dest_score, int *dest_pos, int current_pos, int requested_pos) { int requested_score; requested_score = abs(current_pos - requested_pos); if (requested_score < *dest_score) { *dest_pos = requested_pos; *dest_score = requested_score; } return; } /* This function does the SnapAttraction stuff. It takes x and y coordinates * (*px and *py) and returns the snapped values. */ static void DoSnapAttract( FvwmWindow *fw, int Width, int Height, int *px, int *py) { int nyt,nxl; rectangle self; int score_x; int score_y; nxl = -99999; nyt = -99999; score_x = 99999999; score_y = 99999999; self.x = *px; self.y = *py; self.width = Width; self.height = Height; { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(fw, &g); if (rc == True) { self.height += g.height; } } /* * Snap grid handling */ if (fw->snap_grid_x > 1 && nxl == -99999) { if (*px != *px / fw->snap_grid_x * fw->snap_grid_x) { nxl = (*px + ((*px >= 0) ? fw->snap_grid_x : -fw->snap_grid_x) / 2) / fw->snap_grid_x * fw->snap_grid_x; } } if (fw->snap_grid_y > 1 && nyt == -99999) { if (*py != *py / fw->snap_grid_y * fw->snap_grid_y) { nyt = (*py + ((*py >= 0) ? fw->snap_grid_y : -fw->snap_grid_y) / 2) / fw->snap_grid_y * fw->snap_grid_y; } } /* * snap attraction */ /* snap to other windows or icons*/ if (fw->snap_attraction.proximity > 0 && (fw->snap_attraction.mode & (SNAP_ICONS | SNAP_WINDOWS | SNAP_SAME))) { FvwmWindow *tmp; int maskout = (SNAP_SCREEN | SNAP_SCREEN_WINDOWS | SNAP_SCREEN_ICONS | SNAP_SCREEN_ALL); for (tmp = Scr.FvwmRoot.next; tmp; tmp = tmp->next) { rectangle other; if (fw->Desk != tmp->Desk || fw == tmp) { continue; } /* check snapping type */ switch (fw->snap_attraction.mode & ~(maskout)) { case SNAP_WINDOWS: /* we only snap windows */ if (IS_ICONIFIED(tmp) || IS_ICONIFIED(fw)) { continue; } break; case SNAP_ICONS: /* we only snap icons */ if (!IS_ICONIFIED(tmp) || !IS_ICONIFIED(fw)) { continue; } break; case SNAP_SAME: /* we don't snap unequal */ if (IS_ICONIFIED(tmp) != IS_ICONIFIED(fw)) { continue; } break; default: /* All */ /* NOOP */ break; } /* get other window dimensions */ get_visible_window_or_icon_geometry(tmp, &other); if (other.x >= Scr.MyDisplayWidth || other.x + other.width <= 0 || other.y >= Scr.MyDisplayHeight || other.y + other.height <= 0) { /* do not snap to windows that are not currently * visible */ continue; } /* snap horizontally */ if ( other.y + other.height > *py && other.y < *py + self.height) { if (*px + self.width >= other.x && *px + self.width < other.x + fw->snap_attraction.proximity) { update_pos( &score_x, &nxl, *px, other.x - self.width); } if (*px + self.width >= other.x - fw->snap_attraction.proximity && *px + self.width < other.x) { update_pos( &score_x, &nxl, *px, other.x - self.width); } if (*px <= other.x + other.width && *px > other.x + other.width - fw->snap_attraction.proximity) { update_pos( &score_x, &nxl, *px, other.x + other.width); } if (*px <= other.x + other.width + fw->snap_attraction.proximity && *px > other.x + other.width) { update_pos( &score_x, &nxl, *px, other.x + other.width); } } /* snap vertically */ if ( other.x + other.width > *px && other.x < *px + self.width) { if (*py + self.height >= other.y && *py + self.height < other.y + fw->snap_attraction.proximity) { update_pos( &score_y, &nyt, *py, other.y - self.height); } if (*py + self.height >= other.y - fw->snap_attraction.proximity && *py + self.height < other.y) { update_pos( &score_y, &nyt, *py, other.y - self.height); } if (*py <= other.y + other.height && *py > other.y + other.height - fw->snap_attraction.proximity) { update_pos( &score_y, &nyt, *py, other.y + other.height); } if (*py <= other.y + other.height + fw->snap_attraction.proximity && *py > other.y + other.height) { update_pos( &score_y, &nyt, *py, other.y + other.height); } } } /* for */ } /* snap to other windows */ /* snap to screen egdes */ if (fw->snap_attraction.proximity > 0 && ( ( fw->snap_attraction.mode & SNAP_SCREEN && ( fw->snap_attraction.mode & SNAP_SAME || ( IS_ICONIFIED(fw) && fw->snap_attraction.mode & SNAP_ICONS ) || ( !IS_ICONIFIED(fw) && fw->snap_attraction.mode & SNAP_WINDOWS ))) || ( !IS_ICONIFIED(fw) && fw->snap_attraction.mode & SNAP_SCREEN_WINDOWS ) || ( IS_ICONIFIED(fw) && fw->snap_attraction.mode & SNAP_SCREEN_ICONS ) || fw->snap_attraction.mode & SNAP_SCREEN_ALL )) { /* vertically */ if (!(Scr.MyDisplayWidth < (*px) || (*px + self.width) < 0)) { if (*py + self.height >= Scr.MyDisplayHeight && *py + self.height < Scr.MyDisplayHeight + fw->snap_attraction.proximity) { update_pos( &score_y, &nyt, *py, Scr.MyDisplayHeight - self.height); } if (*py + self.height >= Scr.MyDisplayHeight - fw->snap_attraction.proximity && *py + self.height < Scr.MyDisplayHeight) { update_pos( &score_y, &nyt, *py, Scr.MyDisplayHeight - self.height); } if ((*py <= 0)&&(*py > - fw->snap_attraction.proximity)) { update_pos(&score_y, &nyt, *py, 0); } if ((*py <= fw->snap_attraction.proximity)&&(*py > 0)) { update_pos(&score_y, &nyt, *py, 0); } } /* vertically */ /* horizontally */ if (!(Scr.MyDisplayHeight < (*py) || (*py + self.height) < 0)) { if (*px + self.width >= Scr.MyDisplayWidth && *px + self.width < Scr.MyDisplayWidth + fw->snap_attraction.proximity) { update_pos( &score_x, &nxl, *px, Scr.MyDisplayWidth - self.width); } if (*px + self.width >= Scr.MyDisplayWidth - fw->snap_attraction.proximity && *px + self.width < Scr.MyDisplayWidth) { update_pos( &score_x, &nxl, *px, Scr.MyDisplayWidth - self.width); } if ((*px <= 0) && (*px > - fw->snap_attraction.proximity)) { update_pos(&score_x, &nxl, *px, 0); } if ((*px <= fw->snap_attraction.proximity) && (*px > 0)) { update_pos(&score_x, &nxl, *px, 0); } } /* horizontally */ } /* snap to screen edges */ if (nxl != -99999) { *px = nxl; } if (nyt != -99999) { *py = nyt; } /* * Resist moving windows beyond the edge of the screen */ if (fw->edge_resistance_move > 0) { /* snap to right edge */ if ( *px + Width > Scr.MyDisplayWidth && *px + Width < Scr.MyDisplayWidth + fw->edge_resistance_move) { *px = Scr.MyDisplayWidth - Width; } /* snap to left edge */ else if ((*px < 0) && (*px > -fw->edge_resistance_move)) { *px = 0; } /* snap to bottom edge */ if ( *py + Height > Scr.MyDisplayHeight && *py + Height < Scr.MyDisplayHeight + fw->edge_resistance_move) { *py = Scr.MyDisplayHeight - Height; } /* snap to top edge */ else if (*py < 0 && *py > -fw->edge_resistance_move) { *py = 0; } } /* Resist moving windows between xineramascreens */ if (fw->edge_resistance_xinerama_move > 0 && FScreenIsEnabled()) { int scr_x0, scr_y0; int scr_x1, scr_y1; Bool do_recalc_rectangle = False; FScreenGetResistanceRect( *px, *py, Width, Height, &scr_x0, &scr_y0, &scr_x1, &scr_y1); /* snap to right edge */ if (scr_x1 < Scr.MyDisplayWidth && *px + Width >= scr_x1 && *px + Width < scr_x1 + fw->edge_resistance_xinerama_move) { *px = scr_x1 - Width; do_recalc_rectangle = True; } /* snap to left edge */ else if ( scr_x0 > 0 && *px <= scr_x0 && scr_x0 - *px < fw->edge_resistance_xinerama_move) { *px = scr_x0; do_recalc_rectangle = True; } if (do_recalc_rectangle) { /* Snapping in X direction can move the window off a * screen. Thus, it may no longer be necessary to snap * in Y direction. */ FScreenGetResistanceRect( *px, *py, Width, Height, &scr_x0, &scr_y0, &scr_x1, &scr_y1); } /* snap to bottom edge */ if (scr_y1 < Scr.MyDisplayHeight && *py + Height >= scr_y1 && *py + Height < scr_y1 + fw->edge_resistance_xinerama_move) { *py = scr_y1 - Height; } /* snap to top edge */ else if ( scr_y0 > 0 && *py <= scr_y0 && scr_y0 - *py < fw->edge_resistance_xinerama_move) { *py = scr_y0; } } return; } /* * * Move the rubberband around, return with the new window location * * Returns True if the window has to be resized after the move. * */ Bool __move_loop( const exec_context_t *exc, int XOffset, int YOffset, int Width, int Height, int *FinalX, int *FinalY, Bool do_move_opaque, int cursor) { extern Window bad_window; Bool is_finished = False; Bool is_aborted = False; int xl,xl2,yt,yt2,delta_x,delta_y,paged; unsigned int button_mask = 0; FvwmWindow fw_copy; int dx = Scr.EdgeScrollX ? Scr.EdgeScrollX : Scr.MyDisplayWidth; int dy = Scr.EdgeScrollY ? Scr.EdgeScrollY : Scr.MyDisplayHeight; const int vx = Scr.Vx; const int vy = Scr.Vy; int xl_orig = 0; int yt_orig = 0; int cnx = 0; int cny = 0; int x_virtual_offset = 0; int y_virtual_offset = 0; Bool sent_cn = False; Bool do_resize_too = False; int x_bak; int y_bak; Window move_w = None; int orig_icon_x = 0; int orig_icon_y = 0; Bool do_snap = True; Bool was_snapped = False; /* if Alt is initially pressed don't enable no-snap until Alt is * released */ Bool nosnap_enabled = False; /* Must not set placed by button if the event is a modified KeyEvent */ Bool is_fake_event; FvwmWindow *fw = exc->w.fw; unsigned int draw_parts = PART_NONE; XEvent e; if (!GrabEm(cursor, GRAB_NORMAL)) { XBell(dpy, 0); return False; } if (!IS_MAPPED(fw) && !IS_ICONIFIED(fw)) { do_move_opaque = False; } bad_window = None; if (IS_ICONIFIED(fw)) { if (FW_W_ICON_PIXMAP(fw) != None) { move_w = FW_W_ICON_PIXMAP(fw); } else if (FW_W_ICON_TITLE(fw) != None) { move_w = FW_W_ICON_TITLE(fw); } } else { move_w = FW_W_FRAME(fw); } if ( !XGetGeometry( dpy, move_w, &JunkRoot, &x_bak, &y_bak, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { /* This is allright here since the window may not be mapped * yet. */ } if (IS_ICONIFIED(fw)) { rectangle g; get_visible_icon_geometry(fw, &g); orig_icon_x = g.x; orig_icon_y = g.y; } /* make a copy of the fw structure for sending to the pager */ memcpy(&fw_copy, fw, sizeof(FvwmWindow)); /* prevent flicker when paging */ SET_WINDOW_BEING_MOVED_OPAQUE(fw, do_move_opaque); if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &xl, &yt, &JunkX, &JunkY, &button_mask) == False) { /* pointer is on a different screen */ xl = 0; yt = 0; } else { xl += XOffset; yt += YOffset; } button_mask &= DEFAULT_ALL_BUTTONS_MASK; xl_orig = xl; yt_orig = yt; /* draw initial outline */ if (!IS_ICONIFIED(fw) && ((!do_move_opaque && !Scr.gs.do_emulate_mwm) || !IS_MAPPED(fw))) { draw_move_resize_grid(xl, yt, Width - 1, Height - 1); } if (move_w == FW_W_FRAME(fw) && do_move_opaque) { draw_parts = border_get_transparent_decorations_part(fw); } DisplayPosition(fw, exc->x.elast, xl, yt, True); memset(&e, 0, sizeof(e)); /* Unset the placed by button mask. * If the move is canceled this will remain as zero. */ fw->placed_by_button = 0; while (!is_finished && bad_window != FW_W(fw)) { int rc = 0; int old_xl; int old_yt; old_xl = xl; old_yt = yt; /* wait until there is an interesting event */ while (rc != -1 && (!FPending(dpy) || !FCheckMaskEvent( dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | ButtonMotionMask | ExposureMask, &e))) { XEvent le; int x; int y; fev_get_last_event(&le); xl -= XOffset; yt -= YOffset; rc = HandlePaging( &le, dx, dy, &xl, &yt, &delta_x, &delta_y, False, False, True, fw->edge_delay_ms_move); /* Fake an event to force window reposition */ if (delta_x) { x_virtual_offset = 0; } xl += XOffset; if (delta_y) { y_virtual_offset = 0; } yt += YOffset; if (do_snap) { DoSnapAttract(fw, Width, Height, &xl, &yt); was_snapped = True; } fev_make_null_event(&e, dpy); e.type = MotionNotify; e.xmotion.time = fev_get_evtime(); if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == True) { e.xmotion.x_root = x; e.xmotion.y_root = y; } else { /* pointer is on a different screen */ e.xmotion.x_root = 0; e.xmotion.y_root = 0; } e.xmotion.state = JunkMask; e.xmotion.same_screen = True; break; } if (rc == -1) { /* block until an event arrives */ /* dv (2004-07-01): With XFree 4.1.0.1, some Mouse * events are not reported to fvwm when the pointer * moves very fast and suddenly stops in the corner of * the screen. Handle EnterNotify/LeaveNotify events * too to get an idea where the pointer might be. */ FMaskEvent( dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | ButtonMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask, &e); } /* discard extra events before a logical release */ if (e.type == MotionNotify || e.type == EnterNotify || e.type == LeaveNotify) { while (FPending(dpy) > 0 && FCheckMaskEvent( dpy, ButtonMotionMask | PointerMotionMask | ButtonPressMask | ButtonRelease | KeyPressMask | EnterWindowMask | LeaveWindowMask, &e)) { if (e.type == ButtonPress || e.type == ButtonRelease || e.type == KeyPress) { break; } } } if (e.type == EnterNotify || e.type == LeaveNotify) { XEvent e2; int x; int y; /* Query the pointer to catch the latest information. * This *is* necessary. */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == True) { fev_make_null_event(&e2, dpy); e2.type = MotionNotify; e2.xmotion.time = fev_get_evtime(); e2.xmotion.x_root = x; e2.xmotion.y_root = y; e2.xmotion.state = JunkMask; e2.xmotion.same_screen = True; e = e2; fev_fake_event(&e); } else { /* pointer is on a different screen, * ignore event */ } } is_fake_event = False; /* Handle a limited number of key press events to allow * mouseless operation */ if (e.type == KeyPress) { Keyboard_shortcuts( &e, fw, &x_virtual_offset, &y_virtual_offset, ButtonRelease); is_fake_event = (e.type != KeyPress); } switch (e.type) { case KeyPress: if (!(e.xkey.state & Mod1Mask)) { nosnap_enabled = True; } do_snap = nosnap_enabled && (e.xkey.state & Mod1Mask) ? False : True; /* simple code to bag out of move - CKH */ if (XLookupKeysym(&(e.xkey), 0) == XK_Escape) { if (!do_move_opaque) { switch_move_resize_grid(False); } if (!IS_ICONIFIED(fw)) { if (do_move_opaque) { *FinalX = fw->g.frame.x; *FinalY = fw->g.frame.y; } } else { *FinalX = orig_icon_x; *FinalY = orig_icon_y; } is_aborted = True; is_finished = True; } break; case ButtonPress: if (e.xbutton.button <= NUMBER_OF_MOUSE_BUTTONS && ((Button1Mask << (e.xbutton.button - 1)) & button_mask)) { /* No new button was pressed, just a delayed * event */ break; } if (!IS_MAPPED(fw) && ((e.xbutton.button == 2 && !Scr.gs.do_emulate_mwm) || (e.xbutton.button == 1 && Scr.gs.do_emulate_mwm && (e.xbutton.state & ShiftMask)))) { do_resize_too = True; /* Fallthrough to button-release */ } else if (!button_mask && e.xbutton.button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS && e.xbutton.button > 0 && (move_interactive_finish_button_mask & (1<<(e.xbutton.button-1)))) { do_resize_too = False; break; } else if (button_mask && e.xbutton.button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS && e.xbutton.button > 0 && (move_drag_finish_button_mask & (1<<(e.xbutton.button-1)))) { do_resize_too = False; /* Fallthrough to button-release */ } else { /* Abort the move if * - the move started with a pressed button * and another button was pressed during the * operation * - Any button not in the * move_finish_button_mask is pressed */ /* if (button_mask) */ /* - button_mask will always be set here. * only add an if if we want to be able to * place windows dragged by other means * than releasing the initial button. */ { if (!do_move_opaque) { switch_move_resize_grid(False); } if (!IS_ICONIFIED(fw)) { *FinalX = fw->g.frame.x; *FinalY = fw->g.frame.y; } else { *FinalX = orig_icon_x; *FinalY = orig_icon_y; } is_aborted = True; is_finished = True; } break; } case ButtonRelease: if (!is_fake_event) { fw->placed_by_button = e.xbutton.button; } if (!do_move_opaque) { switch_move_resize_grid(False); } xl2 = e.xbutton.x_root + XOffset + x_virtual_offset; yt2 = e.xbutton.y_root + YOffset + y_virtual_offset; /* ignore the position of the button release if it was * on a different page. */ if (!(((xl < 0 && xl2 >= 0) || (xl >= 0 && xl2 < 0) || (yt < 0 && yt2 >= 0) || (yt >= 0 && yt2 < 0)) && (abs(xl - xl2) > Scr.MyDisplayWidth / 2 || abs(yt - yt2) > Scr.MyDisplayHeight / 2))) { xl = xl2; yt = yt2; } if (xl != xl_orig || yt != yt_orig || vx != Scr.Vx || vy != Scr.Vy || was_snapped) { /* only snap if the window actually moved! */ if (do_snap) { DoSnapAttract( fw, Width, Height, &xl, &yt); was_snapped = True; } } *FinalX = xl; *FinalY = yt; is_finished = True; break; case MotionNotify: if (e.xmotion.same_screen == False) { continue; } if (!(e.xmotion.state & Mod1Mask)) { nosnap_enabled = True; } do_snap = nosnap_enabled && (e.xmotion.state & Mod1Mask) ? False : True; xl = e.xmotion.x_root; yt = e.xmotion.y_root; if (xl > 0 && xl < Scr.MyDisplayWidth - 1) { /* pointer was moved away from the left/right * border with the mouse, reset the virtual x * offset */ x_virtual_offset = 0; } if (yt > 0 && yt < Scr.MyDisplayHeight - 1) { /* pointer was moved away from the top/bottom * border with the mouse, reset the virtual y * offset */ y_virtual_offset = 0; } xl += XOffset + x_virtual_offset; yt += YOffset + y_virtual_offset; if (do_snap) { DoSnapAttract(fw, Width, Height, &xl, &yt); was_snapped = True; } /* check Paging request once and only once after * outline redrawn redraw after paging if needed * - mab */ for (paged = 0; paged <= 1; paged++) { if (!do_move_opaque) { draw_move_resize_grid( xl, yt, Width - 1, Height - 1); } else { if (IS_ICONIFIED(fw)) { set_icon_position(fw, xl, yt); move_icon_to_position(fw); broadcast_icon_geometry( fw, False); } else { XMoveWindow( dpy, FW_W_FRAME(fw), xl, yt); } } DisplayPosition(fw, &e, xl, yt, False); /* prevent window from lagging behind mouse * when paging - mab */ if (paged == 0) { XEvent le; xl = e.xmotion.x_root; yt = e.xmotion.y_root; fev_get_last_event(&le); HandlePaging( &le, dx, dy, &xl, &yt, &delta_x, &delta_y, False, False, False, fw->edge_delay_ms_move); if (delta_x) { x_virtual_offset = 0; } xl += XOffset; if (delta_y) { y_virtual_offset = 0; } yt += YOffset; if (do_snap) { DoSnapAttract( fw, Width, Height, &xl, &yt); was_snapped = True; } if (!delta_x && !delta_y) { /* break from while * (paged <= 1) */ break; } } } /* dv (13-Jan-2014): Without this XFlush the modules * (and probably other windows too) sometimes get their * expose only after the next motion step. */ XFlush(dpy); break; case Expose: if (!do_move_opaque) { /* must undraw the rubber band in case the * event causes some drawing */ switch_move_resize_grid(False); } dispatch_event(&e); if (!do_move_opaque) { draw_move_resize_grid( xl, yt, Width - 1, Height - 1); } break; default: /* cannot happen */ break; } /* switch */ xl += x_virtual_offset; yt += y_virtual_offset; if (do_move_opaque && !IS_ICONIFIED(fw) && !IS_SHADED(fw) && !Scr.bo.do_disable_configure_notify) { /* send configure notify event for windows that care * about their location; don't send anything if * position didn't change */ if (!sent_cn || cnx != xl || cny != yt) { cnx = xl; cny = yt; sent_cn = True; SendConfigureNotify( fw, xl, yt, Width, Height, 0, False); #ifdef FVWM_DEBUG_MSGS fvwm_msg( DBG, "frame_setup_window", "Sent ConfigureNotify (w %d, h %d)", Width, Height); #endif } } if (do_move_opaque) { if (!IS_ICONIFIED(fw)) { fw_copy.g.frame.x = xl; fw_copy.g.frame.y = yt; } if (xl != old_xl || yt != old_yt) { /* only do this with opaque moves, (i.e. the * server is not grabbed) */ if (draw_parts != PART_NONE) { border_draw_decorations( fw, draw_parts, ((fw == get_focus_window())) ? True : False, True, CLEAR_ALL, NULL, NULL); } if (IS_TEAR_OFF_MENU(fw)) { menu_redraw_transparent_tear_off_menu( fw, False); } BroadcastConfig(M_CONFIGURE_WINDOW, &fw_copy); FlushAllMessageQueues(); } } } /* while (!is_finished) */ if (!Scr.gs.do_hide_position_window) { XUnmapWindow(dpy,Scr.SizeWindow); } if (is_aborted || bad_window == FW_W(fw)) { if (vx != Scr.Vx || vy != Scr.Vy) { MoveViewport(vx, vy, False); } if (is_aborted && do_move_opaque) { XMoveWindow(dpy, move_w, x_bak, y_bak); if (draw_parts != PART_NONE) { border_draw_decorations( fw, draw_parts, ((fw == get_focus_window())) ? True : False, True, CLEAR_ALL, NULL, NULL); } menu_redraw_transparent_tear_off_menu(fw, False); } if (bad_window == FW_W(fw)) { XUnmapWindow(dpy, move_w); border_undraw_decorations(fw); XBell(dpy, 0); } } if (!is_aborted && bad_window != FW_W(fw) && IS_ICONIFIED(fw)) { SET_ICON_MOVED(fw, 1); } UngrabEm(GRAB_NORMAL); if (!do_resize_too) { /* Don't wait for buttons to come up when user is placing a new * window and wants to resize it. */ WaitForButtonsUp(True); } SET_WINDOW_BEING_MOVED_OPAQUE(fw, 0); bad_window = None; return do_resize_too; } void CMD_MoveThreshold(F_CMD_ARGS) { int val = 0; if (GetIntegerArguments(action, NULL, &val, 1) < 1 || val < 0) { Scr.MoveThreshold = DEFAULT_MOVE_THRESHOLD; } else { Scr.MoveThreshold = val; } return; } void CMD_OpaqueMoveSize(F_CMD_ARGS) { int val; if (GetIntegerArguments(action, NULL, &val, 1) < 1) { if (strncasecmp(action, "unlimited", 9) == 0) { Scr.OpaqueSize = -1; } else { Scr.OpaqueSize = DEFAULT_OPAQUE_MOVE_SIZE; } } else { Scr.OpaqueSize = val; } return; } static char *hide_options[] = { "never", "move", "resize", NULL }; void CMD_HideGeometryWindow(F_CMD_ARGS) { char *token = PeekToken(action, NULL); Scr.gs.do_hide_position_window = 0; Scr.gs.do_hide_resize_window = 0; switch(GetTokenIndex(token, hide_options, 0, NULL)) { case 0: break; case 1: Scr.gs.do_hide_position_window = 1; break; case 2: Scr.gs.do_hide_resize_window = 1; break; default: Scr.gs.do_hide_position_window = 1; Scr.gs.do_hide_resize_window = 1; break; } return; } void CMD_SnapAttraction(F_CMD_ARGS) { char *cmd; size_t len; len = strlen(action); len += 99; cmd = safemalloc(len); sprintf(cmd, "Style * SnapAttraction %s", action); fvwm_msg( OLD, "CMD_SnapAttraction", "The command SnapAttraction is obsolete. Please use the" " following command instead:\n\n%s", cmd); execute_function( cond_rc, exc, cmd, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); free(cmd); return; } void CMD_SnapGrid(F_CMD_ARGS) { char *cmd; size_t len; len = strlen(action); len += 99; cmd = safemalloc(len); sprintf(cmd, "Style * SnapGrid %s", action); fvwm_msg( OLD, "CMD_SnapGrid", "The command SnapGrid is obsolete. Please use the following" " command instead:\n\n%s", cmd); execute_function( cond_rc, exc, cmd, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); free(cmd); return; } static Pixmap XorPixmap = None; void CMD_XorValue(F_CMD_ARGS) { int val; XGCValues gcv; unsigned long gcm; if (GetIntegerArguments(action, NULL, &val, 1) != 1) { val = 0; } PictureUseDefaultVisual(); gcm = GCFunction|GCLineWidth|GCForeground|GCFillStyle|GCSubwindowMode; gcv.subwindow_mode = IncludeInferiors; gcv.function = GXxor; gcv.line_width = 1; /* use passed in value, or try to calculate appropriate value if 0 */ /* ctwm method: */ /* gcv.foreground = (val1)?(val1):((((unsigned long) 1) << Scr.d_depth) - 1); */ /* Xlib programming manual suggestion: */ gcv.foreground = (val)? (val):(PictureBlackPixel() ^ PictureWhitePixel()); gcv.fill_style = FillSolid; gcv.subwindow_mode = IncludeInferiors; /* modify XorGC, only create once */ if (Scr.XorGC) { XChangeGC(dpy, Scr.XorGC, gcm, &gcv); } else { Scr.XorGC = fvwmlib_XCreateGC(dpy, Scr.Root, gcm, &gcv); } /* free up XorPixmap if neccesary */ if (XorPixmap != None) { XFreePixmap(dpy, XorPixmap); XorPixmap = None; } PictureUseFvwmVisual(); return; } void CMD_XorPixmap(F_CMD_ARGS) { char *PixmapName; FvwmPicture *xp; XGCValues gcv; unsigned long gcm; FvwmPictureAttributes fpa; action = GetNextToken(action, &PixmapName); if (PixmapName == NULL) { /* return to default value. */ action = "0"; CMD_XorValue(F_PASS_ARGS); return; } /* get the picture in the root visual, colorlimit is ignored because the * pixels will be freed */ fpa.mask = FPAM_NO_COLOR_LIMIT | FPAM_NO_ALPHA; PictureUseDefaultVisual(); xp = PGetFvwmPicture(dpy, Scr.Root, NULL, PixmapName, fpa); if (xp == NULL) { fvwm_msg(ERR,"SetXORPixmap","Can't find pixmap %s", PixmapName); free(PixmapName); PictureUseFvwmVisual(); return; } free(PixmapName); /* free up old pixmap */ if (XorPixmap != None) { XFreePixmap(dpy, XorPixmap); } /* make a copy of the picture pixmap */ XorPixmap = XCreatePixmap(dpy, Scr.Root, xp->width, xp->height, Pdepth); XCopyArea(dpy, xp->picture, XorPixmap, DefaultGC(dpy, Scr.screen), 0, 0, xp->width, xp->height, 0, 0); /* destroy picture and free colors */ PDestroyFvwmPicture(dpy, xp); PictureUseFvwmVisual(); /* create Graphics context */ gcm = GCFunction|GCLineWidth|GCTile|GCFillStyle|GCSubwindowMode; gcv.subwindow_mode = IncludeInferiors; gcv.function = GXxor; /* line width of 1 is necessary for Exceed servers */ gcv.line_width = 1; gcv.tile = XorPixmap; gcv.fill_style = FillTiled; gcv.subwindow_mode = IncludeInferiors; /* modify XorGC, only create once */ if (Scr.XorGC) { XChangeGC(dpy, Scr.XorGC, gcm, &gcv); } else { Scr.XorGC = fvwmlib_XCreateGC(dpy, Scr.Root, gcm, &gcv); } return; } /* ----------------------------- resizing code ----------------------------- */ /* Given a mouse location within a window context, return the direction the * window could be resized in, based on the window quadrant. This is the same * as the quadrants drawn by the rubber-band, if "ResizeOpaque" has not been * set. */ static direction_t __resize_get_dir_from_resize_quadrant( int x_off, int y_off, int px, int py) { direction_t dir = DIR_NONE; int tx; int ty; int dx; int dy; if (px < 0 || x_off < 0 || py < 0 || y_off < 0) { return dir; } /* Rough quadrants per window. 3x3. */ tx = (x_off / 3) - 1; ty = (y_off / 3) - 1; dx = x_off - px; dy = y_off - py; if (px < tx) { /* Far left of window. Quadrants of NW, W, SW. */ if (py < ty) { /* North-West direction. */ dir = DIR_NW; } else if (dy < ty) { /* South-West direction. */ dir = DIR_SW; } else { /* West direction. */ dir = DIR_W; } } else if (dx < tx) { /* Far right of window. Quadrants NE, E, SE. */ if (py < ty) { /* North-East direction. */ dir = DIR_NE; } else if (dy < ty) { /* South-East direction */ dir = DIR_SE; } else { /* East direction. */ dir = DIR_E; } } else { if (py < ty) { /* North direction. */ dir = DIR_N; } else if (dy < ty) { /* South direction. */ dir = DIR_S; } } return dir; } static void __resize_get_dir_from_window( int *ret_xmotion, int *ret_ymotion, FvwmWindow *fw, Window context_w) { if (context_w != Scr.Root && context_w != None) { if (context_w == FW_W_SIDE(fw, 0)) /* top */ { *ret_ymotion = 1; } else if (context_w == FW_W_SIDE(fw, 1)) /* right */ { *ret_xmotion = -1; } else if (context_w == FW_W_SIDE(fw, 2)) /* bottom */ { *ret_ymotion = -1; } else if (context_w == FW_W_SIDE(fw, 3)) /* left */ { *ret_xmotion = 1; } else if (context_w == FW_W_CORNER(fw, 0)) /* upper-left */ { *ret_xmotion = 1; *ret_ymotion = 1; } else if (context_w == FW_W_CORNER(fw, 1)) /* upper-right */ { *ret_xmotion = -1; *ret_ymotion = 1; } else if (context_w == FW_W_CORNER(fw, 2)) /* lower left */ { *ret_xmotion = 1; *ret_ymotion = -1; } else if (context_w == FW_W_CORNER(fw, 3)) /* lower right */ { *ret_xmotion = -1; *ret_ymotion = -1; } } return; } static void __resize_get_dir_proximity( int *ret_xmotion, int *ret_ymotion, FvwmWindow *fw, int x_off, int y_off, int px, int py, int *warp_x, int *warp_y, Bool find_nearest_border) { int tx; int ty; direction_t dir; *warp_x = *warp_y = -1; if (px < 0 || x_off < 0 || py < 0 || y_off < 0) { return; } if (find_nearest_border == False) { tx = 0; ty = 0; tx = max(fw->boundary_width, tx); ty = max(fw->boundary_width, ty); if (px < tx) { *ret_xmotion = 1; } else if (x_off < tx) { *ret_xmotion = -1; } if (py < ty) { *ret_ymotion = 1; } else if (y_off < ty) { *ret_ymotion = -1; } return; } /* Get the direction from the quadrant the pointer is in. */ dir = __resize_get_dir_from_resize_quadrant( x_off, y_off, px, py); switch (dir) { case DIR_NW: *ret_xmotion = 1; *ret_ymotion = 1; *warp_x = 0; *warp_y = 0; break; case DIR_SW: *ret_xmotion = 1; *ret_ymotion = -1; *warp_x = 0; *warp_y = (y_off - 1); break; case DIR_W: *ret_xmotion = 1; *warp_x = 0; *warp_y = (y_off / 2); break; case DIR_NE: *ret_xmotion = -1; *ret_ymotion = 1; *warp_x = (x_off - 1); *warp_y = 0; break; case DIR_SE: *ret_xmotion = -1; *ret_ymotion = -1; *warp_x = (x_off - 1); *warp_y = (y_off - 1); break; case DIR_E: *ret_xmotion = -1; *warp_x = (x_off - 1); *warp_y = (y_off / 2); break; case DIR_N: *ret_ymotion = 1; *warp_x = (x_off / 2); *warp_y = 0; break; case DIR_S: *ret_ymotion = -1; *warp_x = (x_off / 2); *warp_y = (y_off - 1); break; default: break; } return; } static void __resize_get_refpos( int *ret_x, int *ret_y, int xmotion, int ymotion, int w, int h, FvwmWindow *fw) { if (xmotion > 0) { *ret_x = 0; } else if (xmotion < 0) { *ret_x = w - 1; } else { *ret_x = w / 2; } if (ymotion > 0) { *ret_y = 0; } else if (ymotion < 0) { *ret_y = h - 1; } else { *ret_y = h / 2; } return; } /* Procedure: * __resize_step - move the rubberband around. This is called for * each motion event when we are resizing * * Inputs: * x_root - the X corrdinate in the root window * y_root - the Y corrdinate in the root window * x_off - x offset of pointer from border (input/output) * y_off - y offset of pointer from border (input/output) * drag - resize internal structure * orig - resize internal structure * xmotionp - pointer to xmotion in resize_window * ymotionp - pointer to ymotion in resize_window * */ static void __resize_step( const exec_context_t *exc, int x_root, int y_root, int *x_off, int *y_off, rectangle *drag, const rectangle *orig, int *xmotionp, int *ymotionp, Bool do_resize_opaque, Bool is_direction_fixed) { int action = 0; int x2; int y2; int xdir; int ydir; x2 = x_root - *x_off; x_root += *x_off; if (is_direction_fixed == True && (*xmotionp != 0 || *ymotionp != 0)) { xdir = *xmotionp; } else if (x2 <= orig->x || (*xmotionp == 1 && x2 < orig->x + orig->width - 1)) { xdir = 1; } else if (x2 >= orig->x + orig->width - 1 || (*xmotionp == -1 && x2 > orig->x)) { xdir = -1; } else { xdir = 0; } switch (xdir) { case 1: if (*xmotionp != 1) { *x_off = -*x_off; x_root = x2; *xmotionp = 1; } drag->x = x_root; drag->width = orig->x + orig->width - x_root; action = 1; break; case -1: if (*xmotionp != -1) { *x_off = -*x_off; x_root = x2; *xmotionp = -1; } drag->x = orig->x; drag->width = 1 + x_root - drag->x; action = 1; break; default: break; } y2 = y_root - *y_off; y_root += *y_off; if (is_direction_fixed == True && (*xmotionp != 0 || *ymotionp != 0)) { ydir = *ymotionp; } else if (y2 <= orig->y || (*ymotionp == 1 && y2 < orig->y + orig->height - 1)) { ydir = 1; } else if (y2 >= orig->y + orig->height - 1 || (*ymotionp == -1 && y2 > orig->y)) { ydir = -1; } else { ydir = 0; } switch (ydir) { case 1: if (*ymotionp != 1) { *y_off = -*y_off; y_root = y2; *ymotionp = 1; } drag->y = y_root; drag->height = orig->y + orig->height - y_root; action = 1; break; case -1: if (*ymotionp != -1) { *y_off = -*y_off; y_root = y2; *ymotionp = -1; } drag->y = orig->y; drag->height = 1 + y_root - drag->y; action = 1; break; default: break; } if (action) { /* round up to nearest OK size to keep pointer inside * rubberband */ constrain_size( exc->w.fw, exc->x.elast, &drag->width, &drag->height, *xmotionp, *ymotionp, CS_ROUND_UP); if (*xmotionp == 1) { drag->x = orig->x + orig->width - drag->width; } if (*ymotionp == 1) { drag->y = orig->y + orig->height - drag->height; } if (!do_resize_opaque) { draw_move_resize_grid( drag->x, drag->y, drag->width - 1, drag->height - 1); } else { frame_setup_window( exc->w.fw, drag->x, drag->y, drag->width, drag->height, False); } } DisplaySize(exc->w.fw, exc->x.elast, drag->width, drag->height, False, False); return; } /* Starts a window resize operation */ static Bool __resize_window(F_CMD_ARGS) { extern Window bad_window; FvwmWindow *fw = exc->w.fw; Bool is_finished = False, is_done = False, is_aborted = False; Bool do_send_cn = False; Bool do_resize_opaque; Bool do_warp_to_border; Bool is_direction_fixed; Bool automatic_border_direction; Bool detect_automatic_direction; Bool fButtonAbort = False; Bool fForceRedraw = False; Bool called_from_title = False; int x,y,delta_x,delta_y,stashed_x,stashed_y; Window ResizeWindow; int dx = Scr.EdgeScrollX ? Scr.EdgeScrollX : Scr.MyDisplayWidth; int dy = Scr.EdgeScrollY ? Scr.EdgeScrollY : Scr.MyDisplayHeight; const int vx = Scr.Vx; const int vy = Scr.Vy; int n; unsigned int button_mask = 0; rectangle sdrag; rectangle sorig; rectangle *drag = &sdrag; const rectangle *orig = &sorig; const window_g g_backup = fw->g; int ymotion = 0; int xmotion = 0; int was_maximized; unsigned edge_wrap_x; unsigned edge_wrap_y; int px; int py; int i; size_borders b; frame_move_resize_args mr_args = NULL; long evmask; XEvent ev; int ref_x; int ref_y; int x_off; int y_off; direction_t dir; int warp_x = 0; int warp_y = 0; bad_window = False; ResizeWindow = FW_W_FRAME(fw); if (fev_get_evpos_or_query(dpy, Scr.Root, exc->x.etrigger, &px, &py) == False || XTranslateCoordinates( dpy, Scr.Root, ResizeWindow, px, py, &px, &py, &JunkChild) == False) { /* pointer is on a different screen - that's okay here */ px = 0; py = 0; } button_mask &= DEFAULT_ALL_BUTTONS_MASK; if (!is_function_allowed(F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, True)) { XBell(dpy, 0); return False; } if (IS_SHADED(fw) || !IS_MAPPED(fw)) { do_resize_opaque = False; evmask = XEVMASK_RESIZE; } else { do_resize_opaque = DO_RESIZE_OPAQUE(fw); evmask = XEVMASK_RESIZE_OPAQUE; } /* no suffix = % of screen, 'p' = pixels, 'c' = increment units */ if (IS_SHADED(fw)) { get_unshaded_geometry(fw, drag); } else { drag->width = fw->g.frame.width; drag->height = fw->g.frame.height; } get_window_borders(fw, &b); n = GetResizeArguments( &action, fw->g.frame.x, fw->g.frame.y, fw->hints.base_width, fw->hints.base_height, fw->hints.width_inc, fw->hints.height_inc, &b, &(drag->width), &(drag->height), &dir, &is_direction_fixed, &do_warp_to_border, &automatic_border_direction, &detect_automatic_direction); if (n == 2) { rectangle new_g; /* size will be less or equal to requested */ if (IS_SHADED(fw)) { rectangle shaded_g; get_unshaded_geometry(fw, &new_g); SET_MAXIMIZED(fw, 0); constrain_size( fw, NULL, &drag->width, &drag->height, xmotion, ymotion, 0); gravity_resize( fw->hints.win_gravity, &new_g, drag->width - new_g.width, drag->height - new_g.height); fw->g.normal = new_g; get_shaded_geometry(fw, &shaded_g, &new_g); frame_setup_window( fw, shaded_g.x, shaded_g.y, shaded_g.width, shaded_g.height, False); } else { new_g = fw->g.frame; SET_MAXIMIZED(fw, 0); constrain_size( fw, NULL, &drag->width, &drag->height, xmotion, ymotion, 0); gravity_resize( fw->hints.win_gravity, &new_g, drag->width - new_g.width, drag->height - new_g.height); frame_setup_window( fw, new_g.x, new_g.y, drag->width, drag->height, False); } update_absolute_geometry(fw); maximize_adjust_offset(fw); ResizeWindow = None; return True; } was_maximized = IS_MAXIMIZED(fw); SET_MAXIMIZED(fw, 0); if (was_maximized) { /* must redraw the buttons now so that the 'maximize' button * does not stay depressed. */ border_draw_decorations( fw, PART_BUTTONS, (fw == Scr.Hilite), True, CLEAR_ALL, NULL, NULL); } if (Scr.bo.do_install_root_cmap) { InstallRootColormap(); } else { InstallFvwmColormap(); } if (!GrabEm(CRS_RESIZE, GRAB_NORMAL)) { XBell(dpy, 0); return False; } /* handle problems with edge-wrapping while resizing */ edge_wrap_x = Scr.flags.do_edge_wrap_x; edge_wrap_y = Scr.flags.do_edge_wrap_y; Scr.flags.do_edge_wrap_x = 0; Scr.flags.do_edge_wrap_y = 0; if (!do_resize_opaque) { MyXGrabServer(dpy); } if (!XGetGeometry( dpy, (Drawable)ResizeWindow, &JunkRoot, &drag->x, &drag->y, (unsigned int*)&drag->width, (unsigned int*)&drag->height, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { UngrabEm(GRAB_NORMAL); if (!do_resize_opaque) { MyXUngrabServer(dpy); } return False; } if (IS_SHADED(fw)) { SET_MAXIMIZED(fw, was_maximized); get_unshaded_geometry(fw, drag); SET_MAXIMIZED(fw, 0); } if (do_resize_opaque) { mr_args = frame_create_move_resize_args( fw, FRAME_MR_OPAQUE, &fw->g.frame, &fw->g.frame, 0, DIR_NONE); } else { Scr.flags.is_wire_frame_displayed = True; } MyXGrabKeyboard(dpy); sorig = *drag; ymotion = 0; xmotion = 0; /* pop up a resize dimensions window */ if (!Scr.gs.do_hide_resize_window) { position_geometry_window(NULL); XMapRaised(dpy, Scr.SizeWindow); } DisplaySize(fw, exc->x.elast, orig->width, orig->height, True, True); if (dir == DIR_NONE && detect_automatic_direction == True) { dir = __resize_get_dir_from_resize_quadrant( orig->width, orig->height, px, py); } if (dir != DIR_NONE) { int grav; grav = gravity_dir_to_grav(dir); gravity_get_offsets(grav, &xmotion, &ymotion); xmotion = -xmotion; ymotion = -ymotion; } if (xmotion == 0 && ymotion == 0) { __resize_get_dir_from_window(&xmotion, &ymotion, fw, PressedW); } if (FW_W_TITLE(fw) != None && PressedW == FW_W_TITLE(fw)) { /* title was pressed to start the resize */ called_from_title = True; } else { for (i = NUMBER_OF_TITLE_BUTTONS; i--; ) { /* see if the title button was pressed to that the * resize */ if (FW_W_BUTTON(fw, i) != None && FW_W_BUTTON(fw, i) == PressedW) { /* yes */ called_from_title = True; } } } /* don't warp if the resize was triggered by a press somwhere on the * title bar */ if (PressedW != Scr.Root && xmotion == 0 && ymotion == 0 && !called_from_title) { __resize_get_dir_proximity( &xmotion, &ymotion, fw, orig->width, orig->height, px, py, &warp_x, &warp_y, automatic_border_direction); if (xmotion != 0 || ymotion != 0) { do_warp_to_border = True; } } if (!IS_SHADED(fw)) { __resize_get_refpos( &ref_x, &ref_y, xmotion, ymotion, orig->width, orig->height, fw); } else { switch (SHADED_DIR(fw)) { case DIR_N: case DIR_NW: case DIR_NE: if (ymotion == -1) { ymotion = 0; } break; case DIR_S: case DIR_SW: case DIR_SE: if (ymotion == 1) { ymotion = 0; } break; default: break; } switch (SHADED_DIR(fw)) { case DIR_E: case DIR_NE: case DIR_SE: if (xmotion == 1) { xmotion = 0; } break; case DIR_W: case DIR_NW: case DIR_SW: if (xmotion == -1) { xmotion = 0; } break; default: break; } __resize_get_refpos( &ref_x, &ref_y, xmotion, ymotion, fw->g.frame.width, fw->g.frame.height, fw); } x_off = 0; y_off = 0; if (do_warp_to_border == True) { int dx; int dy; dx = (xmotion == 0) ? px : ref_x; dy = (ymotion == 0) ? py : ref_y; /* Warp the pointer to the closest border automatically? */ if (automatic_border_direction == True && (warp_x >=0 && warp_y >=0) && !IS_SHADED(fw)) { dx = warp_x; dy = warp_y; } /* warp the pointer to the border */ FWarpPointer( dpy, None, ResizeWindow, 0, 0, 1, 1, dx, dy); XFlush(dpy); } else if (xmotion != 0 || ymotion != 0) { /* keep the distance between pointer and border */ x_off = (xmotion == 0) ? 0 : ref_x - px; y_off = (ymotion == 0) ? 0 : ref_y - py; } else { /* wait until the pointer hits a border before making a * decision about the resize direction */ } /* draw the rubber-band window */ if (!do_resize_opaque) { draw_move_resize_grid( drag->x, drag->y, drag->width - 1, drag->height - 1); } /* kick off resizing without requiring any motion if invoked with a key * press */ if (exc->x.elast->type == KeyPress) { int xo; int yo; if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &stashed_x, &stashed_y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ stashed_x = 0; stashed_y = 0; } xo = 0; yo = 0; __resize_step( exc, stashed_x, stashed_y, &xo, &yo, drag, orig, &xmotion, &ymotion, do_resize_opaque, True); } else { stashed_x = stashed_y = -1; } /* loop to resize */ memset(&ev, 0, sizeof(ev)); while (!is_finished && bad_window != FW_W(fw)) { int rc = 0; int is_resized = False; /* block until there is an interesting event */ while (rc != -1 && (!FPending(dpy) || !FCheckMaskEvent(dpy, evmask, &ev))) { rc = HandlePaging( &ev, dx, dy, &x, &y, &delta_x, &delta_y, False, False, True, fw->edge_delay_ms_resize); if (rc == 1) { /* Fake an event to force window reposition */ ev.type = MotionNotify; ev.xmotion.time = fev_get_evtime(); fForceRedraw = True; break; } } if (rc == -1) { FMaskEvent( dpy, evmask | EnterWindowMask | LeaveWindowMask, &ev); } if (ev.type == MotionNotify || ev.type == EnterNotify || ev.type == LeaveNotify) { /* discard any extra motion events before a release */ /* dv (2004-07-01): With XFree 4.1.0.1, some Mouse * events are not reported to fvwm when the pointer * moves very fast and suddenly stops in the corner of * the screen. Handle EnterNotify/LeaveNotify events * too to get an idea where the pointer might be. */ while ( FCheckMaskEvent( dpy, ButtonMotionMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | EnterWindowMask | LeaveWindowMask, &ev) == True) { if (ev.type == ButtonRelease || ev.type == ButtonPress || ev.type == KeyPress) { break; } } } if (ev.type == EnterNotify || ev.type == LeaveNotify) { XEvent e2; int x; int y; /* Query the pointer to catch the latest information. * This *is* necessary. */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == True) { /* Must NOT use button_mask here, or resize * will not work with num lock */ fev_make_null_event(&e2, dpy); e2.type = MotionNotify; e2.xmotion.time = fev_get_evtime(); e2.xmotion.x_root = x; e2.xmotion.y_root = y; e2.xmotion.state = JunkMask; e2.xmotion.same_screen = True; ev = e2; fev_fake_event(&ev); } else { /* pointer is on a different screen, * ignore event */ } } is_done = False; /* Handle a limited number of key press events to allow * mouseless operation */ if (ev.type == KeyPress) { Keyboard_shortcuts(&ev, fw, NULL, NULL, ButtonRelease); if (ev.type == ButtonRelease) { do_send_cn = True; } } switch (ev.type) { case ButtonPress: is_done = True; if (ev.xbutton.button <= NUMBER_OF_MOUSE_BUTTONS && ((Button1Mask << (ev.xbutton.button - 1)) & button_mask)) { /* No new button was pressed, just a delayed * event */ break; } /* Abort the resize if * - the move started with a pressed button and * another button was pressed during the operation * - no button was started at the beginning and any * button except button 1 was pressed. */ if (button_mask || (ev.xbutton.button != 1)) { fButtonAbort = True; /* fall through */ } else { is_finished = True; do_send_cn = True; break; } case KeyPress: /* simple code to bag out of move - CKH */ if (fButtonAbort || XLookupKeysym(&ev.xkey, 0) == XK_Escape) { is_aborted = True; do_send_cn = True; is_finished = True; } is_done = True; break; case ButtonRelease: is_finished = True; is_done = True; break; case MotionNotify: if (ev.xmotion.same_screen == False) { continue; } if (!fForceRedraw) { x = ev.xmotion.x_root; y = ev.xmotion.y_root; /* resize before paging request to prevent * resize from lagging * mouse - mab */ __resize_step( exc, x, y, &x_off, &y_off, drag, orig, &xmotion, &ymotion, do_resize_opaque, is_direction_fixed); is_resized = True; /* need to move the viewport */ HandlePaging( &ev, dx, dy, &x, &y, &delta_x, &delta_y, False, False, False, fw->edge_delay_ms_resize); } /* redraw outline if we paged - mab */ if (delta_x != 0 || delta_y != 0) { sorig.x -= delta_x; sorig.y -= delta_y; drag->x -= delta_x; drag->y -= delta_y; __resize_step( exc, x, y, &x_off, &y_off, drag, orig, &xmotion, &ymotion, do_resize_opaque, is_direction_fixed); is_resized = True; } fForceRedraw = False; is_done = True; break; case PropertyNotify: { evh_args_t ea; exec_context_changes_t ecc; ecc.x.etrigger = &ev; ea.exc = exc_clone_context(exc, &ecc, ECC_ETRIGGER); HandlePropertyNotify(&ea); exc_destroy_context(ea.exc); is_done = True; break; } default: break; } if (!is_done) { if (!do_resize_opaque) { /* must undraw the rubber band in case the * event causes some drawing */ switch_move_resize_grid(False); } dispatch_event(&ev); if (!do_resize_opaque) { draw_move_resize_grid( drag->x, drag->y, drag->width - 1, drag->height - 1); } } else { if (do_resize_opaque) { /* only do this with opaque resizes, (i.e. the * server is not grabbed) */ if (is_resized == False) { BroadcastConfig( M_CONFIGURE_WINDOW, fw); } else { /* event already broadcast */ } FlushAllMessageQueues(); } } } /* erase the rubber-band */ if (!do_resize_opaque) { switch_move_resize_grid(False); } /* pop down the size window */ if (!Scr.gs.do_hide_resize_window) { XUnmapWindow(dpy, Scr.SizeWindow); } if (is_aborted || bad_window == FW_W(fw)) { /* return pointer if aborted resize was invoked with key */ if (stashed_x >= 0) { FWarpPointer( dpy, None, Scr.Root, 0, 0, 0, 0, stashed_x, stashed_y); } if (was_maximized) { /* since we aborted the resize, the window is still * maximized */ SET_MAXIMIZED(fw, 1); } if (do_resize_opaque) { int xo; int yo; rectangle g; xo = 0; yo = 0; xmotion = 1; ymotion = 1; g = sorig; __resize_step( exc, sorig.x, sorig.y, &xo, &yo, &g, orig, &xmotion, &ymotion, do_resize_opaque, True); } if (vx != Scr.Vx || vy != Scr.Vy) { MoveViewport(vx, vy, False); } /* restore all geometry-related info */ fw->g = g_backup; if (bad_window == FW_W(fw)) { XUnmapWindow(dpy, FW_W_FRAME(fw)); border_undraw_decorations(fw); XBell(dpy, 0); } } else if (!is_aborted && bad_window != FW_W(fw)) { rectangle new_g; /* size will be >= to requested */ constrain_size( fw, exc->x.elast, &drag->width, &drag->height, xmotion, ymotion, CS_ROUND_UP); if (IS_SHADED(fw)) { get_shaded_geometry(fw, &new_g, drag); } else { new_g = *drag; } if (do_resize_opaque) { frame_update_move_resize_args(mr_args, &new_g); } else { frame_setup_window( fw, new_g.x, new_g.y, new_g.width, new_g.height, False); } if (IS_SHADED(fw)) { fw->g.normal.width = drag->width; fw->g.normal.height = drag->height; } } if (is_aborted && was_maximized) { /* force redraw */ border_draw_decorations( fw, PART_BUTTONS, (fw == Scr.Hilite), True, CLEAR_ALL, NULL, NULL); } if (Scr.bo.do_install_root_cmap) { UninstallRootColormap(); } else { UninstallFvwmColormap(); } ResizeWindow = None; if (!do_resize_opaque) { int event_types[2] = { EnterNotify, LeaveNotify }; /* Throw away some events that dont interest us right now. */ discard_typed_events(2, event_types); Scr.flags.is_wire_frame_displayed = False; MyXUngrabServer(dpy); } if (mr_args != NULL) { frame_free_move_resize_args(fw, mr_args); } if (do_send_cn == True) { rectangle g; if (is_aborted) { g = sorig; } else { g = *drag; } SendConfigureNotify(fw, g.x, g.y, g.width, g.height, 0, True); } MyXUngrabKeyboard(dpy); WaitForButtonsUp(True); UngrabEm(GRAB_NORMAL); Scr.flags.do_edge_wrap_x = edge_wrap_x; Scr.flags.do_edge_wrap_y = edge_wrap_y; update_absolute_geometry(fw); maximize_adjust_offset(fw); if (is_aborted) { return False; } return True; } void CMD_Resize(F_CMD_ARGS) { FvwmWindow *fw = exc->w.fw; if (IS_EWMH_FULLSCREEN(fw)) { /* do not unmaximize ! */ CMD_ResizeMaximize(F_PASS_ARGS); return; } __resize_window(F_PASS_ARGS); return; } /* ----------------------------- maximizing code --------------------------- */ Bool is_window_sticky_across_pages(FvwmWindow *fw) { if (IS_STICKY_ACROSS_PAGES(fw) || (IS_ICONIFIED(fw) && IS_ICON_STICKY_ACROSS_PAGES(fw))) { return True; } else { return False; } } Bool is_window_sticky_across_desks(FvwmWindow *fw) { if (IS_STICKY_ACROSS_DESKS(fw) || (IS_ICONIFIED(fw) && IS_ICON_STICKY_ACROSS_DESKS(fw))) { return True; } else { return False; } } static void move_sticky_window_to_same_page( int *x11, int *x12, int *y11, int *y12, int x21, int x22, int y21, int y22) { /* make sure the x coordinate is on the same page as the reference * window */ if (*x11 >= x22) { while (*x11 >= x22) { *x11 -= Scr.MyDisplayWidth; *x12 -= Scr.MyDisplayWidth; } } else if (*x12 <= x21) { while (*x12 <= x21) { *x11 += Scr.MyDisplayWidth; *x12 += Scr.MyDisplayWidth; } } /* make sure the y coordinate is on the same page as the reference * window */ if (*y11 >= y22) { while (*y11 >= y22) { *y11 -= Scr.MyDisplayHeight; *y12 -= Scr.MyDisplayHeight; } } else if (*y12 <= y21) { while (*y12 <= y21) { *y11 += Scr.MyDisplayHeight; *y12 += Scr.MyDisplayHeight; } } return; } static void MaximizeHeight( FvwmWindow *win, int win_width, int win_x, int *win_height, int *win_y, Bool grow_up, Bool grow_down, int top_border, int bottom_border, int *layers) { FvwmWindow *cwin; int x11, x12, x21, x22; int y11, y12, y21, y22; int new_y1, new_y2; rectangle g; Bool rc; x11 = win_x; /* Start x */ y11 = *win_y; /* Start y */ x12 = x11 + win_width; /* End x */ y12 = y11 + *win_height; /* End y */ new_y1 = top_border; new_y2 = bottom_border; for (cwin = Scr.FvwmRoot.next; cwin; cwin = cwin->next) { if (cwin == win || (cwin->Desk != win->Desk && !is_window_sticky_across_desks(cwin))) { continue; } if ((layers[0] >= 0 && cwin->layer < layers[0]) || (layers[1] >= 0 && cwin->layer > layers[1])) { continue; } rc = get_visible_window_or_icon_geometry(cwin, &g); if (rc == False) { continue; } x21 = g.x; y21 = g.y; x22 = x21 + g.width; y22 = y21 + g.height; if (is_window_sticky_across_pages(cwin)) { move_sticky_window_to_same_page( &x21, &x22, &new_y1, &new_y2, x11, x12, y11, y12); } /* Are they in the same X space? */ if (!((x22 <= x11) || (x21 >= x12))) { if ((y22 <= y11) && (y22 >= new_y1)) { new_y1 = y22; } else if ((y12 <= y21) && (new_y2 >= y21)) { new_y2 = y21; } } } if (!grow_up) { new_y1 = y11; } if (!grow_down) { new_y2 = y12; } *win_height = new_y2 - new_y1; *win_y = new_y1; return; } static void MaximizeWidth( FvwmWindow *win, int *win_width, int *win_x, int win_height, int win_y, Bool grow_left, Bool grow_right, int left_border, int right_border, int *layers) { FvwmWindow *cwin; int x11, x12, x21, x22; int y11, y12, y21, y22; int new_x1, new_x2; rectangle g; Bool rc; x11 = *win_x; /* Start x */ y11 = win_y; /* Start y */ x12 = x11 + *win_width; /* End x */ y12 = y11 + win_height; /* End y */ new_x1 = left_border; new_x2 = right_border; for (cwin = Scr.FvwmRoot.next; cwin; cwin = cwin->next) { if (cwin == win || (cwin->Desk != win->Desk && !is_window_sticky_across_desks(cwin))) { continue; } if ((layers[0] >= 0 && cwin->layer < layers[0]) || (layers[1] >= 0 && cwin->layer > layers[1])) { continue; } rc = get_visible_window_or_icon_geometry(cwin, &g); if (rc == False) { continue; } x21 = g.x; y21 = g.y; x22 = x21 + g.width; y22 = y21 + g.height; if (is_window_sticky_across_pages(cwin)) { move_sticky_window_to_same_page( &new_x1, &new_x2, &y21, &y22, x11, x12, y11, y12); } /* Are they in the same Y space? */ if (!((y22 <= y11) || (y21 >= y12))) { if ((x22 <= x11) && (x22 >= new_x1)) { new_x1 = x22; } else if ((x12 <= x21) && (new_x2 >= x21)) { new_x2 = x21; } } } if (!grow_left) { new_x1 = x11; } if (!grow_right) { new_x2 = x12; } *win_width = new_x2 - new_x1; *win_x = new_x1; return; } static void unmaximize_fvwm_window( FvwmWindow *fw) { rectangle new_g; SET_MAXIMIZED(fw, 0); if (IS_SHADED(fw)) { get_shaded_geometry(fw, &new_g, &new_g); } /* We might be restoring a window's geometry coming out of fullscreen, * which might be a maximized window, so ensure we use the correct * geometry reference. * * If the window was not maximized, then we use the window's normal * geometry. */ get_relative_geometry(&new_g, fw->fullscreen.was_maximized ? &fw->fullscreen.g.max : &fw->g.normal); if (fw->fullscreen.was_maximized) { /* If MWMButtons is in use, set the style of the button as * marked as maximized. */ SET_MAXIMIZED(fw, 1); } if (IS_EWMH_FULLSCREEN(fw)) { SET_EWMH_FULLSCREEN(fw, False); if (DO_EWMH_USE_STACKING_HINTS(fw)) { new_layer(fw, fw->ewmh_normal_layer); } } /* TA: Apply the decor change now, if the window we've just restored * was maximized; the client frame and geometry will be updated as a * result of this, so we correctly restore the window at this point. */ if (fw->fullscreen.was_maximized) { fw->fullscreen.was_maximized = 0; apply_decor_change(fw); } frame_setup_window( fw, new_g.x, new_g.y, new_g.width, new_g.height, True); border_draw_decorations( fw, PART_ALL, (Scr.Hilite == fw), True, CLEAR_ALL, NULL, NULL); if (fw->fullscreen.is_shaded) { execute_function_override_window( NULL, NULL, "WindowShade on", 0, fw); fw->fullscreen.is_shaded = 0; } if (fw->fullscreen.is_iconified) { execute_function_override_window( NULL, NULL, "Iconify on", 0, fw); fw->fullscreen.is_iconified = 0; } /* Since the window's geometry will have been constrained already when * coming out of fullscreen, we can always call this; either it's a * noop or the window will be correctly decorated in the case of the * window being restored from fullscreen to a non-maximized state. */ apply_decor_change(fw); return; } static void maximize_fvwm_window( FvwmWindow *fw, rectangle *geometry) { SET_MAXIMIZED(fw, 1); fw->g.max_defect.width = 0; fw->g.max_defect.height = 0; constrain_size( fw, NULL, &geometry->width, &geometry->height, 0, 0, CS_UPDATE_MAX_DEFECT); fw->g.max = *geometry; if (IS_SHADED(fw)) { get_shaded_geometry(fw, geometry, &fw->g.max); } frame_setup_window( fw, geometry->x, geometry->y, geometry->width, geometry->height, True); border_draw_decorations( fw, PART_ALL, (Scr.Hilite == fw), True, CLEAR_ALL, NULL, NULL); update_absolute_geometry(fw); /* remember the offset between old and new position in case the * maximized window is moved more than the screen width/height. */ fw->g.max_offset.x = fw->g.normal.x - fw->g.max.x; fw->g.max_offset.y = fw->g.normal.y - fw->g.max.y; #if 0 fprintf(stderr,"%d %d %d %d, g.max_offset.x = %d, g.max_offset.y = %d, %d %d %d %d\n", fw->g.max.x, fw->g.max.y, fw->g.max.width, fw->g.max.height, fw->g.max_offset.x, fw->g.max_offset.y, fw->g.normal.x, fw->g.normal.y, fw->g.normal.width, fw->g.normal.height); #endif return; } /* * * Procedure: * (Un)Maximize a window. * */ void CMD_Maximize(F_CMD_ARGS) { int page_x, page_y; int val1, val2, val1_unit, val2_unit; int toggle; char *token; char *taction; Bool grow_up = False; Bool grow_down = False; Bool grow_left = False; Bool grow_right = False; Bool do_force_maximize = False; Bool do_forget = False; Bool is_screen_given = False; Bool ignore_working_area = False; int layers[2] = { -1, -1 }; Bool global_flag_parsed = False; int scr_x, scr_y; int scr_w, scr_h; rectangle new_g; FvwmWindow *fw = exc->w.fw; if ( !is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { XBell(dpy, 0); return; } /* Check for "global" flag ("absolute" is for compatibility with E) */ while (!global_flag_parsed) { token = PeekToken(action, &taction); if (!token) { global_flag_parsed = True; } else { if (StrEquals(token, "screen")) { int scr; is_screen_given = True; token = PeekToken(taction, &action); scr = FScreenGetScreenArgument( token, FSCREEN_SPEC_PRIMARY); FScreenGetScrRect( NULL, scr, &scr_x, &scr_y, &scr_w, &scr_h); } else if (StrEquals(token, "ewmhiwa")) { ignore_working_area = True; action = taction; } else if (StrEquals(token, "growonwindowlayer")) { layers[0] = fw->layer; layers[1] = fw->layer; action = taction; } else if (StrEquals(token, "growonlayers")) { int n; n = GetIntegerArguments( taction, &action, layers, 2); if (n != 2) { layers[0] = -1; layers[1] = -1; } } else { global_flag_parsed = True; } } } toggle = ParseToggleArgument(action, &action, -1, 0); if (toggle == 0 && !IS_MAXIMIZED(fw)) { return; } if (toggle == 1 && IS_MAXIMIZED(fw)) { /* Fake that the window is not maximized. */ do_force_maximize = True; } /* find the new page and geometry */ new_g.x = fw->g.frame.x; new_g.y = fw->g.frame.y; new_g.width = fw->g.frame.width; new_g.height = fw->g.frame.height; get_page_offset_check_visible(&page_x, &page_y, fw); /* Check if we should constrain rectangle to some Xinerama screen */ if (!is_screen_given) { fscreen_scr_arg fscr; fscr.xypos.x = fw->g.frame.x + fw->g.frame.width / 2 - page_x; fscr.xypos.y = fw->g.frame.y + fw->g.frame.height / 2 - page_y; FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &scr_x, &scr_y, &scr_w, &scr_h); } if (!ignore_working_area) { EWMH_GetWorkAreaIntersection( fw, &scr_x, &scr_y, &scr_w, &scr_h, EWMH_MAXIMIZE_MODE(fw)); } #if 0 fprintf(stderr, "%s: page=(%d,%d), scr=(%d,%d, %dx%d)\n", __FUNCTION__, page_x, page_y, scr_x, scr_y, scr_w, scr_h); #endif /* parse first parameter */ val1_unit = scr_w; token = PeekToken(action, &taction); if (token && StrEquals(token, "forget")) { if (!IS_MAXIMIZED(fw)) { return; } do_forget = True; do_force_maximize = True; } else if (token && StrEquals(token, "grow")) { grow_left = True; grow_right = True; val1 = 100; val1_unit = scr_w; } else if (token && StrEquals(token, "growleft")) { grow_left = True; val1 = 100; val1_unit = scr_w; } else if (token && StrEquals(token, "growright")) { grow_right = True; val1 = 100; val1_unit = scr_w; } else { if (GetOnePercentArgument(token, &val1, &val1_unit) == 0) { val1 = 100; val1_unit = scr_w; } else if (val1 < 0) { /* handle negative offsets */ if (val1_unit == scr_w) { val1 = 100 + val1; } else { val1 = scr_w + val1; } } } /* parse second parameter */ val2_unit = scr_h; token = PeekToken(taction, NULL); if (do_forget == True) { /* nop */ } else if (token && StrEquals(token, "grow")) { grow_up = True; grow_down = True; val2 = 100; val2_unit = scr_h; } else if (token && StrEquals(token, "growup")) { grow_up = True; val2 = 100; val2_unit = scr_h; } else if (token && StrEquals(token, "growdown")) { grow_down = True; val2 = 100; val2_unit = scr_h; } else { if (GetOnePercentArgument(token, &val2, &val2_unit) == 0) { val2 = 100; val2_unit = scr_h; } else if (val2 < 0) { /* handle negative offsets */ if (val2_unit == scr_h) { val2 = 100 + val2; } else { val2 = scr_h + val2; } } } #if 0 fprintf(stderr, "%s: page=(%d,%d), scr=(%d,%d, %dx%d)\n", __FUNCTION__, page_x, page_y, scr_x, scr_y, scr_w, scr_h); #endif if (do_forget == True) { fw->g.normal = fw->g.max; unmaximize_fvwm_window(fw); } else if (IS_MAXIMIZED(fw) && !do_force_maximize) { unmaximize_fvwm_window(fw); } else /* maximize */ { /* handle command line arguments */ if (grow_up || grow_down) { MaximizeHeight( fw, new_g.width, new_g.x, &new_g.height, &new_g.y, grow_up, grow_down, page_y + scr_y, page_y + scr_y + scr_h, layers); } else if (val2 > 0) { new_g.height = val2 * val2_unit / 100; new_g.y = page_y + scr_y; } if (grow_left || grow_right) { MaximizeWidth( fw, &new_g.width, &new_g.x, new_g.height, new_g.y, grow_left, grow_right, page_x + scr_x, page_x + scr_x + scr_w, layers); } else if (val1 >0) { new_g.width = val1 * val1_unit / 100; new_g.x = page_x + scr_x; } if (val1 == 0 && val2 == 0) { new_g.x = page_x + scr_x; new_g.y = page_y + scr_y; new_g.height = scr_h; new_g.width = scr_w; } /* now maximize it */ maximize_fvwm_window(fw, &new_g); } EWMH_SetWMState(fw, False); return; } /* * * Same as CMD_Resize and CMD_ResizeMove, but the window ends up maximized * without touching the normal geometry. * */ void CMD_ResizeMaximize(F_CMD_ARGS) { rectangle normal_g; rectangle max_g; Bool was_resized; FvwmWindow *fw = exc->w.fw; /* keep a copy of the old geometry */ normal_g = fw->g.normal; /* resize the window normally */ was_resized = __resize_window(F_PASS_ARGS); if (was_resized == True) { /* set the new geometry as the maximized geometry and restore * the old normal geometry */ max_g = fw->g.normal; max_g.x -= Scr.Vx; max_g.y -= Scr.Vy; fw->g.normal = normal_g; /* and mark it as maximized */ maximize_fvwm_window(fw, &max_g); } EWMH_SetWMState(fw, False); return; } void CMD_ResizeMoveMaximize(F_CMD_ARGS) { rectangle normal_g; rectangle max_g; Bool was_resized; FvwmWindow *fw = exc->w.fw; /* keep a copy of the old geometry */ normal_g = fw->g.normal; /* resize the window normally */ was_resized = resize_move_window(F_PASS_ARGS); if (was_resized == True) { /* set the new geometry as the maximized geometry and restore * the old normal geometry */ max_g = fw->g.normal; max_g.x -= Scr.Vx; max_g.y -= Scr.Vy; fw->g.normal = normal_g; /* and mark it as maximized */ maximize_fvwm_window(fw, &max_g); } EWMH_SetWMState(fw, False); return; } /* ----------------------------- stick code -------------------------------- */ int stick_across_pages(F_CMD_ARGS, int toggle) { FvwmWindow *fw = exc->w.fw; if ((toggle == 1 && IS_STICKY_ACROSS_PAGES(fw)) || (toggle == 0 && !IS_STICKY_ACROSS_PAGES(fw))) { return 0; } if (IS_STICKY_ACROSS_PAGES(fw)) { SET_STICKY_ACROSS_PAGES(fw, 0); } else { if (!IsRectangleOnThisPage(&fw->g.frame, Scr.CurrentDesk)) { action = ""; __move_window(F_PASS_ARGS, False, MOVE_PAGE); } SET_STICKY_ACROSS_PAGES(fw, 1); } return 1; } int stick_across_desks(F_CMD_ARGS, int toggle) { FvwmWindow *fw = exc->w.fw; if ((toggle == 1 && IS_STICKY_ACROSS_DESKS(fw)) || (toggle == 0 && !IS_STICKY_ACROSS_DESKS(fw))) { return 0; } if (IS_STICKY_ACROSS_DESKS(fw)) { SET_STICKY_ACROSS_DESKS(fw, 0); fw->Desk = Scr.CurrentDesk; } else { if (fw->Desk != Scr.CurrentDesk) { do_move_window_to_desk(fw, Scr.CurrentDesk); } SET_STICKY_ACROSS_DESKS(fw, 1); } return 1; } static void __handle_stick_exit( FvwmWindow *fw, int do_not_draw, int do_silently) { if (do_not_draw == 0) { border_draw_decorations( fw, PART_TITLE | PART_BUTTONS, (Scr.Hilite==fw), True, CLEAR_ALL, NULL, NULL); } if (!do_silently) { BroadcastConfig(M_CONFIGURE_WINDOW,fw); EWMH_SetWMState(fw, False); EWMH_SetWMDesktop(fw); } return; } void handle_stick_across_pages( F_CMD_ARGS, int toggle, int do_not_draw, int do_silently) { FvwmWindow *fw = exc->w.fw; int did_change; did_change = stick_across_pages(F_PASS_ARGS, toggle); if (did_change) { __handle_stick_exit(fw, do_not_draw, do_silently); } return; } void handle_stick_across_desks( F_CMD_ARGS, int toggle, int do_not_draw, int do_silently) { FvwmWindow *fw = exc->w.fw; int did_change; did_change = stick_across_desks(F_PASS_ARGS, toggle); if (did_change) { __handle_stick_exit(fw, do_not_draw, do_silently); } return; } void handle_stick( F_CMD_ARGS, int toggle_page, int toggle_desk, int do_not_draw, int do_silently) { FvwmWindow *fw = exc->w.fw; int did_change; did_change = 0; did_change |= stick_across_desks(F_PASS_ARGS, toggle_desk); did_change |= stick_across_pages(F_PASS_ARGS, toggle_page); if (did_change) { __handle_stick_exit(fw, do_not_draw, do_silently); } return; } void CMD_Stick(F_CMD_ARGS) { int toggle; toggle = ParseToggleArgument(action, &action, -1, 0); if (toggle == -1 && IS_STICKY_ACROSS_DESKS(exc->w.fw) != IS_STICKY_ACROSS_PAGES(exc->w.fw)) { /* don't switch between only stickypage and only stickydesk. * rather switch it off completely */ toggle = 0; } handle_stick(F_PASS_ARGS, toggle, toggle, 0, 0); return; } void CMD_StickAcrossPages(F_CMD_ARGS) { int toggle; toggle = ParseToggleArgument(action, &action, -1, 0); handle_stick_across_pages(F_PASS_ARGS, toggle, 0, 0); return; } void CMD_StickAcrossDesks(F_CMD_ARGS) { int toggle; toggle = ParseToggleArgument(action, &action, -1, 0); handle_stick_across_desks(F_PASS_ARGS, toggle, 0, 0); return; } fvwm-2.6.7/fvwm/update.c0000644000175700017570000004462612773467232012102 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/Grab.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "cursor.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "update.h" #include "style.h" #include "builtins.h" #include "borders.h" #include "frame.h" #include "ewmh.h" #include "icons.h" #include "geometry.h" #include "move_resize.h" #include "add_window.h" #include "module_interface.h" #include "focus.h" #include "stack.h" #include "icons.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ static void init_style( FvwmWindow *old_t, FvwmWindow *t, window_style *pstyle, short *pbuttons) { /* copy the window structure because we still need some old values. */ memcpy(old_t, t, sizeof(FvwmWindow)); /* determine level of decoration */ setup_style_and_decor(t, pstyle, pbuttons); /* restore some old values */ IS_STICKY_ACROSS_PAGES(t) = IS_STICKY_ACROSS_PAGES(old_t); IS_STICKY_ACROSS_DESKS(t) = IS_STICKY_ACROSS_DESKS(old_t); GET_USER_STATES(t) = GET_USER_STATES(old_t); return; } static void apply_window_updates( FvwmWindow *t, update_win *flags, window_style *pstyle, FvwmWindow *focus_w) { FvwmWindow old_t; short buttons; Bool is_style_initialised = False; rectangle frame_g; const exec_context_t *exc; exec_context_changes_t ecc; frame_g.x = t->g.frame.x; frame_g.y = t->g.frame.y; frame_g.width = t->g.frame.width; frame_g.height = t->g.frame.height; /* TA: 2010-07-28: Conditionally update window states if they're * present -- i.e., we're preserving states set via Windowstyle. */ CLEAR_USER_STATES(t, S_USER_STATES(SCM(*pstyle))); SET_USER_STATES(t, S_USER_STATES(SCF(*pstyle))); if (flags->do_setup_focus_policy) { setup_focus_policy(t); if (t == focus_w && !fpol_query_allow_user_focus(&FW_FOCUS_POLICY(t))) { focus_w = NULL; if (Scr.Hilite == t) { Scr.Hilite = NULL; } flags->do_redraw_decoration = True; } } if (flags->do_update_window_grabs) { focus_grab_buttons(t); } if (IS_TRANSIENT(t) && flags->do_redecorate_transient) { flags->do_redecorate = True; flags->do_update_window_font = True; } /* * is_sticky * is_icon_sticky * * These are a bit complicated because they can move windows to a * different page or desk. */ ecc.type = EXCT_NULL; ecc.w.fw = t; ecc.w.w = FW_W_FRAME(t); ecc.w.wcontext = C_FRAME; exc = exc_create_context( &ecc, ECC_TYPE | ECC_FW | ECC_W | ECC_WCONTEXT); if (flags->do_update_stick_icon && IS_ICONIFIED(t) && !(IS_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_DESKS(t))) { if (IS_ICON_STICKY_ACROSS_PAGES(pstyle) || IS_ICON_STICKY_ACROSS_DESKS(pstyle)) { /* stick and unstick the window to force the icon on * the current page */ handle_stick( NULL, exc, "", S_IS_STICKY_ACROSS_PAGES(SCF(*pstyle)), S_IS_STICKY_ACROSS_DESKS(SCF(*pstyle)), 1, 1); handle_stick(NULL, exc, "", 0, 0, 1, 0); } flags->do_update_icon_title = True; } else if (flags->do_update_stick) { handle_stick( NULL, exc, "", S_IS_STICKY_ACROSS_PAGES(SCF(*pstyle)), S_IS_STICKY_ACROSS_DESKS(SCF(*pstyle)), 0, 0); } exc_destroy_context(exc); if (FMiniIconsSupported && flags->do_update_mini_icon) { if (!HAS_EWMH_MINI_ICON(t) || DO_EWMH_MINI_ICON_OVERRIDE(t)) { change_mini_icon(t, pstyle); } else { if (EWMH_SetIconFromWMIcon(t, NULL, 0, True)) { SET_HAS_EWMH_MINI_ICON(t, True); } else { /* "should" not happen */ SET_HAS_EWMH_MINI_ICON(t, False); change_mini_icon(t, pstyle); } } } if (flags->do_update_visible_window_name) { setup_visible_name(t, False); BroadcastName(M_VISIBLE_NAME,FW_W(t),FW_W_FRAME(t), (unsigned long)t,t->visible_name); EWMH_SetVisibleName(t, False); } if (flags->do_update_visible_icon_name) { setup_visible_name(t, True); BroadcastName(MX_VISIBLE_ICON_NAME,FW_W(t),FW_W_FRAME(t), (unsigned long)t,t->visible_icon_name); EWMH_SetVisibleName(t, True); } if (flags->do_update_window_font || flags->do_update_window_font_height) { if (!is_style_initialised) { init_style(&old_t, t, pstyle, &buttons); is_style_initialised = True; } setup_window_font(t, pstyle, flags->do_update_window_font); flags->do_redecorate = True; } if (flags->do_update_title_text_dir) { flags->do_redecorate = True; } if (flags->do_redecorate || flags->do_update_title_dir) { size_borders b_old; size_borders b_new; int dw = 0; int dh = 0; rectangle naked_g; rectangle *new_g; if (flags->do_redecorate) { if (!is_style_initialised) { init_style(&old_t, t, pstyle, &buttons); is_style_initialised = True; } /* redecorate */ change_auxiliary_windows(t, buttons); /* calculate the new offsets */ /* naked_g: geometry without decor */ gravity_get_naked_geometry( old_t.hints.win_gravity, &old_t, &naked_g, &t->g.normal); /* gravity without decor */ gravity_translate_to_northwest_geometry_no_bw( old_t.hints.win_gravity, &old_t, &naked_g, &naked_g); /* set g.normal with the decor */ gravity_add_decoration( old_t.hints.win_gravity, t, &t->g.normal, &naked_g); } if (flags->do_update_title_dir) { /* new border sizes */ get_window_borders(t, &b_old); SET_TITLE_DIR(t, S_TITLE_DIR(SCF(*pstyle))); setup_title_geometry(t, pstyle); get_window_borders(t, &b_new); /* resizing */ dw = b_new.total_size.width - b_old.total_size.width; dh = b_new.total_size.height - b_old.total_size.height; gravity_resize( t->hints.win_gravity, &t->g.normal, dw, dh); gravity_constrain_size( t->hints.win_gravity, t, &t->g.normal, 0); } if (IS_MAXIMIZED(t)) { if (flags->do_redecorate) { int off_x = old_t.g.normal.x - old_t.g.max.x; int off_y = old_t.g.normal.y - old_t.g.max.y; int new_off_x; int new_off_y; /* maximized windows are always considered to * have NorthWestGravity */ gravity_get_naked_geometry( NorthWestGravity, &old_t, &naked_g, &t->g.max); gravity_translate_to_northwest_geometry_no_bw( NorthWestGravity, &old_t, &naked_g, &naked_g); gravity_add_decoration( NorthWestGravity, t, &t->g.max, &naked_g); /* prevent random paging when unmaximizing * after e.g. the border width has changed */ new_off_x = t->g.normal.x - t->g.max.x; new_off_y = t->g.normal.y - t->g.max.y; t->g.max_offset.x += new_off_x - off_x; t->g.max_offset.y += new_off_y - off_y; } if (flags->do_update_title_dir) { frame_g = t->g.max; gravity_resize( t->hints.win_gravity, &t->g.max, dw, dh); gravity_constrain_size( t->hints.win_gravity, t, &t->g.max, CS_UPDATE_MAX_DEFECT); } new_g = &t->g.max; } else { new_g = &t->g.normal; } if (IS_SHADED(t)) { get_unshaded_geometry(t, new_g); if (USED_TITLE_DIR_FOR_SHADING(t)) { SET_SHADED_DIR(t, GET_TITLE_DIR(t)); } get_shaded_geometry(t, &frame_g, new_g); } else { get_relative_geometry(&frame_g, new_g); } flags->do_setup_frame = True; flags->do_redraw_decoration = True; } if (flags->do_update_rotated_title) { if (t->title_text_rotation != ROTATION_0) { flags->do_setup_frame = True; flags->do_redraw_decoration = True; } } if (flags->do_resize_window) { rectangle old_g; setup_frame_size_limits(t, pstyle); old_g = frame_g; frame_g = t->g.normal; gravity_constrain_size(t->hints.win_gravity, t, &frame_g, 0); t->g.normal = frame_g; if (IS_MAXIMIZED(t)) { frame_g = t->g.max; gravity_constrain_size( t->hints.win_gravity, t, &frame_g, CS_UPDATE_MAX_DEFECT); t->g.max = frame_g; } frame_g = old_g; gravity_constrain_size( t->hints.win_gravity, t, &frame_g, 0); flags->do_setup_frame = True; flags->do_redraw_decoration = True; } if (flags->do_setup_frame) { FvwmWindow *tmp; setup_title_geometry(t, pstyle); /* frame_force_setup_window needs to know if the window is * hilighted */ tmp = get_focus_window(); set_focus_window(focus_w); frame_force_setup_window( t, frame_g.x, frame_g.y, frame_g.width, frame_g.height, True); set_focus_window(tmp); EWMH_SetFrameStrut(t); } if (flags->do_update_window_color) { if (t != focus_w) { flags->do_redraw_decoration = True; } update_window_color_style(t, pstyle); if (t != Scr.Hilite) { flags->do_broadcast_focus = True; } } if (flags->do_update_window_color_hi) { if (t == focus_w) { flags->do_redraw_decoration = True; } update_window_color_hi_style(t, pstyle); flags->do_broadcast_focus = True; if (t == Scr.Hilite) { flags->do_broadcast_focus = True; } } if (flags->do_update_icon_title_cs_hi) { if (t == focus_w && IS_ICONIFIED(t)) { flags->do_redraw_icon = True; } update_icon_title_cs_hi_style(t, pstyle); } if (flags->do_update_icon_title_cs) { if (t != focus_w && IS_ICONIFIED(t)) { flags->do_redraw_icon = True; } update_icon_title_cs_style(t, pstyle); } if (flags->do_update_icon_background_cs) { int old_cs = t->icon_background_cs; update_icon_background_cs_style(t, pstyle); if ((old_cs < 0 && t->icon_background_cs >= 0) || (old_cs >= 0 && t->icon_background_cs < 0)) { flags->do_update_icon = True; } else { flags->do_redraw_icon = True; } } if (flags->do_update_icon_size_limits) { setup_icon_size_limits(t, pstyle); flags->do_update_icon = True; } if (flags->do_update_icon_font) { if (!is_style_initialised) { init_style(&old_t, t, pstyle, &buttons); is_style_initialised = True; } setup_icon_font(t, pstyle, flags->do_update_icon_font); flags->do_update_icon_title = True; } if (flags->do_update_icon_boxes) { change_icon_boxes(t, pstyle); } if (flags->do_update_icon) { setup_icon_background_parameters(t, pstyle); setup_icon_title_parameters(t, pstyle); change_icon(t, pstyle); flags->do_update_icon_placement = True; flags->do_update_icon_title = False; flags->do_redraw_icon = False; flags->do_update_ewmh_icon = True; } if (flags->do_redraw_icon) { /* should not test if the window is iconified */ DrawIconWindow(t, True, True, False, True, NULL);; flags->do_redraw_decoration = False; flags->do_update_icon_title = False; } if (flags->do_update_icon_title) { RedoIconName(t); } if (flags->do_update_icon_placement) { if (IS_ICONIFIED(t)) { initial_window_options_t win_opts; memset(&win_opts, 0, sizeof(win_opts)); SET_ICONIFIED(t, 0); Iconify(t, &win_opts); flags->do_redraw_decoration = False; } } if (flags->do_redraw_decoration) { FvwmWindow *tmp; /* frame_redraw_decorations needs to know if the window is * hilighted */ tmp = get_focus_window(); set_focus_window(focus_w); if (IS_ICONIFIED(t)) { DrawIconWindow(t, True, True, False, False, NULL); } else { border_redraw_decorations(t); } set_focus_window(tmp); } if (flags->do_update_frame_attributes) { setup_frame_attributes(t, pstyle); } if (flags->do_update_ewmh_state_hints) { EWMH_SetWMState(t, False); } if (flags->do_update_modules_flags) { BroadcastConfig(M_CONFIGURE_WINDOW,t); } if (flags->do_update_ewmh_mini_icon || flags->do_update_ewmh_icon) { EWMH_DoUpdateWmIcon( t, flags->do_update_ewmh_mini_icon, flags->do_update_ewmh_icon); } if (flags->do_update_placement_penalty) { setup_placement_penalty(t, pstyle); } if (flags->do_update_working_area) { EWMH_UpdateWorkArea(); } if (flags->do_update_ewmh_stacking_hints) { if (DO_EWMH_USE_STACKING_HINTS(t)) { if (t->ewmh_hint_layer > 0 && t->layer != t->ewmh_hint_layer) { t->ewmh_normal_layer = t->layer; new_layer(t, t->ewmh_hint_layer); } } else { if (t->ewmh_hint_layer > 0 && t->ewmh_normal_layer) { if (t->ewmh_normal_layer) { new_layer(t, t->ewmh_normal_layer); } else { new_layer(t, Scr.DefaultLayer); } } } } if (flags->do_update_ewmh_allowed_actions) { EWMH_SetAllowedActions(t); } if (flags->do_broadcast_focus) { if (Scr.Hilite != NULL && t == Scr.Hilite) { BroadcastPacket( M_FOCUS_CHANGE, 5, (long)FW_W(Scr.Hilite), (long)FW_W_FRAME(Scr.Hilite), (long)0, (long)Scr.Hilite->hicolors.fore, (long)Scr.Hilite->hicolors.back); } } if (flags->do_refresh) { if (!IS_ICONIFIED(t)) { refresh_window(FW_W_FRAME(t), False); } } setup_numeric_vals(t, pstyle); if (flags->do_update_cr_motion_method) { switch (SCR_MOTION_METHOD(&pstyle->flags)) { case WS_CR_MOTION_METHOD_AUTO: if (WAS_CR_MOTION_METHOD_DETECTED(t)) { /* method was already detected, keep it */ break; } /* fall through */ case WS_CR_MOTION_METHOD_USE_GRAV: case WS_CR_MOTION_METHOD_STATIC_GRAV: SET_CR_MOTION_METHOD( t, SCR_MOTION_METHOD(&pstyle->flags)); SET_CR_MOTION_METHOD_DETECTED(t, 0); break; } } if (flags->do_update_layer) { int layer = get_layer(t); if (SUSE_LAYER(&pstyle->flags)) { /* use layer from style */ layer = SGET_LAYER(*pstyle); } /* Set the layer, and modify the stack ring. */ new_layer(t, layer); } return; } /* ---------------------------- builtin commands --------------------------- */ /* takes only care of destroying windows that have to go away. */ void destroy_scheduled_windows(void) { flist *t; Bool do_need_ungrab = False; if (Scr.flags.is_executing_complex_function || Scr.flags.is_executing_menu_function || !Scr.flags.is_window_scheduled_for_destroy) { return; } /* Grab the server during the style update! */ if (GrabEm(CRS_WAIT, GRAB_BUSY)) { do_need_ungrab = True; } MyXGrabServer(dpy); Scr.flags.is_window_scheduled_for_destroy = 0; /* need to destroy one or more windows before looking at the window * list */ for (t = Scr.FWScheduledForDestroy; t != NULL; t = t->next) { destroy_window(t->object); } Scr.FWScheduledForDestroy = flist_free_list(Scr.FWScheduledForDestroy); MyXUngrabServer(dpy); if (do_need_ungrab) { UngrabEm(GRAB_BUSY); } return; } /* similar to the flush_window_updates() function, but does only the updates * for a single window whose decor has been changed. */ void apply_decor_change(FvwmWindow *fw) { window_style style; update_win flags; lookup_style(fw, &style); memset(&flags, 0, sizeof(flags)); flags.do_redecorate = True; flags.do_update_window_font_height = True; apply_window_updates(fw, &flags, &style, get_focus_window()); return; } /* Check and apply new style to each window if the style has changed. */ void flush_window_updates(void) { FvwmWindow *t; window_style style; FvwmWindow *focus_fw; Bool do_need_ungrab = False; update_win flags; /* Grab the server during the style update! */ if (GrabEm(CRS_WAIT, GRAB_BUSY)) { do_need_ungrab = True; } MyXGrabServer(dpy); /* This is necessary in case the focus policy changes. With * ClickToFocus some buttons have to be grabbed/ungrabbed. */ focus_fw = get_focus_window(); DeleteFocus(False); /* Apply the new default font and colours first */ if (Scr.flags.has_default_color_changed || Scr.flags.has_default_font_changed) { ApplyDefaultFontAndColors(); } /* update styles for all windows */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { memset(&flags, 0, sizeof(update_win)); check_window_style_change(t, &flags, &style); if (Scr.flags.has_xinerama_state_changed) { flags.do_update_icon_boxes = True; flags.do_update_icon_placement = True; } if (Scr.flags.has_nr_buttons_changed) { flags.do_redecorate = True; } /* TODO: this is not optimised for minimal redrawing yet*/ if (t->decor->flags.has_changed) { flags.do_redecorate = True; flags.do_update_window_font_height = True; } if (Scr.flags.has_default_font_changed && !HAS_ICON_FONT(t)) { flags.do_update_icon_font = True; } if (Scr.flags.has_default_font_changed && !HAS_WINDOW_FONT(t)) { flags.do_update_window_font = True; } if (t->decor->flags.has_title_height_changed) { flags.do_update_window_font_height = True; } if (Scr.flags.has_mouse_binding_changed) { flags.do_update_window_grabs = True; } /* now apply the changes */ apply_window_updates(t, &flags, &style, focus_fw); } /* restore the focus; also handles the case that the previously focused * window is now NeverFocus */ if (focus_fw) { SetFocusWindow(focus_fw, False, FOCUS_SET_FORCE); if (Scr.flags.has_mouse_binding_changed) { focus_grab_buttons(focus_fw); } } else { DeleteFocus(True); } /* finally clean up the change flags */ reset_style_changes(); reset_decor_changes(); Scr.flags.do_need_window_update = 0; Scr.flags.has_default_font_changed = 0; Scr.flags.has_default_color_changed = 0; Scr.flags.has_mouse_binding_changed = 0; Scr.flags.has_nr_buttons_changed = 0; Scr.flags.has_xinerama_state_changed = 0; MyXUngrabServer(dpy); if (do_need_ungrab) { UngrabEm(GRAB_BUSY); } return; } void CMD_UpdateStyles(F_CMD_ARGS) { if (Scr.flags.do_need_window_update) { flush_window_updates(); } return; } fvwm-2.6.7/fvwm/frame.h0000644000175700017570000000451012773467232011703 00000000000000/* -*-c-*- */ #ifndef FRAME_H #define FRAME_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { FRAME_MR_SETUP, FRAME_MR_SETUP_BY_APP, FRAME_MR_OPAQUE, FRAME_MR_SHRINK, FRAME_MR_SCROLL, /* used internally only, do not set these in any calls */ FRAME_MR_FORCE_SETUP, FRAME_MR_FORCE_SETUP_NO_W, /* used by AddWindow() to suppress drawing during window setup */ FRAME_MR_DONT_DRAW = 0x80 } frame_move_resize_mode; typedef struct { rectangle title_g; rectangle button_g[NUMBER_OF_TITLE_BUTTONS]; } frame_title_layout_t; /* details are hidden in frame.c */ typedef void *frame_move_resize_args; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void frame_init(void); Bool is_frame_hide_window( Window w); void frame_destroyed_frame( Window frame_w); frame_move_resize_args frame_create_move_resize_args( FvwmWindow *fw, frame_move_resize_mode mr_mode, rectangle *start_g, rectangle *end_g, int anim_steps, int shade_dir); void frame_update_move_resize_args( frame_move_resize_args mr_args, rectangle *end_g); void frame_free_move_resize_args( FvwmWindow *fw, frame_move_resize_args mr_args); void frame_get_titlebar_dimensions( FvwmWindow *fw, rectangle *frame_g, rectangle *diff_g, frame_title_layout_t *title_layout); void frame_get_sidebar_geometry( FvwmWindow *fw, DecorFaceStyle *borderstyle, rectangle *frame_g, rectangle *ret_g, Bool *ret_has_x_marks, Bool *ret_has_y_marks); int frame_window_id_to_context( FvwmWindow *fw, Window w, int *ret_num); void frame_move_resize( FvwmWindow *fw, frame_move_resize_args mr_args); void frame_setup_window( FvwmWindow *fw, int x, int y, int w, int h, Bool do_send_configure_notify); void frame_setup_window_app_request( FvwmWindow *fw, int x, int y, int w, int h, Bool do_send_configure_notify); void frame_force_setup_window( FvwmWindow *fw, int x, int y, int w, int h, Bool do_send_configure_notify); void frame_setup_shape( FvwmWindow *fw, int w, int h, int shape_mode); #endif /* FRAME_H */ fvwm-2.6.7/fvwm/module_list.h0000644000175700017570000000766313001406607013125 00000000000000/* -*-c-*- */ #ifndef FVWM_MODULE_LIST_H #define FVWM_MODULE_LIST_H #include "libs/Module.h" #include "libs/queue.h" /* for F_CMD_ARGS */ #include "fvwm/fvwm.h" /* please don't use msg_masks_t and PipeMask outside of module_interface.c. * They are only global to allow to access the IS_MESSAGE_SELECTED macro without * having to call a function. */ typedef struct msg_masks_t { unsigned long m1; unsigned long m2; } msg_masks_t; /* module linked list record, only to be accessed by using the access macros * below */ typedef struct fmodule { struct { unsigned is_cmdline_module : 1; } xflags; int xreadPipe; int xwritePipe; fqueue xpipeQueue; msg_masks_t xPipeMask; msg_masks_t xNoGrabMask; msg_masks_t xSyncMask; char *xname; char *xalias; } fmodule; #define MOD_IS_CMDLINE(m) ((m)->xflags.is_cmdline_module) #define MOD_SET_CMDLINE(m,on) ((m)->xflags.is_cmdline_module = !!(on)) typedef struct fmodule_store { fmodule *module; struct fmodule_store *next; } fmodule_store; /* This defines the module list object */ typedef fmodule_store* fmodule_list; /* this objects allows safe iteration over a module list */ typedef fmodule_store* fmodule_list_itr; #define MOD_READFD(m) ((m)->xreadPipe) #define MOD_WRITEFD(m) ((m)->xwritePipe) #define MOD_PIPEQUEUE(m) ((m)->xpipeQueue) #define MOD_PIPEMASK(m) ((m)->xPipeMask) #define MOD_NAME(m) ((m)->xname) #define MOD_ALIAS(m) ((m)->xalias) /* this is a bit long winded to allow MAX_MESSAGE to be 32 and not get an * integer overflow with (1 << MAX_MESSAGES) and even with * (1<<(MAX_MESSAGES-1)) - 1 */ #define DEFAULT_MASK (MAX_MSG_MASK & ~(M_SENDCONFIG)) #define DEFAULT_XMASK (DEFAULT_XMSG_MASK) /* * Returns zero if the msg is not selected by the mask. Takes care of normal * and extended messages. */ #define IS_MESSAGE_IN_MASK(mask, msg) \ (((msg)&M_EXTENDED_MSG) ? ((mask)->m2 & (msg)) : ((mask)->m1 & (msg))) /* * Returns non zero if one of the specified messages is selected for the module */ #define IS_MESSAGE_SELECTED(module, msg_mask) \ IS_MESSAGE_IN_MASK(&(MOD_PIPEMASK(module)), (msg_mask)) /* * M_SENDCONFIG for modules to tell fvwm that they want to see each * module configuration command as it is entered. Causes modconf.c to * look at each active module, find the ones that sent M_SENDCONFIG, and * send a copy of the command in an M_CONFIG_INFO command. */ /* struct to store module input data */ typedef struct fmodule_input { Window window; fmodule *module; char *command; } fmodule_input; /* * Basic Module Handling Functions */ /* kill all modules */ void module_kill_all(void); /* kill a module */ void module_kill(fmodule *module); /* execute module wraper, desperate mode */ fmodule *executeModuleDesperate(F_CMD_ARGS); /* * Basic Module Communication Functions */ /* send "raw" data to the module */ /* module_send(fmodule *module, unsigned long *ptr, int size); */ void PositiveWrite(fmodule *module, unsigned long *ptr, int size); /* returns a dynamicaly allocated struct with the received data * or NULL on error */ fmodule_input *module_receive(fmodule *module); /* frees an input data struct */ void module_input_discard(fmodule_input *input); /* returns true if received the "expect" string, false otherwise */ Bool module_input_expect(fmodule_input *input, char *expect); /* * Utility Functions */ /* initializes the given iterator */ void module_list_itr_init(fmodule_list_itr *itr); /* gets the next module on the list */ fmodule *module_list_itr_next(fmodule_list_itr *itr); /* free modules in the deathrow */ void module_cleanup(void); /* * Message Queue Handling Functions */ /* message queues */ void FlushAllMessageQueues(void); void FlushMessageQueue(fmodule *module); /* * Misc Functions (should they be here?) */ /* * exposed to be used by modconf.c */ char *skipModuleAliasToken(const char *string); /* dead pipe signal handler - empty */ RETSIGTYPE DeadPipe(int nonsense); #endif /* MODULE_LIST_H */ fvwm-2.6.7/fvwm/menuparameters.h0000644000175700017570000000616512773467232013651 00000000000000/* -*-c-*- */ #ifndef MENU_PARAMETERS_H #define MENU_PARAMETERS_H /* ---------------------------- included header files ---------------------- */ /* Do not #include any files - the file including this file has to take care of * it. */ /* ---------------------------- forward declarations ----------------------- */ struct MenuRoot; struct MenuParameters; struct MenuReturn; struct MenuItem; struct FvwmWindow; /* ---------------------------- type definitions --------------------------- */ /* Return values for UpdateMenu, do_menu, menuShortcuts. This is a lame * hack, in that "_BUTTON" is added to mean a button-release caused the * return-- the macros below help deal with the ugliness. */ typedef enum MenuRC { MENU_ERROR = -1, MENU_NOP = 0, MENU_DONE, MENU_ABORTED, MENU_SUBMENU_DONE, MENU_DOUBLE_CLICKED, MENU_POPUP, MENU_POPDOWN, MENU_SELECTED, MENU_NEWITEM, MENU_NEWITEM_MOVEMENU, MENU_NEWITEM_FIND, MENU_POST, MENU_UNPOST, MENU_TEAR_OFF, MENU_SUBMENU_TORN_OFF, MENU_KILL_TEAR_OFF_MENU, MENU_EXEC_CMD, /* propagate the event to a different menu */ MENU_PROPAGATE_EVENT } MenuRC; typedef struct MenuReturn { MenuRC rc; struct MenuRoot *target_menu; struct { unsigned do_unpost_submenu : 1; unsigned is_first_item_selected : 1; unsigned is_key_press : 1; unsigned is_menu_posted : 1; } flags; } MenuReturn; typedef struct MenuPosHints { /* suggested x/y position */ int x; int y; /* additional offset to x */ int x_offset; /* width of the parent menu or item */ int menu_width; /* to take menu width into account (0, -1 or -0.5) */ float x_factor; /* additional offset factor to x */ float context_x_factor; /* same with height */ float y_factor; int screen_origin_x; int screen_origin_y; /* False if referring to absolute screen position */ Bool is_relative; /* True if referring to a part of a menu */ Bool is_menu_relative; Bool has_screen_origin; } MenuPosHints; typedef struct MenuOptions { struct MenuPosHints pos_hints; /* A position on the Xinerama screen on which the menu should be * started. */ struct { unsigned do_not_warp : 1; unsigned do_warp_on_select : 1; unsigned do_warp_title : 1; unsigned do_select_in_place : 1; unsigned do_tear_off_immediately : 1; unsigned has_poshints : 1; unsigned is_fixed : 1; } flags; } MenuOptions; typedef struct MenuParameters { struct MenuRoot *menu; struct MenuRoot *parent_menu; struct MenuItem *parent_item; const exec_context_t **pexc; struct FvwmWindow *tear_off_root_menu_window; char **ret_paction; XEvent *event_propagate_to_submenu; struct MenuOptions *pops; /* A position on the Xinerama screen on which the menu should be * started. */ int screen_origin_x; int screen_origin_y; struct { unsigned has_default_action : 1; unsigned is_already_mapped : 1; unsigned is_first_root_menu : 1; unsigned is_invoked_by_key_press : 1; unsigned is_sticky : 1; unsigned is_submenu : 1; unsigned is_triggered_by_keypress : 1; } flags; } MenuParameters; typedef struct MenuRepaintTransparentParameters { struct MenuRoot *mr; struct FvwmWindow *fw; } MenuRepaintTransparentParameters; #endif /* MENU_PARAMETERS_H */ fvwm-2.6.7/fvwm/menudim.h0000644000175700017570000000406012773467232012247 00000000000000/* -*-c-*- */ #ifndef MENUDIM_H #define MENUDIM_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ #define MDIM_WIDTH(d) ((d).width) #define MDIM_HEIGHT(d) ((d).height) #define MDIM_ITEM_WIDTH(d) ((d).item_width) #define MDIM_SIDEPIC_X_OFFSET(d) ((d).sidepic_x_offset) #define MDIM_ICON_X_OFFSET(d) ((d).icon_x_offset) #define MDIM_TRIANGLE_X_OFFSET(d) ((d).triangle_x_offset) #define MDIM_ITEM_X_OFFSET(d) ((d).item_text_x_offset) #define MDIM_ITEM_TEXT_Y_OFFSET(d) ((d).item_text_y_offset) #define MDIM_HILIGHT_X_OFFSET(d) ((d).hilight_x_offset) #define MDIM_HILIGHT_WIDTH(d) ((d).hilight_width) #define MDIM_SCREEN_WIDTH(d) ((d).screen_width) #define MDIM_SCREEN_HEIGHT(d) ((d).screen_height) /* ---------------------------- type definitions --------------------------- */ struct MenuDimensions { /* width/height of the menu */ int width; int height; /* width of the actual menu item */ int item_width; /* offset of the sidepic */ int sidepic_x_offset; /* offsets of the mini icons */ int icon_x_offset[MAX_MENU_ITEM_MINI_ICONS]; /* offset of the submenu triangle col */ int triangle_x_offset; /* offset of the actual menu item */ int item_text_x_offset; /* y offset for item text. */ int item_text_y_offset; /* start of the area to be hilighted */ int hilight_x_offset; /* width of the area to be hilighted */ int hilight_width; /* y coordinate for item */ int y_offset; /* width and height of the last screen * the menu was mapped on */ int screen_width; int screen_height; }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ int menudim_middle_x_offset(struct MenuDimensions *mdim); /* ---------------------------- builtin commands --------------------------- */ #endif /* MENUDIM_H */ fvwm-2.6.7/fvwm/ewmh.h0000644000175700017570000000476212773467232011562 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ #ifndef _EWMH_ #define _EWMH_ /* Extended window manager hints support */ /* ewmh_conf.c */ Bool EWMH_BugOpts(char *opt, Bool toggle); void CMD_EwmhNumberOfDesktops(F_CMD_ARGS); void CMD_EwmhBaseStrut(F_CMD_ARGS); Bool EWMH_CMD_Style(char *token, window_style *ptmpstyle, int on); /* for maximize and placement ewmh style */ #define EWMH_IGNORE_WORKING_AREA 0 #define EWMH_USE_WORKING_AREA 1 #define EWMH_USE_DYNAMIC_WORKING_AREA 2 #define EWMH_WORKING_AREA_MASK 3 /* Extended window manager hints support */ #include void EWMH_SetCurrentDesktop(void); void EWMH_SetNumberOfDesktops(void); void EWMH_SetDesktopViewPort(void); void EWMH_SetDesktopGeometry(void); void EWMH_SetActiveWindow(Window w); void EWMH_SetWMDesktop(FvwmWindow *fw); void EWMH_SetWMState(FvwmWindow *fw, Bool do_restore); int EWMH_IsKdeSysTrayWindow(Window w); void EWMH_ManageKdeSysTray(Window w, int type); void EWMH_SetClientList(void); void EWMH_SetClientListStacking(void); void EWMH_UpdateWorkArea(void); void EWMH_GetWorkAreaIntersection( FvwmWindow *fw, int *x, int *y, int *w, int *h, int type); float EWMH_GetBaseStrutIntersection( int x11, int y11, int x12, int y12, Bool use_percent); float EWMH_GetStrutIntersection( int x11, int y11, int x12, int y12, Bool use_percent); void EWMH_SetFrameStrut(FvwmWindow *fw); void EWMH_SetAllowedActions(FvwmWindow *fw); void EWMH_GetIconGeometry(FvwmWindow *fw, rectangle *icon_rect); void EWMH_GetStyle(FvwmWindow *fw, window_style *style); void EWMH_WindowInit(FvwmWindow *fw); void EWMH_RestoreInitialStates(FvwmWindow *fw, int event_type); void EWMH_DestroyWindow(FvwmWindow *fw); void EWMH_WindowDestroyed(void); void EWMH_Init(void); void EWMH_ExitStuff(void); /* ewmh_conf.c */ /* ewmh_events.c */ Bool EWMH_ProcessClientMessage(const exec_context_t *exc); void EWMH_ProcessPropertyNotify(const exec_context_t *exc); /* ewmh_icon.c */ void EWMH_DeleteWmIcon(FvwmWindow *fw, Bool mini_icon, Bool icon); int EWMH_SetIconFromWMIcon( FvwmWindow *fw, CARD32 *list, int size, Bool is_mini_icon); void EWMH_DoUpdateWmIcon(FvwmWindow *fw, Bool mini_icon, Bool icon); /* ewmh_name.c */ void EWMH_SetVisibleName(FvwmWindow *fw, Bool is_icon_name); int EWMH_WMName( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); int EWMH_WMIconName( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any); void EWMH_SetDesktopNames(void); void EWMH_fullscreen(FvwmWindow *fw); #endif /* _EWMH_ */ fvwm-2.6.7/fvwm/bindings.h0000644000175700017570000000144412773467232012411 00000000000000/* -*-c-*- */ #ifndef BINDINGS_H #define BINDINGS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void update_key_bindings(void); unsigned int MaskUsedModifiers(unsigned int in_modifiers); unsigned int GetUnusedModifiers(void); void print_bindings(void); #endif /* BINDINGS_H */ fvwm-2.6.7/fvwm/bindings.c0000644000175700017570000004021112773467232012377 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/modifiers.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/defaults.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "bindings.h" #include "module_interface.h" #include "misc.h" #include "screen.h" #include "focus.h" #include "menubindings.h" #include "move_resize.h" /* for placement_binding */ #ifdef HAVE_STROKE #include "stroke.h" #endif /* HAVE_STROKE */ /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static int mods_unused = DEFAULT_MODS_UNUSED; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void update_nr_buttons( int contexts, int *nr_left_buttons, int *nr_right_buttons, Bool do_set) { int i; int l = *nr_left_buttons; int r = *nr_right_buttons; if (contexts == C_ALL) { return; } /* check for nr_left_buttons */ for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i += 2) { if ((contexts & (C_L1 << i))) { if (do_set || *nr_left_buttons <= i / 2) { *nr_left_buttons = i / 2 + 1; } } } /* check for nr_right_buttons */ for (i = 1; i < NUMBER_OF_TITLE_BUTTONS; i += 2) { if ((contexts & (C_L1 << i))) { if (do_set || *nr_right_buttons <= i / 2) { *nr_right_buttons = i / 2 + 1; } } } if (*nr_left_buttons != l || *nr_right_buttons != r) { Scr.flags.do_need_window_update = 1; Scr.flags.has_nr_buttons_changed = 1; } return; } static int activate_binding(Binding *binding, binding_t type, Bool do_grab) { FvwmWindow *t; Bool rc = 0; if (binding == NULL) { return rc; } if (BIND_IS_PKEY_BINDING(type) || binding->Context == C_ALL) { /* necessary for key bindings that work over unfocused windows */ GrabWindowKeyOrButton( dpy, Scr.Root, binding, C_WINDOW | C_DECOR | C_ROOT | C_ICON | C_EWMH_DESKTOP, GetUnusedModifiers(), None, do_grab); if (do_grab == False) { rc = 1; } } if (do_grab == False && BIND_IS_KEY_BINDING(type) && (binding->Context & C_ROOT)) { rc = 1; } if (fFvwmInStartup == True) { return rc; } /* grab keys immediately */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (!IS_EWMH_DESKTOP(FW_W(t)) && (binding->Context & (C_WINDOW | C_DECOR)) && BIND_IS_KEY_BINDING(type)) { GrabWindowKey( dpy, FW_W_FRAME(t), binding, C_WINDOW | C_DECOR, GetUnusedModifiers(), do_grab); } if (binding->Context & C_ICON) { if (FW_W_ICON_TITLE(t) != None) { GrabWindowKeyOrButton( dpy, FW_W_ICON_TITLE(t), binding, C_ICON, GetUnusedModifiers(), None, do_grab); } if (FW_W_ICON_PIXMAP(t) != None) { GrabWindowKeyOrButton( dpy, FW_W_ICON_PIXMAP(t), binding, C_ICON, GetUnusedModifiers(), None, do_grab); } } if (IS_EWMH_DESKTOP(FW_W(t)) && (binding->Context & C_EWMH_DESKTOP)) { GrabWindowKeyOrButton( dpy, FW_W_PARENT(t), binding, C_EWMH_DESKTOP, GetUnusedModifiers(), None, do_grab); } } return rc; } static int bind_get_bound_button_contexts( Binding **pblist, unsigned short *buttons_grabbed) { int bcontext = 0; Binding *b; if (buttons_grabbed) { *buttons_grabbed = 0; } for (b = *pblist; b != NULL; b = b->NextBinding) { if (!BIND_IS_MOUSE_BINDING(b->type) && !BIND_IS_STROKE_BINDING(b->type)) { continue; } if ((b->Context & (C_WINDOW | C_EWMH_DESKTOP)) && !(BIND_IS_STROKE_BINDING(b->type) && b->Button_Key == 0) && buttons_grabbed != NULL) { if (b->Button_Key == 0) { *buttons_grabbed |= ((1 << NUMBER_OF_EXTENDED_MOUSE_BUTTONS) - 1); } else { *buttons_grabbed |= (1 << (b->Button_Key - 1)); } } if (b->Context != C_ALL && (b->Context & (C_LALL | C_RALL))) { bcontext |= b->Context; } } return bcontext; } static void __rebind_global_key(Binding **pblist, int Button_Key) { Binding *b; for (b = *pblist; b != NULL; b = b->NextBinding) { if (b->Button_Key == Button_Key && (BIND_IS_PKEY_BINDING(b->type) || b->Context == C_ALL)) { activate_binding(b, b->type, True); return; } } return; } /* Parses a mouse or key binding */ static int ParseBinding( Display *dpy, Binding **pblist, char *tline, binding_t type, int *nr_left_buttons, int *nr_right_buttons, unsigned short *buttons_grabbed, Bool is_silent) { char *action; char context_string[20]; char modifier_string[20]; char *ptr; char *token; char key_string[201] = ""; char buffer[80]; char *window_name = NULL; char *p; int button = 0; int n1 = 0; int n2 = 0; int n3 = 0; int context; int modifier; int rc; KeySym keysym = NoSymbol; Bool is_unbind_request = False; Bool is_pass_through = False; Bool are_similar_bindings_left; Binding *b; Binding *rmlist = NULL; STROKE_CODE(char stroke[STROKE_MAX_SEQUENCE + 1] = ""); STROKE_CODE(int n4 = 0); STROKE_CODE(int i); /* tline points after the key word "Mouse" or "Key" */ token = p = PeekToken(tline, &ptr); /* check to see if a window name has been specified. */ if (p == NULL) { fvwm_msg( ERR, "ParseBinding", "empty %s binding, ignored\n", tline); return 0; } if (*p == '(') { /* A window name has been specified for the binding. */ sscanf(p + 1, "%79s", buffer); p = buffer; while (*p != ')') { if (*p == '\0') { if (!is_silent) { fvwm_msg( ERR, "ParseBinding", "Syntax error in line %s -" " missing ')'", tline); } return 0; } ++p; } *p++ = '\0'; window_name = buffer; if (*p != '\0') { if (!is_silent) { fvwm_msg( ERR, "ParseBinding", "Syntax error in line %s - trailing" " text after specified window", tline); } return 0; } token = PeekToken(ptr, &ptr); } if (token != NULL) { if (BIND_IS_KEY_BINDING(type)) { /* see len of key_string above */ n1 = sscanf(token,"%200s", key_string); } #ifdef HAVE_STROKE else if (BIND_IS_STROKE_BINDING(type)) { int num = 0; int j; n1 = 1; i = 0; if (token[0] == 'N' && token[1] != '\0') { num = 1; } j=i+num; while (n1 && token[j] != '\0' && i < STROKE_MAX_SEQUENCE) { if (!isdigit(token[j])) { n1 = 0; } if (num) { /* Numeric pad to Telephone */ if ('7' <= token[j] && token[j] <= '9') { token[j] -= 6; } else if ('1' <= token[j] && token[j] <= '3') { token[j] += 6; } } stroke[i] = token[j]; i++; j=i+num; } stroke[i] = '\0'; if (strlen(token) > STROKE_MAX_SEQUENCE + num) { if (!is_silent) { fvwm_msg( WARN, "ParseBinding", "Too long stroke sequence in" " line %s. Only %i elements" " will be taken into" " account.\n", tline, STROKE_MAX_SEQUENCE); } } } #endif /* HAVE_STROKE */ else { n1 = sscanf(token, "%d", &button); if (button < 0) { if (!is_silent) { fvwm_msg( ERR, "ParseBinding", "Illegal mouse button in line" " %s", tline); } return 0; } if (button > NUMBER_OF_MOUSE_BUTTONS) { if (!is_silent) { fvwm_msg( WARN, "ParseBinding", "Got mouse button %d when the" " maximum is %d.\n You can't" " bind complex functions to" " this button. To suppress" " this warning, use:\n" " Silent Mouse %s", button, NUMBER_OF_MOUSE_BUTTONS, tline); } } } } #ifdef HAVE_STROKE if (BIND_IS_STROKE_BINDING(type)) { token = PeekToken(ptr, &ptr); if (token != NULL) { n4 = sscanf(token,"%d", &button); } } #endif /* HAVE_STROKE */ token = PeekToken(ptr, &ptr); if (token != NULL) { n2 = sscanf(token, "%19s", context_string); } token = PeekToken(ptr, &action); if (token != NULL) { n3 = sscanf(token, "%19s", modifier_string); } if (n1 != 1 || n2 != 1 || n3 != 1 STROKE_CODE(|| (BIND_IS_STROKE_BINDING(type) && n4 != 1))) { if (!is_silent) { fvwm_msg( ERR, "ParseBinding", "Syntax error in line %s", tline); } return 0; } if (wcontext_string_to_wcontext( context_string, &context) && !is_silent) { fvwm_msg( WARN, "ParseBinding", "Illegal context in line %s", tline); } if (modifiers_string_to_modmask(modifier_string, &modifier) && !is_silent) { fvwm_msg( WARN, "ParseBinding", "Illegal modifier in line %s", tline); } if (BIND_IS_KEY_BINDING(type)) { keysym = FvwmStringToKeysym(dpy, key_string); /* Don't let a 0 keycode go through, since that means AnyKey * to the XGrabKey call. */ if (keysym == 0) { if (!is_silent) { fvwm_msg( ERR, "ParseBinding", "No such key: %s", key_string); } return 0; } } if (action != NULL) { action = SkipSpaces(action, NULL, 0); } if ( action == NULL || *action == 0 || (action[0] == '-' && !is_pass_through)) { is_unbind_request = True; } else { is_pass_through = is_pass_through_action(action); if (is_pass_through) { /* pass-through actions indicate that the event be * allowed to pass through to the underlying window. */ if (window_name == NULL) { /* It doesn't make sense to have a pass-through * action on global bindings. */ if (!is_silent) { fvwm_msg( ERR, "ParseBinding", "Invalid action for global " "binding: %s", tline); } return 0; } } } /* short circuit menu bindings for now. */ if ((context & C_MENU) == C_MENU) { menu_binding( dpy, type, button, keysym, context, modifier, action, window_name); /* ParseBinding returns the number of new bindings in pblist * menu bindings does not add to pblist, and should return 0 */ return 0; } /* short circuit placement bindings for now. */ if ((context & C_PLACEMENT) == C_PLACEMENT) { placement_binding(button,keysym,modifier,action); /* ParseBinding returns the number of new bindings in pblist * placement bindings does not add to pblist, and should * return 0 */ return 0; } /* ** Remove the "old" bindings if any */ /* BEGIN remove */ CollectBindingList( dpy, pblist, &rmlist, &are_similar_bindings_left, type, STROKE_ARG((void *)stroke) button, keysym, modifier, context, window_name); if (rmlist != NULL) { int bcontext; if (is_unbind_request && are_similar_bindings_left == False) { int rc = 0; for (b = rmlist; b != NULL; b = b->NextBinding) { /* release the grab */ rc |= activate_binding(b, type, False); } if (rc) { __rebind_global_key( pblist, rmlist->Button_Key); } } FreeBindingList(rmlist); bcontext = bind_get_bound_button_contexts( pblist, buttons_grabbed); update_nr_buttons( bcontext, nr_left_buttons, nr_right_buttons, True); } /* return if it is an unbind request */ if (is_unbind_request) { return 0; } /* END remove */ update_nr_buttons(context, nr_left_buttons, nr_right_buttons, False); if ((modifier & AnyModifier)&&(modifier&(~AnyModifier))) { fvwm_msg( WARN, "ParseBinding", "Binding specified AnyModifier" " and other modifers too. Excess modifiers are" " ignored."); modifier = AnyModifier; } if ( (BIND_IS_MOUSE_BINDING(type) || (BIND_IS_STROKE_BINDING(type) && button != 0)) && (context & (C_WINDOW | C_EWMH_DESKTOP)) && buttons_grabbed != NULL) { if (button == 0) { *buttons_grabbed |= ((1 << NUMBER_OF_EXTENDED_MOUSE_BUTTONS) - 1); } else { *buttons_grabbed |= (1 << (button - 1)); } } rc = AddBinding( dpy, pblist, type, STROKE_ARG((void *)stroke) button, keysym, key_string, modifier, context, (void *)action, NULL, window_name); return rc; } static void binding_cmd(F_CMD_ARGS, binding_t type) { Binding *b; int count; unsigned short btg = Scr.buttons2grab; count = ParseBinding( dpy, &Scr.AllBindings, action, type, &Scr.nr_left_buttons, &Scr.nr_right_buttons, &btg, Scr.flags.are_functions_silent); if (btg != Scr.buttons2grab) { Scr.flags.do_need_window_update = 1; Scr.flags.has_mouse_binding_changed = 1; Scr.buttons2grab = btg; } for ( b = Scr.AllBindings; count > 0 && b != NULL; count--, b = b->NextBinding) { activate_binding(b, type, True); } return; } void print_bindings(void) { Binding *b; fprintf(stderr, "Current list of bindings:\n\n"); for (b = Scr.AllBindings; b != NULL; b = b->NextBinding) { switch (b->type) { case BIND_KEYPRESS: fprintf(stderr, "Key"); break; case BIND_PKEYPRESS: fprintf(stderr, "PointerKey"); break; case BIND_BUTTONPRESS: case BIND_BUTTONRELEASE: fprintf(stderr, "Mouse"); break; case BIND_STROKE: fprintf(stderr, "Stroke"); break; default: fvwm_msg( ERR, "print_bindings", "invalid binding type %d", b->type); continue; } if (b->windowName != NULL) { fprintf(stderr, " (%s)", b->windowName); } switch (b->type) { case BIND_KEYPRESS: case BIND_PKEYPRESS: fprintf(stderr, "\t%s", b->key_name); break; case BIND_BUTTONPRESS: case BIND_BUTTONRELEASE: fprintf(stderr, "\t%d", b->Button_Key); break; case BIND_STROKE: STROKE_CODE( fprintf( stderr, "\t%s\t%d", (char *)b->Stroke_Seq, b->Button_Key)); break; } { char *mod_string; char *context_string; mod_string = charmap_table_to_string( MaskUsedModifiers(b->Modifier),key_modifiers); context_string = charmap_table_to_string( b->Context, win_contexts); fprintf( stderr, "\t%s\t%s\t%s\n", context_string, mod_string, (char *)b->Action); free(mod_string); free(context_string); } } return; } /* ---------------------------- interface functions ------------------------ */ /* Removes all unused modifiers from in_modifiers */ unsigned int MaskUsedModifiers(unsigned int in_modifiers) { return in_modifiers & ~mods_unused; } unsigned int GetUnusedModifiers(void) { return mods_unused; } /* ---------------------------- builtin commands --------------------------- */ void CMD_Key(F_CMD_ARGS) { binding_cmd(F_PASS_ARGS, BIND_KEYPRESS); return; } void CMD_PointerKey(F_CMD_ARGS) { binding_cmd(F_PASS_ARGS, BIND_PKEYPRESS); return; } void CMD_Mouse(F_CMD_ARGS) { binding_cmd(F_PASS_ARGS, BIND_BUTTONPRESS); return; } #ifdef HAVE_STROKE void CMD_Stroke(F_CMD_ARGS) { binding_cmd(F_PASS_ARGS, BIND_STROKE); return; } #endif /* HAVE_STROKE */ /* Declares which X modifiers are actually locks and should be ignored when * testing mouse/key binding modifiers. */ void CMD_IgnoreModifiers(F_CMD_ARGS) { char *token; int mods_unused_old = mods_unused; token = PeekToken(action, &action); if (!token) { mods_unused = 0; } else if (StrEquals(token, "default")) { mods_unused = DEFAULT_MODS_UNUSED; } else if (modifiers_string_to_modmask(token, &mods_unused)) { fvwm_msg( ERR, "ignore_modifiers", "illegal modifier in line %s\n", action); } if (mods_unused != mods_unused_old) { /* broadcast config to modules */ broadcast_ignore_modifiers(); } return; } fvwm-2.6.7/fvwm/menubindings.h0000644000175700017570000000525412773467232013301 00000000000000/* -*-c-*- */ #ifndef MENU_BINDINGS_H #define MENU_BINDINGS_H /* ---------------------------- included header files ---------------------- */ /* Do not #include any files - the file including this file has to take care of * it. */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- forward declarations ----------------------- */ struct MenuRoot; struct MenuParameters; struct MenuReturn; struct MenuItem; /* ---------------------------- type definitions --------------------------- */ typedef struct { unsigned int keystate; unsigned int keycode; Time timestamp; } double_keypress; typedef enum { SA_NONE = 0, SA_ENTER, SA_LEAVE, SA_MOVE_ITEMS, SA_FIRST, SA_LAST, SA_CONTINUE, SA_WARPBACK, SA_SELECT, SA_TEAROFF, SA_ABORT, SA_SCROLL, SA_EXEC_CMD } menu_shortcut_action; /* ---------------------------- exported variables (globals) --------------- */ /* Do not use global variable. Full stop. */ /* ---------------------------- interface functions ------------------------ */ /* Before this function is called, all menu bindings created through * menu_binding() are permanent i.e. they can not be deleted (although * overridden). After calling it, new bindings are stored in the regular list * and can be deleted by the user as usual. * * To be called by SetRCDefaults *only*. */ void menu_bindings_startup_complete(void); /* Parse a menu binding and store it. * * To be called from bindings.c *only*. */ int menu_binding( Display *dpy, binding_t type, int button, KeySym keysym, int context, int modifier, char *action, char *menu_style); /* Checks if the given mouse or keyboard event in the given context * corresponds to a menu binding. If so, the binding is returned. Otherwise * NULL is returned. * * To be called from menus.c *only*. */ Binding *menu_binding_is_mouse(XEvent* event, int context); Binding *menu_binding_is_key(XEvent* event, int context); /* Menu keyboard processing * * Function called instead of Keyboard_Shortcuts() * when a KeyPress event is received. If the key is alphanumeric, * then the menu is scanned for a matching hot key. Otherwise if * it was the escape key then the menu processing is aborted. * If none of these conditions are true, then the default processing * routine is called. * TKP - uses XLookupString so that keypad numbers work with windowlist */ void menu_shortcuts( struct MenuRoot *mr, struct MenuParameters *pmp, struct MenuReturn *pmret, XEvent *event, struct MenuItem **pmi_current, double_keypress *pdkp, int *ret_menu_x, int *ret_menu_y); #endif /* MENU_BINDINGS_H */ fvwm-2.6.7/fvwm/focus_policy.h0000644000175700017570000001652312773467232013316 00000000000000/* -*-c-*- */ #ifndef FOCUS_POLICY_H #define FOCUS_POLICY_H /* Note: focus_policy.[ch] is meant to manage structures of type focus_policy_t * only. No code dealing with *any* external data types belongs in here! Put * it in focus.[ch] instead. */ /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define FPOL_ANY_MODIFIER 0xff /* ---------------------------- access macros ------------------------------ */ #define FP_DO_RAISE_FOCUSED_CLICK(fp) \ ((fp).do_raise_focused_click) #define FP_DO_RAISE_UNFOCUSED_CLICK(fp) \ ((fp).do_raise_unfocused_click) #define FP_DO_FOCUS_CLICK(fp) \ ((fp).do_focus_click) #define FP_DO_RAISE_FOCUSED_CLIENT_CLICK(fp) \ ((fp).do_raise_focused_click.client) #define FPS_RAISE_FOCUSED_CLIENT_CLICK(fp,x) \ ((fp).do_raise_focused_click.client = !!(x)) #define FP_DO_RAISE_UNFOCUSED_CLIENT_CLICK(fp) \ ((fp).do_raise_unfocused_click.client) #define FPS_RAISE_UNFOCUSED_CLIENT_CLICK(fp,x) \ ((fp).do_raise_unfocused_click.client = !!(x)) #define FP_DO_RAISE_FOCUSED_DECOR_CLICK(fp) \ ((fp).do_raise_focused_click.decor) #define FPS_RAISE_FOCUSED_DECOR_CLICK(fp,x) \ ((fp).do_raise_focused_click.decor = !!(x)) #define FP_DO_RAISE_UNFOCUSED_DECOR_CLICK(fp) \ ((fp).do_raise_unfocused_click.decor) #define FPS_RAISE_UNFOCUSED_DECOR_CLICK(fp,x) \ ((fp).do_raise_unfocused_click.decor = !!(x)) #define FP_DO_RAISE_FOCUSED_ICON_CLICK(fp) \ ((fp).do_raise_focused_click.icon) #define FPS_RAISE_FOCUSED_ICON_CLICK(fp,x) \ ((fp).do_raise_focused_click.icon = !!(x)) #define FP_DO_RAISE_UNFOCUSED_ICON_CLICK(fp) \ ((fp).do_raise_unfocused_click.icon) #define FPS_RAISE_UNFOCUSED_ICON_CLICK(fp,x) \ ((fp).do_raise_unfocused_click.icon = !!(x)) #define FP_DO_FOCUS_ENTER(fp) \ ((fp).do_focus_enter) #define FPS_FOCUS_ENTER(fp,x) \ ((fp).do_focus_enter = !!(x)) #define FP_DO_UNFOCUS_LEAVE(fp) \ ((fp).do_unfocus_leave) #define FPS_UNFOCUS_LEAVE(fp,x) \ ((fp).do_unfocus_leave = !!(x)) #define FP_DO_FOCUS_CLICK_CLIENT(fp) \ ((fp).do_focus_click.client) #define FPS_FOCUS_CLICK_CLIENT(fp,x) \ ((fp).do_focus_click.client = !!(x)) #define FP_DO_FOCUS_CLICK_DECOR(fp) \ ((fp).do_focus_click.decor) #define FPS_FOCUS_CLICK_DECOR(fp,x) \ ((fp).do_focus_click.decor = !!(x)) #define FP_DO_FOCUS_CLICK_ICON(fp) \ ((fp).do_focus_click.icon) #define FPS_FOCUS_CLICK_ICON(fp,x) \ ((fp).do_focus_click.icon = !!(x)) #define FP_DO_FOCUS_BY_PROGRAM(fp) \ ((fp).do_focus_by_program) #define FPS_FOCUS_BY_PROGRAM(fp,x) \ ((fp).do_focus_by_program = !!(x)) #define FP_DO_FOCUS_BY_FUNCTION(fp) \ ((fp).do_focus_by_function) #define FPS_FOCUS_BY_FUNCTION(fp,x) \ ((fp).do_focus_by_function = !!(x)) #define FP_DO_WARP_POINTER_ON_FOCUS_FUNC(fp) \ ((fp).do_warp_pointer_on_focus_func) #define FPS_WARP_POINTER_ON_FOCUS_FUNC(fp,x) \ ((fp).do_warp_pointer_on_focus_func = !!(x)) #define FP_IS_LENIENT(fp) \ ((fp).is_lenient) #define FPS_LENIENT(fp,x) \ ((fp).is_lenient = !!(x)) #define FP_USE_MOUSE_BUTTONS(fp) \ ((fp).use_mouse_buttons) #define FPS_MOUSE_BUTTONS(fp,x) \ ((fp).use_mouse_buttons = (x)) #define FP_USE_MODIFIERS(fp) \ ((fp).use_modifiers) #define FPS_MODIFIERS(fp,x) \ ((fp).use_modifiers = (x)) #define FP_DO_PASS_FOCUS_CLICK(fp) \ ((fp).do_pass_focus_click) #define FPS_PASS_FOCUS_CLICK(fp,x) \ ((fp).do_pass_focus_click = !!(x)) #define FP_DO_PASS_RAISE_CLICK(fp) \ ((fp).do_pass_raise_click) #define FPS_PASS_RAISE_CLICK(fp,x) \ ((fp).do_pass_raise_click = !!(x)) #define FP_DO_IGNORE_FOCUS_CLICK_MOTION(fp) \ ((fp).do_ignore_focus_click_motion) #define FPS_IGNORE_FOCUS_CLICK_MOTION(fp,x) \ ((fp).do_ignore_focus_click_motion = !!(x)) #define FP_DO_IGNORE_RAISE_CLICK_MOTION(fp) \ ((fp).do_ignore_raise_click_motion) #define FPS_IGNORE_RAISE_CLICK_MOTION(fp,x) \ ((fp).do_ignore_raise_click_motion = !!(x)) #define FP_DO_ALLOW_FUNC_FOCUS_CLICK(fp) \ ((fp).do_allow_func_focus_click) #define FPS_ALLOW_FUNC_FOCUS_CLICK(fp,x) \ ((fp).do_allow_func_focus_click = !!(x)) #define FP_DO_ALLOW_FUNC_RAISE_CLICK(fp) \ ((fp).do_allow_func_raise_click) #define FPS_ALLOW_FUNC_RAISE_CLICK(fp,x) \ ((fp).do_allow_func_raise_click = !!(x)) #define FP_DO_GRAB_FOCUS(fp) \ ((fp).do_open_grabs_focus) #define FPS_GRAB_FOCUS(fp,x) \ ((fp).do_open_grabs_focus = !!(x)) #define FP_DO_GRAB_FOCUS_TRANSIENT(fp) \ ((fp).do_open_grabs_focus_transient) #define FPS_GRAB_FOCUS_TRANSIENT(fp,x) \ ((fp).do_open_grabs_focus_transient = !!(x)) #define FP_DO_OVERRIDE_GRAB_FOCUS(fp) \ ((fp).do_override_grab_focus) #define FPS_OVERRIDE_GRAB_FOCUS(fp,x) \ ((fp).do_override_grab_focus = !!(x)) #define FP_DO_RELEASE_FOCUS(fp) \ ((fp).do_close_releases_focus) #define FPS_RELEASE_FOCUS(fp,x) \ ((fp).do_close_releases_focus = !!(x)) #define FP_DO_RELEASE_FOCUS_TRANSIENT(fp) \ ((fp).do_close_releases_focus_transient) #define FPS_RELEASE_FOCUS_TRANSIENT(fp,x) \ ((fp).do_close_releases_focus_transient = !!(x)) #define FP_DO_OVERRIDE_RELEASE_FOCUS(fp) \ ((fp).do_override_release_focus) #define FPS_OVERRIDE_RELEASE_FOCUS(fp,x) \ ((fp).do_override_release_focus = !!(x)) #define FP_DO_SORT_WINDOWLIST_BY(fp) \ ((fp).do_sort_windowlist_by) #define FPS_SORT_WINDOWLIST_BY(fp,x) \ ((fp).do_sort_windowlist_by = !!(x)) /* ---------------------------- type definitions --------------------------- */ typedef enum { FPOL_SORT_WL_BY_FOCUS = 0, FPOL_SORT_WL_BY_OPEN = 1 } fpol_sort_windowlist_t; typedef enum { FOCUS_SET_BY_CLICK_CLIENT, FOCUS_SET_BY_CLICK_DECOR, FOCUS_SET_BY_CLICK_ICON, FOCUS_SET_BY_ENTER, FOCUS_SET_BY_PROGRAM, FOCUS_SET_BY_FUNCTION, /* used internally to restore the focus after certain actions */ FOCUS_SET_FORCE } fpol_set_focus_by_t; typedef struct { unsigned client : 1; unsigned decor : 1; unsigned icon : 1; } fpol_context_t; typedef struct { /* raising the window */ fpol_context_t do_raise_focused_click; fpol_context_t do_raise_unfocused_click; /* focus transition */ fpol_context_t do_focus_click; unsigned do_focus_enter : 1; unsigned do_unfocus_leave : 1; unsigned do_focus_by_program : 1; unsigned do_focus_by_function : 1; unsigned do_warp_pointer_on_focus_func : 1; /* application focus model */ unsigned is_lenient : 1; /* click configuration */ unsigned use_mouse_buttons : NUMBER_OF_EXTENDED_MOUSE_BUTTONS; unsigned use_modifiers : 8; /* recycling of focus and raise clicks */ unsigned do_pass_focus_click : 1; unsigned do_pass_raise_click : 1; unsigned do_ignore_focus_click_motion : 1; unsigned do_ignore_raise_click_motion : 1; unsigned do_allow_func_focus_click : 1; unsigned do_allow_func_raise_click : 1; /* keeping track of the focus */ unsigned do_open_grabs_focus : 1; unsigned do_open_grabs_focus_transient : 1; unsigned do_override_grab_focus : 1; unsigned do_close_releases_focus : 1; unsigned do_close_releases_focus_transient : 1; unsigned do_override_release_focus : 1; unsigned do_sort_windowlist_by : 1; } focus_policy_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void fpol_init_default_fp( focus_policy_t *fp); int fpol_query_allow_set_focus( focus_policy_t *fpol, fpol_set_focus_by_t set_by_mode); int fpol_query_allow_user_focus( focus_policy_t *fpol); int fpol_is_policy_changed( focus_policy_t *fpol); #endif /* FOCUS_POLICY_H */ fvwm-2.6.7/fvwm/add_window.c0000644000175700017570000025541613003342500012711 00000000000000/* -*-c-*- */ /* 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 */ /* This module is based on Twm, but has been siginificantly modified * by Rob Nation */ /* * Copyright 1988 by Evans & Sutherland Computer Corporation, * Salt Lake City, Utah * Portions Copyright 1989 by the Massachusetts Institute of Technology * Cambridge, 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 permis- * sion notice appear in supporting documentation, and that the * names of Evans & Sutherland and M.I.T. not be used in advertising * in publicity pertaining to distribution of the software without * specific, written prior permission. * * EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- * ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR * M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- * AGES 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. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/FScreen.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/Grab.h" #include "libs/Strings.h" #include "libs/XResource.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "execcontext.h" #include "commands.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "add_window.h" #include "events.h" #include "eventhandler.h" #include "eventmask.h" #include "module_interface.h" #include "stack.h" #include "update.h" #include "style.h" #include "icons.h" #include "ewmh.h" #include "focus.h" #include "placement.h" #include "geometry.h" #include "session.h" #include "move_resize.h" #include "borders.h" #include "frame.h" #include "colormaps.h" #include "decorations.h" #include "functions.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ char NoName[] = "Untitled"; /* name if no name in XA_WM_NAME */ char NoClass[] = "NoClass"; /* Class if no res_class in class hints */ char NoResource[] = "NoResource"; /* Class if no res_name in class hints */ /* ---------------------------- local functions ---------------------------- */ static void delete_client_context(FvwmWindow *fw) { FvwmWindow *cw; /* We can not simply delete the context. X might have reused the * window structure so we would delete the context that was established * by another FvwmWindow structure in the mean time. */ if (XFindContext( dpy, FW_W(fw), FvwmContext, (caddr_t *)&cw) != XCNOENT && cw == fw) { XDeleteContext(dpy, FW_W(fw), FvwmContext); } return; } /* * * Procedure: * CaptureOneWindow * CaptureAllWindows * * Decorates windows at start-up and during recaptures * */ static void CaptureOneWindow( const exec_context_t *exc, FvwmWindow *fw, Window window, Window keep_on_top_win, Window parent_win, Bool is_recapture) { Window w; unsigned long data[1]; initial_window_options_t win_opts; evh_args_t ea; exec_context_changes_t ecc; XEvent e; if (fw == NULL) { return; } if (IS_SCHEDULED_FOR_DESTROY(fw)) { /* Fvwm might crash in complex functions if we really try to * the dying window here because AddWindow() may fail and leave * a destroyed window in some structures. By the way, it is * pretty useless to recapture a window that will vanish in a * moment. */ return; } /* Grab the server to make sure the window does not die during the * recapture. */ MyXGrabServer(dpy); if ( !XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { /* The window has already died, do not recapture it! */ MyXUngrabServer(dpy); return; } if (XFindContext(dpy, window, FvwmContext, (caddr_t *)&fw) != XCNOENT) { Bool is_mapped = IS_MAPPED(fw); memset(&win_opts, 0, sizeof(win_opts)); win_opts.initial_state = DontCareState; win_opts.flags.do_override_ppos = 1; win_opts.flags.is_recapture = 1; if (IS_ICONIFIED(fw)) { win_opts.initial_state = IconicState; win_opts.flags.is_iconified_by_parent = IS_ICONIFIED_BY_PARENT(fw); } else { win_opts.initial_state = NormalState; win_opts.flags.is_iconified_by_parent = 0; if (Scr.CurrentDesk != fw->Desk) { SetMapStateProp(fw, NormalState); } } data[0] = (unsigned long) fw->Desk; XChangeProperty( dpy, FW_W(fw), _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32, PropModeReplace, (unsigned char *) data, 1); XSelectInput(dpy, FW_W(fw), NoEventMask); w = FW_W(fw); XUnmapWindow(dpy, FW_W_FRAME(fw)); border_undraw_decorations(fw); RestoreWithdrawnLocation(fw, is_recapture, parent_win); SET_DO_REUSE_DESTROYED(fw, 1); /* RBW - 1999/03/20 */ destroy_window(fw); win_opts.flags.is_menu = (is_recapture && fw != NULL && IS_TEAR_OFF_MENU(fw)); fev_make_null_event(&e, dpy); e.xmaprequest.window = w; e.xmaprequest.parent = Scr.Root; ecc.x.etrigger = &e; ecc.w.fw = NULL; ecc.w.w = w; ecc.w.wcontext = C_ROOT; ea.exc = exc_clone_context( exc, &ecc, ECC_ETRIGGER | ECC_FW | ECC_W | ECC_WCONTEXT); HandleMapRequestKeepRaised(&ea, keep_on_top_win, fw, &win_opts); exc_destroy_context(ea.exc); /* HandleMapRequestKeepRaised may have destroyed the fw if the * window vanished while in AddWindow(), so don't access fw * anymore before checking if it is a valid window. */ if (check_if_fvwm_window_exists(fw)) { if (!fFvwmInStartup) { SET_MAP_PENDING(fw, 0); SET_MAPPED(fw, is_mapped); } } } MyXUngrabServer(dpy); return; } /* Put a transparent window all over the screen to hide what happens below. */ static void hide_screen( Bool do_hide, Window *ret_hide_win, Window *ret_parent_win) { static Bool is_hidden = False; static Window hide_win = None; static Window parent_win = None; XSetWindowAttributes xswa; unsigned long valuemask; if (do_hide == is_hidden) { /* nothing to do */ if (ret_hide_win) { *ret_hide_win = hide_win; } if (ret_parent_win) { *ret_parent_win = parent_win; } return; } is_hidden = do_hide; if (do_hide) { xswa.override_redirect = True; xswa.cursor = Scr.FvwmCursors[CRS_WAIT]; xswa.backing_store = NotUseful; xswa.save_under = False; xswa.background_pixmap = None; valuemask = CWOverrideRedirect | CWCursor | CWSaveUnder | CWBackingStore | CWBackPixmap; hide_win = XCreateWindow( dpy, Scr.Root, 0, 0, Scr.MyDisplayWidth, Scr.MyDisplayHeight, 0, Pdepth, InputOutput, Pvisual, valuemask, &xswa); if (hide_win) { /* When recapturing, all windows are reparented to this * window. If they are reparented to the root window, * they will flash over the hide_win with XFree. So * reparent them to an unmapped window that looks like * the root window. */ parent_win = XCreateWindow( dpy, Scr.Root, 0, 0, Scr.MyDisplayWidth, Scr.MyDisplayHeight, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &xswa); if (!parent_win) { XDestroyWindow(dpy, hide_win); hide_win = None; } else { XMapWindow(dpy, hide_win); XFlush(dpy); } } } else { if (hide_win != None) { XDestroyWindow(dpy, hide_win); } if (parent_win != None) { XDestroyWindow(dpy, parent_win); } XFlush(dpy); hide_win = None; parent_win = None; } if (ret_hide_win) { *ret_hide_win = hide_win; } if (ret_parent_win) { *ret_parent_win = parent_win; } return; } /* * * Procedure: * MappedNotOverride - checks to see if we should really * put a fvwm frame on the window * * Returned Value: * 1 - go ahead and frame the window * 0 - don't frame the window * * Inputs: * w - the window to check * */ static int MappedNotOverride( Window w, initial_window_options_t *win_opts) { XWindowAttributes wa; Atom atype; int aformat; unsigned long nitems, bytes_remain; unsigned char *prop; win_opts->initial_state = DontCareState; if ((w==Scr.NoFocusWin)||(!XGetWindowAttributes(dpy, w, &wa))) { return 0; } if (XGetWindowProperty( dpy,w,_XA_WM_STATE,0L,3L,False,_XA_WM_STATE, &atype,&aformat,&nitems,&bytes_remain,&prop)==Success) { if (prop != NULL) { win_opts->initial_state = *(long *)prop; XFree(prop); } } if (wa.override_redirect == True) { XSelectInput(dpy, w, XEVMASK_ORW); XFlush(dpy); } return (((win_opts->initial_state == IconicState) || (wa.map_state != IsUnmapped)) && (wa.override_redirect != True)); } static void do_recapture(F_CMD_ARGS, Bool fSingle) { FvwmWindow *fw = exc->w.fw; int event_types[5] = { ButtonPress, ButtonRelease, MotionNotify, KeyPress, KeyRelease }; MyXGrabServer(dpy); if (fSingle) { CaptureOneWindow( exc, fw, FW_W(fw), None, None, True); } else { CaptureAllWindows(exc, True); } /* Throw away queued up events. We don't want user input during a * recapture. The window the user clicks in might disapper at the very * same moment and the click goes through to the root window. Not good */ XAllowEvents(dpy, AsyncPointer, CurrentTime); discard_typed_events(5, event_types); #ifdef DEBUG_STACK_RING verify_stack_ring_consistency(); #endif MyXUngrabServer(dpy); return; } static void setup_window_structure( FvwmWindow **pfw, Window w, FvwmWindow *ReuseWin) { FvwmWindow save_state; FvwmWindow *savewin = NULL; /* Allocate space for the FvwmWindow struct, or reuse an old one (on Recapture). */ if (ReuseWin == NULL) { *pfw = (FvwmWindow *)safemalloc(sizeof(FvwmWindow)); } else { *pfw = ReuseWin; savewin = &save_state; memcpy(savewin, ReuseWin, sizeof(FvwmWindow)); } /* RBW - 1999/05/28 - modify this when we implement the preserving of various states across a Recapture. The Destroy function in misc.c may also need tweaking, depending on what you want to preserve. For now, just zap any old information, except the desk. */ memset(*pfw, '\0', sizeof(FvwmWindow)); FW_W(*pfw) = w; if (savewin != NULL) { (*pfw)->Desk = savewin->Desk; SET_SHADED(*pfw, IS_SHADED(savewin)); SET_USED_TITLE_DIR_FOR_SHADING( *pfw, USED_TITLE_DIR_FOR_SHADING(savewin)); SET_SHADED_DIR(*pfw, SHADED_DIR(savewin)); SET_NAME_CHANGED(*pfw,IS_NAME_CHANGED(savewin)); (*pfw)->placed_by_button = savewin->placed_by_button; SET_PLACED_BY_FVWM(*pfw, IS_PLACED_BY_FVWM(savewin)); SET_HAS_EWMH_WM_ICON_HINT(*pfw, HAS_EWMH_WM_ICON_HINT(savewin)); (*pfw)->ewmh_mini_icon_width = savewin->ewmh_mini_icon_width; (*pfw)->ewmh_mini_icon_height = savewin->ewmh_mini_icon_height; (*pfw)->ewmh_icon_width = savewin->ewmh_icon_width; (*pfw)->ewmh_icon_height = savewin->ewmh_icon_height; (*pfw)->ewmh_hint_desktop = savewin->ewmh_hint_desktop; /* restore ewmh state */ EWMH_SetWMState(savewin, True); SET_HAS_EWMH_INIT_WM_DESKTOP( *pfw, HAS_EWMH_INIT_WM_DESKTOP(savewin)); SET_HAS_EWMH_INIT_FULLSCREEN_STATE( *pfw, HAS_EWMH_INIT_FULLSCREEN_STATE(savewin)); SET_HAS_EWMH_INIT_HIDDEN_STATE( *pfw, HAS_EWMH_INIT_HIDDEN_STATE(savewin)); SET_HAS_EWMH_INIT_MAXHORIZ_STATE( *pfw, HAS_EWMH_INIT_MAXHORIZ_STATE(savewin)); SET_HAS_EWMH_INIT_MAXVERT_STATE( *pfw, HAS_EWMH_INIT_MAXVERT_STATE(savewin)); SET_HAS_EWMH_INIT_SHADED_STATE( *pfw, HAS_EWMH_INIT_SHADED_STATE(savewin)); SET_HAS_EWMH_INIT_STICKY_STATE( *pfw, HAS_EWMH_INIT_STICKY_STATE(savewin)); CLEAR_USER_STATES(*pfw, ~0); SET_USER_STATES(*pfw, GET_USER_STATES(savewin)); } else { /* make sure that new windows *remember* being shaded with * title dir last */ SET_USED_TITLE_DIR_FOR_SHADING(*pfw,1); } (*pfw)->cmap_windows = (Window *)NULL; if (FMiniIconsSupported) { (*pfw)->mini_pixmap_file = NULL; (*pfw)->mini_icon = NULL; } return; } static void setup_name_count(FvwmWindow *fw, Bool is_icon) { FvwmWindow *t; int count = 0; int win_count; int win_count_counterpart; Bool done = False; FlocaleNameString *titlename, *title_counterpart; FlocaleNameString *t_titlename, *t_title_counterpart; titlename = (is_icon) ? &(fw->icon_name) : &(fw->name); title_counterpart = (is_icon) ? &(fw->name) : &(fw->icon_name); if (!titlename->name) { done = True; } if (titlename->name && title_counterpart->name && strcmp(titlename->name, title_counterpart->name) == 0) { count = is_icon ? fw->icon_name_count : fw->name_count; } while (!done) { done = True; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (t == fw) { continue; } win_count = is_icon ? t->icon_name_count : t->name_count; win_count_counterpart = is_icon ? t->name_count : t->icon_name_count; t_titlename = is_icon ? &(t->icon_name) : &(t->name); t_title_counterpart = is_icon ? &(t->name) : &(t->icon_name); if ((t_titlename->name && strcmp(titlename->name, t_titlename->name) == 0 && win_count == count) || (t_title_counterpart->name && strcmp(t_title_counterpart->name, titlename->name) == 0 && win_count_counterpart == count)) { count++; done = False; } } } if (is_icon) { fw->icon_name_count = count; } else { fw->name_count = count; } return; } static char *interpolate_titleformat_name(FvwmWindow *fw, window_style *style, Bool is_icon) { char stringbuf[MAX_VISIBLE_NAME_LEN] = ""; /* Get the title format string. This check should be redundant thanks * to the checking done in style.c */ const char *format; int count; /* MAX_WINDOW_NAME_NUMBER is defined as "999" -- that's three * characters maximum. win_name_len must be 1 larger for null. */ char win_name_len[MAX_WINDOW_NAME_NUMBER_DIGITS+1]; char w_id[12]; if (is_icon) { format = (style->flags.has_icon_title_format_string) ? SGET_ICON_TITLE_FORMAT_STRING(*style) : DEFAULT_TITLE_FORMAT; } else { format = (style->flags.has_title_format_string) ? SGET_TITLE_FORMAT_STRING(*style) : DEFAULT_TITLE_FORMAT; } while (*format) { int pos; for (pos = 0; format[pos] && format[pos] != '%'; pos++); strncat(stringbuf, format, pos); format += pos; if (*format != '%') continue; format++; switch (*format) { case 'n': if (strlen(stringbuf) + strlen(fw->name.name) > MAX_VISIBLE_NAME_LEN) { fvwm_msg(WARN, "interpolate_titleformat_name", "Visible name is too long based on " "TitleFormat. Not expanding further."); break; } strcat(stringbuf, fw->name.name); break; case 'c': if (strlen(stringbuf) + strlen(fw->class.res_class) > MAX_VISIBLE_NAME_LEN) { fvwm_msg(WARN, "interpolate_titleformat_name", "Visible name is too long based on " "TitleFormat. Not expanding further."); break; } strcat(stringbuf, fw->class.res_class); break; case 'i': /* Not every application will have an icon * name set; don't crash trying to dereference * this if the name doesn't exist. */ if (fw->icon_name.name == NULL) break; if (strlen(stringbuf) + strlen(fw->icon_name.name) > MAX_VISIBLE_NAME_LEN) { fvwm_msg(WARN, "interpolate_titleformat_name", "Visible name is too long based on " "TitleFormat. Not expanding further."); break; } strcat(stringbuf, fw->icon_name.name); break; case 'r': if (strlen(stringbuf) + strlen(fw->class.res_name) > MAX_VISIBLE_NAME_LEN) { fvwm_msg(WARN, "interpolate_titleformat_name", "Visible name is too long based on " "TitleFormat. Not expanding further."); break; } strcat(stringbuf, fw->class.res_name); break; case 't': setup_name_count(fw, is_icon); count = is_icon ? fw->icon_name_count : fw->name_count; if (count > (MAX_WINDOW_NAME_NUMBER - 1)) count = MAX_WINDOW_NAME_NUMBER - 1; sprintf(win_name_len, "%d", ++count); strcat(stringbuf, win_name_len); break; case 'I': sprintf(w_id, "0x%x", (int)FW_W(fw)); strcat(stringbuf, w_id); break; case '%': strcat(stringbuf, "%"); break; default: break; } if (*format) format++; } /* Now allocate our string. */ return strdup(stringbuf); } static void setup_class_and_resource(FvwmWindow *fw) { /* removing NoClass change for now... */ fw->class.res_name = NoResource; fw->class.res_class = NoClass; XGetClassHint(dpy, FW_W(fw), &fw->class); if (fw->class.res_name == NULL) { fw->class.res_name = NoResource; } if (fw->class.res_class == NULL) { fw->class.res_class = NoClass; } FetchWmProtocols (fw); FetchWmColormapWindows (fw); return; } static void setup_window_attr( FvwmWindow *fw, XWindowAttributes *ret_attr) { if (XGetWindowAttributes(dpy, FW_W(fw), ret_attr) == 0) { /* can't happen because fvwm has grabbed the server and does * not destroy the window itself */ } fw->attr_backup.backing_store = ret_attr->backing_store; fw->attr_backup.border_width = ret_attr->border_width; fw->attr_backup.depth = ret_attr->depth; fw->attr_backup.bit_gravity = ret_attr->bit_gravity; fw->attr_backup.is_bit_gravity_stored = 0; fw->attr_backup.visual = ret_attr->visual; fw->attr_backup.colormap = ret_attr->colormap; return; } static void destroy_window_font(FvwmWindow *fw) { if (IS_WINDOW_FONT_LOADED(fw) && !USING_DEFAULT_WINDOW_FONT(fw) && fw->title_font != Scr.DefaultFont) { FlocaleUnloadFont(dpy, fw->title_font); } SET_WINDOW_FONT_LOADED(fw, 0); /* Fall back to default font. There are some race conditions when a * window is destroyed and recaptured where an invalid font might be * accessed otherwise. */ fw->title_font = Scr.DefaultFont; SET_USING_DEFAULT_WINDOW_FONT(fw, 1); return; } static void destroy_icon_font(FvwmWindow *fw) { if (IS_ICON_FONT_LOADED(fw) && !USING_DEFAULT_ICON_FONT(fw) && fw->icon_font != Scr.DefaultFont) { FlocaleUnloadFont(dpy, fw->icon_font); } SET_ICON_FONT_LOADED(fw, 0); /* Fall back to default font (see comment above). */ fw->icon_font = Scr.DefaultFont; SET_USING_DEFAULT_ICON_FONT(fw, 1); return; } static void adjust_fvwm_internal_windows(FvwmWindow *fw) { if (fw == Scr.Hilite) { Scr.Hilite = NULL; } update_last_screen_focus_window(fw); restore_focus_after_unmap(fw, False); frame_destroyed_frame(FW_W(fw)); if (fw == Scr.StolenFocusFvwmWin) { Scr.StolenFocusWin = None; Scr.StolenFocusFvwmWin = NULL; } if (Scr.focus_in_pending_window == fw) { Scr.focus_in_pending_window = NULL; } if (Scr.focus_in_requested_window == fw) { Scr.focus_in_requested_window = NULL; } if (Scr.cascade_window == fw) { Scr.cascade_window = NULL; } return; } static void broadcast_mini_icon(FvwmWindow *fw) { if (!FMiniIconsSupported) { return; } if (fw->mini_pixmap_file && fw->mini_icon) { BroadcastFvwmPicture( M_MINI_ICON, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, fw->mini_icon, fw->mini_pixmap_file); } return; } static void setup_mini_icon(FvwmWindow *fw, window_style *pstyle) { FvwmPictureAttributes fpa; if (!FMiniIconsSupported) { return; } if (SHAS_MINI_ICON(&pstyle->flags)) { fw->mini_pixmap_file = SGET_MINI_ICON_NAME(*pstyle); } else { fw->mini_pixmap_file = NULL; } if (fw->mini_pixmap_file) { fpa.mask = 0; fw->mini_icon = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, fw->mini_pixmap_file, fpa); } else { fw->mini_icon = NULL; } return; } /* * Copy icon size limits from window_style structure to FvwmWindow * structure. */ void setup_icon_size_limits(FvwmWindow *fw, window_style *pstyle) { if (SHAS_ICON_SIZE_LIMITS(&pstyle->flags)) { fw->min_icon_width = SGET_MIN_ICON_WIDTH(*pstyle); fw->min_icon_height = SGET_MIN_ICON_HEIGHT(*pstyle); fw->max_icon_width = SGET_MAX_ICON_WIDTH(*pstyle); fw->max_icon_height = SGET_MAX_ICON_HEIGHT(*pstyle); fw->icon_resize_type = SGET_ICON_RESIZE_TYPE(*pstyle); } else { fw->min_icon_width = MIN_ALLOWABLE_ICON_DIMENSION; fw->min_icon_height = MIN_ALLOWABLE_ICON_DIMENSION; fw->max_icon_width = MAX_ALLOWABLE_ICON_DIMENSION; fw->max_icon_height = MAX_ALLOWABLE_ICON_DIMENSION; fw->icon_resize_type = ICON_RESIZE_TYPE_NONE; } return; } void setup_icon_background_parameters(FvwmWindow *fw, window_style *pstyle) { if (SHAS_ICON_BACKGROUND_PADDING(&pstyle->flags)) { fw->icon_background_padding = SGET_ICON_BACKGROUND_PADDING(*pstyle); } else { fw->icon_background_padding = ICON_BACKGROUND_PADDING; } if (SHAS_ICON_BACKGROUND_RELIEF(&pstyle->flags)) { fw->icon_background_relief = SGET_ICON_BACKGROUND_RELIEF(*pstyle); } else { fw->icon_background_relief = ICON_RELIEF_WIDTH; } return; } void setup_icon_title_parameters(FvwmWindow *fw, window_style *pstyle) { if (SHAS_ICON_TITLE_RELIEF(&pstyle->flags)) { fw->icon_title_relief = SGET_ICON_TITLE_RELIEF(*pstyle); } else { fw->icon_title_relief = ICON_RELIEF_WIDTH; } return; } void setup_numeric_vals(FvwmWindow *fw, window_style *pstyle) { /****** window shading ******/ fw->shade_anim_steps = pstyle->shade_anim_steps; /****** snapattraction, snapgrid, paging ******/ fw->snap_attraction.proximity = pstyle->snap_attraction.proximity; fw->snap_attraction.mode = pstyle->snap_attraction.mode; fw->snap_grid_x = pstyle->snap_grid_x; fw->snap_grid_y = pstyle->snap_grid_y; if (pstyle->flags.has_edge_delay_ms_move) { fw->edge_delay_ms_move = pstyle->edge_delay_ms_move; } else { fw->edge_delay_ms_move = DEFAULT_MOVE_DELAY; } if (pstyle->flags.has_edge_delay_ms_resize) { fw->edge_delay_ms_resize = pstyle->edge_delay_ms_resize; } else { fw->edge_delay_ms_resize = DEFAULT_RESIZE_DELAY; } fw->edge_resistance_move = pstyle->edge_resistance_move; fw->edge_resistance_xinerama_move = pstyle->edge_resistance_xinerama_move; return; } static void setup_frame_window( FvwmWindow *fw) { XSetWindowAttributes attributes; int valuemask; int depth; Visual *visual; FRenderPictFormat *format; valuemask = CWBackingStore | CWBackPixmap | CWEventMask | CWSaveUnder | CWCursor; /* This adds preliminary support for ARGB windows in fvwm. It should evolve to proper ARGB support in frames, menus and modules */ format=FRenderFindVisualFormat(dpy, fw->attr_backup.visual); if (format != NULL && format->type == FRenderPictTypeDirect && format->direct.alphaMask > 0) { depth = fw->attr_backup.depth; visual = fw->attr_backup.visual; attributes.colormap = fw->attr_backup.colormap; attributes.background_pixel = -1; attributes.border_pixel = -1; valuemask |= CWColormap | CWBackPixel | CWBorderPixel; } else { depth = CopyFromParent; visual = CopyFromParent; } attributes.backing_store = NotUseful; attributes.background_pixmap = None; attributes.cursor = Scr.FvwmCursors[CRS_DEFAULT]; attributes.event_mask = XEVMASK_FRAMEW_CAPTURE; attributes.save_under = False; /* create the frame window, child of root, grandparent of client */ FW_W_FRAME(fw) = XCreateWindow( dpy, Scr.Root, fw->g.frame.x, fw->g.frame.y, fw->g.frame.width, fw->g.frame.height, 0, depth, InputOutput, visual, valuemask, &attributes); XSaveContext(dpy, FW_W(fw), FvwmContext, (caddr_t) fw); XSaveContext(dpy, FW_W_FRAME(fw), FvwmContext, (caddr_t) fw); return; } static void setup_title_window( FvwmWindow *fw, int valuemask, XSetWindowAttributes *pattributes) { valuemask |= CWCursor | CWEventMask; pattributes->cursor = Scr.FvwmCursors[CRS_TITLE]; pattributes->event_mask = XEVMASK_TITLEW; FW_W_TITLE(fw) = XCreateWindow( dpy, FW_W_FRAME(fw), 0, 0, 1, 1, 0, Pdepth, InputOutput, Pvisual, valuemask, pattributes); XSaveContext(dpy, FW_W_TITLE(fw), FvwmContext, (caddr_t) fw); return; } static void destroy_title_window(FvwmWindow *fw, Bool do_only_delete_context) { if (!do_only_delete_context) { XDestroyWindow(dpy, FW_W_TITLE(fw)); FW_W_TITLE(fw) = None; } XDeleteContext(dpy, FW_W_TITLE(fw), FvwmContext); XFlush(dpy); FW_W_TITLE(fw) = None; return; } static void change_title_window( FvwmWindow *fw, int valuemask, XSetWindowAttributes *pattributes) { if (HAS_TITLE(fw) && FW_W_TITLE(fw) == None) { setup_title_window(fw, valuemask, pattributes); } else if (!HAS_TITLE(fw) && FW_W_TITLE(fw) != None) { destroy_title_window(fw, False); } return; } static void setup_button_windows( FvwmWindow *fw, int valuemask, XSetWindowAttributes *pattributes, short buttons) { int i; Bool has_button; Bool is_deleted = False; valuemask |= CWCursor | CWEventMask; pattributes->cursor = Scr.FvwmCursors[CRS_SYS]; pattributes->event_mask = XEVMASK_BUTTONW; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { has_button = (((!(i & 1) && i / 2 < Scr.nr_left_buttons) || ( (i & 1) && i / 2 < Scr.nr_right_buttons)) && (buttons & (1 << i))); if (FW_W_BUTTON(fw, i) == None && has_button) { FW_W_BUTTON(fw, i) = XCreateWindow( dpy, FW_W_FRAME(fw), 0, 0, 1, 1, 0, Pdepth, InputOutput, Pvisual, valuemask, pattributes); XSaveContext( dpy, FW_W_BUTTON(fw, i), FvwmContext, (caddr_t)fw); } else if (FW_W_BUTTON(fw, i) != None && !has_button) { /* destroy the current button window */ XDestroyWindow(dpy, FW_W_BUTTON(fw, i)); XDeleteContext(dpy, FW_W_BUTTON(fw, i), FvwmContext); is_deleted = True; FW_W_BUTTON(fw, i) = None; } } if (is_deleted == True) { XFlush(dpy); } return; } static void destroy_button_windows(FvwmWindow *fw, Bool do_only_delete_context) { int i; Bool is_deleted = False; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if (FW_W_BUTTON(fw, i) != None) { if (!do_only_delete_context) { XDestroyWindow(dpy, FW_W_BUTTON(fw, i)); FW_W_BUTTON(fw, i) = None; } XDeleteContext(dpy, FW_W_BUTTON(fw, i), FvwmContext); is_deleted = True; FW_W_BUTTON(fw, i) = None; } } if (is_deleted == True) { XFlush(dpy); } return; } static void change_button_windows( FvwmWindow *fw, int valuemask, XSetWindowAttributes *pattributes, short buttons) { if (HAS_TITLE(fw)) { setup_button_windows( fw, valuemask, pattributes, buttons); } else { destroy_button_windows(fw, False); } return; } static void setup_parent_window(FvwmWindow *fw) { size_borders b; XSetWindowAttributes attributes; int valuemask; valuemask = CWBackingStore | CWBackPixmap | CWCursor | CWEventMask | CWSaveUnder; attributes.backing_store = NotUseful; attributes.background_pixmap = None; attributes.cursor = Scr.FvwmCursors[CRS_DEFAULT]; attributes.event_mask = XEVMASK_PARENTW; attributes.save_under = False; /* This window is exactly the same size as the client for the benefit * of some clients */ get_window_borders(fw, &b); FW_W_PARENT(fw) = XCreateWindow( dpy, FW_W_FRAME(fw), b.top_left.width, b.top_left.height, fw->g.frame.width - b.total_size.width, fw->g.frame.height - b.total_size.height, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); XSaveContext(dpy, FW_W_PARENT(fw), FvwmContext, (caddr_t) fw); return; } static void setup_resize_handle_cursors(FvwmWindow *fw) { unsigned long valuemask; XSetWindowAttributes attributes; int i; if (HAS_NO_BORDER(fw)) { return; } valuemask = CWCursor; attributes.cursor = Scr.FvwmCursors[CRS_DEFAULT]; for (i = 0; i < 4; i++) { if (HAS_HANDLES(fw)) { attributes.cursor = Scr.FvwmCursors[CRS_TOP_LEFT + i]; } XChangeWindowAttributes( dpy, FW_W_CORNER(fw, i), valuemask, &attributes); if (HAS_HANDLES(fw)) { attributes.cursor = Scr.FvwmCursors[CRS_TOP + i]; } XChangeWindowAttributes( dpy, FW_W_SIDE(fw, i), valuemask, &attributes); } return; } static void setup_resize_handle_windows(FvwmWindow *fw) { unsigned long valuemask; XSetWindowAttributes attributes; int i; int c_grav[4] = { NorthWestGravity, NorthEastGravity, SouthWestGravity, SouthEastGravity }; int s_grav[4] = { NorthWestGravity, NorthEastGravity, SouthWestGravity, NorthWestGravity }; if (HAS_NO_BORDER(fw)) { return; } valuemask = CWEventMask | CWBackingStore | CWSaveUnder | CWWinGravity | CWBorderPixel | CWColormap; attributes.event_mask = XEVMASK_BORDERW; attributes.backing_store = NotUseful; attributes.save_under = False; attributes.border_pixel = 0; attributes.colormap = Pcmap; /* Just dump the windows any old place and let frame_setup_window take * care of the mess */ for (i = 0; i < 4; i++) { attributes.win_gravity = c_grav[i]; FW_W_CORNER(fw, i) = XCreateWindow( dpy, FW_W_FRAME(fw), -1, -1, 1, 1, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); XSaveContext( dpy, FW_W_CORNER(fw, i), FvwmContext, (caddr_t)fw); attributes.win_gravity = s_grav[i]; FW_W_SIDE(fw, i) = XCreateWindow( dpy, FW_W_FRAME(fw), -1, -1, 1, 1, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); XSaveContext(dpy, FW_W_SIDE(fw, i), FvwmContext, (caddr_t)fw); } setup_resize_handle_cursors(fw); return; } static void destroy_resize_handle_windows( FvwmWindow *fw, Bool do_only_delete_context) { int i; for (i = 0; i < 4 ; i++) { XDeleteContext(dpy, FW_W_SIDE(fw, i), FvwmContext); XDeleteContext(dpy, FW_W_CORNER(fw, i), FvwmContext); if (!do_only_delete_context) { XDestroyWindow(dpy, FW_W_SIDE(fw, i)); XDestroyWindow(dpy, FW_W_CORNER(fw, i)); FW_W_SIDE(fw, i) = None; FW_W_CORNER(fw, i) = None; } } XFlush(dpy); return; } static void change_resize_handle_windows(FvwmWindow *fw) { if (!HAS_NO_BORDER(fw) && FW_W_SIDE(fw, 0) == None) { setup_resize_handle_windows(fw); } else if (HAS_NO_BORDER(fw) && FW_W_SIDE(fw, 0) != None) { destroy_resize_handle_windows(fw, False); } else { setup_resize_handle_cursors(fw); } return; } static void setup_frame_stacking(FvwmWindow *fw) { int i; int n; Window w[10 + NUMBER_OF_TITLE_BUTTONS]; /* Stacking order (top to bottom): * - Parent window * - Title and buttons * - Corner handles * - Side handles */ n = 0; if (!IS_SHADED(fw)) { w[n] = FW_W_PARENT(fw); n++; } if (HAS_TITLE(fw)) { for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i += 2) { if (FW_W_BUTTON(fw, i) != None) { w[n] = FW_W_BUTTON(fw, i); n++; } } for (i = 2 * NR_RIGHT_BUTTONS - 1; i > 0; i -= 2) { if (FW_W_BUTTON(fw, i) != None) { w[n] = FW_W_BUTTON(fw, i); n++; } } if (FW_W_TITLE(fw) != None) { w[n] = FW_W_TITLE(fw); n++; } } for (i = 0; i < 4; i++) { if (FW_W_CORNER(fw, i) != None) { w[n] = FW_W_CORNER(fw, i); n++; } } for (i = 0; i < 4; i++) { if (FW_W_SIDE(fw, i) != None) { w[n] = FW_W_SIDE(fw, i); n++; } } if (IS_SHADED(fw)) { w[n] = FW_W_PARENT(fw); n++; } XRestackWindows(dpy, w, n); return; } static void get_default_window_attributes( FvwmWindow *fw, unsigned long *pvaluemask, XSetWindowAttributes *pattributes) { *pvaluemask |= CWBackingStore | CWCursor | CWSaveUnder | CWBorderPixel | CWColormap | CWBackPixmap; pattributes->background_pixel = 0; pattributes->background_pixmap = None; pattributes->backing_store = NotUseful; pattributes->cursor = Scr.FvwmCursors[CRS_DEFAULT]; pattributes->save_under = False; pattributes->border_pixel = 0; pattributes->colormap = Pcmap; return; } static void setup_auxiliary_windows( FvwmWindow *fw, Bool setup_frame_and_parent, short buttons) { unsigned long valuemask_save = 0; XSetWindowAttributes attributes; get_default_window_attributes(fw, &valuemask_save, &attributes); if (setup_frame_and_parent) { setup_frame_window(fw); setup_parent_window(fw); } setup_resize_handle_windows(fw); if (HAS_TITLE(fw)) { setup_title_window(fw, valuemask_save, &attributes); setup_button_windows(fw, valuemask_save, &attributes, buttons); } setup_frame_stacking(fw); XMapSubwindows (dpy, FW_W_FRAME(fw)); return; } static void destroy_auxiliary_windows( FvwmWindow *fw, Bool destroy_frame_and_parent) { if (destroy_frame_and_parent) { XDeleteContext(dpy, FW_W_FRAME(fw), FvwmContext); XDeleteContext(dpy, FW_W_PARENT(fw), FvwmContext); delete_client_context(fw); XDestroyWindow(dpy, FW_W_FRAME(fw)); } if (HAS_TITLE(fw)) { destroy_title_window(fw, True); } if (HAS_TITLE(fw)) { destroy_button_windows(fw, True); } if (!HAS_NO_BORDER(fw)) { destroy_resize_handle_windows(fw, True); } XFlush(dpy); return; } static void setup_icon(FvwmWindow *fw, window_style *pstyle) { increase_icon_hint_count(fw); /* find a suitable icon pixmap */ if ((fw->wmhints) && (fw->wmhints->flags & IconWindowHint)) { if (SHAS_ICON(&pstyle->flags) && S_ICON_OVERRIDE(SCF(*pstyle)) == ICON_OVERRIDE) { ICON_DBG((stderr,"si: iwh ignored '%s'\n", fw->name.name)); fw->icon_bitmap_file = SGET_ICON_NAME(*pstyle); } else { ICON_DBG((stderr,"si: using iwh '%s'\n", fw->name.name)); fw->icon_bitmap_file = NULL; } } else if ((fw->wmhints) && (fw->wmhints->flags & IconPixmapHint)) { if (SHAS_ICON(&pstyle->flags) && S_ICON_OVERRIDE(SCF(*pstyle)) != NO_ICON_OVERRIDE) { ICON_DBG((stderr,"si: iph ignored '%s'\n", fw->name.name)); fw->icon_bitmap_file = SGET_ICON_NAME(*pstyle); } else { ICON_DBG((stderr,"si: using iph '%s'\n", fw->name.name)); fw->icon_bitmap_file = NULL; } } else if (SHAS_ICON(&pstyle->flags)) { /* an icon was specified */ ICON_DBG((stderr,"si: using style '%s'\n", fw->name.name)); fw->icon_bitmap_file = SGET_ICON_NAME(*pstyle); } else { /* use default icon */ ICON_DBG((stderr,"si: using default '%s'\n", fw->name.name)); fw->icon_bitmap_file = Scr.DefaultIcon; } /* icon name */ if (!EWMH_WMIconName(fw, NULL, NULL, 0)) { fw->icon_name.name = NoName; fw->icon_name.name_list = NULL; FlocaleGetNameProperty( XGetWMIconName, dpy, FW_W(fw), &(fw->icon_name)); } if (fw->icon_name.name == NoName) { fw->icon_name.name = fw->name.name; SET_WAS_ICON_NAME_PROVIDED(fw, 0); } setup_visible_name(fw, True); /* wait until the window is iconified and the icon window is mapped * before creating the icon window */ FW_W_ICON_TITLE(fw) = None; EWMH_SetVisibleName(fw, True); BroadcastWindowIconNames(fw, False, True); if (fw->icon_bitmap_file != NULL && fw->icon_bitmap_file != Scr.DefaultIcon) { BroadcastName(M_ICON_FILE,FW_W(fw),FW_W_FRAME(fw), (unsigned long)fw,fw->icon_bitmap_file); } return; } static void destroy_icon(FvwmWindow *fw) { free_window_names(fw, False, True); if (IS_PIXMAP_OURS(fw)) { XFreePixmap(dpy, fw->iconPixmap); fw->iconPixmap = None; if (fw->icon_maskPixmap != None) { XFreePixmap(dpy, fw->icon_maskPixmap); fw->icon_maskPixmap = None; } if (fw->icon_alphaPixmap != None) { XFreePixmap(dpy, fw->icon_alphaPixmap); fw->icon_alphaPixmap = None; } if (fw->icon_alloc_pixels != NULL) { if (fw->icon_nalloc_pixels != 0) { PictureFreeColors( dpy, Pcmap, fw->icon_alloc_pixels, fw->icon_nalloc_pixels, 0, fw->icon_no_limit); } free(fw->icon_alloc_pixels); fw->icon_alloc_pixels = NULL; fw->icon_nalloc_pixels = 0; fw->icon_no_limit = 0; } } if (FW_W_ICON_TITLE(fw)) { XDestroyWindow(dpy, FW_W_ICON_TITLE(fw)); XDeleteContext(dpy, FW_W_ICON_TITLE(fw), FvwmContext); XFlush(dpy); } if (FW_W_ICON_PIXMAP(fw) != None) { if (IS_ICON_OURS(fw)) { XDestroyWindow(dpy, FW_W_ICON_PIXMAP(fw)); } else { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } XDeleteContext(dpy, FW_W_ICON_PIXMAP(fw), FvwmContext); } clear_icon(fw); XFlush(dpy); return; } static void setup_icon_boxes(FvwmWindow *fw, window_style *pstyle) { icon_boxes *ib; /* copy iconboxes ptr (if any) */ if (SHAS_ICON_BOXES(&pstyle->flags)) { fw->IconBoxes = SGET_ICON_BOXES(*pstyle); for (ib = fw->IconBoxes; ib; ib = ib->next) { ib->use_count++; } } else { fw->IconBoxes = NULL; } return; } static void destroy_icon_boxes(FvwmWindow *fw) { if (fw->IconBoxes) { fw->IconBoxes->use_count--; if (fw->IconBoxes->use_count == 0 && fw->IconBoxes->is_orphan) { /* finally destroy the icon box */ free_icon_boxes(fw->IconBoxes); fw->IconBoxes = NULL; } } return; } static void setup_layer(FvwmWindow *fw, window_style *pstyle) { FvwmWindow *tf; int layer; if (SUSE_LAYER(&pstyle->flags)) { /* use layer from style */ layer = SGET_LAYER(*pstyle); } else if ((tf = get_transientfor_fvwmwindow(fw)) != NULL) { /* inherit layer from transientfor window */ layer = get_layer(tf); } else { /* use default layer */ layer = Scr.DefaultLayer; } set_default_layer(fw, layer); set_layer(fw, layer); return; } static void destroy_mini_icon(FvwmWindow *fw) { if (fw->mini_icon) { PDestroyFvwmPicture(dpy, fw->mini_icon); fw->mini_icon = 0; } return; } static void setup_key_and_button_grabs(FvwmWindow *fw) { #ifdef BUGS_ARE_COOL /* dv (29-May-2001): If keys are grabbed separately for C_WINDOW and * the other contexts, new windows have problems when bindings are * removed. Therefore, grab all keys in a single pass through the * list. */ GrabAllWindowKeys( dpy, FW_W_FRAME(fw), Scr.AllBindings, C_WINDOW|C_TITLE|C_RALL|C_LALL|C_SIDEBAR, GetUnusedModifiers(), True); #endif GrabAllWindowKeys( dpy, FW_W_FRAME(fw), Scr.AllBindings, C_TITLE|C_RALL|C_LALL|C_SIDEBAR|C_WINDOW, GetUnusedModifiers(), True); setup_focus_policy(fw); return; } static void __add_window_handle_x_resources(FvwmWindow *fw) { int client_argc = 0; char **client_argv = NULL; XrmValue rm_value; XrmDatabase db = NULL; static XrmOptionDescRec table [] = { {"-xrn", NULL, XrmoptionResArg, (caddr_t) NULL}, {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL}, }; /* Get global X resources */ MergeXResources(dpy, &db, False); /* Find out if the client requested a specific style on the command * line. */ if (XGetCommand(dpy, FW_W(fw), &client_argv, &client_argc)) { if (client_argc > 0 && client_argv != NULL) { /* command line takes precedence over all */ MergeCmdLineResources( &db, table, 2, fw->class.res_name, &client_argc, client_argv, True); } } /* parse the database values */ if (GetResourceString(db, "fvwmstyle", fw->class.res_name, &rm_value) && rm_value.size != 0) { char *style_name; int name_len; style_name = rm_value.addr; name_len = rm_value.size-1; /* Trim spaces at the start of the name */ while (name_len>0 && isspace(*style_name)) { style_name++; name_len--; } /* Trim spaces at the end of the name */ while (name_len>0 && isspace(*(style_name+name_len-1))) { name_len--; } if (name_len>0) { fw->style_name = (char*)safemalloc(sizeof(char)* (name_len+1)); memcpy(fw->style_name,style_name,name_len); fw->style_name[name_len] = 0; } } XFreeStringList(client_argv); XrmDestroyDatabase(db); return; } static int is_geometry_invalid_with_hints( const rectangle *g, const XSizeHints *hints) { if (hints->min_width > g->width) { return 1; } else if (hints->min_height > g->height) { return 2; } else if (hints->max_width < g->width) { return 3; } else if (hints->max_height < g->height) { return 4; } if (hints->width_inc > 0) { int remainder; remainder = (g->width - hints->base_width) % hints->width_inc; if (remainder != 0) { return 5; } } if (hints->height_inc > 0) { int remainder; remainder = (g->height - hints->base_height) % hints->height_inc; if (remainder != 0) { return 6; } } if (hints->flags & PAspect) { if ( (long)g->width * (long)hints->min_aspect.y < (long)hints->min_aspect.x * (long)g->height) { /* aspect smaller than minimum aspect */ return 7; } if ( (long)g->width * (long)hints->max_aspect.y > (long)hints->max_aspect.x * (long)g->height) { /* aspect larger than maximum aspect */ return 8; } } return 0; } /* ---------------------------- interface functions ------------------------ */ void setup_visible_name(FvwmWindow *fw, Bool is_icon) { char *ext_name; window_style style; if (fw == NULL) { /* should never happen */ return; } /* TA: Get the window style. */ lookup_style(fw, &style); ext_name = interpolate_titleformat_name(fw, &style, is_icon); if (is_icon) { fw->visible_icon_name = strdup(ext_name); } else { fw->visible_name = strdup(ext_name); } free(ext_name); return; } void setup_window_name(FvwmWindow *fw) { if (!EWMH_WMName(fw, NULL, NULL, 0)) { fw->name.name = NoName; fw->name.name_list = NULL; FlocaleGetNameProperty(XGetWMName, dpy, FW_W(fw), &(fw->name)); } return; } void setup_wm_hints(FvwmWindow *fw) { fw->wmhints = XGetWMHints(dpy, FW_W(fw)); set_focus_model(fw); return; } void setup_title_geometry( FvwmWindow *fw, window_style *pstyle) { int width; int offset; get_title_font_size_and_offset( fw, S_TITLE_DIR(SCF(*pstyle)), S_IS_LEFT_TITLE_ROTATED_CW(SCF(*pstyle)), S_IS_RIGHT_TITLE_ROTATED_CW(SCF(*pstyle)), S_IS_TOP_TITLE_ROTATED(SCF(*pstyle)), S_IS_BOTTOM_TITLE_ROTATED(SCF(*pstyle)), &width, &offset); fw->title_thickness = width; fw->title_text_offset = offset; fw->corner_width = fw->title_thickness + fw->boundary_width; if (!HAS_TITLE(fw)) { fw->title_thickness = 0; } return; } void setup_window_font( FvwmWindow *fw, window_style *pstyle, Bool do_destroy) { /* get rid of old font */ if (do_destroy) { destroy_window_font(fw); /* destroy_window_font resets the IS_WINDOW_FONT_LOADED flag */ } /* load new font */ if (!IS_WINDOW_FONT_LOADED(fw)) { if (S_HAS_WINDOW_FONT(SCF(*pstyle)) && SGET_WINDOW_FONT(*pstyle) && (fw->title_font = FlocaleLoadFont(dpy, SGET_WINDOW_FONT(*pstyle), "fvwm"))) { SET_USING_DEFAULT_WINDOW_FONT(fw, 0); } else { /* no explicit font or failed to load, use default font * instead */ fw->title_font = Scr.DefaultFont; SET_USING_DEFAULT_WINDOW_FONT(fw, 1); } SET_WINDOW_FONT_LOADED(fw, 1); } setup_title_geometry(fw, pstyle); return; } void setup_icon_font( FvwmWindow *fw, window_style *pstyle, Bool do_destroy) { int height = 0; if (IS_ICON_SUPPRESSED(fw) || HAS_NO_ICON_TITLE(fw)) { if (IS_ICON_FONT_LOADED(fw)) { destroy_icon_font(fw); /* destroy_icon_font resets the IS_ICON_FONT_LOADED * flag */ } return; } /* get rid of old font */ if (do_destroy && IS_ICON_FONT_LOADED(fw)) { destroy_icon_font(fw); /* destroy_icon_font resets the IS_ICON_FONT_LOADED flag */ } /* load new font */ if (!IS_ICON_FONT_LOADED(fw)) { if (S_HAS_ICON_FONT(SCF(*pstyle)) && SGET_ICON_FONT(*pstyle) && (fw->icon_font = FlocaleLoadFont(dpy, SGET_ICON_FONT(*pstyle), "fvwm"))) { SET_USING_DEFAULT_ICON_FONT(fw, 0); } else { /* no explicit font or failed to load, use default font * instead */ fw->icon_font = Scr.DefaultFont; SET_USING_DEFAULT_ICON_FONT(fw, 1); } SET_ICON_FONT_LOADED(fw, 1); } /* adjust y position of existing icons */ height = (IS_ICON_FONT_LOADED(fw)) ? fw->icon_font->height : 0; if (height) { resize_icon_title_height(fw, height - fw->icon_font->height); /* this repositions the icon even if the window is not * iconified */ DrawIconWindow(fw, True, True, False, False, NULL); } return; } void setup_style_and_decor( FvwmWindow *fw, window_style *pstyle, short *buttons) { /* first copy the static styles into the window struct */ memcpy(&(FW_COMMON_FLAGS(fw)), &(SCF(*pstyle)), sizeof(common_flags_t)); fw->wShaped = None; if (FShapesSupported) { int i; unsigned int u; Bool b; int boundingShaped; SUPPRESS_UNUSED_VAR_WARNING(i); SUPPRESS_UNUSED_VAR_WARNING(u); SUPPRESS_UNUSED_VAR_WARNING(b); FShapeSelectInput(dpy, FW_W(fw), FShapeNotifyMask); if (FShapeQueryExtents( dpy, FW_W(fw), &boundingShaped, &i, &i, &u, &u, &b, &i, &i, &u, &u)) { fw->wShaped = boundingShaped; } } /* search for a UseDecor tag in the style */ if (!IS_DECOR_CHANGED(fw)) { FvwmDecor *decor = &Scr.DefaultDecor; for (; decor; decor = decor->next) { if (StrEquals(SGET_DECOR_NAME(*pstyle), decor->tag)) { fw->decor = decor; break; } } } if (fw->decor == NULL) { fw->decor = &Scr.DefaultDecor; } GetMwmHints(fw); GetOlHints(fw); fw->buttons = SIS_BUTTON_DISABLED(&pstyle->flags); SelectDecor(fw, pstyle, buttons); if (IS_TRANSIENT(fw) && !pstyle->flags.do_decorate_transient) { SET_HAS_HANDLES(fw, 0); SET_HAS_TITLE(fw, 0); } /* set boundary width to zero for shaped windows */ if (FHaveShapeExtension) { if (fw->wShaped) { set_window_border_size(fw, fw->unshaped_boundary_width); SET_HAS_NO_BORDER(fw, 1); SET_HAS_HANDLES(fw, 0); } } /****** window colors ******/ update_window_color_style(fw, pstyle); update_window_color_hi_style(fw, pstyle); /***** icons colorsets *****/ update_icon_title_cs_style(fw, pstyle); update_icon_title_cs_hi_style(fw, pstyle); update_icon_background_cs_style(fw, pstyle); /***** icons title/background parameters ****/ setup_icon_background_parameters(fw, pstyle); setup_icon_title_parameters(fw, pstyle); /****** some numeric values ******/ setup_numeric_vals(fw, pstyle); /* ConfigureNotify motion method */ if (SCR_MOTION_METHOD(&pstyle->flag_mask)) { CR_MOTION_METHOD(fw) = SCR_MOTION_METHOD(&pstyle->flags); } return; } void change_icon_boxes(FvwmWindow *fw, window_style *pstyle) { destroy_icon_boxes(fw); setup_icon_boxes(fw, pstyle); return; } void setup_frame_size_limits(FvwmWindow *fw, window_style *pstyle) { if (SHAS_MIN_WINDOW_SIZE(&pstyle->flags)) { fw->min_window_width = SGET_MIN_WINDOW_WIDTH(*pstyle); fw->min_window_height = SGET_MIN_WINDOW_HEIGHT(*pstyle); } else { fw->min_window_width = 0; fw->min_window_height = 0; } if (SHAS_MAX_WINDOW_SIZE(&pstyle->flags)) { fw->max_window_width = SGET_MAX_WINDOW_WIDTH(*pstyle); fw->max_window_height = SGET_MAX_WINDOW_HEIGHT(*pstyle); } else { fw->max_window_width = DEFAULT_MAX_MAX_WINDOW_WIDTH; fw->max_window_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT; } return; } void setup_placement_penalty(FvwmWindow *fw, window_style *pstyle) { if (!SHAS_PLACEMENT_PENALTY(&pstyle->flags)) { pl_penalty_struct *p; p = SGET_PLACEMENT_PENALTY_PTR(*pstyle); *p = default_pl_penalty; } if (!SHAS_PLACEMENT_PERCENTAGE_PENALTY(&pstyle->flags)) { pl_percent_penalty_struct *p; p = SGET_PLACEMENT_PERCENTAGE_PENALTY_PTR(*pstyle); *p = default_pl_percent_penalty; } fw->pl_penalty = (*pstyle).pl_penalty; fw->pl_percent_penalty = (*pstyle).pl_percent_penalty; return; } void setup_frame_attributes( FvwmWindow *fw, window_style *pstyle) { XSetWindowAttributes xswa; /* Backing_store is controlled on the client, borders, title & buttons */ switch (pstyle->flags.use_backing_store) { case BACKINGSTORE_DEFAULT: xswa.backing_store = fw->attr_backup.backing_store; break; case BACKINGSTORE_ON: xswa.backing_store = Scr.use_backing_store; break; case BACKINGSTORE_OFF: default: xswa.backing_store = NotUseful; break; } /* parent_relative is applied to the frame and the parent */ xswa.background_pixmap = pstyle->flags.use_parent_relative ? ParentRelative : None; /* Save_under is only useful on the frame */ xswa.save_under = pstyle->flags.do_save_under ? Scr.flags.do_save_under : NotUseful; XChangeWindowAttributes(dpy, FW_W(fw), CWBackingStore, &xswa); XChangeWindowAttributes( dpy, FW_W_PARENT(fw), CWBackPixmap | CWBackingStore, &xswa); XChangeWindowAttributes( dpy, FW_W_FRAME(fw), CWBackPixmap | CWBackingStore | CWSaveUnder, &xswa); return; } void change_auxiliary_windows(FvwmWindow *fw, short buttons) { unsigned long valuemask_save = 0; XSetWindowAttributes attributes; get_default_window_attributes(fw, &valuemask_save, &attributes); change_title_window(fw, valuemask_save, &attributes); change_button_windows(fw, valuemask_save, &attributes, buttons); change_resize_handle_windows(fw); setup_frame_stacking(fw); XMapSubwindows (dpy, FW_W_FRAME(fw)); return; } void increase_icon_hint_count(FvwmWindow *fw) { if (fw->wmhints && (fw->wmhints->flags & (IconWindowHint | IconPixmapHint))) { switch (WAS_ICON_HINT_PROVIDED(fw)) { case ICON_HINT_NEVER: SET_WAS_ICON_HINT_PROVIDED(fw, ICON_HINT_ONCE); break; case ICON_HINT_ONCE: SET_WAS_ICON_HINT_PROVIDED(fw, ICON_HINT_MULTIPLE); break; case ICON_HINT_MULTIPLE: default: break; } ICON_DBG((stderr,"icon hint count++ (%d) '%s'\n", (int)WAS_ICON_HINT_PROVIDED(fw), fw->name.name)); } return; } void change_icon(FvwmWindow *fw, window_style *pstyle) { destroy_icon(fw); setup_icon(fw, pstyle); return; } void change_mini_icon(FvwmWindow *fw, window_style *pstyle) { FvwmPicture *old_mi = fw->mini_icon; destroy_mini_icon(fw); setup_mini_icon(fw, pstyle); broadcast_mini_icon(fw); if (old_mi != NULL && fw->mini_icon == 0) { /* this case is not handled in setup_mini_icon, so we must * broadcast here explicitly */ BroadcastFvwmPicture( M_MINI_ICON, FW_W(fw), FW_W_FRAME(fw), (unsigned long)fw, NULL, ""); } return; } void setup_focus_policy(FvwmWindow *fw) { focus_grab_buttons(fw); return; } Bool validate_transientfor(FvwmWindow *fw) { XWindowAttributes wa; FvwmWindow *cw; Window w; w = FW_W_TRANSIENTFOR(fw); if (w == None || w == FW_W(fw) || w == IS_EWMH_DESKTOP(w)) { FW_W_TRANSIENTFOR(fw) = Scr.Root; return False; } else if (XFindContext(dpy, w, FvwmContext, (caddr_t *)&cw) != XCNOENT) { if (cw == fw) { /* It's a transient of itself, ignore the hint */ FW_W_TRANSIENTFOR(fw) = Scr.Root; return False; } /* Check for transient loops */ while (XFindContext( dpy, FW_W_TRANSIENTFOR(cw), FvwmContext, (caddr_t *)&cw) != XCNOENT && IS_TRANSIENT(cw)) { if (FW_W_TRANSIENTFOR(cw) == FW_W(fw) || cw == fw) { /* loop detected, ignore the hint */ FW_W_TRANSIENTFOR(fw) = Scr.Root; return False; } } } else if (!XGetWindowAttributes(dpy, w, &wa) || wa.map_state != IsViewable) { /* transientfor does not exist or is not viewable or unmapped */ FW_W_TRANSIENTFOR(fw) = Scr.Root; return False; } return True; } Bool setup_transientfor(FvwmWindow *fw) { Bool rc; rc = XGetTransientForHint(dpy, FW_W(fw), &FW_W_TRANSIENTFOR(fw)); SET_TRANSIENT(fw, rc); if (rc == False) { FW_W_TRANSIENTFOR(fw) = Scr.Root; } validate_transientfor(fw); return rc; } /* * * Procedure: * AddWindow - add a new window to the fvwm list * */ FvwmWindow *AddWindow( const char **ret_initial_map_command, const exec_context_t *exc, FvwmWindow *ReuseWin, initial_window_options_t * win_opts) { /* new fvwm window structure */ register FvwmWindow *fw; FvwmWindow *tmp; /* mask for create windows */ unsigned long valuemask; /* attributes for create windows */ XSetWindowAttributes attributes; XWindowAttributes wattr; /* area for merged styles */ window_style style; /* used for faster access */ style_flags *sflags; short buttons; Bool used_sm = False; Bool do_resize_too = False; size_borders b; frame_move_resize_args mr_args; mwtsm_state_args state_args; Window w = exc->w.w; const exec_context_t *exc2; exec_context_changes_t ecc; /****** init window structure ******/ setup_window_structure(&tmp, w, ReuseWin); fw = tmp; /****** Make sure the client window still exists. We don't want to * leave an orphan frame window if it doesn't. Since we now have the * server grabbed, the window can't disappear later without having been * reparented, so we'll get a DestroyNotify for it. We won't have * gotten one for anything up to here, however. ******/ MyXGrabServer(dpy); if (XGetGeometry( dpy, w, &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) == 0) { if (Scr.bo.do_display_new_window_names) { fvwm_msg(INFO, "AddWindow", "new window disappeared"); } free(fw); MyXUngrabServer(dpy); return NULL; } /****** window name ******/ setup_window_name(fw); setup_class_and_resource(fw); /****** style setup ******/ __add_window_handle_x_resources(fw); /* get merged styles */ lookup_style(fw, &style); sflags = SGET_FLAGS_POINTER(style); if (SIS_UNMANAGED(sflags)) { if (Scr.bo.do_display_new_window_names) { fvwm_msg( INFO, "AddWindow", "new window is unmanaged:\n" " name: %s\n" " icon name: (unknown)\n" " resource: %s\n" " class: %s", fw->name.name, fw->class.res_name, fw->class.res_class); } free_window_names(fw, True, True); if (fw->style_name) { free(fw->style_name); } free(fw); MyXUngrabServer(dpy); return AW_UNMANAGED; } /****** window attributes and hints ******/ setup_window_attr(fw, &wattr); setup_wm_hints(fw); /****** basic style and decor ******/ /* If the window is in the NoTitle list, or is a transient, dont * decorate it. If its a transient, and DecorateTransients was * specified, decorate anyway. */ setup_transientfor(fw); if (win_opts->flags.is_menu) { SET_TEAR_OFF_MENU(fw, 1); } fw->decor = NULL; setup_style_and_decor(fw, &style, &buttons); /****** fonts ******/ setup_window_font(fw, &style, False); setup_icon_font(fw, &style, False); /***** visible window name ****/ setup_visible_name(fw, False); EWMH_SetVisibleName(fw, False); if (Scr.bo.do_display_new_window_names) { fvwm_msg( INFO, "AddWindow", "new window:\n" " name: %s\n" " icon name: %s\n" " resource: %s\n" " class: %s", fw->name.name, (fw->icon_name.name == NULL) ? "(unknown)" : fw->icon_name.name, fw->class.res_name, fw->class.res_class); } /****** InitialMapCommand ******/ *ret_initial_map_command = (style.flags.has_initial_map_command_string) ? SGET_INITIAL_MAP_COMMAND_STRING(style) : NULL; /****** state setup ******/ setup_icon_boxes(fw, &style); SET_ICONIFIED(fw, 0); SET_ICON_UNMAPPED(fw, 0); SET_MAXIMIZED(fw, 0); /* * Reparenting generates an UnmapNotify event, followed by a MapNotify. * Set the map state to 0 to prevent a transition back to * WithdrawnState in HandleUnmapNotify. Map state gets set corrected * again in HandleMapNotify. */ SET_MAPPED(fw, 0); /****** window list and stack ring ******/ /* add the window to the end of the fvwm list */ fw->next = Scr.FvwmRoot.next; fw->prev = &Scr.FvwmRoot; while (fw->next != NULL) { fw->prev = fw->next; fw->next = fw->next->next; } /* fw->prev points to the last window in the list, fw->next is * NULL. Now fix the last window to point to fw */ fw->prev->next = fw; /* * RBW - 11/13/1998 - add it into the stacking order chain also. * This chain is anchored at both ends on Scr.FvwmRoot, there are * no null pointers. */ add_window_to_stack_ring_after(fw, &Scr.FvwmRoot); /****** calculate frame size ******/ fw->hints.win_gravity = NorthWestGravity; GetWindowSizeHints(fw); /****** border width ******/ XSetWindowBorderWidth(dpy, FW_W(fw), 0); /****** icon size limits ******/ setup_icon_size_limits(fw, &style); /***** placement penalities *****/ setup_placement_penalty(fw, &style); /* * MatchWinToSM changes fw->attr and the stacking order. * Thus it is important have this call *after* PlaceWindow and the * stacking order initialization. */ get_window_borders(fw, &b); memset(&state_args, 0, sizeof(state_args)); used_sm = MatchWinToSM(fw, &state_args, win_opts); if (used_sm) { /* read the requested absolute geometry */ gravity_translate_to_northwest_geometry_no_bw( fw->hints.win_gravity, fw, &fw->g.normal, &fw->g.normal); gravity_resize( fw->hints.win_gravity, &fw->g.normal, b.total_size.width, b.total_size.height); fw->g.frame = fw->g.normal; fw->g.frame.x -= Scr.Vx; fw->g.frame.y -= Scr.Vy; /****** calculate frame size ******/ setup_frame_size_limits(fw, &style); constrain_size( fw, NULL, &fw->g.frame.width, &fw->g.frame.height, 0, 0, 0); /****** maximize ******/ if (state_args.do_max) { SET_MAXIMIZED(fw, 1); constrain_size( fw, NULL, &fw->g.max.width, &fw->g.max.height, 0, 0, CS_UPDATE_MAX_DEFECT); get_relative_geometry(&fw->g.frame, &fw->g.max); } else { get_relative_geometry(&fw->g.frame, &fw->g.normal); } } else { rectangle attr_g; if (IS_SHADED(fw)) { state_args.do_shade = 1; state_args.used_title_dir_for_shading = USED_TITLE_DIR_FOR_SHADING(fw); state_args.shade_dir = SHADED_DIR(fw); SET_SHADED(fw, 0); } /* Tentative size estimate */ fw->g.frame.width = wattr.width + b.total_size.width; fw->g.frame.height = wattr.height + b.total_size.height; /****** calculate frame size ******/ setup_frame_size_limits(fw, &style); /****** layer ******/ setup_layer(fw, &style); /****** window placement ******/ attr_g.x = wattr.x; attr_g.y = wattr.y; attr_g.width = wattr.width; attr_g.height = wattr.height; do_resize_too = setup_window_placement( fw, &style, &attr_g, win_opts, PLACE_INITIAL); wattr.x = attr_g.x; wattr.y = attr_g.y; /* set up geometry */ fw->g.frame.x = wattr.x; fw->g.frame.y = wattr.y; fw->g.frame.width = wattr.width + b.total_size.width; fw->g.frame.height = wattr.height + b.total_size.height; gravity_constrain_size( fw->hints.win_gravity, fw, &fw->g.frame, 0); update_absolute_geometry(fw); } /****** auxiliary window setup ******/ setup_auxiliary_windows(fw, True, buttons); /****** 'backing store' and 'save under' window setup ******/ setup_frame_attributes(fw, &style); /****** reparent the window ******/ XReparentWindow(dpy, FW_W(fw), FW_W_PARENT(fw), 0, 0); /****** select events ******/ valuemask = CWEventMask | CWDontPropagate; if (IS_TEAR_OFF_MENU(fw)) { attributes.event_mask = XEVMASK_TEAR_OFF_MENUW; } else { attributes.event_mask = XEVMASK_CLIENTW; } attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; XChangeWindowAttributes(dpy, FW_W(fw), valuemask, &attributes); /****** make sure the window is not destroyed when fvwm dies ******/ if (!IS_TEAR_OFF_MENU(fw)) { /* menus were created by fvwm itself, don't add them to the * save set */ XAddToSaveSet(dpy, FW_W(fw)); } /****** now we can sefely ungrab the server ******/ MyXUngrabServer(dpy); /* need to set up the mini icon before drawing */ if (FMiniIconsSupported) { setup_mini_icon(fw, &style); } /****** arrange the frame ******/ if (is_resizing_event_pending(fw) == True) { SET_FORCE_NEXT_CR(fw, 1); SET_FORCE_NEXT_PN(fw, 1); mr_args = frame_create_move_resize_args( fw, FRAME_MR_FORCE_SETUP_NO_W | FRAME_MR_DONT_DRAW, NULL, &fw->g.frame, 0, DIR_NONE); } else { mr_args = frame_create_move_resize_args( fw, FRAME_MR_FORCE_SETUP | FRAME_MR_DONT_DRAW, NULL, &fw->g.frame, 0, DIR_NONE); } frame_move_resize(fw, mr_args); frame_free_move_resize_args(fw, mr_args); /* draw later */ SET_WAS_NEVER_DRAWN(fw, 1); /****** grab keys and buttons ******/ setup_key_and_button_grabs(fw); /****** inform modules of new window ******/ BroadcastConfig(M_ADD_WINDOW,fw); BroadcastWindowIconNames(fw, True, False); /****** place the window in the stack ring ******/ if (!position_new_window_in_stack_ring(fw, SDO_START_LOWERED(sflags))) { XWindowChanges xwc; xwc.sibling = FW_W_FRAME(get_next_window_in_stack_ring(fw)); xwc.stack_mode = Above; XConfigureWindow( dpy, FW_W_FRAME(fw), CWSibling|CWStackMode, &xwc); } /* these are sent and broadcast before res_{class,name} for the benefit * of FvwmIconBox which can't handle M_ICON_FILE after M_RES_NAME */ /****** icon and mini icon ******/ /* migo (20-Jan-2000): the logic is to unset this flag on NULL values */ SET_WAS_ICON_NAME_PROVIDED(fw, 1); setup_icon(fw, &style); if (FMiniIconsSupported) { broadcast_mini_icon(fw); } BroadcastName(M_RES_CLASS,FW_W(fw),FW_W_FRAME(fw), (unsigned long)fw,fw->class.res_class); BroadcastName(M_RES_NAME,FW_W(fw),FW_W_FRAME(fw), (unsigned long)fw,fw->class.res_name); /****** stick window ******/ if (!(fw->hints.flags & USPosition) || used_sm) { int stick_page; int stick_desk; stick_page = is_window_sticky_across_pages(fw); stick_desk = is_window_sticky_across_desks(fw); if ((stick_page && !IsRectangleOnThisPage(&fw->g.frame, Scr.CurrentDesk)) || (stick_desk && fw->Desk != Scr.CurrentDesk)) { /* If it's sticky and the user didn't ask for an * explicit position, force it on screen now. Don't do * that with USPosition because we have to assume the * user knows what (s)he is doing. This is necessary * e.g. if we want a sticky 'panel' in FvwmButtons but * don't want to see when it's mapped in the void. */ ecc.w.fw = fw; ecc.w.w = FW_W_FRAME(fw); ecc.w.wcontext = C_FRAME; exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); SET_STICKY_ACROSS_PAGES(fw, 0); SET_STICKY_ACROSS_DESKS(fw, 0); handle_stick( NULL, exc2, "", stick_page, stick_desk, 1, 0); exc_destroy_context(exc2); } } /****** resize window ******/ if (do_resize_too) { XEvent e; memset(&e, 0, sizeof(e)); FWarpPointer( dpy, Scr.Root, Scr.Root, 0, 0, Scr.MyDisplayWidth, Scr.MyDisplayHeight, fw->g.frame.x + (fw->g.frame.width>>1), fw->g.frame.y + (fw->g.frame.height>>1)); e.xany.type = ButtonPress; e.xbutton.button = 1; e.xbutton.state = Button1Mask; e.xbutton.x_root = fw->g.frame.x + (fw->g.frame.width>>1); e.xbutton.y_root = fw->g.frame.y + (fw->g.frame.height>>1); e.xbutton.x = (fw->g.frame.width>>1); e.xbutton.y = (fw->g.frame.height>>1); e.xbutton.subwindow = None; e.xany.window = FW_W(fw); fev_fake_event(&e); ecc.x.etrigger = &e; ecc.w.fw = fw; ecc.w.wcontext = C_WINDOW; exc2 = exc_clone_context( exc, &ecc, ECC_ETRIGGER | ECC_FW | ECC_WCONTEXT); CMD_Resize(NULL, exc2, ""); exc_destroy_context(exc2); } /****** window colormap ******/ ReInstallActiveColormap(); /****** ewmh setup *******/ EWMH_WindowInit(fw); /****** windowshade ******/ if (state_args.do_shade || SDO_START_SHADED(sflags)) { rectangle big_g; rectangle new_g; frame_move_resize_args mr_args; if (state_args.used_title_dir_for_shading) { state_args.shade_dir = GET_TITLE_DIR(fw); } /* If we've set a style for StartShaded, ensure we override * the state for it here. -- TA. */ if (SDO_START_SHADED(sflags) && !state_args.do_shade) { state_args.shade_dir = SGET_STARTS_SHADED_DIR(style); } big_g = (IS_MAXIMIZED(fw)) ? fw->g.max : fw->g.frame; new_g = big_g; get_shaded_geometry_with_dir( fw, &new_g, &new_g, state_args.shade_dir); mr_args = frame_create_move_resize_args( fw, FRAME_MR_SHRINK | FRAME_MR_DONT_DRAW, &big_g, &new_g, 0, state_args.shade_dir); frame_move_resize(fw, mr_args); SET_SHADED(fw, 1); SET_SHADED_DIR(fw, state_args.shade_dir); frame_free_move_resize_args(fw, mr_args); } if (!IS_SHADED(fw) && !IS_ICONIFIED(fw)) { /* TK always wants some special treatment: If the window is * simply mapped, the tk menus come up at funny Y coordinates. * Tell it it's geometry *again* to work around this problem. */ SendConfigureNotify( fw, fw->g.frame.x, fw->g.frame.y, fw->g.frame.width, fw->g.frame.height, 0, False); } if ( HAS_EWMH_INIT_MAXVERT_STATE(fw) == EWMH_STATE_HAS_HINT || HAS_EWMH_INIT_MAXHORIZ_STATE(fw) == EWMH_STATE_HAS_HINT) { int h; int v; char cmd[256]; if ( is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { h = (HAS_EWMH_INIT_MAXHORIZ_STATE(fw) == EWMH_STATE_HAS_HINT) ? 100 : 0; v = (HAS_EWMH_INIT_MAXVERT_STATE(fw) == EWMH_STATE_HAS_HINT) ? 100 : 0; sprintf(cmd,"Maximize on %i %i", h, v); execute_function_override_window( NULL, NULL, cmd, 0, fw); } } if (HAS_EWMH_INIT_FULLSCREEN_STATE(fw) == EWMH_STATE_HAS_HINT) { EWMH_fullscreen(fw); } if (!XGetGeometry( dpy, FW_W(fw), &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { /* The window has disappeared somehow. For some reason we do * not always get a DestroyNotify on the window, so make sure * it is destroyed. */ destroy_window(fw); fw = NULL; } return fw; } /* * * Procedure: * FetchWMProtocols - finds out which protocols the window supports * * Inputs: * tmp - the fvwm window structure to use * */ void FetchWmProtocols(FvwmWindow *tmp) { Atom *protocols = NULL, *ap; unsigned long *l_protocols; int i, n; Atom atype; int aformat; unsigned long bytes_remain,nitems; if (tmp == NULL) { return; } /* First, try the Xlib function to read the protocols. * This is what Twm uses. */ if (XGetWMProtocols (dpy, FW_W(tmp), &protocols, &n)) { for (i = 0, ap = protocols; i < n; i++, ap++) { if (*ap == (Atom)_XA_WM_TAKE_FOCUS) { SET_WM_TAKES_FOCUS(tmp, 1); set_focus_model(tmp); } if (*ap == (Atom)_XA_WM_DELETE_WINDOW) { SET_WM_DELETES_WINDOW(tmp, 1); } } if (protocols) { XFree((char *)protocols); } } else { /* Next, read it the hard way. mosaic from Coreldraw needs to * be read in this way. */ if ((XGetWindowProperty( dpy, FW_W(tmp), _XA_WM_PROTOCOLS, 0L, 10L, False, _XA_WM_PROTOCOLS, &atype, &aformat, &nitems, &bytes_remain, (unsigned char **)&l_protocols)) == Success) { for (i = 0; i < nitems; i++) { ap = &(l_protocols[i]); if (*ap == (Atom)_XA_WM_TAKE_FOCUS) { SET_WM_TAKES_FOCUS(tmp, 1); set_focus_model(tmp); } if (*ap == (Atom)_XA_WM_DELETE_WINDOW) { SET_WM_DELETES_WINDOW(tmp, 1); } } if (protocols) { XFree((char *)protocols); } } } return; } void GetWindowSizeHintsWithCheck( FvwmWindow *fw, int do_reject_invalid_size_constraints_on_existing_window) { long supplied = 0; char *broken_cause =""; XSizeHints orig_hints; XSizeHints new_hints; Status rc; new_hints = fw->hints; rc = FGetWMNormalHints(dpy, FW_W(fw), &orig_hints, &supplied); if (rc == 0) { new_hints.flags = 0; memset(&orig_hints, 0, sizeof(orig_hints)); } else { new_hints = orig_hints; if (HAS_OVERRIDE_SIZE_HINTS(fw)) { /* ignore the WMNormal hints */ new_hints.flags &= ~(PMinSize | PMaxSize | PResizeInc); new_hints.min_width = 0; new_hints.min_height = 0; new_hints.max_width = 0; new_hints.max_height = 0; new_hints.width_inc = 1; new_hints.height_inc = 1; } } /* Beat up our copy of the hints, so that all important field are * filled in! */ if (new_hints.flags & PResizeInc) { SET_SIZE_INC_SET(fw, 1); if (new_hints.width_inc <= 0) { if (new_hints.width_inc < 0 || (new_hints.width_inc == 0 && (new_hints.flags & PMinSize) && (new_hints.flags & PMaxSize) && new_hints.min_width != new_hints.max_width)) { broken_cause = "width_inc"; } new_hints.width_inc = 1; SET_SIZE_INC_SET(fw, 0); } if (new_hints.height_inc <= 0) { if (new_hints.height_inc < 0 || (new_hints.height_inc == 0 && (new_hints.flags & PMinSize) && (new_hints.flags & PMaxSize) && new_hints.min_height != new_hints.max_height)) { if (!*broken_cause) { broken_cause = "height_inc"; } } new_hints.height_inc = 1; SET_SIZE_INC_SET(fw, 0); } } else { SET_SIZE_INC_SET(fw, 0); new_hints.width_inc = 1; new_hints.height_inc = 1; } if (new_hints.flags & PMinSize) { if (new_hints.min_width < 0 && !*broken_cause) { broken_cause = "min_width"; } if (new_hints.min_height < 0 && !*broken_cause) { broken_cause = "min_height"; } } else { if (new_hints.flags & PBaseSize) { new_hints.min_width = new_hints.base_width; new_hints.min_height = new_hints.base_height; } else { new_hints.min_width = 1; new_hints.min_height = 1; } } if (new_hints.min_width <= 0) { new_hints.min_width = 1; } if (new_hints.min_height <= 0) { new_hints.min_height = 1; } if (new_hints.flags & PMaxSize) { if (new_hints.max_width < new_hints.min_width) { new_hints.max_width = DEFAULT_MAX_MAX_WINDOW_WIDTH; if (!*broken_cause) { broken_cause = "max_width"; } } if (new_hints.max_height < new_hints.min_height) { new_hints.max_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT; if (!*broken_cause) { broken_cause = "max_height"; } } } else { new_hints.max_width = DEFAULT_MAX_MAX_WINDOW_WIDTH; new_hints.max_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT; } /* * ICCCM says that PMinSize is the default if no PBaseSize is given, * and vice-versa. */ if (new_hints.flags & PBaseSize) { if (new_hints.base_width < 0) { new_hints.base_width = 0; if (!*broken_cause) { broken_cause = "base_width"; } } if (new_hints.base_height < 0) { new_hints.base_height = 0; if (!*broken_cause) { broken_cause = "base_height"; } } if ((new_hints.base_width > new_hints.min_width) || (new_hints.base_height > new_hints.min_height)) { /* In this case, doing the aspect ratio calculation for window_size - base_size as prescribed by the ICCCM is going to fail. Resetting the flag disables the use of base_size in aspect ratio calculation while it is still used for grid sizing. */ new_hints.flags &= ~PBaseSize; #if 0 /* Keep silent about this, since the Xlib manual * actually recommends making min <= base <= max ! */ broken_cause = ""; #endif } } else { if (new_hints.flags & PMinSize) { new_hints.base_width = new_hints.min_width; new_hints.base_height = new_hints.min_height; } else { new_hints.base_width = 0; new_hints.base_height = 0; } } if (!(new_hints.flags & PWinGravity)) { new_hints.win_gravity = NorthWestGravity; } if ((new_hints.flags & PMaxSize) && ((new_hints.flags & PMinSize) || (new_hints.flags & PBaseSize))) { if (new_hints.max_width < new_hints.base_width) { new_hints.max_width = DEFAULT_MAX_MAX_WINDOW_WIDTH; if (!*broken_cause) { broken_cause = "max_width"; } } if (new_hints.max_height < new_hints.base_height) { new_hints.max_height = DEFAULT_MAX_MAX_WINDOW_HEIGHT; if (!*broken_cause) { broken_cause = "max_height"; } } } if (new_hints.flags & PAspect) { /* ** check to make sure min/max aspect ratios look valid */ #define maxAspectX new_hints.max_aspect.x #define maxAspectY new_hints.max_aspect.y #define minAspectX new_hints.min_aspect.x #define minAspectY new_hints.min_aspect.y /* ** The math looks like this: ** ** minAspectX maxAspectX ** ---------- <= ---------- ** minAspectY maxAspectY ** ** If that is multiplied out, this must be satisfied: ** ** minAspectX * maxAspectY <= maxAspectX * minAspectY ** ** So, what to do if this isn't met? Ignoring it entirely ** seems safest. ** */ /* We also ignore people who put negative entries into * their aspect ratios. They deserve it. * * We cast to double here, since the values may be large. */ if ((maxAspectX < 0) || (maxAspectY < 0) || (minAspectX < 0) || (minAspectY < 0) || (((double)minAspectX * (double)maxAspectY) > ((double)maxAspectX * (double)minAspectY))) { if (!*broken_cause) { broken_cause = "aspect ratio"; } new_hints.flags &= ~PAspect; fvwm_msg( WARN, "GetWindowSizeHints", "The applicaton window (window id %#lx)\n" " \"%s\" has broken aspect ratio: " "%d/%d - %d/%d\n" " fvwm is ignoring this aspect ratio. ", FW_W(fw), fw->name.name, minAspectX, minAspectY, maxAspectX, maxAspectY); fvwm_msg_report_app(); } else { /* protect against overflow */ if ((maxAspectX > 65536) || (maxAspectY > 65536)) { double ratio = (double) maxAspectX / (double) maxAspectY; if (ratio > 1.0) { maxAspectX = 65536; maxAspectY = 65536 / ratio; } else { maxAspectX = 65536 * ratio; maxAspectY = 65536; } } if ((minAspectX > 65536) || (minAspectY > 65536)) { double ratio = (double) minAspectX / (double) minAspectY; if (ratio > 1.0) { minAspectX = 65536; minAspectY = 65536 / ratio; } else { minAspectX = 65536 * ratio; minAspectY = 65536; } } } #undef maxAspectX #undef maxAspectY #undef minAspectX #undef minAspectY } if (do_reject_invalid_size_constraints_on_existing_window) { int is_invalid; rectangle g; gravity_get_naked_geometry( fw->hints.win_gravity, fw, &g, &fw->g.normal); is_invalid = is_geometry_invalid_with_hints(&g, &new_hints); if (!is_invalid && IS_MAXIMIZED(fw)) { gravity_get_naked_geometry( fw->hints.win_gravity, fw, &g, &fw->g.max); is_invalid = is_geometry_invalid_with_hints( &g, &new_hints); } if (is_invalid) { fvwm_msg( WARN, "GetWindowSizeHints", "reason: %d:" " The hints have been ignored because the" " window's current size would have become" " invalid. The new hints will become active" " when the window generates the next" " ConfigureRequest.\n", is_invalid); } broken_cause = ""; } else { fw->hints = new_hints; fw->orig_hints.width_inc = orig_hints.width_inc; fw->orig_hints.height_inc = orig_hints.height_inc; } if (*broken_cause != 0) { fvwm_msg( WARN, "GetWindowSizeHints", "The application window (id %#lx)\n" " \"%s\" has broken size hints (%s).\n" " fvwm is ignoring those hints. " " hint override = %d, flags = %lx\n" " min_width = %d, min_height = %d, " "max_width = %d, max_height = %d\n" " width_inc = %d, height_inc = %d\n" " min_aspect = %d/%d, max_aspect = %d/%d\n" " base_width = %d, base_height = %d\n" " win_gravity = %d\n", FW_W(fw), fw->name.name, broken_cause, HAS_OVERRIDE_SIZE_HINTS(fw), orig_hints.flags, orig_hints.min_width, orig_hints.min_height, orig_hints.max_width, orig_hints.max_height, orig_hints.width_inc, orig_hints.height_inc, orig_hints.min_aspect.x, orig_hints.min_aspect.y, orig_hints.max_aspect.x, orig_hints.max_aspect.y, orig_hints.base_width, orig_hints.base_height, orig_hints.win_gravity); fvwm_msg_report_app(); } /* final safety net */ if (fw->orig_hints.width_inc <= 0) { fw->orig_hints.width_inc = 1; } if (fw->orig_hints.height_inc <= 0) { fw->orig_hints.height_inc = 1; } return; } void GetWindowSizeHints(FvwmWindow *fw) { GetWindowSizeHintsWithCheck(fw, 0); } /* * * Releases dynamically allocated space used to store window/icon names * */ void free_window_names(FvwmWindow *fw, Bool nukename, Bool nukeicon) { if (!fw) { return; } if (nukename) { if (fw->visible_name && fw->visible_name != fw->name.name && fw->visible_name != NoName) { free(fw->visible_name); } fw->visible_name = NoName; if (fw->name.name) { if (fw->icon_name.name == fw->name.name) { fw->icon_name.name = NoName; } if (fw->visible_icon_name == fw->name.name) { fw->visible_icon_name = fw->icon_name.name; } if (fw->name.name != NoName) { FlocaleFreeNameProperty(&(fw->name)); fw->visible_name = NULL; } } } if (nukeicon) { if (fw->visible_icon_name && fw->visible_icon_name != fw->name.name && fw->visible_icon_name != fw->icon_name.name && fw->visible_icon_name != NoName) { free(fw->visible_icon_name); } fw->visible_icon_name = NoName; if (fw->icon_name.name) { if ((fw->icon_name.name != fw->name.name) && fw->icon_name.name != NoName) { FlocaleFreeNameProperty(&(fw->icon_name)); fw->visible_icon_name = NULL; } } } return; } /* * * Handles destruction of a window * */ void destroy_window(FvwmWindow *fw) { /* Warning, this is also called by HandleUnmapNotify; if it ever needs * to look at the event, HandleUnmapNotify will have to mash the * UnmapNotify into a DestroyNotify. */ if (!fw) { return; } /* remove window style */ if (!IS_SCHEDULED_FOR_DESTROY(fw) && !DO_REUSE_DESTROYED(fw)) { style_id_t s_id; memset(&s_id, 0, sizeof(style_id_t)); SID_SET_WINDOW_ID(s_id, (XID)FW_W(fw)); SID_SET_HAS_WINDOW_ID(s_id, True); style_destroy_style(s_id); } /****** remove from window list ******/ /* if the window is sheduled fro destroy the window has been already * removed from list */ if (!IS_SCHEDULED_FOR_DESTROY(fw)) { /* first, remove the window from the list of all windows! */ if (fw->prev != NULL) { fw->prev->next = fw->next; } if (fw->next != NULL) { fw->next->prev = fw->prev; } fw->next = NULL; fw->prev = NULL; /****** also remove it from the stack ring ******/ /* * RBW - 11/13/1998 - new: have to unhook the stacking order chain also. There's always a prev and next, since this is a ring anchored on Scr.FvwmRoot */ remove_window_from_stack_ring(fw); } /****** check if we have to delay window destruction ******/ if ((Scr.flags.is_executing_complex_function || Scr.flags.is_executing_menu_function) && !DO_REUSE_DESTROYED(fw)) { if (IS_SCHEDULED_FOR_DESTROY(fw)) { return; } /* mark window for destruction */ SET_SCHEDULED_FOR_DESTROY(fw, 1); Scr.flags.is_window_scheduled_for_destroy = 1; /* this is necessary in case the application destroys the * client window and a new window is created with the same * window id */ delete_client_context(fw); XFlush(dpy); /* unmap the the window to fake that it was already removed */ if (IS_ICONIFIED(fw)) { if (FW_W_ICON_TITLE(fw)) { XUnmapWindow(dpy, FW_W_ICON_TITLE(fw)); } if (FW_W_ICON_PIXMAP(fw) != None) { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } } else { XUnmapWindow(dpy, FW_W_FRAME(fw)); } adjust_fvwm_internal_windows(fw); BroadcastPacket( M_DESTROY_WINDOW, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); EWMH_DestroyWindow(fw); focus_grab_buttons_on_layer(fw->layer); Scr.FWScheduledForDestroy = flist_append_obj( Scr.FWScheduledForDestroy, fw); return; } /****** unmap the frame ******/ XUnmapWindow(dpy, FW_W_FRAME(fw)); XFlush(dpy); /* already done above? */ if (!IS_SCHEDULED_FOR_DESTROY(fw)) { SET_SCHEDULED_FOR_DESTROY(fw, 1); adjust_fvwm_internal_windows(fw); BroadcastPacket( M_DESTROY_WINDOW, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); EWMH_DestroyWindow(fw); } focus_grab_buttons_on_layer(fw->layer); /****** destroy auxiliary windows ******/ destroy_auxiliary_windows(fw, True); /****** destroy icon ******/ destroy_icon_boxes(fw); destroy_icon(fw); /****** destroy mini icon ******/ #ifdef MINI_ICON destroy_mini_icon(fw); #endif /****** free strings ******/ free_window_names(fw, True, True); if (fw->style_name) { free(fw->style_name); fw->style_name = NULL; } if (fw->class.res_name && fw->class.res_name != NoResource) { XFree ((char *)fw->class.res_name); fw->class.res_name = NoResource; } if (fw->class.res_class && fw->class.res_class != NoClass) { XFree ((char *)fw->class.res_class); fw->class.res_class = NoClass; } if (fw->mwm_hints) { XFree((char *)fw->mwm_hints); fw->mwm_hints = NULL; } /****** free fonts ******/ destroy_window_font(fw); destroy_icon_font(fw); /****** free wmhints ******/ if (fw->wmhints) { XFree ((char *)fw->wmhints); fw->wmhints = NULL; } /****** free colormap windows ******/ if (fw->cmap_windows != (Window *)NULL) { XFree((void *)fw->cmap_windows); fw->cmap_windows = NULL; } /****** throw away the structure ******/ /* Recapture reuses this struct, so don't free it. */ if (!DO_REUSE_DESTROYED(fw)) { free((char *)fw); } /****** cleanup ******/ XFlush(dpy); return; } /* * * Procedure: * RestoreWithdrawnLocation * * Puts windows back where they were before fvwm took over * */ void RestoreWithdrawnLocation( FvwmWindow *fw, Bool is_restart_or_recapture, Window parent) { int w2,h2; unsigned int mask; XWindowChanges xwc; rectangle naked_g; rectangle unshaded_g; XSetWindowAttributes xswa; if (!fw) { return; } /* always get the latest size hints in case the application changed * the gravity and we do not yet know about it */ XSync(dpy, 0); GetWindowSizeHints(fw); SET_HAS_NEW_WM_NORMAL_HINTS(fw, 0); get_unshaded_geometry(fw, &unshaded_g); gravity_get_naked_geometry( fw->hints.win_gravity, fw, &naked_g, &unshaded_g); gravity_translate_to_northwest_geometry( fw->hints.win_gravity, fw, &naked_g, &naked_g); xwc.x = naked_g.x; xwc.y = naked_g.y; xwc.width = naked_g.width; xwc.height = naked_g.height; xwc.border_width = fw->attr_backup.border_width; mask = (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); /* We can not assume that the window is currently on the screen. * Although this is normally the case, it is not always true. The * most common example is when the user does something in an * application which will, after some amount of computational delay, * cause the window to be unmapped, but then switches screens before * this happens. The XTranslateCoordinates call above will set the * window coordinates to either be larger than the screen, or negative. * This will result in the window being placed in odd, or even * unviewable locations when the window is remapped. The following * code forces the "relative" location to be within the bounds of the * display. * * gpw -- 11/11/93 * * Unfortunately, this does horrendous things during re-starts, * hence the "if (restart)" clause (RN) * * Also, fixed so that it only does this stuff if a window is more than * half off the screen. (RN) */ if (!is_restart_or_recapture) { /* Don't mess with it if its partially on the screen now */ if (unshaded_g.x < 0 || unshaded_g.y < 0 || unshaded_g.x >= Scr.MyDisplayWidth || unshaded_g.y >= Scr.MyDisplayHeight) { w2 = (unshaded_g.width >> 1); h2 = (unshaded_g.height >> 1); if ( xwc.x < -w2 || xwc.x > Scr.MyDisplayWidth - w2) { xwc.x = xwc.x % Scr.MyDisplayWidth; if (xwc.x < -w2) { xwc.x += Scr.MyDisplayWidth; } } if (xwc.y < -h2 || xwc.y > Scr.MyDisplayHeight - h2) { xwc.y = xwc.y % Scr.MyDisplayHeight; if (xwc.y < -h2) { xwc.y += Scr.MyDisplayHeight; } } } } /* restore initial backing store setting on window */ xswa.backing_store = fw->attr_backup.backing_store; XChangeWindowAttributes(dpy, FW_W(fw), CWBackingStore, &xswa); /* reparent to root window */ XReparentWindow( dpy, FW_W(fw), (parent == None) ? Scr.Root : parent, xwc.x, xwc.y); if (IS_ICONIFIED(fw) && !IS_ICON_SUPPRESSED(fw)) { if (FW_W_ICON_TITLE(fw)) { XUnmapWindow(dpy, FW_W_ICON_TITLE(fw)); } if (FW_W_ICON_PIXMAP(fw)) { XUnmapWindow(dpy, FW_W_ICON_PIXMAP(fw)); } } XConfigureWindow(dpy, FW_W(fw), mask, &xwc); if (!is_restart_or_recapture) { /* must be initial capture */ XFlush(dpy); } return; } /* * * Procedure: * Reborder - Removes fvwm border windows * */ void Reborder(void) { FvwmWindow *fw; /* put a border back around all windows */ MyXGrabServer (dpy); /* force reinstall */ InstallWindowColormaps (&Scr.FvwmRoot); /* RBW - 05/15/1998 * Grab the last window and work backwards: preserve stacking order on * restart. */ for (fw = get_prev_window_in_stack_ring(&Scr.FvwmRoot); fw != &Scr.FvwmRoot; fw = get_prev_window_in_stack_ring(fw)) { if (!IS_ICONIFIED(fw) && Scr.CurrentDesk != fw->Desk) { XMapWindow(dpy, FW_W(fw)); SetMapStateProp(fw, NormalState); } RestoreWithdrawnLocation (fw, True, Scr.Root); XUnmapWindow(dpy,FW_W_FRAME(fw)); XDestroyWindow(dpy,FW_W_FRAME(fw)); } MyXUngrabServer (dpy); FOCUS_RESET(); XFlush(dpy); return; } void CaptureAllWindows(const exec_context_t *exc, Bool is_recapture) { int i,j; unsigned int nchildren; Window root, parent, *children; initial_window_options_t win_opts; FvwmWindow *fw; MyXGrabServer(dpy); if (!XQueryTree(dpy, Scr.Root, &root, &parent, &children, &nchildren)) { MyXUngrabServer(dpy); return; } memset(&win_opts, 0, sizeof(win_opts)); win_opts.flags.do_override_ppos = 1; win_opts.flags.is_recapture = 1; if (!(Scr.flags.are_windows_captured)) /* initial capture? */ { evh_args_t ea; exec_context_changes_t ecc; XEvent e; /* weed out icon windows */ for (i = 0; i < nchildren; i++) { if (children[i]) { XWMHints *wmhintsp = XGetWMHints( dpy, children[i]); if (wmhintsp && wmhintsp->flags & IconWindowHint) { for (j = 0; j < nchildren; j++) { if (children[j] == wmhintsp->icon_window) { children[j] = None; break; } } } if (wmhintsp) { XFree ((char *) wmhintsp); } } } /* map all of the non-override, non-icon windows */ e.type = MapRequest; ecc.x.etrigger = &e; for (i = 0; i < nchildren; i++) { if (children[i] && MappedNotOverride(children[i], &win_opts)) { XUnmapWindow(dpy, children[i]); e.xmaprequest.window = children[i]; e.xmaprequest.parent = Scr.Root; ecc.w.fw = NULL; ecc.w.w = children[i]; ecc.w.wcontext = C_ROOT; ea.exc = exc_clone_context( exc, &ecc, ECC_ETRIGGER | ECC_FW | ECC_W | ECC_WCONTEXT); HandleMapRequestKeepRaised( &ea, None, NULL, &win_opts); exc_destroy_context(ea.exc); } } Scr.flags.are_windows_captured = 1; } else /* must be recapture */ { Window keep_on_top_win; Window parent_win; Window focus_w; FvwmWindow *t; t = get_focus_window(); focus_w = (t) ? FW_W(t) : None; hide_screen(True, &keep_on_top_win, &parent_win); /* reborder all windows */ for (i=0;inext) { ; } if (t) { SetFocusWindow(t, True, FOCUS_SET_FORCE); } } } if (nchildren > 0) { XFree((char *)children); } MyXUngrabServer(dpy); return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_Recapture(F_CMD_ARGS) { do_recapture(F_PASS_ARGS, False); return; } void CMD_RecaptureWindow(F_CMD_ARGS) { do_recapture(F_PASS_ARGS, True); return; } fvwm-2.6.7/fvwm/window_flags.h0000644000175700017570000007344212773467232013306 00000000000000/* -*-c-*- */ #ifndef _WINDOW_FLAGS_ #define _WINDOW_FLAGS_ #include "focus_policy.h" /* access to the common flags of a window */ #define FW_COMMON_FLAGS(fw) \ ((fw)->flags.common) #define FW_COMMON_STATIC_FLAGS(fw) \ ((fw)->flags.common.s) #define FW_FOCUS_POLICY(fw) \ ((fw)->flags.common.s.focus_policy) #define DO_LOWER_TRANSIENT(fw) \ ((fw)->flags.common.s.do_lower_transient) #define DO_NOT_SHOW_ON_MAP(fw) \ ((fw)->flags.common.s.do_not_show_on_map) #define DO_RAISE_TRANSIENT(fw) \ ((fw)->flags.common.s.do_raise_transient) #define DO_RESIZE_OPAQUE(fw) \ ((fw)->flags.common.s.do_resize_opaque) #define DO_SHRINK_WINDOWSHADE(fw) \ ((fw)->flags.common.s.do_shrink_windowshade) #define SET_DO_SHRINK_WINDOWSHADE(fw,x) \ (fw)->flags.common.s.do_shrink_windowshade = !!(x) #define SETM_DO_SHRINK_WINDOWSHADE(fw,x) \ (fw)->flag_mask.common.s.do_shrink_windowshade = !!(x) #define DO_SKIP_CIRCULATE(fw) \ ((fw)->flags.common.s.do_circulate_skip) #define SET_DO_SKIP_CIRCULATE(fw,x) \ (fw)->flags.common.s.do_circulate_skip = !!(x) #define SETM_DO_SKIP_CIRCULATE(fw,x) \ (fw)->flag_mask.common.s.do_circulate_skip = !!(x) #define DO_SKIP_ICON_CIRCULATE(fw) \ ((fw)->flags.common.s.do_circulate_skip_icon) #define SET_DO_SKIP_ICON_CIRCULATE(fw,x) \ (fw)->flags.common.s.do_circulate_skip_icon = !!(x) #define SETM_DO_SKIP_ICON_CIRCULATE(fw,x) \ (fw)->flag_mask.common.s.do_circulate_skip_icon = !!(x) #define DO_SKIP_SHADED_CIRCULATE(fw) \ ((fw)->flags.common.s.do_circulate_skip_shaded) #define SET_DO_SKIP_SHADED_CIRCULATE(fw,x) \ (fw)->flags.common.s.do_circulate_skip_shaded = !!(x) #define SETM_DO_SKIP_SHADED_CIRCULATE(fw,x) \ (fw)->flag_mask.common.s.do_circulate_skip_shaded = !!(x) #define DO_SKIP_WINDOW_LIST(fw) \ ((fw)->flags.common.s.do_window_list_skip) #define SET_DO_SKIP_WINDOW_LIST(fw,x) \ (fw)->flags.common.s.do_window_list_skip = !!(x) #define SETM_DO_SKIP_WINDOW_LIST(fw,x) \ (fw)->flag_mask.common.s.do_window_list_skip = !!(x) #define DO_STACK_TRANSIENT_PARENT(fw) \ ((fw)->flags.common.s.do_stack_transient_parent) #define GET_TITLE_DIR(fw) \ ((fw)->flags.common.title_dir) #define HAS_TITLE_DIR(fw,x) \ ((fw)->flags.common.title_dir == x) #define SET_TITLE_DIR(fw,x) \ ((fw)->flags.common.title_dir = x) #define SETM_TITLE_DIR(fw,x) \ ((fw)->flag_mask.common.title_dir = ((x) ? DIR_MAJOR_MASK : 0)) #define SET_USER_STATES(fw, mask) \ ((fw)->flags.common.user_states |= (mask)) #define CLEAR_USER_STATES(fw, mask) \ ((fw)->flags.common.user_states &= ~(mask)) #define TOGGLE_USER_STATES(fw, mask) \ ((fw)->flags.common.user_states ^= (mask)) #define SETM_USER_STATES(fw, mask) \ ((fw)->flag_mask.common.user_states |= (mask)) #define GET_USER_STATES(fw) \ ((fw)->flags.common.user_states) #define GETM_USER_STATES(fw) \ ((fw)->flag_mask.common.user_states) #define HAS_VERTICAL_TITLE(fw) \ ((HAS_TITLE_DIR(fw,DIR_W) || HAS_TITLE_DIR(fw,DIR_E))) #define HAS_STIPPLED_TITLE(fw) \ ((fw)->flags.common.s.has_stippled_title) #define SET_HAS_STIPPLED_TITLE(fw,x) \ (fw)->flags.common.s.has_stippled_title = !!(x) #define SETM_HAS_STIPPLED_TITLE(fw,x) \ (fw)->flag_mask.common.s.has_stippled_title = !!(x) #define HAS_STICKY_STIPPLED_TITLE(fw) \ !((fw)->flags.common.s.has_no_sticky_stippled_title) #define SET_HAS_STICKY_STIPPLED_TITLE(fw,x) \ (fw)->flags.common.s.has_no_sticky_stippled_title = !(x) #define SETM_HAS_STICKY_STIPPLED_TITLE(fw,x) \ (fw)->flag_mask.common.s.has_no_sticky_stippled_title = !!(x) #define HAS_STICKY_STIPPLED_ICON_TITLE(fw) \ !((fw)->flags.common.s.has_no_sticky_stippled_icon_title) #define SET_HAS_STICKY_STIPPLED_ICON_TITLE(fw,x) \ (fw)->flags.common.s.has_no_sticky_stippled_icon_title = !(x) #define SETM_HAS_STICKY_STIPPLED_ICON_TITLE(fw,x) \ (fw)->flag_mask.common.s.has_no_sticky_stippled_icon_title = !!(x) #define HAS_STIPPLED_ICON_TITLE(fw) \ ((fw)->flags.common.s.has_stippled_icon_title) #define SET_HAS_STIPPLED_ICON_TITLE(fw,x) \ (fw)->flags.common.s.has_stippled_icon_title = !!(x) #define SETM_HAS_STIPPLED_ICON_TITLE(fw,x) \ (fw)->flag_mask.common.s.has_stippled_icon_title = !!(x) #define ICON_OVERRIDE_MODE(fw) \ ((fw)->flags.common.s.icon_override) #define SET_ICON_OVERRIDE_MODE(fw,x) \ (fw)->flags.common.s.icon_override = ((x) & ICON_OVERRIDE_MASK) #define SETM_ICON_OVERRIDE_MODE(fw,x) \ (fw)->flag_mask.common.s.icon_override = ((x) ? ICON_OVERRIDE_MASK : 0) #define IS_ICON_STICKY_ACROSS_PAGES(fw) \ ((fw)->flags.common.s.is_icon_sticky_across_pages) #define SET_ICON_STICKY_ACROSS_PAGES(fw,x) \ (fw)->flags.common.s.is_icon_sticky_across_pages = !!(x) #define SETM_ICON_STICKY_ACROSS_PAGES(fw,x) \ (fw)->flag_mask.common.s.is_icon_sticky_across_pages = !!(x) #define IS_ICON_STICKY_ACROSS_DESKS(fw) \ ((fw)->flags.common.s.is_icon_sticky_across_desks) #define SET_ICON_STICKY_ACROSS_DESKS(fw,x) \ (fw)->flags.common.s.is_icon_sticky_across_desks = !!(x) #define SETM_ICON_STICKY_ACROSS_DESKS(fw,x) \ (fw)->flag_mask.common.s.is_icon_sticky_across_desks = !!(x) #define USE_ICON_POSITION_HINT(fw) \ ((fw)->flags.common.s.use_icon_position_hint) #define SET_USE_ICON_POSITION_HINT(fw,x) \ (fw)->flags.common.s.use_icon_position_hint = !!(x) #define SETM_USE_ICON_POSITION_HINT(fw,x) \ (fw)->flag_mask.common.s.use_icon_position_hint = !!(x) #define USE_INDEXED_WINDOW_NAME(fw) \ ((fw)->flags.common.s.use_indexed_window_name) #define SET_USE_INDEXED_WINDOW_NAME(fw,x) \ (fw)->flags.common.s.use_indexed_window_name = !!(x) #define SETM_USE_INDEXED_WINDOW_NAME(fw,x) \ (fw)->flag_mask.common.s.use_indexed_window_name = !!(x) #define USE_INDEXED_ICON_NAME(fw) \ ((fw)->flags.common.s.use_indexed_icon_name) #define SET_USE_INDEXED_ICON_NAME(fw,x) \ (fw)->flags.common.s.use_indexed_icon_name = !!(x) #define SETM_USE_INDEXED_ICON_NAME(fw,x) \ (fw)->flag_mask.common.s.use_indexed_icon_name = !!(x) #define WINDOWSHADE_LAZINESS(fw) \ ((fw)->flags.common.s.windowshade_laziness) #define SET_WINDOWSHADE_LAZINESS(fw,x) \ (fw)->flags.common.s.windowshade_laziness = \ ((x) & WINDOWSHADE_LAZY_MASK) #define SETM_WINDOWSHADE_LAZINESS(fw,x) \ (fw)->flag_mask.common.s.windowshade_laziness = \ ((x) ? WINDOWSHADE_LAZY_MASK : 0) #define DO_EWMH_MINI_ICON_OVERRIDE(fw) \ ((fw)->flags.common.s.do_ewmh_mini_icon_override) #define SET_DO_EWMH_MINI_ICON_OVERRIDE(fw,x) \ (fw)->flags.common.s.do_ewmh_mini_icon_override = !!(x) #define SETM_DO_EWMH_MINI_ICON_OVERRIDE(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_mini_icon_override = !!(x) #define DO_EWMH_DONATE_ICON(fw) \ ((fw)->flags.common.s.do_ewmh_donate_icon) #define SET_DO_EWMH_DONATE_ICON(fw,x) \ (fw)->flags.common.s.do_ewmh_donate_icon = !!(x) #define SETM_DO_EWMH_DONATE_ICON(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_donate_icon = !!(x) #define DO_EWMH_DONATE_MINI_ICON(fw) \ ((fw)->flags.common.s.do_ewmh_donate_mini_icon) #define SET_DO_EWMH_DONATE_MINI_ICON(fw,x) \ (fw)->flags.common.s.do_ewmh_donate_mini_icon = !!(x) #define SETM_DO_EWMH_DONATE_MINI_ICON(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_donate_mini_icon = !!(x) #define DO_EWMH_USE_STACKING_HINTS(fw) \ ((fw)->flags.common.s.do_ewmh_use_stacking_hints) #define SET_DO_EWMH_USE_STACKING_HINTS(fw,x) \ (fw)->flags.common.s.do_ewmh_use_stacking_hints = !!(x) #define SETM_DO_EWMH_USE_STACKING_HINTS(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_use_stacking_hints = !!(x) #define DO_EWMH_IGNORE_STRUT_HINTS(fw) \ ((fw)->flags.common.s.do_ewmh_ignore_strut_hints) #define SET_DO_EWMH_IGNORE_STRUT_HINTS(fw,x) \ (fw)->flags.common.s.do_ewmh_ignore_strut_hints = !!(x) #define SETM_DO_EWMH_IGNORE_STRUT_HINTS(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_ignore_strut_hints = !!(x) #define DO_EWMH_IGNORE_STATE_HINTS(fw) \ ((fw)->flags.common.s.do_ewmh_ignore_state_hints) #define SET_DO_EWMH_IGNORE_STATE_HINTS(fw,x) \ (fw)->flags.common.s.do_ewmh_ignore_state_hints = !!(x) #define SETM_DO_EWMH_IGNORE_STATE_HINTS(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_ignore_state_hints = !!(x) #define DO_EWMH_IGNORE_WINDOW_TYPE(fw) \ ((fw)->flags.common.s.do_ewmh_ignore_window_type) #define SET_DO_EWMH_IGNORE_WINDOW_TYPE(fw,x) \ (fw)->flags.common.s.do_ewmh_ignore_window_type = !!(x) #define SETM_DO_EWMH_IGNORE_WINDOW_TYPE(fw,x) \ (fw)->flag_mask.common.s.do_ewmh_ignore_window_type = !!(x) #define EWMH_MAXIMIZE_MODE(fw) \ ((fw)->flags.common.s.ewmh_maximize_mode) #define SET_EWMH_MAXIMIZE_MODE(fw,x) \ (fw)->flags.common.s.ewmh_maximize_mode = (x) #define SETM_EWMH_MAXIMIZE_MODE(fw,x) \ (fw)->flag_mask.common.s.ewmh_maximize_mode = (x) #define IS_ICON_SUPPRESSED(fw) \ ((fw)->flags.common.s.is_icon_suppressed) #define SET_ICON_SUPPRESSED(fw,x) \ (fw)->flags.common.s.is_icon_suppressed = !!(x) #define SETM_ICON_SUPPRESSED(fw,x) \ (fw)->flag_mask.common.s.is_icon_suppressed = !!(x) #define IS_STICKY_ACROSS_PAGES(fw) \ ((fw)->flags.common.is_sticky_across_pages) #define SET_STICKY_ACROSS_PAGES(fw,x) \ (fw)->flags.common.is_sticky_across_pages = !!(x) #define SETM_STICKY_ACROSS_PAGES(fw,x) \ (fw)->flag_mask.common.is_sticky_across_pages = !!(x) #define IS_STICKY_ACROSS_DESKS(fw) \ ((fw)->flags.common.is_sticky_across_desks) #define SET_STICKY_ACROSS_DESKS(fw,x) \ (fw)->flags.common.is_sticky_across_desks = !!(x) #define SETM_STICKY_ACROSS_DESKS(fw,x) \ (fw)->flag_mask.common.is_sticky_across_desks = !!(x) #define HAS_ICON_FONT(fw) \ ((fw)->flags.common.has_icon_font) #define SET_HAS_ICON_FONT(fw,x) \ (fw)->flags.common.has_icon_font = !!(x) #define SETM_HAS_ICON_FONT(fw,x) \ (fw)->flag_mask.common.has_icon_font = !!(x) #define HAS_NO_ICON_TITLE(fw) \ ((fw)->flags.common.s.has_no_icon_title) #define SET_HAS_NO_ICON_TITLE(fw,x) \ (fw)->flags.common.s.has_no_icon_title = !!(x) #define SETM_HAS_NO_ICON_TITLE(fw,x) \ (fw)->flag_mask.common.s.has_no_icon_title = !!(x) #define HAS_WINDOW_FONT(fw) \ ((fw)->flags.common.has_window_font) #define SET_HAS_WINDOW_FONT(fw,x) \ (fw)->flags.common.has_window_font = !!(x) #define SETM_HAS_WINDOW_FONT(fw,x) \ (fw)->flag_mask.common.has_window_font = !!(x) #define HAS_MWM_BORDER(fw) \ ((fw)->flags.common.s.has_mwm_border) #define HAS_MWM_BUTTONS(fw) \ ((fw)->flags.common.s.has_mwm_buttons) #define HAS_MWM_OVERRIDE_HINTS(fw) \ ((fw)->flags.common.s.has_mwm_override) #define HAS_OVERRIDE_SIZE_HINTS(fw) \ ((fw)->flags.common.s.has_override_size) #define DO_ICONIFY_WINDOW_GROUPS(fw) \ ((fw)->flags.common.s.do_iconify_window_groups) #define DO_IGNORE_GNOME_HINTS(fw) \ ((fw)->flags.common.s.do_ignore_gnome_hints) #define DO_IGNORE_RESTACK(fw) \ ((fw)->flags.common.s.do_ignore_restack) #define DO_IGNORE_ICON_BOXES(fw) \ ((fw)->flags.common.s.do_ignore_icon_boxes) #define DO_USE_WINDOW_GROUP_HINT(fw) \ ((fw)->flags.common.s.do_use_window_group_hint) #define IS_FIXED(fw) \ ((fw)->flags.common.s.is_fixed) #define SET_FIXED(fw,x) \ (fw)->flags.common.s.is_fixed = !!(x) #define SETM_FIXED(fw,x) \ (fw)->flag_mask.common.s.is_fixed = !!(x) #define IS_FIXED_PPOS(fw) \ ((fw)->flags.common.s.is_fixed_ppos) #define SET_FIXED_PPOS(fw,x) \ (fw)->flags.common.s.is_fixed_ppos = !!(x) #define SETM_FIXED_PPOS(fw,x) \ (fw)->flag_mask.common.s.is_fixed_ppos = !!(x) #define IS_SIZE_FIXED(fw) \ ((fw)->flags.common.s.is_size_fixed) #define SET_SIZE_FIXED(fw,x) \ (fw)->flags.common.s.is_size_fixed = !!(x) #define SETM_SIZE_FIXED(fw,x) \ (fw)->flag_mask.common.s.is_size_fixed = !!(x) #define IS_PSIZE_FIXED(fw) \ ((fw)->flags.common.s.is_psize_fixed) #define SET_PSIZE_FIXED(fw,x) \ (fw)->flags.common.s.is_psize_fixed = !!(x) #define SETM_PSIZE_FIXED(fw,x) \ (fw)->flag_mask.common.s.is_psize_fixed = !!(x) #define IS_UNICONIFIABLE(fw) \ ((fw)->flags.common.s.is_uniconifiable) #define SET_IS_UNICONIFIABLE(fw,x) \ (fw)->flags.common.s.is_uniconifiable = !!(x) #define SETM_IS_UNICONIFIABLE(fw,x) \ (fw)->flag_mask.common.s.is_uniconifiable = !!(x) #define IS_UNMAXIMIZABLE(fw) \ ((fw)->flags.common.s.is_unmaximizable) #define SET_IS_UNMAXIMIZABLE(fw,x) \ (fw)->flags.common.s.is_unmaximizable = !!(x) #define SETM_IS_UNMAXIMIZABLE(fw,x) \ (fw)->flag_mask.common.s.is_unmaximizable = !!(x) #define IS_UNCLOSABLE(fw) \ ((fw)->flags.common.s.is_unclosable) #define SET_IS_UNCLOSABLE(fw,x) \ (fw)->flags.common.s.is_unclosable = !!(x) #define SETM_IS_UNCLOSABLE(fw,x) \ (fw)->flag_mask.common.s.is_unclosable = !!(x) #define IS_MAXIMIZE_FIXED_SIZE_DISALLOWED(fw) \ ((fw)->flags.common.s.is_maximize_fixed_size_disallowed) #define SET_MAXIMIZE_FIXED_SIZE_DISALLOWED(fw,x) \ (fw)->flags.common.s.is_maximize_fixed_size_disallowed = !!(x) #define SETM_MAXIMIZE_FIXED_SIZE_DISALLOWED(fw,x) \ (fw)->flag_mask.common.s.is_maximize_fixed_size_disallowed = !!(x) #define HAS_DEPRESSABLE_BORDER(fw) \ ((fw)->flags.common.s.has_depressable_border) #define IS_LEFT_TITLE_ROTATED_CW(fw) \ ((fw)->flags.common.s.is_left_title_rotated_cw) #define SET_IS_LEFT_TITLE_ROTATED_CW(fw,x) \ (fw)->flags.common.s.is_left_title_rotated_cw = !!(x) #define SETM_IS_LEFT_TITLE_ROTATED_CW(fw,x) \ (fw)->flag_mask.common.s.is_left_title_rotated_cw = !!(x) #define IS_RIGHT_TITLE_ROTATED_CW(fw) \ ((fw)->flags.common.s.is_right_title_rotated_cw) #define SET_IS_RIGHT_TITLE_ROTATED_CW(fw,x) \ (fw)->flags.common.s.is_right_title_rotated_cw = !!(x) #define SETM_IS_RIGHT_TITLE_ROTATED_CW(fw,x) \ (fw)->flag_mask.common.s.is_right_title_rotated_cw = !!(x) #define IS_BOTTOM_TITLE_ROTATED(fw) \ ((fw)->flags.common.s.is_bottom_title_rotated) #define SET_IS_BOTTOM_TITLE_ROTATED(fw,x) \ (fw)->flags.common.s.is_bottom_title_rotated = !!(x) #define SETM_IS_BOTTOM_TITLE_ROTATED(fw,x) \ (fw)->flag_mask.common.s.is_bottom_title_rotated = !!(x) #define IS_BOTTOM_TITLE_ROTATED(fw) \ ((fw)->flags.common.s.is_bottom_title_rotated) #define SET_IS_BOTTOM_TITLE_ROTATED(fw,x) \ (fw)->flags.common.s.is_bottom_title_rotated = !!(x) #define SETM_IS_BOTTOM_TITLE_ROTATED(fw,x) \ (fw)->flag_mask.common.s.is_bottom_title_rotated = !!(x) #define USE_TITLE_DECOR_ROTATION(fw) \ ((fw)->flags.common.s.use_title_decor_rotation) #define SET_USE_TITLE_DECOR_ROTATION(fw,x) \ (fw)->flags.common.s.use_title_decor_rotation = !!(x) #define SETM_USE_TITLE_DECOR_ROTATION(fw,x) \ (fw)->flag_mask.common.s.use_title_decor_rotation = !!(x) /* access to the special flags of a window */ #define DO_REUSE_DESTROYED(fw) \ ((fw)->flags.do_reuse_destroyed) #define SET_DO_REUSE_DESTROYED(fw,x) \ (fw)->flags.do_reuse_destroyed = !!(x) #define SETM_DO_REUSE_DESTROYED(fw,x) \ (fw)->flag_mask.do_reuse_destroyed = !!(x) #define HAS_NO_BORDER(fw) \ ((fw)->flags.common.has_no_border) #define SET_HAS_NO_BORDER(fw,x) \ (fw)->flags.common.has_no_border = !!(x) #define SETM_HAS_NO_BORDER(fw,x) \ (fw)->flag_mask.common.has_no_border = !!(x) #define HAS_HANDLES(fw) \ ((fw)->flags.has_handles) #define SET_HAS_HANDLES(fw,x) \ (fw)->flags.has_handles = !!(x) #define SETM_HAS_HANDLES(fw,x) \ (fw)->flag_mask.has_handles = !!(x) #define HAS_ICON_CHANGED(fw) \ ((fw)->flags.has_icon_changed) #define SET_HAS_ICON_CHANGED(fw,x) \ (fw)->flags.has_icon_changed = !!(x) #define SETM_HAS_ICON_CHANGED(fw,x) \ (fw)->flag_mask.has_icon_changed = !!(x) #define HAS_TITLE(fw) \ ((fw)->flags.has_title) #define SET_HAS_TITLE(fw,x) \ (fw)->flags.has_title = !!(x) #define SETM_HAS_TITLE(fw,x) \ (fw)->flag_mask.has_title = !!(x) #define HAS_NEW_WM_NORMAL_HINTS(fw) \ ((fw)->flags.has_new_wm_normal_hints) #define SET_HAS_NEW_WM_NORMAL_HINTS(fw,x) \ (fw)->flags.has_new_wm_normal_hints = !!(x) #define SETM_HAS_NEW_WM_NORMAL_HINTS(fw,x) \ (fw)->flag_mask.has_new_wm_normal_hints = !!(x) #define IS_MAPPED(fw) \ ((fw)->flags.is_mapped) #define SET_MAPPED(fw,x) \ (fw)->flags.is_mapped = !!(x) #define SETM_MAPPED(fw,x) \ (fw)->flag_mask.is_mapped = !!(x) #define IS_DECOR_CHANGED(fw) \ ((fw)->flags.is_decor_changed) #define SET_DECOR_CHANGED(fw,x) \ (fw)->flags.is_decor_changed = !!(x) #define SETM_DECOR_CHANGED(fw,x) \ (fw)->flag_mask.is_decor_changed = !!(x) #define IS_ICON_FONT_LOADED(fw) \ ((fw)->flags.is_icon_font_loaded) #define SET_ICON_FONT_LOADED(fw,x) \ (fw)->flags.is_icon_font_loaded = !!(x) #define SETM_ICON_FONT_LOADED(fw,x) \ (fw)->flag_mask.is_icon_font_loaded = !!(x) #define IS_ICONIFIED(fw) \ ((fw)->flags.is_iconified) #define SET_ICONIFIED(fw,x) \ (fw)->flags.is_iconified = !!(x) #define SETM_ICONIFIED(fw,x) \ (fw)->flag_mask.is_iconified = !!(x) #define IS_ICONIFIED_BY_PARENT(fw) \ ((fw)->flags.is_iconified_by_parent) #define SET_ICONIFIED_BY_PARENT(fw,x) \ (fw)->flags.is_iconified_by_parent = !!(x) #define SETM_ICONIFIED_BY_PARENT(fw,x) \ (fw)->flag_mask.is_iconified_by_parent = !!(x) #define IS_ICON_ENTERED(fw) \ ((fw)->flags.is_icon_entered) #define SET_ICON_ENTERED(fw,x) \ (fw)->flags.is_icon_entered = !!(x) #define SETM_ICON_ENTERED(fw,x) \ (fw)->flag_mask.is_icon_entered = !!(x) #define IS_ICON_OURS(fw) \ ((fw)->flags.is_icon_ours) #define SET_ICON_OURS(fw,x) \ (fw)->flags.is_icon_ours = !!(x) #define SETM_ICON_OURS(fw,x) \ (fw)->flag_mask.is_icon_ours = !!(x) #define IS_ICON_SHAPED(fw) \ ((fw)->flags.is_icon_shaped) #define SET_ICON_SHAPED(fw,x) \ (fw)->flags.is_icon_shaped = !!(x) #define SETM_ICON_SHAPED(fw,x) \ (fw)->flag_mask.is_icon_shaped = !!(x) #define IS_ICON_MOVED(fw) \ ((fw)->flags.is_icon_moved) #define SET_ICON_MOVED(fw,x) \ (fw)->flags.is_icon_moved = !!(x) #define SETM_ICON_MOVED(fw,x) \ (fw)->flag_mask.is_icon_moved = !!(x) #define IS_ICON_UNMAPPED(fw) \ ((fw)->flags.is_icon_unmapped) #define SET_ICON_UNMAPPED(fw,x) \ (fw)->flags.is_icon_unmapped = !!(x) #define SETM_ICON_UNMAPPED(fw,x) \ (fw)->flag_mask.is_icon_unmapped = !!(x) #define IS_IN_TRANSIENT_SUBTREE(fw) \ ((fw)->flags.is_in_transient_subtree) #define SET_IN_TRANSIENT_SUBTREE(fw,x) \ (fw)->flags.is_in_transient_subtree = !!(x) #define IS_MAP_PENDING(fw) \ ((fw)->flags.is_map_pending) #define SET_MAP_PENDING(fw,x) \ (fw)->flags.is_map_pending = !!(x) #define SETM_MAP_PENDING(fw,x) \ (fw)->flag_mask.is_map_pending = !!(x) #define IS_MAXIMIZED(fw) \ ((fw)->flags.is_maximized) #define SET_MAXIMIZED(fw,x) \ (fw)->flags.is_maximized = !!(x) #define SETM_MAXIMIZED(fw,x) \ (fw)->flag_mask.is_maximized = !!(x) #define IS_NAME_CHANGED(fw) \ ((fw)->flags.is_name_changed) #define SET_NAME_CHANGED(fw,x) \ (fw)->flags.is_name_changed = !!(x) #define SETM_NAME_CHANGED(fw,x) \ (fw)->flag_mask.is_name_changed = !!(x) #define IS_PIXMAP_OURS(fw) \ ((fw)->flags.is_pixmap_ours) #define SET_PIXMAP_OURS(fw,x) \ (fw)->flags.is_pixmap_ours = !!(x) #define SETM_PIXMAP_OURS(fw,x) \ (fw)->flag_mask.is_pixmap_ours = !!(x) #define IS_PLACED_BY_FVWM(fw) \ ((fw)->flags.is_placed_by_fvwm) #define SET_PLACED_BY_FVWM(fw,x) \ (fw)->flags.is_placed_by_fvwm = (x) #define SETM_PLACED_BY_FVWM(fw,x) \ (fw)->flag_mask.is_placed_by_fvwm = (x) #define IS_SCHEDULED_FOR_DESTROY(fw) \ ((fw)->flags.is_scheduled_for_destroy) #define SET_SCHEDULED_FOR_DESTROY(fw,x) \ (fw)->flags.is_scheduled_for_destroy = !!(x) #define IS_SCHEDULED_FOR_RAISE(fw) \ ((fw)->flags.is_scheduled_for_raise) #define SET_SCHEDULED_FOR_RAISE(fw,x) \ (fw)->flags.is_scheduled_for_raise = !!(x) #define IS_SHADED(fw) \ ((fw)->flags.is_window_shaded) #define USED_TITLE_DIR_FOR_SHADING(fw) \ ((fw)->flags.used_title_dir_for_shading) #define SET_USED_TITLE_DIR_FOR_SHADING(fw,x) \ ((fw)->flags.used_title_dir_for_shading = !!(x)) #define SHADED_DIR(fw) \ ((fw)->flags.shaded_dir) #define SET_SHADED(fw,x) \ (fw)->flags.is_window_shaded = !!(x) #define SET_SHADED_DIR(fw,x) \ (fw)->flags.shaded_dir = (x) #define SETM_SHADED(fw,x) \ (fw)->flag_mask.is_window_shaded = !!(x) #define IS_TEAR_OFF_MENU(fw) \ ((fw)->flags.is_tear_off_menu) #define SET_TEAR_OFF_MENU(fw,x) \ (fw)->flags.is_tear_off_menu = !!(x) #define SETM_TEAR_OFF_MENU(fw,x) \ (fw)->flag_mask.is_tear_off_menu = !!(x) #define IS_TRANSIENT(fw) \ ((fw)->flags.is_transient) #define SET_TRANSIENT(fw,x) \ (fw)->flags.is_transient = !!(x) #define SETM_TRANSIENT(fw,x) \ (fw)->flag_mask.is_transient = !!(x) #define IS_ICONIFY_PENDING(fw) \ ((fw)->flags.is_iconify_pending) #define SET_ICONIFY_PENDING(fw,x) \ (fw)->flags.is_iconify_pending = !!(x) #define SETM_ICONIFY_PENDING(fw,x) \ (fw)->flag_mask.is_iconify_pending = !!(x) #define DO_ICONIFY_AFTER_MAP(fw) \ ((fw)->flags.do_iconify_after_map) #define SET_ICONIFY_AFTER_MAP(fw,x) \ (fw)->flags.do_iconify_after_map = !!(x) #define SETM_ICONIFY_AFTER_MAP(fw,x) \ (fw)->flag_mask.do_iconify_after_map = !!(x) #define DO_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw) \ ((fw)->flags.do_disable_constrain_size_fullscreen) #define SET_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw,x) \ (fw)->flags.do_disable_constrain_size_fullscreen = !!(x) #define SETM_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw,x) \ (fw)->flag_mask.do_disable_constrain_size_fullscreen = !!(x) #define IS_SIZE_INC_SET(fw) \ ((fw)->flags.is_size_inc_set) #define SET_SIZE_INC_SET(fw,x) \ (fw)->flags.is_size_inc_set = !!(x) #define SETM_SIZE_INC_SET(fw,x) \ (fw)->flag_mask.is_size_inc_set = !!(x) #define IS_STYLE_DELETED(fw) \ ((fw)->flags.is_style_deleted) #define SET_STYLE_DELETED(fw,x) \ (fw)->flags.is_style_deleted = !!(x) #define SETM_STYLE_DELETED(fw,x) \ (fw)->flag_mask.is_style_deleted = !!(x) #define IS_VIEWPORT_MOVED(fw) \ ((fw)->flags.is_viewport_moved) #define SET_VIEWPORT_MOVED(fw,x) \ (fw)->flags.is_viewport_moved = !!(x) #define SETM_VIEWPORT_MOVED(fw,x) \ (fw)->flag_mask.is_viewport_moved = !!(x) #define IS_VIEWPORT_MOVED(fw) \ ((fw)->flags.is_viewport_moved) #define IS_FOCUS_CHANGE_BROADCAST_PENDING(fw) \ ((fw)->flags.is_focus_change_broadcast_pending) #define SET_FOCUS_CHANGE_BROADCAST_PENDING(fw,x) \ (fw)->flags.is_focus_change_broadcast_pending = !!(x) #define SETM_FOCUS_CHANGE_BROADCAST_PENDING(fw,x) \ (fw)->flag_mask.is_focus_change_broadcast_pending = !!(x) #define IS_FULLY_VISIBLE(fw) \ ((fw)->flags.is_fully_visible) #define SET_FULLY_VISIBLE(fw,x) \ (fw)->flags.is_fully_visible = !!(x) #define SETM_FULLY_VISIBLE(fw,x) \ (fw)->flag_mask.is_fully_visible = !!(x) #define IS_PARTIALLY_VISIBLE(fw) \ ((fw)->flags.is_partially_visible) #define SET_PARTIALLY_VISIBLE(fw,x) \ (fw)->flags.is_partially_visible = !!(x) #define SETM_PARTIALLY_VISIBLE(fw,x) \ (fw)->flag_mask.is_partially_visible = !!(x) #define IS_WINDOW_DRAWN_ONCE(fw) \ ((fw)->flags.is_window_drawn_once) #define SET_WINDOW_DRAWN_ONCE(fw,x) \ (fw)->flags.is_window_drawn_once = !!(x) #define SETM_WINDOW_DRAWN_ONCE(fw,x) \ (fw)->flag_mask.is_window_drawn_once = !!(x) #define IS_WINDOW_BEING_MOVED_OPAQUE(fw) \ ((fw)->flags.is_window_being_moved_opaque) #define SET_WINDOW_BEING_MOVED_OPAQUE(fw,x) \ (fw)->flags.is_window_being_moved_opaque = !!(x) #define SETM_WINDOW_BEING_MOVED_OPAQUE(fw,x) \ (fw)->flag_mask.is_window_being_moved_opaque = !!(x) #define IS_WINDOW_BORDER_DRAWN(fw) \ ((fw)->flags.is_window_border_drawn) #define SET_WINDOW_BORDER_DRAWN(fw,x) \ (fw)->flags.is_window_border_drawn = !!(x) #define SETM_WINDOW_BORDER_DRAWN(fw,x) \ (fw)->flag_mask.is_window_border_drawn = !!(x) #define IS_WINDOW_FONT_LOADED(fw) \ ((fw)->flags.is_window_font_loaded) #define SET_WINDOW_FONT_LOADED(fw,x) \ (fw)->flags.is_window_font_loaded = !!(x) #define SETM_WINDOW_FONT_LOADED(fw,x) \ (fw)->flag_mask.is_window_font_loaded = !!(x) #define CR_MOTION_METHOD(fw) \ ((fw)->flags.cr_motion_method) #define SET_CR_MOTION_METHOD(fw,x) \ (fw)->flags.cr_motion_method = ((x) & CR_MOTION_METHOD_MASK) #define SETM_CR_MOTION_METHOD(fw,x) \ (fw)->flag_mask.cr_motion_method = ((x) ? CR_MOTION_METHOD_MASK : 0) #define WAS_CR_MOTION_METHOD_DETECTED(fw) \ ((fw)->flags.was_cr_motion_method_detected) #define SET_CR_MOTION_METHOD_DETECTED(fw,x) \ (fw)->flags.was_cr_motion_method_detected = !!(x) #define SETM_CR_MOTION_METHOD_DETECTED(fw,x) \ (fw)->flag_mask.was_cr_motion_method_detected = !!(x) #define WM_DELETES_WINDOW(fw) \ ((fw)->flags.does_wm_delete_window) #define SET_WM_DELETES_WINDOW(fw,x) \ (fw)->flags.does_wm_delete_window = !!(x) #define SETM_WM_DELETES_WINDOW(fw,x) \ (fw)->flag_mask.does_wm_delete_window = !!(x) #define WM_TAKES_FOCUS(fw) \ ((fw)->flags.does_wm_take_focus) #define SET_WM_TAKES_FOCUS(fw,x) \ (fw)->flags.does_wm_take_focus = !!(x) #define SETM_WM_TAKES_FOCUS(fw,x) \ (fw)->flag_mask.does_wm_take_focus = !!(x) #define DO_FORCE_NEXT_CR(fw) \ ((fw)->flags.do_force_next_cr) #define SET_FORCE_NEXT_CR(fw,x) \ (fw)->flags.do_force_next_cr = !!(x) #define SETM_FORCE_NEXT_CR(fw,x) \ (fw)->flag_mask.do_force_next_cr = !!(x) #define DO_FORCE_NEXT_PN(fw) \ ((fw)->flags.do_force_next_pn) #define SET_FORCE_NEXT_PN(fw,x) \ (fw)->flags.do_force_next_pn = !!(x) #define SETM_FORCE_NEXT_PN(fw,x) \ (fw)->flag_mask.do_force_next_pn = !!(x) #define USING_DEFAULT_WINDOW_FONT(fw) \ ((fw)->flags.using_default_window_font) #define SET_USING_DEFAULT_WINDOW_FONT(fw,x) \ (fw)->flags.using_default_window_font = !!(x) #define SETM_USING_DEFAULT_WINDOW_FONT(fw,x) \ (fw)->flag_mask.using_default_window_font = !!(x) #define USING_DEFAULT_ICON_FONT(fw) \ ((fw)->flags.using_default_icon_font) #define SET_USING_DEFAULT_ICON_FONT(fw,x) \ (fw)->flags.using_default_icon_font = !!(x) #define SETM_USING_DEFAULT_ICON_FONT(fw,x) \ (fw)->flag_mask.using_default_icon_font = !!(x) #define WAS_ICON_HINT_PROVIDED(fw) \ ((fw)->flags.was_icon_hint_provided) #define SET_WAS_ICON_HINT_PROVIDED(fw,x) \ (fw)->flags.was_icon_hint_provided = (x) #define SETM_WAS_ICON_HINT_PROVIDED(fw,x) \ (fw)->flag_mask.was_icon_hint_provided = (x) #define WAS_ICON_NAME_PROVIDED(fw) \ ((fw)->flags.was_icon_name_provided) #define SET_WAS_ICON_NAME_PROVIDED(fw,x) \ (fw)->flags.was_icon_name_provided = (x) #define SETM_WAS_ICON_NAME_PROVIDED(fw,x) \ (fw)->flag_mask.was_icon_name_provided = (x) #define WAS_NEVER_DRAWN(fw) \ ((fw)->flags.was_never_drawn) #define SET_WAS_NEVER_DRAWN(fw,x) \ (fw)->flags.was_never_drawn = (x) #define SETM_WAS_NEVER_DRAWN(fw,x) \ (fw)->flag_mask.was_never_drawn = (x) #define HAS_EWMH_WM_NAME(fw) \ ((fw)->flags.has_ewmh_wm_name) #define SET_HAS_EWMH_WM_NAME(fw,x) \ (fw)->flags.has_ewmh_wm_name = !!(x) #define SETM_HAS_EWMH_WM_NAME(fw,x) \ (fw)->flag_mask.has_ewmh_wm_name = !!(x) #define HAS_EWMH_WM_ICON_NAME(fw) \ ((fw)->flags.has_ewmh_wm_icon_name) #define SET_HAS_EWMH_WM_ICON_NAME(fw,x) \ (fw)->flags.has_ewmh_wm_icon_name = !!(x) #define SETM_HAS_EWMH_WM_ICON_NAME(fw,x) \ (fw)->flag_mask.has_ewmh_wm_icon_name = !!(x) #define HAS_EWMH_WM_ICON_HINT(fw) \ ((fw)->flags.has_ewmh_wm_icon_hint) #define SET_HAS_EWMH_WM_ICON_HINT(fw,x) \ (fw)->flags.has_ewmh_wm_icon_hint = (x) #define SETM_HAS_EWMH_WM_ICON_HINT(fw,x) \ (fw)->flag_mask.has_ewmh_wm_icon_hint = (x) #define USE_EWMH_ICON(fw) \ ((fw)->flags.use_ewmh_icon) #define SET_USE_EWMH_ICON(fw,x) \ (fw)->flags.use_ewmh_icon = !!(x) #define SETM_USE_EWMH_ICON(fw,x) \ (fw)->flag_mask.use_ewmh_icon = !!(x) #define HAS_EWMH_MINI_ICON(fw) \ ((fw)->flags.has_ewmh_mini_icon) #define SET_HAS_EWMH_MINI_ICON(fw,x) \ (fw)->flags.has_ewmh_mini_icon = !!(x) #define SETM_HAS_EWMH_MINI_ICON(fw,x) \ (fw)->flag_mask.has_ewmh_mini_icon = !!(x) #define HAS_EWMH_WM_PID(fw) \ ((fw)->flags.has_ewmh_wm_pid) #define SET_HAS_EWMH_WM_PID(fw,x) \ (fw)->flags.has_ewmh_wm_pid = !!(x) #define SETM_HAS_EWMH_WM_PID(fw,x) \ (fw)->flag_mask.has_ewmh_wm_pid = !!(x) #define IS_EWMH_MODAL(fw) \ ((fw)->flags.is_ewmh_modal) #define SET_EWMH_MODAL(fw,x) \ (fw)->flags.is_ewmh_modal = !!(x) #define SETM_EWMH_MODAL(fw,x) \ (fw)->flag_mask.is_ewmh_modal = !!(x) #define IS_EWMH_FULLSCREEN(fw) \ ((fw)->flags.is_ewmh_fullscreen) #define SET_EWMH_FULLSCREEN(fw,x) \ (fw)->flags.is_ewmh_fullscreen = !!(x) #define SETM_EWMH_FULLSCREEN(fw,x) \ (fw)->flag_mask.is_ewmh_fullscreen = !!(x) #define SET_HAS_EWMH_INIT_FULLSCREEN_STATE(fw,x) \ (fw)->flags.has_ewmh_init_fullscreen_state = (x) #define SETM_HAS_EWMH_INIT_FULLSCREEN_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_fullscreen_state = (x) #define HAS_EWMH_INIT_FULLSCREEN_STATE(fw) \ ((fw)->flags.has_ewmh_init_fullscreen_state) #define SET_HAS_EWMH_INIT_HIDDEN_STATE(fw,x) \ (fw)->flags.has_ewmh_init_hidden_state = (x) #define SETM_HAS_EWMH_INIT_HIDDEN_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_hidden_state = (x) #define HAS_EWMH_INIT_HIDDEN_STATE(fw) \ ((fw)->flags.has_ewmh_init_hidden_state) #define SET_HAS_EWMH_INIT_MAXHORIZ_STATE(fw,x) \ (fw)->flags.has_ewmh_init_maxhoriz_state = (x) #define SETM_HAS_EWMH_INIT_MAXHORIZ_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_maxhoriz_state = (x) #define HAS_EWMH_INIT_MAXHORIZ_STATE(fw) \ ((fw)->flags.has_ewmh_init_maxhoriz_state) #define SET_HAS_EWMH_INIT_MAXVERT_STATE(fw,x) \ (fw)->flags.has_ewmh_init_maxvert_state = (x) #define SETM_HAS_EWMH_INIT_MAXVERT_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_maxvert_state = (x) #define HAS_EWMH_INIT_MAXVERT_STATE(fw) \ ((fw)->flags.has_ewmh_init_maxvert_state) #define SET_HAS_EWMH_INIT_MODAL_STATE(fw,x) \ (fw)->flags.has_ewmh_init_modal_state = (x) #define SETM_HAS_EWMH_INIT_MODAL_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_modal_state = (x) #define HAS_EWMH_INIT_MODAL_STATE(fw) \ ((fw)->flags.has_ewmh_init_modal_state) #define SET_HAS_EWMH_INIT_SHADED_STATE(fw,x) \ (fw)->flags.has_ewmh_init_shaded_state = (x) #define SETM_HAS_EWMH_INIT_SHADED_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_shaded_state = (x) #define HAS_EWMH_INIT_SHADED_STATE(fw) \ ((fw)->flags.has_ewmh_init_shaded_state) #define SET_HAS_EWMH_INIT_SKIP_PAGER_STATE(fw,x) \ (fw)->flags.has_ewmh_init_skip_pager_state = (x) #define SETM_HAS_EWMH_INIT_SKIP_PAGER_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_skip_pager_state = (x) #define HAS_EWMH_INIT_SKIP_PAGER_STATE(fw) \ ((fw)->flags.has_ewmh_init_skip_pager_state) #define SET_HAS_EWMH_INIT_SKIP_TASKBAR_STATE(fw,x) \ (fw)->flags.has_ewmh_init_skip_taskbar_state = (x) #define SETM_HAS_EWMH_INIT_SKIP_TASKBAR_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_skip_taskbar_state = (x) #define HAS_EWMH_INIT_SKIP_TASKBAR_STATE(fw) \ ((fw)->flags.has_ewmh_init_skip_taskbar_state) #define SET_HAS_EWMH_INIT_STICKY_STATE(fw,x) \ (fw)->flags.has_ewmh_init_sticky_state = (x) #define SETM_HAS_EWMH_INIT_STICKY_STATE(fw,x) \ (fw)->flag_mask.has_ewmh_init_sticky_state = (x) #define HAS_EWMH_INIT_STICKY_STATE(fw) \ ((fw)->flags.has_ewmh_init_sticky_state) #define SET_HAS_EWMH_INIT_WM_DESKTOP(fw,x) \ (fw)->flags.has_ewmh_init_wm_desktop = (x) #define SETM_HAS_EWMH_INIT_WM_DESKTOP(fw,x) \ (fw)->flag_mask.has_ewmh_init_wm_desktop = (x) #define HAS_EWMH_INIT_WM_DESKTOP(fw) \ ((fw)->flags.has_ewmh_init_wm_desktop) #endif /* _WINDOW_FLAGS_ */ fvwm-2.6.7/fvwm/menucmd.c0000644000175700017570000001564412773467232012246 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* IMPORTANT NOTE: Do *not* use any constant numbers in this file. All values * have to be #defined in the section below or defaults.h to ensure full * control over the menus. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "functions.h" #include "repeat.h" #include "misc.h" #include "move_resize.h" #include "screen.h" #include "menus.h" #include "menudim.h" #include "menuroot.h" #include "menustyle.h" #include "menuparameters.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void menu_func(F_CMD_ARGS, Bool fStaysUp) { struct MenuRoot *menu; char *ret_action = NULL; struct MenuOptions mops; char *menu_name = NULL; struct MenuParameters mp; struct MenuReturn mret; FvwmWindow * const fw = exc->w.fw; const Window w = exc->w.w; const exec_context_t *exc2; memset(&mops, 0, sizeof(mops)); memset(&mret, 0, sizeof(MenuReturn)); action = GetNextToken(action,&menu_name); action = get_menu_options( action, w, fw, NULL, NULL, NULL, &mops); while (action && *action && isspace((unsigned char)*action)) { action++; } if (action && *action == 0) { action = NULL; } menu = menus_find_menu(menu_name); if (menu == NULL) { if (menu_name) { fvwm_msg(ERR,"menu_func","No such menu %s",menu_name); free(menu_name); } return; } if (menu_name && set_repeat_data( menu_name, (fStaysUp) ? REPEAT_MENU : REPEAT_POPUP,NULL)) { free(menu_name); } memset(&mp, 0, sizeof(mp)); mp.menu = menu; exc2 = exc_clone_context(exc, NULL, 0); mp.pexc = &exc2; MR_IS_TEAR_OFF_MENU(menu) = 0; mp.flags.has_default_action = (action != NULL); mp.flags.is_sticky = fStaysUp; mp.flags.is_submenu = False; mp.flags.is_already_mapped = False; mp.flags.is_triggered_by_keypress = (exc->x.etrigger->type == KeyPress); mp.pops = &mops; mp.ret_paction = &ret_action; do_menu(&mp, &mret); if (mret.rc == MENU_DOUBLE_CLICKED && action) { execute_function(cond_rc, exc2, action, 0); } if (ret_action != NULL) { free(ret_action); } exc_destroy_context(exc2); return; } /* ---------------------------- interface functions ------------------------ */ /* ---------------------------- builtin commands --------------------------- */ /* the function for the "Popup" command */ void CMD_Popup(F_CMD_ARGS) { menu_func(F_PASS_ARGS, False); return; } /* the function for the "Menu" command */ void CMD_Menu(F_CMD_ARGS) { menu_func(F_PASS_ARGS, True); return; } void CMD_AddToMenu(F_CMD_ARGS) { MenuRoot *mr; MenuRoot *mrPrior; char *token, *rest,*item; token = PeekToken(action, &rest); if (!token) { return; } mr = menus_find_menu(token); if (mr && MR_MAPPED_COPIES(mr) != 0) { fvwm_msg(ERR,"add_item_to_menu", "menu %s is in use", token); return; } mr = FollowMenuContinuations(menus_find_menu(token), &mrPrior); if (mr == NULL) { mr = NewMenuRoot(token); } /* Set + state to last menu */ set_last_added_item(ADDED_MENU, mr); rest = GetNextToken(rest, &item); AddToMenu(mr, item, rest, True /* pixmap scan */, True, False); if (item) { free(item); } return; } void CMD_DestroyMenu(F_CMD_ARGS) { MenuRoot *mr; MenuRoot *mrContinuation; Bool do_recreate = False; char *token; token = PeekToken(action, &action); if (!token) { return; } if (StrEquals(token, "recreate")) { do_recreate = True; token = PeekToken(action, NULL); } mr = menus_find_menu(token); if (Scr.last_added_item.type == ADDED_MENU) { set_last_added_item(ADDED_NONE, NULL); } while (mr) { /* save continuation before destroy */ mrContinuation = MR_CONTINUATION_MENU(mr); if (!DestroyMenu(mr, do_recreate, True)) { return; } /* Don't recreate the continuations */ do_recreate = False; mr = mrContinuation; } return; } void CMD_DestroyMenuStyle(F_CMD_ARGS) { MenuStyle *ms = NULL; char *name = NULL; name = PeekToken(action, NULL); if (name == NULL) { fvwm_msg(ERR,"DestroyMenuStyle", "needs one parameter"); return; } ms = menustyle_find(name); if (ms == NULL) { return; } else if (ms == menustyle_get_default_style()) { fvwm_msg(ERR,"DestroyMenuStyle", "cannot destroy default menu style. " "To reset the default menu style use\n %s", DEFAULT_MENU_STYLE); return; } else if (ST_USAGE_COUNT(ms) != 0) { fvwm_msg(ERR, "DestroyMenuStyle", "menu style %s is in use", name); return; } else { menustyle_free(ms); } menus_remove_style_from_menus(ms); return; } void CMD_ChangeMenuStyle(F_CMD_ARGS) { char *name = NULL; char *menuname = NULL; MenuStyle *ms = NULL; MenuRoot *mr = NULL; name = PeekToken(action, &action); if (name == NULL) { fvwm_msg(ERR,"ChangeMenuStyle", "needs at least two parameters"); return; } ms = menustyle_find(name); if (ms == NULL) { fvwm_msg(ERR,"ChangeMenuStyle", "cannot find style %s", name); return; } menuname = PeekToken(action, &action); while (menuname && *menuname) { mr = menus_find_menu(menuname); if (mr == NULL) { fvwm_msg(ERR, "ChangeMenuStyle", "cannot find menu %s", menuname); break; } if (MR_MAPPED_COPIES(mr) != 0) { fvwm_msg(ERR, "ChangeMenuStyle", "menu %s is in use", menuname); } else { MR_STYLE(mr) = ms; MR_IS_UPDATED(mr) = 1; } menuname = PeekToken(action, &action); } return; } fvwm-2.6.7/fvwm/icons.h0000644000175700017570000000157712773467232011736 00000000000000/* -*-c-*- */ #ifndef _ICONS_ #define _ICONS_ #ifdef NO_ICONS #define ICON_HEIGHT(t) 1 #else #define ICON_HEIGHT(t) \ ((t)->icon_font->height + 2*abs((t)->icon_title_relief)) #endif int get_visible_icon_window_count(FvwmWindow *fw); void clear_icon(FvwmWindow *fw); void setup_icon_title_size(FvwmWindow *fw); void GetIconPicture(FvwmWindow *fw, Bool no_icon_window); void AutoPlaceIcon( FvwmWindow *t, initial_window_options_t *win_opts, Bool do_move_immediately); void ChangeIconPixmap(FvwmWindow *fw); void RedoIconName(FvwmWindow *fw); void DrawIconWindow( FvwmWindow *fw, Bool draw_title, Bool draw_pixmap, Bool focus_change, Bool reset_bg, XEvent *pev); void CreateIconWindow(FvwmWindow *fw, int def_x, int def_y); void Iconify(FvwmWindow *fw, initial_window_options_t *win_opts); void DeIconify(FvwmWindow *); void SetMapStateProp(const FvwmWindow *, int); #endif /* _ICONS_ */ fvwm-2.6.7/fvwm/focus.c0000644000175700017570000006577512773467232011747 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/ClientMsg.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "eventhandler.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "focus.h" #include "borders.h" #include "frame.h" #include "virtual.h" #include "stack.h" #include "geometry.h" #include "colormaps.h" #include "add_window.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { unsigned do_allow_force_broadcast : 1; unsigned do_forbid_warp : 1; unsigned do_force : 1; unsigned is_focus_by_flip_focus_cmd : 1; unsigned client_entered : 1; fpol_set_focus_by_t set_by; } sftfwin_args_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Bool lastFocusType; /* Last window which Fvwm gave the focus to NOT the window that really has the * focus */ static FvwmWindow *ScreenFocus = NULL; /* Window which had focus before the pointer moved to a different screen. */ static FvwmWindow *LastScreenFocus = NULL; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void _focus_set(Window w, FvwmWindow *fw) { Scr.focus_in_requested_window = fw; XSetInputFocus(dpy, w, RevertToParent, CurrentTime); return; } void _focus_reset(void) { Scr.focus_in_requested_window = NULL; XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); return; } /* ---------------------------- local functions ---------------------------- */ static Bool focus_get_fpol_context_flag( fpol_context_t *fpol_context, int context) { int flag; switch (context) { case C_WINDOW: case C_EWMH_DESKTOP: flag = fpol_context->client; break; case C_ICON: flag = fpol_context->icon; break; default: flag = fpol_context->decor; break; } return (flag) ? True : False; } /* * Helper functions for setting the focus */ static void __try_program_focus(Window w, const FvwmWindow *fw) { if (fw && WM_TAKES_FOCUS(fw) && FP_DO_FOCUS_BY_PROGRAM(FW_FOCUS_POLICY(fw))) { send_clientmessage(dpy, w, _XA_WM_TAKE_FOCUS, fev_get_evtime()); } return; } static Bool __try_forbid_user_focus( Window w, FvwmWindow *fw) { if (fw == NULL || fpol_query_allow_user_focus(&FW_FOCUS_POLICY(fw)) == True) { return False; } if (WM_TAKES_FOCUS(fw)) { /* give it a chance to take the focus itself */ __try_program_focus(w, fw); XFlush(dpy); } else { /* make sure the window is not hilighted */ border_draw_decorations( fw, PART_ALL, False, False, CLEAR_ALL, NULL, NULL); } return True; } static Bool __check_allow_focus( Window w, FvwmWindow *fw, fpol_set_focus_by_t set_by) { FvwmWindow *sf; if (fw == NULL || set_by == FOCUS_SET_FORCE) { /* always allow to delete focus */ return True; } sf = get_focus_window(); if (!FP_IS_LENIENT(FW_FOCUS_POLICY(fw)) && !focus_does_accept_input_focus(fw) && sf != NULL && sf->Desk == Scr.CurrentDesk) { /* window does not want focus */ return False; } if (fpol_query_allow_set_focus(&FW_FOCUS_POLICY(fw), set_by)) { return True; } return False; } static void __update_windowlist( FvwmWindow *fw, fpol_set_focus_by_t set_by, int is_focus_by_flip_focus_cmd) { lastFocusType = (is_focus_by_flip_focus_cmd) ? True : False; if (fw == NULL || focus_is_focused(fw) || fw == &Scr.FvwmRoot || IS_SCHEDULED_FOR_DESTROY(fw)) { return; } /* Watch out: fw may not be on the windowlist and the windowlist may be * empty */ if (!is_focus_by_flip_focus_cmd && (FP_DO_SORT_WINDOWLIST_BY(FW_FOCUS_POLICY(fw)) == FPOL_SORT_WL_BY_OPEN || set_by == FOCUS_SET_BY_FUNCTION)) { /* move the windowlist around so that fw is at the top */ FvwmWindow *fw2; /* find the window on the windowlist */ for (fw2 = &Scr.FvwmRoot; fw2 && fw2 != fw; fw2 = fw2->next) { /* nothing */ } if (fw2) { /* the window is on the (non-zero length) windowlist */ /* make fw2 point to the last window on the list */ while (fw2->next) { fw2 = fw2->next; } /* close the ends of the windowlist */ fw2->next = Scr.FvwmRoot.next; Scr.FvwmRoot.next->prev = fw2; /* make fw the new start of the list */ Scr.FvwmRoot.next = fw; /* open the closed loop windowlist */ fw->prev->next = NULL; fw->prev = &Scr.FvwmRoot; } } else { /* pluck window from list and deposit at top */ /* remove fw from list */ if (fw->prev) { fw->prev->next = fw->next; } if (fw->next) { fw->next->prev = fw->prev; } /* insert fw at start */ fw->next = Scr.FvwmRoot.next; if (Scr.FvwmRoot.next) { Scr.FvwmRoot.next->prev = fw; } Scr.FvwmRoot.next = fw; fw->prev = &Scr.FvwmRoot; } return; } static Bool __try_other_screen_focus(const FvwmWindow *fw) { if (fw == NULL && !Scr.flags.is_pointer_on_this_screen) { FvwmWindow *sf; sf = get_focus_window(); set_focus_window(NULL); if (sf != NULL) { focus_grab_buttons(sf); } /* DV (25-Nov-2000): Don't give the Scr.NoFocusWin the focus * here. This would steal the focus from the other screen's * root window again. */ return True; } return False; } /* * Sets the input focus to the indicated window. */ static void __set_focus_to_fwin( Window w, FvwmWindow *fw, sftfwin_args_t *args) { FvwmWindow *sf; if (__try_forbid_user_focus(w, fw) == True) { return; } __try_program_focus(w, fw); if (__check_allow_focus(w, fw, args->set_by) == False) { return; } __update_windowlist(fw, args->set_by, args->is_focus_by_flip_focus_cmd); if (__try_other_screen_focus(fw) == True) { return; } if (fw && !args->do_forbid_warp) { if (IS_ICONIFIED(fw)) { rectangle r; Bool rc; rc = get_visible_icon_geometry(fw, &r); if (!rc || !IsRectangleOnThisPage(&r, fw->Desk)) { fw = NULL; w = Scr.NoFocusWin; } } else if (!IsRectangleOnThisPage(&(fw->g.frame), fw->Desk)) { fw = NULL; w = Scr.NoFocusWin; } } sf = get_focus_window(); if (fw == NULL) { FOCUS_SET(Scr.NoFocusWin, NULL); set_focus_window(NULL); Scr.UnknownWinFocused = None; XFlush(dpy); return; } /* RBW - allow focus to go to a NoIconTitle icon window so * auto-raise will work on it. */ if (IS_ICONIFIED(fw)) { Bool is_window_selected = False; if (FW_W_ICON_TITLE(fw)) { w = FW_W_ICON_TITLE(fw); is_window_selected = True; } if ((!is_window_selected || WAS_ICON_HINT_PROVIDED(fw)) && FW_W_ICON_PIXMAP(fw)) { w = FW_W_ICON_PIXMAP(fw); } } if (FP_IS_LENIENT(FW_FOCUS_POLICY(fw))) { FOCUS_SET(w, fw); set_focus_window(fw); if (args->do_allow_force_broadcast) { SET_FOCUS_CHANGE_BROADCAST_PENDING(fw, 1); } Scr.UnknownWinFocused = None; } else if (focus_does_accept_input_focus(fw)) { /* Window will accept input focus */ if (Scr.StolenFocusWin == w && Scr.UnknownWinFocused != None) { /* Without this FocusIn is not generated on the * window if it was focuesed when the unmanaged * window took focus. */ FOCUS_SET(Scr.NoFocusWin, NULL); } FOCUS_SET(w, fw); set_focus_window(fw); if (fw) { if (args->do_allow_force_broadcast) { SET_FOCUS_CHANGE_BROADCAST_PENDING(fw, 1); } } Scr.UnknownWinFocused = None; } else if (sf && sf->Desk == Scr.CurrentDesk) { /* Window doesn't want focus. Leave focus alone */ } else { FOCUS_SET(Scr.NoFocusWin, NULL); set_focus_window(NULL); } XFlush(dpy); return; } static void set_focus_to_fwin( Window w, FvwmWindow *fw, sftfwin_args_t *args) { FvwmWindow *sf; sf = get_focus_window(); if (!args->do_force && fw == sf) { focus_grab_buttons(sf); return; } __set_focus_to_fwin(w, fw, args); /* Make sure the button grabs on the new and the old focused windows * are up to date. */ if (args->client_entered) { focus_grab_buttons_client_entered(fw); } else { focus_grab_buttons(fw); } /* RBW -- don't call this twice for the same window! */ if (fw != get_focus_window()) { if (args->client_entered) { focus_grab_buttons_client_entered(get_focus_window()); } else { focus_grab_buttons(get_focus_window()); } } return; } /* * * Moves pointer to specified window * */ static void warp_to_fvwm_window( const exec_context_t *exc, int warp_x, int x_unit, int warp_y, int y_unit, int do_raise) { int dx,dy; int cx,cy; int x,y; FvwmWindow *t = exc->w.fw; if (t == (FvwmWindow *)0 || (IS_ICONIFIED(t) && FW_W_ICON_TITLE(t) == None)) { return; } if (t->Desk != Scr.CurrentDesk) { goto_desk(t->Desk); } if (IS_ICONIFIED(t)) { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(t, &g); if (rc == False) { get_visible_icon_picture_geometry(t, &g); } cx = g.x + g.width / 2; cy = g.y + g.height / 2; } else { cx = t->g.frame.x + t->g.frame.width/2; cy = t->g.frame.y + t->g.frame.height/2; } dx = (cx + Scr.Vx) / Scr.MyDisplayWidth * Scr.MyDisplayWidth; dy = (cy + Scr.Vy) / Scr.MyDisplayHeight * Scr.MyDisplayHeight; if (dx != Scr.Vx || dy != Scr.Vy) { MoveViewport(dx, dy, True); } if (IS_ICONIFIED(t)) { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(t, &g); if (rc == False) { get_visible_icon_picture_geometry(t, &g); } x = g.x + g.width / 2; y = g.y + g.height / 2; } else { if (x_unit != Scr.MyDisplayWidth && warp_x >= 0) { x = t->g.frame.x + warp_x; } else if (x_unit != Scr.MyDisplayWidth) { x = t->g.frame.x + t->g.frame.width + warp_x; } else if (warp_x >= 0) { x = t->g.frame.x + (t->g.frame.width - 1) * warp_x / 100; } else { x = t->g.frame.x + (t->g.frame.width - 1) * (100 + warp_x) / 100; } if (y_unit != Scr.MyDisplayHeight && warp_y >= 0) { y = t->g.frame.y + warp_y; } else if (y_unit != Scr.MyDisplayHeight) { y = t->g.frame.y + t->g.frame.height + warp_y; } else if (warp_y >= 0) { y = t->g.frame.y + (t->g.frame.height - 1) * warp_y / 100; } else { y = t->g.frame.y + (t->g.frame.height - 1) * (100 + warp_y) / 100; } } FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, 0, 0, x, y); if (do_raise) { RaiseWindow(t, False); } /* If the window is still not visible, make it visible! */ if (t->g.frame.x + t->g.frame.width < 0 || t->g.frame.y + t->g.frame.height < 0 || t->g.frame.x >= Scr.MyDisplayWidth || t->g.frame.y >= Scr.MyDisplayHeight) { frame_setup_window( t, 0, 0, t->g.frame.width, t->g.frame.height, False); FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, 0, 0, 2, 2); } return; } static Bool focus_query_grab_buttons(FvwmWindow *fw, Bool client_entered) { Bool flag; Bool is_focused; if (fw->Desk != Scr.CurrentDesk || IS_ICONIFIED(fw)) { return False; } is_focused = focus_is_focused(fw); if (!is_focused && FP_DO_FOCUS_CLICK_CLIENT(FW_FOCUS_POLICY(fw))) { return True; } if (is_on_top_of_layer_and_above_unmanaged(fw)) { return False; } if (is_focused) { flag = FP_DO_RAISE_FOCUSED_CLIENT_CLICK(FW_FOCUS_POLICY(fw)); } else { flag = FP_DO_RAISE_UNFOCUSED_CLIENT_CLICK(FW_FOCUS_POLICY(fw)); } return (flag) ? True : False; } static FvwmWindow *__restore_focus_after_unmap( const FvwmWindow *fw, Bool do_skip_marked_transients) { FvwmWindow *t = NULL; FvwmWindow *set_focus_to = NULL; t = get_transientfor_fvwmwindow(fw); if (t != NULL && FP_DO_RELEASE_FOCUS_TRANSIENT(FW_FOCUS_POLICY(fw)) && !FP_DO_OVERRIDE_RELEASE_FOCUS(FW_FOCUS_POLICY(t)) && t->Desk == fw->Desk && (!do_skip_marked_transients || !IS_IN_TRANSIENT_SUBTREE(t))) { set_focus_to = t; } else if (t == NULL && FP_DO_RELEASE_FOCUS(FW_FOCUS_POLICY(fw))) { for (t = fw->next; t != NULL && set_focus_to == NULL; t = t->next) { if (!FP_DO_OVERRIDE_RELEASE_FOCUS( FW_FOCUS_POLICY(t)) && t->Desk == fw->Desk && !DO_SKIP_CIRCULATE(t) && !(IS_ICONIFIED(t) && (DO_SKIP_ICON_CIRCULATE(t) || IS_ICON_SUPPRESSED(t))) && (!do_skip_marked_transients || !IS_IN_TRANSIENT_SUBTREE(t))) { /* If it is on a different desk we have to look * for another window */ set_focus_to = t; } } } if (set_focus_to && set_focus_to != fw && set_focus_to->Desk == fw->Desk) { /* Don't transfer focus to windows on other desks */ SetFocusWindow(set_focus_to, True, FOCUS_SET_FORCE); } if (focus_is_focused(fw)) { DeleteFocus(True); } return set_focus_to; } /* * * Moves focus to specified window; only to be called bay Focus and FlipFocus * */ static void __activate_window_by_command( F_CMD_ARGS, int is_focus_by_flip_focus_cmd) { int cx; int cy; Bool do_not_warp; sftfwin_args_t sf_args; FvwmWindow * const fw = exc->w.fw; memset(&sf_args, 0, sizeof(sf_args)); sf_args.do_allow_force_broadcast = 1; sf_args.is_focus_by_flip_focus_cmd = is_focus_by_flip_focus_cmd; sf_args.set_by = FOCUS_SET_BY_FUNCTION; sf_args.client_entered = 0; if (fw == NULL || !FP_DO_FOCUS_BY_FUNCTION(FW_FOCUS_POLICY(fw))) { UngrabEm(GRAB_NORMAL); if (fw) { /* give the window a chance to take the focus itself */ sf_args.do_forbid_warp = 1; sf_args.do_force = 0; set_focus_to_fwin(FW_W(fw), fw, &sf_args); } return; } do_not_warp = StrEquals(PeekToken(action, NULL), "NoWarp"); if (!do_not_warp) { if (fw->Desk != Scr.CurrentDesk) { goto_desk(fw->Desk); } if (IS_ICONIFIED(fw)) { rectangle g; Bool rc; rc = get_visible_icon_title_geometry(fw, &g); if (rc == False) { get_visible_icon_picture_geometry(fw, &g); } cx = g.x + g.width / 2; cy = g.y + g.height / 2; } else { cx = fw->g.frame.x + fw->g.frame.width/2; cy = fw->g.frame.y + fw->g.frame.height/2; } if ( cx < 0 || cx >= Scr.MyDisplayWidth || cy < 0 || cy >= Scr.MyDisplayHeight) { int dx; int dy; dx = ((cx + Scr.Vx) / Scr.MyDisplayWidth) * Scr.MyDisplayWidth; dy = ((cy + Scr.Vy) / Scr.MyDisplayHeight) * Scr.MyDisplayHeight; MoveViewport(dx, dy, True); } #if 0 /* can not happen */ /* If the window is still not visible, make it visible! */ if (fw->g.frame.x + fw->g.frame.width < 0 || fw->g.frame.y + fw->g.frame.height < 0 || fw->g.frame.x >= Scr.MyDisplayWidth || fw->g.frame.y >= Scr.MyDisplayHeight) { frame_setup_window( fw, 0, 0, fw->g.frame.width, fw->g.frame.height, False); if ( FP_DO_WARP_POINTER_ON_FOCUS_FUNC( FW_FOCUS_POLICY(fw))) { FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, Scr.Root, 0, 0, 0, 0, 2, 2); } } #endif } UngrabEm(GRAB_NORMAL); if (fw->Desk == Scr.CurrentDesk) { FvwmWindow *sf; sf = get_focus_window(); sf_args.do_forbid_warp = !!do_not_warp; sf_args.do_force = 0; sf_args.client_entered = 0; set_focus_to_fwin(FW_W(fw), fw, &sf_args); if (sf != get_focus_window()) { /* Ignore EnterNotify event while we are waiting for * this window to be focused. */ Scr.focus_in_pending_window = sf; } } return; } static void __focus_grab_one_button( FvwmWindow *fw, int button, int grab_buttons) { Bool do_grab; do_grab = (grab_buttons & (1 << button)); if ((do_grab & (1 << button)) == (fw->grabbed_buttons & (1 << button))) { return; } if (do_grab) { XGrabButton( dpy, button + 1, AnyModifier, FW_W_PARENT(fw), True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); /* Set window flags accordingly as we grab or ungrab. */ fw->grabbed_buttons |= (1 << button); } else { XUngrabButton(dpy, button + 1, AnyModifier, FW_W_PARENT(fw)); fw->grabbed_buttons &= ~(1 << button); } return; } /* ---------------------------- interface functions ------------------------ */ Bool focus_does_accept_input_focus(const FvwmWindow *fw) { return (!fw || !fw->wmhints || !(fw->wmhints->flags & InputHint) || fw->wmhints->input); } Bool focus_is_focused(const FvwmWindow *fw) { return (fw && fw == ScreenFocus); } Bool focus_query_click_to_raise( FvwmWindow *fw, Bool is_focused, int context) { fpol_context_t *c; if (is_focused) { c = &FP_DO_RAISE_FOCUSED_CLICK(FW_FOCUS_POLICY(fw)); } else { c = &FP_DO_RAISE_UNFOCUSED_CLICK(FW_FOCUS_POLICY(fw)); } return focus_get_fpol_context_flag(c, context); } Bool focus_query_click_to_focus( FvwmWindow *fw, int context) { fpol_context_t *c; c = &FP_DO_FOCUS_CLICK(FW_FOCUS_POLICY(fw)); return focus_get_fpol_context_flag(c, context); } /* Takes as input the window that wants the focus and the one that currently * has the focus and returns if the new window should get it. */ Bool focus_query_open_grab_focus(FvwmWindow *fw, FvwmWindow *focus_win) { if (fw == NULL) { return False; } focus_win = get_focus_window(); if (focus_win != NULL && FP_DO_OVERRIDE_GRAB_FOCUS(FW_FOCUS_POLICY(focus_win))) { /* Don't steal the focus from the current window */ return False; } validate_transientfor(fw); if (IS_TRANSIENT(fw) && FW_W_TRANSIENTFOR(fw) != Scr.Root) { if (focus_win != NULL && FP_DO_GRAB_FOCUS_TRANSIENT(FW_FOCUS_POLICY(fw)) && FW_W(focus_win) == FW_W_TRANSIENTFOR(fw)) { /* it's a transient and its transientfor currently has * focus. */ return True; } } else { if (FP_DO_GRAB_FOCUS(FW_FOCUS_POLICY(fw)) && (focus_win == NULL || !FP_DO_OVERRIDE_GRAB_FOCUS(FW_FOCUS_POLICY(focus_win)))) { return True; } } return False; } /* Returns true if the focus has to be restored to a different window after * unmapping. */ Bool focus_query_close_release_focus(const FvwmWindow *fw) { if (fw == NULL || fw != get_focus_window()) { return False; } if (!IS_TRANSIENT(fw) && (FW_W_TRANSIENTFOR(fw) == Scr.Root || FP_DO_GRAB_FOCUS(FW_FOCUS_POLICY(fw)))) { return True; } else if (IS_TRANSIENT(fw) && FP_DO_GRAB_FOCUS_TRANSIENT(FW_FOCUS_POLICY(fw))) { return True; } return False; } static void __focus_grab_buttons(FvwmWindow *fw, Bool client_entered) { int i; Bool do_grab_window = False; int grab_buttons; if (fw == NULL || IS_SCHEDULED_FOR_DESTROY(fw) || !IS_MAPPED(fw)) { /* It is pointless to grab buttons on dieing windows. Buttons * can not be grabbed when the window is unmapped. */ return; } grab_buttons = Scr.buttons2grab; do_grab_window = focus_query_grab_buttons(fw, client_entered); if (do_grab_window == True) { grab_buttons |= FP_USE_MOUSE_BUTTONS(FW_FOCUS_POLICY(fw)); } if (grab_buttons != fw->grabbed_buttons) { MyXGrabServer(dpy); for (i = 0; i < NUMBER_OF_EXTENDED_MOUSE_BUTTONS; i++) { __focus_grab_one_button(fw, i, grab_buttons); } MyXUngrabServer (dpy); } return; } void focus_grab_buttons(FvwmWindow *fw) { __focus_grab_buttons(fw, False); } void focus_grab_buttons_client_entered(FvwmWindow *fw) { __focus_grab_buttons(fw, True); } void focus_grab_buttons_on_layer(int layer) { FvwmWindow *fw; for ( fw = Scr.FvwmRoot.stack_next; fw != &Scr.FvwmRoot && fw->layer >= layer; fw = fw->stack_next) { if (fw->layer == layer) { focus_grab_buttons(fw); } } return; } void focus_grab_buttons_all(void) { FvwmWindow *fw; for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { focus_grab_buttons(fw); } return; } void _SetFocusWindow( FvwmWindow *fw, Bool do_allow_force_broadcast, fpol_set_focus_by_t set_by, Bool client_entered) { sftfwin_args_t sf_args; memset(&sf_args, 0, sizeof(sf_args)); sf_args.do_allow_force_broadcast = !!do_allow_force_broadcast; sf_args.is_focus_by_flip_focus_cmd = 0; sf_args.do_forbid_warp = 0; sf_args.do_force = 1; sf_args.set_by = set_by; if (client_entered) { sf_args.client_entered = 1; } else { sf_args.client_entered = 0; } set_focus_to_fwin(FW_W(fw), fw, &sf_args); return; } void _ReturnFocusWindow(FvwmWindow *fw) { sftfwin_args_t sf_args; memset(&sf_args, 0, sizeof(sf_args)); sf_args.do_allow_force_broadcast = 1; sf_args.is_focus_by_flip_focus_cmd = 0; sf_args.do_forbid_warp = 1; sf_args.client_entered = 0; sf_args.do_force = 0; sf_args.set_by = FOCUS_SET_FORCE; set_focus_to_fwin(FW_W(fw), fw, &sf_args); return; } void _DeleteFocus(Bool do_allow_force_broadcast) { sftfwin_args_t sf_args; memset(&sf_args, 0, sizeof(sf_args)); sf_args.do_allow_force_broadcast = !!do_allow_force_broadcast; sf_args.is_focus_by_flip_focus_cmd = 0; sf_args.do_forbid_warp = 0; sf_args.client_entered = 0; sf_args.do_force = 0; sf_args.set_by = FOCUS_SET_FORCE; set_focus_to_fwin(Scr.NoFocusWin, NULL, &sf_args); return; } void _ForceDeleteFocus(void) { sftfwin_args_t sf_args; memset(&sf_args, 0, sizeof(sf_args)); sf_args.do_allow_force_broadcast = 1; sf_args.is_focus_by_flip_focus_cmd = 0; sf_args.do_forbid_warp = 0; sf_args.client_entered = 0; sf_args.do_force = 1; sf_args.set_by = FOCUS_SET_FORCE; set_focus_to_fwin(Scr.NoFocusWin, NULL, &sf_args); return; } /* When a window is unmapped (or destroyed) this function takes care of * adjusting the focus window appropriately. */ void restore_focus_after_unmap( const FvwmWindow *fw, Bool do_skip_marked_transients) { extern FvwmWindow *colormap_win; FvwmWindow *set_focus_to = NULL; if (focus_is_focused(fw)) { set_focus_to = __restore_focus_after_unmap( fw, do_skip_marked_transients); } if (fw == Scr.pushed_window) { Scr.pushed_window = NULL; } if (fw == colormap_win) { InstallWindowColormaps(set_focus_to); } return; } Bool IsLastFocusSetByMouse(void) { return lastFocusType; } /* same as above, but forces to regrab buttons on the window under the pointer * if necessary */ void focus_grab_buttons_on_pointer_window(void) { Window w; FvwmWindow *fw; if (!FQueryPointer( dpy, Scr.Root, &JunkRoot, &w, &JunkX, &JunkY, &JunkX, &JunkY, &JunkMask)) { /* pointer is not on this screen */ return; } if (XFindContext(dpy, w, FvwmContext, (caddr_t *) &fw) == XCNOENT) { /* pointer is not over a window */ return; } focus_grab_buttons(fw); return; } /* functions to access ScreenFocus, LastScreenFocus and PreviousFocus */ FvwmWindow *get_focus_window(void) { return ScreenFocus; } void set_focus_window(FvwmWindow *fw) { ScreenFocus = fw; return; } FvwmWindow *get_last_screen_focus_window(void) { return LastScreenFocus; } void set_last_screen_focus_window(FvwmWindow *fw) { LastScreenFocus = fw; return; } void update_last_screen_focus_window(FvwmWindow *fw) { if (fw == LastScreenFocus) { LastScreenFocus = NULL; } return; } void set_focus_model(FvwmWindow *fw) { if (!focus_does_accept_input_focus(fw)) { if (WM_TAKES_FOCUS(fw)) { fw->focus_model = FM_GLOBALLY_ACTIVE; } else { fw->focus_model = FM_NO_INPUT; } } else { if (WM_TAKES_FOCUS(fw)) { fw->focus_model = FM_LOCALLY_ACTIVE; } else { fw->focus_model = FM_PASSIVE; } } return; } /* This function is part of a hack to make focus handling work better with * applications that use the passive focus model but manage focus in their own * sub windows and should thus use the locally active focus model instead. * There are many examples like netscape or ddd. */ void focus_force_refresh_focus(const FvwmWindow *fw) { XWindowAttributes winattrs; MyXGrabServer(dpy); if (XGetWindowAttributes(dpy, FW_W(fw), &winattrs)) { XSelectInput( dpy, FW_W(fw), winattrs.your_event_mask & ~FocusChangeMask); FOCUS_SET(FW_W(fw), NULL /* we don't expect an event */); XSelectInput(dpy, FW_W(fw), winattrs.your_event_mask); } MyXUngrabServer(dpy); return; } void refresh_focus(const FvwmWindow *fw) { Bool do_refresh = False; if (fw == NULL || !focus_is_focused(fw)) { /* only refresh the focus on the currently focused window */ return; } /* only refresh the focus for windows with the passive focus model so * that we don't disturb focus handling more than necessary */ switch (fw->focus_model) { case FM_PASSIVE: do_refresh = True; break; case FM_NO_INPUT: case FM_GLOBALLY_ACTIVE: case FM_LOCALLY_ACTIVE: default: do_refresh = False; break; } if (do_refresh) { focus_force_refresh_focus(fw); } return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_FlipFocus(F_CMD_ARGS) { /* Reorder the window list */ __activate_window_by_command(F_PASS_ARGS, 1); return; } void CMD_Focus(F_CMD_ARGS) { __activate_window_by_command(F_PASS_ARGS, 0); return; } void CMD_WarpToWindow(F_CMD_ARGS) { int val1_unit, val2_unit, n; int val1, val2; int do_raise; char *next; char *token; next = GetNextToken(action, &token); if (StrEquals(token, "!raise")) { do_raise = 0; action = next; } else if (StrEquals(token, "raise")) { do_raise = 1; action = next; } else { do_raise = 1; } n = GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit); if (exc->w.wcontext != C_UNMANAGED) { if (n == 2) { warp_to_fvwm_window( exc, val1, val1_unit, val2, val2_unit, do_raise); } else { warp_to_fvwm_window(exc, 0, 0, 0, 0, do_raise); } } else { int x = 0; int y = 0; if (n == 2) { int wx; int wy; int ww; int wh; if (!XGetGeometry( dpy, exc->w.w, &JunkRoot, &wx, &wy, (unsigned int*)&ww, (unsigned int*)&wh, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth)) { return; } if (val1_unit != Scr.MyDisplayWidth) { x = val1; } else { x = (ww - 1) * val1 / 100; } if (val2_unit != Scr.MyDisplayHeight) { y = val2; } else { y = (wh - 1) * val2 / 100; } if (x < 0) { x += ww; } if (y < 0) { y += wh; } } FWarpPointerUpdateEvpos( exc->x.elast, dpy, None, exc->w.w, 0, 0, 0, 0, x, y); } return; } fvwm-2.6.7/fvwm/read.c0000644000175700017570000001732413001406607011506 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation * * Changed 09/24/98 by Dan Espen: * - remove logic that processed and saved module configuration commands. * Its now in "modconf.c". */ #include "config.h" #include #ifdef HAVE_FCNTL_H #include #endif #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "events.h" #include "misc.h" #include "screen.h" #define MAX_READ_DEPTH 40 static char *curr_read_file = NULL; static char *curr_read_dir = NULL; static int curr_read_depth = 0; static char *prev_read_files[MAX_READ_DEPTH]; static int push_read_file(const char *file) { if (curr_read_depth >= MAX_READ_DEPTH) { fvwm_msg( ERR, "Read", "Nested Read limit %d is reached", MAX_READ_DEPTH); return 0; } prev_read_files[curr_read_depth++] = curr_read_file; curr_read_file = safestrdup(file); if (curr_read_dir) { free(curr_read_dir); } curr_read_dir = NULL; return 1; } static void pop_read_file(void) { if (curr_read_depth == 0) { return; } if (curr_read_file) { free(curr_read_file); } curr_read_file = prev_read_files[--curr_read_depth]; if (curr_read_dir) { free(curr_read_dir); } curr_read_dir = NULL; return; } const char *get_current_read_file(void) { return curr_read_file; } const char *get_current_read_dir(void) { if (!curr_read_dir) { char *dir_end; if (!curr_read_file) { return "."; } /* it should be a library function parse_file_dir() */ dir_end = strrchr(curr_read_file, '/'); if (!dir_end) { dir_end = curr_read_file; } curr_read_dir = safemalloc(dir_end - curr_read_file + 1); strncpy(curr_read_dir, curr_read_file, dir_end - curr_read_file); curr_read_dir[dir_end - curr_read_file] = '\0'; } return curr_read_dir; } /* * Read and execute each line from stream. */ void run_command_stream( cond_rc_t *cond_rc, FILE *f, const exec_context_t *exc) { char *tline; char line[1024]; /* Set close-on-exec flag */ fcntl(fileno(f), F_SETFD, 1); /* Update window decorations in case we were called from a menu that * has now popped down. */ handle_all_expose(); tline = fgets(line, (sizeof line) - 1, f); while (tline) { int l; while (tline && (l = strlen(line)) < sizeof(line) && l >= 2 && line[l-2]=='\\' && line[l-1]=='\n') { tline = fgets(line+l-2,sizeof(line)-l+1,f); } tline=line; while (isspace((unsigned char)*tline)) { tline++; } l = strlen(tline); if (l > 0 && tline[l - 1] == '\n') { tline[l - 1] = '\0'; } execute_function(cond_rc, exc, tline, 0); tline = fgets(line, (sizeof line) - 1, f); } return; } /** * Parse the action string. We expect a filename, and optionally, * the keyword "Quiet". The parameter `cmdname' is used for diagnostic * messages only. * * Returns true if the parse succeeded. * The filename and the presence of the quiet flag are returned * using the pointer arguments. **/ static int parse_filename( char *cmdname, char *action, char **filename, int *quiet_flag) { char *rest; char *option; /* fvwm_msg(INFO,cmdname,"action == '%s'",action); */ /* read file name arg */ rest = GetNextToken(action,filename); if (*filename == NULL) { fvwm_msg(ERR, cmdname, "missing filename parameter"); return 0; } /* optional "Quiet" argument -- flag defaults to `off' (noisy) */ *quiet_flag = 0; rest = GetNextToken(rest,&option); if (option != NULL) { *quiet_flag = strncasecmp(option, "Quiet", 5) == 0; free(option); } return 1; } /** * Returns 0 if file not found **/ int run_command_file( char *filename, const exec_context_t *exc) { char *full_filename; FILE* f = NULL; /* We attempt to open the filename by doing the following: * * - If the file does start with a "/" then it's treated as an * absolute path. * * - Otherwise, it's assumed to be in FVWM_USERDIR OR FVWM_DATADIR, * whichever comes first. * * - If the file starts with "./" or "../" then try and * open the file exactly as specified which means * things like: * * ../.././foo is catered for. At this point, we just try and open * the specified file regardless. * * - *Hidden* files in the CWD would have to be specified as: * * ./.foo */ full_filename = filename; if (full_filename[0] == '/') { /* It's an absolute path */ f = fopen(full_filename,"r"); } else { /* It's a relative path. Check in either FVWM_USERDIR or * FVWM_DATADIR. * */ full_filename = CatString3(fvwm_userdir, "/", filename); if((f = fopen(full_filename, "r")) == NULL) { full_filename = CatString3( FVWM_DATADIR, "/", filename); f = fopen(full_filename, "r"); } } if ((f == NULL) && (f = fopen(filename, "r")) == NULL) { /* We really couldn't open the file. */ return 0; } if (push_read_file(full_filename) == 0) { return 0; } run_command_stream(NULL, f, exc); fclose(f); pop_read_file(); return 1; } /** * Busy Cursor Stuff for Read **/ static void cursor_control(Bool grab) { static int read_depth = 0; static Bool need_ungrab = False; if (!(Scr.BusyCursor & BUSY_READ) && !need_ungrab) { return; } if (grab) { if (!read_depth && GrabEm(CRS_WAIT, GRAB_BUSY)) { need_ungrab = True; } if (need_ungrab) { read_depth++; } } else if (need_ungrab) { read_depth--; if (!read_depth || !(Scr.BusyCursor & BUSY_READ)) { UngrabEm(GRAB_BUSY); need_ungrab = False; read_depth = 0; } } return; } void CMD_Read(F_CMD_ARGS) { char* filename; int read_quietly; DoingCommandLine = False; if (cond_rc != NULL) { cond_rc->rc = COND_RC_OK; } if (!parse_filename("Read", action, &filename, &read_quietly)) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } cursor_control(True); if (!run_command_file(filename, exc)) { if (!read_quietly) { if (filename[0] == '/') { fvwm_msg( ERR, "Read", "file '%s' not found", filename); } else { fvwm_msg( ERR, "Read", "file '%s' not found in %s or " FVWM_DATADIR, filename, fvwm_userdir); } } if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } } free(filename); cursor_control(False); return; } void CMD_PipeRead(F_CMD_ARGS) { char* command; int read_quietly; FILE* f; DoingCommandLine = False; if (cond_rc != NULL) { cond_rc->rc = COND_RC_OK; } if (!parse_filename("PipeRead", action, &command, &read_quietly)) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } cursor_control(True); f = popen(command, "r"); if (f == NULL) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } if (!read_quietly) { fvwm_msg( ERR, "PipeRead", "command '%s' not run", command); } free(command); cursor_control(False); return; } free(command); run_command_stream(cond_rc,f, exc); pclose(f); cursor_control(False); return; } fvwm-2.6.7/fvwm/windowlist.c0000644000175700017570000006051413001406607012775 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all new * by Rob Nation * A little of it is borrowed from ctwm. * Copyright 1993 Robert Nation. No restrictions are placed on this code, * as long as the copyright notice is preserved */ /* * * fvwm window-list popup code * */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/FGettext.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "menudim.h" #include "menuitem.h" #include "menuroot.h" #include "menustyle.h" #include "menus.h" #include "menuparameters.h" #include "conditional.h" #include "stack.h" #include "focus.h" #include "virtual.h" #include "geometry.h" #define SHOW_GEOMETRY (1<<0) #define SHOW_ALLDESKS (1<<1) #define SHOW_NORMAL (1<<2) #define SHOW_ICONIC (1<<3) #define SHOW_STICKY_ACROSS_PAGES (1<<4) #define SHOW_STICKY_ACROSS_DESKS (1<<5) #define NO_DESK_SORT (1<<6) #define SHOW_ICONNAME (1<<7) #define SHOW_ALPHABETIC (1<<8) #define SORT_BYCLASS (1<<9) #define SORT_BYRESOURCE (1<<10) #define SORT_REVERSE (1<<11) #define SHOW_INFONOTGEO (1<<12) #define NO_DESK_NUM (1<<13) #define NO_CURRENT_DESK_TITLE (1<<14) #define TITLE_FOR_ALL_DESKS (1<<15) #define NO_NUM_IN_DESK_TITLE (1<<16) #define SHOW_PAGE_X (1<<17) #define SHOW_PAGE_Y (1<<18) #define NO_LAYER (1<<19) #define SHOW_SCREEN (1<<20) #define SHOW_DEFAULT (SHOW_GEOMETRY | SHOW_ALLDESKS | SHOW_NORMAL | \ SHOW_ICONIC | SHOW_STICKY_ACROSS_PAGES | SHOW_STICKY_ACROSS_DESKS) static char *get_desk_title(int desk, unsigned long flags, Bool is_top_title) { char *desk_name; char *tlabel; desk_name = GetDesktopName(desk); if (desk_name != NULL) { tlabel = (char *)safemalloc(strlen(desk_name)+50); } else { tlabel = (char *)safemalloc(50); } if (desk_name != NULL) { if (flags & NO_NUM_IN_DESK_TITLE) { sprintf(tlabel, "%s%s", desk_name, (is_top_title && (flags & SHOW_GEOMETRY)) ? _("\tGeometry") : ""); } else { sprintf(tlabel,"%d: %s%s", desk, desk_name, (is_top_title && (flags & SHOW_GEOMETRY)) ? _("\tGeometry") : ""); } } else { sprintf(tlabel,_("Desk: %d%s"),desk, (is_top_title && (flags & SHOW_GEOMETRY)) ? _("\tGeometry") : ""); } return tlabel; } /* Function to compare window title names */ static int visibleCompare(const FvwmWindow **a, const FvwmWindow **b) { return strcasecmp((*a)->visible_name, (*b)->visible_name); } static int iconCompare(const FvwmWindow **a, const FvwmWindow **b) { return strcasecmp((*a)->visible_icon_name, (*b)->visible_icon_name); } /* Which of the compare functions to sort on. */ static int (*compare)(const FvwmWindow **a, const FvwmWindow **b); static int classCompare(const FvwmWindow **a, const FvwmWindow **b) { int result = strcasecmp((*a)->class.res_class, (*b)->class.res_class); if (result) { return result; } return strcasecmp((*a)->visible_name, (*b)->visible_name); } static int resourceCompare(const FvwmWindow **a, const FvwmWindow **b) { int result = strcasecmp((*a)->class.res_class, (*b)->class.res_class); if (result) { return result; } result = strcasecmp((*a)->class.res_name, (*b)->class.res_name); if (result) { return result; } return strcasecmp((*a)->visible_name, (*b)->visible_name); } static int classIconCompare(const FvwmWindow **a, const FvwmWindow **b) { int result = strcasecmp((*a)->class.res_class, (*b)->class.res_class); if (result) { return result; } return strcasecmp((*a)->visible_icon_name, (*b)->visible_icon_name); } static int resourceIconCompare(const FvwmWindow **a, const FvwmWindow **b) { int result = strcasecmp((*a)->class.res_class, (*b)->class.res_class); if (result) { return result; } result = strcasecmp((*a)->class.res_name, (*b)->class.res_name); if (result) { return result; } return strcasecmp((*a)->visible_icon_name, (*b)->visible_icon_name); } static int compareReverse(const FvwmWindow **a, const FvwmWindow **b) { return -compare(a, b); } /* * Change by PRB (pete@tecc.co.uk), 31/10/93. Prepend a hot key * specifier to each item in the list. This means allocating the * memory for each item (& freeing it) rather than just using the window * title directly. */ void CMD_WindowList(F_CMD_ARGS) { struct MenuRoot *mr; struct MenuParameters mp; char* ret_action = NULL; FvwmWindow *t; FvwmWindow **windowList; FvwmWindow **iconifiedList = NULL; int numWindows; int ii; char tname[128]; char loc[64]; char *name=NULL; Bool free_name = False; int dwidth; int dheight; char *tlabel; int last_desk_done = INT_MIN; int last_desk_displayed = INT_MIN; int next_desk = 0; char *t_hot=NULL; /* Menu label with hotkey added */ char scut = '0'; /* Current short cut key */ char *opts=NULL; char *tok=NULL; int desk = Scr.CurrentDesk; unsigned long flags = SHOW_DEFAULT; char *func = NULL; char *ffunc = NULL; char *tfunc = NULL; char *default_action = NULL; MenuReturn mret; MenuOptions mops; int low_layer = 0; /* show all layers by default */ int high_layer = INT_MAX; int max_label_width = 0; int skiplist_mode = 0; /* do not show skiplist by default */ Bool use_hotkey = True; KeyCode old_sor_keycode; char sor_default_keyname[8] = { 'M', 'e', 't', 'a', '_', 'L' }; char *sor_keyname = sor_default_keyname; /* Condition vars. */ Bool use_condition = False; Bool current_at_end = False; Bool iconified_at_end = False; int ic = 0; int ij; WindowConditionMask mask; char *cond_flags; Bool first_desk = True; Bool empty_menu = True; Bool was_get_menu_opts_called = False; FvwmWindow * const fw = exc->w.fw; const Window w = exc->w.w; const exec_context_t *exc2; memset(&mops, 0, sizeof(mops)); memset(&mret, 0, sizeof(MenuReturn)); /* parse postitioning args - must call this even if no action is given * because it sets the xinerama screen origin */ if (action && *action) { /* Look for condition - CreateFlagString returns NULL if no '(' * or '[' */ cond_flags = CreateFlagString(action, &action); if (cond_flags) { /* Create window mask */ use_condition = True; DefaultConditionMask(&mask); /* override for Current [] */ mask.my_flags.use_circulate_hit = 1; mask.my_flags.use_circulate_hit_icon = 1; CreateConditionMask(cond_flags, &mask); free(cond_flags); } opts = get_menu_options( action, w, fw, NULL, NULL, NULL, &mops); was_get_menu_opts_called = True; /* parse options */ while (opts && *opts) { opts = GetNextSimpleOption(opts, &tok); if (!tok) { break; } if (StrEquals(tok,"NoHotkeys")) { use_hotkey = False; } else if (StrEquals(tok,"Function")) { opts = GetNextSimpleOption(opts, &func); } else if (StrEquals(tok,"Desk")) { free(tok); opts = GetNextSimpleOption(opts, &tok); if (tok) { desk = atoi(tok); flags &= ~SHOW_ALLDESKS; } } else if (StrEquals(tok,"CurrentDesk")) { desk = Scr.CurrentDesk; flags &= ~SHOW_ALLDESKS; } else if (StrEquals(tok,"NotAlphabetic")) { flags &= ~SHOW_ALPHABETIC; } else if (StrEquals(tok,"Alphabetic")) { flags |= SHOW_ALPHABETIC; } else if (StrEquals(tok,"SortByClass")) { flags |= SORT_BYCLASS; } else if (StrEquals(tok,"SortByResource")) { flags |= SORT_BYRESOURCE; } else if (StrEquals(tok,"ReverseOrder")) { flags |= SORT_REVERSE; } else if (StrEquals(tok,"CurrentAtEnd")) { current_at_end = True; } else if (StrEquals(tok,"IconifiedAtEnd")) { iconified_at_end = True; } else if (StrEquals(tok,"NoDeskSort")) { flags |= NO_DESK_SORT; } else if (StrEquals(tok,"ShowPage")) { flags |= SHOW_PAGE_X | SHOW_PAGE_Y; } else if (StrEquals(tok,"ShowPageX")) { flags |= SHOW_PAGE_X; } else if (StrEquals(tok,"ShowPageY")) { flags |= SHOW_PAGE_Y; } else if (StrEquals(tok,"ShowScreen")) { flags |= SHOW_SCREEN; } else if (StrEquals(tok,"UseIconName")) { flags |= SHOW_ICONNAME; } else if (StrEquals(tok,"NoGeometry")) { flags &= ~SHOW_GEOMETRY; flags &= ~SHOW_INFONOTGEO; } else if (StrEquals(tok,"NoGeometryWithInfo")) { flags &= ~SHOW_GEOMETRY; flags |= SHOW_INFONOTGEO; } else if (StrEquals(tok,"Geometry")) { flags |= SHOW_GEOMETRY; flags &= ~SHOW_INFONOTGEO; } else if (StrEquals(tok,"NoIcons")) { flags &= ~SHOW_ICONIC; } else if (StrEquals(tok,"Icons")) { flags |= SHOW_ICONIC; } else if (StrEquals(tok,"OnlyIcons")) { flags = SHOW_ICONIC; } else if (StrEquals(tok,"NoNormal")) { flags &= ~SHOW_NORMAL; } else if (StrEquals(tok,"Normal")) { flags |= SHOW_NORMAL; } else if (StrEquals(tok,"OnlyNormal")) { flags = SHOW_NORMAL; } else if (StrEquals(tok,"NoSticky")) { flags &= ~(SHOW_STICKY_ACROSS_PAGES); flags &= ~(SHOW_STICKY_ACROSS_DESKS); } else if (StrEquals(tok,"NoStickyPage")) { flags &= ~(SHOW_STICKY_ACROSS_PAGES); } else if (StrEquals(tok,"NoStickyDesk")) { flags &= ~(SHOW_STICKY_ACROSS_DESKS); } else if (StrEquals(tok,"Sticky")) { flags |= SHOW_STICKY_ACROSS_PAGES; flags |= SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"StickyPage")) { flags |= SHOW_STICKY_ACROSS_PAGES; } else if (StrEquals(tok,"StickyDesk")) { flags |= SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"OnlySticky")) { flags = SHOW_STICKY_ACROSS_PAGES; flags = SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"OnlyStickyPage")) { flags = SHOW_STICKY_ACROSS_PAGES; } else if (StrEquals(tok,"OnlyStickyDesk")) { flags = SHOW_STICKY_ACROSS_DESKS; } else if (StrEquals(tok,"UseListSkip")) { /* deprecated as of 02-May-2007 (SS) */ fprintf(stderr, "UseListSkip is deprecated. Please use \"UseSkipList\".\n"); skiplist_mode = 1; } else if (StrEquals(tok,"UseSkipList")) { skiplist_mode = 1; } else if (StrEquals(tok,"OnlyListSkip")) { /* deprecated as of 02-May-2007 (SS) */ fprintf(stderr, "OnlyListSkip is deprecated. Please use \"OnlySkipList\".\n"); skiplist_mode = 2; } else if (StrEquals(tok,"OnlySkipList")) { skiplist_mode = 2; } else if (StrEquals(tok,"NoDeskNum")) { flags |= NO_DESK_NUM; } else if (StrEquals(tok,"NoLayer")) { flags |= NO_LAYER; } else if (StrEquals(tok,"NoCurrentDeskTitle")) { flags |= NO_CURRENT_DESK_TITLE; } else if (StrEquals(tok,"TitleForAllDesks")) { flags |= TITLE_FOR_ALL_DESKS; } else if (StrEquals(tok,"NoNumInDeskTitle")) { flags |= NO_NUM_IN_DESK_TITLE; } /* these are a bit dubious, but we should keep the * OnTop options for compatibility */ else if (StrEquals(tok, "NoOnTop")) { if (high_layer >= Scr.TopLayer) { high_layer = Scr.TopLayer - 1; } } else if (StrEquals(tok, "OnTop")) { if (high_layer < Scr.TopLayer) { high_layer = Scr.TopLayer; } } else if (StrEquals(tok, "OnlyOnTop")) { high_layer = low_layer = Scr.TopLayer; } else if (StrEquals(tok, "NoOnBottom")) { if (low_layer <= Scr.BottomLayer) { low_layer = Scr.BottomLayer - 1; } } else if (StrEquals(tok, "OnBottom")) { if (low_layer > Scr.BottomLayer) { low_layer = Scr.BottomLayer; } } else if (StrEquals(tok, "OnlyOnBottom")) { high_layer = low_layer = Scr.BottomLayer; } else if (StrEquals(tok, "Layer")) { free(tok); opts = GetNextSimpleOption(opts, &tok); if (tok) { low_layer = high_layer = atoi(tok); free(tok); opts = GetNextSimpleOption(opts, &tok); if (tok) { high_layer = atoi(tok); } } } else if (StrEquals(tok, "SelectOnRelease")) { if (sor_keyname != sor_default_keyname) { free(sor_keyname); } sor_keyname = NULL; opts = GetNextSimpleOption(opts, &sor_keyname); } else if (StrEquals(tok, "MaxLabelWidth")) { char *wid; opts = GetNextSimpleOption(opts, &wid); if (wid) { max_label_width = atoi(wid); if (max_label_width < 1) { max_label_width = 1; } free(wid); } } else if (!opts || !*opts) { default_action = safestrdup(tok); } else { fvwm_msg( ERR, "WindowList","Unknown option '%s'", tok); } if (tok) { free(tok); } } } if (was_get_menu_opts_called == False) { opts = get_menu_options( action, w, fw, NULL, NULL, NULL, &mops); } tlabel = get_desk_title(desk, flags, True); mr = NewMenuRoot(tlabel); if (!(flags & NO_CURRENT_DESK_TITLE)) { AddToMenu(mr, tlabel, "TITLE", False, False, False); empty_menu = False; } free(tlabel); numWindows = 0; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { numWindows++; } windowList = malloc(numWindows*sizeof(t)); if (windowList == NULL) { return; } if (iconified_at_end) { iconifiedList = malloc(numWindows*sizeof(t)); if (iconifiedList == NULL) { free(windowList); return; } } /* get the windowlist starting from the current window (if any)*/ t = get_focus_window(); if (t == NULL) { t = Scr.FvwmRoot.next; } else if (current_at_end) { if (t->next) { t = t->next; } else { t = Scr.FvwmRoot.next; } } for (ii = 0; ii < numWindows; ii++) { if (flags & SORT_REVERSE) { windowList[numWindows - ii - 1] = t; } else if (iconified_at_end && IS_ICONIFIED(t)) { iconifiedList[ic++] = t; } else { windowList[ii - ic] = t; } if (t->next) { t = t->next; } else { t = Scr.FvwmRoot.next; } } if (iconified_at_end && ic > 0) { if (current_at_end && ii > ic) { windowList[numWindows - 1] = windowList[--ii - ic]; } for (ij = 0; ij < ic; ij++) { windowList[ij + (ii - ic)] = iconifiedList[ij]; } } /* Do alphabetic sort */ if (flags & (SHOW_ALPHABETIC | SORT_BYCLASS | SORT_BYRESOURCE)) { /* This will be compare or compareReverse if a reverse order * is selected. */ int (*sort)(const FvwmWindow **a, const FvwmWindow **b); switch (flags & (SHOW_ALPHABETIC | SHOW_ICONNAME | \ SORT_BYCLASS | SORT_BYRESOURCE)) { case SHOW_ALPHABETIC: compare = visibleCompare; break; case SHOW_ALPHABETIC | SHOW_ICONNAME: compare = iconCompare; break; /* Sorting based on class name produces an alphabetic * order so the keyword alphabetic is redundant. */ case SORT_BYCLASS: case SORT_BYCLASS | SHOW_ALPHABETIC: compare = classCompare; break; case SORT_BYCLASS | SHOW_ICONNAME: case SORT_BYCLASS | SHOW_ICONNAME | SHOW_ALPHABETIC: compare = classIconCompare; break; case SORT_BYRESOURCE: case SORT_BYRESOURCE | SORT_BYCLASS: case SORT_BYRESOURCE | SORT_BYCLASS | SHOW_ALPHABETIC: compare = resourceCompare; break; case SORT_BYRESOURCE | SHOW_ICONNAME: case SORT_BYRESOURCE | SHOW_ICONNAME | SORT_BYCLASS: case SORT_BYRESOURCE | SHOW_ICONNAME | SORT_BYCLASS | \ SHOW_ALPHABETIC: compare = resourceIconCompare; break; /* All current cases are covered, but if something * changes in the future we leave compare valid even if * it isn't what is expected. */ default: compare = visibleCompare; break; } if ( flags & SORT_REVERSE ) { sort = compareReverse; } else { sort = compare; } qsort(windowList, numWindows, sizeof(t), (int(*)(const void*, const void*))sort); } while(next_desk != INT_MAX) { /* Sort window list by desktop number */ if ((flags & SHOW_ALLDESKS) && !(flags & NO_DESK_SORT)) { /* run through the windowlist finding the first desk * not already processed */ next_desk = INT_MAX; for (ii = 0; ii < numWindows; ii++) { t = windowList[ii]; if (t->Desk >last_desk_done && t->Desk < next_desk) { next_desk = t->Desk; } } } if (!(flags & SHOW_ALLDESKS)) { /* if only doing one desk and it hasn't been done */ if (last_desk_done == INT_MIN) next_desk = desk; /* select the desk */ else next_desk = INT_MAX; /* flag completion */ } if (flags & NO_DESK_SORT) next_desk = INT_MAX; /* only go through loop once */ last_desk_done = next_desk; for (ii = 0; ii < numWindows; ii++) { t = windowList[ii]; if (t->Desk != next_desk && !(flags & NO_DESK_SORT)) { continue; } if (skiplist_mode == 0 && DO_SKIP_WINDOW_LIST(t)) { /* don't want skiplist windows - skip */ continue; } if (skiplist_mode == 2 && !DO_SKIP_WINDOW_LIST(t)) { /* don't want no skiplist one - skip */ continue; } if (use_condition && !MatchesConditionMask(t, &mask)) { /* doesn't match specified condition */ continue; } if (!(flags & SHOW_ICONIC) && (IS_ICONIFIED(t))) { /* don't want icons - skip */ continue; } if (!(flags & SHOW_STICKY_ACROSS_PAGES) && (IS_STICKY_ACROSS_PAGES(t))) { /* don't want sticky ones - skip */ continue; } if (!(flags & SHOW_STICKY_ACROSS_DESKS) && (IS_STICKY_ACROSS_DESKS(t))) { /* don't want sticky ones - skip */ continue; } if (!(flags & SHOW_NORMAL) && !(IS_ICONIFIED(t) || IS_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_DESKS(t))) { /* don't want "normal" ones - skip */ continue; } if (get_layer(t) < low_layer || get_layer(t) > high_layer) { /* don't want this layer */ continue; } empty_menu = False; /* add separator between desks when geometry * shown but not at the top*/ if (t->Desk != last_desk_displayed) { if (last_desk_displayed != INT_MIN) { if (((flags & SHOW_GEOMETRY) || (flags & SHOW_INFONOTGEO)) && !(flags & TITLE_FOR_ALL_DESKS)) { AddToMenu( mr, NULL, NULL, False, False, False); } if (flags & TITLE_FOR_ALL_DESKS) { tlabel = get_desk_title( t->Desk, flags, False); AddToMenu( mr, tlabel, "TITLE", False, False, False); free(tlabel); } } last_desk_displayed = t->Desk; } if (first_desk && flags & TITLE_FOR_ALL_DESKS) { tlabel = get_desk_title(t->Desk, flags, False); AddToMenu( mr, tlabel, "TITLE", False, False, False); free(tlabel); } first_desk = False; if (flags & SHOW_ICONNAME) { name = t->visible_icon_name; } else { name = t->visible_name; } free_name = False; if (!name) { name = "NULL_NAME"; } else if (max_label_width > 0 && strlen(name) > max_label_width) { name = strdup(name); name[max_label_width] = '\0'; free_name = True; } t_hot = safemalloc(strlen(name) + 80); if (use_hotkey) { /* Generate label */ sprintf(t_hot, "&%c. ", scut); } else { *t_hot = 0; } if (!(flags & SHOW_INFONOTGEO)) { strcat(t_hot, name); } if (*t_hot == 0) { strcpy(t_hot, " "); } /* Next shortcut key */ if (scut == '9') { scut = 'A'; } else if (scut == 'Z') { scut = '0'; } else { scut++; } if (flags & SHOW_INFONOTGEO) { tname[0]=0; if (!IS_ICONIFIED(t) && !(flags & NO_DESK_NUM)) { sprintf(loc,"%d:", t->Desk); strcat(tname,loc); } if (IS_ICONIFIED(t)) { strcat(tname, "("); } strcat(t_hot,"\t"); strcat(t_hot,tname); strcat(t_hot, name); if (IS_ICONIFIED(t)) { strcat(t_hot, ")"); } } else if (flags & SHOW_GEOMETRY) { size_borders b; tname[0]=0; if (IS_ICONIFIED(t)) { strcpy(tname, "("); } if (!(flags & NO_DESK_NUM)) { sprintf(loc, "%d", t->Desk); strcat(tname, loc); } if (flags & SHOW_SCREEN) { fscreen_scr_arg fscr; int scr; fscr.xypos.x = Scr.Vx + t->g.frame.x + t->g.frame.width / 2; fscr.xypos.y = Scr.Vy + t->g.frame.y + t->g.frame.height / 2; scr = FScreenGetScrId( &fscr, FSCREEN_XYPOS); sprintf(loc, "@%d", scr); strcat(tname, loc); } if (flags & SHOW_PAGE_X) { sprintf(loc, "+%d", (Scr.Vx + t->g.frame.x + t->g.frame.width / 2) / Scr.MyDisplayWidth); strcat(tname, loc); } if (flags & SHOW_PAGE_Y) { sprintf(loc, "+%d", (Scr.Vy + t->g.frame.y + t->g.frame.height/2) / Scr.MyDisplayHeight); strcat(tname, loc); } if (!(flags & NO_LAYER)) { sprintf(loc, "(%d)", (get_layer(t))); strcat(tname, loc); } strcat(tname, ":"); get_window_borders(t, &b); dheight = t->g.frame.height - b.total_size.height; dwidth = t->g.frame.width - b.total_size.width; dwidth = (dwidth - t->hints.base_width) /t->orig_hints.width_inc; dheight = (dheight - t->hints.base_height) /t->orig_hints.height_inc; sprintf(loc,"%d",dwidth); strcat(tname, loc); sprintf(loc,"x%d",dheight); strcat(tname, loc); if (t->g.frame.x >=0) { sprintf(loc,"+%d",t->g.frame.x); } else { sprintf(loc,"%d",t->g.frame.x); } strcat(tname, loc); if (t->g.frame.y >=0) { sprintf(loc,"+%d",t->g.frame.y); } else { sprintf(loc,"%d",t->g.frame.y); } strcat(tname, loc); if (IS_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_DESKS(t)) { strcat(tname, " S"); } if (IS_ICONIFIED(t)) { strcat(tname, ")"); } strcat(t_hot,"\t"); strcat(t_hot,tname); } ffunc = func ? func : "WindowListFunc"; tfunc = safemalloc(strlen(ffunc) + 36); /* support two ways for now: window context * (new) and window id param (old) */ sprintf(tfunc, "WindowId %lu %s %lu", FW_W(t), ffunc, FW_W(t)); AddToMenu( mr, t_hot, tfunc, False, False, False); free(tfunc); /* Add the title pixmap */ if (FMiniIconsSupported && t->mini_icon) { MI_MINI_ICON(MR_LAST_ITEM(mr))[0] = t->mini_icon; /* increase the cache count. Otherwise the * pixmap will be eventually removed from the * cache by DestroyMenu */ t->mini_icon->count++; } if (t_hot) { free(t_hot); } if (free_name) { free(name); } } } if (empty_menu) { /* force current desk title */ tlabel = get_desk_title(desk, flags, True); AddToMenu(mr, tlabel, "TITLE", False, False, False); free(tlabel); } if (func) { free(func); } free(windowList); if (iconified_at_end) { free(iconifiedList); } /* Use the WindowList menu style if there is one */ change_mr_menu_style(mr, "WindowList"); /* Activate select_on_release style */ old_sor_keycode = MST_SELECT_ON_RELEASE_KEY(mr); if (sor_keyname && (!MST_SELECT_ON_RELEASE_KEY(mr) || sor_keyname != sor_default_keyname)) { MST_SELECT_ON_RELEASE_KEY(mr) = XKeysymToKeycode( dpy, FvwmStringToKeysym(dpy, sor_keyname)); } memset(&mp, 0, sizeof(mp)); mp.menu = mr; exc2 = exc_clone_context(exc, NULL, 0); mp.pexc = &exc2; mp.flags.has_default_action = (default_action && *default_action != 0); mp.flags.is_sticky = 1; mp.flags.is_submenu = 0; mp.flags.is_already_mapped = 0; mp.flags.is_triggered_by_keypress = (!default_action && exc->x.etrigger->type == KeyPress); mp.pops = &mops; mp.ret_paction = &ret_action; do_menu(&mp, &mret); /* Restore old menu style */ MST_SELECT_ON_RELEASE_KEY(mr) = old_sor_keycode; if (ret_action) { free(ret_action); } DestroyMenu(mr, False, False); if (mret.rc == MENU_DOUBLE_CLICKED && default_action && *default_action) { execute_function(cond_rc, exc2, default_action, 0); } if (default_action != NULL) { free(default_action); } if (use_condition) { FreeConditionMask(&mask); } if (sor_keyname && sor_keyname != sor_default_keyname) { free(sor_keyname); } exc_destroy_context(exc2); return; } fvwm-2.6.7/fvwm/decorations.h0000644000175700017570000000206012773467232013121 00000000000000/* -*-c-*- */ #ifndef DECORATIONS_H #define DECORATIONS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { RQORIG_PROGRAM = False, RQORIG_PROGRAM_US = True, RQORIG_MODULE_INPUT, RQORIG_FVWM_USER, } request_origin_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void GetMwmHints(FvwmWindow *t); void GetOlHints(FvwmWindow *t); void SelectDecor(FvwmWindow *t, window_style *pstyle, short *buttons); Bool is_function_allowed( int function, char *action_string, const FvwmWindow *t, request_origin_t request_origin, Bool do_allow_override_mwm_hints); #endif /* DECORATIONS_H */ fvwm-2.6.7/fvwm/borders.h0000644000175700017570000000403212773467232012250 00000000000000/* -*-c-*- */ #ifndef _BORDERS_H #define _BORDERS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define NPARTS_KEEP_STATE 12 /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { PART_NONE = 0x0, /* the border drawing code relies on the fact that the border bits * occupy the lowest ten bits in this order! */ PART_BORDER_N = 0x1, PART_BORDER_S = 0x2, PART_BORDER_E = 0x4, PART_BORDER_W = 0x8, PART_BORDER_NW = 0x10, PART_BORDER_NE = 0x20, PART_BORDER_SW = 0x40, PART_BORDER_SE = 0x80, PART_TITLE = 0x100, PART_BUTTONS = 0x200, PART_X_HANDLES = 0x400, PART_Y_HANDLES = 0x800, /* combinations of the above values */ PART_SIDES = 0x0f, PART_CORNERS = 0xf0, PART_FRAME = 0xff, PART_TITLEBAR = 0x300, PART_HANDLES = 0xc00, PART_ALL = 0xfff } window_parts; typedef enum { CLEAR_NONE = 0x0, CLEAR_FRAME = 0x1, CLEAR_TITLE = 0x2, CLEAR_BUTTONS = 0x4, CLEAR_ALL = 0x7 } clear_window_parts; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ DecorFace *border_get_border_style( FvwmWindow *fw, Bool has_focus); int border_is_using_border_style( FvwmWindow *fw, Bool has_focus); int border_context_to_parts( int context); void border_get_part_geometry( FvwmWindow *fw, window_parts part, rectangle *sidebar_g, rectangle *ret_g, Window *ret_w); int get_button_number(int context); void border_draw_decorations( FvwmWindow *t, window_parts draw_parts, Bool has_focus, int force, clear_window_parts clear_parts, rectangle *old_g, rectangle *new_g); void border_undraw_decorations( FvwmWindow *fw); void border_redraw_decorations( FvwmWindow *fw); unsigned int border_get_transparent_decorations_part( FvwmWindow *fw); #endif /* _BORDERS_H */ fvwm-2.6.7/fvwm/functions.h0000644000175700017570000000473212773467232012627 00000000000000/* -*-c-*- */ #ifndef FUNCTIONS_H #define FUNCTIONS_H /* ---------------------------- included header files ---------------------- */ #include "execcontext.h" /* ---------------------------- global definitions ------------------------- */ /* Bits for the function flag byte. */ typedef enum { FUNC_NEEDS_WINDOW = 0x01, FUNC_DONT_REPEAT = 0x02, FUNC_ADD_TO = 0x04, FUNC_DECOR = 0x08, FUNC_ALLOW_UNMANAGED = 0x10, /* only to be passed to execute_function() */ FUNC_IS_UNMANAGED = 0x20, FUNC_DONT_EXPAND_COMMAND = 0x40, FUNC_DONT_DEFER = 0x80, /* The values are not used internally but by external scripts parsing * functable. Hence all the values below are 0 */ /* tagging used only for building the documentation */ FUNC_OBSOLETE = 0, FUNC_DEPRECATED = 0, /* command grouping (used only for building the documentation) */ /*!!!*/ FG_BINDING = 0, FG_MODULE = 0, FG_MENU = 0, FG_SESSION = 0, FG_STYLE = 0, FG_MOVE = 0, FG_STATE = 0, FG_COND = 0, FG_USER = 0, FG_COLOR = 0, FG_EWMH_GNOME = 0, FG_VIRTUAL = 0, FG_FOCUS = 0, FG_MISC = 0, FG_OLD = 0 } execute_flags_t; /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* used for parsing commands*/ typedef struct { char *keyword; #ifdef __STDC__ void (*action)(F_CMD_ARGS); #else void (*action)(); #endif short func_t; FUNC_FLAGS_TYPE flags; int cursor; } func_t; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void find_func_t( char *action, short *func_t, FUNC_FLAGS_TYPE *flags); Bool functions_is_complex_function( const char *function_name); void execute_function( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags); void execute_function_override_wcontext( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, int wcontext); void execute_function_override_window( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, FvwmWindow *fw); #endif /* FUNCTIONS_H */ fvwm-2.6.7/fvwm/fvwm.c0000644000175700017570000020130513006057357011555 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_GETPWUID # include #endif #if HAVE_SYS_SYSTEMINFO_H /* Solaris has sysinfo instead of gethostname. */ #include #endif #include #include #include "libs/fvwmlib.h" #include "libs/envvar.h" #include "libs/Strings.h" #include "libs/System.h" #include "libs/Grab.h" #include "libs/ColorUtils.h" #include "libs/Graphics.h" #include "libs/FScreen.h" #include "libs/FShape.h" #include "libs/PictureBase.h" #include "libs/PictureUtils.h" #include "libs/Fsvg.h" #include "libs/FRenderInit.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "builtins.h" #include "module_list.h" #include "colorset.h" #include "events.h" #include "eventhandler.h" #include "eventmask.h" #include "icccm2.h" #include "ewmh.h" #include "add_window.h" #include "libs/fvwmsignal.h" #include "stack.h" #include "virtual.h" #include "session.h" #include "read.h" #include "focus.h" #include "update.h" #include "move_resize.h" #include "frame.h" #include "menus.h" #include "menubindings.h" #include "libs/FGettext.h" /* ---------------------------- local definitions -------------------------- */ #define MAXHOSTNAME 255 #define MAX_CFG_CMDS 10 #define MAX_ARG_SIZE 25 #define g_width 2 #define g_height 2 #define l_g_width 4 #define l_g_height 2 #define s_g_width 4 #define s_g_height 4 /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ extern int last_event_type; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef enum { FVWM_RUNNING = 0, FVWM_DONE, FVWM_RESTART } fvwm_run_state_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static char *config_commands[MAX_CFG_CMDS]; static int num_config_commands=0; /* assorted gray bitmaps for decorative borders */ static char g_bits[] = {0x02, 0x01}; static char l_g_bits[] = {0x08, 0x02}; static char s_g_bits[] = {0x01, 0x02, 0x04, 0x08}; static char *home_dir; static volatile sig_atomic_t fvwmRunState = FVWM_RUNNING; static const char *init_function_names[4] = { "InitFunction", "RestartFunction", "ExitFunction", "Nop" }; /* ---------------------------- exported variables (globals) --------------- */ int master_pid; /* process number of 1st fvwm process */ ScreenInfo Scr; /* structures for the screen */ Display *dpy = NULL; /* which display are we talking to */ Bool fFvwmInStartup = True; /* Set to False when startup has finished */ Bool DoingCommandLine = False; /* Set True before each cmd line arg */ XContext FvwmContext; /* context for fvwm windows */ XContext MenuContext; /* context for fvwm menus */ int JunkX = 0, JunkY = 0; Window JunkRoot, JunkChild; /* junk window */ int JunkWidth, JunkHeight, JunkBW, JunkDepth; unsigned int JunkMask; Bool debugging = False; Bool debugging_stack_ring = False; Window bad_window = None; char **g_argv; int g_argc; char *state_filename = NULL; char *restart_state_filename = NULL; /* $HOME/.fs-restart */ Bool Restarting = False; int x_fd; char *display_name = NULL; char *fvwm_userdir; char const *Fvwm_VersionInfo; char const *Fvwm_LicenseInfo; char const *Fvwm_SupportInfo; Atom _XA_MIT_PRIORITY_COLORS; Atom _XA_WM_CHANGE_STATE; Atom _XA_WM_STATE; Atom _XA_WM_COLORMAP_WINDOWS; Atom _XA_WM_TAKE_FOCUS; Atom _XA_WM_DELETE_WINDOW; Atom _XA_WM_DESKTOP; Atom _XA_MwmAtom; Atom _XA_MOTIF_WM; Atom _XA_OL_WIN_ATTR; Atom _XA_OL_WT_BASE; Atom _XA_OL_WT_CMD; Atom _XA_OL_WT_HELP; Atom _XA_OL_WT_NOTICE; Atom _XA_OL_WT_OTHER; Atom _XA_OL_DECOR_ADD; Atom _XA_OL_DECOR_DEL; Atom _XA_OL_DECOR_CLOSE; Atom _XA_OL_DECOR_RESIZE; Atom _XA_OL_DECOR_HEADER; Atom _XA_OL_DECOR_ICON_NAME; Atom _XA_WM_WINDOW_ROLE; Atom _XA_WINDOW_ROLE; Atom _XA_WM_CLIENT_LEADER; Atom _XA_SM_CLIENT_ID; Atom _XA_XROOTPMAP_ID; Atom _XA_XSETROOT_ID; /* ---------------------------- local functions ---------------------------- */ static void SaveDesktopState(void) { FvwmWindow *t; unsigned long data[1]; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { data[0] = (unsigned long) t->Desk; XChangeProperty( dpy, FW_W(t), _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32, PropModeReplace, (unsigned char *)data, 1); } data[0] = (unsigned long) Scr.CurrentDesk; XChangeProperty( dpy, Scr.Root, _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32, PropModeReplace, (unsigned char *) data, 1); XFlush(dpy); return; } static void InternUsefulAtoms (void) { /* Create priority colors if necessary. */ _XA_MIT_PRIORITY_COLORS = XInternAtom( dpy, "_MIT_PRIORITY_COLORS", False); _XA_WM_CHANGE_STATE = XInternAtom(dpy, "WM_CHANGE_STATE", False); _XA_WM_STATE = XInternAtom(dpy, "WM_STATE", False); _XA_WM_COLORMAP_WINDOWS = XInternAtom( dpy, "WM_COLORMAP_WINDOWS", False); _XA_WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False); _XA_WM_TAKE_FOCUS = XInternAtom(dpy, "WM_TAKE_FOCUS", False); _XA_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False); _XA_WM_DESKTOP = XInternAtom(dpy, "WM_DESKTOP", False); _XA_MwmAtom=XInternAtom(dpy, "_MOTIF_WM_HINTS",False); _XA_MOTIF_WM=XInternAtom(dpy, "_MOTIF_WM_INFO",False); _XA_OL_WIN_ATTR=XInternAtom(dpy, "_OL_WIN_ATTR",False); _XA_OL_WT_BASE=XInternAtom(dpy, "_OL_WT_BASE",False); _XA_OL_WT_CMD=XInternAtom(dpy, "_OL_WT_CMD",False); _XA_OL_WT_HELP=XInternAtom(dpy, "_OL_WT_HELP",False); _XA_OL_WT_NOTICE=XInternAtom(dpy, "_OL_WT_NOTICE",False); _XA_OL_WT_OTHER=XInternAtom(dpy, "_OL_WT_OTHER",False); _XA_OL_DECOR_ADD=XInternAtom(dpy, "_OL_DECOR_ADD",False); _XA_OL_DECOR_DEL=XInternAtom(dpy, "_OL_DECOR_DEL",False); _XA_OL_DECOR_CLOSE=XInternAtom(dpy, "_OL_DECOR_CLOSE",False); _XA_OL_DECOR_RESIZE=XInternAtom(dpy, "_OL_DECOR_RESIZE",False); _XA_OL_DECOR_HEADER=XInternAtom(dpy, "_OL_DECOR_HEADER",False); _XA_OL_DECOR_ICON_NAME=XInternAtom(dpy, "_OL_DECOR_ICON_NAME",False); _XA_WM_WINDOW_ROLE=XInternAtom(dpy, "WM_WINDOW_ROLE",False); _XA_WINDOW_ROLE=XInternAtom(dpy, "WINDOW_ROLE",False); _XA_WM_CLIENT_LEADER=XInternAtom(dpy, "WM_CLIENT_LEADER",False); _XA_SM_CLIENT_ID=XInternAtom(dpy, "SM_CLIENT_ID",False); _XA_XROOTPMAP_ID=XInternAtom(dpy, "_XROOTPMAP_ID",False); _XA_XSETROOT_ID=XInternAtom(dpy, "_XSETROOT_ID",False); return; } /* exit handler that will try to release any grabs */ static void catch_exit(void) { if (dpy != NULL) { /* Don't care if this is called from an X error handler. We * *have* to try this, whatever happens. XFree 4.0 may freeze * if we don't do this. */ XUngrabServer(dpy); XUngrabPointer(dpy, CurrentTime); XUngrabKeyboard(dpy, CurrentTime); } return; } /* * Restart on a signal */ static RETSIGTYPE Restart(int sig) { fvwmRunState = FVWM_RESTART; /* This function might not return - it could "long-jump" * right out, so we need to do everything we need to do * BEFORE we call it ... */ fvwmSetTerminate(sig); SIGNAL_RETURN; } static RETSIGTYPE SigDone(int sig) { fvwmRunState = FVWM_DONE; /* This function might not return - it could "long-jump" * right out, so we need to do everything we need to do * BEFORE we call it ... */ fvwmSetTerminate(sig); SIGNAL_RETURN; } /* * parse_command_args - parses a given command string into a given limited * argument array suitable for execv*. The parsing is similar to shell's. * Returns: * positive number of parsed arguments - on success, * 0 - on empty command (only spaces), * negative - on no command or parsing error. * * Any character can be quoted with a backslash (even inside single quotes). * Every command argument is separated by a space/tab/new-line from both sizes * or is at the start/end of the command. Sequential spaces are ignored. * An argument can be enclosed into single quotes (no further expanding) * or double quotes (expending environmental variables $VAR or ${VAR}). * The character '~' is expanded into user home directory (if not in quotes). * * In the current implementation, parsed arguments are stored in one * large static string pointed by returned argv[0], so they will be lost * on the next function call. This can be changed using dynamic allocation, * in this case the caller must free the string pointed by argv[0]. */ static int parse_command_args( const char *command, char **argv, int max_argc, const char **error_msg) { /* It is impossible to guess the exact length because of expanding */ #define MAX_TOTAL_ARG_LEN 256 /* char *arg_string = safemalloc(MAX_TOTAL_ARG_LEN); */ static char arg_string[MAX_TOTAL_ARG_LEN]; int total_arg_len = 0; int error_code = 0; int argc; char *aptr = arg_string; const char *cptr = command; #define the_char (*cptr) #define adv_char (cptr++) #define top_char (*cptr == '\\' ? *(cptr + 1) : *cptr) #define pop_char (*(cptr++) == '\\' ? *(cptr++) : *(cptr - 1)) #define can_add_arg_char (total_arg_len < MAX_TOTAL_ARG_LEN-1) #define add_arg_char(ch) (++total_arg_len, *(aptr++) = ch) #define can_add_arg_str(str) (total_arg_len < MAX_TOTAL_ARG_LEN - strlen(str)) #define add_arg_str(str) \ {\ const char *tmp = str;\ while (*tmp)\ {\ add_arg_char(*(tmp++));\ }\ } *error_msg = ""; if (!command) { *error_msg = "No command"; return -1; } for (argc = 0; argc < max_argc - 1; argc++) { int s_quote = 0; argv[argc] = aptr; while (isspace(the_char)) { adv_char; } if (the_char == '\0') { break; } while ((s_quote || !isspace(the_char)) && the_char != '\0' && can_add_arg_char) { if (the_char == '"') { if (s_quote) { s_quote = 0; } else { s_quote = 1; } adv_char; } else if (!s_quote && the_char == '\'') { adv_char; while (the_char != '\'' && the_char != '\0' && can_add_arg_char) { add_arg_char(pop_char); } if (the_char == '\'') { adv_char; } else if (!can_add_arg_char) { break; } else { *error_msg = "No closing single quote"; error_code = -3; break; } } else if (!s_quote && the_char == '~') { if (!can_add_arg_str(home_dir)) { break; } add_arg_str(home_dir); adv_char; } else if (the_char == '$') { int beg, len; const char *str = getFirstEnv(cptr, &beg, &len); if (!str || beg) { add_arg_char(the_char); adv_char; continue; } if (!can_add_arg_str(str)) { break; } add_arg_str(str); cptr += len; } else { if (add_arg_char(pop_char) == '\0') { break; } } } if (*(aptr-1) == '\0') { *error_msg = "Unexpected last backslash"; error_code = -2; break; } if (error_code) { break; } if (the_char == '~' || the_char == '$' || !can_add_arg_char) { *error_msg = "The command is too long"; error_code = -argc - 100; break; } if (s_quote) { *error_msg = "No closing double quote"; error_code = -4; break; } add_arg_char('\0'); } #undef the_char #undef adv_char #undef top_char #undef pop_char #undef can_add_arg_char #undef add_arg_char #undef can_add_arg_str #undef add_arg_str argv[argc] = NULL; if (argc == 0 && !error_code) { *error_msg = "Void command"; } return error_code ? error_code : argc; } /* * */ static char *get_display_name(char *display_name, int screen_num) { char *msg; char *new_dn; char *cp; char string_screen_num[32]; CopyString(&msg, display_name); cp = strchr(msg, ':'); if (cp != NULL) { cp = strchr(cp, '.'); if (cp != NULL) { /* truncate at display part */ *cp = '\0'; } } sprintf(string_screen_num, ".%d", screen_num); new_dn = safemalloc( strlen(msg) + strlen(string_screen_num) + 1); new_dn[0] = '\0'; strcat(new_dn, msg); strcat(new_dn, string_screen_num); free(msg); return new_dn; } /* * * Procedure: * Done - tells fvwm to clean up and exit * */ /* if restart is true, command must not be NULL... */ void Done(int restart, char *command) { const char *exit_func_name; if (!restart) { MoveViewport(0,0,False); } /* migo (03/Jul/1999): execute [Session]ExitFunction */ exit_func_name = get_init_function_name(2); if (functions_is_complex_function(exit_func_name)) { const exec_context_t *exc; exec_context_changes_t ecc; char *action = safestrdup( CatString2("Function ", exit_func_name)); ecc.type = restart ? EXCT_TORESTART : EXCT_QUIT; ecc.w.wcontext = C_ROOT; exc = exc_create_context(&ecc, ECC_TYPE | ECC_WCONTEXT); execute_function(NULL, exc, action, 0); exc_destroy_context(exc); free(action); } /* XFree freeze hack */ XUngrabPointer(dpy, CurrentTime); XUngrabKeyboard(dpy, CurrentTime); XUngrabServer(dpy); if (!restart) { Reborder(); } EWMH_ExitStuff(); if (restart) { Bool do_preserve_state = True; SaveDesktopState(); if (command) { while (isspace(command[0])) { command++; } if (strncmp(command, "--dont-preserve-state", 21) == 0) { do_preserve_state = False; command += 21; while (isspace(command[0])) command++; } } if (command[0] == '\0') { command = NULL; /* native restart */ } /* won't return under SM on Restart without parameters */ RestartInSession( restart_state_filename, command == NULL, do_preserve_state); /* RBW - 06/08/1999 - without this, windows will wander to * other pages on a Restart/Recapture because Restart gets the * window position information out of sync. There may be a * better way to do this (i.e., adjust the Restart code), but * this works for now. */ MoveViewport(0,0,False); Reborder(); /* Really make sure that the connection is closed and cleared! */ CloseICCCM2(); catch_exit(); XCloseDisplay(dpy); dpy = NULL; /* really need to destroy all windows, explicitly, not sleep, * but this is adequate for now */ sleep(1); if (command) { char *my_argv[MAX_ARG_SIZE]; const char *error_msg; int n = parse_command_args( command, my_argv, MAX_ARG_SIZE, &error_msg); if (n <= 0) { fvwm_msg( ERR, "Done", "Restart command parsing error in" " (%s): [%s]", command, error_msg); } else if (strcmp(my_argv[0], "--pass-args") == 0) { if (n != 2) { fvwm_msg( ERR, "Done", "Restart --pass-args: single" " name expected. (restarting" " '%s' instead)", g_argv[0]); } else { int i; my_argv[0] = my_argv[1]; for (i = 1; i < g_argc && i < MAX_ARG_SIZE - 1; i++) { my_argv[i] = g_argv[i]; } my_argv[i] = NULL; execvp(my_argv[0], my_argv); fvwm_msg( ERR, "Done", "Call of '%s' failed!" " (restarting '%s' instead)", my_argv[0], g_argv[0]); perror(" system error description"); } } else { char *str = NULL; /* Warn against an old 'Restart fvwm2' usage */ if (n == 1 && strcmp(my_argv[0], "fvwm2") == 0) { str = "fvwm2"; } /* If we are at it, warn against a 'Restart * fvwm' usage as well */ else if (n == 1 && strcmp(my_argv[0], "fvwm") == 0) { str = "fvwm"; } if (str) { fvwm_msg( WARN, "Done", "`Restart %s' might not do" " what you want, see the man" " page.\n\tUse Restart without" " parameters if you mean to" " restart the same WM.", str); } execvp(my_argv[0], my_argv); fvwm_msg( ERR, "Done", "Call of '%s' failed!" " (restarting '%s' instead)", my_argv[0], g_argv[0]); perror(" system error description"); } } execvp(g_argv[0], g_argv); /* that _should_ work */ fvwm_msg(ERR, "Done", "Call of '%s' failed!", g_argv[0]); perror(" system error description"); } else { CloseICCCM2(); catch_exit(); XCloseDisplay(dpy); dpy = NULL; } /* dv (15-Jan-2000): This must be done after calling CloseICCCM2()! * Otherwise fvwm ignores map requests while it still has * SubstructureRedirect selected on the root window ==> windows end up * in nirvana. This explicitly happened with windows unswallowed by * FvwmButtons. */ module_kill_all(); exit(0); } /*********************************************************************** * * Procedure: * InstallSignals: install the signal handlers, using whatever * means we have at our disposal. The more POSIXy, the better * ************************************************************************/ static void InstallSignals(void) { #ifdef HAVE_SIGACTION struct sigaction sigact; /* * All signals whose handlers call fvwmSetTerminate() * must be mutually exclusive - we mustn't receive one * while processing any of the others ... */ sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGTERM); sigaddset(&sigact.sa_mask, SIGUSR1); #ifdef SA_RESTART sigact.sa_flags = SA_RESTART; #else sigact.sa_flags = 0; #endif sigact.sa_handler = DeadPipe; sigaction(SIGPIPE, &sigact, NULL); sigact.sa_handler = Restart; sigaction(SIGUSR1, &sigact, NULL); sigact.sa_handler = SigDone; sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); /* Unblock these signals so that we can process them again. */ sigprocmask(SIG_UNBLOCK, &sigact.sa_mask, NULL); /* Reap all zombies automatically! This signal handler will only be * called if a child process dies, not if someone sends a child a STOP * signal. Note that none of our "terminate" signals can be delivered * until the SIGCHLD handler completes, and this is a Good Thing * because the terminate handlers might exit abruptly via "siglongjmp". * This could potentially leave SIGCHLD handler with unfinished * business ... * * NOTE: We could still receive SIGPIPE signals within the SIGCHLD * handler, but the SIGPIPE handler has the SA_RESTART flag set and so * should not affect our "wait" system call. */ sigact.sa_flags |= SA_NOCLDSTOP; sigact.sa_handler = fvwmReapChildren; sigaction(SIGCHLD, &sigact, NULL); #else #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGUSR1) | sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) ); #endif /* * We don't have sigaction(), so fall back on * less reliable methods ... */ signal(SIGPIPE, DeadPipe); signal(SIGUSR1, Restart); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGUSR1, 0); #endif signal(SIGINT, SigDone); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGINT, 0); #endif signal(SIGHUP, SigDone); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGHUP, 0); #endif signal(SIGQUIT, SigDone); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGQUIT, 0); #endif signal(SIGTERM, SigDone); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGTERM, 0); #endif signal(SIGCHLD, fvwmReapChildren); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGCHLD, 0); #endif #endif /* When fvwm restarts, the SIGCHLD handler is automatically reset * to the default handler. This means that Zombies left over from * the previous instance of fvwm could still be roaming the process * table if they exited while the default handler was in place. * We fix this by invoking the SIGCHLD handler NOW, so that they * may finally rest in peace. */ fvwmReapChildren(0); return; } void fvmm_deinstall_signals(void) { signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGPIPE, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGUSR1, SIG_DFL); return; } /*********************************************************************** * * LoadDefaultLeftButton -- loads default left button # into * assumes associated button memory is already free * ************************************************************************/ static void LoadDefaultLeftButton(DecorFace *df, int i) { struct vector_coords *v = &df->u.vector; int j = 0; memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = DefaultVectorButton; switch (i % 5) { case 0: case 4: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 22; v->y[0] = 39; v->c[0] = 1; v->x[1] = 78; v->y[1] = 39; v->c[1] = 1; v->x[2] = 78; v->y[2] = 61; v->x[3] = 22; v->y[3] = 61; v->x[4] = 22; v->y[4] = 39; v->c[4] = 1; break; case 1: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 32; v->y[0] = 45; v->x[1] = 68; v->y[1] = 45; v->x[2] = 68; v->y[2] = 55; v->c[2] = 1; v->x[3] = 32; v->y[3] = 55; v->c[3] = 1; v->x[4] = 32; v->y[4] = 45; break; case 2: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 49; v->y[0] = 49; v->c[0] = 1; v->x[1] = 51; v->y[1] = 49; v->c[1] = 1; v->x[2] = 51; v->y[2] = 51; v->x[3] = 49; v->y[3] = 51; v->x[4] = 49; v->y[4] = 49; v->c[4] = 1; break; case 3: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 32; v->y[0] = 45; v->c[0] = 1; v->x[1] = 68; v->y[1] = 45; v->c[1] = 1; v->x[2] = 68; v->y[2] = 55; v->x[3] = 32; v->y[3] = 55; v->x[4] = 32; v->y[4] = 45; v->c[4] = 1; break; } /* set offsets to 0, for all buttons */ for(j = 0 ; j < v->num ; j++) { v->xoff[j] = 0; v->yoff[j] = 0; } return; } /*********************************************************************** * * LoadDefaultRightButton -- loads default left button # into * assumes associated button memory is already free * ************************************************************************/ static void LoadDefaultRightButton(DecorFace *df, int i) { struct vector_coords *v = &df->u.vector; int j = 0; memset(&df->style, 0, sizeof(df->style)); DFS_FACE_TYPE(df->style) = DefaultVectorButton; switch (i % 5) { case 0: case 3: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 25; v->y[0] = 25; v->c[0] = 1; v->x[1] = 75; v->y[1] = 25; v->c[1] = 1; v->x[2] = 75; v->y[2] = 75; v->x[3] = 25; v->y[3] = 75; v->x[4] = 25; v->y[4] = 25; v->c[4] = 1; break; case 1: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 39; v->y[0] = 39; v->c[0] = 1; v->x[1] = 61; v->y[1] = 39; v->c[1] = 1; v->x[2] = 61; v->y[2] = 61; v->x[3] = 39; v->y[3] = 61; v->x[4] = 39; v->y[4] = 39; v->c[4] = 1; break; case 2: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 49; v->y[0] = 49; v->c[0] = 1; v->x[1] = 51; v->y[1] = 49; v->c[1] = 1; v->x[2] = 51; v->y[2] = 51; v->x[3] = 49; v->y[3] = 51; v->x[4] = 49; v->y[4] = 49; v->c[4] = 1; break; case 4: v->num = 5; v->x = (signed char*)safemalloc(sizeof(char) * v->num); v->y = (signed char*)safemalloc(sizeof(char) * v->num); v->xoff = (signed char*)safemalloc(sizeof(char) * v->num); v->yoff = (signed char*)safemalloc(sizeof(char) * v->num); v->c = (signed char*)safecalloc(v->num, sizeof(char)); v->x[0] = 36; v->y[0] = 36; v->c[0] = 1; v->x[1] = 64; v->y[1] = 36; v->c[1] = 1; v->x[2] = 64; v->y[2] = 64; v->x[3] = 36; v->y[3] = 64; v->x[4] = 36; v->y[4] = 36; v->c[4] = 1; break; } /* set offsets to 0, for all buttons */ for(j = 0 ; j < v->num ; j++) { v->xoff[j] = 0; v->yoff[j] = 0; } return; } /*********************************************************************** * * Procedure: * CreateGCs - open fonts and create all the needed GC's. I only * want to do this once, hence the first_time flag. * ***********************************************************************/ static void CreateGCs(void) { XGCValues gcv; unsigned long gcm; /* create scratch GC's */ gcm = GCFunction|GCLineWidth; gcv.function = GXcopy; gcv.line_width = 0; Scr.ScratchGC1 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.ScratchGC2 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.ScratchGC3 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.ScratchGC4 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.TitleGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.BordersGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.TransMaskGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv); Scr.ScratchMonoPixmap = XCreatePixmap(dpy, Scr.Root, 1, 1, 1); Scr.MonoGC = fvwmlib_XCreateGC(dpy, Scr.ScratchMonoPixmap, gcm, &gcv); Scr.ScratchAlphaPixmap = XCreatePixmap( dpy, Scr.Root, 1, 1, FRenderGetAlphaDepth()); Scr.AlphaGC = fvwmlib_XCreateGC(dpy, Scr.ScratchAlphaPixmap, gcm, &gcv); return; } /*********************************************************************** * * Procedure: * InitVariables - initialize fvwm variables * ************************************************************************/ static void InitVariables(void) { FvwmContext = XUniqueContext(); MenuContext = XUniqueContext(); /* initialize some lists */ Scr.AllBindings = NULL; Scr.functions = NULL; menus_init(); Scr.last_added_item.type = ADDED_NONE; Scr.DefaultIcon = NULL; Scr.DefaultColorset = -1; Scr.StdGC = 0; Scr.StdReliefGC = 0; Scr.StdShadowGC = 0; Scr.XorGC = 0; /* zero all flags */ memset(&Scr.flags, 0, sizeof(Scr.flags)); /* create graphics contexts */ CreateGCs(); FW_W(&Scr.FvwmRoot) = Scr.Root; Scr.FvwmRoot.next = 0; init_stack_and_layers(); Scr.root_pushes = 0; Scr.fvwm_pushes = 0; Scr.pushed_window = &Scr.FvwmRoot; Scr.FvwmRoot.number_cmap_windows = 0; Scr.FvwmRoot.attr_backup.colormap = Pcmap; Scr.MyDisplayWidth = DisplayWidth(dpy, Scr.screen); Scr.MyDisplayHeight = DisplayHeight(dpy, Scr.screen); Scr.BusyCursor = BUSY_NONE; Scr.Hilite = NULL; Scr.DefaultFont = NULL; Scr.VxMax = 2*Scr.MyDisplayWidth; Scr.VyMax = 2*Scr.MyDisplayHeight; Scr.Vx = 0; Scr.Vy = 0; Scr.SizeWindow = None; /* Sets the current desktop number to zero */ /* Multiple desks are available even in non-virtual * compilations */ Scr.CurrentDesk = 0; Scr.EdgeScrollX = DEFAULT_EDGE_SCROLL * Scr.MyDisplayWidth / 100; Scr.EdgeScrollY = DEFAULT_EDGE_SCROLL * Scr.MyDisplayHeight / 100; Scr.ScrollDelay = DEFAULT_SCROLL_DELAY; Scr.OpaqueSize = DEFAULT_OPAQUE_MOVE_SIZE; Scr.MoveThreshold = DEFAULT_MOVE_THRESHOLD; /* ClickTime is set to the positive value upon entering the * event loop. */ Scr.ClickTime = -DEFAULT_CLICKTIME; Scr.ColormapFocus = COLORMAP_FOLLOWS_MOUSE; /* set major operating modes */ Scr.NumBoxes = 0; Scr.cascade_x = 0; Scr.cascade_y = 0; /* the last Cascade placed window or NULL, we don't want NULL * initially */ Scr.cascade_window = &Scr.FvwmRoot; Scr.buttons2grab = 0; /* initialisation of the head of the desktops info */ Scr.Desktops = (DesktopsInfo *)safemalloc(sizeof(DesktopsInfo)); Scr.Desktops->name = NULL; Scr.Desktops->desk = 0; /* not desk 0 */ Scr.Desktops->ewmh_dyn_working_area.x = Scr.Desktops->ewmh_working_area.x = 0; Scr.Desktops->ewmh_dyn_working_area.y = Scr.Desktops->ewmh_working_area.y = 0; Scr.Desktops->ewmh_dyn_working_area.width = Scr.Desktops->ewmh_working_area.width = Scr.MyDisplayWidth; Scr.Desktops->ewmh_dyn_working_area.height = Scr.Desktops->ewmh_working_area.height = Scr.MyDisplayHeight; Scr.Desktops->next = NULL; /* ewmh desktop */ Scr.EwmhDesktop = NULL; InitFvwmDecor(&Scr.DefaultDecor); Scr.DefaultDecor.tag = "Default"; /* Initialize RaiseHackNeeded by identifying X servers possibly running under NT. This is probably not an ideal solution, since eg NCD also produces X servers which do not run under NT. "Hummingbird Communications Ltd." is the ServerVendor string of the Exceed X server under NT, "Network Computing Devices Inc." is the ServerVendor string of the PCXware X server under Windows. "WRQ, Inc." is the ServerVendor string of the Reflection X server under Windows. */ Scr.bo.is_raise_hack_needed = (strcmp ( ServerVendor (dpy), "Hummingbird Communications Ltd.") == 0) || (strcmp ( ServerVendor (dpy), "Network Computing Devices Inc.") == 0) || (strcmp (ServerVendor (dpy), "WRQ, Inc.") == 0); Scr.bo.is_modality_evil = 0; Scr.bo.do_disable_configure_notify = 0; Scr.bo.do_install_root_cmap = 0; Scr.bo.do_enable_flickering_qt_dialogs_workaround = 1; Scr.bo.do_enable_qt_drag_n_drop_workaround = 0; Scr.bo.do_enable_ewmh_iconic_state_workaround = 0; Scr.gs.do_emulate_mwm = DEFAULT_EMULATE_MWM; Scr.gs.do_emulate_win = DEFAULT_EMULATE_WIN; Scr.gs.use_active_down_buttons = DEFAULT_USE_ACTIVE_DOWN_BUTTONS; Scr.gs.use_inactive_buttons = DEFAULT_USE_INACTIVE_BUTTONS; Scr.gs.use_inactive_down_buttons = DEFAULT_USE_INACTIVE_DOWN_BUTTONS; /* Not the right place for this, should only be called once * somewhere .. */ /* EdgeCommands - no edge commands by default */ Scr.PanFrameTop.command = NULL; Scr.PanFrameBottom.command = NULL; Scr.PanFrameRight.command = NULL; Scr.PanFrameLeft.command = NULL; /* EdgeLeaveCommands - no edge leave commands by default */ Scr.PanFrameTop.command_leave = NULL; Scr.PanFrameBottom.command_leave = NULL; Scr.PanFrameRight.command_leave = NULL; Scr.PanFrameLeft.command_leave = NULL; Scr.flags.is_pointer_on_this_screen = !!FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &JunkX, &JunkY, &JunkMask); /* make sure colorset 0 exists */ alloc_colorset(0); return; } static void usage(int is_verbose) { fprintf(stderr, "usage: %s", g_argv[0]); fprintf(stderr, " [-d display]" " [-f cfgfile]" " [-c cmd]" " [-s [screen_num]]" " [-I vis-id | -C vis-class]" " [-l colors" " [-L|A|S|P] ...]" " [-r]" " [OTHER OPTIONS] ..." "\n"); if (!is_verbose) { fprintf( stderr, "Try '%s --help' for more information.\n", g_argv[0]); return; } fprintf(stderr, " -A: allocate palette\n" " -c cmd: preprocess configuration file with \n" " -C vis-class: use visual class \n" " -d display: run fvwm on \n" " -D: enable debug oputput\n" " -f cfgfile: read configuration from \n" " -F file: used internally for session management\n" " -h, -?: print this help message\n" " -i client-id: used internally for session management\n" " -I vis-id: use visual \n" " -l colors: try to use no more than colors\n" " -L: strict color limit\n" " -P: visual palette\n" " -r: replace running window manager\n" " -s [screen]: manage a single screen\n" " -S: static palette\n" " -V: print version information\n" ); fprintf( stderr, "Try 'man %s' for more information.\n", PACKAGE); return; } static void setVersionInfo(void) { char version_str[256]; char license_str[512]; char support_str[512] = ""; int support_len; /* Set version information string */ sprintf(version_str, "fvwm %s%s compiled on %s at %s", VERSION, VERSIONINFO, __DATE__, __TIME__); Fvwm_VersionInfo = safestrdup(version_str); sprintf(license_str, "fvwm comes with NO WARRANTY, to the extent permitted by law. " "You may\nredistribute copies of fvwm under " "the terms of the GNU General Public License.\n" "For more information about these matters, see the file " "named COPYING."); Fvwm_LicenseInfo = safestrdup(license_str); #ifdef HAVE_READLINE strcat(support_str, " ReadLine,"); #endif #ifdef HAVE_RPLAY strcat(support_str, " RPlay,"); #endif #ifdef HAVE_STROKE strcat(support_str, " Stroke,"); #endif #ifdef XPM strcat(support_str, " XPM,"); #endif #ifdef HAVE_RSVG strcat(support_str, " SVG,"); #endif if (FHaveShapeExtension) strcat(support_str, " Shape,"); #ifdef HAVE_XSHM strcat(support_str, " XShm,"); #endif #ifdef SESSION strcat(support_str, " SM,"); #endif #ifdef HAVE_BIDI strcat(support_str, " Bidi text,"); #endif #ifdef HAVE_XINERAMA strcat(support_str, " Xinerama,"); #endif #ifdef HAVE_XRENDER strcat(support_str, " XRender,"); #endif #ifdef HAVE_XCURSOR strcat(support_str, " XCursor,"); #endif #ifdef HAVE_XFT strcat(support_str, " XFT,"); #endif #ifdef HAVE_NLS strcat(support_str, " NLS,"); #endif support_len = strlen(support_str); if (support_len > 0) { /* strip last comma */ support_str[support_len - 1] = '\0'; Fvwm_SupportInfo = safestrdup( CatString2("with support for:", support_str)); } else { Fvwm_SupportInfo = "with no optional feature support"; } return; } /* Sets some initial style values & such */ static void SetRCDefaults(void) { #define RC_DEFAULTS_COMPLETE ((char *)-1) int i; /* set up default colors, fonts, etc */ const char *defaults[][3] = { { "XORValue 0", "", "" }, { "ImagePath "FVWM_DATADIR"/default-config/images", "", "" }, { "SetEnv FVWM_DATADIR "FVWM_DATADIR"", "", "" }, /* The below is historical -- before we had a default * configuration which defines these and more. */ { "DefaultFont", "", "" }, { "DefaultColors black grey", "", "" }, { DEFAULT_MENU_STYLE, "", "" }, { "TitleStyle Centered -- Raised", "", "" }, { "Style * Color lightgrey/dimgrey", "", "" }, { "Style * HilightFore black, HilightBack grey", "", "" }, { "DestroyFunc FvwmMakeMissingDesktopMenu", "", "" }, { "AddToFunc FvwmMakeMissingDesktopMenu I PipeRead 'fvwm-menu-desktop --enable-mini-icons --fvwm-icons'", "", "" }, { "AddToMenu MenuFvwmRoot \"", _("Builtin Menu"), "\" Title" }, { "+ MissingSubmenuFunction FvwmMakeMissingDesktopMenu","",""}, { "+ \"&1. XTerm\" Exec xterm", "", ""}, { "+ \"&2. ", _("Issue fvwm commands"), "\" Module FvwmConsole" }, { "+ \"&D. ", _("Desktop Menu"), "\" Popup FvwmMenu" }, { "+ \"&R. ", _("Restart fvwm"), "\" Restart" }, { "+ \"&X. ", _("Exit fvwm"), "\" Quit" }, { "Mouse 1 R A Menu MenuFvwmRoot", "", "" }, /* default menu navigation */ { "Key Escape M A MenuClose", "", "" }, { "Key Return M A MenuSelectItem", "", "" }, { "Key Left M A MenuCursorLeft", "", "" }, { "Key Right M A MenuCursorRight", "", "" }, { "Key Up M A MenuMoveCursor -1", "", "" }, { "Key Down M A MenuMoveCursor 1", "", "" }, { "Mouse 1 MI A MenuSelectItem", "", "" }, /* don't add anything below */ { RC_DEFAULTS_COMPLETE, "", "" }, { "Read "FVWM_DATADIR"/ConfigFvwmDefaults", "", "" }, { NULL, NULL, NULL } }; for (i = 0; defaults[i][0] != NULL; i++) { const exec_context_t *exc; exec_context_changes_t ecc; char *cmd; if (defaults[i][0] == RC_DEFAULTS_COMPLETE) { menu_bindings_startup_complete(); continue; } ecc.type = Restarting ? EXCT_RESTART : EXCT_INIT; ecc.w.wcontext = C_ROOT; exc = exc_create_context(&ecc, ECC_TYPE | ECC_WCONTEXT); cmd = CatString3( defaults[i][0], defaults[i][1], defaults[i][2]); execute_function(NULL, exc, cmd, 0); exc_destroy_context(exc); } #undef RC_DEFAULTS_COMPLETE return; } static int CatchRedirectError(Display *dpy, XErrorEvent *event) { fvwm_msg(ERR, "CatchRedirectError", "another WM is running"); exit(1); /* to make insure happy */ return 0; } /* CatchFatal - Shuts down if the server connection is lost */ static int CatchFatal(Display *dpy) { /* No action is taken because usually this action is caused by someone using "xlogout" to be able to switch between multiple window managers */ module_kill_all(); exit(1); /* to make insure happy */ return 0; } /* FvwmErrorHandler - displays info on internal errors */ static int FvwmErrorHandler(Display *dpy, XErrorEvent *event) { if (event->error_code == BadWindow) { bad_window = event->resourceid; return 0; } /* some errors are acceptable, mostly they're caused by * trying to update a lost window or free'ing another modules colors */ if (event->error_code == BadWindow || event->request_code == X_GetGeometry || event->error_code == BadDrawable || event->request_code == X_ConfigureWindow || event->request_code == X_SetInputFocus|| event->request_code == X_GrabButton || event->request_code == X_ChangeWindowAttributes || event->request_code == X_InstallColormap || event->request_code == X_FreePixmap || event->request_code == X_FreeColors) { return 0; } fvwm_msg(ERR, "FvwmErrorHandler", "*** internal error ***"); fvwm_msg(ERR, "FvwmErrorHandler", "Request %d, Error %d, EventType: %d", event->request_code, event->error_code, last_event_type); return 0; } /* ---------------------------- interface functions ------------------------ */ /* Does initial window captures and runs init/restart function */ void StartupStuff(void) { #define start_func_name "StartFunction" const char *init_func_name; const exec_context_t *exc; exec_context_changes_t ecc; ecc.type = Restarting ? EXCT_RESTART : EXCT_INIT; ecc.w.wcontext = C_ROOT; exc = exc_create_context(&ecc, ECC_TYPE | ECC_WCONTEXT); CaptureAllWindows(exc, False); /* Turn off the SM stuff after the initial capture so that new windows * will not be matched by accident. */ if (Restarting) { DisableRestoringState(); } /* Have to do this here too because preprocessor modules have not run * to the end when HandleEvents is entered from the main loop. */ checkPanFrames(); fFvwmInStartup = False; /* Make sure the geometry window uses the current font */ resize_geometry_window(); /* Make sure we have the correct click time now. */ if (Scr.ClickTime < 0) { Scr.ClickTime = -Scr.ClickTime; } # if 0 /* It is safe to ungrab here: if not, and one of the init functions * does not finish, we've got a complete freeze! */ /* DV (15-Jul-2004): No, it is not safe to ungrab. If another * application grabs the pointer before execute_function gets it, the * start functions are not executed. And the pointer is grabbed * during function execution anyway, so releasing it here buys us * nothing. */ UngrabEm(GRAB_STARTUP); XUngrabPointer(dpy, CurrentTime); #endif /* migo (04-Sep-1999): execute StartFunction */ if (functions_is_complex_function(start_func_name)) { char *action = "Function " start_func_name; execute_function(NULL, exc, action, 0); } /* migo (03-Jul-1999): execute [Session]{Init|Restart}Function */ init_func_name = get_init_function_name(Restarting == True); if (functions_is_complex_function(init_func_name)) { char *action = safestrdup( CatString2("Function ", init_func_name)); execute_function(NULL, exc, action, 0); free(action); } /* see comment above */ UngrabEm(GRAB_STARTUP); XUngrabPointer(dpy, CurrentTime); /* This should be done after the initialization is finished, since * it directly changes the global state. */ LoadGlobalState(state_filename); /* ** migo (20-Jun-1999): Remove state file after usage. ** migo (09-Jul-1999): but only on restart, otherwise it can be reused. */ if (Restarting) { unlink(state_filename); } exc_destroy_context(exc); /* TA: 20091212: If we get here, we're done restarting, so reset the * flag back to False! */ Restarting = False; return; } /*********************************************************************** * * LoadDefaultButton -- loads default button # into button structure * assumes associated button memory is already free * ************************************************************************/ void LoadDefaultButton(DecorFace *df, int i) { if (i & 1) { LoadDefaultRightButton(df, i / 2); } else { LoadDefaultLeftButton(df, i / 2); } return; } /*********************************************************************** * * ResetOrDestroyAllButtons -- resets all buttons to defaults * destroys existing buttons * ************************************************************************/ void DestroyAllButtons(FvwmDecor *decor) { TitleButton *tbp; DecorFace *face; int i; int j; for (tbp = decor->buttons, i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++, tbp++) { for (j = 0, face = TB_STATE(*tbp); j < BS_MaxButtonState; j++, face++) { FreeDecorFace(dpy, face); } } return; } void ResetAllButtons(FvwmDecor *decor) { TitleButton *tbp; DecorFace *face; int i; int j; DestroyAllButtons(decor); for (tbp = decor->buttons, i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++, tbp++) { memset(&TB_FLAGS(*tbp), 0, sizeof(TB_FLAGS(*tbp))); TB_JUSTIFICATION(*tbp) = JUST_CENTER; for (face = TB_STATE(*tbp), j = 0; j < BS_MaxButtonState; j++, face++) { LoadDefaultButton(face, i); } } /* standard MWM decoration hint assignments (veliaa@rpi.edu) [Menu] - Title Bar - [Minimize] [Maximize] */ TB_MWM_DECOR_FLAGS(decor->buttons[0]) |= MWM_DECOR_MENU; TB_MWM_DECOR_FLAGS(decor->buttons[1]) |= MWM_DECOR_MAXIMIZE; TB_MWM_DECOR_FLAGS(decor->buttons[3]) |= MWM_DECOR_MINIMIZE; return; } void SetMWM_INFO(Window window) { struct mwminfo { long props[2]; /* prop[0]: flags */ /* prop[1]: win */ } motif_wm_info; static char set_yorn='n'; if (set_yorn=='y') { return; } if (Scr.bo.is_modality_evil) { /* Set Motif WM_INFO atom to make motif relinquish * broken handling of modal dialogs */ motif_wm_info.props[0] = 2; motif_wm_info.props[1] = window; XChangeProperty( dpy,Scr.Root, _XA_MOTIF_WM, _XA_MOTIF_WM,32, PropModeReplace, (unsigned char *)&motif_wm_info, 2); set_yorn='y'; } return; } /* * set_init_function_name - sets one of the init, restart or exit function names * get_init_function_name - gets one of the init, restart or exit function names * * First parameter defines a function type: 0 - init, 1 - restart, 2 - exit. */ void set_init_function_name(int n, const char *name) { init_function_names[n >= 0 && n < 3? n: 3] = name; return; } const char *get_init_function_name(int n) { return init_function_names[n >= 0 && n < 3? n: 3]; } #ifndef _PATH_DEVNULL # define _PATH_DEVNULL "/dev/null" #endif static void reopen_fd(int fd, char* mode, FILE *of) { struct stat sbuf; FILE *f; int rc; errno = 0; rc = fstat(fd, &sbuf); if (rc == 0) { return; } else if (errno != EBADF) { exit(77); } f = freopen(_PATH_DEVNULL, mode, of); if (f == 0 || fileno(f) != fd) { exit(88); } return; } /*********************************************************************** * * Procedure: * main - start of fvwm * ***********************************************************************/ int main(int argc, char **argv) { unsigned long valuemask; XSetWindowAttributes attributes; int i; int len; char *display_string; Bool do_force_single_screen = False; int single_screen_num = -1; Bool replace_wm = False; int visualClass = -1; int visualId = -1; PictureColorLimitOption colorLimitop = {-1, -1, -1, -1, -1}; const exec_context_t *exc; exec_context_changes_t ecc; DBUG("main", "Entered, about to parse args"); fvwmlib_init_max_fd(); /* Tell the FEvent module an event type that is not used by fvwm. */ fev_init_invalid_event_type(KeymapNotify); /* close open fds */ for (i = 3; i < fvwmlib_max_fd; i++) { close(i); } /* reopen stdin, stdout and stderr if necessary */ reopen_fd(0, "rb", stdin); reopen_fd(1, "wb", stdout); reopen_fd(2, "wb", stderr); memset(&Scr, 0, sizeof(Scr)); /* for use on restart */ g_argv = (char **)safemalloc((argc + 4) * sizeof(char *)); g_argc = argc; for (i = 0; i < argc; i++) { g_argv[i] = argv[i]; } g_argv[g_argc] = NULL; FlocaleInit(LC_CTYPE, "", "", "fvwm"); FGettextInit("fvwm", LOCALEDIR, "fvwm"); setVersionInfo(); /* Put the default module directory into the environment so it can be * used later by the config file, etc. */ flib_putenv("FVWM_MODULEDIR", "FVWM_MODULEDIR=" FVWM_MODULEDIR); /* Figure out user's home directory */ home_dir = getenv("HOME"); #ifdef HAVE_GETPWUID if (home_dir == NULL) { struct passwd* pw = getpwuid(getuid()); if (pw != NULL) { home_dir = safestrdup(pw->pw_dir); } } #endif if (home_dir == NULL) { home_dir = "/"; /* give up and use root dir */ } /* Figure out where to read and write user's data files. */ fvwm_userdir = getenv("FVWM_USERDIR"); if (fvwm_userdir == NULL) { char *s; fvwm_userdir = safestrdup(CatString2(home_dir, "/.fvwm")); /* Put the user directory into the environment so it can be used * later everywhere. */ s = safestrdup(CatString2("FVWM_USERDIR=", fvwm_userdir)); flib_putenv("FVWM_USERDIR", s); free(s); } /* Create FVWM_USERDIR directory if needed */ if (access(fvwm_userdir, F_OK) != 0) { mkdir(fvwm_userdir, 0777); } if (access(fvwm_userdir, W_OK) != 0) { fvwm_msg( ERR, "main", "No write permissions in `%s/'.\n", fvwm_userdir); } for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-debug_stack_ring") == 0 || strcmp(argv[i], "--debug-stack-ring") == 0) { debugging_stack_ring = True; } else if (strcmp(argv[i], "-D") == 0 || strcmp(argv[i], "-debug") == 0 || strcmp(argv[i], "--debug") == 0) { debugging = True; } else if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "-clientid") == 0 || strcmp(argv[i], "--clientid") == 0 || strcmp(argv[i], "-clientId") == 0 || strcmp(argv[i], "--clientId") == 0) { if (++i >= argc) { usage(0); exit(1); } SetClientID(argv[i]); } else if (strcmp(argv[i], "-F") == 0 || strcmp(argv[i], "-restore") == 0 || strcmp(argv[i], "--restore") == 0) { if (++i >= argc) { usage(0); exit(1); } state_filename = argv[i]; } else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "-single-screen") == 0 || strcmp(argv[i], "--single-screen") == 0) { do_force_single_screen = True; if (i+1 < argc && argv[i+1][0] != '-') { i++; if (sscanf(argv[i], "%d", &single_screen_num) == 0) { usage(0); exit(1); } } } else if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "-display") == 0 || strcmp(argv[i], "--display") == 0) { if (++i >= argc) { usage(0); exit(1); } display_name = argv[i]; } else if (strcmp(argv[i], "-f") == 0) { if (++i >= argc) { usage(0); exit(1); } if (num_config_commands < MAX_CFG_CMDS) { config_commands[num_config_commands] = (char *)malloc(6+strlen(argv[i])); strcpy(config_commands[num_config_commands], "Read "); strcat(config_commands[num_config_commands], argv[i]); /* Check to see if the file requested exists. * If it doesn't, use the default config * instead. */ if (access(argv[i], F_OK) != 0) { free(config_commands[num_config_commands]); config_commands[num_config_commands] = safestrdup("Read " FVWM_DATADIR "/default-config/config"); } num_config_commands++; } else { fvwm_msg( ERR, "main", "only %d -f and -cmd parms allowed!", MAX_CFG_CMDS); } } else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "-cmd") == 0 || strcmp(argv[i], "--cmd") == 0) { if (++i >= argc) { usage(0); exit(1); } if (num_config_commands < MAX_CFG_CMDS) { config_commands[num_config_commands] = safestrdup(argv[i]); num_config_commands++; } else { fvwm_msg( ERR, "main", "only %d -f and -cmd parms allowed!", MAX_CFG_CMDS); } } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0 || strcmp(argv[i], "--help") == 0) { usage(1); exit(0); } else if (strcmp(argv[i], "-blackout") == 0) { /* obsolete option */ fvwm_msg( WARN, "main", "The -blackout option is obsolete, it will be " "removed in 3.0."); } else if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "-replace") == 0 || strcmp(argv[i], "--replace") == 0) { replace_wm = True; } /* check for visualId before visual to remove ambiguity */ else if (strcmp(argv[i], "-I") == 0 || strcmp(argv[i], "-visualid") == 0 || strcmp(argv[i], "--visualid") == 0 || strcmp(argv[i], "-visualId") == 0 || strcmp(argv[i], "--visualId") == 0) { visualClass = -1; if (++i >= argc) { usage(0); exit(1); } if (sscanf(argv[i], "0x%x", &visualId) == 0) { if (sscanf(argv[i], "%d", &visualId) == 0) { usage(0); exit(1); } } } else if (strcmp(argv[i], "-C") == 0 || strcmp(argv[i], "-visual") == 0 || strcmp(argv[i], "--visual") == 0) { visualId = None; if (++i >= argc) { usage(0); exit(1); } if (strncasecmp(argv[i], "staticg", 7) == 0) { visualClass = StaticGray; } else if (strncasecmp(argv[i], "g", 1) == 0) { visualClass = GrayScale; } else if (strncasecmp(argv[i], "staticc", 7) == 0) { visualClass = StaticColor; } else if (strncasecmp(argv[i], "p", 1) == 0) { visualClass = PseudoColor; } else if (strncasecmp(argv[i], "t", 1) == 0) { visualClass = TrueColor; } else if (strncasecmp(argv[i], "d", 1) == 0) { visualClass = DirectColor; } else { usage(0); exit(1); } } else if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-color-limit") == 0 || strcmp(argv[i], "--color-limit") == 0) { if (++i >= argc) { usage(0); exit(1); } colorLimitop.color_limit = atoi(argv[i]); } else if (strcmp(argv[i], "-L") == 0 || strcmp(argv[i], "-strict-color-limit") == 0 || strcmp(argv[i], "--strict-color-limit") == 0) { colorLimitop.strict = True; } else if (strcmp(argv[i], "-A") == 0 || strcmp(argv[i], "-allocate-palette") == 0 || strcmp(argv[i], "--allocate-palette") == 0) { colorLimitop.allocate = True; } else if (strcmp(argv[i], "-S") == 0 || strcmp(argv[i], "-static-palette") == 0 || strcmp(argv[i], "--static-palette") == 0) { colorLimitop.not_dynamic = True; } else if (strcmp(argv[i], "-P") == 0 || strcmp(argv[i], "-visual-palette") == 0 || strcmp(argv[i], "--visual-palette") == 0) { colorLimitop.use_named_table = True; } else if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "--version") == 0) { printf("%s\n%s\n\n%s\n", Fvwm_VersionInfo, Fvwm_SupportInfo, Fvwm_LicenseInfo); exit(0); } else { usage(0); fprintf(stderr, "invalid option -- %s\n", argv[i]); exit(1); } } DBUG("main", "Done parsing args"); DBUG("main", "Installing signal handlers"); InstallSignals(); if (single_screen_num >= 0) { char *dn = NULL; if (display_name) { dn = display_name; } if (!dn) { dn = getenv("DISPLAY"); } if (!dn) { /* should never happen ? */ if (!(dpy = XOpenDisplay(dn))) { fvwm_msg( ERR, "main", "can't open display %s" "to get the default display", XDisplayName(dn)); } else { dn = XDisplayString(dpy); } } if (dn == NULL) { fvwm_msg( ERR, "main", "couldn't find default display (%s)", XDisplayName(dn)); } else { char *new_dn; new_dn = get_display_name(dn, single_screen_num); if (dpy && strcmp(new_dn, dn) == 0) { /* allready opened */ Pdpy = dpy; } else if (dpy) { XCloseDisplay(dpy); dpy = NULL; } if (!dpy && !(Pdpy = dpy = XOpenDisplay(new_dn))) { fvwm_msg( ERR, "main", "can't open display %s, single screen " "number %d maybe not correct", new_dn, single_screen_num); } Scr.screen = single_screen_num; Scr.NumberOfScreens = ScreenCount(dpy); free(new_dn); } } if (!dpy) { if(!(Pdpy = dpy = XOpenDisplay(display_name))) { fvwm_msg( ERR, "main", "can't open display %s", XDisplayName(display_name)); exit (1); } Scr.screen= DefaultScreen(dpy); Scr.NumberOfScreens = ScreenCount(dpy); } atexit(catch_exit); master_pid = getpid(); if (!do_force_single_screen) { int myscreen = 0; char *new_dn; char *dn; dn = XDisplayString(dpy); for (i=0;i Pdepth) { Pvisual = vinfo[i].visual; Pdepth = vinfo[i].depth; } } if (vinfo) { XFree(vinfo); } /* Detection of a card with 2 hardware colormaps (8+24) which * use depth 8 for the default. We can use our own depth 24 * cmap without affecting other applications. */ if (Pdepth == 0 && DefaultDepth(dpy, Scr.screen) <= 8) { template.class = TrueColor; vinfo = XGetVisualInfo( dpy, VisualScreenMask|VisualClassMask, &template, &total); for(i = 0; i 8) { Pvisual = vinfo[i].visual; Pdepth = vinfo[i].depth; } } if (vinfo) { XFree(vinfo); } } /* have to have a colormap for non-default visual windows */ if (Pdepth > 0) { if (Pvisual->class == DirectColor) { Pcmap = XCreateColormap( dpy, Scr.Root, Pvisual, AllocAll); } else { Pcmap = XCreateColormap( dpy, Scr.Root, Pvisual, AllocNone); } } /* use default visuals if none found so far */ else { Pvisual = DefaultVisual(dpy, Scr.screen); Pdepth = DefaultDepth(dpy, Scr.screen); Pcmap = DefaultColormap(dpy, Scr.screen); Pdefault = True; } } PictureSetupWhiteAndBlack(); /* make a copy of the visual stuff so that XorPixmap can swap with root */ PictureSaveFvwmVisual(); Scr.ColorLimit = 0; PUseDynamicColors = 0; Scr.ColorLimit = PictureInitColors( PICTURE_CALLED_BY_FVWM, True, &colorLimitop, True, True); #ifdef Frsvg_init Frsvg_init(); #endif FShapeInit(dpy); FRenderInit(dpy); Scr.pscreen = XScreenOfDisplay(dpy, Scr.screen); Scr.use_backing_store = DoesBackingStore(Scr.pscreen); Scr.flags.do_save_under = DoesSaveUnders(Scr.pscreen); InternUsefulAtoms(); /* Make sure property priority colors is empty */ XChangeProperty(dpy, Scr.Root, _XA_MIT_PRIORITY_COLORS, XA_CARDINAL, 32, PropModeReplace, NULL, 0); Scr.FvwmCursors = CreateCursors(dpy); XDefineCursor(dpy, Scr.Root, Scr.FvwmCursors[CRS_ROOT]); /* create a window which will accept the keyboard focus when no other * windows have it */ /* do this before any RC parsing as some GC's are created from this * window rather than the root window */ attributes.event_mask = XEVMASK_NOFOCUSW; attributes.override_redirect = True; attributes.colormap = Pcmap; attributes.cursor = Scr.FvwmCursors[CRS_DEFAULT]; attributes.background_pixmap = None; attributes.border_pixel = 0; Scr.NoFocusWin=XCreateWindow( dpy, Scr.Root, -10, -10, 10, 10, 0, Pdepth, InputOutput, Pvisual, CWEventMask | CWOverrideRedirect | CWColormap | CWBackPixmap | CWBorderPixel | CWCursor, &attributes); XMapWindow(dpy, Scr.NoFocusWin); SetMWM_INFO(Scr.NoFocusWin); FOCUS_SET(Scr.NoFocusWin, NULL); frame_init(); XFlush(dpy); if (debugging) { sync_server(1); } SetupICCCM2(replace_wm); XSetIOErrorHandler(CatchFatal); { /* We need to catch any errors of XSelectInput on the root * window here. The event mask contains * SubstructureRedirectMask which can be acquired by exactly * one client (window manager). Synchronizing is necessary * here because Neither XSetErrorHandler nor XSelectInput * generate any protocol requests. */ XSync(dpy, 0); XSetErrorHandler(CatchRedirectError); XSelectInput(dpy, Scr.Root, XEVMASK_ROOTW); XSync(dpy, 0); XSetErrorHandler(FvwmErrorHandler); } { /* do not grab the pointer earlier because if fvwm exits with * the pointer grabbed while a different display is visible, * XFree 4.0 freezes. */ Cursor cursor = XCreateFontCursor(dpy, XC_watch); XGrabPointer( dpy, Scr.Root, 0, 0, GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime); } { Atom atype; int aformat; unsigned long nitems, bytes_remain; unsigned char *prop; if (XGetWindowProperty( dpy, Scr.Root, _XA_WM_DESKTOP, 0L, 1L, True, _XA_WM_DESKTOP, &atype, &aformat, &nitems, &bytes_remain, &prop) == Success) { if (prop != NULL) { Restarting = True; /* do_force_single_screen = True; */ } } } restart_state_filename = safestrdup( CatString3(fvwm_userdir, "/.fs-restart-", getenv("HOSTDISPLAY"))); if (!state_filename && Restarting) { state_filename = restart_state_filename; } /* This should be done early enough to have the window states loaded * before the first call to AddWindow. */ LoadWindowStates(state_filename); InitVariables(); if (visualClass != -1 || visualId != -1) { /* this is so that menus use the (non-default) fvwm colormap */ FW_W(&Scr.FvwmRoot) = Scr.NoFocusWin; Scr.FvwmRoot.number_cmap_windows = 1; Scr.FvwmRoot.cmap_windows = &Scr.NoFocusWin; } InitEventHandlerJumpTable(); Scr.gray_bitmap = XCreateBitmapFromData(dpy,Scr.Root,g_bits, g_width,g_height); EWMH_Init(); DBUG("main", "Setting up rc file defaults..."); SetRCDefaults(); flush_window_updates(); simplify_style_list(); DBUG("main", "Running config_commands..."); ecc.type = Restarting ? EXCT_RESTART : EXCT_INIT; ecc.w.wcontext = C_ROOT; exc = exc_create_context(&ecc, ECC_TYPE | ECC_WCONTEXT); if (num_config_commands > 0) { int i; for (i = 0; i < num_config_commands; i++) { DoingCommandLine = True; execute_function(NULL, exc, config_commands[i], 0); free(config_commands[i]); } DoingCommandLine = False; } else { /* Run startup command file in these places (default prefix): * ~/.fvwm/config * /usr/local/share/fvwm/config * and for compatibility: * ~/.fvwm/.fvwm2rc * /usr/local/share/fvwm/system.fvwm2rc * and for compatibility to be discontinued: * ~/.fvwm2rc, * /usr/local/share/fvwm/.fvwm2rc * /usr/local/etc/system.fvwm2rc */ if ( !run_command_file(CatString3( fvwm_userdir, "/", FVWM_CONFIG), exc) && !run_command_file(CatString3( FVWM_DATADIR, "/", FVWM_CONFIG), exc) && !run_command_file(CatString3( fvwm_userdir, "/", FVWM2RC), exc) && !run_command_file(CatString3( home_dir, "/", FVWM2RC), exc) && !run_command_file(CatString3( FVWM_DATADIR, "/", FVWM2RC), exc) && !run_command_file(CatString3( FVWM_DATADIR, "/system", FVWM2RC), exc) && !run_command_file(CatString3( FVWM_CONFDIR, "/system", FVWM2RC), exc) && !run_command_file(CatString3( FVWM_DATADIR, "/default-config/", "config"), exc)) { fvwm_msg( ERR, "main", "Cannot read startup config file," " tried: \n\t%s/%s\n\t%s/%s\n\t%s/%s\n\t" "%s/%s\n\t%s/%s\n\t%s/system%s\n\t%s/system%s", fvwm_userdir, FVWM_CONFIG, FVWM_DATADIR, FVWM_CONFIG, fvwm_userdir, FVWM2RC, home_dir, FVWM2RC, FVWM_DATADIR, FVWM2RC, FVWM_DATADIR, FVWM2RC, FVWM_CONFDIR, FVWM2RC); } } exc_destroy_context(exc); DBUG("main", "Done running config_commands"); if (Pdepth<2) { Scr.gray_pixmap = XCreatePixmapFromBitmapData( dpy, Scr.NoFocusWin, g_bits, g_width, g_height, PictureBlackPixel(), PictureWhitePixel(), Pdepth); Scr.light_gray_pixmap = XCreatePixmapFromBitmapData( dpy, Scr.NoFocusWin, l_g_bits, l_g_width, l_g_height, PictureBlackPixel(), PictureWhitePixel(), Pdepth); Scr.sticky_gray_pixmap = XCreatePixmapFromBitmapData( dpy, Scr.NoFocusWin, s_g_bits, s_g_width, s_g_height, PictureBlackPixel(), PictureWhitePixel(), Pdepth); } attributes.background_pixel = Scr.StdBack; attributes.colormap = Pcmap; attributes.border_pixel = 0; valuemask = CWBackPixel | CWColormap | CWBorderPixel; Scr.SizeWindow = XCreateWindow( dpy, Scr.Root, 0, 0, 1, 1, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); resize_geometry_window(); initPanFrames(); MyXGrabServer(dpy); checkPanFrames(); MyXUngrabServer(dpy); CoerceEnterNotifyOnCurrentWindow(); SessionInit(); DBUG("main", "Entering HandleEvents loop..."); HandleEvents(); switch (fvwmRunState) { case FVWM_DONE: Done(0, NULL); /* does not return */ case FVWM_RESTART: Done(1, ""); /* does not return */ default: DBUG("main", "Unknown fvwm run-state"); } exit(0); } fvwm-2.6.7/fvwm/colormaps.c0000644000175700017570000002474612773467232012620 00000000000000/* -*-c-*- */ /* 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 */ /* This module is all new * by Rob Nation * * This code handles colormaps for fvwm. * * Copyright 1994 Robert Nation. No restrictions are placed on this code, * as long as the copyright notice is preserved . No guarantees or * warrantees of any sort whatsoever are given or implied or anything. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "execcontext.h" #include "eventhandler.h" #include "functions.h" #include "bindings.h" #include "misc.h" #include "screen.h" #include "colormaps.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Bool client_controls_colormaps = False; static Colormap last_cmap = None; /* ---------------------------- exported variables (globals) --------------- */ const FvwmWindow *colormap_win; /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ void set_client_controls_colormaps(Bool flag) { client_controls_colormaps = flag; return; } /* HandleColormapNotify - colormap notify event handler * * This procedure handles both a client changing its own colormap, and * a client explicitly installing its colormap itself (only the window * manager should do that, so we must set it correctly). */ void colormap_handle_colormap_notify(const evh_args_t *ea) { XEvent evdummy; XColormapEvent *cevent = (XColormapEvent *)ea->exc->x.etrigger; Bool ReInstall = False; XWindowAttributes attr; FvwmWindow *fw = ea->exc->w.fw; if (!fw) { return; } if (cevent->new) { if (XGetWindowAttributes(dpy, FW_W(fw), &attr) != 0) { fw->attr_backup.colormap = attr.colormap; if (fw == colormap_win && fw->number_cmap_windows == 0) { last_cmap = attr.colormap; } ReInstall = True; } } else if ((cevent->state == ColormapUninstalled)&& (last_cmap == cevent->colormap)) { /* Some window installed its colormap, change it back */ ReInstall = True; } while (FCheckTypedEvent(dpy, ColormapNotify, &evdummy)) { if (XFindContext( dpy, cevent->window, FvwmContext, (caddr_t *) &fw) == XCNOENT) { fw = NULL; } if ((fw)&&(cevent->new)) { if (XGetWindowAttributes(dpy, FW_W(fw), &attr) != 0) { fw->attr_backup.colormap = attr.colormap; if (fw == colormap_win && fw->number_cmap_windows == 0) { last_cmap = attr.colormap; } ReInstall = True; } } else if ((fw)&& (cevent->state == ColormapUninstalled)&& (last_cmap == cevent->colormap)) { /* Some window installed its colormap, change it back */ ReInstall = True; } else if ((fw)&& (cevent->state == ColormapInstalled)&& (last_cmap == cevent->colormap)) { /* The last color map installed was the correct one. * Do not change anything */ ReInstall = False; } } /* Reinstall the colormap that we think should be installed, * UNLESS and unrecognized window has the focus - it might be * an override-redirect window that has its own colormap. */ if (ReInstall && Scr.UnknownWinFocused == None && !client_controls_colormaps) { XInstallColormap(dpy,last_cmap); } return; } /* Re-Install the active colormap */ void ReInstallActiveColormap(void) { InstallWindowColormaps(colormap_win); return; } /* Procedure: * InstallWindowColormaps - install the colormaps for one fvwm window * * Inputs: * type - type of event that caused the installation * tmp - for a subset of event types, the address of the * window structure, whose colormaps are to be installed. */ void InstallWindowColormaps(const FvwmWindow *fw) { int i; XWindowAttributes attributes; Window w; Bool ThisWinInstalled = False; /* If no window, then install fvwm colormap */ if (!fw) { fw = &Scr.FvwmRoot; } colormap_win = fw; /* Save the colormap to be loaded for when force loading of * root colormap(s) ends. */ Scr.pushed_window = fw; /* Don't load any new colormap if root/fvwm colormap(s) has been * force loaded. */ if (Scr.root_pushes || Scr.fvwm_pushes || client_controls_colormaps) { return; } if (fw->number_cmap_windows > 0) { for (i=fw->number_cmap_windows -1; i>=0;i--) { w = fw->cmap_windows[i]; if (w == FW_W(fw)) { ThisWinInstalled = True; } if (!XGetWindowAttributes(dpy,w,&attributes)) { attributes.colormap = last_cmap; } /* * On Sun X servers, don't install 24 bit TrueColor * colourmaps. Despite what the server says, these * colourmaps are always installed. */ if (last_cmap != attributes.colormap #if defined(sun) && defined(TRUECOLOR_ALWAYS_INSTALLED) && !(attributes.depth == 24 && attributes.visual->class == TrueColor) #endif ) { last_cmap = attributes.colormap; XInstallColormap(dpy, last_cmap); } } } if (!ThisWinInstalled) { if (last_cmap != fw->attr_backup.colormap #if defined(sun) && defined(TRUECOLOR_ALWAYS_INSTALLED) && !(fw->attr_backup.depth == 24 && fw->attr_backup.visual->class == TrueColor) #endif ) { last_cmap = fw->attr_backup.colormap; XInstallColormap(dpy, last_cmap); } } return; } /* Force (un)loads root colormap(s) * * These matching routines provide a mechanism to insure that * the root colormap(s) is installed during operations like * rubber banding that require colors from * that colormap. Calls may be nested arbitrarily deeply, * as long as there is one UninstallRootColormap call per * InstallRootColormap call. * * {Uni,I}nstall{Root,Fvwm}Colormap calls may be freely intermixed */ void InstallRootColormap(void) { if (last_cmap != DefaultColormap(dpy, Scr.screen)) { last_cmap = DefaultColormap(dpy, Scr.screen); XInstallColormap(dpy, last_cmap); } Scr.root_pushes++; return; } /* Unstacks one layer of root colormap pushing * If we peel off the last layer, re-install the application colormap * or the fvwm colormap if fvwm has a menu posted */ void UninstallRootColormap(void) { if (Scr.root_pushes) { Scr.root_pushes--; } if (!Scr.root_pushes) { if (!Scr.fvwm_pushes) { InstallWindowColormaps(Scr.pushed_window); } else if (last_cmap != Pcmap) { last_cmap = Pcmap; XInstallColormap(dpy, last_cmap); } } return; } /* Procedures: * {Uni/I}nstallFvwmColormap - Force (un)loads fvwm colormap(s) * This is used to ensure the fvwm colormap is installed during * menu operations */ void InstallFvwmColormap(void) { if (last_cmap != Pcmap) { last_cmap = Pcmap; XInstallColormap(dpy, last_cmap); } Scr.fvwm_pushes++; return; } void UninstallFvwmColormap(void) { if (Scr.fvwm_pushes) { Scr.fvwm_pushes--; } if (!Scr.fvwm_pushes) { if (!Scr.root_pushes) { InstallWindowColormaps(Scr.pushed_window); } else if (last_cmap != DefaultColormap(dpy, Scr.screen)) { last_cmap = DefaultColormap(dpy, Scr.screen); XInstallColormap(dpy, last_cmap); } } return; } /* Gets the WM_COLORMAP_WINDOWS property from the window * * This property typically doesn't exist, but a few applications * use it. These seem to occur mostly on SGI machines. */ void FetchWmColormapWindows (FvwmWindow *fw) { XWindowAttributes getattribs; XSetWindowAttributes setattribs; long i; unsigned long valuemask; if (fw->cmap_windows != (Window *)NULL) { XFree((void *)fw->cmap_windows); } if (!XGetWMColormapWindows (dpy, FW_W(fw), &(fw->cmap_windows), &(fw->number_cmap_windows))) { fw->number_cmap_windows = 0; fw->cmap_windows = NULL; } /* we need to be notified of Enter events into these subwindows * so we can set their colormaps */ if (fw->number_cmap_windows != 0) { for (i = 0; i < fw->number_cmap_windows; i++) { if (XGetWindowAttributes( dpy, fw->cmap_windows[i], &getattribs)) { valuemask = CWEventMask; setattribs.event_mask = getattribs.your_event_mask | EnterWindowMask | LeaveWindowMask; XChangeWindowAttributes( dpy, fw->cmap_windows[i], valuemask, &setattribs); } } } return; } /* Looks through the window list for any matching COLORMAP_WINDOWS * windows and installs the colormap if one exists. */ void EnterSubWindowColormap(Window win) { FvwmWindow *t; long i; XWindowAttributes attribs; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (t->number_cmap_windows != 0) { for (i = 0; i < t->number_cmap_windows; i++) { if (t->cmap_windows[i] == win) { if (XGetWindowAttributes( dpy,win,&attribs)) { last_cmap = attribs.colormap; XInstallColormap( dpy, last_cmap); } return; } } } } return; } void LeaveSubWindowColormap(Window win) { FvwmWindow *t; long i; int bWinInList, bParentInList; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (t->number_cmap_windows != 0) { bWinInList = 0; bParentInList = 0; for (i=0;inumber_cmap_windows;i++) { if (t->cmap_windows[i] == win) { bWinInList = 1; } if (t->cmap_windows[i] == FW_W(t)) { bParentInList = 1; } } if (bWinInList) { if (bParentInList) { InstallWindowColormaps(t); } else { InstallWindowColormaps(NULL); } return; } } } return; } fvwm-2.6.7/fvwm/menugeometry.h0000644000175700017570000000244512773467232013336 00000000000000/* -*-c-*- */ #ifndef MENU_GEOMETRY_H #define MENU_GEOMETRY_H /* ---------------------------- included header files ---------------------- */ /* Do not #include any files - the file including this file has to take care of * it. */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- forward declarations ----------------------- */ struct MenuRoot; struct MenuParameters; /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* Do not use global variable. Full stop. */ /* ---------------------------- interface functions ------------------------ */ /* * All functions in this file are to be used from menu*.c *only* */ Bool menu_get_geometry( struct MenuRoot *mr, Window *root_return, int *x_return, int *y_return, int *width_return, int *height_return, int *border_width_return, int *depth_return); Bool menu_get_outer_geometry( struct MenuRoot *mr, struct MenuParameters *pmp, Window *root_return, int *x_return, int *y_return, int *width_return, int *height_return, int *border_width_return, int *depth_return); #endif /* MENU_GEOMETRY_H */ fvwm-2.6.7/fvwm/condrc.c0000644000175700017570000000341112773467232012053 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "condrc.h" /* --------------------------- local definitions --------------------------- */ /* --------------------------- local macros -------------------------------- */ /* --------------------------- imports ------------------------------------- */ /* --------------------------- included code files ------------------------- */ /* --------------------------- local types --------------------------------- */ /* --------------------------- forward declarations ------------------------ */ /* --------------------------- local variables ----------------------------- */ /* --------------------------- exported variables (globals) ---------------- */ /* --------------------------- local functions ----------------------------- */ /* --------------------------- interface functions ------------------------- */ void condrc_init(cond_rc_t *cond_rc) { memset(cond_rc, 0, sizeof(*cond_rc)); cond_rc->rc = COND_RC_OK; return; } fvwm-2.6.7/fvwm/borders.c0000644000175700017570000035542313001406607012240 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* IMPORTANT NOTE: * * The functions in this module *must not* assume that the geometries in the * FvwmWindow structure reflect the desired geometry of the window or its * parts. While the window is resized or shaded, they may hold the old * geometry instead of the new one (but you can not rely on this). Therefore, * these geometries must not be accessed directly or indirectly (by the * functions from geometry,c). Use the geometries that are passed in via * structure pointers, e.d. "td". */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/Graphics.h" #include "libs/Picture.h" #include "libs/PictureGraphics.h" #include "libs/FRenderInit.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "execcontext.h" #include "externs.h" #include "misc.h" #include "screen.h" #include "geometry.h" #include "borders.h" #include "builtins.h" #include "icons.h" #include "frame.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ #define SWAP_ARGS(f,a1,a2) (f)?(a2):(a1),(f)?(a1):(a2) /* ---------------------------- imports ------------------------------------ */ extern Window PressedW; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { struct { unsigned use_pixmap : 1; } flags; Pixel pixel; struct { Pixmap p; Pixmap shape; Pixmap alpha; int depth; FvwmRenderAttributes fra; rectangle g; int stretch_w; int stretch_h; struct { unsigned is_tiled : 1; unsigned is_stretched : 1; } flags; } pixmap; } pixmap_background_type; typedef struct { Pixmap p; FvwmPicture *mp_created_pic; int cs; FvwmPicture *mp_pic; int mp_part; Bool created; } bar_pixmap; typedef struct { int count; bar_pixmap *bps; } bar_bs_pixmaps; /* for UseTitleStyle & Colorset */ typedef struct { Pixmap frame_pixmap; bar_bs_pixmaps bar_pixmaps[BS_MaxButtonState]; } dynamic_common_decorations; typedef struct { int relief_width; GC relief_gc; GC shadow_gc; Pixel fore_color; Pixel back_color; int cs; int border_cs; /* for UseBorderStyle */ int bg_border_cs; /* for UseBorderStyle */ Pixmap back_pixmap; XSetWindowAttributes attributes; unsigned long valuemask; Pixmap texture_pixmap; int texture_pixmap_width; int texture_pixmap_height; XSetWindowAttributes notex_attributes; unsigned long notex_valuemask; dynamic_common_decorations dynamic_cd; } common_decorations_type; typedef struct { GC relief; GC shadow; GC transparent; } draw_border_gcs; typedef struct { int offset_tl; int offset_br; int thickness; int length; unsigned has_x_marks : 1; unsigned has_y_marks : 1; } border_marks_descr; typedef struct { int w_dout; int w_hiout; int w_trout; int w_c; int w_trin; int w_shin; int w_din; int sum; int trim; unsigned is_flat : 1; } border_relief_size_descr; typedef struct { rectangle sidebar_g; border_relief_size_descr relief; border_marks_descr marks; draw_border_gcs gcs; } border_relief_descr; typedef struct { unsigned pressed_bmask : NUMBER_OF_TITLE_BUTTONS; unsigned lit_bmask : NUMBER_OF_TITLE_BUTTONS; unsigned toggled_bmask : NUMBER_OF_TITLE_BUTTONS; unsigned clear_bmask : NUMBER_OF_TITLE_BUTTONS; unsigned draw_bmask : NUMBER_OF_TITLE_BUTTONS; unsigned max_bmask : NUMBER_OF_TITLE_BUTTONS; ButtonState bstate[NUMBER_OF_TITLE_BUTTONS]; unsigned is_title_pressed : 1; unsigned is_title_lit : 1; unsigned do_clear_title : 1; ButtonState tstate; } border_titlebar_state; typedef struct { GC rgc; GC sgc; FlocaleWinString fstr; DecorFaceStyle *tstyle; DecorFace *df; unsigned is_toggled : 1; } title_draw_descr; typedef struct { common_decorations_type *cd; rectangle frame_g; rectangle bar_g; /* titlebar geo vs the frame */ rectangle left_buttons_g; /* vs the frame */ rectangle right_buttons_g; /* vs the frame */ frame_title_layout_t layout; frame_title_layout_t old_layout; border_titlebar_state tbstate; int length; /* text */ int offset; /* text offset */ /* MultiPixmap Geometries */ rectangle under_text_g; /* vs the titlebar */ rectangle left_main_g; /* vs the titlebar */ rectangle right_main_g; /* vs the titlebar */ rectangle full_left_main_g; /* vs the frame */ rectangle full_right_main_g; /* vs the frame */ int left_end_length; int left_of_text_length; int right_end_length; int right_of_text_length; rotation_t draw_rotation; rotation_t restore_rotation; unsigned td_is_rotated : 1; unsigned has_been_saved : 1; unsigned has_vt : 1; /* vertical title ? */ unsigned has_an_upsidedown_rotation : 1; /* 270 || 180 */ } titlebar_descr; /* ---------------------------- forward declarations ----------------------- */ /* forward declarations are not so good */ /* for grouping titlebar_descr computation */ static void border_rotate_titlebar_descr(FvwmWindow *fw, titlebar_descr *td); /* for grouping the MultiPixmap stuff */ static Bool border_mp_get_use_title_style_parts_and_geometry( titlebar_descr *td, FvwmPicture **pm, FvwmAcs *acs, unsigned short sf, int is_left, rectangle *g, int *part); /* ---------------------------- local variables ---------------------------- */ static const char ulgc[] = { 1, 0, 0, 0x7f, 2, 1, 1 }; static const char brgc[] = { 1, 1, 2, 0x7f, 0, 0, 3 }; /* ---------------------------- exported variables (globals) --------------- */ XGCValues Globalgcv; unsigned long Globalgcm; /* ---------------------------- local functions ---------------------------- */ static Bool is_button_toggled( FvwmWindow *fw, int button) { mwm_flags mf; if (!HAS_MWM_BUTTONS(fw)) { return False; } mf = TB_MWM_DECOR_FLAGS(GetDecor(fw, buttons[button])); if ((mf & MWM_DECOR_MAXIMIZE) && IS_MAXIMIZED(fw)) { return True; } if ((mf & MWM_DECOR_SHADE) && IS_SHADED(fw)) { return True; } if ((mf & MWM_DECOR_STICK) && (IS_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw))) { return True; } if (TB_FLAGS(fw->decor->buttons[button]).has_layer && fw->layer == TB_LAYER(fw->decor->buttons[button])) { return True; } return False; } /* rules to get button state */ static ButtonState border_flags_to_button_state( int is_pressed, int is_lit, int is_toggled) { if (!is_lit && Scr.gs.use_inactive_buttons) { if (is_pressed && Scr.gs.use_inactive_down_buttons) { return (is_toggled) ? BS_ToggledInactiveDown : BS_InactiveDown; } else { return (is_toggled) ? BS_ToggledInactiveUp : BS_InactiveUp; } } else { if (is_pressed && Scr.gs.use_active_down_buttons) { return (is_toggled) ? BS_ToggledActiveDown : BS_ActiveDown; } else { return (is_toggled) ? BS_ToggledActiveUp : BS_ActiveUp; } } } static void get_common_decorations( common_decorations_type *cd, FvwmWindow *t, window_parts draw_parts, Bool has_focus, Bool is_border, Bool do_change_gcs) { DecorFace *df; color_quad *draw_colors; df = border_get_border_style(t, has_focus); cd->bg_border_cs = -1; cd->cs = -1; if (has_focus) { /* are we using textured borders? */ if (DFS_FACE_TYPE(df->style) == TiledPixmapButton && GetDecor(t, BorderStyle.active.u.p->depth) == Pdepth) { cd->texture_pixmap = GetDecor( t, BorderStyle.active.u.p->picture); cd->texture_pixmap_width = GetDecor( t, BorderStyle.active.u.p->width); cd->texture_pixmap_height = GetDecor( t, BorderStyle.active.u.p->height); } else if (DFS_FACE_TYPE(df->style) == ColorsetButton) { cd->bg_border_cs = GetDecor( t, BorderStyle.active.u.acs.cs); } cd->back_pixmap = Scr.gray_pixmap; if (is_border) { draw_colors = &(t->border_hicolors); cd->cs = t->border_cs_hi; } else { draw_colors = &(t->hicolors); cd->cs = t->cs_hi; } } else { if (DFS_FACE_TYPE(df->style) == TiledPixmapButton && GetDecor(t, BorderStyle.inactive.u.p->depth) == Pdepth) { cd->texture_pixmap = GetDecor( t, BorderStyle.inactive.u.p->picture); cd->texture_pixmap_width = GetDecor( t, BorderStyle.inactive.u.p->width); cd->texture_pixmap_height = GetDecor( t, BorderStyle.inactive.u.p->height); } else if (DFS_FACE_TYPE(df->style) == ColorsetButton) { cd->bg_border_cs = GetDecor( t, BorderStyle.inactive.u.acs.cs); } if (IS_STICKY_ACROSS_PAGES(t) || IS_STICKY_ACROSS_DESKS(t)) { cd->back_pixmap = Scr.sticky_gray_pixmap; } else { cd->back_pixmap = Scr.light_gray_pixmap; } if (is_border) { draw_colors = &(t->border_colors); cd->cs = t->border_cs; } else { draw_colors = &(t->colors); cd->cs = t->cs; } } cd->fore_color = draw_colors->fore; cd->back_color = draw_colors->back; if (do_change_gcs) { Globalgcv.foreground = draw_colors->hilight; Globalgcm = GCForeground; XChangeGC(dpy, Scr.ScratchGC1, Globalgcm, &Globalgcv); Globalgcv.foreground = draw_colors->shadow; XChangeGC(dpy, Scr.ScratchGC2, Globalgcm, &Globalgcv); cd->relief_gc = Scr.ScratchGC1; cd->shadow_gc = Scr.ScratchGC2; } /* MWMBorder style means thin 3d effects */ cd->relief_width = (HAS_MWM_BORDER(t) ? 1 : 2); if (cd->texture_pixmap) { cd->attributes.background_pixmap = cd->texture_pixmap; cd->valuemask = CWBackPixmap; } else { if (Pdepth < 2) { cd->attributes.background_pixmap = cd->back_pixmap; cd->valuemask = CWBackPixmap; } else { cd->attributes.background_pixel = cd->back_color; cd->valuemask = CWBackPixel; } } if (Pdepth < 2) { cd->notex_attributes.background_pixmap = cd->back_pixmap; cd->notex_valuemask = CWBackPixmap; } else { cd->notex_attributes.background_pixel = cd->back_color; cd->notex_valuemask = CWBackPixel; } return; } static window_parts border_get_changed_border_parts( FvwmWindow *fw, rectangle *old_sidebar_g, rectangle *new_sidebar_g, int cs) { window_parts changed_parts; changed_parts = PART_NONE; if (!CSET_IS_TRANSPARENT_PR(cs) && CSET_HAS_PIXMAP(cs) && (old_sidebar_g->x != new_sidebar_g->x || old_sidebar_g->y != new_sidebar_g->y || old_sidebar_g->width != new_sidebar_g->width || old_sidebar_g->height != new_sidebar_g->height)) { /* optimizable? */ changed_parts |= PART_FRAME; return changed_parts; } if (old_sidebar_g->x != new_sidebar_g->x) { changed_parts |= (PART_FRAME & (~PART_BORDER_W)); } if (old_sidebar_g->y != new_sidebar_g->y) { changed_parts |= (PART_FRAME & (~PART_BORDER_N)); } if (old_sidebar_g->width != new_sidebar_g->width) { changed_parts |= PART_BORDER_N | PART_BORDER_S; if (DFS_FACE_TYPE(GetDecor(fw, BorderStyle.active.style)) == TiledPixmapButton) { changed_parts |= PART_BORDER_NE | PART_BORDER_E | PART_BORDER_SE; } } if (old_sidebar_g->height != new_sidebar_g->height) { changed_parts |= PART_BORDER_W | PART_BORDER_E; if (DFS_FACE_TYPE(GetDecor(fw, BorderStyle.active.style)) == TiledPixmapButton) { changed_parts |= PART_BORDER_SW | PART_BORDER_S | PART_BORDER_SE; } } return changed_parts; } static int border_get_parts_and_pos_to_draw( common_decorations_type *cd, FvwmWindow *fw, window_parts pressed_parts, window_parts force_draw_parts, rectangle *old_g, rectangle *new_g, Bool do_hilight, border_relief_descr *br) { window_parts draw_parts; window_parts parts_to_light; rectangle sidebar_g_old; DecorFaceStyle *borderstyle; Bool has_x_marks; Bool has_x_marks_old; Bool has_y_marks; Bool has_y_marks_old; int cs = cd->bg_border_cs; draw_parts = 0; borderstyle = (do_hilight) ? &GetDecor(fw, BorderStyle.active.style) : &GetDecor(fw, BorderStyle.inactive.style); frame_get_sidebar_geometry( fw, borderstyle, new_g, &br->sidebar_g, &has_x_marks, &has_y_marks); if (has_x_marks == True) { draw_parts |= PART_X_HANDLES; br->marks.has_x_marks = 1; } else { br->marks.has_x_marks = 0; } if (has_y_marks == True) { draw_parts |= PART_Y_HANDLES; br->marks.has_y_marks = 1; } else { br->marks.has_y_marks = 0; } draw_parts |= (pressed_parts ^ fw->decor_state.parts_inverted); parts_to_light = (do_hilight == True) ? PART_FRAME : PART_NONE; draw_parts |= (parts_to_light ^ fw->decor_state.parts_lit); draw_parts |= (~(fw->decor_state.parts_drawn) & PART_FRAME); draw_parts |= force_draw_parts; if (old_g == NULL) { old_g = &fw->g.frame; } if ((draw_parts & PART_FRAME) == PART_FRAME) { draw_parts |= PART_FRAME; return draw_parts; } frame_get_sidebar_geometry( fw, borderstyle, old_g, &sidebar_g_old, &has_x_marks_old, &has_y_marks_old); if (has_x_marks_old != has_x_marks) { draw_parts |= (PART_FRAME & (~(PART_BORDER_N | PART_BORDER_S))); } if (has_y_marks_old != has_y_marks) { draw_parts |= (PART_FRAME & (~(PART_BORDER_W | PART_BORDER_E))); } draw_parts |= border_get_changed_border_parts( fw, &sidebar_g_old, &br->sidebar_g, cs); draw_parts &= (PART_FRAME | PART_HANDLES); return draw_parts; } static window_parts border_get_tb_parts_to_draw( FvwmWindow *fw, titlebar_descr *td, rectangle *old_g, rectangle *new_g, window_parts force_draw_parts) { window_parts draw_parts; ButtonState old_state; int i; DecorFace *df,*tdf; td->tbstate.draw_bmask = 0; draw_parts = PART_NONE; /* first time? */ draw_parts |= (~(fw->decor_state.parts_drawn) & PART_TITLE); td->tbstate.draw_bmask |= (~(fw->decor_state.buttons_drawn)); /* forced? */ draw_parts |= force_draw_parts; td->tbstate.draw_bmask |= (force_draw_parts & PART_BUTTONS) ? ~0 : 0; /* check if state changed */ old_state = border_flags_to_button_state( (fw->decor_state.parts_inverted & PART_TITLE), (fw->decor_state.parts_lit & PART_TITLE), 0); if (old_state != td->tbstate.tstate) { draw_parts |= PART_TITLE; } /* size changed? */ if ((td->old_layout.title_g.width != td->layout.title_g.width || td->old_layout.title_g.height != td->layout.title_g.height) && td->layout.title_g.x >= 0 && td->layout.title_g.y >= 0) { draw_parts |= PART_TITLE; } /* same for buttons */ for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { unsigned int mask = (1 << i); if (FW_W_BUTTON(fw, i) == None) { continue; } old_state = border_flags_to_button_state( (fw->decor_state.buttons_inverted & mask), (fw->decor_state.buttons_lit & mask), (fw->decor_state.buttons_toggled & mask)); if (old_state != td->tbstate.bstate[i]) { draw_parts |= PART_BUTTONS; td->tbstate.draw_bmask |= mask; } if ((td->old_layout.button_g[i].width != td->layout.button_g[i].width || td->old_layout.button_g[i].height != td->layout.button_g[i].height) && td->layout.button_g[i].x >= 0 && td->layout.button_g[i].y >= 0) { draw_parts |= PART_BUTTONS; td->tbstate.draw_bmask |= mask; } } /* position changed and background is tiled or a cset? */ if ((draw_parts & PART_TITLE) == PART_NONE && td->layout.title_g.x >= 0 && td->layout.title_g.y >= 0) { df = &TB_STATE(GetDecor(fw, titlebar))[td->tbstate.tstate]; if (DFS_USE_BORDER_STYLE(df->style) && (((td->old_layout.title_g.x != td->layout.title_g.x || td->old_layout.title_g.y != td->layout.title_g.y) && ((td->cd->valuemask & CWBackPixmap) || CSET_PIXMAP_IS_TILED(td->cd->bg_border_cs))) || (old_g->width != new_g->width && CSET_PIXMAP_IS_X_STRETCHED(td->cd->bg_border_cs)) || (old_g->height != new_g->height && CSET_PIXMAP_IS_Y_STRETCHED(td->cd->bg_border_cs)) || ((old_g->x != new_g->x || old_g->y != new_g->y) && CSET_IS_TRANSPARENT_ROOT(td->cd->bg_border_cs)))) { draw_parts |= PART_TITLE; } if ((draw_parts & PART_TITLE) == PART_NONE && (old_g->x != new_g->x || old_g->y != new_g->y)) { for (tdf = df; tdf != NULL; tdf = tdf->next) { if (DFS_FACE_TYPE(tdf->style) == ColorsetButton && CSET_IS_TRANSPARENT_ROOT(tdf->u.acs.cs)) { draw_parts |= PART_TITLE; break; } } } } for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { unsigned int mask; DecorFaceStyle *bs; mask = (1 << i); bs = &TB_STATE( GetDecor(fw, buttons[i]))[td->tbstate.bstate[i]].style; if ((td->tbstate.draw_bmask & mask) || td->layout.button_g[i].x < 0 || td->layout.button_g[i].y < 0) { continue; } if (DFS_USE_BORDER_STYLE(*bs) && (((td->old_layout.button_g[i].x != td->layout.button_g[i].x|| td->old_layout.button_g[i].y != td->layout.button_g[i].y) && ((td->cd->valuemask & CWBackPixmap) || CSET_PIXMAP_IS_TILED(td->cd->bg_border_cs))) || (old_g->width != new_g->width && CSET_PIXMAP_IS_X_STRETCHED(td->cd->bg_border_cs)) || (old_g->height != new_g->height && CSET_PIXMAP_IS_Y_STRETCHED(td->cd->bg_border_cs)) || ((old_g->x != new_g->x || old_g->y != new_g->y) && CSET_IS_TRANSPARENT_ROOT(td->cd->bg_border_cs)))) { td->tbstate.draw_bmask |= mask; } else if (DFS_USE_TITLE_STYLE(*bs)) { df = &TB_STATE(GetDecor( fw, titlebar))[td->tbstate.bstate[i]]; for(tdf = df; tdf != NULL; tdf = tdf->next) { int cs; if (DFS_FACE_TYPE(tdf->style) == MultiPixmap) { /* can be improved */ td->tbstate.draw_bmask |= mask; break; } if (DFS_FACE_TYPE(tdf->style) != ColorsetButton || !CSET_HAS_PIXMAP(tdf->u.acs.cs)) { continue; } cs = tdf->u.acs.cs; if(((td->old_layout.button_g[i].x != td->layout.button_g[i].x || td->old_layout.button_g[i].y != td->layout.button_g[i].y) || CSET_PIXMAP_IS_TILED(cs)) || (old_g->width != new_g->width && CSET_PIXMAP_IS_X_STRETCHED(cs)) || (old_g->height != new_g->height && CSET_PIXMAP_IS_Y_STRETCHED(cs)) || ((old_g->x != new_g->x || old_g->y != new_g->y) && CSET_IS_TRANSPARENT_ROOT(cs))) { td->tbstate.draw_bmask |= mask; break; } } } if (td->tbstate.draw_bmask & mask) { continue; } if (old_g->x != new_g->x || old_g->y != new_g->y) { df = &TB_STATE(GetDecor( fw, buttons[i]))[td->tbstate.bstate[i]]; for(tdf = df; tdf != NULL; tdf = tdf->next) { if (DFS_FACE_TYPE(tdf->style) == ColorsetButton && CSET_IS_TRANSPARENT_ROOT(tdf->u.acs.cs)) { td->tbstate.draw_bmask |= mask; break; } } } } td->tbstate.max_bmask = 0; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if (FW_W_BUTTON(fw, i) == None) { continue; } if ((i & 1) == 1 && i / 2 < Scr.nr_right_buttons) { td->tbstate.max_bmask |= (1 << i); } else if ((i & 1) == 0 && i / 2 < Scr.nr_left_buttons) { td->tbstate.max_bmask |= (1 << i); } } td->tbstate.draw_bmask &= td->tbstate.max_bmask; td->tbstate.pressed_bmask &= td->tbstate.max_bmask; td->tbstate.lit_bmask &= td->tbstate.max_bmask; td->tbstate.toggled_bmask &= td->tbstate.max_bmask; td->tbstate.clear_bmask &= td->tbstate.max_bmask; if (td->tbstate.draw_bmask == 0) { draw_parts &= ~PART_BUTTONS; } else { draw_parts |= PART_BUTTONS; } draw_parts &= PART_TITLEBAR; return draw_parts; } static void border_get_border_gcs( draw_border_gcs *ret_gcs, common_decorations_type *cd, FvwmWindow *fw, Bool do_hilight) { static GC transparent_gc = None; DecorFaceStyle *borderstyle; Bool is_reversed = False; if (transparent_gc == None && !HAS_NO_BORDER(fw) && !HAS_MWM_BORDER(fw)) { XGCValues xgcv; xgcv.function = GXnoop; xgcv.plane_mask = 0; transparent_gc = fvwmlib_XCreateGC( dpy, Scr.NoFocusWin, GCFunction | GCPlaneMask, &xgcv); } ret_gcs->transparent = transparent_gc; /* get the border style bits */ borderstyle = (do_hilight) ? &GetDecor(fw, BorderStyle.active.style) : &GetDecor(fw, BorderStyle.inactive.style); if (borderstyle->flags.button_relief == DFS_BUTTON_IS_SUNK) { is_reversed = True; } if (is_reversed) { ret_gcs->shadow = cd->relief_gc; ret_gcs->relief = cd->shadow_gc; } else { ret_gcs->relief = cd->relief_gc; ret_gcs->shadow = cd->shadow_gc; } return; } static void trim_border_layout( FvwmWindow *fw, DecorFaceStyle *borderstyle, border_relief_size_descr *ret_size_descr) { /* If the border is too thin to accomodate the standard look, we remove * parts of the border so that at least one pixel of the original * colour is visible. We make an exception for windows with a border * width of 2, though. */ if ((!IS_SHADED(fw) || HAS_TITLE(fw)) && fw->boundary_width == 2) { ret_size_descr->trim--; } if (ret_size_descr->trim < 0) { ret_size_descr->trim = 0; } for ( ; ret_size_descr->trim > 0; ret_size_descr->trim--) { if (ret_size_descr->w_hiout > 1) { ret_size_descr->w_hiout--; } else if (ret_size_descr->w_shin > 0) { ret_size_descr->w_shin--; } else if (ret_size_descr->w_hiout > 0) { ret_size_descr->w_hiout--; } else if (ret_size_descr->w_trout > 0) { ret_size_descr->w_trout = 0; ret_size_descr->w_trin = 0; ret_size_descr->w_din = 0; ret_size_descr->w_hiout = 1; } ret_size_descr->sum--; } ret_size_descr->w_c = fw->boundary_width - ret_size_descr->sum; return; } static void check_remove_inset( DecorFaceStyle *borderstyle, border_relief_size_descr *ret_size_descr) { if (!DFS_HAS_NO_INSET(*borderstyle)) { return; } ret_size_descr->w_shin = 0; ret_size_descr->sum--; ret_size_descr->trim--; if (ret_size_descr->w_trin) { ret_size_descr->w_trout = 0; ret_size_descr->w_trin = 0; ret_size_descr->w_din = 0; ret_size_descr->w_hiout = 1; ret_size_descr->sum -= 2; ret_size_descr->trim -= 2; } return; } static void border_fetch_mwm_layout( FvwmWindow *fw, DecorFaceStyle *borderstyle, border_relief_size_descr *ret_size_descr) { /* MWM borders look like this: * * HHCCCCS from outside to inside on the left and top border * SSCCCCH from outside to inside on the bottom and right border * ||||||| * |||||||__ w_shin (inner shadow area) * ||||||___ w_c (transparent area) * |||||____ w_c (transparent area) * ||||_____ w_c (transparent area) * |||______ w_c (transparent area) * ||_______ w_hiout (outer hilight area) * |________ w_hiout (outer hilight area) * * * C = original colour * H = hilight * S = shadow */ ret_size_descr->w_dout = 0; ret_size_descr->w_hiout = 2; ret_size_descr->w_trout = 0; ret_size_descr->w_trin = 0; ret_size_descr->w_shin = 1; ret_size_descr->w_din = 0; ret_size_descr->sum = 3; ret_size_descr->trim = ret_size_descr->sum - fw->boundary_width + 1; check_remove_inset(borderstyle, ret_size_descr); trim_border_layout(fw, borderstyle, ret_size_descr); return; } static void border_fetch_fvwm_layout( FvwmWindow *fw, DecorFaceStyle *borderstyle, border_relief_size_descr *ret_size_descr) { /* Fvwm borders look like this: * * SHHCCSS from outside to inside on the left and top border * SSCCHHS from outside to inside on the bottom and right border * ||||||| * |||||||__ w_din (inner dark area) * ||||||___ w_shin (inner shadow area) * |||||____ w_trin (inner transparent/shadow area) * ||||_____ w_c (transparent area) * |||______ w_trout (outer transparent/hilight area) * ||_______ w_hiout (outer hilight area) * |________ w_dout (outer dark area) * * C = original colour * H = hilight * S = shadow * * reduced to 5 pixels it looks like this: * * SHHCS * SSCHS * ||||| * |||||__ w_din (inner dark area) * ||||___ w_trin (inner transparent/shadow area) * |||____ w_trout (outer transparent/hilight area) * ||_____ w_hiout (outer hilight area) * |______ w_dout (outer dark area) */ ret_size_descr->w_dout = 1; ret_size_descr->w_hiout = 1; ret_size_descr->w_trout = 1; ret_size_descr->w_trin = 1; ret_size_descr->w_shin = 1; ret_size_descr->w_din = 1; /* w_trout + w_trin counts only as one pixel of border because * they let one pixel of the original colour shine through. */ ret_size_descr->sum = 6; ret_size_descr->trim = ret_size_descr->sum - fw->boundary_width; check_remove_inset(borderstyle, ret_size_descr); trim_border_layout(fw, borderstyle, ret_size_descr); return; } static void border_get_border_relief_size_descr( border_relief_size_descr *ret_size_descr, FvwmWindow *fw, Bool do_hilight) { DecorFaceStyle *borderstyle; if (is_window_border_minimal(fw)) { /* the border is too small, only a background but no relief */ ret_size_descr->is_flat = 1; return; } borderstyle = (do_hilight) ? &GetDecor(fw, BorderStyle.active.style) : &GetDecor(fw, BorderStyle.inactive.style); if (borderstyle->flags.button_relief == DFS_BUTTON_IS_FLAT) { ret_size_descr->is_flat = 1; return; } ret_size_descr->is_flat = 0; /* get the relief layout */ if (HAS_MWM_BORDER(fw)) { border_fetch_mwm_layout(fw, borderstyle, ret_size_descr); } else { border_fetch_fvwm_layout(fw, borderstyle, ret_size_descr); } return; } static void border_get_border_marks_descr( common_decorations_type *cd, border_relief_descr *br, FvwmWindow *fw) { int inset; /* get mark's length and thickness */ inset = (br->relief.w_shin != 0 || br->relief.w_din != 0); br->marks.length = fw->boundary_width - br->relief.w_dout - inset; if (br->marks.length <= 0) { br->marks.has_x_marks = 0; br->marks.has_y_marks = 0; return; } br->marks.thickness = cd->relief_width; if (br->marks.thickness > br->marks.length) { br->marks.thickness = br->marks.length; } /* get offsets from outer side of window */ br->marks.offset_tl = br->relief.w_dout; br->marks.offset_br = -br->relief.w_dout - br->marks.length - br->marks.offset_tl; return; } static Pixmap border_create_decor_pixmap( common_decorations_type *cd, rectangle *decor_g) { Pixmap p; p = XCreatePixmap( dpy, Scr.Root, decor_g->width, decor_g->height, Pdepth); return p; } static void border_draw_part_relief( border_relief_descr *br, rectangle *frame_g, rectangle *part_g, Pixmap dest_pix, Bool is_inverted) { int i; int off_x = 0; int off_y = 0; int width = frame_g->width - 1; int height = frame_g->height - 1; int w[7]; GC gc[4]; w[0] = br->relief.w_dout; w[1] = br->relief.w_hiout; w[2] = br->relief.w_trout; w[3] = br->relief.w_c; w[4] = br->relief.w_trin; w[5] = br->relief.w_shin; w[6] = br->relief.w_din; gc[(is_inverted == True)] = br->gcs.relief; gc[!(is_inverted == True)] = br->gcs.shadow; gc[2] = br->gcs.transparent; gc[3] = br->gcs.shadow; off_x = -part_g->x; off_y = -part_g->y; width = frame_g->width - 1; height = frame_g->height - 1; for (i = 0; i < 7; i++) { if (ulgc[i] != 0x7f && w[i] > 0) { do_relieve_rectangle( dpy, dest_pix, off_x, off_y, width, height, gc[(int)ulgc[i]], gc[(int)brgc[i]], w[i], False); } off_x += w[i]; off_y += w[i]; width -= 2 * w[i]; height -= 2 * w[i]; } return; } static void border_draw_x_mark( border_relief_descr *br, int x, int y, Pixmap dest_pix, Bool do_draw_shadow) { int k; int length; GC gc; if (br->marks.has_x_marks == 0) { return; } x += br->marks.offset_tl; gc = (do_draw_shadow) ? br->gcs.shadow : br->gcs.relief; /* draw it */ for (k = 0, length = br->marks.length - 1; k < br->marks.thickness; k++, length--) { int x1; int x2; int y1; int y2; if (length < 0) { break; } if (do_draw_shadow) { x1 = x + k; y1 = y - 1 - k; } else { x1 = x; y1 = y + k; } x2 = x1 + length; y2 = y1; XDrawLine(dpy, dest_pix, gc, x1, y1, x2, y2); } return; } static void border_draw_y_mark( border_relief_descr *br, int x, int y, Pixmap dest_pix, Bool do_draw_shadow) { int k; int length; GC gc; if (br->marks.has_y_marks == 0) { return; } y += br->marks.offset_tl; gc = (do_draw_shadow) ? br->gcs.shadow : br->gcs.relief; /* draw it */ for (k = 0, length = br->marks.length; k < br->marks.thickness; k++, length--) { int x1; int x2; int y1; int y2; if (length <= 0) { break; } if (do_draw_shadow) { x1 = x - 1 - k; y1 = y + k; } else { x1 = x + k; y1 = y; } x2 = x1; y2 = y1 + length - 1; XDrawLine(dpy, dest_pix, gc, x1, y1, x2, y2); } return; } static void border_draw_part_marks( border_relief_descr *br, rectangle *part_g, window_parts part, Pixmap dest_pix) { int l; int t; int w; int h; int o; l = br->sidebar_g.x; t = br->sidebar_g.y; w = part_g->width; h = part_g->height; o = br->marks.offset_br; switch (part) { case PART_BORDER_N: border_draw_y_mark(br, 0, 0, dest_pix, False); border_draw_y_mark(br, w, 0, dest_pix, True); break; case PART_BORDER_S: border_draw_y_mark(br, 0, h + o, dest_pix, False); border_draw_y_mark(br, w, h + o, dest_pix, True); break; case PART_BORDER_E: border_draw_x_mark(br, w + o, 0, dest_pix, False); border_draw_x_mark(br, w + o, h, dest_pix, True); break; case PART_BORDER_W: border_draw_x_mark(br, 0, 0, dest_pix, False); border_draw_x_mark(br, 0, h, dest_pix, True); break; case PART_BORDER_NW: border_draw_x_mark(br, 0, t, dest_pix, True); border_draw_y_mark(br, l, 0, dest_pix, True); break; case PART_BORDER_NE: border_draw_x_mark(br, l + o, t, dest_pix, True); border_draw_y_mark(br, 0, 0, dest_pix, False); break; case PART_BORDER_SW: border_draw_x_mark(br, 0, 0, dest_pix, False); border_draw_y_mark(br, l, t + o, dest_pix, True); break; case PART_BORDER_SE: border_draw_x_mark(br, l + o, 0, dest_pix, False); border_draw_y_mark(br, 0, t + o, dest_pix, False); break; default: return; } return; } inline static void border_set_part_background( Window w, Pixmap pix) { XSetWindowAttributes xswa; xswa.background_pixmap = pix; XChangeWindowAttributes(dpy, w, CWBackPixmap, &xswa); return; } /* render the an image into the pixmap */ static void border_fill_pixmap_background( Pixmap dest_pix, rectangle *dest_g, pixmap_background_type *bg, common_decorations_type *cd) { Bool do_tile; Bool do_stretch; XGCValues xgcv; unsigned long valuemask; Pixmap p = None, shape = None, alpha = None; int src_width, src_height; do_tile = (bg->flags.use_pixmap && bg->pixmap.flags.is_tiled) ? True : False; do_stretch = (bg->flags.use_pixmap && bg->pixmap.flags.is_stretched) ? True : False; xgcv.fill_style = FillSolid; valuemask = GCFillStyle; if (!bg->flags.use_pixmap) { /* solid pixel */ xgcv.foreground = bg->pixel; xgcv.clip_x_origin = 0; xgcv.clip_y_origin = 0; xgcv.clip_mask = None; valuemask |= GCForeground | GCClipMask | GCClipXOrigin | GCClipYOrigin; XChangeGC(dpy, Scr.BordersGC, valuemask, &xgcv); XFillRectangle( dpy, dest_pix, Scr.BordersGC, dest_g->x, dest_g->y, dest_g->width - dest_g->x, dest_g->height - dest_g->y); return; } if (do_stretch) { if (bg->pixmap.p) { p = CreateStretchPixmap( dpy, bg->pixmap.p, bg->pixmap.g.width, bg->pixmap.g.height, bg->pixmap.depth, bg->pixmap.stretch_w, bg->pixmap.stretch_h, (bg->pixmap.depth == 1)? Scr.MonoGC:Scr.BordersGC); } if (bg->pixmap.shape) { shape = CreateStretchPixmap( dpy, bg->pixmap.shape, bg->pixmap.g.width, bg->pixmap.g.height, 1, bg->pixmap.stretch_w, bg->pixmap.stretch_h, Scr.MonoGC); } if (bg->pixmap.alpha) { alpha = CreateStretchPixmap( dpy, bg->pixmap.alpha, bg->pixmap.g.width, bg->pixmap.g.height, FRenderGetAlphaDepth(), bg->pixmap.stretch_w, bg->pixmap.stretch_h, Scr.AlphaGC); } src_width = bg->pixmap.stretch_w; src_height = bg->pixmap.stretch_h; } else { p = bg->pixmap.p; shape = bg->pixmap.shape; alpha = bg->pixmap.alpha; src_width = bg->pixmap.g.width; src_height = bg->pixmap.g.height; } if (do_tile == False) { /* pixmap, offset stored in dest_g->x/y */ xgcv.foreground = cd->fore_color; xgcv.background = cd->back_color; valuemask |= GCForeground|GCBackground; XChangeGC(dpy, Scr.BordersGC, valuemask, &xgcv); PGraphicsRenderPixmaps( dpy, Scr.NoFocusWin, p, shape, alpha, bg->pixmap.depth, &(bg->pixmap.fra), dest_pix, Scr.BordersGC, Scr.MonoGC, Scr.AlphaGC, bg->pixmap.g.x, bg->pixmap.g.y, src_width, src_height, dest_g->x, dest_g->y, dest_g->width - dest_g->x, dest_g->height - dest_g->y, False); } else { /* tiled pixmap */ xgcv.foreground = cd->fore_color; xgcv.background = cd->back_color; valuemask |= GCForeground|GCBackground; XChangeGC(dpy, Scr.BordersGC, valuemask, &xgcv); PGraphicsRenderPixmaps( dpy, Scr.NoFocusWin, p, shape, alpha, bg->pixmap.depth, &(bg->pixmap.fra), dest_pix, Scr.BordersGC, Scr.MonoGC, Scr.AlphaGC, bg->pixmap.g.x, bg->pixmap.g.y, src_width, src_height, dest_g->x, dest_g->y, dest_g->width - dest_g->x, dest_g->height - dest_g->y, True); } if (p && p != bg->pixmap.p) { XFreePixmap(dpy, p); } if (shape && shape != bg->pixmap.shape) { XFreePixmap(dpy, shape); } if (alpha && alpha != bg->pixmap.alpha) { XFreePixmap(dpy, alpha); } return; } /* create a root transparent colorset bg, we take in account a possible * drawing rotation */ static Pixmap border_create_root_transparent_pixmap( titlebar_descr *td, Window w, int width, int height, int cs) { int my_w, my_h; Pixmap p; if (!CSET_IS_TRANSPARENT_ROOT(cs)) { return None; } if (td->td_is_rotated && (td->draw_rotation == ROTATION_90 || td->draw_rotation == ROTATION_270)) { my_h = width; my_w = height; } else { my_w = width; my_h = height; } p = CreateBackgroundPixmap( dpy, w, my_w, my_h, &Colorset[cs], Pdepth, Scr.BordersGC, False); if (p && td->td_is_rotated) { Pixmap tmp; tmp = CreateRotatedPixmap( dpy, p, my_w, my_h, Pdepth, Scr.BordersGC, td->restore_rotation); XFreePixmap(dpy, p); p = tmp; } return p; } static void border_get_frame_pixmap( common_decorations_type *cd, rectangle *frame_g) { dynamic_common_decorations *dcd = &(cd->dynamic_cd); if (dcd->frame_pixmap != None) { /* should not happen */ fprintf(stderr, "Bad use of border_get_frame_pixmap!!\n"); dcd->frame_pixmap = None; } if (cd->bg_border_cs < 0 || CSET_IS_TRANSPARENT(cd->bg_border_cs)) { /* should not happen */ } else { dcd->frame_pixmap = CreateBackgroundPixmap( dpy, Scr.NoFocusWin, frame_g->width, frame_g->height, &Colorset[cd->bg_border_cs], Pdepth, Scr.BordersGC, False); } return; } static void border_get_border_background( pixmap_background_type *bg, common_decorations_type *cd, rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w) { *free_bg_pixmap = False; if (cd->texture_pixmap) { bg->flags.use_pixmap = 1; bg->pixmap.p = cd->texture_pixmap; bg->pixmap.g.width = cd->texture_pixmap_width; bg->pixmap.g.height = cd->texture_pixmap_height; bg->pixmap.shape = None; bg->pixmap.alpha = None; bg->pixmap.depth = Pdepth; bg->pixmap.flags.is_tiled = 1; bg->pixmap.flags.is_stretched = 0; bg->pixmap.fra.mask = 0; } else if (cd->bg_border_cs >= 0 && !CSET_IS_TRANSPARENT_PR(cd->bg_border_cs)) { colorset_t *cs_t = &Colorset[cd->bg_border_cs]; XGCValues xgcv; if (CSET_IS_TRANSPARENT_ROOT(cd->bg_border_cs)) { bg->pixmap.p = CreateBackgroundPixmap( dpy, w, part_g->width, part_g->height, cs_t, Pdepth, Scr.BordersGC, False); } else { /* FIXME */ if (cd->dynamic_cd.frame_pixmap == None) { border_get_frame_pixmap(cd, relative_g); } bg->pixmap.p = XCreatePixmap( dpy, cd->dynamic_cd.frame_pixmap, part_g->width, part_g->height, Pdepth); xgcv.fill_style = FillTiled; xgcv.tile = cd->dynamic_cd.frame_pixmap; xgcv.ts_x_origin = - relative_g->x; xgcv.ts_y_origin = - relative_g->y; XChangeGC( dpy, Scr.BordersGC, GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, &xgcv); XFillRectangle( dpy, bg->pixmap.p, Scr.BordersGC, 0, 0, part_g->width, part_g->height); xgcv.fill_style = FillSolid; XChangeGC(dpy, Scr.BordersGC, GCFillStyle, &xgcv); } bg->pixmap.g.width = part_g->width; bg->pixmap.g.height = part_g->height; bg->flags.use_pixmap = 1; bg->pixmap.shape = None; bg->pixmap.alpha = None; bg->pixmap.depth = Pdepth; bg->pixmap.flags.is_tiled = 1; bg->pixmap.flags.is_stretched = 0; bg->pixmap.fra.mask = 0; *free_bg_pixmap = True; } else { bg->flags.use_pixmap = 0; bg->pixel = cd->attributes.background_pixel; } return; } static void border_draw_one_border_part( common_decorations_type *cd, FvwmWindow *fw, rectangle *sidebar_g, rectangle *frame_g, border_relief_descr *br, window_parts part, window_parts draw_handles, Bool is_inverted, Bool do_clear) { pixmap_background_type bg; rectangle part_g; rectangle pix_g; rectangle relative_g; Pixmap p; Window w; Bool free_bg_pixmap = False; /* make a pixmap */ border_get_part_geometry(fw, part, sidebar_g, &part_g, &w); if (part_g.width <= 0 || part_g.height <= 0) { return; } p = border_create_decor_pixmap(cd, &part_g); /* set the background tile */ relative_g.width = fw->g.frame.width; relative_g.height = fw->g.frame.height; relative_g.x = part_g.x; relative_g.y = part_g.y; border_get_border_background( &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w); if (cd->texture_pixmap) { switch (part) { case PART_BORDER_E: bg.pixmap.g.x = frame_g->width - fw->boundary_width; break; case PART_BORDER_NE: case PART_BORDER_SE: bg.pixmap.g.x = frame_g->width - fw->corner_width; break; case PART_BORDER_N: case PART_BORDER_S: bg.pixmap.g.x = fw->corner_width; break; default: bg.pixmap.g.x = 0; break; } switch (part) { case PART_BORDER_S: bg.pixmap.g.y = frame_g->height - fw->boundary_width; break; case PART_BORDER_SW: case PART_BORDER_SE: bg.pixmap.g.y = frame_g->height - fw->corner_width; break; case PART_BORDER_W: case PART_BORDER_E: bg.pixmap.g.y = fw->corner_width; break; default: bg.pixmap.g.y = 0; break; } } else { bg.pixmap.g.x = 0; bg.pixmap.g.y = 0; } /* set the geometry for drawing the Tiled pixmap; maybe add the relief * as offset? */ pix_g.x = 0; pix_g.y = 0; pix_g.width = part_g.width; pix_g.height = part_g.height; border_fill_pixmap_background(p, &pix_g, &bg, cd); if (free_bg_pixmap && bg.pixmap.p) { XFreePixmap(dpy, bg.pixmap.p); } /* draw the relief over the background */ if (!br->relief.is_flat) { border_draw_part_relief(br, frame_g, &part_g, p, is_inverted); /* draw the handle marks */ if (br->marks.has_x_marks || br->marks.has_y_marks) { border_draw_part_marks(br, &part_g, part, p); } } /* apply the pixmap and destroy it */ border_set_part_background(w, p); if (do_clear == True) { XClearWindow(dpy,w); } XFreePixmap(dpy, p); return; } static void border_draw_all_border_parts( common_decorations_type *cd, FvwmWindow *fw, border_relief_descr *br, rectangle *frame_g, window_parts draw_parts, window_parts pressed_parts, Bool do_hilight, Bool do_clear) { window_parts part; window_parts draw_handles; /* get the description of the drawing directives */ border_get_border_relief_size_descr(&br->relief, fw, do_hilight); border_get_border_marks_descr(cd, br, fw); /* fetch the gcs used to draw the border */ border_get_border_gcs(&br->gcs, cd, fw, do_hilight); /* draw everything in a big loop */ draw_parts &= (PART_FRAME | PART_HANDLES); draw_handles = (draw_parts & PART_HANDLES); for (part = PART_BORDER_N; (part & PART_FRAME); part <<= 1) { if (part & draw_parts) { border_draw_one_border_part( cd, fw, &br->sidebar_g, frame_g, br, part, draw_handles, (pressed_parts & part) ? True : False, do_clear); } } return; } /* * * Draws a little pattern within a window (more complex) * */ static void border_draw_vector_to_pixmap( Pixmap dest_pix, common_decorations_type *cd, int is_toggled, struct vector_coords *coords, rectangle *pixmap_g) { GC gcs[4]; int i; if (coords->use_fgbg == 1) { Globalgcv.foreground = cd->fore_color; Globalgcm = GCForeground; XChangeGC(dpy, Scr.ScratchGC3, Globalgcm, &Globalgcv); Globalgcv.foreground = cd->back_color; XChangeGC(dpy, Scr.ScratchGC4, Globalgcm, &Globalgcv); gcs[3] = Scr.ScratchGC3; /* @3 is fg */ gcs[2] = Scr.ScratchGC4; /* @2 is bg */ } if (is_toggled) { gcs[0] = cd->relief_gc; gcs[1] = cd->shadow_gc; } else { gcs[0] = cd->shadow_gc; gcs[1] = cd->relief_gc; } for (i = 1; i < coords->num; i++) { if (coords->c[i] < 0 || coords->c[i] >= 4) { /* don't draw a line */ continue; } XDrawLine( dpy, dest_pix, gcs[coords->c[i]], pixmap_g->width * coords->x[i-1] / 100 + coords->xoff[i-1], pixmap_g->height * coords->y[i-1] / 100 + coords->yoff[i-1], pixmap_g->width * coords->x[i] / 100 + coords->xoff[i], pixmap_g->height * coords->y[i] / 100 + coords->yoff[i]); } return; } /* * * Handle Title pixmaps used for UseTitleStyle * */ static void border_setup_bar_pixmaps( titlebar_descr *td, dynamic_common_decorations *dcd, DecorFace *df, ButtonState bs) { int count = dcd->bar_pixmaps[bs].count; DecorFace *tsdf; int i, j, mp_part_left, mp_part_right; if (count != 0) { /* ok */ return; } for (tsdf = df; tsdf != NULL; tsdf = tsdf->next) { if (DFS_FACE_TYPE(tsdf->style) == ColorsetButton) { count++; } else if (DFS_FACE_TYPE(tsdf->style) == MultiPixmap) { border_mp_get_use_title_style_parts_and_geometry( td, tsdf->u.mp.pixmaps, tsdf->u.mp.acs, tsdf->u.mp.solid_flags, True, NULL, &mp_part_left); border_mp_get_use_title_style_parts_and_geometry( td, tsdf->u.mp.pixmaps, tsdf->u.mp.acs, tsdf->u.mp.solid_flags, False, NULL, &mp_part_right); for (j = 0; j < UTS_TBMP_NUM_PIXMAPS; j++) { if (j != mp_part_left && j != mp_part_right) { continue; } if (tsdf->u.mp.acs[j].cs >= 0 || tsdf->u.mp.pixmaps[j]) { count++; } } } } if (count == 0) { dcd->bar_pixmaps[bs].count = -1; return; } else { dcd->bar_pixmaps[bs].bps = (bar_pixmap *)safemalloc(count*sizeof(bar_pixmap)); } dcd->bar_pixmaps[bs].count = count; i = 0; for (tsdf = df; tsdf != NULL; tsdf = tsdf->next) { if (DFS_FACE_TYPE(tsdf->style) == ColorsetButton) { dcd->bar_pixmaps[bs].bps[i].p = None; dcd->bar_pixmaps[bs].bps[i].mp_created_pic = NULL; dcd->bar_pixmaps[bs].bps[i].cs = tsdf->u.acs.cs; dcd->bar_pixmaps[bs].bps[i].mp_pic = NULL; dcd->bar_pixmaps[bs].bps[i].created = 0; dcd->bar_pixmaps[bs].bps[i].mp_part = TBMP_NONE; i++; } else if (DFS_FACE_TYPE(tsdf->style) == MultiPixmap) { border_mp_get_use_title_style_parts_and_geometry( td, tsdf->u.mp.pixmaps, tsdf->u.mp.acs, tsdf->u.mp.solid_flags, True, NULL, &mp_part_left); border_mp_get_use_title_style_parts_and_geometry( td, tsdf->u.mp.pixmaps, tsdf->u.mp.acs, tsdf->u.mp.solid_flags, False, NULL, &mp_part_right); for (j = 0; j < UTS_TBMP_NUM_PIXMAPS; j++) { if (j != mp_part_left && j != mp_part_right) { continue; } if (tsdf->u.mp.acs[j].cs >= 0 || tsdf->u.mp.pixmaps[j]) { dcd->bar_pixmaps[bs].bps[i].p = None; dcd->bar_pixmaps[bs].bps[i]. mp_created_pic = NULL; dcd->bar_pixmaps[bs].bps[i].cs = tsdf->u.mp.acs[j].cs; dcd->bar_pixmaps[bs].bps[i].mp_pic = tsdf->u.mp.pixmaps[j]; dcd->bar_pixmaps[bs].bps[i].created = 0; dcd->bar_pixmaps[bs].bps[i].mp_part = j; i++; } } } } } static Pixmap border_get_bar_pixmaps( dynamic_common_decorations *dcd, rectangle *bar_g, ButtonState bs, int cset, FvwmPicture *mp_pic, int mp_part, int stretch, FvwmPicture **mp_ret_pic) { ButtonState b; int i,j; int count = dcd->bar_pixmaps[bs].count; if (count <= 0) { return None; } i = 0; while(i < count && (dcd->bar_pixmaps[bs].bps[i].cs != cset || dcd->bar_pixmaps[bs].bps[i].mp_part != mp_part || dcd->bar_pixmaps[bs].bps[i].mp_pic != mp_pic)) { i++; } if (i == count) { return None; } if (mp_ret_pic) { *mp_ret_pic = dcd->bar_pixmaps[bs].bps[i].mp_created_pic; } if (dcd->bar_pixmaps[bs].bps[i].p == None) { /* see if we have it */ b = 0; while (b < BS_MaxButtonState) { int c = dcd->bar_pixmaps[b].count; j = 0; while(j < c && (dcd->bar_pixmaps[b].bps[j].cs != cset || dcd->bar_pixmaps[b].bps[j].mp_part != mp_part || dcd->bar_pixmaps[b].bps[j].mp_pic != mp_pic)) { j++; } if (j < c && dcd->bar_pixmaps[b].bps[j].p) { dcd->bar_pixmaps[bs].bps[i].p = dcd->bar_pixmaps[b].bps[j].p; if (mp_pic && mp_ret_pic) { *mp_ret_pic = dcd->bar_pixmaps[bs].bps[i]. mp_created_pic = dcd->bar_pixmaps[b].bps[j]. mp_created_pic; } break; } b++; } } if (dcd->bar_pixmaps[bs].bps[i].p == None) { if (cset >= 0) { dcd->bar_pixmaps[bs].bps[i].p = CreateBackgroundPixmap( dpy, Scr.NoFocusWin, bar_g->width, bar_g->height, &Colorset[cset], Pdepth, Scr.BordersGC, False); dcd->bar_pixmaps[bs].bps[i].created = True; } else if (mp_pic && mp_ret_pic) { if (stretch) { dcd->bar_pixmaps[bs].bps[i].mp_created_pic = PGraphicsCreateStretchPicture( dpy, Scr.NoFocusWin, mp_pic, bar_g->width, bar_g->height, Scr.BordersGC, Scr.MonoGC, Scr.AlphaGC); } else { dcd->bar_pixmaps[bs].bps[i].mp_created_pic = PGraphicsCreateTiledPicture( dpy, Scr.NoFocusWin, mp_pic, bar_g->width, bar_g->height, Scr.BordersGC, Scr.MonoGC, Scr.AlphaGC); } if (dcd->bar_pixmaps[bs].bps[i].mp_created_pic) { dcd->bar_pixmaps[bs].bps[i].created = True; *mp_ret_pic = dcd->bar_pixmaps[bs].bps[i]. mp_created_pic; dcd->bar_pixmaps[bs].bps[i].p = dcd->bar_pixmaps[bs].bps[i]. mp_created_pic->picture; } } } return dcd->bar_pixmaps[bs].bps[i].p; } static void border_free_bar_pixmaps( dynamic_common_decorations *dcd) { ButtonState bs; int i; for (bs = 0; bs < BS_MaxButtonState; bs++) { if (dcd->bar_pixmaps[bs].count < 1) { continue; } for (i = 0; i < dcd->bar_pixmaps[bs].count; i++) { if (dcd->bar_pixmaps[bs].bps[i].mp_created_pic && dcd->bar_pixmaps[bs].bps[i].created) { PDestroyFvwmPicture( dpy, dcd->bar_pixmaps[bs].bps[i]. mp_created_pic); } else if (dcd->bar_pixmaps[bs].bps[i].p != None && dcd->bar_pixmaps[bs].bps[i].created) { XFreePixmap( dpy, dcd->bar_pixmaps[bs].bps[i].p); } } free(dcd->bar_pixmaps[bs].bps); } } /* * * MultiPixmap (aka, fancy title bar) (tril@igs.net) * */ #define TBMP_HAS_PART(p, pm, acs, sf) \ (pm[p] || acs[p].cs >= 0 || (sf & (1 << p))) /* Tile or stretch src into dest, starting at the given location and * continuing for the given width and height. This is a utility function used * by border_mp_draw_mp_titlebar. (tril@igs.net) */ static void border_mp_render_into_pixmap( titlebar_descr *td, common_decorations_type *cd, FvwmPicture **src, FvwmAcs *acs, Pixel *pixels, unsigned short solid_flags, unsigned short stretch_flags, int part, Pixmap dest, Window w, rectangle *full_g, rectangle *title_g, ButtonState bs, rectangle *g) { int x = 0; int y = 0; pixmap_background_type bg; rectangle dest_g; dynamic_common_decorations *dcd; dcd = &cd->dynamic_cd; /* setup some default */ bg.pixmap.fra.mask = 0; bg.pixmap.flags.is_stretched = 0; bg.pixmap.flags.is_tiled = 0; bg.flags.use_pixmap = 1; bg.pixmap.p = bg.pixmap.alpha = bg.pixmap.shape = None; bg.pixmap.g.x = 0; bg.pixmap.g.y = 0; dest_g.width = g->width + g->x; dest_g.height = g->height + g->y; dest_g.x = g->x; dest_g.y = g->y; if (solid_flags & (1 << part)) { bg.flags.use_pixmap = 0; bg.pixel = pixels[part]; border_fill_pixmap_background(dest, &dest_g, &bg, cd); return; } else if (acs[part].cs >= 0) { Pixmap p = None; bg.pixmap.fra.mask = FRAM_HAVE_ADDED_ALPHA; bg.pixmap.fra.added_alpha_percent = acs[part].alpha_percent; if (CSET_IS_TRANSPARENT_PR(acs[part].cs)) { return; } if (CSET_IS_TRANSPARENT_ROOT(acs[part].cs)) { p = border_create_root_transparent_pixmap( td, w, g->width + g->x, g->height + g->y, acs[part].cs); bg.pixmap.p = p; bg.pixmap.depth = Pdepth; bg.pixmap.g.width = g->width; bg.pixmap.g.height = g->height; bg.pixmap.g.x = g->x; bg.pixmap.g.y = g->y; } else if (full_g != NULL) { bg.pixmap.p = border_get_bar_pixmaps( dcd, full_g, bs, acs[part].cs, NULL, part, (stretch_flags & (1 << part)), NULL); if (bg.pixmap.p) { if (part != TBMP_RIGHT_MAIN) { /* left buttons offset */ x = title_g->x - full_g->x; y = title_g->y - full_g->y; } bg.pixmap.g.width = full_g->width; bg.pixmap.g.height = full_g->height; bg.pixmap.flags.is_tiled = 1; bg.pixmap.g.x = x; bg.pixmap.g.y = y; bg.pixmap.depth = Pdepth; } } if (!bg.pixmap.p) { int bg_w, bg_h; p = CreateBackgroundPixmap( dpy, w, g->width, g->height, &Colorset[acs[part].cs], Pdepth, Scr.BordersGC, False); bg.pixmap.p = p; GetWindowBackgroundPixmapSize( &Colorset[acs[part].cs], g->width, g->height, &bg_w, &bg_h); bg.pixmap.g.width = bg_w; bg.pixmap.g.height = bg_h; bg.pixmap.depth = Pdepth; bg.pixmap.flags.is_tiled = 1; } if (bg.pixmap.p) { border_fill_pixmap_background(dest, &dest_g, &bg, cd); } if (p) { XFreePixmap(dpy, p); } } else if (src[part]) { FvwmPicture *full_pic = NULL; Pixmap p; if (full_g != NULL) { p = border_get_bar_pixmaps( dcd, full_g, bs, -1, src[part], part, (stretch_flags & (1 << part)), &full_pic); if (p && full_pic) { if (part != TBMP_RIGHT_MAIN) { /* left buttons offset */ x = title_g->x - full_g->x; y = title_g->y - full_g->y; } bg.pixmap.p = full_pic->picture; bg.pixmap.shape = full_pic->mask; bg.pixmap.alpha = full_pic->alpha; bg.pixmap.depth = full_pic->depth; bg.pixmap.g.width = full_pic->width; bg.pixmap.g.height = full_pic->height; bg.pixmap.g.x = x; bg.pixmap.g.y = y; } } if (!bg.pixmap.p) { if (stretch_flags & (1 << part)) { bg.pixmap.flags.is_stretched = 1; } else { bg.pixmap.flags.is_tiled = 1; } bg.pixmap.p = src[part]->picture; bg.pixmap.shape = src[part]->mask; bg.pixmap.alpha = src[part]->alpha; bg.pixmap.depth = src[part]->depth; bg.pixmap.g.width = src[part]->width; bg.pixmap.g.height = src[part]->height; bg.pixmap.stretch_w = dest_g.width - dest_g.x; bg.pixmap.stretch_h = dest_g.height - dest_g.y; } if (bg.pixmap.p) { border_fill_pixmap_background(dest, &dest_g, &bg, cd); } } return; } static int border_mp_get_length( titlebar_descr *td, FvwmPicture **pm, FvwmAcs *acs, unsigned int solid_flags, int part) { if (acs[part].cs >= 0 || (solid_flags & (1 << part))) { /* arbitrary */ if (td->has_vt) { return td->bar_g.width/2; } else { return td->bar_g.height/2; } } if (pm[part] == NULL) { return 0; } else if (td->has_vt) { return pm[part]->height; } else { return pm[part]->width; } } /* geometries relatively to the frame */ static void border_mp_get_titlebar_descr( FvwmWindow *fw, titlebar_descr *td, DecorFace *df) { DecorFace *tsdf; FvwmPicture **pm; FvwmAcs *acs; int add,tmpi; int left_of_text = 0; int right_of_text = 0; int left_end = 0; int right_end = 0; int before_space, after_space, under_offset, under_width; Bool has_mp = False; JustificationType just; unsigned short sf; int is_start = 0; just = TB_JUSTIFICATION(GetDecor(fw, titlebar)); /* first compute under text width */ if (td->length > 0) { under_width = td->length + 2*TBMP_TITLE_PADDING; } else { under_width = 0; } if (under_width > fw->title_length) { under_width = fw->title_length; td->offset = (fw->title_length - td->length) / 2; just = JUST_CENTER; } for (tsdf = df; tsdf != NULL; tsdf = tsdf->next) { if (tsdf->style.face_type != MultiPixmap) { continue; } has_mp = True; acs = tsdf->u.mp.acs; pm = tsdf->u.mp.pixmaps; sf = tsdf->u.mp.solid_flags; add = border_mp_get_length( td, pm, acs, sf, TBMP_LEFT_OF_TEXT); if (add > left_of_text && add + left_end + right_of_text + right_end + under_width + 2*TBMP_MIN_RL_TITLE_LENGTH <= fw->title_length) { left_of_text = add; } add = border_mp_get_length( td, pm, acs, sf, TBMP_RIGHT_OF_TEXT); if (add > right_of_text && add + left_end + left_of_text + right_end + under_width + 2*TBMP_MIN_RL_TITLE_LENGTH <= fw->title_length) { right_of_text = add; } add = border_mp_get_length( td, pm, acs, sf, TBMP_LEFT_END); if (add > left_end && add + right_of_text + left_of_text + right_end + under_width + 2*TBMP_MIN_RL_TITLE_LENGTH <= fw->title_length) { left_end = add; } add = border_mp_get_length( td, pm, acs, sf, TBMP_RIGHT_END); if (add > right_end && add + right_of_text + left_of_text + left_end + under_width + 2*TBMP_MIN_RL_TITLE_LENGTH <= fw->title_length) { right_end = add; } } if (!has_mp) { return; } switch (just) { case JUST_LEFT: is_start = 1; /* fall through */ case JUST_RIGHT: if (td->has_an_upsidedown_rotation) { is_start = !is_start; } if (is_start) { if (td->has_an_upsidedown_rotation) { td->offset = max( td->offset, right_of_text + right_end + TBMP_MIN_RL_TITLE_LENGTH + TBMP_TITLE_PADDING); } else { td->offset = max( td->offset, left_of_text + left_end + TBMP_MIN_RL_TITLE_LENGTH + TBMP_TITLE_PADDING); } } else { if (td->has_an_upsidedown_rotation) { td->offset = min( td->offset, fw->title_length - (td->length + left_of_text + left_end + TBMP_MIN_RL_TITLE_LENGTH + TBMP_TITLE_PADDING)); } else { td->offset = min( td->offset, fw->title_length - (td->length + right_of_text + right_end + TBMP_MIN_RL_TITLE_LENGTH + TBMP_TITLE_PADDING)); } } break; case JUST_CENTER: default: break; } under_offset = td->offset - (under_width - td->length)/2; before_space = under_offset; if (td->has_vt) { after_space = td->layout.title_g.height - before_space - under_width; } else { after_space = td->layout.title_g.width - before_space - under_width; } if (td->has_an_upsidedown_rotation) { td->left_end_length = right_end; td->left_of_text_length = right_of_text; td->right_of_text_length = left_of_text; td->right_end_length = left_end; tmpi = before_space; before_space = after_space; after_space = tmpi; } else { td->left_end_length = left_end; td->left_of_text_length = left_of_text; td->right_of_text_length = right_of_text; td->right_end_length = right_end; } if (td->has_vt) { td->under_text_g.width = td->bar_g.width; td->under_text_g.height = under_width; td->under_text_g.x = 0; td->under_text_g.y = under_offset; } else { td->under_text_g.height = td->bar_g.height; td->under_text_g.width = under_width; td->under_text_g.x = under_offset; td->under_text_g.y = 0; } /* width & height */ if (td->has_vt) { /* left */ td->full_left_main_g.width = td->bar_g.width; td->full_left_main_g.height = before_space + td->left_buttons_g.height; td->left_main_g.width = td->bar_g.width; td->left_main_g.height = before_space; /* right */ td->full_right_main_g.width = td->bar_g.width; td->full_right_main_g.height = after_space + td->right_buttons_g.height; td->right_main_g.width = td->bar_g.width; td->right_main_g.height = after_space; } else { /* left */ td->full_left_main_g.height = td->bar_g.height; td->full_left_main_g.width = before_space + td->left_buttons_g.width; td->left_main_g.height = td->bar_g.height; td->left_main_g.width = before_space; /* right */ td->full_right_main_g.height = td->bar_g.height; td->full_right_main_g.width = after_space + td->right_buttons_g.width; td->right_main_g.height = td->bar_g.height; td->right_main_g.width = after_space; } /* position */ if (td->has_an_upsidedown_rotation) { td->full_right_main_g.x = td->bar_g.x; td->full_right_main_g.y = td->bar_g.y; td->right_main_g.x = 0; td->right_main_g.y = 0; } else { td->full_left_main_g.x = td->bar_g.x; td->full_left_main_g.y = td->bar_g.y; td->left_main_g.x = 0; td->left_main_g.y = 0; } if (td->has_vt) { if (td->has_an_upsidedown_rotation) { td->full_left_main_g.x = td->bar_g.x; td->full_left_main_g.y = td->full_right_main_g.height + td->bar_g.y + td->under_text_g.height; td->left_main_g.y = td->under_text_g.y + td->under_text_g.height; td->left_main_g.x = 0; } else { td->full_right_main_g.x = td->bar_g.x; td->full_right_main_g.y = td->full_left_main_g.height + td->bar_g.y + td->under_text_g.height; td->right_main_g.y = td->under_text_g.y + td->under_text_g.height; td->right_main_g.x = 0; } } else { if (td->has_an_upsidedown_rotation) { td->full_left_main_g.x = td->full_right_main_g.width + td->bar_g.x + td->under_text_g.width; td->full_left_main_g.y = td->bar_g.y; td->left_main_g.x = td->under_text_g.x + td->under_text_g.width; td->left_main_g.y = 0; } else { td->full_right_main_g.x = td->full_left_main_g.width + td->bar_g.x + td->under_text_g.width; td->full_right_main_g.y = td->bar_g.y; td->right_main_g.x = td->under_text_g.x + td->under_text_g.width; td->right_main_g.y = 0; } } } /* the returned geometries are relative to the titlebar (not the frame) */ static void border_mp_get_extreme_geometry( titlebar_descr *td, FvwmPicture **pm, FvwmAcs *acs, unsigned short sf, rectangle *left_of_text_g, rectangle *right_of_text_g, rectangle *left_end_g, rectangle *right_end_g) { int left_of_text = 0; int right_of_text = 0; int left_end = 0; int right_end = 0; left_of_text = border_mp_get_length( td, pm, acs, sf, TBMP_LEFT_OF_TEXT); left_end = border_mp_get_length( td, pm, acs, sf, TBMP_LEFT_END); right_of_text = border_mp_get_length( td, pm, acs, sf, TBMP_RIGHT_OF_TEXT); right_end = border_mp_get_length( td, pm, acs, sf, TBMP_RIGHT_END); if (left_of_text > 0 && left_of_text <= td->left_of_text_length) { if (td->has_vt) { left_of_text_g->y = td->under_text_g.y - left_of_text; left_of_text_g->x = 0; left_of_text_g->height = left_of_text; left_of_text_g->width = td->bar_g.width; } else { left_of_text_g->x = td->under_text_g.x - left_of_text; left_of_text_g->y = 0; left_of_text_g->width = left_of_text; left_of_text_g->height = td->bar_g.height; } } else { left_of_text_g->x = 0; left_of_text_g->y = 0; left_of_text_g->width = 0; left_of_text_g->height = 0; } if (right_of_text > 0 && right_of_text <= td->right_of_text_length) { if (td->has_vt) { right_of_text_g->y = td->under_text_g.y + td->under_text_g.height; right_of_text_g->x = 0; right_of_text_g->height = right_of_text; right_of_text_g->width = td->bar_g.width; } else { right_of_text_g->x = td->under_text_g.x + td->under_text_g.width; right_of_text_g->y = 0; right_of_text_g->width = right_of_text; right_of_text_g->height = td->bar_g.height; } } else { right_of_text_g->x = 0; right_of_text_g->y = 0; right_of_text_g->width = 0; right_of_text_g->height = 0; } if (left_end > 0 && left_end <= td->left_end_length) { if (td->has_vt) { left_end_g->y = 0; left_end_g->x = 0; left_end_g->height = left_end; left_end_g->width = td->bar_g.width; } else { left_end_g->x = 0; left_end_g->y = 0; left_end_g->width = left_end; left_end_g->height = td->bar_g.height; } } else { left_end_g->x = 0; left_end_g->y = 0; left_end_g->width = 0; left_end_g->height = 0; } if (right_end > 0 && right_end <= td->right_end_length) { if (td->has_vt) { right_end_g->y = td->layout.title_g.height - right_end; right_end_g->x = 0; right_end_g->height = right_end; right_end_g->width = td->bar_g.width; } else { right_end_g->x = td->layout.title_g.width - right_end; right_end_g->y = 0; right_end_g->width = right_end; right_end_g->height = td->bar_g.height; } } else { right_end_g->x = 0; right_end_g->y = 0; right_end_g->width = 0; right_end_g->height = 0; } return; } static Bool border_mp_get_use_title_style_parts_and_geometry( titlebar_descr *td, FvwmPicture **pm, FvwmAcs *acs, unsigned short sf, int is_left, rectangle *g, int *part) { rectangle *tmp_g = NULL; Bool g_ok = True; if (is_left && TBMP_HAS_PART(TBMP_LEFT_BUTTONS, pm, acs, sf)) { *part = TBMP_LEFT_BUTTONS; tmp_g = &td->left_buttons_g; } else if (!is_left && TBMP_HAS_PART(TBMP_RIGHT_BUTTONS, pm, acs, sf)) { *part = TBMP_RIGHT_BUTTONS; tmp_g = &td->right_buttons_g; } else if (is_left && TBMP_HAS_PART(TBMP_LEFT_MAIN, pm, acs, sf)) { *part = TBMP_LEFT_MAIN; tmp_g = &td->full_left_main_g; } else if (!is_left && TBMP_HAS_PART(TBMP_RIGHT_MAIN, pm, acs, sf)) { *part = TBMP_RIGHT_MAIN; tmp_g = &td->full_right_main_g; } else if (TBMP_HAS_PART(TBMP_MAIN, pm, acs, sf)) { *part = TBMP_MAIN; tmp_g = &(td->bar_g); } else { *part = TBMP_NONE; } if (g && tmp_g) { g->x = tmp_g->x; g->y = tmp_g->y; g->width = tmp_g->width; g->height = tmp_g->height; g_ok = True; } return g_ok; } /* Redraws multi-pixmap titlebar (tril@igs.net) */ static void border_mp_draw_mp_titlebar( FvwmWindow *fw, titlebar_descr *td, DecorFace *df, Pixmap dest_pix, Window w) { FvwmPicture **pm; FvwmAcs *acs; Pixel *pixels; unsigned short solid_flags; unsigned short stretch_flags; rectangle tmp_g, left_of_text_g,left_end_g,right_of_text_g,right_end_g; ButtonState bs; bs = td->tbstate.tstate; pm = df->u.mp.pixmaps; acs = df->u.mp.acs; pixels = df->u.mp.pixels; stretch_flags = df->u.mp.stretch_flags; solid_flags = df->u.mp.solid_flags; tmp_g.x = 0; tmp_g.y = 0; tmp_g.width = td->layout.title_g.width; tmp_g.height = td->layout.title_g.height; if (TBMP_HAS_PART(TBMP_MAIN, pm, acs, solid_flags)) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_MAIN, dest_pix, w, &td->bar_g, &td->layout.title_g, bs, &tmp_g); } else if (td->length <= 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_LEFT_MAIN, dest_pix, w, NULL, &td->layout.title_g, bs, &tmp_g); } border_mp_get_extreme_geometry( td, pm, acs, solid_flags, &left_of_text_g, &right_of_text_g, &left_end_g, &right_end_g); if (td->length > 0) { if (TBMP_HAS_PART(TBMP_LEFT_MAIN, pm, acs, solid_flags) && td->left_main_g.width > 0 && td->left_main_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_LEFT_MAIN, dest_pix, w, &td->full_left_main_g, &td->layout.title_g, bs, &td->left_main_g); } if (TBMP_HAS_PART(TBMP_RIGHT_MAIN, pm, acs, solid_flags) && td->right_main_g.width > 0 && td->right_main_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_RIGHT_MAIN, dest_pix, w, &td->full_right_main_g, &td->layout.title_g, bs, &td->right_main_g); } if (TBMP_HAS_PART(TBMP_UNDER_TEXT, pm, acs, solid_flags) && td->under_text_g.width > 0 && td->under_text_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_UNDER_TEXT, dest_pix, w, NULL, &td->layout.title_g, bs, &td->under_text_g); } if (left_of_text_g.width > 0 && left_of_text_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_LEFT_OF_TEXT, dest_pix, w, NULL, &td->layout.title_g, bs, &left_of_text_g); } if (right_of_text_g.width > 0 && right_of_text_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_RIGHT_OF_TEXT, dest_pix, w, NULL, &td->layout.title_g, bs, &right_of_text_g); } } if (left_end_g.width > 0 && left_end_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_LEFT_END, dest_pix, w, NULL, &td->layout.title_g, bs, &left_end_g); } if (right_end_g.width > 0 && right_end_g.height > 0) { border_mp_render_into_pixmap( td, td->cd, pm, acs, pixels, solid_flags, stretch_flags, TBMP_RIGHT_END, dest_pix, w, NULL, &td->layout.title_g, bs, &right_end_g); } return; } /* * * draw title bar and buttons * */ static void border_draw_decor_to_pixmap( FvwmWindow *fw, Pixmap dest_pix, Window w, pixmap_background_type *solid_bg, rectangle *w_g, DecorFace *df, titlebar_descr *td, ButtonState bs, int use_title_style, int is_toggled, int left1right0) { register DecorFaceType type = DFS_FACE_TYPE(df->style); pixmap_background_type bg; rectangle dest_g; FvwmPicture *p; int width,height; int border; int lr_just, tb_just; common_decorations_type *cd; cd = td->cd; /* setup some default */ bg.pixmap.fra.mask = 0; bg.pixmap.flags.is_stretched = 0; bg.pixmap.flags.is_tiled = 0; bg.flags.use_pixmap = 0; bg.pixmap.g.x = 0; bg.pixmap.g.y = 0; if (DFS_BUTTON_RELIEF(df->style) == DFS_BUTTON_IS_FLAT) { border = 0; } else { border = HAS_MWM_BORDER(fw) ? 1 : 2; } dest_g.width = w_g->width; dest_g.height = w_g->height; dest_g.x = border; dest_g.y = border; switch (type) { case SimpleButton: /* do nothing */ break; case SolidButton: /* overwrite with the default background */ dest_g.x = 0; dest_g.y = 0; border_fill_pixmap_background(dest_pix, &dest_g, solid_bg, cd); break; case VectorButton: case DefaultVectorButton: border_draw_vector_to_pixmap( dest_pix, cd, is_toggled, &df->u.vector, w_g); break; case MiniIconButton: case PixmapButton: case ShrunkPixmapButton: case StretchedPixmapButton: if (w_g->width - 2*border <= 0 || w_g->height - 2*border <= 0) { break; } if (FMiniIconsSupported && type == MiniIconButton) { if (!fw->mini_icon) { break; } p = fw->mini_icon; if (cd->cs >= 0) { bg.pixmap.fra.mask |= FRAM_HAVE_ICON_CSET; bg.pixmap.fra.colorset = &Colorset[cd->cs]; } } else { p = df->u.p; } width = p->width; height = p->height; if ((type == ShrunkPixmapButton || type == MiniIconButton) && (p->width > w_g->width - 2*border || p->height > w_g->height - 2*border)) { /* do so that the picture fit into the destination */ bg.pixmap.stretch_w = width = min(w_g->width - 2*border, p->width); bg.pixmap.stretch_h = height = min(w_g->height - 2*border, p->height); bg.pixmap.flags.is_stretched = 1; } else if (type == StretchedPixmapButton && (p->width < w_g->width - 2*border || p->height < w_g->height - 2*border)) { /* do so that the picture fit into the destination */ bg.pixmap.stretch_w = width = max(w_g->width - 2*border, p->width); bg.pixmap.stretch_h = height = max(w_g->height - 2*border, p->height); bg.pixmap.flags.is_stretched = 1; } lr_just = DFS_H_JUSTIFICATION(df->style); tb_just = DFS_V_JUSTIFICATION(df->style); if (!td->td_is_rotated && fw->title_text_rotation != ROTATION_0) { if (fw->title_text_rotation == ROTATION_180) { switch (lr_just) { case JUST_LEFT: lr_just = JUST_RIGHT; break; case JUST_RIGHT: lr_just = JUST_LEFT; break; case JUST_CENTER: default: break; } switch (tb_just) { case JUST_TOP: tb_just = JUST_BOTTOM; break; case JUST_BOTTOM: tb_just = JUST_TOP; break; case JUST_CENTER: default: break; } } else if (fw->title_text_rotation == ROTATION_90) { switch (lr_just) { case JUST_LEFT: tb_just = JUST_TOP; break; case JUST_RIGHT: tb_just = JUST_BOTTOM; break; case JUST_CENTER: default: tb_just = JUST_CENTER; break; } switch (DFS_V_JUSTIFICATION(df->style)) { case JUST_TOP: lr_just = JUST_RIGHT; break; case JUST_BOTTOM: lr_just = JUST_LEFT; break; case JUST_CENTER: default: lr_just = JUST_CENTER; break; } } else if (fw->title_text_rotation == ROTATION_270) { switch (lr_just) { case JUST_LEFT: tb_just = JUST_BOTTOM; break; case JUST_RIGHT: tb_just = JUST_TOP; break; case JUST_CENTER: default: tb_just = JUST_CENTER; break; } switch (DFS_V_JUSTIFICATION(df->style)) { case JUST_TOP: lr_just = JUST_LEFT; break; case JUST_BOTTOM: lr_just = JUST_RIGHT; break; case JUST_CENTER: default: lr_just = JUST_CENTER; break; } } } switch (lr_just) { case JUST_LEFT: dest_g.x = border; break; case JUST_RIGHT: dest_g.x = (int)(w_g->width - width - border); break; case JUST_CENTER: default: /* round down */ dest_g.x = (int)(w_g->width - width) / 2; break; } switch (tb_just) { case JUST_TOP: dest_g.y = border; break; case JUST_BOTTOM: dest_g.y = (int)(w_g->height - height - border); break; case JUST_CENTER: default: /* round down */ dest_g.y = (int)(w_g->height - height) / 2; break; } if (dest_g.x < border) { dest_g.x = border; } if (dest_g.y < border) { dest_g.y = border; } bg.flags.use_pixmap = 1; bg.pixmap.p = p->picture; bg.pixmap.shape = p->mask; bg.pixmap.alpha = p->alpha; bg.pixmap.depth = p->depth; bg.pixmap.g.width = p->width; bg.pixmap.g.height = p->height; border_fill_pixmap_background(dest_pix, &dest_g, &bg, cd); break; case TiledPixmapButton: case AdjustedPixmapButton: if (w_g->width - 2*border <= 0 || w_g->height - 2*border <= 0) { break; } p = df->u.p; if (type == TiledPixmapButton) { bg.pixmap.flags.is_tiled = 1; } else { bg.pixmap.stretch_w = width = w_g->width - 2*dest_g.x; bg.pixmap.stretch_h = height = w_g->height - 2*dest_g.y; bg.pixmap.flags.is_stretched = 1; } bg.flags.use_pixmap = 1; bg.pixmap.p = p->picture; bg.pixmap.shape = p->mask; bg.pixmap.alpha = p->alpha; bg.pixmap.depth = p->depth; bg.pixmap.g.width = p->width; bg.pixmap.g.height = p->height; border_fill_pixmap_background(dest_pix, &dest_g, &bg, cd); break; case MultiPixmap: /* for UseTitleStyle only */ { int is_left = left1right0; int part = TBMP_NONE; int ap, cs; unsigned int stretch; Pixmap tmp = None; FvwmPicture *full_pic = NULL; rectangle g; dynamic_common_decorations *dcd = &(cd->dynamic_cd); FvwmPicture **pm; FvwmAcs *acs; Pixel *pixels; unsigned short sf; pm = df->u.mp.pixmaps; acs = df->u.mp.acs; pixels = df->u.mp.pixels; sf = df->u.mp.solid_flags; if (!border_mp_get_use_title_style_parts_and_geometry( td, pm, acs, sf, is_left, &g, &part)) { g.width = 0; g.height = 0; g.x = 0; g.y = 0; } if (part == TBMP_NONE) { break; } if (sf & (1 << part)) { bg.flags.use_pixmap = 0; bg.pixel = pixels[part]; border_fill_pixmap_background( dest_pix, &dest_g, &bg, cd); break; } cs = acs[part].cs; ap = acs[part].alpha_percent; if (CSET_IS_TRANSPARENT_PR(cs)) { break; } if (cs >= 0) { bg.pixmap.fra.mask = FRAM_HAVE_ADDED_ALPHA; bg.pixmap.fra.added_alpha_percent = ap; } stretch = !!(df->u.mp.stretch_flags & (1 << part)); bg.flags.use_pixmap = 1; dest_g.x = 0; dest_g.y = 0; if (cs >= 0 && use_title_style && g.width > 0 && g.height > 0 && !CSET_IS_TRANSPARENT_ROOT(cs) && (bg.pixmap.p = border_get_bar_pixmaps( dcd, &g, bs, cs, NULL, part, stretch, NULL)) != None) { bg.pixmap.g.width = g.width; bg.pixmap.g.height = g.height; bg.pixmap.flags.is_tiled = 1; bg.pixmap.g.x = w_g->x - g.x; bg.pixmap.g.y = w_g->y - g.y; bg.pixmap.shape = None; bg.pixmap.alpha = None; bg.pixmap.depth = Pdepth; } else if (CSET_IS_TRANSPARENT_ROOT(cs)) { tmp = border_create_root_transparent_pixmap( td, w, w_g->width, w_g->height, cs); bg.pixmap.p = tmp; bg.pixmap.g.width = w_g->width; bg.pixmap.g.height = w_g->height; bg.pixmap.shape = None; bg.pixmap.alpha = None; bg.pixmap.depth = Pdepth; } else if (cs >= 0) { int bg_w, bg_h; tmp = CreateBackgroundPixmap( dpy, w, w_g->width, w_g->height, &Colorset[cs], Pdepth, Scr.BordersGC, False); bg.pixmap.p = tmp; GetWindowBackgroundPixmapSize( &Colorset[cs], w_g->width, w_g->height, &bg_w, &bg_h); bg.pixmap.g.width = bg_w; bg.pixmap.g.height = bg_h; bg.pixmap.shape = None; bg.pixmap.alpha = None; bg.pixmap.depth = Pdepth; bg.pixmap.flags.is_tiled = 1; } else if (pm[part] && g.width > 0 && g.height > 0 && border_get_bar_pixmaps( dcd, &g, bs, -1, pm[part], part, stretch, &full_pic) != None && full_pic) { bg.pixmap.p = full_pic->picture; bg.pixmap.shape = full_pic->mask; bg.pixmap.alpha = full_pic->alpha; bg.pixmap.depth = full_pic->depth; bg.pixmap.g.width = full_pic->width; bg.pixmap.g.height = full_pic->height; bg.pixmap.g.x = w_g->x - g.x; bg.pixmap.g.y = w_g->y - g.y; } else if (pm[part]) { p = pm[part]; if (df->u.mp.stretch_flags & (1 << part)) { bg.pixmap.flags.is_stretched = 1; } else { bg.pixmap.flags.is_tiled = 1; } bg.pixmap.p = p->picture; bg.pixmap.shape = p->mask; bg.pixmap.alpha = p->alpha; bg.pixmap.depth = p->depth; bg.pixmap.g.width = p->width; bg.pixmap.g.height = p->height; bg.pixmap.stretch_w = dest_g.width - dest_g.x; bg.pixmap.stretch_h = dest_g.height - dest_g.y; } else { /* should not happen */ return; } if (bg.pixmap.p != None) { border_fill_pixmap_background( dest_pix, &dest_g, &bg, cd); } if (tmp != None) { XFreePixmap(dpy, tmp); } break; } case ColorsetButton: { colorset_t *cs_t = &Colorset[df->u.acs.cs]; int cs = df->u.acs.cs; Pixmap tmp = None; int bg_w, bg_h; if (CSET_IS_TRANSPARENT_PR(cs)) { break; } dest_g.x = 0; dest_g.y = 0; if (use_title_style && !CSET_IS_TRANSPARENT_ROOT(cs) && (bg.pixmap.p = border_get_bar_pixmaps( &(cd->dynamic_cd), &(td->bar_g), bs, cs, NULL, TBMP_NONE, 0, NULL)) != None) { bg.pixmap.g.width = td->bar_g.width; bg.pixmap.g.height = td->bar_g.height; bg.pixmap.g.x = w_g->x - td->bar_g.x; bg.pixmap.g.y = w_g->y - td->bar_g.y; } else if (CSET_IS_TRANSPARENT_ROOT(cs)) { tmp = border_create_root_transparent_pixmap( td, w, w_g->width, w_g->height, cs); if (tmp == None) { break; } bg.pixmap.p = tmp; bg.pixmap.g.width = w_g->width; bg.pixmap.g.height = w_g->height; bg.pixmap.shape = None; bg.pixmap.alpha = None; bg.pixmap.depth = Pdepth; } else { tmp = CreateBackgroundPixmap( dpy, w, w_g->width, w_g->height, cs_t, Pdepth, Scr.BordersGC, False); if (tmp == None) { break; } bg.pixmap.p = tmp; GetWindowBackgroundPixmapSize( cs_t, w_g->width, w_g->height, &bg_w, &bg_h); bg.pixmap.g.width = bg_w; bg.pixmap.g.height = bg_h; bg.pixmap.g.x = 0; bg.pixmap.g.y = 0; } bg.flags.use_pixmap = 1; bg.pixmap.shape = None; bg.pixmap.alpha = None; bg.pixmap.depth = Pdepth; bg.pixmap.flags.is_tiled = 1; bg.pixmap.fra.mask = FRAM_HAVE_ADDED_ALPHA; bg.pixmap.fra.added_alpha_percent = df->u.acs.alpha_percent; border_fill_pixmap_background(dest_pix, &dest_g, &bg, cd); if (tmp) { XFreePixmap(dpy, tmp); } break; } case GradientButton: /* draw the gradient into the pixmap */ CreateGradientPixmap( dpy, dest_pix, Scr.TransMaskGC, df->u.grad.gradient_type, 0, 0, df->u.grad.npixels, df->u.grad.xcs, df->u.grad.do_dither, &df->u.grad.d_pixels, &df->u.grad.d_npixels, dest_pix, 0, 0, w_g->width, w_g->height, NULL); break; default: fvwm_msg(ERR, "DrawButton", "unknown button type: %i", type); break; } return; } static void border_set_button_pixmap( FvwmWindow *fw, titlebar_descr *td, int button, Pixmap *dest_pix, Window w) { pixmap_background_type bg; unsigned int mask; int is_left_button; int do_reverse_relief; ButtonState bs; DecorFace *df; rectangle *button_g; GC rgc; GC sgc; Bool free_bg_pixmap = False; rectangle pix_g; /* prepare variables */ mask = (1 << button); if (td->has_an_upsidedown_rotation) { is_left_button = (button & 1); } else { is_left_button = !(button & 1); } button_g = &td->layout.button_g[button]; bs = td->tbstate.bstate[button]; df = &TB_STATE(GetDecor(fw, buttons[button]))[bs]; rgc = td->cd->relief_gc; sgc = td->cd->shadow_gc; /* prepare background, either from the window colour or from the * border style */ if (!DFS_USE_BORDER_STYLE(df->style)) { /* fill with the button background colour */ bg.flags.use_pixmap = 0; bg.pixel = td->cd->back_color; pix_g.x = 0; pix_g.y = 0; pix_g.width = button_g->width; pix_g.height = button_g->height; border_fill_pixmap_background(*dest_pix, &pix_g, &bg, td->cd); } else { /* draw pixmap background inherited from border style */ rectangle relative_g; relative_g.width = td->frame_g.width; relative_g.height = td->frame_g.height; relative_g.x = button_g->x; relative_g.y = button_g->y; border_get_border_background( &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w); bg.pixmap.g.x = 0; bg.pixmap.g.y = 0; /* set the geometry for drawing the Tiled pixmap; * FIXME: maybe add the relief as offset? */ pix_g.x = 0; pix_g.y = 0; pix_g.width = button_g->width; pix_g.height = button_g->height; border_fill_pixmap_background(*dest_pix, &pix_g, &bg, td->cd); if (free_bg_pixmap && bg.pixmap.p) { XFreePixmap(dpy, bg.pixmap.p); } } /* handle title style */ if (DFS_USE_TITLE_STYLE(df->style)) { /* draw background inherited from title style */ DecorFace *tsdf; Pixmap tmp; if (td->draw_rotation != ROTATION_0) { tmp = CreateRotatedPixmap( dpy, *dest_pix, td->layout.button_g[button].width, td->layout.button_g[button].height, Pdepth, Scr.BordersGC, td->restore_rotation); XFreePixmap(dpy, *dest_pix); *dest_pix = tmp; border_rotate_titlebar_descr(fw, td); button_g = &td->layout.button_g[button]; is_left_button = !(button & 1); } for (tsdf = &TB_STATE(GetDecor(fw, titlebar))[bs]; tsdf != NULL; tsdf = tsdf->next) { bg.pixel = tsdf->u.back; border_draw_decor_to_pixmap( fw, *dest_pix, w, &bg, button_g, tsdf, td, bs, True, (td->tbstate.toggled_bmask & mask), is_left_button); } if (td->draw_rotation != ROTATION_0) { tmp = CreateRotatedPixmap( dpy, *dest_pix, td->layout.button_g[button].width, td->layout.button_g[button].height, Pdepth, Scr.BordersGC, td->draw_rotation); XFreePixmap(dpy, *dest_pix); *dest_pix = tmp; border_rotate_titlebar_descr(fw, td); button_g = &td->layout.button_g[button]; if (td->has_an_upsidedown_rotation) { is_left_button = (button & 1); } else { is_left_button = !(button & 1); } } } /* handle button style */ for ( ; df; df = df->next) { /* draw background from button style */ bg.pixel = df->u.back; border_draw_decor_to_pixmap( fw, *dest_pix, w, &bg, button_g, df, td, bs, False, (td->tbstate.toggled_bmask & mask), is_left_button); } /* draw the button relief */ do_reverse_relief = !!(td->tbstate.pressed_bmask & mask); switch (DFS_BUTTON_RELIEF( TB_STATE(GetDecor(fw, buttons[button]))[bs].style)) { case DFS_BUTTON_IS_SUNK: do_reverse_relief ^= 1; /* fall through*/ case DFS_BUTTON_IS_UP: do_relieve_rectangle( dpy, *dest_pix, 0, 0, button_g->width - 1, button_g->height - 1, (do_reverse_relief) ? sgc : rgc, (do_reverse_relief) ? rgc : sgc, td->cd->relief_width, True); break; default: /* flat */ break; } return; } static void border_draw_one_button( FvwmWindow *fw, titlebar_descr *td, int button) { Pixmap p; /* make a pixmap */ if (td->layout.button_g[button].x < 0 || td->layout.button_g[button].y < 0) { return; } p = border_create_decor_pixmap(td->cd, &(td->layout.button_g[button])); /* set the background tile */ border_set_button_pixmap(fw, td, button, &p, FW_W_BUTTON(fw, button)); /* apply the pixmap and destroy it */ border_set_part_background(FW_W_BUTTON(fw, button), p); XFreePixmap(dpy, p); if ((td->tbstate.clear_bmask & (1 << button)) != 0) { XClearWindow(dpy, FW_W_BUTTON(fw, button)); } return; } static void border_draw_title_stick_lines( FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd, Pixmap dest_pix) { int i; int num; int min; int max; int left_x; int left_w; int right_x; int right_w; int under_text_length = 0; int under_text_offset = 0; int right_length = 0; int left_length = 0; rotation_t rotation; if (!( (HAS_STICKY_STIPPLED_TITLE(fw) && (IS_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw))) || HAS_STIPPLED_TITLE(fw))) { return; } if (td->td_is_rotated) { rotation = td->restore_rotation; } else { rotation = ROTATION_0; } if (td->has_vt && td->under_text_g.height > 0) { under_text_length = td->under_text_g.height; under_text_offset = td->under_text_g.y; left_length = td->left_main_g.height - td->left_of_text_length - td->left_end_length; right_length = td->right_main_g.height - td->right_of_text_length - td->right_end_length; } else if (!td->has_vt && td->under_text_g.width > 0) { under_text_length = td->under_text_g.width; under_text_offset = td->under_text_g.x; left_length = td->left_main_g.width - td->left_of_text_length - td->left_end_length; right_length = td->right_main_g.width - td->right_of_text_length - td->right_end_length; } /* If the window is sticky either across pages or * desks and it has a stippled title, but nothing for * sticky_stippled_title, then don't bother drawing them, just * return immediately. -- Thomas Adam */ if ( (IS_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw)) && (!HAS_STICKY_STIPPLED_TITLE(fw) && HAS_STIPPLED_TITLE(fw)) ) { return; } num = (int)(fw->title_thickness / WINDOW_TITLE_STICK_VERT_DIST / 2) * 2 - 1; min = fw->title_thickness / 2 - num * 2 + 1; max = fw->title_thickness / 2 + num * 2 - WINDOW_TITLE_STICK_VERT_DIST + 1; left_x = WINDOW_TITLE_STICK_OFFSET + td->left_end_length; left_w = ((under_text_length == 0)? td->offset:under_text_offset) - left_x - WINDOW_TITLE_TO_STICK_GAP - td->left_of_text_length; right_x = ((under_text_length == 0)? td->offset + td->length : under_text_offset + under_text_length) + td->right_of_text_length + WINDOW_TITLE_TO_STICK_GAP - 1; right_w = fw->title_length - right_x - WINDOW_TITLE_STICK_OFFSET - td->right_end_length; /* an odd number of lines every WINDOW_TITLE_STICK_VERT_DIST pixels */ if (left_w < WINDOW_TITLE_STICK_MIN_WIDTH) { left_x = td->left_end_length + ((left_length > WINDOW_TITLE_STICK_MIN_WIDTH)? (left_length - WINDOW_TITLE_STICK_MIN_WIDTH)/2 : 0); left_w = WINDOW_TITLE_STICK_MIN_WIDTH; } if (right_w < WINDOW_TITLE_STICK_MIN_WIDTH) { right_w = WINDOW_TITLE_STICK_MIN_WIDTH; right_x = fw->title_length - WINDOW_TITLE_STICK_MIN_WIDTH - 1 - td->right_end_length - ((right_length > WINDOW_TITLE_STICK_MIN_WIDTH)? (right_length - WINDOW_TITLE_STICK_MIN_WIDTH)/2 : 0); } for (i = min; i <= max; i += WINDOW_TITLE_STICK_VERT_DIST) { if (left_w > 0) { do_relieve_rectangle_with_rotation( dpy, dest_pix, SWAP_ARGS(td->has_vt, left_x, i), SWAP_ARGS(td->has_vt, left_w, 1), tdd->sgc, tdd->rgc, 1, False, rotation); } if (right_w > 0) { do_relieve_rectangle_with_rotation( dpy, dest_pix, SWAP_ARGS(td->has_vt, right_x, i), SWAP_ARGS(td->has_vt, right_w, 1), tdd->sgc, tdd->rgc, 1, False, rotation); } } return; } static void border_draw_title_mono( FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd, FlocaleWinString *fstr, Pixmap dest_pix) { int has_vt; has_vt = HAS_VERTICAL_TITLE(fw); XFillRectangle( dpy, dest_pix, td->cd->relief_gc, td->offset - 2, 0, td->length+4, fw->title_thickness); if (fw->visible_name != (char *)NULL) { FlocaleDrawString(dpy, fw->title_font, fstr, 0); } /* for mono, we clear an area in the title bar where the window * title goes, so that its more legible. For color, no need */ do_relieve_rectangle( dpy, dest_pix, 0, 0, SWAP_ARGS(has_vt, td->offset - 3, fw->title_thickness - 1), tdd->rgc, tdd->sgc, td->cd->relief_width, False); do_relieve_rectangle( dpy, dest_pix, SWAP_ARGS(has_vt, td->offset + td->length + 2, 0), SWAP_ARGS(has_vt, fw->title_length - td->length - td->offset - 3, fw->title_thickness - 1), tdd->rgc, tdd->sgc, td->cd->relief_width, False); XDrawLine( dpy, dest_pix, tdd->sgc, SWAP_ARGS(has_vt, 0, td->offset + td->length + 1), SWAP_ARGS(has_vt, td->offset + td->length + 1, fw->title_thickness)); return; } static void border_draw_title_relief( FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd, Pixmap dest_pix) { int reverse = 0; rotation_t rotation; if (td->td_is_rotated) { rotation = td->restore_rotation; } else { rotation = ROTATION_0; } /* draw title relief */ switch (DFS_BUTTON_RELIEF(*tdd->tstyle)) { case DFS_BUTTON_IS_SUNK: reverse = 1; case DFS_BUTTON_IS_UP: do_relieve_rectangle_with_rotation( dpy, dest_pix, 0, 0, SWAP_ARGS( td->has_vt, fw->title_length - 1, fw->title_thickness - 1), (reverse) ? tdd->sgc : tdd->rgc, (reverse) ? tdd->rgc : tdd->sgc, td->cd->relief_width, True, rotation); break; default: /* flat */ break; } return; } static void border_draw_title_deep( FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd, FlocaleWinString *fstr, Pixmap dest_pix, Window w) { DecorFace *df; pixmap_background_type bg; bg.flags.use_pixmap = 0; for (df = tdd->df; df != NULL; df = df->next) { if (df->style.face_type == MultiPixmap) { border_mp_draw_mp_titlebar( fw, td, df, dest_pix, w); } else { bg.pixel = df->u.back; border_draw_decor_to_pixmap( fw, dest_pix, w, &bg, &td->layout.title_g, df, td, td->tbstate.tstate, True, tdd->is_toggled, 1); } } FlocaleDrawString(dpy, fw->title_font, &tdd->fstr, 0); return; } static void border_get_titlebar_draw_descr( FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd, Pixmap dest_pix) { memset(tdd, 0, sizeof(*tdd)); /* prepare the gcs and variables */ if (td->tbstate.is_title_pressed) { tdd->rgc = td->cd->shadow_gc; tdd->sgc = td->cd->relief_gc; } else { tdd->rgc = td->cd->relief_gc; tdd->sgc = td->cd->shadow_gc; } NewFontAndColor(fw->title_font, td->cd->fore_color, td->cd->back_color); tdd->tstyle = &TB_STATE( GetDecor(fw, titlebar))[td->tbstate.tstate].style; tdd->df = &TB_STATE(GetDecor(fw, titlebar))[td->tbstate.tstate]; /* fetch the title string */ tdd->fstr.str = fw->visible_name; tdd->fstr.win = dest_pix; if (td->td_is_rotated) { tdd->fstr.flags.text_rotation = ROTATION_0; } else { tdd->fstr.flags.text_rotation = fw->title_text_rotation; } if (td->has_vt) { tdd->fstr.y = td->offset; tdd->fstr.x = fw->title_text_offset + 1; } else { tdd->fstr.x = td->offset; tdd->fstr.y = fw->title_text_offset + 1; } if (td->cd->cs >= 0) { tdd->fstr.colorset = &Colorset[td->cd->cs]; tdd->fstr.flags.has_colorset = 1; } tdd->fstr.gc = Scr.TitleGC; return; } static void border_set_title_pixmap( FvwmWindow *fw, titlebar_descr *td, Pixmap *dest_pix, Window w) { pixmap_background_type bg; title_draw_descr tdd; FlocaleWinString fstr; Bool free_bg_pixmap = False; rectangle pix_g; border_get_titlebar_draw_descr(fw, td, &tdd, *dest_pix); /* prepare background, either from the window colour or from the * border style */ if (!DFS_USE_BORDER_STYLE(*tdd.tstyle)) { /* fill with the button background colour */ bg.flags.use_pixmap = 0; bg.pixel = td->cd->back_color; pix_g.x = 0; pix_g.y = 0; pix_g.width = td->layout.title_g.width; pix_g.height = td->layout.title_g.height; border_fill_pixmap_background( *dest_pix, &pix_g, &bg, td->cd); } else { /* draw pixmap background inherited from border style */ rectangle relative_g; Pixmap tmp; if (td->draw_rotation != ROTATION_0) { tmp = CreateRotatedPixmap( dpy, *dest_pix, td->layout.title_g.width, td->layout.title_g.height, Pdepth, Scr.BordersGC, td->restore_rotation); XFreePixmap(dpy, *dest_pix); *dest_pix = tmp; border_rotate_titlebar_descr(fw, td); } relative_g.width = td->frame_g.width; relative_g.height = td->frame_g.height; relative_g.x = td->layout.title_g.x; relative_g.y = td->layout.title_g.y; border_get_border_background( &bg, td->cd, &td->layout.title_g, &relative_g, &free_bg_pixmap, w); bg.pixmap.g.x = 0; bg.pixmap.g.y = 0; /* set the geometry for drawing the Tiled pixmap; * FIXME: maybe add the relief as offset? */ pix_g.x = 0; pix_g.y = 0; pix_g.width = td->layout.title_g.width; pix_g.height = td->layout.title_g.height; border_fill_pixmap_background( *dest_pix, &pix_g, &bg, td->cd); if (free_bg_pixmap && bg.pixmap.p) { XFreePixmap(dpy, bg.pixmap.p); } if (td->draw_rotation != ROTATION_0) { tmp = CreateRotatedPixmap( dpy, *dest_pix, td->layout.title_g.width, td->layout.title_g.height, Pdepth, Scr.BordersGC, td->draw_rotation); XFreePixmap(dpy, *dest_pix); *dest_pix = tmp; border_rotate_titlebar_descr(fw, td); } } if (Pdepth < 2) { border_draw_title_mono(fw, td, &tdd, &fstr, *dest_pix); } else { border_draw_title_deep(fw, td, &tdd, &fstr, *dest_pix, w); } border_draw_title_relief(fw, td, &tdd, *dest_pix); border_draw_title_stick_lines(fw, td, &tdd, *dest_pix); return; } static void border_draw_title( FvwmWindow *fw, titlebar_descr *td) { Pixmap p; if (td->layout.title_g.x < 0 || td->layout.title_g.y < 0) { return; } if (td->draw_rotation != ROTATION_0) { border_rotate_titlebar_descr(fw, td); } /* make a pixmap */ p = border_create_decor_pixmap(td->cd, &(td->layout.title_g)); /* set the background tile */ #if 0 fprintf(stderr,"drawing title\n"); #endif border_set_title_pixmap(fw, td, &p, FW_W_TITLE(fw)); if (td->draw_rotation != ROTATION_0) { Pixmap tmp; tmp = CreateRotatedPixmap( dpy, p, td->layout.title_g.width, td->layout.title_g.height, Pdepth, Scr.BordersGC, td->draw_rotation); XFreePixmap(dpy, p); p = tmp; border_rotate_titlebar_descr(fw, td); } /* apply the pixmap and destroy it */ border_set_part_background(FW_W_TITLE(fw), p); XFreePixmap(dpy, p); if (td->tbstate.do_clear_title) { XClearWindow(dpy, FW_W_TITLE(fw)); } return; } static void border_draw_buttons( FvwmWindow *fw, titlebar_descr *td) { int i; /* draw everything in a big loop */ #if 0 fprintf(stderr, "drawing buttons 0x%04x\n", td->tbstate.draw_bmask); #endif for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { unsigned int mask = (1 << i); if ((td->tbstate.draw_bmask & mask) != 0) { border_draw_one_button(fw, td, i); } } /* update the button states */ fw->decor_state.buttons_drawn |= td->tbstate.draw_bmask; fw->decor_state.buttons_inverted = td->tbstate.pressed_bmask; fw->decor_state.buttons_lit = td->tbstate.lit_bmask; fw->decor_state.buttons_toggled = td->tbstate.toggled_bmask; return; } static void border_setup_use_title_style( FvwmWindow *fw, titlebar_descr *td) { int i; DecorFace *df, *tsdf; ButtonState bs, tsbs; /* use a full bar pixmap (for Colorset) or non window size pixmaps * (for MultiPixmap) under certain condition: * - for the buttons which use title style * - for title which have a button with UseTitle style */ tsbs = td->tbstate.tstate; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { bs = td->tbstate.bstate[i]; df = &TB_STATE(GetDecor(fw, buttons[i]))[bs]; tsdf = &TB_STATE(GetDecor(fw, buttons[i]))[tsbs]; if (FW_W_BUTTON(fw, i) != None) { if (DFS_USE_TITLE_STYLE(df->style)) { border_setup_bar_pixmaps( td, &(td->cd->dynamic_cd), &TB_STATE(GetDecor(fw, titlebar))[bs], bs); } if (DFS_USE_TITLE_STYLE(tsdf->style)) { border_setup_bar_pixmaps( td, &(td->cd->dynamic_cd), &TB_STATE(GetDecor(fw, titlebar))[tsbs], tsbs); } } } return; } static void border_rotate_titlebar_descr( FvwmWindow *fw, titlebar_descr *td) { rotation_t rotation; int i, tmpi; static titlebar_descr saved_td; if (td->draw_rotation == ROTATION_0) { return; } if (!td->has_been_saved) { td->has_been_saved = True; memcpy(&saved_td, td, sizeof(titlebar_descr)); } if (!td->td_is_rotated) { /* make the bar horizontal */ switch(td->draw_rotation) { case ROTATION_90: /* cw */ rotation = ROTATION_270; break; case ROTATION_270: /* ccw */ rotation = ROTATION_90; break; case ROTATION_180: rotation = ROTATION_180; break; default: return; } td->has_vt = 0; td->has_an_upsidedown_rotation = 0; td->td_is_rotated = 1; } else { /* restore */ memcpy(td, &saved_td, sizeof(titlebar_descr)); td->td_is_rotated = 0; return; } #define ROTATE_RECTANGLE(rot, r, vs_frame, vs_titlebar, vs_title) \ { \ rectangle tr; \ tr.x = r->x; \ tr.y = r->y; \ tr.width = r->width; \ tr.height = r->height; \ switch(rot) \ { \ case ROTATION_270: /* ccw */ \ tr.x = r->y; \ if (vs_frame) \ { \ tr.y = td->frame_g.width - (r->x+r->width); \ } \ else if (vs_titlebar) \ { \ tr.y = td->bar_g.width - \ (r->x+r->width); \ } \ else if (vs_title) \ { \ tr.y = td->layout.title_g.width - \ (r->x+r->width); \ } \ else \ { \ tr.y = r->x; \ } \ tr.width = r->height; \ tr.height = r->width; \ break; \ case ROTATION_90: /* cw */ \ if (vs_frame) \ { \ tr.x = td->frame_g.height - (r->y+r->height); \ } \ else if (vs_titlebar) \ { \ tr.x = td->bar_g.height - \ (r->y+r->height); \ } \ else if (vs_title) \ { \ tr.x = td->layout.title_g.height - \ (r->y+r->height); \ } \ else \ { \ tr.x = r->y; \ } \ tr.y = r->x; \ tr.width = r->height; \ tr.height = r->width; \ break; \ case ROTATION_180: \ if (vs_frame) \ { \ tr.x = td->frame_g.width - (r->x+r->width); \ } \ else if (vs_titlebar) \ { \ tr.x = td->bar_g.width - \ (r->x + r->width); \ } \ else if (vs_title) \ { \ tr.x = td->layout.title_g.width - \ (r->x + r->width); \ } \ else \ { \ tr.x = r->x; \ } \ break; \ case ROTATION_0: \ break; \ } \ r->x = tr.x; \ r->y = tr.y; \ r->width = tr.width; \ r->height = tr.height; \ } switch(rotation) { case ROTATION_90: td->offset = td->layout.title_g.height - td->offset - td->length; tmpi = td->left_end_length; td->left_end_length = td->right_end_length; td->right_end_length = tmpi; tmpi = td->left_of_text_length; td->left_of_text_length = td->right_of_text_length; td->right_of_text_length = tmpi; break; case ROTATION_270: break; case ROTATION_180: td->offset = td->layout.title_g.width - td->offset - td->length; tmpi = td->left_end_length; td->left_end_length = td->right_end_length; td->right_end_length = tmpi; tmpi = td->left_of_text_length; td->left_of_text_length = td->right_of_text_length; td->right_of_text_length = tmpi; break; case ROTATION_0: break; } ROTATE_RECTANGLE(rotation, (&td->left_buttons_g), True, False, False) ROTATE_RECTANGLE(rotation, (&td->right_buttons_g), True, False, False) for (i=0; i < NUMBER_OF_TITLE_BUTTONS; i++) { ROTATE_RECTANGLE( rotation, (&td->layout.button_g[i]), True, False, False) } ROTATE_RECTANGLE(rotation, (&td->under_text_g), False, False, True) ROTATE_RECTANGLE(rotation, (&td->left_main_g), False, False, True) ROTATE_RECTANGLE(rotation, (&td->right_main_g), False, False, True) ROTATE_RECTANGLE(rotation, (&td->full_left_main_g), True, False, False) ROTATE_RECTANGLE(rotation, (&td->full_right_main_g), True, False, False) ROTATE_RECTANGLE(rotation, (&td->layout.title_g), True, False, False) ROTATE_RECTANGLE(rotation, (&td->bar_g), True, False, False) ROTATE_RECTANGLE(rotation, (&td->frame_g), False, False, False); #undef ROTATE_RECTANGLE } static void border_get_titlebar_descr_state( FvwmWindow *fw, window_parts pressed_parts, int pressed_button, clear_window_parts clear_parts, Bool do_hilight, border_titlebar_state *tbstate) { int i; if ((pressed_parts & PART_BUTTONS) != PART_NONE && pressed_button >= 0) { tbstate->pressed_bmask = (1 << pressed_button); } else { tbstate->pressed_bmask = 0; } if ((clear_parts & CLEAR_BUTTONS) != CLEAR_NONE) { tbstate->clear_bmask = 0x3FF; } else { tbstate->clear_bmask = 0; } tbstate->lit_bmask = (do_hilight == True) ? ~0 : 0; if ((pressed_parts & PART_TITLE) != PART_NONE) { tbstate->is_title_pressed = 1; } else { tbstate->is_title_pressed = 0; } if ((clear_parts & CLEAR_TITLE) != CLEAR_NONE) { tbstate->do_clear_title = 1; } else { tbstate->do_clear_title = 0; } tbstate->is_title_lit = (do_hilight == True) ? 1 : 0; tbstate->toggled_bmask = 0; for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { unsigned int mask = (1 << i); if (is_button_toggled(fw, i)) { tbstate->toggled_bmask |= mask; } tbstate->bstate[i] = border_flags_to_button_state( tbstate->pressed_bmask & mask, tbstate->lit_bmask & mask, tbstate->toggled_bmask & mask); } tbstate->tstate = border_flags_to_button_state( tbstate->is_title_pressed, tbstate->is_title_lit, 0); } static window_parts border_get_titlebar_descr( common_decorations_type *cd, FvwmWindow *fw, window_parts pressed_parts, int pressed_button, window_parts force_draw_parts, clear_window_parts clear_parts, rectangle *old_g, rectangle *new_g, Bool do_hilight, titlebar_descr *ret_td) { window_parts draw_parts; int i; DecorFace *df; int is_start = 0; JustificationType just; int lbl = 0; int rbl = 0; ret_td->cd = cd; ret_td->frame_g = *new_g; if (old_g == NULL) { old_g = &fw->g.frame; } frame_get_titlebar_dimensions(fw, old_g, NULL, &ret_td->old_layout); frame_get_titlebar_dimensions(fw, new_g, NULL, &ret_td->layout); ret_td->has_vt = HAS_VERTICAL_TITLE(fw); if (USE_TITLE_DECOR_ROTATION(fw)) { ret_td->draw_rotation = fw->title_text_rotation; switch(ret_td->draw_rotation) { case ROTATION_90: ret_td->restore_rotation = ROTATION_270; break; case ROTATION_270: /* ccw */ ret_td->restore_rotation = ROTATION_90; break; case ROTATION_180: ret_td->restore_rotation = ROTATION_180; break; default: break; } } if (fw->title_text_rotation == ROTATION_270 || fw->title_text_rotation == ROTATION_180) { ret_td->has_an_upsidedown_rotation = True; } /* geometry of the title bar title + buttons */ if (!ret_td->has_vt) { ret_td->bar_g.width = new_g->width - 2 * fw->boundary_width; ret_td->bar_g.height = ret_td->layout.title_g.height; ret_td->bar_g.x = fw->boundary_width; ret_td->bar_g.y = ret_td->layout.title_g.y; } else { ret_td->bar_g.width = ret_td->layout.title_g.width; ret_td->bar_g.height = new_g->height - 2 * fw->boundary_width; ret_td->bar_g.y = fw->boundary_width; ret_td->bar_g.x = ret_td->layout.title_g.x; } /* buttons geometries */ if (ret_td->has_vt) { ret_td->left_buttons_g.width = ret_td->bar_g.width; ret_td->right_buttons_g.width = ret_td->bar_g.width; } else { ret_td->left_buttons_g.height = ret_td->bar_g.height; ret_td->right_buttons_g.height = ret_td->bar_g.width; } for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if (FW_W_BUTTON(fw, i) == None) { continue; } if (ret_td->has_vt) { if (i & 1) { rbl += ret_td->layout.button_g[i].height; } else { lbl += ret_td->layout.button_g[i].height; } } else { if (i & 1) { rbl += ret_td->layout.button_g[i].width; } else { lbl += ret_td->layout.button_g[i].width; } } } if (ret_td->has_an_upsidedown_rotation) { if (ret_td->has_vt) { ret_td->left_buttons_g.height = rbl; ret_td->right_buttons_g.height = lbl; ret_td->right_buttons_g.y = fw->boundary_width; ret_td->right_buttons_g.x = ret_td->bar_g.x; ret_td->left_buttons_g.y = ret_td->layout.title_g.y + ret_td->layout.title_g.height; ret_td->left_buttons_g.x = ret_td->bar_g.x; } else { ret_td->left_buttons_g.width = rbl; ret_td->right_buttons_g.width = lbl; ret_td->right_buttons_g.x = fw->boundary_width; ret_td->right_buttons_g.y = ret_td->bar_g.y; ret_td->left_buttons_g.x = ret_td->layout.title_g.x + ret_td->layout.title_g.width; ret_td->left_buttons_g.y = ret_td->bar_g.y; } } else { if (ret_td->has_vt) { ret_td->left_buttons_g.height = lbl; ret_td->right_buttons_g.height = rbl; ret_td->left_buttons_g.y = fw->boundary_width; ret_td->left_buttons_g.x = ret_td->bar_g.x; ret_td->right_buttons_g.y = ret_td->layout.title_g.y + ret_td->layout.title_g.height; ret_td->right_buttons_g.x = ret_td->bar_g.x; } else { ret_td->left_buttons_g.width = lbl; ret_td->right_buttons_g.width = rbl; ret_td->left_buttons_g.x = fw->boundary_width; ret_td->left_buttons_g.y = ret_td->bar_g.y; ret_td->right_buttons_g.x = ret_td->layout.title_g.x + ret_td->layout.title_g.width; ret_td->right_buttons_g.y = ret_td->bar_g.y; } } /* initialise flags */ border_get_titlebar_descr_state( fw, pressed_parts, pressed_button, clear_parts, do_hilight, &(ret_td->tbstate)); /* get the title string length and position * This is not in "tdd" (titlebar_draw_descr), because these are needed * to draw the buttons with UseTitleStyle */ just = TB_JUSTIFICATION(GetDecor(fw, titlebar)); if (fw->visible_name != (char *)NULL) { ret_td->length = FlocaleTextWidth( fw->title_font, fw->visible_name, (ret_td->has_vt) ? -strlen(fw->visible_name) : strlen(fw->visible_name)); if (ret_td->length > fw->title_length - 2*MIN_WINDOW_TITLE_TEXT_OFFSET) { ret_td->length = fw->title_length - 2*MIN_WINDOW_TITLE_TEXT_OFFSET; just = JUST_CENTER; } if (ret_td->length < 0) { ret_td->length = 0; } } else { ret_td->length = 0; } if (ret_td->length == 0) { just = JUST_CENTER; } df = &TB_STATE(GetDecor(fw, titlebar))[ret_td->tbstate.tstate]; switch (just) { case JUST_LEFT: is_start = 1; /* fall through */ case JUST_RIGHT: if (ret_td->has_an_upsidedown_rotation) { is_start = !is_start; } if (is_start) { if (WINDOW_TITLE_TEXT_OFFSET + ret_td->length <= fw->title_length) { ret_td->offset = WINDOW_TITLE_TEXT_OFFSET; } else { ret_td->offset = fw->title_length - ret_td->length; } } else { ret_td->offset = fw->title_length - ret_td->length - WINDOW_TITLE_TEXT_OFFSET; } break; case JUST_CENTER: default: ret_td->offset = (fw->title_length - ret_td->length) / 2; break; } if (ret_td->offset < MIN_WINDOW_TITLE_TEXT_OFFSET) { ret_td->offset = MIN_WINDOW_TITLE_TEXT_OFFSET; } /* setup MultiPixmap */ border_mp_get_titlebar_descr(fw, ret_td, df); /* determine the parts to draw */ draw_parts = border_get_tb_parts_to_draw( fw, ret_td, old_g, new_g, force_draw_parts); return draw_parts; } static void border_draw_titlebar( common_decorations_type *cd, FvwmWindow *fw, window_parts pressed_parts, int pressed_button, window_parts force_draw_parts, clear_window_parts clear_parts, rectangle *old_g, rectangle *new_g, Bool do_hilight) { window_parts draw_parts; titlebar_descr td; if (!HAS_TITLE(fw)) { /* just reset border states */ fw->decor_state.parts_drawn &= ~(PART_TITLE); fw->decor_state.parts_lit &= ~(PART_TITLE); fw->decor_state.parts_inverted &= ~(PART_TITLE); fw->decor_state.buttons_drawn = 0; fw->decor_state.buttons_lit = 0; fw->decor_state.buttons_inverted = 0; fw->decor_state.buttons_toggled = 0; return; } memset(&td, 0, sizeof(td)); draw_parts = border_get_titlebar_descr( cd, fw, pressed_parts, pressed_button, force_draw_parts, clear_parts, old_g, new_g, do_hilight, &td); if ((draw_parts & PART_TITLE) != PART_NONE || (draw_parts & PART_BUTTONS) != PART_NONE) { /* set up UseTitleStyle Colorset */ border_setup_use_title_style(fw, &td); } if ((draw_parts & PART_TITLE) != PART_NONE) { border_draw_title(fw, &td); } if ((draw_parts & PART_BUTTONS) != PART_NONE) { border_draw_buttons(fw, &td); } border_free_bar_pixmaps(&(td.cd->dynamic_cd)); /* update the decor states */ fw->decor_state.parts_drawn |= draw_parts; if (do_hilight) { fw->decor_state.parts_lit |= draw_parts; } else { fw->decor_state.parts_lit &= ~draw_parts; } fw->decor_state.parts_inverted &= ~draw_parts; fw->decor_state.parts_inverted |= (draw_parts & pressed_parts); if (draw_parts & PART_BUTTONS) { fw->decor_state.buttons_drawn |= td.tbstate.draw_bmask; fw->decor_state.parts_lit = (do_hilight) ? ~0 : 0; if (td.tbstate.pressed_bmask) { fw->decor_state.buttons_inverted = td.tbstate.pressed_bmask; } else { fw->decor_state.buttons_inverted &= ~td.tbstate.draw_bmask; } fw->decor_state.buttons_toggled = (fw->decor_state.buttons_toggled & ~td.tbstate.max_bmask) | td.tbstate.toggled_bmask; } return; } /* * * Redraws the windows borders * */ static void border_draw_border_parts( common_decorations_type *cd, FvwmWindow *fw, window_parts pressed_parts, window_parts force_draw_parts, clear_window_parts clear_parts, rectangle *old_g, rectangle *new_g, Bool do_hilight) { border_relief_descr br; window_parts draw_parts; Bool do_clear; if (HAS_NO_BORDER(fw)) { /* just reset border states */ fw->decor_state.parts_drawn &= ~(PART_FRAME | PART_HANDLES); fw->decor_state.parts_lit &= ~(PART_FRAME | PART_HANDLES); fw->decor_state.parts_inverted &= ~(PART_FRAME | PART_HANDLES); return; } do_clear = (clear_parts & CLEAR_FRAME) ? True : False; /* determine the parts to draw and the position to place them */ if (HAS_DEPRESSABLE_BORDER(fw)) { pressed_parts &= PART_FRAME; } else { pressed_parts = PART_NONE; } force_draw_parts &= PART_FRAME; memset(&br, 0, sizeof(br)); draw_parts = border_get_parts_and_pos_to_draw( cd, fw, pressed_parts, force_draw_parts, old_g, new_g, do_hilight, &br); if ((draw_parts & PART_FRAME) != PART_NONE) { border_draw_all_border_parts( cd, fw, &br, new_g, draw_parts, pressed_parts, do_hilight, do_clear); } /* update the decor states */ fw->decor_state.parts_drawn |= draw_parts; if (do_hilight) { fw->decor_state.parts_lit |= draw_parts; } else { fw->decor_state.parts_lit &= ~draw_parts; } fw->decor_state.parts_inverted &= ~draw_parts; fw->decor_state.parts_inverted |= (draw_parts & pressed_parts); return; } /* ---------------------------- interface functions ------------------------ */ DecorFace *border_get_border_style( FvwmWindow *fw, Bool has_focus) { DecorFace *df; if (has_focus == True) { df = &(GetDecor(fw, BorderStyle.active)); } else { df = &(GetDecor(fw, BorderStyle.inactive)); } return df; } int border_is_using_border_style( FvwmWindow *fw, Bool has_focus) { ButtonState bs; int is_pressed; int is_toggled; int i; /* title */ is_pressed = (FW_W_TITLE(fw) == PressedW); bs = border_flags_to_button_state(is_pressed, has_focus, 0); if (DFS_USE_BORDER_STYLE(TB_STATE(GetDecor(fw, titlebar))[bs].style)) { return 1; } for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { if (FW_W_BUTTON(fw, i) == None) { continue; } is_pressed = (FW_W_BUTTON(fw, i) == PressedW); is_toggled = (is_button_toggled(fw, i) == True); bs = border_flags_to_button_state( is_pressed, (has_focus == True), is_toggled); if (DFS_USE_BORDER_STYLE( TB_STATE(GetDecor(fw, buttons[i]))[bs].style)) { return 1; } } return 0; } int border_context_to_parts( int context) { if (context == C_FRAME || context == C_SIDEBAR || context == (C_FRAME | C_SIDEBAR)) { return PART_FRAME; } else if (context == C_F_TOPLEFT) { return PART_BORDER_NW; } else if (context == C_F_TOPRIGHT) { return PART_BORDER_NE; } else if (context == C_F_BOTTOMLEFT) { return PART_BORDER_SW; } else if (context == C_F_BOTTOMRIGHT) { return PART_BORDER_SE; } else if (context == C_SB_LEFT) { return PART_BORDER_W; } else if (context == C_SB_RIGHT) { return PART_BORDER_E; } else if (context == C_SB_TOP) { return PART_BORDER_N; } else if (context == C_SB_BOTTOM) { return PART_BORDER_S; } else if (context == C_TITLE) { return PART_TITLE; } else if (context & (C_LALL | C_RALL)) { return PART_BUTTONS; } return PART_NONE; } void border_get_part_geometry( FvwmWindow *fw, window_parts part, rectangle *sidebar_g, rectangle *ret_g, Window *ret_w) { int bw; bw = fw->boundary_width; /* ret_g->x and ret->y is just an offset relatively to the w, * maybe we can take the relief in account? */ switch (part) { case PART_BORDER_N: ret_g->x = sidebar_g->x; ret_g->y = 0; *ret_w = FW_W_SIDE(fw, 0); break; case PART_BORDER_E: ret_g->x = 2 * sidebar_g->x + sidebar_g->width - bw; ret_g->y = sidebar_g->y; *ret_w = FW_W_SIDE(fw, 1); break; case PART_BORDER_S: ret_g->x = sidebar_g->x; ret_g->y = 2 * sidebar_g->y + sidebar_g->height - bw; *ret_w = FW_W_SIDE(fw, 2); break; case PART_BORDER_W: ret_g->x = 0; ret_g->y = sidebar_g->y; *ret_w = FW_W_SIDE(fw, 3); break; case PART_BORDER_NW: ret_g->x = 0; ret_g->y = 0; *ret_w = FW_W_CORNER(fw, 0); break; case PART_BORDER_NE: ret_g->x = sidebar_g->x + sidebar_g->width; ret_g->y = 0; *ret_w = FW_W_CORNER(fw, 1); break; case PART_BORDER_SW: ret_g->x = 0; ret_g->y = sidebar_g->y + sidebar_g->height; *ret_w = FW_W_CORNER(fw, 2); break; case PART_BORDER_SE: ret_g->x = sidebar_g->x + sidebar_g->width; ret_g->y = sidebar_g->y + sidebar_g->height; *ret_w = FW_W_CORNER(fw, 3); break; default: break; } switch (part) { case PART_BORDER_N: case PART_BORDER_S: ret_g->width = sidebar_g->width; ret_g->height = bw; break; case PART_BORDER_E: case PART_BORDER_W: ret_g->width = bw; ret_g->height = sidebar_g->height; break; case PART_BORDER_NW: case PART_BORDER_NE: case PART_BORDER_SW: case PART_BORDER_SE: ret_g->width = sidebar_g->x; ret_g->height = sidebar_g->y; break; default: return; } return; } int get_button_number(int context) { int i; for (i = 0; (C_L1 << i) & (C_LALL | C_RALL); i++) { if (context & (C_L1 << i)) { return i; } } return -1; } void border_draw_decorations( FvwmWindow *fw, window_parts draw_parts, Bool has_focus, Bool do_force, clear_window_parts clear_parts, rectangle *old_g, rectangle *new_g) { common_decorations_type cd; Bool do_redraw_titlebar = False; window_parts pressed_parts; window_parts force_parts; int context; int item; if (fw == NULL) { return; } if (WAS_NEVER_DRAWN(fw)) { /* force drawing everything */ do_force = True; draw_parts = PART_ALL; SET_WAS_NEVER_DRAWN(fw, 0); } memset(&cd, 0, sizeof(cd)); /* can't compare with True here, old code calls this with value "2" */ if (do_force != False) { force_parts = draw_parts; } else { force_parts = PART_NONE; } if (has_focus) { /* don't re-draw just for kicks */ if (Scr.Hilite != fw && Scr.Hilite != NULL) { FvwmWindow *t = Scr.Hilite; Scr.Hilite = NULL; /* make sure that the previously highlighted * window got unhighlighted */ border_draw_decorations( t, PART_ALL, False, True, CLEAR_ALL, NULL, NULL); } Scr.Hilite = fw; } else if (fw == Scr.Hilite) { Scr.Hilite = NULL; } if (fw->Desk != Scr.CurrentDesk) { return; } if (IS_ICONIFIED(fw)) { DrawIconWindow(fw, True, True, True, False, NULL); return; } /* calculate some values and flags */ if ((draw_parts & PART_TITLEBAR) && HAS_TITLE(fw)) { do_redraw_titlebar = True; } get_common_decorations( &cd, fw, draw_parts, has_focus, False, do_redraw_titlebar); /* redraw */ context = frame_window_id_to_context(fw, PressedW, &item); if ((context & (C_LALL | C_RALL)) == 0) { item = -1; } pressed_parts = border_context_to_parts(context); if (new_g == NULL) { new_g = &fw->g.frame; } if (do_redraw_titlebar) { border_draw_titlebar( &cd, fw, pressed_parts & PART_TITLEBAR, item, force_parts & PART_TITLEBAR, clear_parts, old_g, new_g, has_focus); } if (draw_parts & PART_FRAME) { Pixmap save_pix = cd.dynamic_cd.frame_pixmap; memset(&cd, 0, sizeof(cd)); get_common_decorations( &cd, fw, draw_parts, has_focus, True, True); cd.dynamic_cd.frame_pixmap = save_pix; border_draw_border_parts( &cd, fw, (pressed_parts & (PART_FRAME | PART_HANDLES)), (force_parts & (PART_FRAME | PART_HANDLES)), clear_parts, old_g, new_g, has_focus); } if (cd.dynamic_cd.frame_pixmap != None) { XFreePixmap(dpy, cd.dynamic_cd.frame_pixmap); } return; } void border_undraw_decorations( FvwmWindow *fw) { memset(&fw->decor_state, 0, sizeof(fw->decor_state)); return; } /* * * redraw the decoration when style change * */ void border_redraw_decorations( FvwmWindow *fw) { FvwmWindow *u = Scr.Hilite; /* domivogt (6-Jun-2000): Don't check if the window is visible here. * If we do, some updates are not applied and when the window becomes * visible again, the X Server may not redraw the window. */ border_draw_decorations( fw, PART_ALL, (Scr.Hilite == fw), True, CLEAR_ALL, NULL, NULL); Scr.Hilite = u; return; } /* * * get the the root transparent parts of the decoration * */ unsigned int border_get_transparent_decorations_part(FvwmWindow *fw) { DecorFace *df,*tdf; unsigned int draw_parts = PART_NONE; int i; window_parts pressed_parts; int context; int item; border_titlebar_state tbstate; Bool title_use_borderstyle = False; Bool buttons_use_borderstyle = False; Bool buttons_use_titlestyle = False; context = frame_window_id_to_context(fw, PressedW, &item); if ((context & (C_LALL | C_RALL)) == 0) { item = -1; } pressed_parts = border_context_to_parts(context); memset(&tbstate, 0, sizeof(tbstate)); border_get_titlebar_descr_state( fw, pressed_parts & PART_TITLEBAR, item, CLEAR_ALL, (Scr.Hilite == fw), &tbstate); for(i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++) { df = &TB_STATE(GetDecor(fw, buttons[i]))[tbstate.bstate[i]]; if (DFS_USE_TITLE_STYLE(df->style)) { buttons_use_titlestyle = True; } if (DFS_USE_BORDER_STYLE(df->style)) { buttons_use_borderstyle = True; } for(tdf = df; tdf != NULL; tdf = tdf->next) { if (DFS_FACE_TYPE(tdf->style) == ColorsetButton && CSET_IS_TRANSPARENT_ROOT(tdf->u.acs.cs)) { draw_parts |= PART_BUTTONS; break; } } } df = &TB_STATE(GetDecor(fw, titlebar))[tbstate.tstate]; if (DFS_USE_BORDER_STYLE(df->style)) { title_use_borderstyle = True; } for(tdf = df; tdf != NULL; tdf = tdf->next) { if (DFS_FACE_TYPE(tdf->style) == ColorsetButton && CSET_IS_TRANSPARENT_ROOT(tdf->u.acs.cs)) { draw_parts |= PART_TITLE; break; } else if (DFS_FACE_TYPE(tdf->style) == MultiPixmap) { int i; for (i = 0; i < TBMP_NUM_PIXMAPS; i++) { if (CSET_IS_TRANSPARENT_ROOT( tdf->u.mp.acs[i].cs)) { draw_parts |= PART_TITLE; break; } } } } df = border_get_border_style(fw, (Scr.Hilite == fw)); if (DFS_FACE_TYPE(df->style) == ColorsetButton && CSET_IS_TRANSPARENT_ROOT(df->u.acs.cs)) { draw_parts |= PART_FRAME|PART_HANDLES; } if (draw_parts & PART_FRAME) { if (title_use_borderstyle) { draw_parts |= PART_TITLE; } if (buttons_use_borderstyle) { draw_parts |= PART_BUTTONS; } } if ((draw_parts & PART_TITLE) && buttons_use_titlestyle) { draw_parts |= PART_BUTTONS; } #if 0 fprintf(stderr,"Transparant Part: %u\n", draw_parts); #endif return draw_parts; } /* ---------------------------- builtin commands --------------------------- */ /* * * Sets the allowed button states * */ void CMD_ButtonState(F_CMD_ARGS) { char *token; while ((token = PeekToken(action, &action))) { static char first = True; if (!token && first) { Scr.gs.use_active_down_buttons = DEFAULT_USE_ACTIVE_DOWN_BUTTONS; Scr.gs.use_inactive_buttons = DEFAULT_USE_INACTIVE_BUTTONS; Scr.gs.use_inactive_down_buttons = DEFAULT_USE_INACTIVE_DOWN_BUTTONS; return; } first = False; if (StrEquals("activedown", token)) { Scr.gs.use_active_down_buttons = ParseToggleArgument( action, &action, DEFAULT_USE_ACTIVE_DOWN_BUTTONS, True); } else if (StrEquals("inactive", token)) { Scr.gs.use_inactive_buttons = ParseToggleArgument( action, &action, DEFAULT_USE_INACTIVE_BUTTONS, True); } else if (StrEquals("inactivedown", token)) { Scr.gs.use_inactive_down_buttons = ParseToggleArgument( action, &action, DEFAULT_USE_INACTIVE_DOWN_BUTTONS, True); } else { Scr.gs.use_active_down_buttons = DEFAULT_USE_ACTIVE_DOWN_BUTTONS; Scr.gs.use_inactive_buttons = DEFAULT_USE_INACTIVE_BUTTONS; Scr.gs.use_inactive_down_buttons = DEFAULT_USE_INACTIVE_DOWN_BUTTONS; fvwm_msg(ERR, "cmd_button_state", "Unknown button state %s", token); return; } } return; } /* * * Sets the border style (veliaa@rpi.edu) * */ void CMD_BorderStyle(F_CMD_ARGS) { char *parm; char *prev; FvwmDecor *decor = Scr.cur_decor ? Scr.cur_decor : &Scr.DefaultDecor; Scr.flags.do_need_window_update = 1; decor->flags.has_changed = 1; for (prev = action; (parm = PeekToken(action, &action)); prev = action) { if (StrEquals(parm, "active") || StrEquals(parm, "inactive")) { int len; char *end, *tmp; DecorFace tmpdf, *df; memset(&tmpdf.style, 0, sizeof(tmpdf.style)); DFS_FACE_TYPE(tmpdf.style) = SimpleButton; tmpdf.next = NULL; if (FMiniIconsSupported) { tmpdf.u.p = NULL; } if (StrEquals(parm,"active")) { df = &decor->BorderStyle.active; } else { df = &decor->BorderStyle.inactive; } df->flags.has_changed = 1; while (isspace(*action)) { ++action; } if (*action != '(') { if (!*action) { fvwm_msg( ERR, "SetBorderStyle", "error in %s border" " specification", parm); return; } while (isspace(*action)) { ++action; } if (ReadDecorFace(action, &tmpdf,-1,True)) { FreeDecorFace(dpy, df); *df = tmpdf; } break; } end = strchr(++action, ')'); if (!end) { fvwm_msg( ERR, "SetBorderStyle", "error in %s border specification", parm); return; } len = end - action + 1; tmp = safemalloc(len); strncpy(tmp, action, len - 1); tmp[len - 1] = 0; ReadDecorFace(tmp, df,-1,True); free(tmp); action = end + 1; } else if (strcmp(parm,"--")==0) { if (ReadDecorFace( prev, &decor->BorderStyle.active,-1,True)) { ReadDecorFace( prev, &decor->BorderStyle.inactive, -1, False); } decor->BorderStyle.active.flags.has_changed = 1; decor->BorderStyle.inactive.flags.has_changed = 1; break; } else { DecorFace tmpdf; memset(&tmpdf.style, 0, sizeof(tmpdf.style)); DFS_FACE_TYPE(tmpdf.style) = SimpleButton; tmpdf.next = NULL; if (FMiniIconsSupported) { tmpdf.u.p = NULL; } if (ReadDecorFace(prev, &tmpdf,-1,True)) { FreeDecorFace(dpy,&decor->BorderStyle.active); decor->BorderStyle.active = tmpdf; ReadDecorFace( prev, &decor->BorderStyle.inactive, -1, False); decor->BorderStyle.active.flags.has_changed = 1; decor->BorderStyle.inactive.flags.has_changed = 1; } break; } } return; } fvwm-2.6.7/fvwm/eventhandler.h0000644000175700017570000000356512773467232013301 00000000000000/* -*-c-*- */ #ifndef EVENTHANDLER_H #define EVENTHANDLER_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct { const exec_context_t *exc; } evh_args_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* ---------------------------- event handlers ----------------------------- */ void HandleEvents(void); void HandleExpose(const evh_args_t *ea); void HandleFocusIn(const evh_args_t *ea); void HandleFocusOut(const evh_args_t *ea); void HandleDestroyNotify(const evh_args_t *ea); void HandleMapRequest(const evh_args_t *ea); void HandleMapRequestKeepRaised( const evh_args_t *ea, Window KeepRaised, FvwmWindow *ReuseWin, initial_window_options_t *win_opts); void HandleMapNotify(const evh_args_t *ea); void HandleUnmapNotify(const evh_args_t *ea); void HandleMotionNotify(const evh_args_t *ea); void HandleButtonRelease(const evh_args_t *ea); void HandleButtonPress(const evh_args_t *ea); void HandleEnterNotify(const evh_args_t *ea); void HandleLeaveNotify(const evh_args_t *ea); void HandleConfigureRequest(const evh_args_t *ea); void HandleClientMessage(const evh_args_t *ea); void HandlePropertyNotify(const evh_args_t *ea); void HandleKeyPress(const evh_args_t *ea); void HandleKeyRelease(const evh_args_t *ea); void HandleVisibilityNotify(const evh_args_t *ea); STROKE_CODE(void HandleButtonRelease(const evh_args_t *ea)); STROKE_CODE(void HandleMotionNotify(const evh_args_t *ea)); #endif /* EVENTHANDLER_H */ fvwm-2.6.7/fvwm/stack.h0000644000175700017570000000325712773467232011725 00000000000000/* -*-c-*- */ #ifndef _STACK_H #define _STACK_H #define DEBUG_STACK_RING 1 #ifdef DEBUG_STACK_RING void verify_stack_ring_consistency(void); #endif void remove_window_from_stack_ring(FvwmWindow *t); void add_window_to_stack_ring_after(FvwmWindow *t, FvwmWindow *add_after_win); FvwmWindow *get_next_window_in_stack_ring(const FvwmWindow *t); FvwmWindow *get_prev_window_in_stack_ring(const FvwmWindow *t); FvwmWindow *get_transientfor_fvwmwindow(const FvwmWindow *t); Bool position_new_window_in_stack_ring(FvwmWindow *t, Bool do_lower); void RaiseWindow(FvwmWindow *t, Bool is_client_request); void LowerWindow(FvwmWindow *t, Bool is_client_request); Bool HandleUnusualStackmodes( unsigned int stack_mode, FvwmWindow *r, Window rw, FvwmWindow *sib, Window sibw); void BroadcastRestackAllWindows(void); void BroadcastRestackThisWindow(FvwmWindow *t); int compare_window_layers(FvwmWindow *t, FvwmWindow *s); void set_default_layer(FvwmWindow *t, int layer); void set_layer(FvwmWindow *t, int layer); int get_layer(FvwmWindow *t); void new_layer(FvwmWindow *t, int layer); void init_stack_and_layers(void); Bool is_on_top_of_layer(FvwmWindow *t); Bool is_on_top_of_layer_and_above_unmanaged(FvwmWindow *t); /* This function recursively finds the transients of the window t and sets * their is_in_transient_subtree flag. If a layer is given, only windows in * this layer are checked. If the layer is < 0, all windows are considered. */ #define MARK_RAISE 0 #define MARK_LOWER 1 #define MARK_RESTACK 2 #define MARK_ALL 3 #define MARK_ALL_LAYERS -1 void mark_transient_subtree( FvwmWindow *t, int layer, int mark_mode, Bool do_ignore_icons, Bool use_window_group_hint); #endif /* _STACK_H */ fvwm-2.6.7/fvwm/module_list.c0000644000175700017570000006712013001406607013112 00000000000000/* -*-c-*- */ /* 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 #ifdef HAVE_FCNTL_H #include #endif /* for F_CMD_ARGS */ #include "fvwm/fvwm.h" #include "execcontext.h" /* end of for CMD_ARGS */ /*for debug message*/ #include "fvwm.h" #include "misc.h" /* end of for debug message */ /* for get_current_read_file */ #include "read.h" /* for busy cursor */ #include "cursor.h" /* for Scr global */ #include "screen.h" #include "externs.h" /* for module syncronous */ #include "libs/ftime.h" #include "libs/System.c" #include "libs/envvar.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/wild.h" #include "libs/fvwmsignal.h" #include "events.h" #include "bindings.h" /* for positive write */ #include "module_list.h" #include "module_interface.h" /* * Use POSIX behaviour if we can, otherwise use SysV instead * should this be here? */ #ifndef O_NONBLOCK # define O_NONBLOCK O_NDELAY #endif #define MOD_NOGRABMASK(m) ((m)->xNoGrabMask) #define MOD_SYNCMASK(m) ((m)->xSyncMask) typedef struct { unsigned long *data; int size; int done; } mqueue_object_type; /* the linked list pointers to the first and last modules */ static fmodule_list module_list = NULL; /* keep to-be-deleted modules in a deathrow until they are deleted safely. */ static fmodule_list death_row = NULL; /* * static functions */ static fmodule *module_alloc(void); static void module_free(fmodule *module); /* * list handling functions */ static inline void module_list_insert(fmodule *module, fmodule_list *list); static inline fmodule *module_list_remove(fmodule *module, fmodule_list *list); static inline void module_list_destroy(fmodule_list *list); static void KillModuleByName(char *name, char *alias); static char *get_pipe_name(fmodule *module); static void DeleteMessageQueueBuff(fmodule *module); static inline void msg_mask_set( msg_masks_t *msg_mask, unsigned long m1, unsigned long m2); static void set_message_mask(msg_masks_t *mask, unsigned long msg); void module_kill_all(void) { module_list_destroy(&module_list); return; } static fmodule *module_alloc(void) { fmodule *module; module = (fmodule *)safemalloc(sizeof(fmodule)); MOD_SET_CMDLINE(module, 0); MOD_READFD(module) = -1; MOD_WRITEFD(module) = -1; fqueue_init(&MOD_PIPEQUEUE(module)); msg_mask_set(&MOD_PIPEMASK(module), DEFAULT_MASK, DEFAULT_MASK); msg_mask_set(&MOD_NOGRABMASK(module), 0, 0); msg_mask_set(&MOD_SYNCMASK(module), 0, 0); MOD_NAME(module) = NULL; MOD_ALIAS(module) = NULL; return module; } /* closes the pipes and frees every data associated with a module record */ static void module_free(fmodule *module) { if (module == NULL) { return; } close(MOD_WRITEFD(module)); close(MOD_READFD(module)); if (MOD_NAME(module) != NULL) { free(MOD_NAME(module)); } if (MOD_ALIAS(module) != NULL) { free(MOD_ALIAS(module)); } while (!FQUEUE_IS_EMPTY(&(MOD_PIPEQUEUE(module)))) { DeleteMessageQueueBuff(module); } free(module); return; } static inline void module_list_insert(fmodule *module, fmodule_list *list) { fmodule_store *new_store; DBUG("module_list_insert", "inserting module"); if (module == NULL) { return; } new_store = (fmodule_store*)safemalloc(sizeof(fmodule_store)); new_store->module = module; new_store->next = *list; *list = new_store; return; } static inline fmodule *module_list_remove(fmodule *module, fmodule_list *list) { fmodule_store **position; if (module == NULL) { return NULL; } for ( position = list; *position != NULL; position = &((*position)->next)) { if ((*position)->module == module) { /* found it */ fmodule_store *current; DBUG("module_list_remove", "Removing from module list"); current = *position; *position = (*position)->next; free(current); return module; } } /* module not found */ DBUG("module_list_remove", "Tried to remove a not listed module!"); return NULL; } static inline void module_list_destroy(fmodule_list *list) { fmodule_store *current; fmodule_store *next; for (current = *list; current != NULL; current = next) { next = current->next; module_free(current->module); free(current); } *list = NULL; return; } static fmodule *do_execute_module( F_CMD_ARGS, Bool desperate, Bool do_listen_only) { int fvwm_to_app[2], app_to_fvwm[2]; int i, val, nargs = 0; char *cptr = NULL; char **args = NULL; char *arg1 = NULL; char arg2[20]; char arg3[20]; char arg5[20]; char arg6[20]; char *token; extern char *ModulePath; Window win; FvwmWindow * const fw = exc->w.fw; fmodule *module; fvwm_to_app[0] = -1; fvwm_to_app[1] = -1; app_to_fvwm[1] = -1; app_to_fvwm[0] = -1; args = (char **)safemalloc(7 * sizeof(char *)); /* Olivier: Why ? */ /* if (eventp->type != KeyPress) */ /* UngrabEm(); */ if (action == NULL) { goto err_exit; } if (fw) { win = FW_W(fw); } else { win = None; } action = GetNextToken(action, &cptr); if (!cptr) { goto err_exit; } arg1 = searchPath(ModulePath, cptr, EXECUTABLE_EXTENSION, X_OK); if (arg1 == NULL) { /* If this function is called in 'desparate' mode this means * fvwm is trying a module name as a last resort. In this case * the error message is inappropriate because it was most * likely a typo in a command, not a module name. */ if (!desperate) { fvwm_msg( ERR, "executeModule", "No such module '%s' in ModulePath '%s'", cptr, ModulePath); } goto err_exit; } #ifdef REMOVE_EXECUTABLE_EXTENSION { char *p; p = arg1 + strlen(arg1) - strlen(EXECUTABLE_EXTENSION); if (strcmp(p, EXECUTABLE_EXTENSION) == 0) { *p = 0; } } #endif /* I want one-ended pipes, so I open two two-ended pipes, * and close one end of each. I need one ended pipes so that * I can detect when the module crashes/malfunctions */ if (do_listen_only == True) { fvwm_to_app[0] = -1; fvwm_to_app[1] = -1; } else if (pipe(fvwm_to_app) != 0) { fvwm_msg(ERR, "executeModule", "Failed to open pipe"); goto err_exit; } if (pipe(app_to_fvwm) != 0) { fvwm_msg(ERR, "executeModule", "Failed to open pipe2"); goto err_exit; } if ( fvwm_to_app[0] >= fvwmlib_max_fd || fvwm_to_app[1] >= fvwmlib_max_fd || app_to_fvwm[0] >= fvwmlib_max_fd || app_to_fvwm[1] >= fvwmlib_max_fd) { fvwm_msg(ERR, "executeModule", "too many open fds"); goto err_exit; } /* all ok, create the space and fill up */ module = module_alloc(); MOD_NAME(module) = stripcpy(cptr); free(cptr); sprintf(arg2, "%d", app_to_fvwm[1]); sprintf(arg3, "%d", fvwm_to_app[0]); sprintf(arg5, "%lx", (unsigned long)win); sprintf(arg6, "%lx", (unsigned long)exc->w.wcontext); args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = (char *)get_current_read_file(); if (!args[3]) { args[3] = "none"; } args[4] = arg5; args[5] = arg6; for (nargs = 6; action = GetNextToken(action, &token), token; nargs++) { args = (char **)saferealloc( (void *)args, (nargs + 2) * sizeof(char *)); args[nargs] = token; if (MOD_ALIAS(module) == NULL) { const char *ptr = skipModuleAliasToken(args[nargs]); if (ptr && *ptr == '\0') { MOD_ALIAS(module) = stripcpy(args[nargs]); } } } args[nargs] = NULL; /* Try vfork instead of fork. The man page says that vfork is better! */ /* Also, had to change exit to _exit() */ /* Not everyone has vfork! */ val = fork(); if (val > 0) { /* This fork remains running fvwm */ /* close appropriate descriptors from each pipe so * that fvwm will be able to tell when the app dies */ close(app_to_fvwm[1]); /* dont't care that this may be -1 */ close(fvwm_to_app[0]); /* add these pipes to fvwm's active pipe list */ MOD_WRITEFD(module) = fvwm_to_app[1]; MOD_READFD(module) = app_to_fvwm[0]; msg_mask_set( &MOD_PIPEMASK(module), DEFAULT_MASK, DEFAULT_MASK); free(arg1); if (DoingCommandLine) { /* add to the list of command line modules */ DBUG("executeModule", "starting commandline module\n"); MOD_SET_CMDLINE(module, 1); } /* make the PositiveWrite pipe non-blocking. Don't want to jam * up fvwm because of an uncooperative module */ if (MOD_WRITEFD(module) >= 0) { fcntl(MOD_WRITEFD(module), F_SETFL, O_NONBLOCK); } /* Mark the pipes close-on exec so other programs * won`t inherit them */ if (fcntl(MOD_READFD(module), F_SETFD, 1) == -1) { fvwm_msg( ERR, "executeModule", "module close-on-exec failed"); } if ( MOD_WRITEFD(module) >= 0 && fcntl(MOD_WRITEFD(module), F_SETFD, 1) == -1) { fvwm_msg( ERR, "executeModule", "module close-on-exec failed"); } /* module struct is completed, insert into the list */ module_list_insert(module, &module_list); for (i = 6; i < nargs; i++) { if (args[i] != 0) { free(args[i]); } } } else if (val ==0) { /* this is the child */ /* this fork execs the module */ #ifdef FORK_CREATES_CHILD /* dont't care that this may be -1 */ close(fvwm_to_app[1]); close(app_to_fvwm[0]); #endif fvmm_deinstall_signals(); if (!Pdefault) { char visualid[32]; char colormap[32]; sprintf( visualid, "FVWM_VISUALID=%lx", XVisualIDFromVisual(Pvisual)); flib_putenv("FVWM_VISUALID", visualid); sprintf(colormap, "FVWM_COLORMAP=%lx", Pcmap); flib_putenv("FVWM_COLORMAP", colormap); } else { flib_unsetenv("FVWM_VISUALID"); flib_unsetenv("FVWM_COLORMAP"); } /* Why is this execvp?? We've already searched the module * path! */ execvp(arg1,args); fvwm_msg( ERR, "executeModule", "Execution of module failed: %s", arg1); perror(""); close(app_to_fvwm[1]); /* dont't care that this may be -1 */ close(fvwm_to_app[0]); #ifdef FORK_CREATES_CHILD exit(1); #endif } else { fvwm_msg(ERR, "executeModule", "Fork failed"); free(arg1); for (i = 6; i < nargs; i++) { if (args[i] != 0) { free(args[i]); } } free(args); module_free(module); return NULL; } free(args); return module; err_exit: if (arg1 != NULL) { free(arg1); } if (cptr != NULL) { free(cptr); } if (args != NULL) { free(args); } /* dont't care that these may be -1 */ close(fvwm_to_app[0]); close(fvwm_to_app[1]); close(app_to_fvwm[0]); close(app_to_fvwm[1]); return NULL; } fmodule *executeModuleDesperate(F_CMD_ARGS) { fmodule *m; m = do_execute_module(F_PASS_ARGS, True, False); return m; } void module_kill(fmodule *module) { module_list_insert( module_list_remove(module, &module_list), &death_row); return; } /* free modules in the deathrow */ void module_cleanup(void) { module_list_destroy(&death_row); return; } /* void module_send(fmodule *module, unsigned long *ptr, int size) */ /* This used to be marked "fvwm_inline". I removed this when I added the lockonsend logic. The routine seems too big to want to inline. dje 9/4/98 */ extern int myxgrabcount; /* defined in libs/Grab.c */ extern char *ModuleUnlock; /* defined in libs/Module.c */ void PositiveWrite(fmodule *module, unsigned long *ptr, int size) { extern int moduleTimeout; msg_masks_t mask; if (ptr == NULL) { return; } if (MOD_WRITEFD(module) == -1) { return; } if (!IS_MESSAGE_IN_MASK(&(MOD_PIPEMASK(module)), ptr[1])) { return; } /* a dirty hack to prevent FvwmAnimate triggering during Recapture */ /* would be better to send RecaptureStart and RecaptureEnd messages. */ /* If module is lock on send for iconify message and it's an * iconify event and server grabbed, then return */ mask.m1 = (MOD_NOGRABMASK(module).m1 & MOD_SYNCMASK(module).m1); mask.m2 = (MOD_NOGRABMASK(module).m2 & MOD_SYNCMASK(module).m2); if (IS_MESSAGE_IN_MASK(&mask, ptr[1]) && myxgrabcount != 0) { return; } /* DV: This was once the AddToMessageQueue function. Since it was only * called once, put it in here for better performance. */ { mqueue_object_type *c; c = (mqueue_object_type *)malloc( sizeof(mqueue_object_type) + size); if (c == NULL) { fvwm_msg(ERR, "PositiveWrite", "malloc failed\n"); exit(1); } c->size = size; c->done = 0; c->data = (unsigned long *)(c + 1); memcpy((void*)c->data, (const void*)ptr, size); fqueue_add_at_end(&(MOD_PIPEQUEUE(module)), c); } /* dje, from afterstep, for FvwmAnimate, allows modules to sync with * fvwm. this is disabled when the server is grabbed, otherwise * deadlocks happen. M_LOCKONSEND has been replaced by a separated * mask which defines on which messages the fvwm-to-module * communication need to be lock on send. olicha Nov 13, 1999 */ /* migo (19-Aug-2000): removed !myxgrabcount to sync M_DESTROY_WINDOW */ /* dv (06-Jul-2002): added the !myxgrabcount again. Deadlocks *do* * happen without it. There must be another way to fix * M_DESTROY_WINDOW handling in FvwmEvent. */ /*if (IS_MESSAGE_IN_MASK(&(MOD_SYNCMASK(module)), ptr[1]))*/ if ( IS_MESSAGE_IN_MASK( &(MOD_SYNCMASK(module)), ptr[1]) && !myxgrabcount) { fd_set readSet; int channel = MOD_READFD(module); struct timeval timeout; Bool done = False; fmodule_input *input; FlushMessageQueue(module); while (!done) { int rc = 0; /* * We give the read a long timeout; if the module * fails to respond within this time then it deserves * to be KILLED! * * NOTE: rather than impose an arbitrary timeout on the * user, we will make this a configuration parameter. */ do { timeout.tv_sec = moduleTimeout; timeout.tv_usec = 0; FD_ZERO(&readSet); FD_SET(channel, &readSet); /* Wait for input to arrive on just one * descriptor, with a timeout (fvwmSelect <= 0) * or read() returning wrong size is bad news */ rc = fvwmSelect( channel + 1, &readSet, NULL, NULL, &timeout); /* retry if select() failed with EINTR */ } while (rc < 0 && !isTerminated && (errno == EINTR)); if ( isTerminated ) { break; } if (rc > 0) { input = module_receive(module); if ( input == NULL || module_input_expect(input, ModuleUnlockResponse)) { module_input_discard(input); done = True; } else { module_input_execute(input); } } else { char *name; name = get_pipe_name(module); /* Doh! Something has gone wrong - get rid of * the offender! */ fvwm_msg(ERR, "PositiveWrite", "Failed to read descriptor from" " '%s':\n" "- data available=%c\n" "- terminate signal=%c\n", name, (FD_ISSET(channel, &readSet) ? 'Y' : 'N'), isTerminated ? 'Y' : 'N'); module_kill(module); break; } /* Execute all messages from the module until UNLOCK is * received N.B. This may cause recursion if a command * results in a sync message to another module, which * in turn may send a command that results in another * sync message to this module. * Hippo: I don't think this will cause deadlocks, but * the third time we get here the first times UNLOCK * will be read and then on returning up the third * level UNLOCK will be read at the first level. This * could be difficult to fix without turning queueing * on. Turning queueing on may be bad because it can * be useful for modules to be able to inject commands * from modules in a synchronous manner. e.g. * FvwmIconMan can tell FvwmAnimate to do an animation * when a window is de-iconified from the IconMan, * queueing make s this happen too late. */ } } return; } fmodule_input *module_receive(fmodule *module) { unsigned long size; unsigned long cont; Window win; int n; fmodule_input *input = NULL; n = read(MOD_READFD(module), &win, sizeof(Window)); if (n < sizeof(Window)) { /* exit silently, module should have died.. */ goto err; } n = read(MOD_READFD(module), &size, sizeof(size)); if (n < sizeof(size)) { fvwm_msg( ERR, "module_receive", "Fail to read command size (Module: %p, read: %i, " "size: %i)", module, n, (int)sizeof(size)); goto err; } if (size > MAX_MODULE_INPUT_TEXT_LEN) { fvwm_msg(ERR, "module_receive", "Module(%p) command is too big (%ld), limit is %d", module, size, MAX_MODULE_INPUT_TEXT_LEN); /* The rest of the output from this module is going to be * scrambled so let's kill it rather than risk interpreting * garbage */ goto err; } /* allocate all storage at once */ /* also save space for the '\0' termination character */ input = (fmodule_input *)safemalloc( sizeof(fmodule_input) + sizeof(char)*(size + 1)); input->module = module; input->window = win; input->command = (char*)input + sizeof(fmodule_input); n = read(MOD_READFD(module), input->command, size); if (n < size) { fvwm_msg( ERR, "module_receive", "Fail to read command (Module: %p, read: %i, size:" " %ld)", module, n, size); goto err; } input->command[n] = '\0'; n = read(MOD_READFD(module), &cont, sizeof(cont)); if (n < sizeof(cont)) { fvwm_msg(ERR, "module_receive", "Module %p, Size Problems (read: %d, size: %d)", module, n, (int)sizeof(cont)); goto err; } if (cont == 0) { /* this is documented as a valid way for a module to quit * so let's not complain */ module_kill(module); } return input; err: module_kill(module); module_input_discard(input); return NULL; } /* frees the module input data struct */ void module_input_discard(fmodule_input *input) { if (input==NULL) { return; } free(input); } /* returns true if the module command matches "expect", false otherwise */ Bool module_input_expect(fmodule_input *input, char *expect) { if (input == NULL || input->command == NULL || expect == NULL) { return False; } if (strncasecmp(input->command, expect, strlen(expect)) == 0) { /* the module sent the expected string */ return True; } return False; } void module_list_itr_init(fmodule_list_itr *itr) { *itr = module_list; return; } fmodule *module_list_itr_next(fmodule_list_itr *itr) { fmodule *module; if (*itr == NULL) { return NULL; } module = (*itr)->module; *itr = (*itr)->next; return module; } static void KillModuleByName(char *name, char *alias) { fmodule_list_itr moditr; fmodule *module; if (name == NULL) { return; } module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { if ( MOD_NAME(module) != NULL && matchWildcards(name, MOD_NAME(module)) && (!alias || ( MOD_ALIAS(module) && matchWildcards(alias, MOD_ALIAS(module))))) { module_kill(module); } } return; } static char *get_pipe_name(fmodule *module) { char *name=""; if (MOD_NAME(module) != NULL) { if (MOD_ALIAS(module) != NULL) { name = CatString3( MOD_NAME(module), " ", MOD_ALIAS(module)); } else { name = MOD_NAME(module); } } else { name = CatString3("(null)", "", ""); } return name; } /* * returns a pointer inside a string (just after the alias) if ok or NULL */ char *skipModuleAliasToken(const char *string) { #define is_valid_first_alias_char(ch) (isalpha(ch) || (ch) == '/') #define is_valid_alias_char(ch) (is_valid_first_alias_char(ch) \ || isalnum(ch) || (ch) == '-' || \ (ch) == '.' || (ch) == '/') if (is_valid_first_alias_char(*string)) { int len = 1; string++; while (*string && is_valid_alias_char(*string)) { if (++len > MAX_MODULE_ALIAS_LEN) { return NULL; } string++; } return (char *)string; } return NULL; #undef is_valid_first_alias_char #undef is_valid_alias_char } /* message mask handling - does this belong here? */ static inline void msg_mask_set( msg_masks_t *msg_mask, unsigned long m1, unsigned long m2) { msg_mask->m1 = m1; msg_mask->m2 = m2; return; } /* * Sets the mask to the specific value. If M_EXTENDED_MSG is set in mask, the * function operates only on the extended messages, otherwise it operates only * on normal messages. */ static void set_message_mask(msg_masks_t *mask, unsigned long msg) { if (msg & M_EXTENDED_MSG) { mask->m2 = (msg & ~M_EXTENDED_MSG); } else { mask->m1 = msg; } return; } /* message queues */ static void DeleteMessageQueueBuff(fmodule *module) { mqueue_object_type *obj; if (fqueue_get_first(&(MOD_PIPEQUEUE(module)), (void **)&obj) == 1) { /* remove from queue */ fqueue_remove_or_operate_from_front( &(MOD_PIPEQUEUE(module)), NULL, NULL, NULL, NULL); /* we don't need to free the obj->data here because it's in the * same malloced block as the obj itself. */ free(obj); } return; } void FlushMessageQueue(fmodule *module) { extern int moduleTimeout; mqueue_object_type *obj; char *dptr; int a; if (module == NULL) { return; } while (fqueue_get_first(&(MOD_PIPEQUEUE(module)), (void **)&obj) == 1) { dptr = (char *)obj->data; while (obj->done < obj->size) { a = write(MOD_WRITEFD(module), &dptr[obj->done], obj->size - obj->done); if (a >=0) { obj->done += a; } /* the write returns EWOULDBLOCK or EAGAIN if the pipe * is full. (This is non-blocking I/O). SunOS returns * EWOULDBLOCK, OSF/1 returns EAGAIN under these * conditions. Hopefully other OSes return one of these * values too. Solaris 2 doesn't seem to have a man * page for write(2) (!) */ else if (errno == EWOULDBLOCK || errno == EAGAIN) { fd_set writeSet; struct timeval timeout; int channel = MOD_WRITEFD(module); int rc = 0; do { /* Wait until the pipe accepts further * input */ timeout.tv_sec = moduleTimeout; timeout.tv_usec = 0; FD_ZERO(&writeSet); FD_SET(channel, &writeSet); rc = fvwmSelect( channel + 1, NULL, &writeSet, NULL, &timeout); /* retry if select() failed with EINTR */ } while ((rc < 0) && !isTerminated && (errno == EINTR)); if ( isTerminated ) { return; } if (!FD_ISSET(channel, &writeSet)) { char *name; name = get_pipe_name(module); /* Doh! Something has gone wrong - get * rid of the offender! */ fvwm_msg( ERR, "FlushMessageQueue", "Failed to write descriptor to" " '%s':\n" "- select rc=%d\n" "- terminate signal=%c\n", name, rc, isTerminated ? 'Y' : 'N'); module_kill(module); return; } /* pipe accepts further input; continue */ continue; } else if (errno != EINTR) { module_kill(module); return; } } DeleteMessageQueueBuff(module); } return; } void FlushAllMessageQueues(void) { fmodule_list_itr moditr; fmodule *module; module_list_itr_init(&moditr); while ( (module = module_list_itr_next(&moditr)) != NULL) { FlushMessageQueue(module); } return; } /* empty, only here so that the signal handling initialization code is the * same for modules and fvwm */ RETSIGTYPE DeadPipe(int sig) { SIGNAL_RETURN; } void CMD_Module(F_CMD_ARGS) { do_execute_module(F_PASS_ARGS, False, False); return; } void CMD_ModuleListenOnly(F_CMD_ARGS) { do_execute_module(F_PASS_ARGS, False, True); return; } void CMD_KillModule(F_CMD_ARGS) { char *name; char *alias = NULL; action = GetNextToken(action,&name); if (!name) { return; } GetNextToken(action, &alias); KillModuleByName(name, alias); free(name); if (alias) { free(alias); } return; } void CMD_ModuleSynchronous(F_CMD_ARGS) { int sec = 0; char *next; char *token; char *expect = ModuleFinishedStartupResponse; fmodule *module; fd_set in_fdset; fd_set out_fdset; time_t start_time; Bool done = False; Bool need_ungrab = False; char *escape = NULL; XEvent tmpevent; if (!action) { return; } token = PeekToken(action, &next); if (StrEquals(token, "expect")) { token = PeekToken(next, &next); if (token) { expect = alloca(strlen(token) + 1); strcpy(expect, token); } action = next; token = PeekToken(action, &next); } if (token && StrEquals(token, "timeout")) { if (GetIntegerArguments(next, &next, &sec, 1) > 0 && sec > 0) { /* we have a delay, skip the number */ action = next; } else { fvwm_msg(ERR, "executeModuleSync", "illegal timeout"); return; } } if (!action) { /* no module name */ return; } module = do_execute_module(F_PASS_ARGS, False, False); if (module == NULL) { /* executing the module failed, just return */ return; } /* Busy cursor stuff */ if (Scr.BusyCursor & BUSY_MODULESYNCHRONOUS) { if (GrabEm(CRS_WAIT, GRAB_BUSY)) need_ungrab = True; } /* wait for module input */ start_time = time(NULL); while (!done) { struct timeval timeout; int num_fd; /* A signal here could interrupt the select call. We would * then need to restart our select, unless the signal was * a "terminate" signal. Note that we need to reinitialise * all of select's parameters after it has returned. */ do { FD_ZERO(&in_fdset); FD_ZERO(&out_fdset); FD_SET(MOD_READFD(module), &in_fdset); if (!FQUEUE_IS_EMPTY(&MOD_PIPEQUEUE(module))) { FD_SET(MOD_WRITEFD(module), &out_fdset); } timeout.tv_sec = 0; timeout.tv_usec = 1; num_fd = fvwmSelect( fvwmlib_max_fd, &in_fdset, &out_fdset, 0, &timeout); } while (num_fd < 0 && !isTerminated); /* Exit if we have received a "terminate" signal */ if (isTerminated) { break; } if (num_fd > 0) { if (FD_ISSET(MOD_READFD(module), &in_fdset)) { fmodule_input * input; /* Check for module input. */ input = module_receive(module); if ( input == NULL || module_input_expect(input,expect)) { module_input_discard(input); done = True; } else { module_input_execute(input); } } if ((MOD_WRITEFD(module) >= 0) && FD_ISSET(MOD_WRITEFD(module), &out_fdset)) { FlushMessageQueue(module); } } usleep(1000); if (difftime(time(NULL), start_time) >= sec && sec) { /* timeout */ done = True; } /* Check for "escape function" */ if (FPending(dpy) && FCheckMaskEvent(dpy, KeyPressMask, &tmpevent)) { int context; XClassHint *class; char *name; Window w; context = GetContext( NULL, exc->w.fw, &tmpevent, &w); if (exc->w.fw != NULL) { class = &(exc->w.fw->class); name = exc->w.fw->name.name; } else { class = NULL; name = NULL; } escape = CheckBinding( Scr.AllBindings, STROKE_ARG(0) tmpevent.xkey.keycode, tmpevent.xkey.state, GetUnusedModifiers(), context, BIND_KEYPRESS, class, name); if (escape != NULL) { if (!strcasecmp(escape,"escapefunc")) { done = True; } } } } /* while */ if (need_ungrab) { UngrabEm(GRAB_BUSY); } return; } /* mask handling - does this belong here? */ void CMD_set_mask(F_CMD_ARGS) { unsigned long val; if (exc->m.module == NULL) { return; } if (!action || sscanf(action, "%lu", &val) != 1) { val = 0; } set_message_mask(&(MOD_PIPEMASK(exc->m.module)), (unsigned long)val); return; } void CMD_set_sync_mask(F_CMD_ARGS) { unsigned long val; if (exc->m.module == NULL) { return; } if (!action || sscanf(action,"%lu",&val) != 1) { val = 0; } set_message_mask(&(MOD_SYNCMASK(exc->m.module)), (unsigned long)val); return; } void CMD_set_nograb_mask(F_CMD_ARGS) { unsigned long val; if (exc->m.module == NULL) { return; } if (!action || sscanf(action,"%lu",&val) != 1) { val = 0; } set_message_mask(&(MOD_NOGRABMASK(exc->m.module)), (unsigned long)val); return; } fvwm-2.6.7/fvwm/schedule.c0000644000175700017570000001565113001406607012370 00000000000000/* -*-c-*- */ /* 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 #include "libs/fvwmlib.h" #include "libs/queue.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/Parse.h" #include "fvwm.h" #include "externs.h" #include "colorset.h" #include "bindings.h" #include "misc.h" #include "cursor.h" #include "functions.h" #include "commands.h" #include "screen.h" typedef struct { int id; Time time_to_execute; Window window; char *command; int period; /* in milliseconds */ } sq_object_type; static int last_schedule_id = 0; static int next_schedule_id = -1; static fqueue sq = FQUEUE_INIT; static int cmp_times(Time t1, Time t2) { unsigned long ul1 = (unsigned long)t1; unsigned long ul2 = (unsigned long)t2; unsigned long diff; signed long udiff; diff = ul1 - ul2; udiff = *(signed long *)&diff; if (udiff > 0) { return 1; } else if (udiff < 0) { return -1; } else { return 0; } } static int cmp_object_time(void *object1, void *object2, void *args) { sq_object_type *so1 = (sq_object_type *)object1; sq_object_type *so2 = (sq_object_type *)object2; return cmp_times(so1->time_to_execute, so2->time_to_execute); } static int check_deschedule_obj_func(void *object, void *args) { sq_object_type *obj = object; return (obj->id == *(int *)args); } static void destroy_obj_func(void *object) { sq_object_type *obj = object; if (obj->command != NULL) { free(obj->command); } free(obj); return; } static void deschedule(int *pid) { int id; if (FQUEUE_IS_EMPTY(&sq)) { return; } /* get the job group id to deschedule */ if (pid != NULL) { id = *pid; } else { id = last_schedule_id; } /* deschedule matching jobs */ fqueue_remove_or_operate_all( &sq, check_deschedule_obj_func, NULL, destroy_obj_func, (void *)&id); return; } static void schedule( Window window, char *command, Time time_to_execute, int *pid, int period) { sq_object_type *new_obj; if (command == NULL || *command == 0) { return; } /* create the new object */ new_obj = (sq_object_type *)safemalloc(sizeof(sq_object_type)); memset(new_obj, 0, sizeof(sq_object_type)); new_obj->window = window; new_obj->command = safestrdup(command); new_obj->time_to_execute = time_to_execute; new_obj->period = period; /* 0 if this is not a periodic command */ /* set the job group id */ if (pid != NULL) { new_obj->id = *pid; } else { new_obj->id = next_schedule_id; next_schedule_id--; if (next_schedule_id >= 0) { /* wrapped around */ next_schedule_id = -1; } } last_schedule_id = new_obj->id; /* insert into schedule queue */ fqueue_add_inside(&sq, new_obj, cmp_object_time, NULL); return; } static int check_execute_obj_func(void *object, void *args) { sq_object_type *obj = object; Time *ptime = (Time *)args; return (cmp_times(*ptime, obj->time_to_execute) >= 0); } static void execute_obj_func(void *object, void *args) { sq_object_type *obj = object; if (obj->command != NULL) { /* execute the command */ const exec_context_t *exc; exec_context_changes_t ecc; exec_context_change_mask_t mask = ECC_TYPE | ECC_WCONTEXT; ecc.type = EXCT_SCHEDULE; ecc.w.wcontext = C_ROOT; if (XFindContext( dpy, obj->window, FvwmContext, (caddr_t *)&ecc.w.fw) != XCNOENT) { ecc.w.wcontext = C_WINDOW; mask |= ECC_FW; } exc = exc_create_context(&ecc, mask); execute_function(NULL, exc, obj->command, 0); exc_destroy_context(exc); } if (obj->period > 0) { /* This is a periodic function, so reschedule it. */ sq_object_type *new_obj = (sq_object_type *)safemalloc(sizeof(sq_object_type)); memcpy(new_obj, obj, sizeof(sq_object_type)); obj->command = NULL; /* new_obj->command now points to cmd. */ new_obj->time_to_execute = fev_get_evtime() + new_obj->period; /* insert into schedule queue */ fqueue_add_inside(&sq, new_obj, cmp_object_time, NULL); } XFlush(dpy); return; } /* executes all scheduled commands that are due for execution */ void squeue_execute(void) { Time current_time; if (FQUEUE_IS_EMPTY(&sq)) { return; } current_time = get_server_time(); fqueue_remove_or_operate_all( &sq, check_execute_obj_func, execute_obj_func, destroy_obj_func, ¤t_time); return; } /* returns the time in milliseconds to wait before next queue command must be * executed or -1 if none is queued */ int squeue_get_next_ms(void) { int ms; sq_object_type *obj; if (fqueue_get_first(&sq, (void **)&obj) == 0) { return -1; } if (cmp_times(fev_get_evtime(), obj->time_to_execute) >= 0) { /* jobs pending to be executed immediately */ ms = 0; } else { /* execute jobs later */ ms = obj->time_to_execute - fev_get_evtime(); } return ms; } int squeue_get_next_id(void) { return next_schedule_id; } int squeue_get_last_id(void) { return last_schedule_id; } void CMD_Schedule(F_CMD_ARGS) { Window xw; Time time; Time current_time; char *taction; char *token; char *next; int ms; int id; int *pid; int n; FvwmWindow * const fw = exc->w.fw; Bool is_periodic = False; token = PeekToken(action, &next); if (token && strcasecmp(token, "periodic") == 0) { is_periodic = True; action = next; } /* get the time to execute */ n = GetIntegerArguments(action, &action, &ms, 1); if (n <= 0) { fvwm_msg(ERR, "CMD_Schedule", "Requires time to schedule as argument"); return; } if (ms < 0) { ms = 0; } #if 0 /* eats up way too much cpu if schedule is used excessively */ current_time = get_server_time(); #else /* with this version, scheduled commands may be executed earlier than * intended. */ current_time = fev_get_evtime(); #endif time = current_time + (Time)ms; /* get the job group id to schedule */ n = GetIntegerArgumentsAnyBase(action, &taction, &id, 1); if (n >= 1) { pid = &id; action = taction; } else { pid = NULL; } /* get the window to operate on */ if (fw != NULL) { xw = FW_W(fw); } else { xw = None; } /* schedule the job */ schedule(xw, action, time, pid, (is_periodic == True ? ms : 0)); return; } void CMD_Deschedule(F_CMD_ARGS) { int id; int *pid; int n; /* get the job group id to deschedule */ n = GetIntegerArgumentsAnyBase(action, &action, &id, 1); if (n <= 0) { /* none, use default */ pid = NULL; } else { pid = &id; } /* deschedule matching jobs */ deschedule(pid); return; } fvwm-2.6.7/fvwm/update.h0000644000175700017570000000364212773467232012100 00000000000000/* -*-c-*- */ #ifndef _UPDATE_ #define _UPDATE_ /* Ipmortant not: All the flags below must have a positive syntax. If a flag * is set, this indicates that something has to happen with the window. */ typedef struct { unsigned do_broadcast_focus : 1; unsigned do_redecorate : 1; unsigned do_redecorate_transient : 1; unsigned do_redraw_decoration : 1; unsigned do_redraw_icon : 1; unsigned do_refresh : 1; unsigned do_resize_window : 1; unsigned do_setup_focus_policy : 1; unsigned do_setup_frame : 1; unsigned do_update_cr_motion_method : 1; unsigned do_update_ewmh_allowed_actions : 1; unsigned do_update_ewmh_icon : 1; unsigned do_update_ewmh_mini_icon : 1; unsigned do_update_ewmh_stacking_hints : 1; unsigned do_update_ewmh_state_hints : 1; unsigned do_update_frame_attributes : 1; unsigned do_update_icon : 1; unsigned do_update_icon_background_cs : 1; unsigned do_update_icon_boxes : 1; unsigned do_update_icon_font : 1; unsigned do_update_icon_placement : 1; unsigned do_update_icon_size_limits : 1; unsigned do_update_icon_title : 1; unsigned do_update_icon_title_cs : 1; unsigned do_update_icon_title_cs_hi : 1; unsigned do_update_mini_icon : 1; unsigned do_update_layer : 1; unsigned do_update_modules_flags : 1; unsigned do_update_placement_penalty : 1; unsigned do_update_rotated_title : 1; unsigned do_update_stick : 1; unsigned do_update_stick_icon : 1; unsigned do_update_title_dir : 1; unsigned do_update_title_text_dir : 1; unsigned do_update_visible_icon_name : 1; unsigned do_update_visible_window_name : 1; unsigned do_update_window_color : 1; unsigned do_update_window_color_hi : 1; unsigned do_update_window_font : 1; unsigned do_update_window_font_height : 1; unsigned do_update_window_grabs : 1; unsigned do_update_working_area : 1; } update_win; void destroy_scheduled_windows(void); void apply_decor_change(FvwmWindow *fw); void flush_window_updates(void); #endif /* _UPDATE_ */ fvwm-2.6.7/fvwm/misc.c0000644000175700017570000003254212773467232011545 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "libs/ftime.h" #ifdef FVWM_DEBUG_TIME #include #endif #include "libs/Parse.h" #include "libs/Target.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "cursor.h" #include "misc.h" #include "screen.h" #include "module_interface.h" #include "events.h" #include "eventmask.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ #define GRAB_EVMASK (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | \ PointerMotionMask | EnterWindowMask | LeaveWindowMask) /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static int grab_count[GRAB_MAXVAL] = { 1, 1, 0, 0, 0, 0, 0 }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* * Change the appearance of the grabbed cursor. */ static void change_grab_cursor(int cursor) { if (cursor != None) { XChangeActivePointerGrab( dpy, GRAB_EVMASK, Scr.FvwmCursors[cursor], CurrentTime); } return; } /* ---------------------------- interface functions ------------------------ */ int GetTwoArguments( char *action, int *val1, int *val2, int *val1_unit, int *val2_unit) { *val1_unit = Scr.MyDisplayWidth; *val2_unit = Scr.MyDisplayHeight; return GetTwoPercentArguments(action, val1, val2, val1_unit, val2_unit); } /* * Grab the pointer. * grab_context: GRAB_NORMAL, GRAB_BUSY, GRAB_MENU, GRAB_BUSYMENU, * GRAB_PASSIVE. * GRAB_STARTUP and GRAB_NONE are used at startup but are not made * to be grab_context. * GRAB_PASSIVE does not actually grab, but only delays the following ungrab * until the GRAB_PASSIVE is released too. */ #define DEBUG_GRAB 0 #if DEBUG_GRAB void print_grab_stats(char *text) { int i; fprintf(stderr,"grab_stats (%s):", text); for (i = 0; i < GRAB_MAXVAL; i++) { fprintf(stderr," %d", grab_count[i]); } fprintf(stderr," \n"); return; } #endif Bool GrabEm(int cursor, int grab_context) { int i = 0; int val = 0; int rep; Window grab_win; extern Window PressedW; if (grab_context <= GRAB_STARTUP || grab_context >= GRAB_MAXVAL) { fvwm_msg( ERR, "GrabEm", "Bug: Called with illegal context %d", grab_context); return False; } if (grab_context == GRAB_PASSIVE) { grab_count[grab_context]++; grab_count[GRAB_ALL]++; return True; } if (grab_count[GRAB_ALL] > grab_count[GRAB_PASSIVE]) { /* already grabbed, just change the grab cursor */ if (grab_context == GRAB_FREEZE_CURSOR) { if (XGrabPointer( dpy, (PressedW != None) ? PressedW : Scr.NoFocusWin, True, GRAB_EVMASK, GrabModeAsync, GrabModeAsync, None, Scr.FvwmCursors[CRS_DEFAULT], CurrentTime) != GrabSuccess) { return False; } return True; } grab_count[grab_context]++; grab_count[GRAB_ALL]++; if (grab_context != GRAB_BUSY || grab_count[GRAB_STARTUP] == 0) { change_grab_cursor(cursor); } return True; } /* move the keyboard focus prior to grabbing the pointer to * eliminate the enterNotify and exitNotify events that go * to the windows. But GRAB_BUSY. */ switch (grab_context) { case GRAB_BUSY: if ( Scr.Hilite != NULL ) { grab_win = FW_W(Scr.Hilite); } else { grab_win = Scr.Root; } /* retry to grab the busy cursor only once */ rep = 2; break; case GRAB_PASSIVE: /* cannot happen */ return False; case GRAB_FREEZE_CURSOR: grab_win = (PressedW != None) ? PressedW : Scr.NoFocusWin; rep = 2; break; default: grab_win = Scr.Root; rep = NUMBER_OF_GRAB_ATTEMPTS; break; } XFlush(dpy); while (i < rep && (val = XGrabPointer( dpy, grab_win, True, GRAB_EVMASK, GrabModeAsync, GrabModeAsync, None, (grab_context == GRAB_FREEZE_CURSOR) ? None : Scr.FvwmCursors[cursor], CurrentTime) != GrabSuccess)) { switch (val) { case GrabInvalidTime: case GrabNotViewable: /* give up */ i += rep; break; case GrabSuccess: break; case AlreadyGrabbed: case GrabFrozen: default: /* If you go too fast, other windows may not get a * chance to release any grab that they have. */ i++; if (grab_context == GRAB_FREEZE_CURSOR) { break; } if (i < rep) { usleep(1000 * TIME_BETWEEN_GRAB_ATTEMPTS); } break; } } XFlush(dpy); /* If we fall out of the loop without grabbing the pointer, its * time to give up */ if (val != GrabSuccess) { return False; } grab_count[grab_context]++; grab_count[GRAB_ALL]++; #if DEBUG_GRAB print_grab_stats("grabbed"); #endif return True; } /* * * UnGrab the pointer * */ Bool UngrabEm(int ungrab_context) { if (ungrab_context <= GRAB_ALL || ungrab_context >= GRAB_MAXVAL) { fvwm_msg( ERR, "UngrabEm", "Bug: Called with illegal context %d", ungrab_context); return False; } if (grab_count[ungrab_context] == 0 || grab_count[GRAB_ALL] == 0) { /* context is not grabbed */ return False; } XFlush(dpy); grab_count[ungrab_context]--; grab_count[GRAB_ALL]--; if (grab_count[GRAB_ALL] > 0) { int new_cursor = None; /* there are still grabs left - switch grab cursor */ switch (ungrab_context) { case GRAB_NORMAL: case GRAB_BUSY: case GRAB_MENU: if (grab_count[GRAB_BUSYMENU] > 0) { new_cursor = CRS_WAIT; } else if (grab_count[GRAB_BUSY] > 0) { new_cursor = CRS_WAIT; } else if (grab_count[GRAB_MENU] > 0) { new_cursor = CRS_MENU; } else { new_cursor = None; } break; case GRAB_BUSYMENU: /* switch back from busymenu cursor to normal menu * cursor */ new_cursor = CRS_MENU; break; default: new_cursor = None; break; } if (grab_count[GRAB_ALL] > grab_count[GRAB_PASSIVE]) { #if DEBUG_GRAB print_grab_stats("-restore"); #endif change_grab_cursor(new_cursor); } } else { #if DEBUG_GRAB print_grab_stats("-ungrab"); #endif XUngrabPointer(dpy, CurrentTime); } XFlush(dpy); return True; } #ifndef fvwm_msg /* Some ports (i.e. VMS) define their own version */ /* ** fvwm_msg: used to send output from fvwm to files and or stderr/stdout ** ** type -> DBG == Debug, ERR == Error, INFO == Information, WARN == Warning, ** OLD == Command or option deprecated ** id -> name of function, or other identifier */ static char *fvwm_msg_strings[] = { "<> ", "", "", "<> ", "<> ", "<> " }; void fvwm_msg(fvwm_msg_t type, char *id, char *msg, ...) { va_list args; char *mfmt; char fvwm_id[20]; char time_str[40] = "\0"; #ifdef FVWM_DEBUG_TIME clock_t time_val, time_taken; static clock_t start_time = 0; static clock_t prev_time = 0; struct tms not_used_tms; time_t mytime; struct tm *t_ptr; #endif #ifdef FVWM_DEBUG_TIME time(&mytime); t_ptr = localtime(&mytime); if (start_time == 0) { /* get clock ticks */ prev_time = start_time = (unsigned int)times(¬_used_tms); } time_val = (unsigned int)times(¬_used_tms); /* get clock ticks */ time_taken = time_val - prev_time; prev_time = time_val; sprintf(time_str, "%.2d:%.2d:%.2d%7ld ", t_ptr->tm_hour, t_ptr->tm_min, t_ptr->tm_sec, time_taken); #endif strcpy(fvwm_id, "fvwm"); if (Scr.NumberOfScreens > 1) { sprintf(&fvwm_id[strlen(fvwm_id)], ".%d", (int)Scr.screen); } if (type == ERR) { /* I hate to use a fixed length but this will do for now */ char tmp[2 * MAX_TOKEN_LENGTH]; sprintf(tmp, "[%s][%s]: %s", fvwm_id, id, fvwm_msg_strings[(int)type]); va_start(args, msg); vsprintf(tmp + strlen(tmp), msg, args); va_end(args); tmp[strlen(tmp) + 1] = '\0'; tmp[strlen(tmp)] = '\n'; if (strlen(tmp) >= MAX_MODULE_INPUT_TEXT_LEN) { sprintf(tmp + MAX_MODULE_INPUT_TEXT_LEN - 5, "...\n"); } fprintf(stderr, "%s", tmp); BroadcastName(M_ERROR, 0, 0, 0, tmp); } else { fprintf(stderr, "%s[%s][%s]: %s", time_str, fvwm_id, id, fvwm_msg_strings[(int)type]); va_start(args, msg); { int n; n = asprintf(&mfmt, "%s\n", msg); (void)n; } vfprintf(stderr, mfmt, args); va_end(args); free(mfmt); } } /* fvwm_msg */ #endif void fvwm_msg_report_app(void) { fprintf( stderr, " If you are having a problem with the application, send a" " bug report\n" " with this message included to the application owner.\n" " There is no need to notify fvwm-workers@fvwm.org.\n"); return; } void fvwm_msg_report_app_and_workers(void) { fprintf( stderr, " If you are having a problem with the application, send" " a bug report with\n" " this message included to the application owner and" " notify\n" " fvwm-workers@fvwm.org.\n"); return; } /* Store the last item that was added with '+' */ void set_last_added_item(last_added_item_t type, void *item) { Scr.last_added_item.type = type; Scr.last_added_item.item = item; return; } /* some fancy font handling stuff */ void NewFontAndColor(FlocaleFont *flf, Pixel color, Pixel backcolor) { Globalgcm = GCForeground | GCBackground; if (flf->font) { Globalgcm |= GCFont; Globalgcv.font = flf->font->fid; } Globalgcv.foreground = color; Globalgcv.background = backcolor; XChangeGC(dpy,Scr.TitleGC,Globalgcm,&Globalgcv); return; } /* * * For menus, move, and resize operations, we can effect keyboard * shortcuts by warping the pointer. * */ void Keyboard_shortcuts( XEvent *ev, FvwmWindow *fw, int *x_defect, int *y_defect, int ReturnEvent) { int x_move_size = 0; int y_move_size = 0; if (fw) { x_move_size = fw->hints.width_inc; y_move_size = fw->hints.height_inc; } fvwmlib_keyboard_shortcuts( dpy, Scr.screen, ev, x_move_size, y_move_size, x_defect, y_defect, ReturnEvent); return; } /* * * Check if the given FvwmWindow structure still points to a valid window. * */ Bool check_if_fvwm_window_exists(FvwmWindow *fw) { FvwmWindow *t; for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (t == fw) return True; } return False; } /* rounds x down to the next multiple of m */ int truncate_to_multiple (int x, int m) { return (x < 0) ? (m * (((x + 1) / m) - 1)) : (m * (x / m)); } Bool IsRectangleOnThisPage(const rectangle *rec, int desk) { return (desk == Scr.CurrentDesk && rec->x + (signed int)rec->width > 0 && (rec->x < 0 || rec->x < Scr.MyDisplayWidth) && rec->y + (signed int)rec->height > 0 && (rec->y < 0 || rec->y < Scr.MyDisplayHeight)) ? True : False; } /* returns the FvwmWindow that contains the pointer or NULL if none */ FvwmWindow *get_pointer_fvwm_window(void) { int x,y; Window win; Window ancestor; FvwmWindow *t; if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &win, &JunkX, &JunkY, &x, &y, &JunkMask) == False) { /* pointer is on a different screen */ return NULL; } for (t = NULL ; win != Scr.Root && win != None; win = ancestor) { Window root = None; Window *children; unsigned int nchildren; if (XFindContext(dpy, win, FvwmContext, (caddr_t *) &t) != XCNOENT) { /* found a matching window context */ return t; } /* get next higher ancestor window */ children = NULL; if (!XQueryTree( dpy, win, &root, &ancestor, &children, &nchildren)) { return NULL; } if (children) { XFree(children); } } return t; } /* Returns the current X server time */ Time get_server_time(void) { XEvent xev; XSetWindowAttributes attr; /* add PropChange to NoFocusWin events */ attr.event_mask = PropertyChangeMask; XChangeWindowAttributes (dpy, Scr.NoFocusWin, CWEventMask, &attr); /* provoke an event */ XChangeProperty( dpy, Scr.NoFocusWin, XA_WM_CLASS, XA_STRING, 8, PropModeAppend, NULL, 0); FWindowEvent(dpy, Scr.NoFocusWin, PropertyChangeMask, &xev); attr.event_mask = XEVMASK_NOFOCUSW; XChangeWindowAttributes(dpy, Scr.NoFocusWin, CWEventMask, &attr); return xev.xproperty.time; } void print_g(char *text, rectangle *g) { fprintf(stderr,"%s: ", (text != NULL) ? text : ""); if (g == NULL) { fprintf(stderr, "(null)\n"); return; } fprintf(stderr,"%4d %4d %4dx%4d (%4d - %4d, %4d - %4d)\n", g->x, g->y, g->width, g->height, g->x, g->x + g->width, g->y, g->y + g->height); return; } fvwm-2.6.7/fvwm/virtual.c0000644000175700017570000014776113001406607012272 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/FGettext.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "cursor.h" #include "events.h" #include "eventmask.h" #include "misc.h" #include "screen.h" #include "virtual.h" #include "module_interface.h" #include "module_list.h" #include "focus.h" #include "ewmh.h" #include "move_resize.h" #include "borders.h" #include "frame.h" #include "geometry.h" #include "icons.h" #include "stack.h" #include "functions.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* * dje 12/19/98 * * Testing with edge_thickness of 1 showed that some XServers don't * care for 1 pixel windows, causing EdgeScrolling not to work with some * servers. One bug report was for SUNOS 4.1.3_U1. We didn't find out * the exact cause of the problem. Perhaps no enter/leave events were * generated. * * Allowed: 0,1,or 2 pixel pan frames. * * 0 completely disables mouse edge scrolling, even while dragging a * window. * * 1 gives the smallest pan frames, which seem to work best except on * some servers. * * 2 is the default. */ static int edge_thickness = 2; static int last_edge_thickness = 2; static int prev_page_x = 0; static int prev_page_y = 0; static int prev_desk = 0; static int prev_desk_and_page_desk = 0; static int prev_desk_and_page_page_x = 0; static int prev_desk_and_page_page_y = 0; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static Bool _pred_button_event(Display *display, XEvent *event, XPointer arg) { return (event->type == ButtonPress || event->type == ButtonRelease) ? True : False; } static void __drag_viewport(const exec_context_t *exc, int scroll_speed) { XEvent e; int x; int y; unsigned int button_mask = 0; Bool is_finished = False; if (!GrabEm(CRS_MOVE, GRAB_NORMAL)) { XBell(dpy, 0); return; } if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &button_mask) == False) { /* pointer is on a different screen */ /* Is this the best thing to do? */ UngrabEm(GRAB_NORMAL); return; } MyXGrabKeyboard(dpy); button_mask &= DEFAULT_ALL_BUTTONS_MASK; memset(&e, 0, sizeof(e)); while (!is_finished) { int old_x; int old_y; old_x = x; old_y = y; FMaskEvent( dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | ButtonMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask, &e); /* discard extra events before a logical release */ if (e.type == MotionNotify || e.type == EnterNotify || e.type == LeaveNotify) { while (FPending(dpy) > 0 && FCheckMaskEvent( dpy, ButtonMotionMask | PointerMotionMask | ButtonPressMask | ButtonRelease | KeyPressMask | EnterWindowMask | LeaveWindowMask, &e)) { if (e.type == ButtonPress || e.type == ButtonRelease || e.type == KeyPress) { break; } } } if (e.type == EnterNotify || e.type == LeaveNotify) { XEvent e2; int px; int py; /* Query the pointer to catch the latest information. * This *is* necessary. */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &px, &py, &JunkX, &JunkY, &JunkMask) == True) { fev_make_null_event(&e2, dpy); e2.type = MotionNotify; e2.xmotion.time = fev_get_evtime(); e2.xmotion.x_root = px; e2.xmotion.y_root = py; e2.xmotion.state = JunkMask; e2.xmotion.same_screen = True; e = e2; fev_fake_event(&e); } else { /* pointer is on a different screen, * ignore event */ } } /* Handle a limited number of key press events to allow * mouseless operation */ if (e.type == KeyPress) { Keyboard_shortcuts( &e, NULL, NULL, NULL, ButtonRelease); } switch (e.type) { case KeyPress: /* simple code to bag out of move - CKH */ if (XLookupKeysym(&(e.xkey), 0) == XK_Escape) { is_finished = True; } break; case ButtonPress: if (e.xbutton.button <= NUMBER_OF_MOUSE_BUTTONS && ((Button1Mask << (e.xbutton.button - 1)) & button_mask)) { /* No new button was pressed, just a delayed * event */ break; } /* fall through */ case ButtonRelease: x = e.xbutton.x_root; y = e.xbutton.y_root; is_finished = True; break; case MotionNotify: if (e.xmotion.same_screen == False) { continue; } x = e.xmotion.x_root; y = e.xmotion.y_root; break; case Expose: dispatch_event(&e); break; default: /* cannot happen */ break; } /* switch */ if (x != old_x || y != old_y) { MoveViewport( Scr.Vx + scroll_speed * (x - old_x), Scr.Vy + scroll_speed * (y - old_y), False); FlushAllMessageQueues(); } } /* while*/ UngrabEm(GRAB_NORMAL); MyXUngrabKeyboard(dpy); WaitForButtonsUp(True); } /* * * Parse arguments for "Desk" and "MoveToDesk" (formerly "WindowsDesk"): * * (nil) : desk number = current desk * n : desk number = current desk + n * 0 n : desk number = n * n x : desk number = current desk + n * 0 n min max : desk number = n, but limit to min/max * n min max : desk number = current desk + n, but wrap around at desk #min * or desk #max * n x min max : desk number = current desk + n, but wrap around at desk #min * or desk #max * * The current desk number is returned if not enough parameters could be * read (or if action is empty). * */ static int GetDeskNumber(char *action, int current_desk) { int n; int m; int is_relative; int desk; int val[4]; int min, max; if (MatchToken(action, "prev")) { return prev_desk; } n = GetIntegerArguments(action, NULL, &(val[0]), 4); if (n <= 0) { return Scr.CurrentDesk; } if (n == 1) { return current_desk + val[0]; } desk = current_desk; m = 0; if (val[0] == 0) { /* absolute desk number */ desk = val[1]; is_relative = 0; } else { /* relative desk number */ desk += val[0]; is_relative = 1; } if (n == 3) { m = 1; } if (n == 4) { m = 2; } if (n > 2) { /* handle limits */ if (val[m] <= val[m+1]) { min = val[m]; max = val[m+1]; } else { /* min > max is nonsense, so swap 'em. */ min = val[m+1]; max = val[m]; } if (is_relative) { /* Relative moves wrap around. */ if (desk < min) { desk += (max - min + 1); } else if (desk > max) { desk -= (max - min + 1); } } else if (desk < min) { /* Relative move outside of range, wrap around. */ if (val[0] < 0) { desk = max; } else { desk = min; } } else if (desk > max) { /* Move outside of range, truncate. */ if (val[0] > 0) { desk = min; } else { desk = max; } } } return desk; } /* * * Unmaps a window on transition to a new desktop * */ static void unmap_window(FvwmWindow *t) { XWindowAttributes winattrs; unsigned long eventMask = 0; Status ret; /* * Prevent the receipt of an UnmapNotify, since that would * cause a transition to the Withdrawn state. */ ret = XGetWindowAttributes(dpy, FW_W(t), &winattrs); if (ret) { eventMask = winattrs.your_event_mask; /* suppress UnmapRequest event */ XSelectInput(dpy, FW_W(t), eventMask & ~StructureNotifyMask); } if (IS_ICONIFIED(t)) { if (FW_W_ICON_PIXMAP(t) != None) { XUnmapWindow(dpy,FW_W_ICON_PIXMAP(t)); } if (FW_W_ICON_TITLE(t) != None) { XUnmapWindow(dpy,FW_W_ICON_TITLE(t)); } } else { XUnmapWindow(dpy,FW_W_FRAME(t)); border_undraw_decorations(t); #ifdef ICCCM2_UNMAP_WINDOW_PATCH /* this is required by the ICCCM2 */ XUnmapWindow(dpy, FW_W(t)); #endif if (!Scr.bo.do_enable_ewmh_iconic_state_workaround) { SetMapStateProp(t, IconicState); } } if (ret) { XSelectInput(dpy, FW_W(t), eventMask); XFlush(dpy); } return; } /* * * Maps a window on transition to a new desktop * */ static void map_window(FvwmWindow *t) { XWindowAttributes winattrs; unsigned long eventMask = 0; Status ret; if (IS_SCHEDULED_FOR_DESTROY(t)) { return; } /* * Prevent the receipt of an UnmapNotify, since that would * cause a transition to the Withdrawn state. */ ret = XGetWindowAttributes(dpy, FW_W(t), &winattrs); if (ret) { eventMask = winattrs.your_event_mask; /* suppress MapRequest event */ XSelectInput(dpy, FW_W(t), eventMask & ~StructureNotifyMask); } if (IS_ICONIFIED(t)) { if (FW_W_ICON_PIXMAP(t) != None) { XMapWindow(dpy,FW_W_ICON_PIXMAP(t)); } if (FW_W_ICON_TITLE(t) != None) { XMapWindow(dpy,FW_W_ICON_TITLE(t)); } } else if (IS_MAPPED(t)) { border_draw_decorations( t, PART_ALL, (t == get_focus_window()) ? True : False, False, CLEAR_ALL, NULL, NULL); XMapWindow(dpy, FW_W_FRAME(t)); XMapWindow(dpy, FW_W_PARENT(t)); XMapSubwindows(dpy, FW_W_FRAME(t)); #ifdef ICCCM2_UNMAP_WINDOW_PATCH /* this is required by the ICCCM2 */ XMapWindow(dpy, FW_W(t)); #endif if (!Scr.bo.do_enable_ewmh_iconic_state_workaround) { SetMapStateProp(t, NormalState); } } if (ret) { XSelectInput(dpy, FW_W(t), eventMask); XFlush(dpy); } return; } /* * * Unmap all windows on a desk - * - Part 1 of a desktop switch * - must eventually be followed by a call to MapDesk * - unmaps from the bottom of the stack up * */ static void UnmapDesk(int desk, Bool grab) { FvwmWindow *t; FvwmWindow *sf = get_focus_window(); if (grab) { MyXGrabServer(dpy); } for (t = get_prev_window_in_stack_ring(&Scr.FvwmRoot); t != &Scr.FvwmRoot; t = get_prev_window_in_stack_ring(t)) { /* Only change mapping for non-sticky windows */ if (!is_window_sticky_across_desks(t) && !IS_ICON_UNMAPPED(t)) { if (t->Desk == desk) { if (sf == t) { t->flags.is_focused_on_other_desk = 1; t->FocusDesk = desk; DeleteFocus(True); } else { t->flags.is_focused_on_other_desk = 0; } unmap_window(t); SET_FULLY_VISIBLE(t, 0); SET_PARTIALLY_VISIBLE(t, 0); } } else { t->flags.is_focused_on_other_desk = 0; } } if (grab) { MyXUngrabServer(dpy); } return; } /* * * Map all windows on a desk - * - Part 2 of a desktop switch * - only use if UnmapDesk has previously been called * - maps from the top of the stack down * */ static void MapDesk(int desk, Bool grab) { FvwmWindow *t; FvwmWindow *FocusWin = NULL; FvwmWindow *StickyWin = NULL; FvwmWindow *sf = get_focus_window(); Scr.flags.is_map_desk_in_progress = 1; if (grab) { MyXGrabServer(dpy); } for (t = get_next_window_in_stack_ring(&Scr.FvwmRoot); t != &Scr.FvwmRoot; t = get_next_window_in_stack_ring(t)) { /* Only change mapping for non-sticky windows */ if (!is_window_sticky_across_desks(t) && !IS_ICON_UNMAPPED(t)) { if (t->Desk == desk) { map_window(t); } } else { /* If window is sticky, just update its desk (it's * still mapped). */ t->Desk = desk; if (sf == t) { StickyWin = t; } } } if (grab) { MyXUngrabServer(dpy); } for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { /* Autoplace any sticky icons, so that sticky icons from the old desk don't land on top of stationary ones on the new desk. */ if (is_window_sticky_across_desks(t) && IS_ICONIFIED(t) && !IS_ICON_MOVED(t) && !IS_ICON_UNMAPPED(t)) { AutoPlaceIcon(t, NULL, True); } /* Keep track of the last-focused window on the new desk. */ if (t->flags.is_focused_on_other_desk && t->FocusDesk == desk) { t->flags.is_focused_on_other_desk = 0; FocusWin = t; } } /* If a sticky window has focus, don't disturb it. */ if (!StickyWin && FocusWin) { /* Otherwise, handle remembering the last-focused clicky * window. */ if (!FP_DO_UNFOCUS_LEAVE(FW_FOCUS_POLICY(FocusWin))) { ReturnFocusWindow(FocusWin); } else { DeleteFocus(True); } } Scr.flags.is_map_desk_in_progress = 0; return; } /* ---------------------------- interface functions ------------------------ */ /* * * Check to see if the pointer is on the edge of the screen, and scroll/page * if needed * * Returns * 0: no paging * 1: paging occured * -1: no need to call the function again before a new event arrives */ int HandlePaging( XEvent *pev, int HorWarpSize, int VertWarpSize, int *xl, int *yt, int *delta_x, int *delta_y, Bool Grab, Bool fLoop, Bool do_continue_previous, int delay) { static int add_time = 0; int x,y; XEvent e; static Time my_timestamp = 0; static Time my_last_timestamp = 0; static Bool is_timestamp_valid = False; static int last_x = 0; static int last_y = 0; static Bool is_last_position_valid = False; *delta_x = 0; *delta_y = 0; if (!is_timestamp_valid && do_continue_previous) { /* don't call me again until something has happened */ return -1; } if (!is_timestamp_valid && pev->type == MotionNotify) { x = pev->xmotion.x_root; y = pev->xmotion.y_root; if ((Scr.VxMax == 0 || (x >= edge_thickness && x < Scr.MyDisplayWidth - edge_thickness)) && (Scr.VyMax == 0 || (y >= edge_thickness && y < Scr.MyDisplayHeight - edge_thickness))) { return -1; } } if (delay < 0 || (HorWarpSize == 0 && VertWarpSize==0)) { is_timestamp_valid = False; add_time = 0; return 0; } if (Scr.VxMax == 0 && Scr.VyMax == 0) { is_timestamp_valid = False; add_time = 0; return 0; } if (!is_timestamp_valid) { is_timestamp_valid = True; my_timestamp = fev_get_evtime(); is_last_position_valid = False; add_time = 0; last_x = -1; last_y = -1; } else if (my_last_timestamp != fev_get_evtime()) { add_time = 0; } my_last_timestamp = fev_get_evtime(); do { int rc; Window JunkW; int JunkC; unsigned int JunkM; if (FCheckPeekIfEvent(dpy, &e, _pred_button_event, NULL)) { is_timestamp_valid = False; add_time = 0; return 0; } /* get pointer location */ rc = FQueryPointer( dpy, Scr.Root, &JunkW, &JunkW, &x, &y, &JunkC, &JunkC, &JunkM); if (rc == False) { /* pointer is on a different screen */ x = 0; y = 0; } /* check actual pointer location since PanFrames can get buried * under window being moved or resized - mab */ if (x >= edge_thickness && x < Scr.MyDisplayWidth-edge_thickness && y >= edge_thickness && y < Scr.MyDisplayHeight-edge_thickness) { is_timestamp_valid = False; add_time = 0; return 0; } if (!fLoop && is_last_position_valid && (x - last_x > MAX_PAGING_MOVE_DISTANCE || x - last_x < -MAX_PAGING_MOVE_DISTANCE || y - last_y > MAX_PAGING_MOVE_DISTANCE || y - last_y < -MAX_PAGING_MOVE_DISTANCE)) { /* The pointer is moving too fast, prevent paging until * it slows down. Don't prevent paging when fLoop is * set since we can't be sure that HandlePaging will be * called again. */ is_timestamp_valid = True; my_timestamp = fev_get_evtime(); add_time = 0; last_x = x; last_y = y; return 0; } last_x = x; last_y = y; is_last_position_valid = True; usleep(10000); add_time += 10; } while (fLoop && fev_get_evtime() - my_timestamp + add_time < delay); if (fev_get_evtime() - my_timestamp + add_time < delay) { return 0; } /* Get the latest pointer position. This is necessary as XFree 4.1.0.1 * sometimes does not report mouse movement when it should. */ if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen - ignore */ } /* Move the viewport */ /* and/or move the cursor back to the approximate correct location */ /* that is, the same place on the virtual desktop that it */ /* started at */ if (x < edge_thickness) { *delta_x = -HorWarpSize; } else if (x >= Scr.MyDisplayWidth-edge_thickness) { *delta_x = HorWarpSize; } else { *delta_x = 0; } if (Scr.VxMax == 0) { *delta_x = 0; } if (y < edge_thickness) { *delta_y = -VertWarpSize; } else if (y >= Scr.MyDisplayHeight-edge_thickness) { *delta_y = VertWarpSize; } else { *delta_y = 0; } if (Scr.VyMax == 0) { *delta_y = 0; } /* Ouch! lots of bounds checking */ if (Scr.Vx + *delta_x < 0) { if (!(Scr.flags.do_edge_wrap_x)) { *delta_x = -Scr.Vx; *xl = x - *delta_x; } else { *delta_x += Scr.VxMax + Scr.MyDisplayWidth; *xl = x + *delta_x % Scr.MyDisplayWidth + HorWarpSize; } } else if (Scr.Vx + *delta_x > Scr.VxMax) { if (!(Scr.flags.do_edge_wrap_x)) { *delta_x = Scr.VxMax - Scr.Vx; *xl = x - *delta_x; } else { *delta_x -= Scr.VxMax +Scr.MyDisplayWidth; *xl = x + *delta_x % Scr.MyDisplayWidth - HorWarpSize; } } else { *xl = x - *delta_x; } if (Scr.Vy + *delta_y < 0) { if (!(Scr.flags.do_edge_wrap_y)) { *delta_y = -Scr.Vy; *yt = y - *delta_y; } else { *delta_y += Scr.VyMax + Scr.MyDisplayHeight; *yt = y + *delta_y % Scr.MyDisplayHeight + VertWarpSize; } } else if (Scr.Vy + *delta_y > Scr.VyMax) { if (!(Scr.flags.do_edge_wrap_y)) { *delta_y = Scr.VyMax - Scr.Vy; *yt = y - *delta_y; } else { *delta_y -= Scr.VyMax + Scr.MyDisplayHeight; *yt = y + *delta_y % Scr.MyDisplayHeight - VertWarpSize; } } else { *yt = y - *delta_y; } /* Check for paging -- and don't warp the pointer. */ is_timestamp_valid = False; add_time = 0; if (*delta_x == 0 && *delta_y == 0) { return 0; } /* make sure the pointer isn't warped into the panframes */ if (*xl < edge_thickness) { *xl = edge_thickness; } if (*yt < edge_thickness) { *yt = edge_thickness; } if (*xl >= Scr.MyDisplayWidth - edge_thickness) { *xl = Scr.MyDisplayWidth - edge_thickness -1; } if (*yt >= Scr.MyDisplayHeight - edge_thickness) { *yt = Scr.MyDisplayHeight - edge_thickness -1; } if (Grab) { MyXGrabServer(dpy); } /* Turn off the rubberband if its on */ switch_move_resize_grid(False); FWarpPointer(dpy,None,Scr.Root,0,0,0,0,*xl,*yt); MoveViewport(Scr.Vx + *delta_x,Scr.Vy + *delta_y,False); if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, xl, yt, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ *xl = 0; *yt = 0; } if (Grab) { MyXUngrabServer(dpy); } return 1; } /* the root window is surrounded by four window slices, which are InputOnly. * So you can see 'through' them, but they eat the input. An EnterEvent in * one of these windows causes a Paging. The windows have the according cursor * pointing in the pan direction or are hidden if there is no more panning * in that direction. This is mostly intended to get a panning even atop * of Motif applictions, which does not work yet. It seems Motif windows * eat all mouse events. * * Hermann Dunkel, HEDU, dunkel@cul-ipn.uni-kiel.de 1/94 */ /* * checkPanFrames hides PanFrames if they are on the very border of the * VIRTUAL screen and EdgeWrap for that direction is off. * (A special cursor for the EdgeWrap border could be nice) HEDU */ void checkPanFrames(void) { Bool do_unmap_l = False; Bool do_unmap_r = False; Bool do_unmap_t = False; Bool do_unmap_b = False; if (!Scr.flags.are_windows_captured) return; /* thickness of 0 means remove the pan frames */ if (edge_thickness == 0) { do_unmap_l = True; do_unmap_r = True; do_unmap_t = True; do_unmap_b = True; } /* Remove Pan frames if paging by edge-scroll is permanently or * temporarily disabled */ if (Scr.EdgeScrollX == 0 || Scr.VxMax == 0) { do_unmap_l = True; do_unmap_r = True; } if (Scr.EdgeScrollY == 0 || Scr.VyMax == 0) { do_unmap_t = True; do_unmap_b = True; } if (Scr.Vx == 0 && !Scr.flags.do_edge_wrap_x) { do_unmap_l = True; } if (Scr.Vx == Scr.VxMax && !Scr.flags.do_edge_wrap_x) { do_unmap_r = True; } if (Scr.Vy == 0 && !Scr.flags.do_edge_wrap_y) { do_unmap_t = True; } if (Scr.Vy == Scr.VyMax && !Scr.flags.do_edge_wrap_y) { do_unmap_b = True; } /* correct the unmap variables if pan frame commands are set */ if (edge_thickness != 0) { if (Scr.PanFrameLeft.command != NULL || Scr.PanFrameLeft.command_leave != NULL) { do_unmap_l = False; } if (Scr.PanFrameRight.command != NULL || Scr.PanFrameRight.command_leave != NULL) { do_unmap_r = False; } if (Scr.PanFrameBottom.command != NULL || Scr.PanFrameBottom.command_leave != NULL) { do_unmap_b = False; } if (Scr.PanFrameTop.command != NULL || Scr.PanFrameTop.command_leave != NULL) { do_unmap_t = False; } } /* * hide or show the windows */ /* left */ if (do_unmap_l) { if (Scr.PanFrameLeft.isMapped) { XUnmapWindow(dpy, Scr.PanFrameLeft.win); Scr.PanFrameLeft.isMapped = False; } } else { if (edge_thickness != last_edge_thickness) { XResizeWindow( dpy, Scr.PanFrameLeft.win, edge_thickness, Scr.MyDisplayHeight); } if (!Scr.PanFrameLeft.isMapped) { XMapRaised(dpy, Scr.PanFrameLeft.win); Scr.PanFrameLeft.isMapped = True; } } /* right */ if (do_unmap_r) { if (Scr.PanFrameRight.isMapped) { XUnmapWindow(dpy, Scr.PanFrameRight.win); Scr.PanFrameRight.isMapped = False; } } else { if (edge_thickness != last_edge_thickness) { XMoveResizeWindow( dpy, Scr.PanFrameRight.win, Scr.MyDisplayWidth - edge_thickness, 0, edge_thickness, Scr.MyDisplayHeight); } if (!Scr.PanFrameRight.isMapped) { XMapRaised(dpy, Scr.PanFrameRight.win); Scr.PanFrameRight.isMapped = True; } } /* top */ if (do_unmap_t) { if (Scr.PanFrameTop.isMapped) { XUnmapWindow(dpy, Scr.PanFrameTop.win); Scr.PanFrameTop.isMapped = False; } } else { if (edge_thickness != last_edge_thickness) { XResizeWindow( dpy, Scr.PanFrameTop.win, Scr.MyDisplayWidth, edge_thickness); } if (!Scr.PanFrameTop.isMapped) { XMapRaised(dpy, Scr.PanFrameTop.win); Scr.PanFrameTop.isMapped = True; } } /* bottom */ if (do_unmap_b) { if (Scr.PanFrameBottom.isMapped) { XUnmapWindow(dpy, Scr.PanFrameBottom.win); Scr.PanFrameBottom.isMapped = False; } } else { if (edge_thickness != last_edge_thickness) { XMoveResizeWindow( dpy, Scr.PanFrameBottom.win, 0, Scr.MyDisplayHeight - edge_thickness, Scr.MyDisplayWidth, edge_thickness); } if (!Scr.PanFrameBottom.isMapped) { XMapRaised(dpy, Scr.PanFrameBottom.win); Scr.PanFrameBottom.isMapped = True; } } last_edge_thickness = edge_thickness; return; } /* * * Gotta make sure these things are on top of everything else, or they * don't work! * * For some reason, this seems to be unneeded. * */ void raisePanFrames(void) { Window windows[4]; int n; /* Note: make sure the stacking order of the pan frames is not changed * every time they are raised by using XRestackWindows. */ n = 0; if (Scr.PanFrameTop.isMapped) { windows[n++] = Scr.PanFrameTop.win; } if (Scr.PanFrameLeft.isMapped) { windows[n++] = Scr.PanFrameLeft.win; } if (Scr.PanFrameRight.isMapped) { windows[n++] = Scr.PanFrameRight.win; } if (Scr.PanFrameBottom.isMapped) { windows[n++] = Scr.PanFrameBottom.win; } if (n > 0) { XRaiseWindow(dpy, windows[0]); if (n > 1) { XRestackWindows(dpy, windows, n); } } return; } /* * * Creates the windows for edge-scrolling * */ void initPanFrames(void) { XSetWindowAttributes attributes; unsigned long valuemask; int saved_thickness; /* Not creating the frames disables all subsequent behavior */ /* TKP. This is bad, it will cause an XMap request on a null window * later*/ /* if (edge_thickness == 0) return; */ saved_thickness = edge_thickness; if (edge_thickness == 0) { edge_thickness = 2; } attributes.event_mask = XEVMASK_PANFW; valuemask= (CWEventMask | CWCursor); attributes.cursor = Scr.FvwmCursors[CRS_TOP_EDGE]; /* I know these overlap, it's useful when at (0,0) and the top one is * unmapped */ Scr.PanFrameTop.win = XCreateWindow( dpy, Scr.Root, 0, 0, Scr.MyDisplayWidth, edge_thickness, 0, CopyFromParent, InputOnly, CopyFromParent, valuemask, &attributes); attributes.cursor = Scr.FvwmCursors[CRS_LEFT_EDGE]; Scr.PanFrameLeft.win = XCreateWindow( dpy, Scr.Root, 0, 0, edge_thickness, Scr.MyDisplayHeight, 0, CopyFromParent, InputOnly, CopyFromParent, valuemask, &attributes); attributes.cursor = Scr.FvwmCursors[CRS_RIGHT_EDGE]; Scr.PanFrameRight.win = XCreateWindow( dpy, Scr.Root, Scr.MyDisplayWidth - edge_thickness, 0, edge_thickness, Scr.MyDisplayHeight, 0, CopyFromParent, InputOnly, CopyFromParent, valuemask, &attributes); attributes.cursor = Scr.FvwmCursors[CRS_BOTTOM_EDGE]; Scr.PanFrameBottom.win = XCreateWindow( dpy, Scr.Root, 0, Scr.MyDisplayHeight - edge_thickness, Scr.MyDisplayWidth, edge_thickness, 0, CopyFromParent, InputOnly, CopyFromParent, valuemask, &attributes); Scr.PanFrameTop.isMapped=Scr.PanFrameLeft.isMapped= Scr.PanFrameRight.isMapped= Scr.PanFrameBottom.isMapped=False; edge_thickness = saved_thickness; return; } Bool is_pan_frame(Window w) { if (w == Scr.PanFrameTop.win || w == Scr.PanFrameBottom.win || w == Scr.PanFrameLeft.win || w == Scr.PanFrameRight.win) { return True; } else { return False; } } /* * * Moves the viewport within the virtual desktop * */ void MoveViewport(int newx, int newy, Bool grab) { FvwmWindow *t, *t1; int deltax,deltay; int PageTop, PageLeft; int PageBottom, PageRight; int txl, txr, tyt, tyb; if (grab) { MyXGrabServer(dpy); } if (newx > Scr.VxMax) { newx = Scr.VxMax; } if (newy > Scr.VyMax) { newy = Scr.VyMax; } if (newx < 0) { newx = 0; } if (newy < 0) { newy = 0; } deltay = Scr.Vy - newy; deltax = Scr.Vx - newx; /* Identify the bounding rectangle that will be moved into the viewport. */ PageBottom = Scr.MyDisplayHeight - deltay - 1; PageRight = Scr.MyDisplayWidth - deltax - 1; PageTop = 0 - deltay; PageLeft = 0 - deltax; if (deltax || deltay) { prev_page_x = Scr.Vx; prev_page_y = Scr.Vy; prev_desk_and_page_page_x = Scr.Vx; prev_desk_and_page_page_y = Scr.Vy; prev_desk_and_page_desk = Scr.CurrentDesk; } Scr.Vx = newx; Scr.Vy = newy; if (deltax || deltay) { BroadcastPacket( M_NEW_PAGE, 7, (long)Scr.Vx, (long)Scr.Vy, (long)Scr.CurrentDesk, (long)Scr.MyDisplayWidth, (long)Scr.MyDisplayHeight, (long)((Scr.VxMax / Scr.MyDisplayWidth) + 1), (long)((Scr.VyMax / Scr.MyDisplayHeight) + 1)); /* * RBW - 11/13/1998 - new: chase the chain * bidirectionally, all at once! The idea is to move the * windows that are moving out of the viewport from the bottom * of the stacking order up, to minimize the expose-redraw * overhead. Windows that will be moving into view will be * moved top down, for the same reason. Use the new * stacking-order chain, rather than the old last-focused * chain. * * domivogt (29-Nov-1999): It's faster to first map windows * top to bottom and then unmap windows bottom up. */ t = get_next_window_in_stack_ring(&Scr.FvwmRoot); while (t != &Scr.FvwmRoot) { /* * If the window is moving into the viewport... */ txl = t->g.frame.x; tyt = t->g.frame.y; txr = t->g.frame.x + t->g.frame.width - 1; tyb = t->g.frame.y + t->g.frame.height - 1; if (is_window_sticky_across_pages(t) && !IS_VIEWPORT_MOVED(t)) { /* the absolute position has changed */ t->g.normal.x -= deltax; t->g.normal.y -= deltay; t->g.max.x -= deltax; t->g.max.y -= deltay; /* Block double move. */ SET_VIEWPORT_MOVED(t, 1); } if ((txr >= PageLeft && txl <= PageRight && tyb >= PageTop && tyt <= PageBottom) && !IS_VIEWPORT_MOVED(t) && !IS_WINDOW_BEING_MOVED_OPAQUE(t)) { /* Block double move. */ SET_VIEWPORT_MOVED(t, 1); /* If the window is iconified, and sticky * Icons is set, then the window should * essentially be sticky */ if (!is_window_sticky_across_pages(t)) { if (IS_ICONIFIED(t)) { modify_icon_position( t, deltax, deltay); move_icon_to_position(t); broadcast_icon_geometry( t, False); } frame_setup_window( t, t->g.frame.x + deltax, t->g.frame.y + deltay, t->g.frame.width, t->g.frame.height, False); } } /* Bump to next win... */ t = get_next_window_in_stack_ring(t); } t1 = get_prev_window_in_stack_ring(&Scr.FvwmRoot); while (t1 != &Scr.FvwmRoot) { /* *If the window is not moving into the viewport... */ SET_VIEWPORT_MOVED(t, 1); txl = t1->g.frame.x; tyt = t1->g.frame.y; txr = t1->g.frame.x + t1->g.frame.width - 1; tyb = t1->g.frame.y + t1->g.frame.height - 1; if (! (txr >= PageLeft && txl <= PageRight && tyb >= PageTop && tyt <= PageBottom) && !IS_VIEWPORT_MOVED(t1) && !IS_WINDOW_BEING_MOVED_OPAQUE(t1)) { /* If the window is iconified, and sticky * Icons is set, then the window should * essentially be sticky */ if (!is_window_sticky_across_pages(t1)) { if (IS_ICONIFIED(t1)) { modify_icon_position( t1, deltax, deltay); move_icon_to_position(t1); broadcast_icon_geometry( t1, False); } frame_setup_window( t1, t1->g.frame.x + deltax, t1->g.frame.y + deltay, t1->g.frame.width, t1->g.frame.height, False); } } /* Bump to next win... */ t1 = get_prev_window_in_stack_ring(t1); } for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { if (IS_VIEWPORT_MOVED(t)) { /* Clear double move blocker. */ SET_VIEWPORT_MOVED(t, 0); } /* If its an icon, and its sticking, autoplace it so * that it doesn't wind up on top a a stationary * icon */ if (is_window_sticky_across_pages(t) && IS_ICONIFIED(t) && !IS_ICON_MOVED(t) && !IS_ICON_UNMAPPED(t)) { AutoPlaceIcon(t, NULL, True); } } } checkPanFrames(); /* regrab buttons in case something got obscured or unobscured */ focus_grab_buttons_all(); #if 0 /* dv (2004-07-01): I don't think that's a good idea. We could eat too * many events. */ /* do this with PanFrames too ??? HEDU */ { XEvent e; while (FCheckTypedEvent(dpy, MotionNotify, &e)) { /* nothing */ } } #endif if (grab) { MyXUngrabServer(dpy); } EWMH_SetDesktopViewPort(); return; } void goto_desk(int desk) { /* RBW - the unmapping operations are now removed to their own * functions so they can also be used by the new GoToDeskAndPage * command. */ if (Scr.CurrentDesk != desk) { prev_desk = Scr.CurrentDesk; prev_desk_and_page_desk = Scr.CurrentDesk; prev_desk_and_page_page_x = Scr.Vx; prev_desk_and_page_page_y = Scr.Vy; UnmapDesk(Scr.CurrentDesk, True); Scr.CurrentDesk = desk; MapDesk(desk, True); focus_grab_buttons_all(); BroadcastPacket(M_NEW_DESK, 1, (long)Scr.CurrentDesk); /* FIXME: domivogt (22-Apr-2000): Fake a 'restack' for sticky * window upon desk change. This is a workaround for a * problem in FvwmPager: The pager has a separate 'root' * window for each desk. If the active desk changes, the * pager destroys sticky mini windows and creates new ones in * the other desktop 'root'. But the pager can't know where to * stack them. So we have to tell it explicitly where they * go :-( This should be fixed in the pager, but right now the * pager doesn't maintain the stacking order. */ BroadcastRestackAllWindows(); EWMH_SetCurrentDesktop(); } return; } /* * * Move a window to a new desktop * */ void do_move_window_to_desk(FvwmWindow *fw, int desk) { if (fw == NULL) { return; } /* * Set the window's desktop, and map or unmap it as needed. */ /* Only change mapping for non-sticky windows */ if (!is_window_sticky_across_desks(fw) /*&& !IS_ICON_UNMAPPED(fw)*/) { if (fw->Desk == Scr.CurrentDesk) { fw->Desk = desk; if (fw == get_focus_window()) { DeleteFocus(True); } unmap_window(fw); SET_FULLY_VISIBLE(fw, 0); SET_PARTIALLY_VISIBLE(fw, 0); } else if (desk == Scr.CurrentDesk) { fw->Desk = desk; /* If its an icon, auto-place it */ if (IS_ICONIFIED(fw)) { AutoPlaceIcon(fw, NULL, True); } map_window(fw); } else { fw->Desk = desk; } BroadcastConfig(M_CONFIGURE_WINDOW,fw); } focus_grab_buttons_on_layer(fw->layer); EWMH_SetWMDesktop(fw); return; } Bool get_page_arguments(char *action, int *page_x, int *page_y) { int val[2]; int suffix[2]; char *token; char *taction; int wrapx; int wrapy; int limitdeskx; int limitdesky; wrapx = 0; wrapy = 0; limitdeskx = 1; limitdesky = 1; for (; ; action = taction) { int do_reverse; token = PeekToken(action, &taction); if (token == NULL) { *page_x = Scr.Vx; *page_y = Scr.Vy; return True; } if (StrEquals(token, "prev")) { /* last page selected */ *page_x = prev_page_x; *page_y = prev_page_y; return True; } do_reverse = 0; for ( ; *token == '!'; token++) { do_reverse = !do_reverse; } if (StrEquals(token, "wrapx")) { wrapx = (1 ^ do_reverse); } else if (StrEquals(token, "wrapy")) { wrapy = (1 ^ do_reverse); } else if (StrEquals(token, "nodesklimitx")) { limitdeskx = (0 ^ do_reverse); } else if (StrEquals(token, "nodesklimity")) { limitdesky = (0 ^ do_reverse); } else { /* no more options */ break; } } if (GetSuffixedIntegerArguments(action, NULL, val, 2, "pw", suffix) != 2) { return 0; } if (suffix[0] == 1) { *page_x = val[0] * Scr.MyDisplayWidth + Scr.Vx; } else if (suffix[0] == 2) { *page_x += val[0] * Scr.MyDisplayWidth; } else if (val[0] >= 0) { *page_x = val[0] * Scr.MyDisplayWidth; } else { *page_x = (val[0] + 1) * Scr.MyDisplayWidth + Scr.VxMax; } if (suffix[1] == 1) { *page_y = val[1] * Scr.MyDisplayHeight + Scr.Vy; } else if (suffix[1] == 2) { *page_y += val[1] * Scr.MyDisplayHeight; } else if (val[1] >= 0) { *page_y = val[1] * Scr.MyDisplayHeight; } else { *page_y = (val[1] + 1) * Scr.MyDisplayHeight + Scr.VyMax; } /* limit to desktop size */ if (limitdeskx && !wrapx) { if (*page_x < 0) { *page_x = 0; } else if (*page_x > Scr.VxMax) { *page_x = Scr.VxMax; } } else if (limitdeskx && wrapx) { while (*page_x < 0) { *page_x += Scr.VxMax + Scr.MyDisplayWidth; } while (*page_x > Scr.VxMax) { *page_x -= Scr.VxMax + Scr.MyDisplayWidth; } } if (limitdesky && !wrapy) { if (*page_y < 0) { *page_y = 0; } else if (*page_y > Scr.VyMax) { *page_y = Scr.VyMax; } } else if (limitdesky && wrapy) { while (*page_y < 0) { *page_y += Scr.VyMax + Scr.MyDisplayHeight; } while (*page_y > Scr.VyMax) { *page_y -= Scr.VyMax + Scr.MyDisplayHeight; } } return True; } char *GetDesktopName(int desk) { DesktopsInfo *d; d = Scr.Desktops->next; while (d != NULL && d->desk != desk) { d = d->next; } if (d != NULL) { return d->name; } return NULL; } /* ---------------------------- builtin commands --------------------------- */ /* EdgeCommand - binds a function to a pan frame enter event */ void CMD_EdgeCommand(F_CMD_ARGS) { direction_t direction; char * command; /* get the direction */ direction = gravity_parse_dir_argument(action, &action, DIR_NONE); if (direction >= 0 && direction <= DIR_MAJOR_MASK) { /* check if the command does contain at least one token */ command = safestrdup(action); if (PeekToken(action , &action) == NULL) { /* the command does not contain a token so the command of this edge is removed */ free(command); command = NULL; } /* assign command to the edge(s) */ if (direction == DIR_N) { if (Scr.PanFrameTop.command != NULL) { free(Scr.PanFrameTop.command); } Scr.PanFrameTop.command = command; } else if (direction == DIR_S) { if (Scr.PanFrameBottom.command != NULL) { free(Scr.PanFrameBottom.command); } Scr.PanFrameBottom.command = command; } else if (direction == DIR_W) { if (Scr.PanFrameLeft.command != NULL) { free(Scr.PanFrameLeft.command); } Scr.PanFrameLeft.command = command; } else if (direction == DIR_E) { if (Scr.PanFrameRight.command != NULL) { free(Scr.PanFrameRight.command); } Scr.PanFrameRight.command = command; } else { /* this should never happen */ fvwm_msg(ERR, "EdgeCommand", "Internal error in CMD_EdgeCommand"); } } else { /* check if the argument does contain at least one token */ if (PeekToken(action , &action) == NULL) { /* Just plain EdgeCommand, so all edge commands are * removed */ if (Scr.PanFrameTop.command != NULL) { free(Scr.PanFrameTop.command); Scr.PanFrameTop.command = NULL; } if (Scr.PanFrameBottom.command != NULL) { free(Scr.PanFrameBottom.command); Scr.PanFrameBottom.command = NULL; } if (Scr.PanFrameLeft.command != NULL) { free(Scr.PanFrameLeft.command); Scr.PanFrameLeft.command = NULL; } if (Scr.PanFrameRight.command != NULL) { free(Scr.PanFrameRight.command); Scr.PanFrameRight.command = NULL; } } else { /* not a proper direction */ fvwm_msg(ERR, "EdgeCommand", "EdgeCommand [direction [function]]"); } } /* maybe something has changed so we adapt the pan frames */ checkPanFrames(); return; } /* EdgeLeaveCommand - binds a function to a pan frame Leave event */ void CMD_EdgeLeaveCommand(F_CMD_ARGS) { direction_t direction; char * command; /* get the direction */ direction = gravity_parse_dir_argument(action, &action, DIR_NONE); if (direction >= 0 && direction <= DIR_MAJOR_MASK) { /* check if the command does contain at least one token */ command = safestrdup(action); if (PeekToken(action , &action) == NULL) { /* the command does not contain a token so the command of this edge is removed */ free(command); command = NULL; } /* assign command to the edge(s) */ if (direction == DIR_N) { if (Scr.PanFrameTop.command_leave != NULL) { free(Scr.PanFrameTop.command_leave); } Scr.PanFrameTop.command_leave = command; } else if (direction == DIR_S) { if (Scr.PanFrameBottom.command_leave != NULL) { free(Scr.PanFrameBottom.command_leave); } Scr.PanFrameBottom.command_leave = command; } else if (direction == DIR_W) { if (Scr.PanFrameLeft.command_leave != NULL) { free(Scr.PanFrameLeft.command_leave); } Scr.PanFrameLeft.command_leave = command; } else if (direction == DIR_E) { if (Scr.PanFrameRight.command_leave != NULL) { free(Scr.PanFrameRight.command_leave); } Scr.PanFrameRight.command_leave = command; } else { /* this should never happen */ fvwm_msg(ERR, "EdgeLeaveCommand", "Internal error in CMD_EdgeLeaveCommand"); } } else { /* check if the argument does contain at least one token */ if (PeekToken(action , &action) == NULL) { /* Just plain EdgeLeaveCommand, so all edge commands are * removed */ if (Scr.PanFrameTop.command_leave != NULL) { free(Scr.PanFrameTop.command_leave); Scr.PanFrameTop.command_leave = NULL; } if (Scr.PanFrameBottom.command_leave != NULL) { free(Scr.PanFrameBottom.command_leave); Scr.PanFrameBottom.command_leave = NULL; } if (Scr.PanFrameLeft.command_leave != NULL) { free(Scr.PanFrameLeft.command_leave); Scr.PanFrameLeft.command_leave = NULL; } if (Scr.PanFrameRight.command_leave != NULL) { free(Scr.PanFrameRight.command_leave); Scr.PanFrameRight.command_leave = NULL; } } else { /* not a proper direction */ fvwm_msg(ERR, "EdgeLeaveCommand", "EdgeLeaveCommand [direction [function]]"); } } /* maybe something has changed so we adapt the pan frames */ checkPanFrames(); return; } void CMD_EdgeThickness(F_CMD_ARGS) { int val, n; n = GetIntegerArguments(action, NULL, &val, 1); if (n != 1) { fvwm_msg(ERR,"setEdgeThickness", "EdgeThickness requires 1 numeric argument," " found %d args",n); return; } /* check range */ if (val < 0 || val > 2) { fvwm_msg(ERR,"setEdgeThickness", "EdgeThickness arg must be between 0 and 2," " found %d",val); return; } edge_thickness = val; checkPanFrames(); return; } void CMD_EdgeScroll(F_CMD_ARGS) { int val1, val2, val1_unit, val2_unit, n; char *token; n = GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit); if (n != 2) { fvwm_msg( ERR, "SetEdgeScroll", "EdgeScroll requires two arguments"); return; } /* * if edgescroll >1000 and <100000 * wrap at edges of desktop (a "spherical" desktop) */ if (val1 >= 1000 && val1_unit != 100) { val1 /= 1000; Scr.flags.do_edge_wrap_x = 1; } else { Scr.flags.do_edge_wrap_x = 0; } if (val2 >= 1000 && val2_unit != 100) { val2 /= 1000; Scr.flags.do_edge_wrap_y = 1; } else { Scr.flags.do_edge_wrap_y = 0; } action=SkipNTokens(action,2); token = PeekToken(action, NULL); if (token) { if (StrEquals(token, "wrap")) { Scr.flags.do_edge_wrap_x = 1; Scr.flags.do_edge_wrap_y = 1; } else if (StrEquals(token, "wrapx")) { Scr.flags.do_edge_wrap_x = 1; } else if (StrEquals(token, "wrapy")) { Scr.flags.do_edge_wrap_y = 1; } } Scr.EdgeScrollX = val1 * val1_unit / 100; Scr.EdgeScrollY = val2 * val2_unit / 100; checkPanFrames(); return; } void CMD_EdgeResistance(F_CMD_ARGS) { int val[3]; int n; val[0] = 0; n = GetIntegerArguments(action, NULL, val, 3); if (n > 1 && val[0] >= 10000) { /* map val[0] >= 10000 in old syntax to -1 in new syntax */ val[0] = -1; } if (n == 1) { Scr.ScrollDelay = val[0]; } else if (n >= 2 && n <= 3) { char cmd[99]; char stylecmd[99]; char stylecmd2[99]; Scr.ScrollDelay = val[0]; sprintf(cmd, "EdgeResistance %d", val[0]); sprintf(stylecmd, "Style * EdgeMoveDelay %d", val[0]); if (n == 2) { sprintf( stylecmd2, "Style * EdgeMoveResistance %d", val[1]); } else { sprintf( stylecmd2, "Style * EdgeMoveResistance %d %d", val[1], val[2]); } fvwm_msg( OLD, "CMD_EdgeResistance", "The command EdgeResistance with three arguments is" " obsolete. Please use the following commands" " instead:\n%s\n%s\n%s\n", cmd, stylecmd, stylecmd2); execute_function( cond_rc, exc, cmd, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); execute_function( cond_rc, exc, stylecmd, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); execute_function( cond_rc, exc, stylecmd2, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); } else { fvwm_msg( ERR, "CMD_EdgeResistance", "EdgeResistance requires two or three arguments"); return; } return; } void CMD_Xinerama(F_CMD_ARGS) { int toggle; toggle = ParseToggleArgument(action, NULL, -1, 0); if (toggle == -1) { toggle = !FScreenIsEnabled(); } if (!toggle != !FScreenIsEnabled()) { Scr.flags.do_need_window_update = True; Scr.flags.has_xinerama_state_changed = True; FScreenOnOff(toggle); broadcast_xinerama_state(); } return; } void CMD_XineramaPrimaryScreen(F_CMD_ARGS) { int val; val = FScreenGetScreenArgument(action, 0); FScreenSetPrimaryScreen(val); if (FScreenIsEnabled()) { Scr.flags.do_need_window_update = True; Scr.flags.has_xinerama_state_changed = True; } broadcast_xinerama_state(); return; } void CMD_XineramaSls(F_CMD_ARGS) { int toggle; toggle = ParseToggleArgument(action, NULL, -1, 0); if (toggle == -1) { toggle = !FScreenIsSLSEnabled(); } if (!toggle != !FScreenIsSLSEnabled()) { if (FScreenIsEnabled()) { Scr.flags.do_need_window_update = True; Scr.flags.has_xinerama_state_changed = True; } FScreenSLSOnOff(toggle); broadcast_xinerama_state(); } return; } void CMD_XineramaSlsSize(F_CMD_ARGS) { int val[2]; if (GetIntegerArguments(action, NULL, val, 2) != 2 && GetRectangleArguments(action, &val[0], &val[1]) != 2) { val[0] = 1; val[1] = 1; } if (FScreenConfigureSLSSize(val[0], val[1])) { broadcast_xinerama_state(); } return; } void CMD_XineramaSlsScreens(F_CMD_ARGS) { int nscreens; char *args; if (GetIntegerArguments(action, &args, &nscreens, 1) != 1) { nscreens = 0; args = NULL; } else if (args == NULL) { nscreens = 0; } if (FScreenConfigureSLSScreens(nscreens, args)) { broadcast_xinerama_state(); } return; } void CMD_DesktopSize(F_CMD_ARGS) { int val[2]; if (GetIntegerArguments(action, NULL, val, 2) != 2 && GetRectangleArguments(action, &val[0], &val[1]) != 2) { fvwm_msg(ERR, "CMD_DesktopSize", "DesktopSize requires two arguments"); return; } Scr.VxMax = (val[0] <= 0) ? 0: val[0]*Scr.MyDisplayWidth-Scr.MyDisplayWidth; Scr.VyMax = (val[1] <= 0) ? 0: val[1]*Scr.MyDisplayHeight-Scr.MyDisplayHeight; BroadcastPacket( M_NEW_PAGE, 7, (long)Scr.Vx, (long)Scr.Vy, (long)Scr.CurrentDesk, (long)Scr.MyDisplayWidth, (long)Scr.MyDisplayHeight, (long)((Scr.VxMax / Scr.MyDisplayWidth) + 1), (long)((Scr.VyMax / Scr.MyDisplayHeight) + 1)); checkPanFrames(); EWMH_SetDesktopGeometry(); return; } /* * * Move to a new desktop * */ void CMD_GotoDesk(F_CMD_ARGS) { goto_desk(GetDeskNumber(action, Scr.CurrentDesk)); return; } void CMD_Desk(F_CMD_ARGS) { CMD_GotoDesk(F_PASS_ARGS); return; } /* * * Move to a new desktop and page at the same time. * This function is designed for use by the Pager, and replaces the old * GoToDesk 0 10000 hack. * - unmap all windows on the current desk so they don't flash when the * viewport is moved, then switch the viewport, then the desk. * */ void CMD_GotoDeskAndPage(F_CMD_ARGS) { int val[3]; Bool is_new_desk; if (MatchToken(action, "prev")) { val[0] = prev_desk_and_page_desk; val[1] = prev_desk_and_page_page_x; val[2] = prev_desk_and_page_page_y; } else if (GetIntegerArguments(action, NULL, val, 3) == 3) { val[1] *= Scr.MyDisplayWidth; val[2] *= Scr.MyDisplayHeight; } else { return; } is_new_desk = (Scr.CurrentDesk != val[0]); if (is_new_desk) { UnmapDesk(Scr.CurrentDesk, True); } prev_desk_and_page_page_x = Scr.Vx; prev_desk_and_page_page_y = Scr.Vy; MoveViewport(val[1], val[2], True); if (is_new_desk) { prev_desk = Scr.CurrentDesk; prev_desk_and_page_desk = Scr.CurrentDesk; Scr.CurrentDesk = val[0]; MapDesk(val[0], True); focus_grab_buttons_all(); BroadcastPacket(M_NEW_DESK, 1, (long)Scr.CurrentDesk); /* FIXME: domivogt (22-Apr-2000): Fake a 'restack' for sticky * window upon desk change. This is a workaround for a * problem in FvwmPager: The pager has a separate 'root' * window for each desk. If the active desk changes, the * pager destroys sticky mini windows and creates new ones in * the other desktop 'root'. But the pager can't know where to * stack them. So we have to tell it ecplicitly where they * go :-( This should be fixed in the pager, but right now the * pager doesn't the stacking order. */ BroadcastRestackAllWindows(); } else { BroadcastPacket(M_NEW_DESK, 1, (long)Scr.CurrentDesk); } EWMH_SetCurrentDesktop(); return; } void CMD_GotoPage(F_CMD_ARGS) { int x; int y; x = Scr.Vx; y = Scr.Vy; if (!get_page_arguments(action, &x, &y)) { fvwm_msg( ERR, "goto_page_func", "GotoPage: invalid arguments: %s", action); return; } if (x < 0) { x = 0; } if (x > Scr.VxMax) { x = Scr.VxMax; } if (y < 0) { y = 0; } if (y > Scr.VyMax) { y = Scr.VyMax; } MoveViewport(x,y,True); return; } /* function with parsing of command line */ void CMD_MoveToDesk(F_CMD_ARGS) { int desk; FvwmWindow * const fw = exc->w.fw; desk = GetDeskNumber(action, fw->Desk); if (desk == fw->Desk) { return; } do_move_window_to_desk(fw, desk); return; } void CMD_Scroll(F_CMD_ARGS) { int x,y; int val1, val2, val1_unit, val2_unit; if (GetTwoArguments(action, &val1, &val2, &val1_unit, &val2_unit) != 2) { /* less then two integer parameters implies interactive * scroll check if we are scrolling in reverse direction */ char *option; int scroll_speed = 1; option = PeekToken(action, NULL); if (option != NULL) { if (StrEquals(option, "Reverse")) { scroll_speed *= -1; } } __drag_viewport(exc, scroll_speed); return; } if ((val1 > -100000)&&(val1 < 100000)) { x = Scr.Vx + val1*val1_unit/100; } else { x = Scr.Vx + (val1/1000)*val1_unit/100; } if ((val2 > -100000)&&(val2 < 100000)) { y=Scr.Vy + val2*val2_unit/100; } else { y = Scr.Vy + (val2/1000)*val2_unit/100; } if (((val1 <= -100000)||(val1 >= 100000))&&(x>Scr.VxMax)) { int xpixels; xpixels = (Scr.VxMax / Scr.MyDisplayWidth + 1) * Scr.MyDisplayWidth; x %= xpixels; y += Scr.MyDisplayHeight * (1+((x-Scr.VxMax-1)/xpixels)); if (y > Scr.VyMax) { y %= (Scr.VyMax / Scr.MyDisplayHeight + 1) * Scr.MyDisplayHeight; } } if (((val1 <= -100000)||(val1 >= 100000))&&(x<0)) { x = Scr.VxMax; y -= Scr.MyDisplayHeight; if (y < 0) { y=Scr.VyMax; } } if (((val2 <= -100000)||(val2>= 100000))&&(y>Scr.VyMax)) { int ypixels = (Scr.VyMax / Scr.MyDisplayHeight + 1) * Scr.MyDisplayHeight; y %= ypixels; x += Scr.MyDisplayWidth * (1+((y-Scr.VyMax-1)/ypixels)); if (x > Scr.VxMax) { x %= (Scr.VxMax / Scr.MyDisplayWidth + 1) * Scr.MyDisplayWidth; } } if (((val2 <= -100000)||(val2>= 100000))&&(y<0)) { y = Scr.VyMax; x -= Scr.MyDisplayWidth; if (x < 0) { x=Scr.VxMax; } } MoveViewport(x,y,True); return; } /* * * Defines the name of a desktop * */ void CMD_DesktopName(F_CMD_ARGS) { int desk; DesktopsInfo *t, *d, *new, **prev; if (GetIntegerArguments(action, &action, &desk, 1) != 1) { fvwm_msg( ERR,"CMD_DesktopName", "First argument to DesktopName must be an integer: %s", action); return; } d = Scr.Desktops->next; while (d != NULL && d->desk != desk) { d = d->next; } if (d != NULL) { if (d->name != NULL) { free(d->name); d->name = NULL; } if (action != NULL && *action && *action != '\n') { CopyString(&d->name, action); } } else { /* new deskops entries: add it in order */ d = Scr.Desktops->next; t = Scr.Desktops; prev = &(Scr.Desktops->next); while (d != NULL && d->desk < desk) { t = t->next; prev = &(d->next); d = d->next; } if (d == NULL) { /* add it at the end */ *prev = (DesktopsInfo *)safemalloc( sizeof(DesktopsInfo)); memset(*prev, 0, sizeof(DesktopsInfo)); (*prev)->desk = desk; if (action != NULL && *action && *action != '\n') { CopyString(&((*prev)->name), action); } } else { /* instert it */ new = (DesktopsInfo *)safemalloc(sizeof(DesktopsInfo)); memset(new, 0, sizeof(DesktopsInfo)); new->desk = desk; if (action != NULL && *action && *action != '\n') { CopyString(&(new->name), action); } t->next = new; new->next = d; } /* should check/set the working areas */ } if (!fFvwmInStartup) { char *msg; const char *default_desk_name = _("Desk"); /* should send the info to the FvwmPager and set the EWMH * desktop names */ if (action != NULL && *action && *action != '\n') { msg = (char *)safemalloc(strlen(action) + 44); sprintf(msg, "DesktopName %d %s", desk, action); } else { msg = (char *)safemalloc(strlen(default_desk_name)+44); sprintf( msg, "DesktopName %d %s %d", desk, default_desk_name, desk); } BroadcastConfigInfoString(msg); free(msg); } EWMH_SetDesktopNames(); return; } fvwm-2.6.7/fvwm/session.h0000644000175700017570000000357712773467232012310 00000000000000/* -*-c-*- */ /* Description: * exports from session.c shall go into this file * * Created: * 4 April 1999 - Steve Robbins */ #ifndef SESSION_H #define SESSION_H /* ** Load and save the 'global', ie not window-related, state of fvwm ** into a file. */ void LoadGlobalState(char *filename); /* ** Turn off SM for new windows */ void DisableRestoringState(void); /* ** Load and save window states. */ void LoadWindowStates (char *filename); /* ** Save state to the named file, and if running under SM, ** make the SM properly restart fvwm. */ void RestartInSession (char *filename, Bool isNative, Bool doPreserveState); /* ** Fill in the FvwmWindow struct with information saved from ** the last session. This expects the fields ** t->w ** t->name ** t->class ** t->tmpflags.NameChanged ** to have meaningful values. The shade and maximize flags are set ** if the window should start out as shaded or maximized, respecively. ** The dimensions returned in x, y, w, h should be used when the ** window is to be maximized. */ typedef struct { int shade_dir; unsigned do_shade : 1; unsigned used_title_dir_for_shading : 1; unsigned do_max : 1; } mwtsm_state_args; Bool MatchWinToSM( FvwmWindow *ewin, mwtsm_state_args *ret_state_args, initial_window_options_t *win_opts); void SetClientID(char *client_id); /* ** Try to open a connection to the session manager. If non-NULL, ** reuse the client_id. */ void SessionInit(void); /* ** The file number of the session manager connection or -1 ** if no session manager was found. */ extern int sm_fd; /* ** Process messages received from the session manager. Call this ** from the main event loop when there is input waiting sm_fd. */ void ProcessICEMsgs(void); /* * Fvwm Function implementation */ Bool quitSession(void); Bool saveSession(void); Bool saveQuitSession(void); #endif fvwm-2.6.7/fvwm/eventmask.h0000644000175700017570000000466312773467232012617 00000000000000/* -*-c-*- */ #ifndef EVENTMASK_H #define EVENTMASK_H /* ---------------------------- global definitions ------------------------- */ #define XEVMASK_FRAMEW \ (SubstructureRedirectMask | VisibilityChangeMask | \ EnterWindowMask | LeaveWindowMask) #define XEVMASK_FRAMEW_CAPTURE (XEVMASK_FRAMEW | StructureNotifyMask) #define XEVMASK_TITLEW \ (ButtonPressMask | ButtonReleaseMask | \ OwnerGrabButtonMask | /*ButtonMotionMask | PointerMotionMask | */\ EnterWindowMask | LeaveWindowMask) #define XEVMASK_BUTTONW \ XEVMASK_TITLEW #define XEVMASK_PARENTW \ (SubstructureRedirectMask) #define XEVMASK_BORDERW \ (ButtonPressMask | ButtonReleaseMask | \ EnterWindowMask | LeaveWindowMask) #define XEVMASK_CLIENTW \ (StructureNotifyMask | PropertyChangeMask | \ EnterWindowMask | LeaveWindowMask | \ ColormapChangeMask | FocusChangeMask) #define XEVMASK_ICONW \ (ButtonPressMask | ButtonReleaseMask | \ VisibilityChangeMask | ExposureMask | KeyPressMask | KeyReleaseMask | \ EnterWindowMask | LeaveWindowMask | FocusChangeMask) #define XEVMASK_ICONPW \ XEVMASK_ICONW #define XEVMASK_MENU \ (ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyReleaseMask | \ KeyPressMask | VisibilityChangeMask | ButtonMotionMask | \ PointerMotionMask) #define XEVMASK_TEAR_OFF_MENU \ (XEVMASK_MENU | LeaveWindowMask | EnterWindowMask) #define XEVMASK_MENUW \ (ExposureMask | KeyPressMask | KeyReleaseMask) #define XEVMASK_TEAR_OFF_MENUW \ (XEVMASK_MENUW | EnterWindowMask | LeaveWindowMask | \ StructureNotifyMask) #define XEVMASK_TEAR_OFF_SUBMENUW \ (XEVMASK_MENUW | LeaveWindowMask) #define XEVMASK_PANFW \ (ButtonPressMask | ButtonReleaseMask | KeyReleaseMask | KeyPressMask | \ EnterWindowMask | LeaveWindowMask | VisibilityChangeMask) #define XEVMASK_NOFOCUSW \ (KeyPressMask | KeyReleaseMask | FocusChangeMask) #define XEVMASK_MENUNFW \ (KeyPressMask | KeyReleaseMask | FocusChangeMask) #define XEVMASK_ORW \ (FocusChangeMask) #define XEVMASK_ROOTW \ (LeaveWindowMask| EnterWindowMask | \ PropertyChangeMask | SubstructureRedirectMask | KeyPressMask | \ KeyReleaseMask | \ SubstructureNotifyMask | ColormapChangeMask | \ STROKE_CODE(ButtonMotionMask | DEFAULT_ALL_BUTTONS_MOTION_MASK |) \ ButtonPressMask | ButtonReleaseMask) #define XEVMASK_RESIZE \ (ButtonPressMask | ButtonReleaseMask | KeyPressMask | \ PointerMotionMask | ButtonMotionMask | ExposureMask) #define XEVMASK_RESIZE_OPAQUE \ (XEVMASK_RESIZE | PropertyChangeMask) #endif /* EVENTMASK_H */ fvwm-2.6.7/fvwm/ConfigFvwmDefaults0000644000175700017570000001355613006057357014123 00000000000000# This file gets installed in the "datadir" during fvwm # installation. Do not remove or change this file. # # Created on 21/Mar/1999 by DanEspen (dje): # - FvwmDefaults file. Contains fvwm defaults, and enough to help out # the new user with no configuration file. # This picks up from where the builtin table in fvwm.c SetRCDefaults ends. # TA: 2012-01-02: Set the default cursor style to a dot, if FVWM is busy # in a PipeRead or Read operation. ImagePath +:$[FVWM_USERDIR] BusyCursor Read True CursorStyle Wait Dot # Set at least 2 root keys to bring up the builtin menu: Silent Key Help R A Popup MenuFvwmRoot Key F1 R A Popup MenuFvwmRoot # Ctrl-Alt-Escape for aborting Wait pause and ModuleSynchronous command Key Escape A MC EscapeFunc # Needed by the builtin WindowList command, this should match the manpage AddToFunc WindowListFunc + I Iconify off + I FlipFocus + I Raise + I WarpToWindow !raise 5p 5p # Needed by the ewmh support AddToFunc EWMHActivateWindowFunc + I Iconify off + I Focus + I Raise # Also in the fvwm man page AddToFunc UrgencyFunc + I Iconify off + I FlipFocus + I Raise + I WarpToWindow 5p 5p AddToFunc UrgencyDoneFunc I Nop # Needed by modules which use session management # FSMExecFuncWithSessionManagment "module_sm_env" "action" "orig_sm_env" AddToFunc FSMExecFuncWithSessionManagment + I Setenv SESSION_MANAGER $0 + I $1 + I Setenv SESSION_MANAGER $2 # Default styles Style * LowerTransient, RaiseTransient, StackTransientParent Style * TileCascadePlacement, Title, MouseFocus Style * UseIconPosition, RightTitleRotatedCW, UseTitleDecorRotation Style * EWMHPlacementUseDynamicWorkingArea, EWMHMaximizeUseDynamicWorkingArea # Default styles for tear off menus Style fvwm_menu NoPPosition, NeverFocus, NoLenience, \ WindowListSkip, CirculateSkip # Alt-Tab: Key Tab A M WindowList Root c c NoDeskSort # Basic Mouse controls: Mouse 1 T A FuncFvwmRaiseLowerX Move Mouse 1 FS A FuncFvwmRaiseLowerX Resize Mouse 2 FST A FuncFvwmRaiseLowerX Move AddToFunc FuncFvwmRaiseLowerX + I Raise + M $0 + D Lower ###################### # BEGIN MENU BINDINGS # # # hard coded defaults that can not be deleted #Key Escape M A MenuClose #Key Return M A MenuSelectItem #Key Left M A MenuCursorLeft #Key Right M A MenuCursorRight #Key Up M A MenuMoveCursor -1 #Key Down M A MenuMoveCursor 1 #Mouse 1 M A MenuSelectItem # Normal bindings Silent Key Delete M A MenuClose Silent Key KP_Separator M A MenuClose Silent Key KP_Decimal M A MenuClose Silent Key Space M A MenuSelectItem Silent Key KP_Enter M A MenuSelectItem # move to last entry of menu ('More...' if this exists) and # try to enter the menu. Otherwise try to enter the current # submenu Silent Key Insert M A MenuEnterContinuation Silent Key KP_Insert M A MenuEnterContinuation Silent Key KP_0 M A MenuEnterContinuation Silent Key KP_Left M A MenuCursorLeft Silent Key KP_4 M A MenuCursorLeft Silent Key KP_Right M A MenuCursorRight Silent Key KP_6 M A MenuCursorRight #back Silent Key b M A MenuLeaveSubmenu #forward Silent Key f M A MenuEnterSubmenu Silent Key Page_Up M A MenuMoveCursor -5 Silent Key KP_Prior M A MenuMoveCursor -5 Silent Key KP_9 M A MenuMoveCursor -5 Silent Key Page_Down M A MenuMoveCursor +5 Silent Key KP_Next M A MenuMoveCursor +5 Silent Key KP_3 M A MenuMoveCursor +5 # Up Silent Key KP_Up M A MenuMoveCursor -1 Silent Key KP_8 M A MenuMoveCursor -1 #prior Silent Key p M A MenuMoveCursor -1 Silent Key Up M S MenuMoveCursor 0 0 Silent Key KP_Up M S MenuMoveCursor 0 0 Silent Key KP_8 M S MenuMoveCursor 0 0 #prior Silent Key p M S MenuMoveCursor 0 0 Silent Key Up M C MenuMoveCursor -5 Silent Key KP_Up M C MenuMoveCursor -5 Silent Key KP_8 M C MenuMoveCursor -5 #prior Silent Key p M C MenuMoveCursor -5 Silent Key Up M M MenuMoveCursor -1s Silent Key KP_Up M M MenuMoveCursor -1s Silent Key KP_8 M M MenuMoveCursor -1s #prior Silent Key p M M MenuMoveCursor -1s # Down Silent Key KP_Down M A MenuMoveCursor 1 Silent Key KP_2 M A MenuMoveCursor 1 #next Silent Key n M A MenuMoveCursor 1 Silent Key Down M S MenuMoveCursor 0 -1 Silent Key KP_Down M S MenuMoveCursor 0 -1 Silent Key KP_2 M S MenuMoveCursor 0 -1 #next Silent Key n M S MenuMoveCursor 0 -1 Silent Key Down M C MenuMoveCursor +5 Silent Key KP_Down M C MenuMoveCursor +5 Silent Key KP_2 M C MenuMoveCursor +5 #next Silent Key n M C MenuMoveCursor +5 Silent Key Down M M MenuMoveCursor +1s Silent Key KP_Down M M MenuMoveCursor +1s Silent Key KP_2 M M MenuMoveCursor +1s #next Silent Key n M M MenuMoveCursor +1s Silent Key Tab M A MenuMoveCursor +1 Silent Key Tab M C MenuMoveCursor +1s Silent Key Tab M MC MenuMoveCursor +5 Silent Key Tab M S MenuMoveCursor -1 Silent Key Tab M SM MenuMoveCursor -1 Silent Key Tab M SC MenuMoveCursor -1s Silent Key Tab M SMC MenuMoveCursor -5 Silent Key Home M A MenuMoveCursor 0 0 Silent Key KP_Home M A MenuMoveCursor 0 0 Silent Key KP_7 M A MenuMoveCursor 0 0 Silent Key End M A MenuMoveCursor 0 -1 Silent Key KP_End M A MenuMoveCursor 0 -1 Silent Key KP_1 M A MenuMoveCursor 0 -1 Silent Key BackSpace M A MenuTearOff Silent Key KP_Add M A MenuScroll 1 Silent Key KP_Subtract M A MenuScroll -1 # vi bindings Silent Key h M A MenuCursorLeft Silent Key l M A MenuCursorRight Silent Key k M A MenuMoveCursor -1 Silent Key k M C MenuMoveCursor -5 Silent Key j M A MenuMoveCursor 1 Silent Key j M C MenuMoveCursor 5 # emacs bindings Silent Key a M C MenuMoveCursor 0 0 Silent Key e M C MenuMoveCursor 0 -1 Silent Key b M C MenuMoveCursor -1 Silent Key f M C MenuMoveCursor +1 Silent Key Left M C MenuMoveCursor -1s Silent Key Right M C MenuMoveCursor +1s Silent Key g M C MenuClose # Mouse bindings Mouse 0 MI A MenuSelectItem Mouse 0 MTS A MenuLeaveSubmenu Silent Mouse 4 MIT A MenuScroll -1 Silent Mouse 5 MIT A MenuScroll +1 # NB: Only on title -- changes syntax for remapping the TearOff functionality Mouse 2 MT A MenuTearOff # # # END MENU BINDINGS #################### fvwm-2.6.7/fvwm/conditional.c0000644000175700017570000013343513001406607013100 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/wild.h" #include "libs/FScreen.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "functions.h" #include "conditional.h" #include "misc.h" #include "screen.h" #include "update.h" #include "style.h" #include "focus.h" #include "geometry.h" #include "stack.h" #include "commands.h" #include "decorations.h" #include "virtual.h" #include "infostore.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* * * Direction = 1 ==> "Next" operation * Direction = -1 ==> "Previous" operation * Direction = 0 ==> operation on current window (returns pass or fail) * */ static FvwmWindow *Circulate( FvwmWindow *sf, char *action, int Direction, char **restofline) { int pass = 0; FvwmWindow *fw, *found = NULL; WindowConditionMask mask; char *flags; /* Create window mask */ flags = CreateFlagString(action, restofline); DefaultConditionMask(&mask); if (Direction == 0) { /* override for Current [] */ mask.my_flags.use_circulate_hit = 1; mask.my_flags.use_circulate_hit_icon = 1; mask.my_flags.use_circulate_hit_shaded = 1; } CreateConditionMask(flags, &mask); if (flags) { free(flags); } if (sf == NULL || Direction == 0) { sf = get_focus_window(); } if (sf != NULL) { if (Direction > 0) { fw = sf->prev; } else if (Direction < 0) { fw = sf->next; } else { fw = sf; } } else { fw = NULL; if (Direction == 0) { FreeConditionMask(&mask); return NULL; } } for (pass = 0; pass < 3 && !found; pass++) { while (fw && !found && fw != &Scr.FvwmRoot) { /* Make CirculateUp and CirculateDown take args. by * Y.NOMURA */ if (MatchesConditionMask(fw, &mask)) { found = fw; } else { if (Direction > 0) { fw = fw->prev; } else { fw = fw->next; } } if (Direction == 0) { FreeConditionMask(&mask); return found; } } if (fw == NULL || fw == &Scr.FvwmRoot) { if (Direction > 0) { /* Go to end of list */ for (fw = Scr.FvwmRoot.next; fw && fw->next; fw = fw->next) { /* nop */ } } else { /* Go to top of list */ fw = Scr.FvwmRoot.next; } } } FreeConditionMask(&mask); return found; } static void circulate_cmd( F_CMD_ARGS, int new_context, int circ_dir, Bool do_use_found, Bool do_exec_on_match) { FvwmWindow *found; char *restofline; found = Circulate(exc->w.fw, action, circ_dir, &restofline); if (cond_rc != NULL) { cond_rc->rc = (found == NULL) ? COND_RC_NO_MATCH : COND_RC_OK; } if ((!found == !do_exec_on_match) && restofline) { const exec_context_t *exc2; exec_context_changes_t ecc; int flags; ecc.w.fw = (do_use_found == True) ? found : NULL; if (found != NULL) { ecc.w.w = FW_W(found); flags = FUNC_DONT_DEFER; } else { ecc.w.w = None; flags = 0; } ecc.w.wcontext = new_context; exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); execute_function(cond_rc, exc2, restofline, flags); exc_destroy_context(exc2); } return; } static void select_cmd(F_CMD_ARGS) { char *restofline; char *flags; WindowConditionMask mask; FvwmWindow * const fw = exc->w.fw; if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } flags = CreateFlagString(action, &restofline); DefaultConditionMask(&mask); mask.my_flags.use_circulate_hit = 1; mask.my_flags.use_circulate_hit_icon = 1; mask.my_flags.use_circulate_hit_shaded = 1; CreateConditionMask(flags, &mask); if (flags) { free(flags); } if (MatchesConditionMask(fw, &mask) && restofline) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_OK; } execute_function_override_wcontext( cond_rc, exc, restofline, 0, C_WINDOW); } else if (cond_rc != NULL) { cond_rc->rc = COND_RC_NO_MATCH; } FreeConditionMask(&mask); return; } static Bool cond_check_access(char *file, int type, Bool im) { char *full_file; char *path = NULL; if (!file || *file == 0) { return False; } if (file[0] == '/') { if (access(file, type) == 0) { return True; } else { return False; } } if (type != X_OK && im == False) { return False; } if (im == False) { path = getenv("PATH"); } else { path = PictureGetImagePath(); } if (path == NULL || *path == 0) { return False; } full_file = searchPath(path, file, NULL, type); if (full_file) { free(full_file); return True; } return False; } /* ---------------------------- interface functions ------------------------ */ /* * Parses the flag string and returns the text between [ ] or ( ) * characters. The start of the rest of the line is put in restptr. * Note that the returned string is allocated here and it must be * freed when it is not needed anymore. * NOTE - exported via .h */ char *CreateFlagString(char *string, char **restptr) { char *retval; char *c; char *start; char closeopt; int length; c = string; while (isspace((unsigned char)*c) && (*c != 0)) { c++; } if (*c == '[' || *c == '(') { char *d; /* Get the text between [ ] or ( ) */ if (*c == '[') { closeopt = ']'; } else { closeopt = ')'; } c++; start = c; length = 0; while (*c != closeopt) { if (*c == 0) { fvwm_msg(ERR, "CreateFlagString", "Conditionals require closing " "parenthesis"); *restptr = NULL; return NULL; } /* skip quoted string */ d = SkipQuote(c, NULL, NULL, NULL); length += d - c; c = d; } /* We must allocate a new string because we null terminate the * string between the [ ] or ( ) characters. */ retval = safemalloc(length + 1); strncpy(retval, start, length); retval[length] = 0; *restptr = c + 1; } else { retval = NULL; *restptr = c; } return retval; } /* * The name_condition field of the mask is allocated in CreateConditionMask. * It must be freed. * NOTE - exported via .h */ void FreeConditionMask(WindowConditionMask *mask) { struct name_condition *pp,*pp2; struct namelist *p,*p2; for (pp=mask->name_condition; pp; ) { /* One malloc() is done for all the name strings. The string is tokenised & the name fields point to different parts of the one string. The start of the string is the first name in the string which is actually the last node in the linked list. */ for (p=pp->namelist; p; ) { p2=p->next; if(!p2) { free(p->name); } free(p); p=p2; } pp2=pp->next; free(pp); pp=pp2; } } /* Assign the default values for the window mask * NOTE - exported via .h */ void DefaultConditionMask(WindowConditionMask *mask) { memset(mask, 0, sizeof(WindowConditionMask)); /* -2 means no layer condition, -1 means current */ mask->layer = -2; return; } /* * Note that this function allocates the name field of the mask struct. * FreeConditionMask must be called for the mask when the mask is discarded. * NOTE - exported via .h */ void CreateConditionMask(char *flags, WindowConditionMask *mask) { char *allocated_condition; char *next_condition; char *condition; char *tmp; unsigned int state; if (flags == NULL) { return; } /* Next parse the flags in the string. */ next_condition = GetNextFullOption(flags, &allocated_condition); condition = PeekToken(allocated_condition, &tmp); while (condition) { char *cond; int on; cond = condition; on = 1; if (*cond == '!') { on = 0; cond++; } if (StrEquals(cond,"AcceptsFocus")) { mask->my_flags.do_accept_focus = on; mask->my_flags.use_do_accept_focus = 1; } else if (StrEquals(cond,"Focused")) { mask->my_flags.needs_focus = (on) ? NEEDS_TRUE : NEEDS_FALSE; } else if (StrEquals(cond,"HasPointer")) { mask->my_flags.needs_pointer = (on) ? NEEDS_TRUE : NEEDS_FALSE; } else if (StrEquals(cond,"Iconic")) { SET_ICONIFIED(mask, on); SETM_ICONIFIED(mask, 1); } else if (StrEquals(cond,"Visible")) { SET_PARTIALLY_VISIBLE(mask, on); SETM_PARTIALLY_VISIBLE(mask, 1); } else if (StrEquals(cond,"Overlapped")) { mask->my_flags.needs_overlapped = on; mask->my_flags.do_check_overlapped = 1; } else if (StrEquals(cond,"PlacedByButton")) { int button; int button_mask; if (sscanf(tmp, "%d", &button) && (button >= 1 && button <= NUMBER_OF_EXTENDED_MOUSE_BUTTONS)) { tmp = SkipNTokens(tmp, 1); button_mask = (1<<(button-1)); } else { button_mask = (1<placed_by_button_mask & mask->placed_by_button_set_mask & ~button_mask) { fvwm_msg(WARN, "PlacedByButton", "Condition always False."); } mask->placed_by_button_mask |= button_mask; } else { mask->placed_by_button_mask &= ~button_mask; } mask->placed_by_button_set_mask |= button_mask; } else if (StrEquals(cond,"PlacedByButton3")) { if (on) { if (mask->placed_by_button_mask & mask->placed_by_button_set_mask & ~(1<<2)) { fvwm_msg(WARN, "PlacedByButton3", "Condition always False."); } mask->placed_by_button_mask |= (1<<2); } else { mask->placed_by_button_mask &= ~(1<<2); } mask->placed_by_button_set_mask |= (1<<2); } else if (StrEquals(cond,"Raised")) { SET_FULLY_VISIBLE(mask, on); SETM_FULLY_VISIBLE(mask, 1); } else if (StrEquals(cond,"Sticky")) { SET_STICKY_ACROSS_PAGES(mask, on); SET_STICKY_ACROSS_DESKS(mask, on); SETM_STICKY_ACROSS_PAGES(mask, 1); SETM_STICKY_ACROSS_DESKS(mask, 1); } else if (StrEquals(cond,"StickyAcrossPages")) { SET_STICKY_ACROSS_PAGES(mask, on); SETM_STICKY_ACROSS_PAGES(mask, 1); } else if (StrEquals(cond,"StickyAcrossDesks")) { SET_STICKY_ACROSS_DESKS(mask, on); SETM_STICKY_ACROSS_DESKS(mask, 1); } else if (StrEquals(cond,"StickyIcon")) { SET_ICON_STICKY_ACROSS_PAGES(mask, on); SET_ICON_STICKY_ACROSS_DESKS(mask, on); SETM_ICON_STICKY_ACROSS_PAGES(mask, 1); SETM_ICON_STICKY_ACROSS_DESKS(mask, 1); } else if (StrEquals(cond,"StickyAcrossPagesIcon")) { SET_ICON_STICKY_ACROSS_PAGES(mask, on); SETM_ICON_STICKY_ACROSS_PAGES(mask, 1); } else if (StrEquals(cond,"StickyAcrossDesksIcon")) { SET_ICON_STICKY_ACROSS_DESKS(mask, on); SETM_ICON_STICKY_ACROSS_DESKS(mask, 1); } else if (StrEquals(cond,"Maximized")) { SET_MAXIMIZED(mask, on); SETM_MAXIMIZED(mask, 1); } else if (StrEquals(cond,"FixedSize")) { /* don't set mask here, because we make the test here (and don't compare against window's mask) by checking allowed function */ SET_SIZE_FIXED(mask, on); SETM_SIZE_FIXED(mask, 1); } else if (StrEquals(cond, "FixedPosition")) { SET_FIXED(mask, on); SETM_FIXED(mask, 1); } else if (StrEquals(cond,"HasHandles")) { SET_HAS_HANDLES(mask, on); SETM_HAS_HANDLES(mask, 1); } else if (StrEquals(cond,"Iconifiable")) { SET_IS_UNICONIFIABLE(mask, !on); SETM_IS_UNICONIFIABLE(mask, 1); } else if (StrEquals(cond,"Maximizable")) { SET_IS_UNMAXIMIZABLE(mask, !on); SETM_IS_UNMAXIMIZABLE(mask, 1); } else if (StrEquals(cond,"Closable")) { SET_IS_UNCLOSABLE(mask, !on); SETM_IS_UNCLOSABLE(mask, 1); } else if (StrEquals(cond,"Shaded")) { SET_SHADED(mask, on); SETM_SHADED(mask, 1); } else if (StrEquals(cond,"Transient")) { SET_TRANSIENT(mask, on); SETM_TRANSIENT(mask, 1); } else if (StrEquals(cond,"PlacedByFvwm")) { SET_PLACED_BY_FVWM(mask, on); SETM_PLACED_BY_FVWM(mask, 1); } else if (StrEquals(cond,"CurrentDesk")) { mask->my_flags.needs_current_desk = on; mask->my_flags.do_check_desk = 1; } else if (StrEquals(cond,"CurrentPage")) { mask->my_flags.needs_current_desk_and_page = on; mask->my_flags.do_check_desk_and_page = 1; } else if (StrEquals(cond,"CurrentGlobalPage")) { mask->my_flags.needs_current_desk_and_global_page = on; mask->my_flags.do_check_desk_and_global_page = 1; } else if (StrEquals(cond,"CurrentPageAnyDesk") || StrEquals(cond,"CurrentScreen")) { mask->my_flags.needs_current_page = on; mask->my_flags.do_check_page = 1; } else if (StrEquals(cond,"AnyScreen")) { mask->my_flags.do_not_check_screen = on; } else if (StrEquals(cond,"CurrentGlobalPageAnyDesk")) { mask->my_flags.needs_current_global_page = on; mask->my_flags.do_check_global_page = 1; } else if (StrEquals(cond,"CirculateHit")) { mask->my_flags.use_circulate_hit = on; } else if (StrEquals(cond,"CirculateHitIcon")) { mask->my_flags.use_circulate_hit_icon = on; } else if (StrEquals(cond,"CirculateHitShaded")) { mask->my_flags.use_circulate_hit_shaded = on; } else if (StrEquals(cond,"State")) { if (sscanf(tmp, "%u", &state) && state <= 31) { state = (1 << state); if (on) { SET_USER_STATES(mask, state); } else { CLEAR_USER_STATES(mask, state); } SETM_USER_STATES(mask, state); tmp = SkipNTokens(tmp, 1); } } else if (StrEquals(cond, "Layer")) { if (sscanf(tmp, "%d", &mask->layer)) { tmp = SkipNTokens(tmp, 1); if (mask->layer < 0) { /* silently ignore invalid layers */ mask->layer = -2; } } else { /* needs current layer */ mask->layer = -1; } mask->my_flags.needs_same_layer = on; } else if (StrEquals(cond, "Desk")) { if (sscanf(tmp, "%d", &mask->desk)) { tmp = SkipNTokens(tmp, 1); } mask->my_flags.do_check_cond_desk = on; } else if (StrEquals(cond, "Screen")) { if (sscanf(tmp, "%d", &mask->screen)) { tmp = SkipNTokens(tmp, 1); } mask->my_flags.do_check_screen = 1; if (!on) mask->my_flags.do_not_check_screen = 1; } else { struct name_condition *pp; struct namelist *p; char *condp = safestrdup(cond); pp = (struct name_condition *) safemalloc(sizeof(struct name_condition)); pp->invert = (!on ? True : False); pp->namelist = NULL; pp->next = mask->name_condition; mask->name_condition = pp; for (;;) { p = (struct namelist *) safemalloc(sizeof(struct namelist)); p->name=condp; p->next=pp->namelist; pp->namelist=p; while(*condp && *condp != '|') { condp++; } if(!*condp) { break; } *condp++='\0'; } } if (tmp && *tmp) { fvwm_msg(OLD, "CreateConditionMask", "Use comma instead of whitespace to " "separate conditions"); } else { if (allocated_condition != NULL) { free(allocated_condition); allocated_condition = NULL; } if (next_condition && *next_condition) { next_condition = GetNextFullOption( next_condition, &allocated_condition); } tmp = allocated_condition; } condition = PeekToken(tmp, &tmp); } return; } /* * Checks whether the given window matches the mask created with * CreateConditionMask. * NOTE - exported via .h */ Bool MatchesConditionMask(FvwmWindow *fw, WindowConditionMask *mask) { int does_match; int is_on_desk; int is_on_page; int is_on_global_page; FvwmWindow *sf = get_focus_window(); struct name_condition *pp; struct namelist *p; char *name; /* match FixedSize conditional */ /* special treatment for FixedSize, because more than just the is_size_fixed flag makes a window unresizable (width and height hints etc.) */ if (IS_SIZE_FIXED(mask) && mask->flag_mask.common.s.is_size_fixed && is_function_allowed(F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if (!IS_SIZE_FIXED(mask) && mask->flag_mask.common.s.is_size_fixed && !is_function_allowed(F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if (IS_FIXED(mask) && mask->flag_mask.common.s.is_fixed && is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if (!IS_FIXED(mask) && mask->flag_mask.common.s.is_fixed && !is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if (IS_UNICONIFIABLE(mask) && mask->flag_mask.common.s.is_uniconifiable && is_function_allowed(F_ICONIFY, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if ( !IS_UNICONIFIABLE(mask) && mask->flag_mask.common.s.is_uniconifiable && !is_function_allowed( F_ICONIFY, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if ( IS_UNMAXIMIZABLE(mask) && mask->flag_mask.common.s.is_unmaximizable && is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if ( !IS_UNMAXIMIZABLE(mask) && mask->flag_mask.common.s.is_unmaximizable && !is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False)) { return False; } if ( IS_UNCLOSABLE(mask) && mask->flag_mask.common.s.is_unclosable && (is_function_allowed( F_CLOSE, NULL, fw, RQORIG_PROGRAM_US,False) || is_function_allowed( F_DELETE, NULL, fw, RQORIG_PROGRAM_US,False) || is_function_allowed( F_DESTROY, NULL, fw, RQORIG_PROGRAM_US, False))) { return False; } if ( !IS_UNCLOSABLE(mask) && mask->flag_mask.common.s.is_unclosable && (!is_function_allowed( F_CLOSE, NULL, fw, RQORIG_PROGRAM_US,False) && !is_function_allowed( F_DELETE, NULL, fw, RQORIG_PROGRAM_US,False) && !is_function_allowed( F_DESTROY, NULL, fw, RQORIG_PROGRAM_US,False))) { return False; } if (!blockcmpmask((char *)&(fw->flags), (char *)&(mask->flags), (char *)&(mask->flag_mask), sizeof(fw->flags))) { return False; } if (!mask->my_flags.use_circulate_hit && DO_SKIP_CIRCULATE(fw)) { return False; } if (!mask->my_flags.use_circulate_hit_icon && IS_ICONIFIED(fw) && DO_SKIP_ICON_CIRCULATE(fw)) { return False; } if (!mask->my_flags.use_circulate_hit_shaded && IS_SHADED(fw) && DO_SKIP_SHADED_CIRCULATE(fw)) { return False; } if (IS_ICONIFIED(fw) && IS_TRANSIENT(fw) && IS_ICONIFIED_BY_PARENT(fw)) { return False; } /* desk and page matching */ is_on_desk = 1; if (mask->my_flags.do_check_desk || mask->my_flags.do_check_desk_and_page || mask->my_flags.do_check_desk_and_global_page) { is_on_desk = (fw->Desk == Scr.CurrentDesk); } is_on_page = 1; if (mask->my_flags.do_check_page || mask->my_flags.do_check_desk_and_page) { if (FScreenIsEnabled() && !mask->my_flags.do_not_check_screen) { is_on_page = !!FScreenIsRectangleOnScreen( NULL, FSCREEN_CURRENT, &(fw->g.frame)); } else { is_on_page = !!IsRectangleOnThisPage( &(fw->g.frame), Scr.CurrentDesk); } } is_on_global_page = 1; if (mask->my_flags.do_check_global_page || mask->my_flags.do_check_desk_and_global_page) { is_on_global_page = !!IsRectangleOnThisPage( &(fw->g.frame), Scr.CurrentDesk); } if (mask->my_flags.do_check_desk_and_page) { int is_on_desk_and_page; is_on_desk_and_page = (is_on_desk && is_on_page); if (mask->my_flags.needs_current_desk_and_page != is_on_desk_and_page) { return False; } } else if (mask->my_flags.do_check_desk_and_global_page) { int is_on_desk_and_global_page; is_on_desk_and_global_page = (is_on_desk && is_on_global_page); if (mask->my_flags.needs_current_desk_and_global_page != is_on_desk_and_global_page) { return False; } } if (mask->my_flags.do_check_desk && mask->my_flags.needs_current_desk != is_on_desk) { return False; } if (mask->my_flags.do_check_page) { if (mask->my_flags.needs_current_page != is_on_page) { return False; } } else if (mask->my_flags.do_check_global_page) { if (mask->my_flags.needs_current_global_page != is_on_global_page) { return False; } } for (pp = mask->name_condition; pp; pp = pp->next) { does_match = 0; for (p = pp->namelist; p; p = p->next) { name=p->name; does_match |= matchWildcards(name, fw->name.name); does_match |= matchWildcards(name, fw->icon_name.name); if(fw->class.res_class) does_match |= matchWildcards(name, fw->class.res_class); if(fw->class.res_name) does_match |= matchWildcards(name, fw->class.res_name); } if(( pp->invert && does_match) || (!pp->invert && !does_match)) { return False; } } if (mask->layer == -1 && sf) { int is_same_layer; is_same_layer = (fw->layer == sf->layer); if (mask->my_flags.needs_same_layer != is_same_layer) { return False; } } if (mask->layer >= 0) { int is_same_layer; is_same_layer = (fw->layer == mask->layer); if (mask->my_flags.needs_same_layer != is_same_layer) { return False; } } if (mask->placed_by_button_set_mask) { if (!((mask->placed_by_button_set_mask & (1<<(fw->placed_by_button - 1))) == (mask->placed_by_button_set_mask & mask->placed_by_button_mask))) { return False; } } if (GET_USER_STATES(mask) != (mask->flag_mask.common.user_states & GET_USER_STATES(fw))) { return False; } if (mask->my_flags.use_do_accept_focus) { Bool f; f = focus_does_accept_input_focus(fw); if (fw && !FP_DO_FOCUS_BY_FUNCTION(FW_FOCUS_POLICY(fw))) { f = False; } else if (fw && FP_IS_LENIENT(FW_FOCUS_POLICY(fw))) { f = True; } if (!f != !mask->my_flags.do_accept_focus) { return False; } } if (mask->my_flags.needs_focus != NEEDS_ANY) { int is_focused; is_focused = (fw == get_focus_window()); if (!is_focused && mask->my_flags.needs_focus == NEEDS_TRUE) { return False; } else if (is_focused && mask->my_flags.needs_focus == NEEDS_FALSE) { return False; } } if (mask->my_flags.needs_pointer != NEEDS_ANY) { int has_pointer; FvwmWindow *t; t = get_pointer_fvwm_window(); if (t != NULL && t == fw) { has_pointer = 1; } else { has_pointer = 0; } if (!has_pointer && mask->my_flags.needs_pointer == NEEDS_TRUE) { return False; } else if (has_pointer && mask->my_flags.needs_pointer == NEEDS_FALSE) { return False; } } if (mask->my_flags.do_check_overlapped) { int is_o; is_o = (is_on_top_of_layer(fw) == False); if (is_o != mask->my_flags.needs_overlapped) { return False; } } if (mask->my_flags.do_check_cond_desk) { if (fw->Desk == mask->desk) return True; else return False; if (fw->Desk != mask->desk) return True; else return False; } if (mask->my_flags.do_check_screen) { rectangle g; int scr; get_unshaded_geometry(fw, &g); scr = FScreenOfPointerXY(g.x, g.y); if (mask->my_flags.do_not_check_screen) { /* Negation of (!screen n) specified. */ return (scr != mask->screen); } else return (scr == mask->screen); } return True; } static void direction_cmd(F_CMD_ARGS, Bool is_scan) { rectangle my_g; rectangle his_g; int my_cx; int my_cy; int his_cx; int his_cy; int cross = 0; int offset = 0; int distance = 0; int cycle = False; int forward = False; int score; int best_cross = 0; int best_score; int worst_score = -1; FvwmWindow *tfw; FvwmWindow *fw_best; int dir; int dir2; Bool right_handed=False; char *flags; char *restofline; char *tmp; float tx; float ty; WindowConditionMask mask; Bool is_pointer_relative; FvwmWindow * const fw = exc->w.fw; /* Parse the direction. */ tmp = PeekToken(action, &action); if (StrEquals(tmp, "FromPointer")) { is_pointer_relative = True; tmp = PeekToken(action, &action); } else { is_pointer_relative = False; } dir = gravity_parse_dir_argument(tmp, NULL, -1); if (dir == -1 || dir > DIR_ALL_MASK) { fvwm_msg(ERR, "Direction", "Invalid direction %s", (tmp) ? tmp : ""); if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } if (is_scan) { cycle = True; tmp = PeekToken(action, &action); if ( ! tmp ) { fvwm_msg( ERR, "Direction", "Missing minor direction %s", (tmp) ? tmp : ""); if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } dir2 = gravity_parse_dir_argument(tmp, NULL, -1); /* if enum direction_t changes, this is trashed. */ if (dir2 == -1 || dir2 > DIR_NW || (dir < 4) != (dir2 < 4) || (abs(dir - dir2) & 1) != 1) { fvwm_msg( ERR, "Direction", "Invalid minor direction %s", (tmp) ? tmp : ""); if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } else if (dir2 - dir == 1 || dir2 - dir == -3) { right_handed=True; } } /* Create the mask for flags */ flags = CreateFlagString(action, &restofline); if (!restofline) { if (flags) { free(flags); } if (cond_rc != NULL) { cond_rc->rc = COND_RC_NO_MATCH; } return; } DefaultConditionMask(&mask); CreateConditionMask(flags, &mask); if (flags) { free(flags); } /* If there is a focused window, use that as a starting point. * Otherwise we use the pointer as a starting point. */ if (fw && is_pointer_relative == False) { get_visible_window_or_icon_geometry(fw, &my_g); my_cx = my_g.x + my_g.width / 2; my_cy = my_g.y + my_g.height / 2; } else { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &my_g.x, &my_g.y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ my_g.x = 0; my_g.y = 0; } my_g.width = 1; my_g.height = 1; my_cx = my_g.x; my_cy = my_g.y; } /* Next we iterate through all windows and choose the closest one in * the wanted direction. */ fw_best = NULL; best_score = -1; for (tfw = Scr.FvwmRoot.next; tfw != NULL; tfw = tfw->next) { /* Skip every window that does not match conditionals. Also * skip the currently focused window. That would be too * close. :) */ if (tfw == fw || !MatchesConditionMask(tfw, &mask)) { continue; } /* Calculate relative location of the window. */ get_visible_window_or_icon_geometry(tfw, &his_g); his_g.x -= my_cx; his_g.y -= my_cy; his_cx = his_g.x + his_g.width / 2; his_cy = his_g.y + his_g.height / 2; if (dir > DIR_MAJOR_MASK && dir <= DIR_MINOR_MASK) { int tx; /* Rotate the diagonals 45 degrees counterclockwise. To * do this, multiply the matrix /+h +h\ with the vector * (x y). \-h +h/ * h = sqrt(0.5). We can set h := 1 since absolute * distance doesn't * matter here. */ tx = his_cx + his_cy; his_cy = -his_cx + his_cy; his_cx = tx; } /* Arrange so that distance and offset are positive in desired * direction. */ switch (dir) { case DIR_S: case DIR_SW: forward = True; case DIR_N: case DIR_NE: cross = -his_cx; offset = (his_cx < 0) ? -his_cx : his_cx; distance = (dir == DIR_N || dir == DIR_NE) ? -his_cy : his_cy; break; case DIR_E: /* E */ case DIR_SE: /* SE */ forward = True; case DIR_W: /* W */ case DIR_NW: /* NW */ cross = his_cy; offset = (his_cy < 0) ? -his_cy : his_cy; distance = (dir == DIR_W || dir == DIR_NW) ? -his_cx : his_cx; break; case DIR_C: offset = 0; tx = (float)his_cx; ty = (float)his_cy; distance = (int)sqrt(tx * tx + ty * ty); break; } if (cycle) { offset=0; } else if (distance < 0) { /* Target must be in given direction. */ continue; } else if (distance == 0 && dir != DIR_C) { continue; } /* Calculate score for this window. The smaller the better. */ score = distance + offset; if (!right_handed) { cross= -cross; } if (cycle) { int ordered = (forward == (cross < best_cross)); if (distance < 0 && best_score == -1 && (score < worst_score || (score == worst_score && ordered))) { fw_best = tfw; worst_score = score; best_cross = cross; } if (score == 0 && forward == (cross < 0) && dir != DIR_C) { continue; } if (distance >= 0 && (best_score == -1 || score < best_score || (score == best_score && ordered))) { fw_best = tfw; best_score = score; best_cross = cross; } } else { /* windows more than 45 degrees off the direction are * heavily penalized and will only be chosen if nothing * else within a million pixels */ if (offset > distance) { score += 1000000; } if (best_score == -1 || score < best_score || (score == best_score && dir == DIR_C)) { fw_best = tfw; best_score = score; } } } /* for */ if (fw_best) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_OK; } execute_function_override_window( cond_rc, exc, restofline, 0, fw_best); } else if (cond_rc != NULL) { cond_rc->rc = COND_RC_NO_MATCH; } FreeConditionMask(&mask); return; } static int __rc_matches_rcstring_consume( char **ret_rest, cond_rc_t *cond_rc, char *action) { cond_rc_enum match_rc; char *orig_flags; char *flags; int is_not_reversed = 1; int ret; /* Create window mask */ orig_flags = CreateFlagString(action, ret_rest); flags = orig_flags; if (flags == NULL) { match_rc = COND_RC_NO_MATCH; } else { if (*flags == '!') { is_not_reversed = 0; flags++; } if (StrEquals(flags, "1") || StrEquals(flags, "match")) { match_rc = COND_RC_OK; } else if (StrEquals(flags, "0") || StrEquals(flags, "nomatch")) { match_rc = COND_RC_NO_MATCH; } else if (StrEquals(flags, "-1") || StrEquals(flags, "error")) { match_rc = COND_RC_ERROR; } else if (StrEquals(flags, "-2") || StrEquals(flags, "break")) { match_rc = COND_RC_BREAK; } else { match_rc = COND_RC_NO_MATCH; /* Does anyone check for other numerical returncode * values? If so, this might have to be changed. */ fprintf( stderr, "Unrecognised condition \"%s\" in" " TestRc command.\n", flags); } } if (orig_flags != NULL) { free(orig_flags); } ret = ((cond_rc->rc == match_rc) == is_not_reversed); return ret; } /* ---------------------------- builtin commands --------------------------- */ void CMD_Prev(F_CMD_ARGS) { circulate_cmd(F_PASS_ARGS, C_WINDOW, -1, True, True); return; } void CMD_Next(F_CMD_ARGS) { circulate_cmd(F_PASS_ARGS, C_WINDOW, 1, True, True); return; } void CMD_None(F_CMD_ARGS) { circulate_cmd(F_PASS_ARGS, C_ROOT, 1, False, False); /* invert return code */ switch (cond_rc->rc) { case COND_RC_OK: cond_rc->rc = COND_RC_NO_MATCH; break; case COND_RC_NO_MATCH: cond_rc->rc = COND_RC_OK; break; default: break; } return; } void CMD_Any(F_CMD_ARGS) { circulate_cmd(F_PASS_ARGS, exc->w.wcontext, 1, False, True); return; } void CMD_Current(F_CMD_ARGS) { circulate_cmd(F_PASS_ARGS, C_WINDOW, 0, True, True); return; } void CMD_PointerWindow(F_CMD_ARGS) { exec_context_changes_t ecc; ecc.w.fw = get_pointer_fvwm_window(); exc = exc_clone_context(exc, &ecc, ECC_FW); select_cmd(F_PASS_ARGS); exc_destroy_context(exc); return; } void CMD_ThisWindow(F_CMD_ARGS) { select_cmd(F_PASS_ARGS); return; } void CMD_Pick(F_CMD_ARGS) { select_cmd(F_PASS_ARGS); return; } void CMD_All(F_CMD_ARGS) { FvwmWindow *t, **g; char *restofline; WindowConditionMask mask; char *flags; int num, i; Bool does_any_window_match = False; char *token; Bool do_reverse = False; Bool use_stack = False; while (True) /* break when a non-option is found */ { token = PeekToken(action, &restofline); if (StrEquals(token, "Reverse")) { if (!*restofline) { /* if not any more actions, then Reverse * probably is some user function, so ignore * it and do the old behaviour */ break; } else { do_reverse = True; action = restofline; } } else if (StrEquals(token, "UseStack")) { if (!*restofline) { /* if not any more actions, then UseStack * probably is some user function, so ignore * it and do the old behaviour */ break; } else { use_stack = True; action = restofline; } } else { /* No more options -- continue with flags and * commands */ break; } } flags = CreateFlagString(action, &restofline); DefaultConditionMask(&mask); mask.my_flags.use_circulate_hit = 1; mask.my_flags.use_circulate_hit_icon = 1; mask.my_flags.use_circulate_hit_shaded = 1; CreateConditionMask(flags, &mask); if (flags) { free(flags); } num = 0; for (t = Scr.FvwmRoot.next; t; t = t->next) { num++; } g = (FvwmWindow **)safemalloc(num * sizeof(FvwmWindow *)); num = 0; if (!use_stack) { for (t = Scr.FvwmRoot.next; t; t = t->next) { if (MatchesConditionMask(t, &mask)) { g[num++] = t; does_any_window_match = True; } } } else { for (t = Scr.FvwmRoot.stack_next; t && t != &Scr.FvwmRoot; t = t->stack_next) { if (MatchesConditionMask(t, &mask)) { g[num++] = t; does_any_window_match = True; } } } if (do_reverse) { for (i = num-1; i >= 0; i--) { execute_function_override_window( cond_rc, exc, restofline, 0, g[i]); } } else { for (i = 0; i < num; i++) { execute_function_override_window( cond_rc, exc, restofline, 0, g[i]); } } if (cond_rc != NULL && cond_rc->rc != COND_RC_BREAK) { cond_rc->rc = (does_any_window_match == False) ? COND_RC_NO_MATCH : COND_RC_OK; } free(g); FreeConditionMask(&mask); return; } /* * Execute a function to the closest window in the given * direction. */ void CMD_Direction(F_CMD_ARGS) { direction_cmd(F_PASS_ARGS,False); } void CMD_ScanForWindow(F_CMD_ARGS) { direction_cmd(F_PASS_ARGS,True); } void CMD_WindowId(F_CMD_ARGS) { FvwmWindow *t; char *token; char *naction; unsigned long win; Bool use_condition = False; Bool use_screenroot = False; WindowConditionMask mask; char *flags, *restofline; /* Get window ID */ action = GetNextToken(action, &token); if (token && StrEquals(token, "root")) { int screen = Scr.screen; free(token); token = PeekToken(action, &naction); if (!token || GetIntegerArguments(token, NULL, &screen, 1) != 1) { screen = Scr.screen; } else { action = naction; } use_screenroot = True; if (screen < 0 || screen >= Scr.NumberOfScreens) { screen = 0; } win = XRootWindow(dpy, screen); if (win == None) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } return; } } else if (token) { /* SunOS doesn't have strtoul */ win = (unsigned long)strtol(token, NULL, 0); free(token); } else { win = 0; } /* Look for condition - CreateFlagString returns NULL if no '(' or '[' */ if (!use_screenroot) { flags = CreateFlagString(action, &restofline); if (flags) { /* Create window mask */ use_condition = True; DefaultConditionMask(&mask); /* override for Current [] */ mask.my_flags.use_circulate_hit = 1; mask.my_flags.use_circulate_hit_icon = 1; mask.my_flags.use_circulate_hit_icon = 1; CreateConditionMask(flags, &mask); free(flags); /* Relocate action */ action = restofline; } } /* Search windows */ for (t = Scr.FvwmRoot.next; t; t = t->next) { if (FW_W(t) == win) { /* do it if no conditions or the conditions match */ if (action && (!use_condition || MatchesConditionMask(t, &mask))) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_OK; } execute_function_override_window( cond_rc, exc, action, 0, t); } else if (cond_rc != NULL) { cond_rc->rc = COND_RC_NO_MATCH; } break; } } if (!t) { /* The window is not managed by fvwm. Still some functions may * work on it. */ if (use_condition) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } } else if (XGetGeometry( dpy, win, &JunkRoot, &JunkX, &JunkY, (unsigned int*)&JunkWidth, (unsigned int*)&JunkHeight, (unsigned int*)&JunkBW, (unsigned int*)&JunkDepth) != 0) { if (cond_rc != NULL) { cond_rc->rc = COND_RC_OK; } if (action != NULL) { const exec_context_t *exc2; exec_context_changes_t ecc; ecc.w.fw = NULL; ecc.w.w = win; ecc.w.wcontext = C_UNMANAGED; exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); execute_function( cond_rc, exc2, action, FUNC_IS_UNMANAGED); exc_destroy_context(exc2); } } else { /* window id does not exist */ if (cond_rc != NULL) { cond_rc->rc = COND_RC_ERROR; } } } /* Tidy up */ if (use_condition) { FreeConditionMask(&mask); } return; } void CMD_TestRc(F_CMD_ARGS) { char *rest; if (cond_rc == NULL) { /* useless if no return code to compare to is given */ return; } if (__rc_matches_rcstring_consume(&rest, cond_rc, action) && rest != NULL) { /* execute the command in root window context; overwrite the * return code with the return code of the command */ execute_function(cond_rc, exc, rest, 0); } return; } void CMD_Break(F_CMD_ARGS) { int rc; if (cond_rc == NULL) { return; } rc = GetIntegerArguments(action, &action, &cond_rc->break_levels, 1); if (rc != 1 || cond_rc->break_levels <= 0) { cond_rc->break_levels = -1; } cond_rc->rc = COND_RC_BREAK; return; } void CMD_NoWindow(F_CMD_ARGS) { execute_function_override_window(cond_rc, exc, action, 0, NULL); return; } /* ver() - convert a version string to a floating-point number that * can be used to compare different versions. * ie. converts "2.5.11" to 2005011 */ static int ver (char *str) { char *n; int v; str = DoPeekToken(str, &n, NULL, ".", NULL); if (!n) { return -1.0; } v = atoi(n) * 1000000; str = DoPeekToken(str, &n, NULL, ".", NULL); if (!n) { return -1.0; } v += atoi(n) * 1000; str = DoPeekToken(str, &n, NULL, ".", NULL); if (!n) { return -1.0; } v += atoi(n); return v; } /* match_version() - compare $version against this version of fvwm * using the operator specified by $operator. */ static Bool match_version(char *version, char *operator) { static int fvwm_version = -1; const int v = ver(version); if (fvwm_version < 0) { char *tmp = safestrdup(VERSION); fvwm_version = ver(tmp); free(tmp); } if (v < 0) { fprintf( stderr, "match_version: Invalid version: %s\n", version); return False; } if (strcmp(operator, ">=") == 0) { return fvwm_version >= v; } else if (strcmp(operator, ">") == 0) { return fvwm_version > v; } else if (strcmp(operator, "<=") == 0) { return fvwm_version <= v; } else if (strcmp(operator, "<") == 0) { return fvwm_version < v; } else if (strcmp(operator, "==") == 0) { return (v == fvwm_version); } else if (strcmp(operator, "!=") == 0) { return (v != fvwm_version); } else { fprintf( stderr, "match_version: Invalid operator: %s\n", operator); } return False; } void CMD_Test(F_CMD_ARGS) { char *restofline; char *flags; char *condition; char *flags_ptr; int match; int error; flags = CreateFlagString(action, &restofline); /* Next parse the flags in the string. */ flags_ptr = flags; flags_ptr = GetNextSimpleOption(flags_ptr, &condition); match = 1; error = 0; while (condition) { char *cond; int reverse; cond = condition; reverse = 0; if (*cond == '!') { reverse = 1; cond++; } if (StrEquals(cond, "True")) { match = 1; } else if (StrEquals(cond, "False")) { match = 0; } else if (StrEquals(cond, "Version")) { char *pattern; flags_ptr = GetNextSimpleOption(flags_ptr, &pattern); if (pattern) { char *ver; flags_ptr = GetNextSimpleOption( flags_ptr, &ver); if (ver == NULL) { match = matchWildcards( pattern, VERSION); } else { match = match_version(ver, pattern); free(ver); } free(pattern); } else { error = 1; } } else if (StrEquals(cond, "Start")) { match = exc->type == EXCT_INIT || exc->type == EXCT_RESTART; } else if (StrEquals(cond, "Init")) { match = exc->type == EXCT_INIT; } else if (StrEquals(cond, "Restart")) { match = exc->type == EXCT_RESTART; } else if (StrEquals(cond, "Exit")) { match = exc->type == EXCT_QUIT || exc->type == EXCT_TORESTART; } else if (StrEquals(cond, "Quit")) { match = exc->type == EXCT_QUIT; } else if (StrEquals(cond, "ToRestart")) { match = exc->type == EXCT_TORESTART; } else if (StrEquals(cond, "x") || StrEquals(cond, "r") || StrEquals(cond, "w") || StrEquals(cond, "f") || StrEquals(cond, "i")) { char *pattern; int type = X_OK; Bool im = 0; switch(cond[0]) { case 'X': case 'x': type = X_OK; break; case 'R': case 'r': type = R_OK; break; case 'W': case 'w': type = W_OK; break; case 'f': case 'F': type = F_OK; break; case 'i': case 'I': im = True; type = R_OK; break; default: /* cannot happen */ break; } flags_ptr = GetNextSimpleOption(flags_ptr, &pattern); if (pattern) { match = cond_check_access(pattern, type, im); free(pattern); } else { error = 1; } } else if (StrEquals(cond, "EnvIsSet")) { char *var_name; flags_ptr = GetNextSimpleOption(flags_ptr, &var_name); if (var_name) { const char *value = getenv(var_name); match = (value != NULL) ? 1 : 0; } else { error = 1; } } else if (StrEquals(cond, "EnvMatch")) { char *var_name; flags_ptr = GetNextSimpleOption(flags_ptr, &var_name); if (var_name) { const char *value; if ( (strlen(var_name) > 10) && (memcmp(var_name,"infostore.",10) == 0) ) { value = get_metainfo_value(var_name+10); } else { value = getenv(var_name); } char *pattern; /* unfortunately, GetNextSimpleOption is * broken, does not accept quoted empty "" * * DV (2-Sep-2014): It is *not* broken. The * parsing functions never return empty tokens * by design. */ flags_ptr = GetNextSimpleOption( flags_ptr, &pattern); if (!value) { value = ""; } if (pattern) { match = /* include empty string case */ (!pattern[0] && !value[0]) || matchWildcards(pattern, value); } else { error = 1; } } else { error = 1; } } else if (StrEquals(cond, "EdgeIsActive")) { direction_t dir= DIR_NONE; char *dirname; char *next; next = GetNextSimpleOption(flags_ptr, &dirname); if (dirname) { dir = gravity_parse_dir_argument( dirname, NULL, DIR_NONE); if (dir == DIR_NONE) { if (!StrEquals(dirname, "Any")) { next = flags_ptr; } } else if (dir > DIR_MAJOR_MASK) { error = 1; } free(dirname); } if (!error) { if (((dir == DIR_W || dir == DIR_NONE) && Scr.PanFrameLeft.isMapped) || ((dir == DIR_N || dir == DIR_NONE) && Scr.PanFrameTop.isMapped) || ((dir == DIR_S || dir == DIR_NONE) && Scr.PanFrameBottom.isMapped) || ((dir == DIR_E || dir == DIR_NONE) && Scr.PanFrameRight.isMapped)) { match = 1; } else { match = 0; } } flags_ptr = next; } else if (StrEquals(cond, "EdgeHasPointer")) { int x,y; Window win; direction_t dir = DIR_NONE; char *dirname; char *next; next = GetNextSimpleOption(flags_ptr, &dirname); if (dirname) { dir = gravity_parse_dir_argument( dirname, NULL, DIR_NONE); if (dir == DIR_NONE) { if (!StrEquals(dirname, "Any")) { next = flags_ptr; } } else if (dir > DIR_MAJOR_MASK) { error = 1; } free(dirname); } if (!error) { if (FQueryPointer( dpy, Scr.Root, &JunkRoot, &win, &JunkX, &JunkY, &x, &y, &JunkMask) == False) { /* pointer is on a different screen */ match = 0; } else if (is_pan_frame(win)) { if (dir == DIR_NONE || (dir == DIR_N && win == Scr.PanFrameTop.win) || (dir == DIR_S && win == Scr.PanFrameBottom.win) || (dir == DIR_E && win == Scr.PanFrameRight.win) || (dir == DIR_W && win == Scr.PanFrameLeft.win)) { match = 1; } else { match = 0; } } else { match = 0; } } flags_ptr = next; } else { /* unrecognized condition */ error = 1; fprintf( stderr, "Unrecognised condition \"%s\" in" " Test command.\n", cond); } if (reverse) { match = !match; } free(condition); if (error || !match) { break; } flags_ptr = GetNextSimpleOption(flags_ptr, &condition); } if (flags != NULL) { free(flags); } if (!error && match) { execute_function(cond_rc, exc, restofline, 0); } if (cond_rc != NULL) { if (error) { cond_rc->rc = COND_RC_ERROR; } else if (match) { cond_rc->rc = COND_RC_OK; } else { cond_rc->rc = COND_RC_NO_MATCH; } } return; } fvwm-2.6.7/fvwm/expand.c0000644000175700017570000006265713001406607012063 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/ColorUtils.h" #include "libs/FScreen.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" #include "functions.h" #include "misc.h" #include "move_resize.h" #include "screen.h" #include "geometry.h" #include "read.h" #include "virtual.h" #include "colorset.h" #include "schedule.h" #include "infostore.h" #include "libs/FGettext.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/Fsvg.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ extern char const * const Fvwm_VersionInfo; /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static char *partial_function_vars[] = { "bg.cs", "desk.name", "fg.cs", "fgsh.cs", "gt.", "hilight.cs", "infostore.", "shadow.cs", NULL }; static char *function_vars[] = { "cond.rc", "cw.height", "cw.width", "cw.x", "cw.y", "desk.height", "desk.n", "desk.pagesx", "desk.pagesy", "desk.width", "func.context", "i.height", "i.width", "i.x", "i.y", "ip.height", "ip.width", "ip.x", "ip.y", "it.height", "it.width", "it.x", "it.y", "page.nx", "page.ny", "pointer.cx", "pointer.cy", "pointer.wx", "pointer.wy", "pointer.x", "pointer.y", "pointer.screen", "schedule.last", "schedule.next", "screen", "version.info", "version.line", "version.num", "vp.height", "vp.width", "vp.x", "vp.y", "w.class", "w.height", "w.iconname", "w.iconfile", "w.miniiconfile", "w.iconfile.svgopts", "w.miniiconfile.svgopts", "w.id", "w.name", "w.resource", "w.visiblename", "w.width", "w.x", "w.y", "w.desk", "w.layer", "w.screen", /* ewmh working area */ "wa.height", "wa.width", "wa.x", "wa.y", /* ewmh dynamic working area */ "dwa.height", "dwa.width", "dwa.x", "dwa.y", NULL }; enum { VAR_BG_CS, VAR_DESK_NAME, VAR_FG_CS, VAR_FGSH_CS, VAR_GT_, VAR_HILIGHT_CS, VAR_INFOSTORE_, VAR_SHADOW_CS } partial_extended_vars; enum { VAR_COND_RC, VAR_CW_HEIGHT, VAR_CW_WIDTH, VAR_CW_X, VAR_CW_Y, VAR_DESK_HEIGHT, VAR_DESK_N, VAR_DESK_PAGESX, VAR_DESK_PAGESY, VAR_DESK_WIDTH, VAR_FUNC_CONTEXT, VAR_I_HEIGHT, VAR_I_WIDTH, VAR_I_X, VAR_I_Y, VAR_IP_HEIGHT, VAR_IP_WIDTH, VAR_IP_X, VAR_IP_Y, VAR_IT_HEIGHT, VAR_IT_WIDTH, VAR_IT_X, VAR_IT_Y, VAR_PAGE_NX, VAR_PAGE_NY, VAR_POINTER_CX, VAR_POINTER_CY, VAR_POINTER_WX, VAR_POINTER_WY, VAR_POINTER_X, VAR_POINTER_Y, VAR_POINTER_SCREEN, VAR_SCHEDULE_LAST, VAR_SCHEDULE_NEXT, VAR_SCREEN, VAR_VERSION_INFO, VAR_VERSION_LINE, VAR_VERSION_NUM, VAR_VP_HEIGHT, VAR_VP_WIDTH, VAR_VP_X, VAR_VP_Y, VAR_W_CLASS, VAR_W_HEIGHT, VAR_W_ICONNAME, VAR_W_ICONFILE, VAR_W_MINIICONFILE, VAR_W_ICONFILE_SVGOPTS, VAR_W_MINIICONFILE_SVGOPTS, VAR_W_ID, VAR_W_NAME, VAR_W_RESOURCE, VAR_W_VISIBLE_NAME, VAR_W_WIDTH, VAR_W_X, VAR_W_Y, VAR_W_DESK, VAR_W_LAYER, VAR_W_SCREEN, /* ewmh working area */ VAR_WA_HEIGHT, VAR_WA_WIDTH, VAR_WA_X, VAR_WA_Y, /* ewmh dynamic working area */ VAR_DWA_HEIGHT, VAR_DWA_WIDTH, VAR_DWA_X, VAR_DWA_Y } extended_vars; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ int __eae_parse_range(char *input, int *lower, int *upper) { int rc; int n; *lower = 0; *upper = INT_MAX; if (*input == '*') { return 0; } if (!isdigit(*input)) { return -1; } rc = sscanf(input, "%d-%d%n", lower, upper, &n); if (rc < 2) { rc = sscanf(input, "%d%n", lower, &n); if (rc < 1) { /* not a positional argument */ return -1; } if (input[n] == '-') { /* $[n- */ n++; } else { /* $[n */ *upper = *lower; } } input += n; if (*input != 0) { /* trailing characters - not good */ return -1; } if (*upper < *lower) { /* the range is reverse - not good */ return -1; } return 0; } static signed int expand_args_extended( char *input, char *argument_string, char *output) { int rc; int lower; int upper; int i; size_t len; rc = __eae_parse_range(input, &lower, &upper); if (rc == -1) { return -1; } /* Skip to the start of the requested argument range */ if (lower > 0) { argument_string = SkipNTokens(argument_string, lower); } if (!argument_string) { /* replace with empty string */ return 0; } /* TODO: optimise handling of $[0] to $[9] which have already been * parsed */ for (i = lower, len = 0; i <= upper; i++) { char *token; size_t tlen; token = PeekToken(argument_string, &argument_string); if (token == NULL) { break; } /* copy the token */ if (i > lower) { if (output != NULL) { *output = ' '; output++; } len++; } tlen = strlen(token); if (output != NULL && tlen > 0) { memcpy(output, token, tlen); output += tlen; } len += tlen; } return (int)len; } static signed int expand_vars_extended( char *var_name, char *output, cond_rc_t *cond_rc, const exec_context_t *exc) { char *rest; char dummy[64] = "\0"; char *target = (output) ? output : dummy; int cs = -1; int n; int i; int l; int x; int y; Pixel pixel = 0; int val = -12345678; const char *string = NULL; char *allocated_string = NULL; char *quoted_string = NULL; Bool should_quote = False; Bool is_numeric = False; Bool is_target = False; Bool is_x; Window context_w = Scr.Root; FvwmWindow *fw = exc->w.fw; signed int len = -1; /* allow partial matches for *.cs, gt, ... etc. variables */ switch ((i = GetTokenIndex(var_name, partial_function_vars, -1, &rest))) { case VAR_FG_CS: case VAR_BG_CS: case VAR_HILIGHT_CS: case VAR_SHADOW_CS: case VAR_FGSH_CS: if (!isdigit(*rest) || (*rest == '0' && *(rest + 1) != 0)) { /* not a non-negative integer without leading zeros */ return -1; } if (sscanf(rest, "%d%n", &cs, &n) < 1) { return -1; } if (*(rest + n) != 0) { /* trailing characters */ return -1; } if (cs < 0) { return -1; } alloc_colorset(cs); switch (i) { case VAR_FG_CS: pixel = Colorset[cs].fg; break; case VAR_BG_CS: pixel = Colorset[cs].bg; break; case VAR_HILIGHT_CS: pixel = Colorset[cs].hilite; break; case VAR_SHADOW_CS: pixel = Colorset[cs].shadow; break; case VAR_FGSH_CS: pixel = Colorset[cs].fgsh; break; } is_target = True; len = pixel_to_color_string(dpy, Pcmap, pixel, target, False); goto GOT_STRING; case VAR_GT_: if (rest == NULL) { return -1; } string = _(rest); goto GOT_STRING; case VAR_INFOSTORE_: if (rest == NULL) return -1; if ((string = get_metainfo_value(rest)) == NULL) return -1; goto GOT_STRING; case VAR_DESK_NAME: if (sscanf(rest, "%d%n", &cs, &n) < 1) { return -1; } if (*(rest + n) != 0) { /* trailing characters */ return -1; } string = GetDesktopName(cs); if (string == NULL) { const char *ddn = _("Desk"); allocated_string = (char *)safemalloc(19 + strlen(ddn)); sprintf(allocated_string, "%s %i", ddn, cs); string = allocated_string; } goto GOT_STRING; default: break; } /* only exact matches for all other variables */ switch ((i = GetTokenIndex(var_name, function_vars, 0, &rest))) { case VAR_DESK_N: is_numeric = True; val = Scr.CurrentDesk; break; case VAR_DESK_WIDTH: is_numeric = True; val = Scr.VxMax + Scr.MyDisplayWidth; break; case VAR_DESK_HEIGHT: is_numeric = True; val = Scr.VyMax + Scr.MyDisplayHeight; break; case VAR_DESK_PAGESX: is_numeric = True; val = (int)(Scr.VxMax / Scr.MyDisplayWidth) + 1; break; case VAR_DESK_PAGESY: is_numeric = True; val = (int)(Scr.VyMax / Scr.MyDisplayHeight) + 1; break; case VAR_VP_X: is_numeric = True; val = Scr.Vx; break; case VAR_VP_Y: is_numeric = True; val = Scr.Vy; break; case VAR_VP_WIDTH: is_numeric = True; val = Scr.MyDisplayWidth; break; case VAR_VP_HEIGHT: is_numeric = True; val = Scr.MyDisplayHeight; break; case VAR_WA_HEIGHT: is_numeric = True; val = Scr.Desktops->ewmh_working_area.height; break; case VAR_WA_WIDTH: is_numeric = True; val = Scr.Desktops->ewmh_working_area.width; break; case VAR_WA_X: is_numeric = True; val = Scr.Desktops->ewmh_working_area.x; break; case VAR_WA_Y: is_numeric = True; val = Scr.Desktops->ewmh_working_area.y; break; case VAR_DWA_HEIGHT: is_numeric = True; val = Scr.Desktops->ewmh_dyn_working_area.height; break; case VAR_DWA_WIDTH: is_numeric = True; val = Scr.Desktops->ewmh_dyn_working_area.width; break; case VAR_DWA_X: is_numeric = True; val = Scr.Desktops->ewmh_dyn_working_area.x; break; case VAR_DWA_Y: is_numeric = True; val = Scr.Desktops->ewmh_dyn_working_area.y; break; case VAR_PAGE_NX: is_numeric = True; val = (int)(Scr.Vx / Scr.MyDisplayWidth); break; case VAR_PAGE_NY: is_numeric = True; val = (int)(Scr.Vy / Scr.MyDisplayHeight); break; case VAR_W_ID: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { is_target = True; sprintf(target, "0x%x", (int)FW_W(fw)); } break; case VAR_W_NAME: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { string = fw->name.name; should_quote = True; } break; case VAR_W_ICONNAME: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { string = fw->icon_name.name; should_quote = True; } break; case VAR_W_ICONFILE: case VAR_W_MINIICONFILE: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { char *t; t = (i == VAR_W_ICONFILE) ? fw->icon_bitmap_file : fw->mini_pixmap_file; /* expand the path if possible */ allocated_string = PictureFindImageFile(t, NULL, R_OK); if (allocated_string == NULL) { string = t; } else if (USE_SVG && *allocated_string == ':' && (string = strchr(allocated_string + 1, ':'))) { string++; } else { string = allocated_string; } } break; case VAR_W_ICONFILE_SVGOPTS: case VAR_W_MINIICONFILE_SVGOPTS: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { char *t; if (!USE_SVG) { return -1; } t = (i == VAR_W_ICONFILE_SVGOPTS) ? fw->icon_bitmap_file : fw->mini_pixmap_file; /* expand the path if possible */ allocated_string = PictureFindImageFile(t, NULL, R_OK); string = allocated_string; if (string && *string == ':' && (t = strchr(string + 1, ':'))) { *t = 0; } else { string = ""; } } break; case VAR_W_CLASS: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { string = fw->class.res_class; should_quote = True; } break; case VAR_W_RESOURCE: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { string = fw->class.res_name; should_quote = True; } break; case VAR_W_VISIBLE_NAME: if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { string = fw->visible_name; should_quote = True; } break; case VAR_W_X: case VAR_W_Y: case VAR_W_WIDTH: case VAR_W_HEIGHT: if (!fw || IS_ICONIFIED(fw) || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } else { rectangle g; is_numeric = True; get_unshaded_geometry(fw, &g); switch (i) { case VAR_W_X: val = g.x; break; case VAR_W_Y: val = g.y; break; case VAR_W_WIDTH: val = g.width; break; case VAR_W_HEIGHT: val = g.height; break; default: return -1; } } break; case VAR_CW_X: case VAR_CW_Y: case VAR_CW_WIDTH: case VAR_CW_HEIGHT: if (!fw || IS_ICONIFIED(fw) || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } else { rectangle g; is_numeric = True; get_client_geometry(fw, &g); switch (i) { case VAR_CW_X: val = g.x; break; case VAR_CW_Y: val = g.y; break; case VAR_CW_WIDTH: val = g.width; break; case VAR_CW_HEIGHT: val = g.height; break; default: return -1; } } break; case VAR_IT_X: case VAR_IT_Y: case VAR_IT_WIDTH: case VAR_IT_HEIGHT: if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } else { rectangle g; if (get_visible_icon_title_geometry(fw, &g) == False) { return -1; } is_numeric = True; switch (i) { case VAR_IT_X: val = g.x; break; case VAR_IT_Y: val = g.y; break; case VAR_IT_WIDTH: val = g.width; break; case VAR_IT_HEIGHT: val = g.height; break; default: return -1; } } break; case VAR_IP_X: case VAR_IP_Y: case VAR_IP_WIDTH: case VAR_IP_HEIGHT: if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } else { rectangle g; if (get_visible_icon_picture_geometry(fw, &g) == False) { return -1; } is_numeric = True; switch (i) { case VAR_IP_X: val = g.x; break; case VAR_IP_Y: val = g.y; break; case VAR_IP_WIDTH: val = g.width; break; case VAR_IP_HEIGHT: val = g.height; break; default: return -1; } } break; case VAR_I_X: case VAR_I_Y: case VAR_I_WIDTH: case VAR_I_HEIGHT: if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } else { rectangle g; if (get_visible_icon_geometry(fw, &g) == False) { return -1; } is_numeric = True; switch (i) { case VAR_I_X: val = g.x; break; case VAR_I_Y: val = g.y; break; case VAR_I_WIDTH: val = g.width; break; case VAR_I_HEIGHT: val = g.height; break; default: return -1; } } break; case VAR_W_DESK: if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } is_numeric = True; if (is_window_sticky_across_desks(fw)) { val = Scr.CurrentDesk; } else { val = fw->Desk; } break; case VAR_W_LAYER: if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } is_numeric = True; val = fw->layer; break; case VAR_W_SCREEN: if (!fw || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } else { is_numeric = True; rectangle g; get_unshaded_geometry(fw, &g); val = FScreenOfPointerXY(g.x, g.y); } break; case VAR_SCREEN: is_numeric = True; val = Scr.screen; break; case VAR_SCHEDULE_LAST: is_numeric = True; val = squeue_get_last_id(); break; case VAR_SCHEDULE_NEXT: is_numeric = True; val = squeue_get_next_id(); break; case VAR_COND_RC: if (cond_rc == NULL) { return -1; } switch (cond_rc->rc) { case COND_RC_OK: case COND_RC_NO_MATCH: case COND_RC_ERROR: case COND_RC_BREAK: val = (int)(cond_rc->rc); break; default: return -1; } is_numeric = True; break; case VAR_POINTER_X: case VAR_POINTER_Y: if (is_numeric == False) { is_numeric = True; context_w = Scr.Root; } /* fall through */ case VAR_POINTER_WX: case VAR_POINTER_WY: if (is_numeric == False) { if (!fw || IS_ICONIFIED(fw) || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } is_numeric = True; context_w = FW_W_FRAME(fw); } /* fall through */ case VAR_POINTER_CX: case VAR_POINTER_CY: if (is_numeric == False) { if (!fw || IS_ICONIFIED(fw) || IS_SHADED(fw) || IS_EWMH_DESKTOP(FW_W(fw))) { return -1; } is_numeric = True; context_w = FW_W(fw); } is_x = False; switch (i) { case VAR_POINTER_X: case VAR_POINTER_WX: case VAR_POINTER_CX: is_x = True; } if (FQueryPointer(dpy, context_w, &JunkRoot, &JunkChild, &JunkX, &JunkY, &x, &y, &JunkMask) == False) { /* pointer is on a different screen, don't expand */ return -1; } val = (is_x) ? x : y; break; case VAR_POINTER_SCREEN: is_numeric = True; FQueryPointer(dpy, context_w, &JunkRoot, &JunkChild, &JunkX, &JunkY, &x, &y, &JunkMask); val = FScreenOfPointerXY(x, y); break; case VAR_VERSION_NUM: string = VERSION; break; case VAR_VERSION_INFO: string = VERSIONINFO; break; case VAR_VERSION_LINE: string = Fvwm_VersionInfo; break; case VAR_FUNC_CONTEXT: is_target = True; target[0] = wcontext_wcontext_to_char(exc->w.wcontext); target[1] = '\0'; break; default: /* unknown variable - try to find it in the environment */ string = getenv(var_name); if (!string) { /* Replace it with unexpanded variable. This is needed * since var_name might have been expanded */ l = strlen(var_name) + 3; if (output) { strcpy(output, "$["); strcpy(output + 2, var_name); output[l - 1] = ']'; output[l] = 0; } return l; } } GOT_STRING: if (is_numeric) { is_target = True; sprintf(target, "%d", val); } if (is_target) { string = target; } else { if (!string) { return -1; } if (output) { strcpy(output, string); } } if (len < 0) { len = strlen(string); } if (should_quote) { quoted_string = (char *)safemalloc(len * 2 + 3); len = QuoteString(quoted_string, string) - quoted_string; if (output) { strcpy(output, quoted_string); } free(quoted_string); } if (allocated_string) { free(allocated_string); } return len; } /* ---------------------------- interface functions ------------------------ */ char *expand_vars( char *input, char *arguments[], Bool addto, Bool ismod, cond_rc_t *cond_rc, const exec_context_t *exc) { int l, i, l2, n, k, j, m; int xlen, xlevel; Bool name_has_dollar; char *out; char *var; const char *string = NULL; Bool is_string = False; FvwmWindow *fw = exc->w.fw; l = strlen(input); l2 = l; if (input[0] == '+' && Scr.last_added_item.type == ADDED_FUNCTION) { addto = 1; } /* Calculate best guess at length of expanded string */ i = 0; while (i < l) { if (input[i] == '$' && (!ismod || !isalpha(input[i + 1]))) { switch (input[i + 1]) { case '$': /* skip the second $, it is not a part of * variable */ i++; break; case '[': /* extended variables */ m = i + 2; var = &input[m]; xlevel = 1; name_has_dollar = False; while (m < l && xlevel && input[m]) { /* handle nested variables */ if (input[m] == ']') { xlevel--; } else if (input[m] == '[') { xlevel++; } else if (input[m] == '$') { name_has_dollar = True; } if (xlevel) { m++; } } if (input[m] == ']') { input[m] = 0; /* handle variable name */ k = strlen(var); if (addto) { i += k + 2; input[m] = ']'; break; } if (name_has_dollar) { var = expand_vars( var, arguments, addto, ismod, cond_rc, exc); } xlen = expand_args_extended( var, arguments ? arguments[0] : NULL, NULL); if (xlen < 0) { xlen = expand_vars_extended( var, NULL, cond_rc, exc); } if (name_has_dollar) { free(var); } if (xlen >= 0) { l2 += xlen - (k + 2); } i += k + 2; input[m] = ']'; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '*': if (input[i + 1] == '*') { n = 0; } else { n = input[i + 1] - '0' + 1; } if (arguments[n] != NULL) { l2 += strlen(arguments[n]) - 2; i++; } break; case '.': string = get_current_read_dir(); break; case 'w': case 'd': case 'x': case 'y': l2 += 16; i++; break; case 'c': case 'r': case 'n': if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { switch(input[i + 1]) { case 'c': if (fw->class.res_class && fw->class.res_class[0]) { string = fw->class. res_class; } break; case 'r': if (fw->class.res_name && fw->class.res_name[0]) { string = fw->class. res_name; } break; case 'n': if (fw->name.name && fw->name.name[0]) { string = fw->name.name; } break; } } break; case 'v': if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { switch(input[i + 1]) { case 'v': if(fw->visible_name) { string = fw->visible_name; } break; } } if (Fvwm_VersionInfo) { l2 += strlen(Fvwm_VersionInfo) + 2; } break; } if (string) { for (k = 0; string[k] != 0; k++, l2++) { if (string[k] == '\'') { l2++; } } string = NULL; } } i++; } /* Actually create expanded string */ i = 0; out = safemalloc(l2 + 1); j = 0; while (i < l) { if (input[i] == '$' && (!ismod || !isalpha(input[i + 1]))) { switch (input[i + 1]) { case '[': /* extended variables */ if (addto) { /* Don't expand these in an 'AddToFunc' * command */ out[j++] = input[i]; break; } m = i + 2; var = &input[m]; xlevel = 1; name_has_dollar = False; while (m < l && xlevel && input[m]) { /* handle nested variables */ if (input[m] == ']') { xlevel--; } else if (input[m] == '[') { xlevel++; } else if (input[m] == '$') { name_has_dollar = True; } if (xlevel) { m++; } } if (input[m] == ']') { input[m] = 0; /* handle variable name */ k = strlen(var); if (name_has_dollar) { var = expand_vars( var, arguments, addto, ismod, cond_rc, exc); } xlen = expand_args_extended( var, arguments ? arguments[0] : NULL, &out[j]); if (xlen < 0) { xlen = expand_vars_extended( var, &out[j], cond_rc, exc); } if (name_has_dollar) { free(var); } input[m] = ']'; if (xlen >= 0) { j += xlen; i += k + 2; } else { /* copy the whole string in * square brackets */ for ( ; i <= m; i++, j++) { out[j] = input[i]; } i--; } } else { out[j++] = input[i]; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '*': if (input[i + 1] == '*') { n = 0; } else { n = input[i + 1] - '0' + 1; } if (arguments[n] != NULL) { for (k = 0; arguments[n][k]; k++) { out[j++] = arguments[n][k]; } i++; } else if (addto == 1) { out[j++] = '$'; } else { i++; } break; case '.': string = get_current_read_dir(); is_string = True; break; case 'w': if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { fvwm_msg(OLD, "expand_vars", "Use $[w.id] instead of $w"); sprintf(&out[j], "0x%x", (int)FW_W(fw)); } else { sprintf(&out[j], "$w"); } j += strlen(&out[j]); i++; break; case 'd': fvwm_msg(OLD, "expand_vars", "Use $[desk.n] instead of $d"); sprintf(&out[j], "%d", Scr.CurrentDesk); j += strlen(&out[j]); i++; break; case 'x': fvwm_msg(OLD, "expand_vars", "Use $[vp.x] instead of $x"); sprintf(&out[j], "%d", Scr.Vx); j += strlen(&out[j]); i++; break; case 'y': fvwm_msg(OLD, "expand_vars", "Use $[vp.y] instead of $y"); sprintf(&out[j], "%d", Scr.Vy); j += strlen(&out[j]); i++; break; case 'c': case 'r': case 'n': if (fw && !IS_EWMH_DESKTOP(FW_W(fw))) { switch(input[i + 1]) { case 'c': fvwm_msg(OLD, "expand_vars", "Use $[w.class] " "instead of $c"); if (fw->class.res_class && fw->class.res_class[0]) { string = fw->class. res_class; } break; case 'r': fvwm_msg(OLD, "expand_vars", "Use $[w.resource] " "instead of $r"); if (fw->class.res_name && fw->class.res_name[0]) { string = fw->class. res_name; } break; case 'n': fvwm_msg(OLD, "expand_vars", "Use $[w.name] " "instead of $n"); if (fw->name.name && fw->name.name[0]) { string = fw->name.name; } break; } } is_string = True; break; case 'v': fvwm_msg(OLD, "expand_vars", "Use $[version.line] instead of $v"); sprintf(&out[j], "%s", (Fvwm_VersionInfo) ? Fvwm_VersionInfo : ""); j += strlen(&out[j]); i++; break; case '$': out[j++] = '$'; i++; break; default: out[j++] = input[i]; break; } /* switch */ if (is_string && string) { j = QuoteString(&out[j], string) - out; string = NULL; is_string = False; i++; } else if (is_string) { out[j++] = '$'; is_string = False; } } /* if '$' */ else { out[j++] = input[i]; } i++; } out[j] = 0; return out; } fvwm-2.6.7/fvwm/functable.c0000644000175700017570000005726513001406607012546 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include "fvwm.h" #include "execcontext.h" #include "commands.h" #include "cursor.h" #include "functions.h" #include "misc.h" #include "functable.h" /* ---------------------------- local definitions -------------------------- */ /* The function names in the first field *must* be in lowercase or else the * function cannot be called. The func parameter of the macro is also used * for parsing by modules that rely on the old case of the commands. */ #define CMD_ENT(cmd, func, cmd_id, flags, cursor) \ { cmd, func, cmd_id, flags, cursor } /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* IMPORTANT: command description should not be longer than 53 characters. */ /* If you change func_table format, change also perllib/FVWM/create-commands */ /* The next line must be blank for modules to properly parse this file. */ const func_t func_table[] = { /* CMD_ENT("#", CMD_Comment, 0, 0, 0), */ /* # - Comment line (ignored) */ /* CMD_ENT("*", CMD_Asterisk, 0, 0, 0), */ /* * - Module configuration line (no space after asterisk) */ CMD_ENT("+", CMD_Plus, F_ADDMENU2, 0, 0), /* + - Continue the last AddToFunc, AddToMenu or AddToDecor */ CMD_ENT("addbuttonstyle", CMD_AddButtonStyle, F_ADD_BUTTON_STYLE, FUNC_DECOR, 0), /* - Add to a button style (see ButtonStyle) */ CMD_ENT("addtitlestyle", CMD_AddTitleStyle, F_ADD_TITLE_STYLE, FUNC_DECOR, 0), /* - Add to a title style (see TitleStyle) */ CMD_ENT("addtodecor", CMD_AddToDecor, F_ADD_DECOR, 0, 0), /* - Add a decor definition (will be obsolete) */ CMD_ENT("addtofunc", CMD_AddToFunc, F_ADDFUNC, FUNC_ADD_TO, 0), /* - Add a function definition */ CMD_ENT("addtomenu", CMD_AddToMenu, F_ADDMENU, 0, 0), /* - Add a menu definition */ CMD_ENT("all", CMD_All, F_ALL, 0, 0), /* - Operate on all windows matching the given condition */ CMD_ENT("animatedmove", CMD_AnimatedMove, F_ANIMATED_MOVE, FUNC_NEEDS_WINDOW, CRS_MOVE), /* - Like Move, but uses animation to move windows */ CMD_ENT("any", CMD_Any, F_ANY, 0, 0), /* - Operate if there is any window matching the condition */ CMD_ENT("beep", CMD_Beep, F_BEEP, 0, 0), /* - Produce a bell */ CMD_ENT("borderstyle", CMD_BorderStyle, F_BORDERSTYLE, FUNC_DECOR, 0), /* - Define a window border look (will be reworked) */ CMD_ENT("break", CMD_Break, F_BREAK, 0, 0), /* - Stop executing the current (but not parent) function */ CMD_ENT("bugopts", CMD_BugOpts, F_BUG_OPTS, 0, 0), /* - Set some application bug workarounds */ CMD_ENT("busycursor", CMD_BusyCursor, F_BUSY_CURSOR, 0, 0), /* - Show/don't show the wait cursor in certain operations */ CMD_ENT("buttonstate", CMD_ButtonState, F_BUTTON_STATE, 0, 0), /* - Disable some titlebar button states (not recommended) */ CMD_ENT("buttonstyle", CMD_ButtonStyle, F_BUTTON_STYLE, FUNC_DECOR, 0), /* - Define a window button look (will be reworked) */ CMD_ENT("changedecor", CMD_ChangeDecor, F_CHANGE_DECOR, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Attach decor to a window (will be obsolete) */ CMD_ENT("changemenustyle", CMD_ChangeMenuStyle, F_CHANGE_MENUSTYLE, 0, 0), /* - Attach menu style to a menu (see MenuStyle) */ CMD_ENT("cleanupcolorsets", CMD_CleanupColorsets, F_NOP, 0, 0), /* - Reset all used colorsets with the default gray colors */ CMD_ENT("clicktime", CMD_ClickTime, F_CLICK, 0, 0), /* - Set a time in milliseconds for click and double click */ CMD_ENT("close", CMD_Close, F_CLOSE, FUNC_NEEDS_WINDOW, CRS_DESTROY), /* - Try to Delete a window, if this fails, Destroy it */ CMD_ENT("colorlimit", CMD_ColorLimit, F_COLOR_LIMIT, 0, 0), /* - Set limit on colors used (obsolete) */ CMD_ENT("colormapfocus", CMD_ColormapFocus, F_COLORMAP_FOCUS, 0, 0), /* - Change the colormap behaviour for low-depth X servers */ CMD_ENT("colorset", CMD_Colorset, F_NOP, 0, 0), /* - Manage colors used like fg, bg, image bg, gradient bg */ CMD_ENT("copymenustyle", CMD_CopyMenuStyle, F_COPY_MENU_STYLE, 0, 0), /* - Copy the existing menu style to new or existing one */ CMD_ENT("current", CMD_Current, F_CURRENT, 0, 0), /* - Operate on the currently focused window */ CMD_ENT("cursormove", CMD_CursorMove, F_MOVECURSOR, 0, 0), /* - Move the cursor pointer non interactively */ CMD_ENT("cursorstyle", CMD_CursorStyle, F_CURSOR_STYLE, 0, 0), /* - Define different cursor pointer shapes and colors */ CMD_ENT("defaultcolors", CMD_DefaultColors, F_DFLT_COLORS, 0, 0), /* - Set colors for the feedback window (will be obsolete) */ CMD_ENT("defaultcolorset", CMD_DefaultColorset, F_DFLT_COLORSET, 0, 0), /* - Set colors for the Move/Resize feedback window */ CMD_ENT("defaultfont", CMD_DefaultFont, F_DFLT_FONT, 0, 0), /* - The default font to use (mainly for feedback window) */ CMD_ENT("defaulticon", CMD_DefaultIcon, F_DFLT_ICON, 0, 0), /* - The default icon to use for iconified windows */ CMD_ENT("defaultlayers", CMD_DefaultLayers, F_DFLT_LAYERS, 0, 0), /* - Set StaysOnBottom, StaysPut, StaysOnTop layer numbers */ CMD_ENT("delete", CMD_Delete, F_DELETE, FUNC_NEEDS_WINDOW, CRS_DESTROY), /* - Try to delete a window using the X delete protocol */ CMD_ENT("deschedule", CMD_Deschedule, F_DESCHEDULE, 0, 0), /* - Remove commands sheduled earlier using Schedule */ CMD_ENT("desk", CMD_Desk, F_GOTO_DESK, 0, 0), /* - (obsolete, use GotoDesk instead) */ CMD_ENT("desktopname", CMD_DesktopName, F_DESKTOP_NAME, 0, 0), /* - Define the desktop names used in WindowList, modules */ CMD_ENT("desktopsize", CMD_DesktopSize, F_SETDESK, 0, 0), /* - Set virtual desktop size in units of physical pages */ CMD_ENT("destroy", CMD_Destroy, F_DESTROY, FUNC_NEEDS_WINDOW, CRS_DESTROY), /* - Kill a window without any warning to an application */ CMD_ENT("destroydecor", CMD_DestroyDecor, F_DESTROY_DECOR, 0, 0), /* - Delete decor defined by AddToDecor (will be obsolete) */ CMD_ENT("destroyfunc", CMD_DestroyFunc, F_DESTROY_FUNCTION, 0, 0), /* - Delete function defined using AddToFunc */ CMD_ENT("destroymenu", CMD_DestroyMenu, F_DESTROY_MENU, 0, 0), /* - Delete menu defined using AddToMenu */ CMD_ENT("destroymenustyle", CMD_DestroyMenuStyle, F_DESTROY_MENUSTYLE, 0, 0), /* - Delete menu style defined using MenuStyle */ CMD_ENT("destroymoduleconfig", CMD_DestroyModuleConfig, F_DESTROY_MOD, 0, 0), /* - Delete matching module config lines defined using "*" */ CMD_ENT("destroystyle", CMD_DestroyStyle, F_DESTROY_STYLE, 0, 0), /* - Delete style defined using Style */ CMD_ENT("destroywindowstyle", CMD_DestroyWindowStyle, F_DESTROY_WINDOW_STYLE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Delete style defined using WindowStyle */ CMD_ENT("direction", CMD_Direction, F_DIRECTION, 0, 0), /* - Operate on the next window in the specified direction */ CMD_ENT("echo", CMD_Echo, F_ECHO, 0, 0), /* - Print message to stderr, mainly for debugging */ CMD_ENT("echofuncdefinition", CMD_EchoFuncDefinition, F_ECHO_FUNC_DEFINITION, 0, 0), /* - Print the definion of a function */ CMD_ENT("edgecommand", CMD_EdgeCommand, F_EDGE_COMMAND, 0, 0), /* - Bind one or another screen edge to an fvwm action */ CMD_ENT("edgeleavecommand", CMD_EdgeLeaveCommand, F_EDGE_LEAVE_COMMAND, 0, 0), /* - Bind one or another screen edge to an fvwm action */ CMD_ENT("edgeresistance", CMD_EdgeResistance, F_EDGE_RES, 0, 0), /* - Control viewport scrolling and window move over edge */ CMD_ENT("edgescroll", CMD_EdgeScroll, F_EDGE_SCROLL, 0, 0), /* - Control how much of the viewport is scrolled if any */ CMD_ENT("edgethickness", CMD_EdgeThickness, F_NOP, 0, 0), /* - Control how closely to edge to run command/scrolling */ CMD_ENT("emulate", CMD_Emulate, F_EMULATE, 0, 0), /* - Only used to position the position/size window */ CMD_ENT("escapefunc", CMD_EscapeFunc, F_ESCAPE_FUNC, 0, 0), /* - Abort a wait or ModuleSynchonous command */ CMD_ENT("ewmhbasestruts", CMD_EwmhBaseStruts, F_EWMH_BASE_STRUTS, 0, 0), /* - Define restricted areas of the screen */ CMD_ENT("ewmhnumberofdesktops", CMD_EwmhNumberOfDesktops, F_EWMH_NUMBER_OF_DESKTOPS, 0, 0), /* - For ewmh pager, define number of desktops */ CMD_ENT("exec", CMD_Exec, F_EXEC, 0, 0), /* - Execute an external command */ CMD_ENT("execuseshell", CMD_ExecUseShell, F_EXEC_SETUP, 0, 0), /* - The shell to use to execute an external command */ CMD_ENT("fakeclick", CMD_FakeClick, F_FAKE_CLICK, 0, 0), /* - Generate a mouse click */ CMD_ENT("fakekeypress", CMD_FakeKeypress, F_FAKE_KEYPRESS, 0, 0), /* - Send a keyboard event to a window */ CMD_ENT("flipfocus", CMD_FlipFocus, F_FLIP_FOCUS, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Focus a window without rotating windowlist order */ CMD_ENT("focus", CMD_Focus, F_FOCUS, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Give focus to a window */ CMD_ENT("focusstyle", CMD_FocusStyle, F_FOCUSSTYLE, 0, 0), /* - Configure focus and raise policy for windows */ CMD_ENT("function", CMD_Function, F_FUNCTION, 0, 0), /* Function - Execute a user defined function, see AddToFunc */ CMD_ENT("globalopts", CMD_GlobalOpts, F_GLOBAL_OPTS, 0, 0), /* - (obsolete, use corresponding Style * instead) */ CMD_ENT("gotodesk", CMD_GotoDesk, F_GOTO_DESK, 0, 0), /* - Switch viewport to another desk same page */ CMD_ENT("gotodeskandpage", CMD_GotoDeskAndPage, F_GOTO_DESK, 0, 0), /* - Switch viewport to another desk and page */ CMD_ENT("gotopage", CMD_GotoPage, F_GOTO_PAGE, 0, 0), /* - Switch viewport to another page same desk */ CMD_ENT("hidegeometrywindow", CMD_HideGeometryWindow, F_HIDEGEOMWINDOW, 0, 0), /* - Hide/show the position/size window */ CMD_ENT("hilightcolor", CMD_HilightColor, F_HICOLOR, 0, 0), /* - (obsolete, use Style * HighlightFore/Back) */ CMD_ENT("hilightcolorset", CMD_HilightColorset, F_HICOLORSET, 0, 0), /* - (obsolete, use Style * HighlightColorset) */ CMD_ENT("iconfont", CMD_IconFont, F_ICONFONT, 0, 0), /* - (obsolete, use Style * IconFont) */ CMD_ENT("iconify", CMD_Iconify, F_ICONIFY, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Change iconification status of a window (minimize) */ CMD_ENT("iconpath", CMD_IconPath, F_ICON_PATH, 0, 0), /* - (obsolete, use ImagePath instead) */ CMD_ENT("ignoremodifiers", CMD_IgnoreModifiers, F_IGNORE_MODIFIERS, 0, 0), /* - Modifiers to ignore on mouse and key bindings */ CMD_ENT("imagepath", CMD_ImagePath, F_IMAGE_PATH, 0, 0), /* - Directories to search for images */ CMD_ENT("infostoreadd", CMD_InfoStoreAdd, F_INFOSTOREADD, 0, 0), /* - Adds an entry (key/value pairs) to the infostore */ CMD_ENT("infostoreclear", CMD_InfoStoreClear, F_INFOSTORECLEAR, 0, 0), /* - Clears all entries from the infostore */ CMD_ENT("infostoreremove", CMD_InfoStoreRemove, F_INFOSTOREREMOVE, 0, 0), /* - Removes an entry from the infostore */ CMD_ENT(PRE_KEEPRC, CMD_KeepRc, F_KEEPRC, 0, 0), /* KeepRc - Do not modify the previous command return code */ CMD_ENT("key", CMD_Key, F_KEY, 0, 0), /* - Bind or unbind a key to an fvwm action */ CMD_ENT("killmodule", CMD_KillModule, F_KILL_MODULE, 0, 0), /* - Stops an fvwm module */ CMD_ENT("layer", CMD_Layer, F_LAYER, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Change the layer of a window */ CMD_ENT("localepath", CMD_LocalePath, F_LOCALE_PATH, 0, 0), /* - Directories/domains to search for locale data */ CMD_ENT("lower", CMD_Lower, F_LOWER, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Lower a window within a layer */ CMD_ENT("maximize", CMD_Maximize, F_MAXIMIZE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Toggle maximal-size status of a window */ CMD_ENT("menu", CMD_Menu, F_STAYSUP, 0, 0), /* - Display (post) a menu */ CMD_ENT("menustyle", CMD_MenuStyle, F_MENUSTYLE, 0, 0), /* - Control appearance and behavior of a menu */ CMD_ENT("module", CMD_Module, F_MODULE, 0, 0), /* - Invoke an fvwm module */ CMD_ENT("modulelistenonly", CMD_ModuleListenOnly, F_MODULE_LISTEN_ONLY, 0, 0), /* - Invoke an fvwm module */ CMD_ENT("modulepath", CMD_ModulePath, F_MODULE_PATH, 0, 0), /* - Modify the directories to search for an fvwm module */ CMD_ENT("modulesynchronous", CMD_ModuleSynchronous, F_MODULE_SYNC, 0, 0), /* - Invoke an fvwm module synchronously */ CMD_ENT("moduletimeout", CMD_ModuleTimeout, F_NOP, 0, 0), /* - Set timeout value for response from module */ CMD_ENT("mouse", CMD_Mouse, F_MOUSE, 0, 0), /* - Bind or unbind a mouse button press to an fvwm action */ CMD_ENT("move", CMD_Move, F_MOVE, FUNC_NEEDS_WINDOW, CRS_MOVE), /* - Move a window */ CMD_ENT("movethreshold", CMD_MoveThreshold, F_MOVE_THRESHOLD, 0, 0), /* - Set number of pixels in a click and a hold vs. a drag */ CMD_ENT("movetodesk", CMD_MoveToDesk, F_MOVE_TO_DESK, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Move a window to another desk same page */ CMD_ENT("movetopage", CMD_MoveToPage, F_MOVE_TO_PAGE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Move a window to another page same desk */ CMD_ENT("movetoscreen", CMD_MoveToScreen, F_MOVE_TO_SCREEN, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Move a window to another Xinerama screen */ CMD_ENT("next", CMD_Next, F_NEXT, 0, 0), /* - Operate on the next window matching conditions */ CMD_ENT("none", CMD_None, F_NONE, 0, 0), /* - Perform command if no window matches conditions */ CMD_ENT("nop", CMD_Nop, F_NOP, FUNC_DONT_REPEAT, 0), /* - Do nothing (used internally) */ CMD_ENT("nowindow", CMD_NoWindow, F_NOP, 0, 0), /* - Prefix that runs a command without a window context */ CMD_ENT("opaquemovesize", CMD_OpaqueMoveSize, F_OPAQUE, 0, 0), /* - Set maximum size window fvwm should move opaquely */ CMD_ENT("pick", CMD_Pick, F_PICK, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Prefix to force a window context, prompted if needed */ CMD_ENT("piperead", CMD_PipeRead, F_READ, 0, 0), /* - Exec system command interpret output as fvwm commands */ CMD_ENT("pixmappath", CMD_PixmapPath, F_PIXMAP_PATH, 0, 0), /* - (obsolete, use ImagePath instead) */ CMD_ENT("placeagain", CMD_PlaceAgain, F_PLACEAGAIN, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Replace a window using initial window placement logic */ CMD_ENT("pointerkey", CMD_PointerKey, F_POINTERKEY, 0, 0), /* - Bind an action to a key based on pointer not focus */ CMD_ENT("pointerwindow", CMD_PointerWindow, F_POINTERWINDOW, 0, 0), /* - Operate on window under pointer if it meets conditions */ CMD_ENT("popup", CMD_Popup, F_POPUP, 0, 0), /* - Display (pop-up) a menu, see also Menu */ CMD_ENT("prev", CMD_Prev, F_PREV, 0, 0), /* - Operate on the precious window matching conditions */ CMD_ENT("printinfo", CMD_PrintInfo, F_PRINTINFO, 0, 0), /* - Print information about the state of fvwm */ CMD_ENT("propertychange", CMD_PropertyChange, F_NOP, 0, 0), /* - Internal, used for inter-module communication */ CMD_ENT("quit", CMD_Quit, F_QUIT, 0, 0), /* - Exit fvwm */ CMD_ENT("quitscreen", CMD_QuitScreen, F_QUIT_SCREEN, 0, 0), /* - Stop managing the specified screen */ CMD_ENT("quitsession", CMD_QuitSession, F_QUIT_SESSION, 0, 0), /* - Ask session manager to shut down itself and fvwm */ CMD_ENT("raise", CMD_Raise, F_RAISE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Raise a window in a layer */ CMD_ENT("raiselower", CMD_RaiseLower, F_RAISELOWER, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Alternately raise or lower a window in a layer */ CMD_ENT("read", CMD_Read, F_READ, 0, 0), /* - Read fvwm commands from a file */ CMD_ENT("readwritecolors", CMD_ReadWriteColors, F_NOP, 0, 0), /* - Used for colorset speed hacks (will be removed?) */ CMD_ENT("recapture", CMD_Recapture, F_RECAPTURE, 0, 0), /* - Reapply styles to all windows (will be obsolete) */ CMD_ENT("recapturewindow", CMD_RecaptureWindow, F_RECAPTURE_WINDOW, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Reapply styles to one window (will be obsolete) */ CMD_ENT("refresh", CMD_Refresh, F_REFRESH, 0, 0), /* - Cause all windows to redraw themselves */ CMD_ENT("refreshwindow", CMD_RefreshWindow, F_REFRESH, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Cause one window to redraw itself */ CMD_ENT(PRE_REPEAT, CMD_Repeat, F_REPEAT, FUNC_DONT_REPEAT, 0), /* - Repeat (very unreliably) the last command, don't use */ CMD_ENT("resize", CMD_Resize, F_RESIZE, FUNC_NEEDS_WINDOW, CRS_RESIZE), /* - Cause a window to be resized */ CMD_ENT("resizemaximize", CMD_ResizeMaximize, F_RESIZE_MAXIMIZE, FUNC_NEEDS_WINDOW, CRS_RESIZE), /* - Resize a window and mark window as maximized */ CMD_ENT("resizemove", CMD_ResizeMove, F_RESIZEMOVE, FUNC_NEEDS_WINDOW, CRS_RESIZE), /* - Resize and move in one operation */ CMD_ENT("resizemovemaximize", CMD_ResizeMoveMaximize, F_RESIZEMOVE_MAXIMIZE, FUNC_NEEDS_WINDOW, CRS_RESIZE), /* - Resize and move in one operation and mark maximized */ CMD_ENT("restacktransients", CMD_RestackTransients, F_RESTACKTRANSIENTS, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Regroup the window transients in the stack */ CMD_ENT("restart", CMD_Restart, F_RESTART, 0, 0), /* - Restart itself or replace with another window manager */ CMD_ENT("savequitsession", CMD_SaveQuitSession, F_SAVE_QUIT_SESSION, 0, 0), /* - Cause session manager to save and shutdown fvwm */ CMD_ENT("savesession", CMD_SaveSession, F_SAVE_SESSION, 0, 0), /* - Cause session manager to save the session */ CMD_ENT("scanforwindow", CMD_ScanForWindow, F_SCANFORWINDOW, 0, 0), /* - Operate on the matching window in the given direction */ CMD_ENT("schedule", CMD_Schedule, F_SCHEDULE, 0, 0), /* - Run an fvwm command after a delay */ CMD_ENT("scroll", CMD_Scroll, F_SCROLL, 0, 0), /* - Scroll the desktop viewport */ CMD_ENT("send_configinfo", CMD_Send_ConfigInfo, F_CONFIG_LIST, FUNC_DONT_REPEAT, 0), /* - Internal, used for module communication */ CMD_ENT("send_reply", CMD_Send_Reply, F_SEND_REPLY, FUNC_DONT_REPEAT, 0), /* - Internal, used for module communication */ CMD_ENT("send_windowlist", CMD_Send_WindowList, F_SEND_WINDOW_LIST, FUNC_DONT_REPEAT, 0), /* - Internal, used for module communication */ CMD_ENT("sendtomodule", CMD_SendToModule, F_SEND_STRING, FUNC_DONT_REPEAT, 0), /* - Send a string (action) to a module */ CMD_ENT("set_mask", CMD_set_mask, F_SET_MASK, FUNC_DONT_REPEAT, 0), /* - Internal, used for module communication */ CMD_ENT("set_nograb_mask", CMD_set_nograb_mask, F_SET_NOGRAB_MASK, FUNC_DONT_REPEAT, 0), /* - Internal, used for module communication */ CMD_ENT("set_sync_mask", CMD_set_sync_mask, F_SET_SYNC_MASK, FUNC_DONT_REPEAT, 0), /* - Internal, used for module communication */ CMD_ENT("setanimation", CMD_SetAnimation, F_SET_ANIMATION, 0, 0), /* - Control animated moves and menus */ CMD_ENT("setenv", CMD_SetEnv, F_SETENV, 0, 0), /* - Set an environment variable */ CMD_ENT(PRE_SILENT, CMD_Silent, F_SILENT, 0, 0), /* Silent - Suppress errors on command, avoid window selection */ CMD_ENT("snapattraction", CMD_SnapAttraction, F_SNAP_ATT, 0, 0), /* - Control attraction of windows during move */ CMD_ENT("snapgrid", CMD_SnapGrid, F_SNAP_GRID, 0, 0), /* - Control grid used with SnapAttraction */ CMD_ENT("state", CMD_State, F_STATE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Control user defined window states */ CMD_ENT("stick", CMD_Stick, F_STICK, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Change window stickyness */ CMD_ENT("stickacrossdesks", CMD_StickAcrossDesks, F_STICKACROSSDESKS, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Change window stickyness on a desk basis */ CMD_ENT("stickacrosspages", CMD_StickAcrossPages, F_STICKACROSSPAGES, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Change window stickyness on a page basis */ #ifdef HAVE_STROKE CMD_ENT("stroke", CMD_Stroke, F_STROKE, 0, 0), /* - Bind a stroke to an fvwm action */ CMD_ENT("strokefunc", CMD_StrokeFunc, F_STROKE_FUNC, 0, 0), /* - Record stroke and execute corresponding stroke action */ #endif /* HAVE_STROKE */ CMD_ENT("style", CMD_Style, F_STYLE, 0, 0), /* - Set attributes of windows that match a pattern */ CMD_ENT("tearmenuoff", CMD_TearMenuOff, F_TEARMENUOFF, 0, 0), /* TearMenuOff - Convert a menu to a window, for use in menu items */ CMD_ENT("test", CMD_Test, F_TEST_, 0, 0), /* - Execute command if conditions are met */ CMD_ENT("testrc", CMD_TestRc, F_TESTRC, 0, 0), /* - Conditional switch (may be changed) */ CMD_ENT("thiswindow", CMD_ThisWindow, F_THISWINDOW, 0, 0), /* - Operate on the context window if it meets conditions */ CMD_ENT("title", CMD_Title, F_TITLE, 0, 0), /* Title - Insert title into a menu */ CMD_ENT("titlestyle", CMD_TitleStyle, F_TITLESTYLE, FUNC_DECOR, 0), /* - Control window title */ CMD_ENT("unsetenv", CMD_UnsetEnv, F_SETENV, 0, 0), /* - Remove an environment variable */ CMD_ENT("updatedecor", CMD_UpdateDecor, F_UPDATE_DECOR, 0, 0), /* - Update window decor (obsolete and not needed anymore) */ CMD_ENT("updatestyles", CMD_UpdateStyles, F_UPDATE_STYLES, 0, 0), /* - Cause styles to update while still in a function */ CMD_ENT("wait", CMD_Wait, F_WAIT, 0, 0), /* - Pause until a matching window appears */ CMD_ENT("warptowindow", CMD_WarpToWindow, F_WARP, FUNC_NEEDS_WINDOW | FUNC_ALLOW_UNMANAGED, CRS_SELECT), /* - Warp the pointer to a window */ CMD_ENT("windowfont", CMD_WindowFont, F_WINDOWFONT, 0, 0), /* - (obsolete, use Style * Font) */ CMD_ENT("windowid", CMD_WindowId, F_WINDOWID, 0, 0), /* - Execute command for window matching the windowid */ CMD_ENT("windowlist", CMD_WindowList, F_WINDOWLIST, 0, 0), /* - Display the window list as a menu to select a window */ CMD_ENT("windowshade", CMD_WindowShade, F_WINDOW_SHADE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Shade/unshade a window */ CMD_ENT("windowshadeanimate", CMD_WindowShadeAnimate, F_SHADE_ANIMATE, 0, 0), /* - (obsolete, use Style * WindowShadeSteps) */ CMD_ENT("windowstyle", CMD_WindowStyle, F_WINDOW_STYLE, FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Set styles on the selected window */ CMD_ENT("xinerama", CMD_Xinerama, F_XINERAMA, 0, 0), /* - Control Xinerama support */ CMD_ENT("xineramaprimaryscreen", CMD_XineramaPrimaryScreen, F_XINERAMAPRIMARYSCREEN, 0, 0), /* - Identify Xinerama primary screen */ CMD_ENT("xineramasls", CMD_XineramaSls, F_XINERAMASLS, 0, 0), /* - Control single logical screen support */ CMD_ENT("xineramaslsscreens", CMD_XineramaSlsScreens, F_XINERAMASLSSCREENS, 0, 0), /* - Configure layout for single logical screen */ CMD_ENT("xineramaslssize", CMD_XineramaSlsSize, F_XINERAMASLSSIZE, 0, 0), /* - Configure layout for single logical screen sizes */ CMD_ENT("xorpixmap", CMD_XorPixmap, F_XOR, 0, 0), /* - Use a pixmap for move/resize rubber-band */ CMD_ENT("xorvalue", CMD_XorValue, F_XOR, 0, 0), /* - Change bits used for move/resize rubber-band */ CMD_ENT("xsync", CMD_XSync, F_XSYNC, 0, 0), /* - For debugging, send all pending requests to X server */ CMD_ENT("xsynchronize", CMD_XSynchronize, F_XSYNCHRONIZE, 0, 0), /* - For debugging, cause all X requests to be synchronous */ { "", 0, 0, 0, 0 } }; fvwm-2.6.7/fvwm/ewmh.c0000644000175700017570000013322113001406607011526 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ /* 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 */ /* * An implementation of the Extended Window Manager Hints specification * http://freedesktop.org/Standards/wm-spec/ * * Not Implemented (draft 1.3 - 2004-05-01): * * _NET_DESKTOP_LAYOUT (not useful for us) * _NET_VIRTUAL_ROOTS (not useful at all for us) * _NET_SHOWING_DESKTOP should be implemented * _NET_REQUEST_FRAME_EXTENTS may be implemented * * Some _NET_WINDOW_TYPE are simply ignored: * _NET_WM_WINDOW_TYPE_SPLASH * _NET_WM_WINDOW_TYPE_UTILITIES * _KDE_NET_WM_WINDOW_TYPE_OVERRIDE (deprecated) * * _NET_WM_STATE_DEMANDS_ATTENTION state * * _NET_WM_STRUT_PARTIAL should be implemented * * _NET_WM_USER_TIME can be used to decide if we give the focus to a newly * mapped window * * The kill huge process protocol: _NET_WM_PID and _NET_WM_PING * * _NET_WM_HANDLED_ICONS (what to do? Nothing?) * * "Source indication in requests" is not used but can be useful with some * "ignore styles" * * Problems: * - _NET_WM_WINDOW_TYPE_TOOLBAR is interpreted in a different way * in GNOME (the spec) and in KDE 2/3.0 (~ simple dock?). * */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "fvwm.h" #include "execcontext.h" #include "functions.h" #include "commands.h" #include "misc.h" #include "screen.h" #include "update.h" #include "stack.h" #include "style.h" #include "externs.h" #include "decorations.h" #include "ewmh.h" #include "ewmh_intern.h" #include "geometry.h" #include "window_flags.h" typedef struct kst_item { Window w; struct kst_item *next; } KstItem; Atom XA_UTF8_STRING = None; KstItem *ewmh_KstWinList = NULL; /* * Default */ ewmhInfo ewmhc = { 4, /* NumberOfDesktops */ 0, /* MaxDesktops limit the number of desktops*/ 0, /* CurrentNumberOfDesktops */ False, /* NeedsToCheckDesk */ {0, 0, 0, 0}, /* BaseStrut */ }; /* * The ewmh atoms lists */ #define ENTRY(name, type, func) {name, None, type, func} /* WARNING: lists must be in "name" alphabetic order! */ /* EWMH_ATOM_LIST_CLIENT_ROOT * net atoms that can be send (Client Message) by a client and do not * need a window to operate */ ewmh_atom ewmh_atom_client_root[] = { ENTRY("_NET_CURRENT_DESKTOP", XA_CARDINAL, ewmh_CurrentDesktop), ENTRY("_NET_DESKTOP_GEOMETRY", XA_CARDINAL, ewmh_DesktopGeometry), ENTRY("_NET_DESKTOP_NAMES", None, None), ENTRY("_NET_DESKTOP_VIEWPORT", XA_CARDINAL, ewmh_DesktopViewPort), ENTRY("_NET_NUMBER_OF_DESKTOPS", XA_CARDINAL, ewmh_NumberOfDesktops), {NULL,0,0,0} }; /* EWMH_ATOM_LIST_CLIENT_WIN * net atoms that can be send (Client Message) by a client and do need * window to operate */ ewmh_atom ewmh_atom_client_win[] = { ENTRY("_NET_ACTIVE_WINDOW", XA_WINDOW, ewmh_ActiveWindow), ENTRY("_NET_CLOSE_WINDOW", XA_WINDOW, ewmh_CloseWindow), ENTRY("_NET_MOVERESIZE_WINDOW", XA_WINDOW, ewmh_MoveResizeWindow), ENTRY("_NET_RESTACK_WINDOW", XA_WINDOW, ewmh_RestackWindow), ENTRY("_NET_WM_DESKTOP", XA_CARDINAL, ewmh_WMDesktop), ENTRY("_NET_WM_MOVERESIZE", XA_WINDOW, ewmh_MoveResize), ENTRY("_NET_WM_STATE", XA_ATOM, ewmh_WMState), {NULL,0,0,0} }; /* EWMH_ATOM_LIST_WM_STATE * the different wm state, a client can ask to add, remove or toggle * via a _NET_WM_STATE Client message. fvwm must maintain these states * too */ ewmh_atom ewmh_atom_wm_state[] = { ENTRY( "_NET_WM_STATE_ABOVE", XA_ATOM, ewmh_WMStateStaysOnTop), ENTRY( "_NET_WM_STATE_BELOW", XA_ATOM, ewmh_WMStateStaysOnBottom), ENTRY( "_NET_WM_STATE_FULLSCREEN", XA_ATOM, ewmh_WMStateFullScreen), ENTRY("_NET_WM_STATE_HIDDEN", XA_ATOM, ewmh_WMStateHidden), ENTRY( "_NET_WM_STATE_MAXIMIZED_HORIZ", XA_ATOM, ewmh_WMStateMaxHoriz), ENTRY( "_NET_WM_STATE_MAXIMIZED_HORZ", XA_ATOM, ewmh_WMStateMaxHoriz), ENTRY("_NET_WM_STATE_MAXIMIZED_VERT", XA_ATOM, ewmh_WMStateMaxVert), ENTRY("_NET_WM_STATE_MODAL", XA_ATOM, ewmh_WMStateModal), ENTRY("_NET_WM_STATE_SHADED", XA_ATOM, ewmh_WMStateShaded), ENTRY( "_NET_WM_STATE_SKIP_PAGER", XA_ATOM, ewmh_WMStateSkipPager), ENTRY( "_NET_WM_STATE_SKIP_TASKBAR", XA_ATOM, ewmh_WMStateSkipTaskBar), ENTRY( "_NET_WM_STATE_STAYS_ON_TOP", XA_ATOM, ewmh_WMStateStaysOnTop), ENTRY("_NET_WM_STATE_STICKY", XA_ATOM, ewmh_WMStateSticky), {NULL,0,0,0} }; #define EWMH_NUMBER_OF_STATE sizeof(ewmh_atom_wm_state)/sizeof(ewmh_atom) - 1 /* EWMH ATOM_LIST_ALLOWED_ACTIONS: atom for _NET_WM_ALLOWED_ACTIONS */ ewmh_atom ewmh_atom_allowed_actions[] = { ENTRY("_NET_WM_ACTION_CHANGE_DESKTOP", XA_ATOM, ewmh_AllowsYes), ENTRY("_NET_WM_ACTION_CLOSE", XA_ATOM, ewmh_AllowsClose), ENTRY("_NET_WM_ACTION_FULLSCREEN", XA_ATOM, ewmh_AllowsFullScreen), ENTRY("_NET_WM_ACTION_MAXIMIZE_HORZ", XA_ATOM, ewmh_AllowsMaximize), ENTRY("_NET_WM_ACTION_MAXIMIZE_VERT", XA_ATOM, ewmh_AllowsMaximize), ENTRY("_NET_WM_ACTION_MINIMIZE", XA_ATOM, ewmh_AllowsMinimize), ENTRY("_NET_WM_ACTION_MOVE", XA_ATOM, ewmh_AllowsMove), ENTRY("_NET_WM_ACTION_RESIZE", XA_ATOM, ewmh_AllowsResize), ENTRY("_NET_WM_ACTION_SHADE", XA_ATOM, ewmh_AllowsYes), ENTRY("_NET_WM_ACTION_STICK", XA_ATOM, ewmh_AllowsYes), {NULL,0,0,0} }; #define EWMH_NUMBER_OF_ALLOWED_ACTIONS \ sizeof(ewmh_atom_allowed_actions)/sizeof(ewmh_atom) - 1 /* EWMH ATOM_LIST_WINDOW_TYPE: the various window type */ ewmh_atom ewmh_atom_window_type[] = { ENTRY("_NET_WM_WINDOW_TYPE_DESKTOP", XA_ATOM, ewmh_HandleDesktop), ENTRY("_NET_WM_WINDOW_TYPE_DIALOG", XA_ATOM, ewmh_HandleDialog), ENTRY("_NET_WM_WINDOW_TYPE_DOCK", XA_ATOM, ewmh_HandleDock), ENTRY("_NET_WM_WINDOW_TYPE_MENU", XA_ATOM, ewmh_HandleMenu), ENTRY("_NET_WM_WINDOW_TYPE_NORMAL", XA_ATOM, ewmh_HandleNormal), ENTRY("_NET_WM_WINDOW_TYPE_TOOLBAR", XA_ATOM, ewmh_HandleToolBar), ENTRY("_NET_WM_WINDOW_TYPE_NOTIFICATION", XA_ATOM, ewmh_HandleNotification), {NULL,0,0,0} }; /* EWMH ATOM_LIST_FIXED_PROPERTY * property that have a window at startup and which should not change */ ewmh_atom ewmh_atom_fixed_property[] = { ENTRY("_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", XA_WINDOW, None), ENTRY("_NET_WM_HANDLED_ICON", XA_ATOM, None), ENTRY("_NET_WM_PID", XA_ATOM, None), ENTRY("_NET_WM_WINDOW_TYPE", XA_ATOM, None), {NULL,0,0,0} }; /* EWMH ATOM_LIST_PROPERTY_NOTIFY * properties of a window which is updated by the window via a PropertyNotify * event */ ewmh_atom ewmh_atom_property_notify[] = { ENTRY("_NET_WM_ICON", XA_CARDINAL, ewmh_WMIcon), ENTRY("_NET_WM_ICON_GEOMETRY", XA_CARDINAL, ewmh_WMIconGeometry), ENTRY("_NET_WM_ICON_NAME", None, EWMH_WMIconName), ENTRY("_NET_WM_NAME", None, EWMH_WMName), ENTRY("_NET_WM_STRUT", XA_CARDINAL, ewmh_WMStrut), {NULL,0,0,0} }; /* EWMH_ATOM_LIST_FVWM_ROOT: root atom that should be maintained by fvwm only */ ewmh_atom ewmh_atom_fvwm_root[] = { ENTRY("_KDE_NET_SYSTEM_TRAY_WINDOWS", XA_WINDOW, None), ENTRY("_NET_CLIENT_LIST", XA_WINDOW, None), ENTRY("_NET_CLIENT_LIST_STACKING", XA_WINDOW, None), ENTRY("_NET_SUPPORTED", XA_ATOM, None), ENTRY("_NET_SUPPORTING_WM_CHECK", XA_WINDOW, None), ENTRY("_NET_VIRTUAL_ROOTS", XA_WINDOW, None), ENTRY("_NET_WORKAREA", XA_CARDINAL, None), {NULL,0,0,0} }; /* EWMH_ATOM_LIST_FVWM_WIN: window atom that should be maintained by fvwm * only */ ewmh_atom ewmh_atom_fvwm_win[] = { ENTRY("_KDE_NET_WM_FRAME_STRUT", XA_CARDINAL, None), ENTRY("_NET_FRAME_EXTENTS", XA_CARDINAL, None), ENTRY("_NET_WM_ALLOWED_ACTIONS", XA_ATOM, None), ENTRY("_NET_WM_ICON_VISIBLE_NAME", None, None), ENTRY("_NET_WM_VISIBLE_NAME", None, None), {NULL,0,0,0} }; #define NUMBER_OF_ATOM_LISTS 9 #define L_ENTRY(x,y) {x,y,sizeof(y)/sizeof(ewmh_atom)} ewmh_atom_list atom_list[] = { L_ENTRY(EWMH_ATOM_LIST_CLIENT_ROOT, ewmh_atom_client_root), L_ENTRY(EWMH_ATOM_LIST_CLIENT_WIN, ewmh_atom_client_win), L_ENTRY(EWMH_ATOM_LIST_WM_STATE, ewmh_atom_wm_state), L_ENTRY(EWMH_ATOM_LIST_ALLOWED_ACTIONS, ewmh_atom_allowed_actions), L_ENTRY(EWMH_ATOM_LIST_WINDOW_TYPE, ewmh_atom_window_type), L_ENTRY(EWMH_ATOM_LIST_FIXED_PROPERTY, ewmh_atom_fixed_property), L_ENTRY(EWMH_ATOM_LIST_PROPERTY_NOTIFY, ewmh_atom_property_notify), L_ENTRY(EWMH_ATOM_LIST_FVWM_ROOT, ewmh_atom_fvwm_root), L_ENTRY(EWMH_ATOM_LIST_FVWM_WIN, ewmh_atom_fvwm_win), L_ENTRY(EWMH_ATOM_LIST_END, NULL) }; /* * Atoms utilities */ static int compare(const void *a, const void *b) { return (strcmp((char *)a, ((ewmh_atom *)b)->name)); } static ewmh_atom *get_ewmh_atom_by_name( const char *atom_name, ewmh_atom_list_name list_name) { ewmh_atom *a = NULL; Bool done = 0; int i = 0; while(!done && atom_list[i].name != EWMH_ATOM_LIST_END) { if (atom_list[i].name == list_name || list_name == EWMH_ATOM_LIST_ALL) { a = (ewmh_atom *)bsearch( atom_name, atom_list[i].list, atom_list[i].size - 1, sizeof(ewmh_atom), compare); if (a != NULL || list_name != EWMH_ATOM_LIST_ALL) { done = 1; } } i++; } return a; } ewmh_atom *ewmh_GetEwmhAtomByAtom(Atom atom, ewmh_atom_list_name list_name) { int i = 0; for (i = 0; atom_list[i].name != EWMH_ATOM_LIST_END; i++) { ewmh_atom *item; if (list_name != atom_list[i].name && list_name != EWMH_ATOM_LIST_ALL) { continue; } for (item = atom_list[i].list; item->name != NULL; item++) { if (atom == item->atom) { return item; } } if (list_name == atom_list[i].name) { return NULL; } } return NULL; } static int atom_size(int format) { if (format == 32) { return sizeof(long); } else { return (format >> 3); } } void ewmh_ChangeProperty( Window w, const char *atom_name, ewmh_atom_list_name list, unsigned char *data, int length) { ewmh_atom *a; int format = 32; if ((a = get_ewmh_atom_by_name(atom_name, list)) != NULL) { int asize; int free_data = 0; if (a->atom_type == XA_UTF8_STRING) { format = 8; } asize = atom_size(format); if ( format == 32 && asize * 8 != format && strcmp(atom_name, "_NET_WM_ICON") == 0) { long *datacopy = (long*)safemalloc(asize * length); int i; for (i = 0; i < length; i++) { datacopy[i] = ((CARD32 *)data)[i]; } data = (unsigned char*)datacopy; free_data = 1; } XChangeProperty( dpy, w, a->atom, a->atom_type , format, PropModeReplace, data, length); if (free_data) { free(data); } } return; } void ewmh_DeleteProperty( Window w, const char *atom_name, ewmh_atom_list_name list) { ewmh_atom *a; if ((a = get_ewmh_atom_by_name(atom_name, list)) != NULL) { XDeleteProperty(dpy, w, a->atom); } return; } static void *atom_get(Window win, Atom to_get, Atom type, int *size) { unsigned char *retval; Atom type_ret; unsigned long bytes_after, num_ret; long length; int format_ret; void *data; int ok; retval = NULL; length = 0x7fffffff; ok = XGetWindowProperty( dpy, win, to_get, 0L, length, False, type, &type_ret, &format_ret, &num_ret, &bytes_after, &retval); if ((ok == Success) && (retval) && (num_ret > 0) && (format_ret > 0)) { int asize; asize = atom_size(format_ret); data = safemalloc(num_ret * asize); if (format_ret == 32 && asize * 8 != format_ret) { int i; for (i = 0; i < num_ret; i++) { ((CARD32 *)data)[i] = ((long *)retval)[i]; } } else { if (data) { memcpy(data, retval, num_ret * asize); } } XFree(retval); *size = num_ret * (format_ret >> 3); return data; } if (retval) { XFree(retval); } return NULL; } void *ewmh_AtomGetByName( Window win, const char *atom_name, ewmh_atom_list_name list, int *size) { ewmh_atom *a; void *data = NULL; if ((a = get_ewmh_atom_by_name(atom_name, list)) != NULL) { data = atom_get(win, a->atom, a->atom_type, size); } return data; } /* * client_root: here the client is fvwm */ static int check_desk(void) { int d = -1; FvwmWindow *fw; for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { if (!IS_STICKY_ACROSS_DESKS(fw)) { d = max(d, fw->Desk); } } return d; } void EWMH_SetCurrentDesktop(void) { long val; val = Scr.CurrentDesk; if (val < 0 || (val >= ewmhc.MaxDesktops && ewmhc.MaxDesktops != 0)) { return; } if (val >= ewmhc.CurrentNumberOfDesktops || (ewmhc.NumberOfDesktops != ewmhc.CurrentNumberOfDesktops && val < ewmhc.CurrentNumberOfDesktops)) { EWMH_SetNumberOfDesktops(); } ewmh_ChangeProperty(Scr.Root,"_NET_CURRENT_DESKTOP", EWMH_ATOM_LIST_CLIENT_ROOT, (unsigned char *)&val, 1); return; } void EWMH_SetNumberOfDesktops(void) { long val; if (ewmhc.CurrentNumberOfDesktops < ewmhc.NumberOfDesktops) { ewmhc.CurrentNumberOfDesktops = ewmhc.NumberOfDesktops; } if (ewmhc.CurrentNumberOfDesktops > ewmhc.NumberOfDesktops || ewmhc.NeedsToCheckDesk) { int d = check_desk(); ewmhc.NeedsToCheckDesk = False; if (d >= ewmhc.MaxDesktops && ewmhc.MaxDesktops != 0) d = 0; ewmhc.CurrentNumberOfDesktops = max(ewmhc.NumberOfDesktops, d+1); } if (Scr.CurrentDesk >= ewmhc.CurrentNumberOfDesktops && (Scr.CurrentDesk < ewmhc.MaxDesktops || ewmhc.MaxDesktops == 0)) { ewmhc.CurrentNumberOfDesktops = Scr.CurrentDesk + 1; } val = (long)ewmhc.CurrentNumberOfDesktops; ewmh_ChangeProperty(Scr.Root, "_NET_NUMBER_OF_DESKTOPS", EWMH_ATOM_LIST_CLIENT_ROOT, (unsigned char *)&val, 1); ewmh_SetWorkArea(); return; } void EWMH_SetDesktopViewPort(void) { long val[256][2]; /* no more than 256 desktops */ int i = 0; while(i < ewmhc.NumberOfDesktops && i < 256) { val[i][0] = Scr.Vx; val[i][1] = Scr.Vy; i++; } ewmh_ChangeProperty( Scr.Root, "_NET_DESKTOP_VIEWPORT", EWMH_ATOM_LIST_CLIENT_ROOT, (unsigned char *)&val, i*2); return; } void EWMH_SetDesktopGeometry(void) { long val[2]; val[0] = Scr.VxMax + Scr.MyDisplayWidth; val[1] = Scr.VyMax + Scr.MyDisplayHeight; ewmh_ChangeProperty( Scr.Root,"_NET_DESKTOP_GEOMETRY", EWMH_ATOM_LIST_CLIENT_ROOT, (unsigned char *)&val, 2); return; } /* * client_win: here the client is fvwm */ void EWMH_SetActiveWindow(Window w) { ewmh_ChangeProperty( Scr.Root, "_NET_ACTIVE_WINDOW", EWMH_ATOM_LIST_CLIENT_WIN, (unsigned char *)&w, 1); return; } void EWMH_SetWMDesktop(FvwmWindow *fw) { long desk = fw->Desk; if (IS_STICKY_ACROSS_DESKS(fw)) { desk = (unsigned long)-1; } else if (desk >= ewmhc.CurrentNumberOfDesktops) { ewmhc.NeedsToCheckDesk = True; EWMH_SetNumberOfDesktops(); } ewmh_ChangeProperty( FW_W(fw), "_NET_WM_DESKTOP", EWMH_ATOM_LIST_CLIENT_WIN, (unsigned char *)&desk, 1); return; } /* * fvwm must maintain the _NET_WM_STATE */ void EWMH_SetWMState(FvwmWindow *fw, Bool do_restore) { Atom wm_state[EWMH_NUMBER_OF_STATE]; int i = 0; ewmh_atom *list = ewmh_atom_wm_state; while(list->name != NULL) { if (list->action(fw, NULL, NULL, do_restore)) { wm_state[i++] = list->atom; } list++; } if (i > 0) { ewmh_ChangeProperty( FW_W(fw), "_NET_WM_STATE", EWMH_ATOM_LIST_CLIENT_WIN, (unsigned char *)wm_state, i); } else { ewmh_DeleteProperty( FW_W(fw), "_NET_WM_STATE", EWMH_ATOM_LIST_CLIENT_WIN); } return; } /* * fvwm_root */ /*** kde system tray ***/ /* #define DEBUG_KST */ static void add_kst_item(Window w) { KstItem *t,**prev; t = ewmh_KstWinList; prev = &ewmh_KstWinList; while(t != NULL) { prev = &(t->next); t = t->next; } *prev = (KstItem *)safemalloc(sizeof(KstItem)); (*prev)->w = w; (*prev)->next = NULL; return; } static void delete_kst_item(Window w) { KstItem *t,**prev; t = ewmh_KstWinList; prev = &ewmh_KstWinList; while((t!= NULL)&&(t->w != w)) { prev = &(t->next); t = t->next; } if (t == NULL) { return; } if(prev != NULL) { *prev = t->next; } free(t); return; } static void set_kde_sys_tray(void) { Window *wins = NULL; KstItem *t; int i = 0, nbr = 0; t = ewmh_KstWinList; while(t != NULL) { nbr++; t = t->next; } if (nbr > 0) { wins = (Window *)safemalloc(sizeof(Window) * nbr); } t = ewmh_KstWinList; #ifdef DEBUG_KST fprintf(stderr,"ADD_TO_KST: "); #endif while (t != NULL) { #ifdef DEBUG_KST fprintf(stderr,"0x%lx ",t->w); #endif wins[i++] = t->w; t = t->next; } #ifdef DEBUG_KST fprintf(stderr,"\n"); #endif ewmh_ChangeProperty(Scr.Root,"_KDE_NET_SYSTEM_TRAY_WINDOWS", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)wins,i); if (wins != NULL) { free(wins); } return; } void ewmh_AddToKdeSysTray(FvwmWindow *fw) { int size = 0; CARD32 *val; KstItem *t; val = ewmh_AtomGetByName( FW_W(fw), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", EWMH_ATOM_LIST_FIXED_PROPERTY, &size); if (val == NULL) { return; } free(val); t = ewmh_KstWinList; while(t != NULL && t->w != FW_W(fw)) t = t->next; if (t != NULL) { return; /* already in the list */ } add_kst_item(FW_W(fw)); set_kde_sys_tray(); return; } #if 0 /* not used at present time */ void ewmh_FreeKdeSysTray(void) { KstItem *t; t = ewmh_KstWinList; while(t != NULL) { XSelectInput(dpy, t->w, NoEventMask); delete_kst_item(t->w); t = ewmh_KstWinList; } set_kde_sys_tray(); return; } #endif int EWMH_IsKdeSysTrayWindow(Window w) { KstItem *t; t = ewmh_KstWinList; while(t != NULL && t->w != w) { t = t->next; } if (t == NULL) { return 0; } #ifdef DEBUG_KST fprintf(stderr,"IsKdeSysTrayWindow: 0x%lx\n", w); #endif return 1; } void EWMH_ManageKdeSysTray(Window w, int type) { KstItem *t; t = ewmh_KstWinList; while(t != NULL && t->w != w) { t = t->next; } if (t == NULL) { return; } switch(type) { case UnmapNotify: #ifdef DEBUG_KST fprintf(stderr,"KST_UNMAP: 0x%lx\n", w); #endif XSelectInput(dpy, w, StructureNotifyMask); XFlush(dpy); break; case DestroyNotify: #ifdef DEBUG_KST fprintf(stderr,"KST_DESTROY: 0x%lx\n", w); #endif XSelectInput(dpy, t->w, NoEventMask); XFlush(dpy); delete_kst_item(w); set_kde_sys_tray(); break; case ReparentNotify: #ifdef DEBUG_KST fprintf(stderr,"KST_Reparent: 0x%lx\n", w); #endif XSelectInput(dpy, w, StructureNotifyMask); XFlush(dpy); break; default: #ifdef DEBUG_KST fprintf(stderr,"KST_NO: 0x%lx\n", w); #endif break; } return; } /**** Client lists ****/ void EWMH_SetClientList(void) { Window *wl = NULL; FvwmWindow *fw; int nbr = 0; int i = 0; for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { nbr++; } if (nbr != 0) { wl = (Window *)safemalloc(sizeof(Window) * nbr); for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { wl[i++] = FW_W(fw); } } ewmh_ChangeProperty( Scr.Root,"_NET_CLIENT_LIST", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)wl, nbr); if (wl != NULL) { free (wl); } return; } void EWMH_SetClientListStacking(void) { Window *wl = NULL; FvwmWindow *fw; int nbr = 0; int i = 0; for ( fw = Scr.FvwmRoot.stack_next; fw != &Scr.FvwmRoot; fw = fw->stack_next) { nbr++; } i = nbr-1; if (nbr != 0) { wl = (Window *)safemalloc(sizeof(Window) * nbr); for ( fw = Scr.FvwmRoot.stack_next; fw != &Scr.FvwmRoot; fw = fw->stack_next) { wl[i--] = FW_W(fw); } } ewmh_ChangeProperty( Scr.Root,"_NET_CLIENT_LIST_STACKING", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)wl, nbr); if (wl != NULL) { free (wl); } return; } /**** Working Area stuff ****/ /**** At present time we support only sticky windows with strut ****/ void ewmh_SetWorkArea(void) { long val[256][4]; /* no more than 256 desktops */ int i = 0; while(i < ewmhc.NumberOfDesktops && i < 256) { val[i][0] = Scr.Desktops->ewmh_working_area.x; val[i][1] = Scr.Desktops->ewmh_working_area.y; val[i][2] = Scr.Desktops->ewmh_working_area.width; val[i][3] = Scr.Desktops->ewmh_working_area.height; i++; } ewmh_ChangeProperty( Scr.Root, "_NET_WORKAREA", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)&val, i*4); return; } void ewmh_ComputeAndSetWorkArea(void) { int left = ewmhc.BaseStrut.left; int right = ewmhc.BaseStrut.right; int top = ewmhc.BaseStrut.top; int bottom = ewmhc.BaseStrut.bottom; int x,y,width,height; FvwmWindow *fw; for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { if ( DO_EWMH_IGNORE_STRUT_HINTS(fw) || !IS_STICKY_ACROSS_PAGES(fw)) { continue; } left = max(left, fw->strut.left); right = max(right, fw->strut.right); top = max(top, fw->strut.top); bottom = max(bottom, fw->strut.bottom); } x = left; y = top; width = Scr.MyDisplayWidth - (left + right); height = Scr.MyDisplayHeight - (top + bottom); if ( Scr.Desktops->ewmh_working_area.x != x || Scr.Desktops->ewmh_working_area.y != y || Scr.Desktops->ewmh_working_area.width != width || Scr.Desktops->ewmh_working_area.height != height) { Scr.Desktops->ewmh_working_area.x = x; Scr.Desktops->ewmh_working_area.y = y; Scr.Desktops->ewmh_working_area.width = width; Scr.Desktops->ewmh_working_area.height = height; ewmh_SetWorkArea(); } return; } void ewmh_HandleDynamicWorkArea(void) { int dyn_left = ewmhc.BaseStrut.left; int dyn_right = ewmhc.BaseStrut.right; int dyn_top = ewmhc.BaseStrut.top; int dyn_bottom = ewmhc.BaseStrut.bottom; int x,y,width,height; FvwmWindow *fw; for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { if ( DO_EWMH_IGNORE_STRUT_HINTS(fw) || !IS_STICKY_ACROSS_PAGES(fw)) { continue; } dyn_left = max(dyn_left, fw->dyn_strut.left); dyn_right = max(dyn_right, fw->dyn_strut.right); dyn_top = max(dyn_top, fw->dyn_strut.top); dyn_bottom = max(dyn_bottom, fw->dyn_strut.bottom); } x = dyn_left; y = dyn_top; width = Scr.MyDisplayWidth - (dyn_left + dyn_right); height = Scr.MyDisplayHeight - (dyn_top + dyn_bottom); if ( Scr.Desktops->ewmh_dyn_working_area.x != x || Scr.Desktops->ewmh_dyn_working_area.y != y || Scr.Desktops->ewmh_dyn_working_area.width != width || Scr.Desktops->ewmh_dyn_working_area.height != height) { Scr.Desktops->ewmh_dyn_working_area.x = x; Scr.Desktops->ewmh_dyn_working_area.y = y; Scr.Desktops->ewmh_dyn_working_area.width = width; Scr.Desktops->ewmh_dyn_working_area.height = height; /* here we may update the maximized window ...etc */ } return; } void EWMH_UpdateWorkArea(void) { ewmh_ComputeAndSetWorkArea(); ewmh_HandleDynamicWorkArea(); return; } void EWMH_GetWorkAreaIntersection( FvwmWindow *fw, int *x, int *y, int *w, int *h, int type) { int nx,ny,nw,nh; int area_x = Scr.Desktops->ewmh_working_area.x; int area_y = Scr.Desktops->ewmh_working_area.y; int area_w = Scr.Desktops->ewmh_working_area.width; int area_h = Scr.Desktops->ewmh_working_area.height; Bool is_dynamic = False; switch(type) { case EWMH_IGNORE_WORKING_AREA: return; case EWMH_USE_WORKING_AREA: break; case EWMH_USE_DYNAMIC_WORKING_AREA: is_dynamic = True; break; default: break; } if (is_dynamic) { area_x = Scr.Desktops->ewmh_dyn_working_area.x; area_y = Scr.Desktops->ewmh_dyn_working_area.y; area_w = Scr.Desktops->ewmh_dyn_working_area.width; area_h = Scr.Desktops->ewmh_dyn_working_area.height; } nx = max(*x, area_x); ny = max(*y, area_y); nw = min(*x + *w, area_x + area_w) - nx; nh = min(*y + *h, area_y + area_h) - ny; *x = nx; *y = ny; *w = nw; *h = nh; return; } static float get_intersection( int x11, int y11, int x12, int y12, int x21, int y21, int x22, int y22, Bool use_percent) { float ret = 0; int xl, xr, yt, yb; if (x11 < x22 && x12 > x21 && y11 < y22 && y12 > y21) { xl = max(x11, x21); xr = min(x12, x22); yt = max(y11, y21); yb = min(y12, y22); ret = (xr - xl) * (yb - yt); } if (use_percent && (x22 - x21) * (y22 - y21) != 0 && (x12 - x11) * (y12 - y11) != 0) { ret = 100 * max(ret / ((x22 - x21) * (y22 - y21)), ret / ((x12 - x11) * (y12 - y11))); } return ret; } static float ewmh_GetStrutIntersection( int x11, int y11, int x12, int y12, int left, int right, int top, int bottom, Bool use_percent) { float ret = 0; int x21, y21, x22, y22; /* left */ x21 = 0; y21 = 0; x22 = left; y22 = Scr.MyDisplayHeight; ret += get_intersection( x11, y11, x12, y12, x21, y21, x22, y22, use_percent); /* right */ x21 = Scr.MyDisplayWidth - right; y21 = 0; x22 = Scr.MyDisplayWidth; y22 = Scr.MyDisplayHeight; ret += get_intersection( x11, y11, x12, y12, x21, y21, x22, y22, use_percent); /* top */ x21 = 0; y21 = 0; x22 = Scr.MyDisplayWidth; y22 = top; ret += get_intersection( x11, y11, x12, y12, x21, y21, x22, y22, use_percent); /* bottom */ x21 = 0; y21 = Scr.MyDisplayHeight - bottom; x22 = Scr.MyDisplayWidth; y22 = Scr.MyDisplayHeight; ret += get_intersection( x11, y11, x12, y12, x21, y21, x22, y22, use_percent); return ret; } float EWMH_GetBaseStrutIntersection( int x11, int y11, int x12, int y12, Bool use_percent) { return ewmh_GetStrutIntersection( x11, y11, x12, y12, ewmhc.BaseStrut.left, ewmhc.BaseStrut.right, ewmhc.BaseStrut.top, ewmhc.BaseStrut.bottom, use_percent); } float EWMH_GetStrutIntersection( int x11, int y11, int x12, int y12, Bool use_percent) { int left, right, top, bottom; left = Scr.Desktops->ewmh_working_area.x; right = Scr.MyDisplayWidth - (Scr.Desktops->ewmh_working_area.x + Scr.Desktops->ewmh_working_area.width); top = Scr.Desktops->ewmh_working_area.y; bottom = Scr.MyDisplayHeight - (Scr.Desktops->ewmh_working_area.y + Scr.Desktops->ewmh_working_area.height); return ewmh_GetStrutIntersection( x11, y11, x12, y12, left, right, top, bottom, use_percent); } /* * fvwm_win */ void EWMH_SetFrameStrut(FvwmWindow *fw) { long val[4]; size_borders b; if (EWMH_IsKdeSysTrayWindow(FW_W(fw))) { /* Fixed position of tray window in kicker */ return; } get_window_borders(fw, &b); /* left */ val[0] = b.top_left.width; /* right */ val[1] = b.bottom_right.width; /* top */ val[2] = b.top_left.height; /* bottom */ val[3] = b.bottom_right.height; ewmh_ChangeProperty( FW_W(fw), "_KDE_NET_WM_FRAME_STRUT", EWMH_ATOM_LIST_FVWM_WIN, (unsigned char *)&val, 4); ewmh_ChangeProperty( FW_W(fw), "_NET_FRAME_EXTENTS", EWMH_ATOM_LIST_FVWM_WIN, (unsigned char *)&val, 4); return; } /* * allowed actions */ Bool ewmh_AllowsYes( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { return True; } Bool ewmh_AllowsClose( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { return is_function_allowed( F_CLOSE, NULL, fw, RQORIG_PROGRAM_US, False); } Bool ewmh_AllowsFullScreen( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if ( !is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False) || !is_function_allowed( F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False) || !is_function_allowed( F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, True)) { return False; } return True; } Bool ewmh_AllowsMinimize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { return is_function_allowed(F_ICONIFY, NULL, fw, RQORIG_PROGRAM_US, False); } Bool ewmh_AllowsMaximize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { return is_function_allowed(F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False); } Bool ewmh_AllowsMove( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { return is_function_allowed(F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False); } Bool ewmh_AllowsResize( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { return is_function_allowed(F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, False); } void EWMH_SetAllowedActions(FvwmWindow *fw) { Atom wm_actions[EWMH_NUMBER_OF_ALLOWED_ACTIONS]; int i = 0; ewmh_atom *list = ewmh_atom_allowed_actions; while(list->name != NULL) { if (list->action(fw, NULL, NULL, 0)) wm_actions[i++] = list->atom; list++; } if (i > 0) { ewmh_ChangeProperty( FW_W(fw), "_NET_WM_ALLOWED_ACTIONS", EWMH_ATOM_LIST_FVWM_WIN, (unsigned char *)wm_actions, i); } else { ewmh_DeleteProperty( FW_W(fw), "_NET_WM_ALLOWED_ACTIONS", EWMH_ATOM_LIST_FVWM_WIN); } return; } /* * Window types */ int ewmh_HandleDesktop( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { if (Scr.EwmhDesktop != NULL && FW_W(Scr.EwmhDesktop) != FW_W(fw)) { fvwm_msg( WARN,"ewmh_HandleDesktop", "A Desktop application (0x%lx) already runs! This" " can cause problems\n", FW_W(Scr.EwmhDesktop)); /* what to do ? */ } fw->ewmh_window_type = EWMH_WINDOW_TYPE_DESKTOP_ID; Scr.EwmhDesktop = fw; SSET_LAYER(*style, 0); style->flags.use_layer = 1; style->flag_mask.use_layer = 1; style->change_mask.use_layer = 1; S_SET_IS_STICKY_ACROSS_PAGES(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*style), 1); S_SET_IS_FIXED(SCF(*style), 1); S_SET_IS_FIXED(SCM(*style), 1); S_SET_IS_FIXED(SCC(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCF(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCM(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCF(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCM(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCC(*style), 1); S_SET_IS_UNICONIFIABLE(SCF(*style), 1); S_SET_IS_UNICONIFIABLE(SCM(*style), 1); S_SET_IS_UNICONIFIABLE(SCC(*style), 1); S_SET_IS_UNMAXIMIZABLE(SCF(*style), 1); S_SET_IS_UNMAXIMIZABLE(SCM(*style), 1); S_SET_IS_UNMAXIMIZABLE(SCC(*style), 1); /* No border */ SSET_BORDER_WIDTH(*style, 0); style->flags.has_border_width = 1; style->flag_mask.has_border_width = 1; style->change_mask.has_border_width = 1; SSET_HANDLE_WIDTH(*style, 0); style->flags.has_handle_width = 1; style->flag_mask.has_handle_width = 1; style->change_mask.has_handle_width = 1; /* no title */ style->flags.has_no_title = 1; style->flag_mask.has_no_title = 1; style->change_mask.has_no_title = 1; /* ClickToFocus, I do not think we should use NeverFocus */ FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCF(*style)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCM(*style)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCC(*style)), 1); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCF(*style)), 1); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCM(*style)), 1); FPS_GRAB_FOCUS(S_FOCUS_POLICY(SCC(*style)), 1); /* ClickToFocusPassesClick */ FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCF(*style)), 1); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCM(*style)), 1); FPS_PASS_FOCUS_CLICK(S_FOCUS_POLICY(SCC(*style)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCF(*style)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCM(*style)), 1); FPS_PASS_RAISE_CLICK(S_FOCUS_POLICY(SCC(*style)), 1); /* not useful */ FPS_RAISE_FOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCF(*style)), 0); FPS_RAISE_FOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCM(*style)), 1); FPS_RAISE_FOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCC(*style)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCF(*style)), 0); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCM(*style)), 1); FPS_RAISE_UNFOCUSED_CLIENT_CLICK(S_FOCUS_POLICY(SCC(*style)), 1); FPS_RAISE_FOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCF(*style)), 0); FPS_RAISE_FOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCM(*style)), 1); FPS_RAISE_FOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCC(*style)), 1); FPS_RAISE_UNFOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCF(*style)), 0); FPS_RAISE_UNFOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCM(*style)), 1); FPS_RAISE_UNFOCUSED_DECOR_CLICK(S_FOCUS_POLICY(SCC(*style)), 1); return 1; } int ewmh_HandleDialog( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { fw->ewmh_window_type = EWMH_WINDOW_TYPE_DIALOG_ID; return 0; } int ewmh_HandleDock( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { fw->ewmh_window_type = EWMH_WINDOW_TYPE_DOCK_ID; S_SET_IS_STICKY_ACROSS_PAGES(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCF(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCM(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCF(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCM(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCC(*style), 1); S_SET_IS_UNICONIFIABLE(SCF(*style), 1); S_SET_IS_UNICONIFIABLE(SCM(*style), 1); S_SET_IS_UNICONIFIABLE(SCC(*style), 1); S_SET_IS_UNMAXIMIZABLE(SCF(*style), 1); S_SET_IS_UNMAXIMIZABLE(SCM(*style), 1); S_SET_IS_UNMAXIMIZABLE(SCC(*style), 1); if (fw->ewmh_hint_layer == -1) { fw->ewmh_hint_layer = Scr.TopLayer; if (DO_EWMH_USE_STACKING_HINTS(style)) { SSET_LAYER(*style, Scr.TopLayer); style->flags.use_layer = 1; style->flag_mask.use_layer = 1; style->change_mask.use_layer = 1; } else if (!style->change_mask.use_layer) { SSET_LAYER(*style, Scr.DefaultLayer); style->flags.use_layer = 1; style->flag_mask.use_layer = 1; style->change_mask.use_layer = 1; } } /* no title ? MWM hints should be used by the app but ... */ return 1; } int ewmh_HandleMenu( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { fw->ewmh_window_type = EWMH_WINDOW_TYPE_MENU_ID; /* tear off menu */ S_SET_DO_WINDOW_LIST_SKIP(SCF(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCM(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCF(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCM(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCC(*style), 1); /* NeverFocus */ FPS_LENIENT(S_FOCUS_POLICY(SCF(*style)), 0); FPS_LENIENT(S_FOCUS_POLICY(SCM(*style)), 1); FPS_LENIENT(S_FOCUS_POLICY(SCC(*style)), 1); FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCF(*style)), 0); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCF(*style)), 0); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCF(*style)), 0); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCF(*style)), 0); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCF(*style)), 0); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCF(*style)), 0); FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCM(*style)), 1); FPS_FOCUS_ENTER(S_FOCUS_POLICY(SCC(*style)), 1); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCM(*style)), 1); FPS_UNFOCUS_LEAVE(S_FOCUS_POLICY(SCC(*style)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCM(*style)), 1); FPS_FOCUS_CLICK_CLIENT(S_FOCUS_POLICY(SCC(*style)), 1); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCM(*style)), 1); FPS_FOCUS_CLICK_DECOR(S_FOCUS_POLICY(SCC(*style)), 1); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCM(*style)), 1); FPS_FOCUS_CLICK_ICON(S_FOCUS_POLICY(SCC(*style)), 1); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCM(*style)), 1); FPS_FOCUS_BY_FUNCTION(S_FOCUS_POLICY(SCC(*style)), 1); return 1; } int ewmh_HandleNormal( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { fw->ewmh_window_type = EWMH_WINDOW_TYPE_NORMAL_ID; return 0; } int ewmh_HandleToolBar( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { fw->ewmh_window_type = EWMH_WINDOW_TYPE_TOOLBAR_ID; /* this ok for KDE 2 (and 3??) but I do not think that a toolbar should be sticky */ S_SET_IS_STICKY_ACROSS_PAGES(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_PAGES(SCC(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCF(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCM(*style), 1); S_SET_IS_STICKY_ACROSS_DESKS(SCC(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCF(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCM(*style), 1); S_SET_DO_WINDOW_LIST_SKIP(SCC(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCF(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCM(*style), 1); S_SET_DO_CIRCULATE_SKIP(SCC(*style), 1); /* no title ? MWM hints should be used by the app but ... */ return 1; } int ewmh_HandleNotification( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { /* fw->ewmh_window_type is generally used by FvwmIdent, but for this * EWMH type it is not used. Reporting on unmanaged windows with * FvwmIdent won't work anyway as the click to the window is eaten. * So although setting this is a NOP, it might be useful for things in * the future. */ fw->ewmh_window_type = EWMH_WINDOW_TYPE_NOTIFICATION_ID; style->flags.is_unmanaged = 1; style->flag_mask.is_unmanaged = 1; style->change_mask.is_unmanaged = 1; return 1; } void ewmh_HandleWindowType(FvwmWindow *fw, window_style *style) { CARD32 *val; unsigned int nitems; ewmh_atom *list = ewmh_atom_window_type; int size = 0; int i = 0; Bool found = False; fw->ewmh_window_type = 0; if (DO_EWMH_IGNORE_WINDOW_TYPE(style)) { return; } val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_WINDOW_TYPE", EWMH_ATOM_LIST_FIXED_PROPERTY, &size); if (val == NULL) { return; } /* we support only one window type: the first that we support */ nitems = size / sizeof(CARD32); while(i < nitems && !found) { list = ewmh_atom_window_type; while(list->name != NULL && !found) { if (list->atom == val[i]) { list->action(fw, NULL, style, 0); found = True; } list++; } i++; } free(val); return; } /* * a workaround for ksmserver exit windows */ static int ksmserver_workarround(FvwmWindow *fw) { if (fw->name.name != NULL && fw->class.res_name != NULL && fw->icon_name.name != NULL && fw->class.res_class != NULL && strcmp(fw->name.name, "ksmserver") == 0 && strcmp(fw->class.res_class, "ksmserver") == 0 && strcmp(fw->icon_name.name, "ksmserver") == 0 && strcmp(fw->class.res_name, "unnamed") == 0) { int layer = 0; if (IS_TRANSIENT(fw)) { layer = Scr.TopLayer + 2; } else { layer = Scr.TopLayer + 1; } new_layer(fw, layer); return 1; } return 0; } /* * Window Initialisation / Destroy */ void EWMH_GetStyle(FvwmWindow *fw, window_style *style) { if (style->change_mask.use_layer) { fw->ewmh_normal_layer = SGET_LAYER(*style); } else if (fw->ewmh_normal_layer == 0) { fw->ewmh_normal_layer = Scr.DefaultLayer; } ewmh_WMState(fw, NULL, style, 0); ewmh_WMDesktop(fw, NULL, style, 0); /* the window type override the state hint */ ewmh_HandleWindowType(fw, style); return; } static void ewmh_check_wm_pid(FvwmWindow *fw) { int size = 0; CARD32 *val; fw->ewmh_window_type = 0; val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_PID", EWMH_ATOM_LIST_FIXED_PROPERTY, &size); if (val != NULL) { free(val); SET_HAS_EWMH_WM_PID(fw, 1); if (CR_MOTION_METHOD(fw) == CR_MOTION_METHOD_AUTO) { SET_CR_MOTION_METHOD(fw, CR_MOTION_METHOD_USE_GRAV); SET_CR_MOTION_METHOD_DETECTED(fw, 1); } } return; } /* see also EWMH_WMName and EWMH_WMIconName in add_window */ void EWMH_WindowInit(FvwmWindow *fw) { /*EWMH_DLOG("Init window 0x%lx",FW_W(fw));*/ EWMH_SetWMState(fw, False); EWMH_SetWMDesktop(fw); EWMH_SetAllowedActions(fw); ewmh_WMStrut(fw, NULL, NULL, 0); ewmh_WMIconGeometry(fw, NULL, NULL, 0); ewmh_AddToKdeSysTray(fw); EWMH_SetFrameStrut(fw); if (IS_EWMH_DESKTOP(FW_W(fw))) { return; } if (ksmserver_workarround(fw)) { return; } ewmh_WMIcon(fw, NULL, NULL, 0); ewmh_check_wm_pid(fw); /*EWMH_DLOG("window 0x%lx initialised",FW_W(fw));*/ return; } /* unmap or reparent: restore state */ void EWMH_RestoreInitialStates(FvwmWindow *fw, int event_type) { EWMH_SetWMState(fw, True); if (HAS_EWMH_INIT_WM_DESKTOP(fw) == EWMH_STATE_HAS_HINT) { ewmh_ChangeProperty( FW_W(fw), "_NET_WM_DESKTOP", EWMH_ATOM_LIST_CLIENT_WIN, (unsigned char *)&(fw->ewmh_hint_desktop), 1); } else { ewmh_DeleteProperty( FW_W(fw), "_NET_WM_DESKTOP", EWMH_ATOM_LIST_CLIENT_WIN); } if (HAS_EWMH_WM_ICON_HINT(fw) == EWMH_FVWM_ICON) { EWMH_DeleteWmIcon(fw, True, True); } return; } /* a window are going to be destroyed (in the add_window.c destroy_window * sens) */ void EWMH_DestroyWindow(FvwmWindow *fw) { if (IS_EWMH_DESKTOP(FW_W(fw))) { Scr.EwmhDesktop = NULL; } if (fw->Desk >= ewmhc.NumberOfDesktops) { ewmhc.NeedsToCheckDesk = True; } return; } /* a window has been destroyed (unmap/reparent/destroy) */ void EWMH_WindowDestroyed(void) { EWMH_SetClientList(); EWMH_SetClientListStacking(); if (ewmhc.NeedsToCheckDesk) { EWMH_SetNumberOfDesktops(); } ewmh_ComputeAndSetWorkArea(); ewmh_HandleDynamicWorkArea(); return; } /* * Init Stuff */ static int set_all_atom_in_list(ewmh_atom *list) { int l = 0; while(list->name != NULL) { list->atom = XInternAtom(dpy,list->name,False); if (list->atom_type == None) { list->atom_type = XA_UTF8_STRING; } l++; list++; } return l; } static void set_net_supported(int l) { Atom *supported; int i, k = 0; supported = (Atom *)safemalloc(l*sizeof(Atom)); for(i=0; i < NUMBER_OF_ATOM_LISTS; i++) { ewmh_atom *list = atom_list[i].list; while(list->name != NULL) { supported[k++] = list->atom; list++; } } ewmh_ChangeProperty( Scr.Root, "_NET_SUPPORTED", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)supported, k); free(supported); return; } static void clean_up(void) { ewmh_ChangeProperty( Scr.Root,"_KDE_NET_SYSTEM_TRAY_WINDOWS", EWMH_ATOM_LIST_FVWM_ROOT, NULL, 0); return; } void EWMH_Init(void) { int i; int supported_count = 0; long val; XTextProperty text; unsigned char utf_name[4]; char *names[1]; XClassHint classhints; /* initialisation of all the atoms */ XA_UTF8_STRING = XInternAtom(dpy,"UTF8_STRING",False); for(i=0; i < NUMBER_OF_ATOM_LISTS; i++) { supported_count += set_all_atom_in_list(atom_list[i].list); } /* the laws that we respect */ set_net_supported(supported_count); /* use the Scr.NoFocusWin as the WM_CHECK window */ val = Scr.NoFocusWin; ewmh_ChangeProperty( Scr.Root, "_NET_SUPPORTING_WM_CHECK", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)&val, 1); ewmh_ChangeProperty( Scr.NoFocusWin, "_NET_SUPPORTING_WM_CHECK", EWMH_ATOM_LIST_FVWM_ROOT, (unsigned char *)&val, 1); names[0] = "fvwm"; classhints.res_name= "fvwm"; classhints.res_class= "FVWM"; XSetClassHint(dpy, Scr.NoFocusWin, &classhints); if (XStringListToTextProperty(names, 1, &text)) { XSetWMName(dpy, Scr.NoFocusWin, &text); XFree(text.value); } /* FVWM in UTF8 */ utf_name[0] = 0x46; utf_name[1] = 0x56; utf_name[2] = 0x57; utf_name[3] = 0x4D; ewmh_ChangeProperty( Scr.NoFocusWin, "_NET_WM_NAME", EWMH_ATOM_LIST_PROPERTY_NOTIFY, (unsigned char *)&utf_name, 4); clean_up(); EWMH_SetDesktopNames(); EWMH_SetCurrentDesktop(); EWMH_SetNumberOfDesktops(); EWMH_SetDesktopViewPort(); EWMH_SetDesktopGeometry(); EWMH_SetClientList(); EWMH_SetClientListStacking(); ewmh_ComputeAndSetWorkArea(); return; } /* * Exit Stuff */ void EWMH_ExitStuff(void) { FvwmWindow *fw; for (fw = Scr.FvwmRoot.next; fw != NULL; fw = fw->next) { EWMH_RestoreInitialStates(fw, 0); } return; } #ifdef EWMH_DEBUG void EWMH_DLOG(char *msg, ...) { va_list args; clock_t time_val, time_taken; static clock_t start_time = 0; static clock_t prev_time = 0; struct tms not_used_tms; char buffer[200]; /* oversized */ time_t mytime; struct tm *t_ptr; time(&mytime); t_ptr = localtime(&mytime); if (start_time == 0) { /* get clock ticks */ prev_time = start_time = (unsigned int)times(¬_used_tms); } /* get clock ticks */ time_val = (unsigned int)times(¬_used_tms); time_taken = time_val - prev_time; prev_time = time_val; sprintf( buffer, "%.2d:%.2d:%.2d %6ld", t_ptr->tm_hour, t_ptr->tm_min, t_ptr->tm_sec, time_taken); fprintf(stderr, "EWMH DEBUG: "); va_start(args,msg); vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, "\n"); fprintf(stderr, " [time]: %s\n",buffer); return; } #endif void EWMH_fullscreen(FvwmWindow *fw) { fscreen_scr_arg fscr; rectangle scr_g; size_borders b; int page_x; int page_y; char cmd[128] = "\0"; /* maximize with ResizeMoveMaximize */ if ( !is_function_allowed( F_MAXIMIZE, NULL, fw, RQORIG_PROGRAM_US, False) || !is_function_allowed( F_MOVE, NULL, fw, RQORIG_PROGRAM_US, False) || !is_function_allowed( F_RESIZE, NULL, fw, RQORIG_PROGRAM_US, True)) { return; } fw->fullscreen.was_maximized = 0; fw->fullscreen.is_shaded = 0; /* Keep the old geometry when restoring from fullscreen. */ memcpy(&fw->fullscreen.g, &fw->g, sizeof(struct window_g)); if (IS_MAXIMIZED(fw)) fw->fullscreen.was_maximized = 1; if (IS_ICONIFIED(fw)) { fw->fullscreen.is_iconified = 1; execute_function_override_window( NULL, NULL, "Iconify off", 0, fw); } if (IS_SHADED(fw)) { int sas = fw->shade_anim_steps; fw->fullscreen.is_shaded = 1; fw->shade_anim_steps = 0; execute_function_override_window( NULL, NULL, "WindowShade off", 0, fw); fw->shade_anim_steps = sas; } SET_EWMH_FULLSCREEN(fw,True); apply_decor_change(fw); fscr.xypos.x = fw->g.frame.x + fw->g.frame.width / 2; fscr.xypos.y = fw->g.frame.y + fw->g.frame.height / 2; FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &scr_g.x, &scr_g.y, &scr_g.width, &scr_g.height); get_window_borders(fw, &b); get_page_offset_check_visible(&page_x, &page_y, fw); sprintf( cmd, "ResizeMoveMaximize %dp %dp +%dp +%dp ewmhiwa", scr_g.width, scr_g.height, scr_g.x - b.top_left.width + page_x, scr_g.y - b.top_left.height + page_y); if (DO_EWMH_USE_STACKING_HINTS(fw)) { int sl = fw->ewmh_normal_layer; new_layer(fw, Scr.TopLayer); if (sl == 0) { fw->ewmh_normal_layer = Scr.DefaultLayer; } else { fw->ewmh_normal_layer = sl; } } if (cmd[0] != 0) { SET_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw, 1); execute_function_override_window(NULL, NULL, cmd, 0, fw); SET_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw, 0); } return; } fvwm-2.6.7/fvwm/externs.h0000644000175700017570000000607712773467232012313 00000000000000/* -*-c-*- */ /* * Copyright 1988 by Evans & Sutherland Computer Corporation, * Salt Lake City, Utah * Portions Copyright 1989 by the Massachusetts Institute of Technology * Cambridge, 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 permis- * sion notice appear in supporting documentation, and that the * names of Evans & Sutherland and M.I.T. not be used in advertising * in publicity pertaining to distribution of the software without * specific, written prior permission. * * EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- * ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR * M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- * AGES 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 EXTERNS_H #define EXTERNS_H void Done(int, char *) __attribute__((__noreturn__)); void set_init_function_name(int n, const char *name); const char *get_init_function_name(int n); extern char NoName[]; extern char NoClass[]; extern char NoResource[]; extern XGCValues Globalgcv; extern unsigned long Globalgcm; extern int master_pid; extern Display *dpy; extern int x_fd; extern XContext FvwmContext; extern Bool fFvwmInStartup; extern Bool DoingCommandLine; extern Bool debugging; extern Bool debugging_stack_ring; extern int GrabPointerState; extern Window JunkRoot, JunkChild; extern int JunkX, JunkY; extern int JunkWidth, JunkHeight, JunkBW, JunkDepth; extern unsigned int JunkMask; extern char *fvwm_userdir; extern char *display_name; extern Atom _XA_MIT_PRIORITY_COLORS; extern Atom _XA_WM_CHANGE_STATE; extern Atom _XA_WM_STATE; extern Atom _XA_WM_COLORMAP_WINDOWS; extern Atom _XA_WM_PROTOCOLS; extern Atom _XA_WM_TAKE_FOCUS; extern Atom _XA_WM_SAVE_YOURSELF; extern Atom _XA_WM_DELETE_WINDOW; extern Atom _XA_WM_DESKTOP; extern Atom _XA_OL_WIN_ATTR; extern Atom _XA_OL_WT_BASE; extern Atom _XA_OL_WT_CMD; extern Atom _XA_OL_WT_HELP; extern Atom _XA_OL_WT_NOTICE; extern Atom _XA_OL_WT_OTHER; extern Atom _XA_OL_DECOR_ADD; extern Atom _XA_OL_DECOR_DEL; extern Atom _XA_OL_DECOR_CLOSE; extern Atom _XA_OL_DECOR_RESIZE; extern Atom _XA_OL_DECOR_HEADER; extern Atom _XA_OL_DECOR_ICON_NAME; extern Atom _XA_WM_WINDOW_ROLE; extern Atom _XA_WINDOW_ROLE; extern Atom _XA_WM_CLIENT_LEADER; extern Atom _XA_SM_CLIENT_ID; extern Atom _XA_WIN_SX; extern Atom _XA_MANAGER; extern Atom _XA_ATOM_PAIR; extern Atom _XA_WM_COLORMAP_NOTIFY; extern Atom _XA_XROOTPMAP_ID; extern Atom _XA_XSETROOT_ID; #endif /* _EXTERNS_ */ fvwm-2.6.7/fvwm/ewmh_names.c0000644000175700017570000001524713001406607012720 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Olivier Chapuis */ /* 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 #include #include #include "libs/fvwmlib.h" #include "libs/Flocale.h" #include "libs/FlocaleCharset.h" #include "libs/Ficonv.h" #include "fvwm.h" #include "window_flags.h" #include "cursor.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "module_interface.h" #include "borders.h" #include "add_window.h" #include "icons.h" #include "ewmh.h" #include "ewmh_intern.h" #include "externs.h" /* * set the visibale window name and icon name */ void EWMH_SetVisibleName(FvwmWindow *fw, Bool is_icon_name) { unsigned char *val; char *tmp_str; FlocaleCharset *fc = NULL; if (!FiconvSupport) { return; } /* set the ewmh visible name only if it is != wm name */ if (is_icon_name) { if ((fw->icon_name_count == 0 || !USE_INDEXED_ICON_NAME(fw)) && !HAS_EWMH_WM_ICON_NAME(fw) && !HAS_EWMH_WM_NAME(fw)) { ewmh_DeleteProperty( FW_W(fw), "_NET_WM_ICON_VISIBLE_NAME", EWMH_ATOM_LIST_FVWM_WIN); return; } if (IS_ICON_FONT_LOADED(fw) && fw->icon_font != NULL) { fc = fw->icon_font->str_fc; } tmp_str = fw->visible_icon_name; } else { if ((fw->name_count == 0 || !USE_INDEXED_WINDOW_NAME(fw)) && !HAS_EWMH_WM_NAME(fw) && !HAS_EWMH_WM_ICON_NAME(fw)) { ewmh_DeleteProperty( FW_W(fw), "_NET_WM_VISIBLE_NAME", EWMH_ATOM_LIST_FVWM_WIN); return; } if (IS_WINDOW_FONT_LOADED(fw) && fw->title_font != NULL) { fc = fw->title_font->str_fc; } tmp_str = fw->visible_name; } if (tmp_str == NULL) { return; /* should never happen */ } val = (unsigned char *)FiconvCharsetToUtf8( dpy, fc, tmp_str, strlen(tmp_str)); if (val == NULL) { return; } if (is_icon_name) { ewmh_ChangeProperty( FW_W(fw), "_NET_WM_ICON_VISIBLE_NAME", EWMH_ATOM_LIST_FVWM_WIN, (unsigned char *)val, strlen((char *)val)); } else { ewmh_ChangeProperty( FW_W(fw), "_NET_WM_VISIBLE_NAME", EWMH_ATOM_LIST_FVWM_WIN, (unsigned char *)val, strlen((char *)val)); } free(val); } /* * setup and property notify */ int EWMH_WMIconName( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int size = 0; char *val; char *tmp_str; FlocaleCharset *fc = NULL; if (!FiconvSupport) { return 0; } val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_ICON_NAME", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); if (val == NULL) { SET_HAS_EWMH_WM_ICON_NAME(fw,0); return 0; } if (IS_ICON_FONT_LOADED(fw) && fw->icon_font != NULL) { fc = fw->icon_font->str_fc; } tmp_str = (char *)FiconvUtf8ToCharset( dpy, fc, (const char *) val, size); free(val); if (tmp_str == NULL) { SET_HAS_EWMH_WM_ICON_NAME(fw, 0); return 0; } if (strlen(tmp_str) > MAX_ICON_NAME_LEN) { tmp_str[MAX_ICON_NAME_LEN] = 0; } SET_HAS_EWMH_WM_ICON_NAME(fw, 1); if (fw->icon_name.name && strcmp(tmp_str, fw->icon_name.name) == 0) { /* migo: some apps update their names every second */ free(tmp_str); return 0; } if (ev != NULL) { /* client message */ free_window_names(fw, False, True); } fw->icon_name.name = tmp_str; SET_WAS_ICON_NAME_PROVIDED(fw, 1); if (ev == NULL) { /* return now for setup */ return 1; } setup_visible_name(fw, True); EWMH_SetVisibleName(fw, True); BroadcastWindowIconNames(fw, False, True); RedoIconName(fw); return 1; } int EWMH_WMName( FvwmWindow *fw, XEvent *ev, window_style *style, unsigned long any) { int size = 0; char *val; char *tmp_str; FlocaleCharset *fc = NULL; if (!FiconvSupport) return 0; val = ewmh_AtomGetByName( FW_W(fw), "_NET_WM_NAME", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size); if (val == NULL) { SET_HAS_EWMH_WM_NAME(fw,0); return 0; } if (IS_WINDOW_FONT_LOADED(fw) && fw->title_font != NULL) { fc = fw->title_font->str_fc; } tmp_str = (char *)FiconvUtf8ToCharset( dpy, fc, (const char *) val, size); free(val); if (tmp_str == NULL) { SET_HAS_EWMH_WM_NAME(fw,0); return 0; } if (strlen(tmp_str) > MAX_WINDOW_NAME_LEN) { tmp_str[MAX_WINDOW_NAME_LEN] = 0; } SET_HAS_EWMH_WM_NAME(fw, 1); if (fw->name.name && strcmp(tmp_str, fw->name.name) == 0) { /* migo: some apps update their names every second */ free(tmp_str); return 0; } if (ev != NULL) { /* client message */ free_window_names(fw, True, False); } fw->name.name = tmp_str; if (ev == NULL) { return 1; } setup_visible_name(fw, False); SET_NAME_CHANGED(fw, 1); EWMH_SetVisibleName(fw, False); BroadcastWindowIconNames(fw, True, False); /* fix the name in the title bar */ if (!IS_ICONIFIED(fw)) { border_draw_decorations( fw, PART_TITLE, (Scr.Hilite == fw), True, CLEAR_ALL, NULL, NULL); } if (!WAS_ICON_NAME_PROVIDED(fw)) { fw->icon_name = fw->name; setup_visible_name(fw, True); BroadcastWindowIconNames(fw, False, True); EWMH_SetVisibleName(fw, True); RedoIconName(fw); } return 0; } #define MAX(A,B) ((A)>(B)? (A):(B)) /* * set the desktop name */ void EWMH_SetDesktopNames(void) { int nbr = 0; int len = 0; int i; int j = 0; DesktopsInfo *d,*s; unsigned char **names; unsigned char *val; if (!FiconvSupport) { return; } d = Scr.Desktops->next; /* skip negative desk */ while (d != NULL && d->desk < 0) { d = d->next; } s = d; while (d != NULL && d->name != NULL && d->desk == nbr) { nbr++; d = d->next; } if (nbr == 0) { return; } names = (void *)safemalloc(sizeof(*names)*nbr); for (i = 0; i < nbr; i++) { names[i] = (unsigned char *)FiconvCharsetToUtf8( dpy, NULL, s->name, strlen(s->name)); if (names[i]) { len += strlen((char *)names[i]) + 1; } else { len++; } s = s->next; } val = (unsigned char *)safemalloc(len); for (i = 0; i < nbr; i++) { if (names[i] != NULL) { memcpy(&val[j], names[i], strlen((char *)names[i])); j += strlen((char *)names[i]); free(names[i]); } val[j++] = '\0'; } ewmh_ChangeProperty( Scr.Root, "_NET_DESKTOP_NAMES", EWMH_ATOM_LIST_CLIENT_ROOT, (unsigned char *)val, len); free(names); free(val); } fvwm-2.6.7/fvwm/focus.h0000644000175700017570000000535612773467232011741 00000000000000/* -*-c-*- */ #ifndef FOCUS_H #define FOCUS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ #define FOCUS_SET(w, fw) _focus_set(w, fw) #define FOCUS_RESET() _focus_reset() #define SetFocusWindow(a, b, c) _SetFocusWindow(a, b, c, False); #define SetFocusWindowClientEntered(a, b, c) _SetFocusWindow(a, b, c, True); #define ReturnFocusWindow(a) _ReturnFocusWindow(a); #define DeleteFocus(a) _DeleteFocus(a); #define ForceDeleteFocus() _ForceDeleteFocus(); /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* * Triggers X protocol actions to set the focus to the given window. It also * stores the FvwmWindow pointer to indicate that fvwm requested focus for that * FvwmWindow, not the application itself or someone else. */ void _focus_set(Window w, FvwmWindow *fw); void _focus_reset(void); /* * * Sets/deletes the input focus to the indicated window. * */ void _SetFocusWindow( FvwmWindow *fw, Bool do_allow_force_broadcast, fpol_set_focus_by_t set_by, Bool client_entered); void _ReturnFocusWindow(FvwmWindow *fw); void _DeleteFocus(Bool do_allow_force_broadcast); void _ForceDeleteFocus(void); void restore_focus_after_unmap( const FvwmWindow *fw, Bool do_skip_marked_transients); /* * These need documentation */ Bool IsLastFocusSetByMouse(void); void focus_grab_buttons(FvwmWindow *fw); void focus_grab_buttons_client_entered(FvwmWindow *fw); void focus_grab_buttons_on_layer(int layer); void focus_grab_buttons_all(void); void focus_grab_buttons_on_pointer_window(void); Bool focus_does_accept_input_focus(const FvwmWindow *fw); Bool focus_is_focused(const FvwmWindow *fw); Bool focus_query_click_to_raise( FvwmWindow *fw, Bool is_focused, int context); Bool focus_query_click_to_focus( FvwmWindow *fw, int context); Bool focus_query_open_grab_focus(FvwmWindow *fw, FvwmWindow *focus_win); Bool focus_query_close_release_focus(const FvwmWindow *fw); FvwmWindow *focus_get_transientfor_fwin(const FvwmWindow *fw); FvwmWindow *get_focus_window(void); void set_focus_window(FvwmWindow *fw); FvwmWindow *get_last_screen_focus_window(void); void set_last_screen_focus_window(FvwmWindow *fw); void update_last_screen_focus_window(FvwmWindow *fw); void set_focus_model(FvwmWindow *fw); void focus_force_refresh_focus(const FvwmWindow *fw); void refresh_focus(const FvwmWindow *fw); #endif /* FOCUS_H */ fvwm-2.6.7/fvwm/menustyle.c0000644000175700017570000013326613001406607012624 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/ColorUtils.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/Graphics.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "colorset.h" #include "menustyle.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static MenuStyle *default_menu_style; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void menustyle_free_face(MenuFace *mf) { switch (mf->type) { case GradientMenu: if (Pdepth <= 8 && mf->u.grad.npixels > 0 && !mf->u.grad.do_dither) { Pixel *p; int i; p = (Pixel *)safemalloc( mf->u.grad.npixels * sizeof(Pixel)); for(i=0; i < mf->u.grad.npixels; i++) { p[i] = mf->u.grad.xcs[i].pixel; } PictureFreeColors( dpy, Pcmap, p, mf->u.grad.npixels, 0, False); free(p); } free(mf->u.grad.xcs); mf->u.grad.xcs = NULL; break; case PixmapMenu: case TiledPixmapMenu: if (mf->u.p) { PDestroyFvwmPicture(dpy, mf->u.p); } mf->u.p = NULL; break; case SolidMenu: fvwmlib_free_colors(dpy, &mf->u.back, 1, True); default: break; } mf->type = SimpleMenu; return; } static void menustyle_copy_face(MenuFace *destmf, MenuFace *origmf) { FvwmPictureAttributes fpa; int i; menustyle_free_face(destmf); destmf->type = SimpleMenu; switch (origmf->type) { case SolidMenu: fvwmlib_copy_color( dpy, &destmf->u.back, &origmf->u.back, False, True); destmf->type = SolidMenu; break; case GradientMenu: destmf->u.grad.xcs = (XColor *)safemalloc(sizeof(XColor) * origmf->u.grad.npixels); memcpy(destmf->u.grad.xcs, origmf->u.grad.xcs, sizeof(XColor) * origmf->u.grad.npixels); for (i = 0; iu.grad.npixels;i++) { fvwmlib_clone_color(origmf->u.grad.xcs[i].pixel); } destmf->u.grad.npixels = origmf->u.grad.npixels; destmf->u.grad.do_dither = origmf->u.grad.do_dither; destmf->type = GradientMenu; destmf->gradient_type = origmf->gradient_type; break; case PixmapMenu: case TiledPixmapMenu: fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; if (destmf->u.p) destmf->u.p = NULL; if (origmf->u.p) destmf->u.p = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, origmf->u.p->name, fpa); destmf->type = origmf->type; break; default: break; } } /* * * Reads a menu face line into a structure (veliaa@rpi.edu) * */ static Boolean menustyle_parse_face(char *s, MenuFace *mf, int verbose) { char *style; char *token; char *action = s; FvwmPictureAttributes fpa; s = GetNextToken(s, &style); if (style && strncasecmp(style, "--", 2) == 0) { free(style); return True; } menustyle_free_face(mf); mf->type = SimpleMenu; /* determine menu style */ if (!style) { return True; } else if (StrEquals(style,"Solid")) { s = GetNextToken(s, &token); if (token) { mf->type = SolidMenu; mf->u.back = GetColor(token); free(token); } else { if (verbose) { fvwm_msg(ERR, "menustyle_parse_face", "no color given for Solid face type:" " %s", action); } free(style); return False; } } else if (StrEquals(style+1, "Gradient")) { char **s_colors; int npixels, nsegs, *perc; XColor *xcs; if (!IsGradientTypeSupported(style[0])) { return False; } /* translate the gradient string into an array of colors etc */ npixels = ParseGradient(s, NULL, &s_colors, &perc, &nsegs); if (npixels <= 0) { return False; } /* dither ? */ mf->u.grad.do_dither = False; if (Pdepth <= 8) { mf->u.grad.do_dither = True; } /* grab the colors */ xcs = AllocAllGradientColors( s_colors, perc, nsegs, npixels, mf->u.grad.do_dither); if (xcs == None) { return False; } mf->u.grad.xcs = xcs; mf->u.grad.npixels = npixels; mf->type = GradientMenu; mf->gradient_type = toupper(style[0]); } else if (StrEquals(style,"Pixmap") || StrEquals(style,"TiledPixmap")) { s = GetNextToken(s, &token); fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; if (token) { mf->u.p = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, token, fpa); if (mf->u.p == NULL) { if (verbose) { fvwm_msg(ERR, "menustyle_parse_face", "couldn't load pixmap %s", token); } free(token); free(style); return False; } free(token); mf->type = (StrEquals(style,"TiledPixmap")) ? TiledPixmapMenu : PixmapMenu; } else { if (verbose) { fvwm_msg(ERR, "menustyle_parse_face", "missing pixmap name for style %s", style); } free(style); return False; } } else { if (verbose) { fvwm_msg( ERR, "menustyle_parse_face", "unknown style %s: %s", style, action); } free(style); return False; } free(style); return True; } static void parse_vertical_spacing_line( char *args, signed char *above, signed char *below, signed char above_default, signed char below_default) { int val[2]; if (GetIntegerArguments(args, NULL, val, 2) != 2 || val[0] < MIN_VERTICAL_SPACING || val[0] > MAX_VERTICAL_SPACING || val[1] < MIN_VERTICAL_SPACING || val[1] > MAX_VERTICAL_SPACING) { /* illegal or missing parameters, return to default */ *above = above_default; *below = below_default; return; } *above = val[0]; *below = val[1]; return; } static void parse_vertical_margins_line( char *args, unsigned char *top, unsigned char *bottom, signed char top_default, signed char bottom_default) { int val[2]; if (GetIntegerArguments(args, NULL, val, 2) != 2 || val[0] < 0 || val[0] > MAX_MENU_MARGIN || val[1] < 0 || val[1] > MAX_MENU_MARGIN) { /* invalid or missing parameters, return to default */ *top = top_default; *bottom = bottom_default; return; } *top = val[0]; *bottom = val[1]; return; } static MenuStyle *menustyle_parse_old_style(F_CMD_ARGS) { char *buffer, *rest; char *fore, *back, *stipple, *font, *style, *animated; MenuStyle *ms = NULL; rest = GetNextToken(action,&fore); rest = GetNextToken(rest,&back); rest = GetNextToken(rest,&stipple); rest = GetNextToken(rest,&font); rest = GetNextToken(rest,&style); rest = GetNextToken(rest,&animated); if (!fore || !back || !stipple || !font || !style) { fvwm_msg(ERR, "menustyle_parse_old_style", "error in %s style specification", action); } else { buffer = (char *)alloca(strlen(action) + 100); sprintf(buffer, "* \"%s\", Foreground \"%s\", Background \"%s\", " "Greyed \"%s\", Font \"%s\", \"%s\"", style, fore, back, stipple, font, (animated && StrEquals(animated, "anim")) ? "Animation" : "AnimationOff"); fvwm_msg(OLD, "menustyle_parse_old_style", "The old MenuStyle snytax has been deprecated. " "Use 'MenuStyle %s' instead of 'MenuStyle %s'\n", buffer, action); action = buffer; ms = menustyle_parse_style(F_PASS_ARGS); } if (fore) { free(fore); } if (back) { free(back); } if (stipple) { free(stipple); } if (font) { free(font); } if (style) { free(style); } if (animated) { free(animated); } return ms; } static int menustyle_get_styleopt_index(char *option) { char *optlist[] = { "fvwm", "mwm", "win", "Foreground", "Background", "Greyed", "HilightBack", "HilightBackOff", "ActiveFore", "ActiveForeOff", "Hilight3DThick", "Hilight3DThin", "Hilight3DOff", "Animation", "AnimationOff", "Font", "MenuFace", "PopupDelay", "PopupOffset", "TitleWarp", "TitleWarpOff", "TitleUnderlines0", "TitleUnderlines1", "TitleUnderlines2", "SeparatorsLong", "SeparatorsShort", "TrianglesSolid", "TrianglesRelief", "PopupImmediately", "PopupDelayed", "DoubleClickTime", "SidePic", "SideColor", "PopupAsRootmenu", "PopupAsSubmenu", "RemoveSubmenus", "HoldSubmenus", "SubmenusRight", "SubmenusLeft", "BorderWidth", "Hilight3DThickness", "ItemFormat", "AutomaticHotkeys", "AutomaticHotkeysOff", "VerticalItemSpacing", "VerticalTitleSpacing", "MenuColorset", "ActiveColorset", "GreyedColorset", "SelectOnRelease", "PopdownImmediately", "PopdownDelayed", "PopdownDelay", "PopupActiveArea", "PopupIgnore", "PopupClose", "MouseWheel", "ScrollOffPage", "TrianglesUseFore", "TitleColorset", "HilightTitleBack", "TitleFont", "VerticalMargins", "UniqueHotkeyActivatesImmediate", NULL }; return GetTokenIndex(option, optlist, 0, NULL); } static void change_or_make_gc(GC *gc, unsigned long gcm, XGCValues *gcv) { if (*gc != None) { XChangeGC(dpy, *gc, gcm, gcv); } else { *gc = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, gcv); } return; } /* ---------------------------- interface functions ------------------------ */ MenuStyle *menustyle_get_default_style(void) { return default_menu_style; } void menustyle_free(MenuStyle *ms) { MenuStyle *before = default_menu_style; if (!ms) { return; } menustyle_free_face(&ST_FACE(ms)); if (FORE_GC(ST_MENU_INACTIVE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_INACTIVE_GCS(ms))); } if (FORE_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_ACTIVE_GCS(ms))); } if (BACK_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, BACK_GC(ST_MENU_ACTIVE_GCS(ms))); } if (HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms))); } if (SHADOW_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, SHADOW_GC(ST_MENU_ACTIVE_GCS(ms))); } if (HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms))) { XFreeGC(dpy, HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms))); } if (SHADOW_GC(ST_MENU_INACTIVE_GCS(ms))) { XFreeGC(dpy, SHADOW_GC(ST_MENU_INACTIVE_GCS(ms))); } if (FORE_GC(ST_MENU_STIPPLE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_STIPPLE_GCS(ms))); } if (FORE_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_TITLE_GCS(ms))); } if (BACK_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, BACK_GC(ST_MENU_TITLE_GCS(ms))); } if (HILIGHT_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, HILIGHT_GC(ST_MENU_TITLE_GCS(ms))); } if (SHADOW_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, SHADOW_GC(ST_MENU_TITLE_GCS(ms))); } if (ST_SIDEPIC(ms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(ms)); } if (ST_HAS_SIDE_COLOR(ms) == 1) { fvwmlib_free_colors(dpy, &ST_SIDE_COLOR(ms), 1, True); } if (ST_PSTDFONT(ms) && !ST_USING_DEFAULT_FONT(ms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(ms)); } if (ST_PTITLEFONT(ms) && !ST_USING_DEFAULT_TITLEFONT(ms)) { FlocaleUnloadFont(dpy, ST_PTITLEFONT(ms)); } if (ST_ITEM_FORMAT(ms)) { free(ST_ITEM_FORMAT(ms)); } fvwmlib_free_colors(dpy, &ST_MENU_COLORS(ms).back,1,True); fvwmlib_free_colors(dpy, &ST_MENU_COLORS(ms).fore,1,True); if (ST_HAS_STIPPLE_FORE(ms)) { fvwmlib_free_colors( dpy, &ST_MENU_STIPPLE_COLORS(ms).fore,1,True); } if (ST_HAS_ACTIVE_BACK(ms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(ms).back,1,True); } if (ST_HAS_ACTIVE_FORE(ms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(ms).fore,1,True); } while (ST_NEXT_STYLE(before) != ms) { /* Not too many checks, may segfault in race conditions */ before = ST_NEXT_STYLE(before); } ST_NEXT_STYLE(before) = ST_NEXT_STYLE(ms); free(ST_NAME(ms)); free(ms); return; } MenuStyle *menustyle_find(char *name) { MenuStyle *ms = default_menu_style; while (ms) { if (strcasecmp(ST_NAME(ms),name)==0) { return ms; } ms = ST_NEXT_STYLE(ms); } return NULL; } void menustyle_update(MenuStyle *ms) { XGCValues gcv; unsigned long gcm; color_quad c_inactive; color_quad c_active; color_quad c_stipple; color_quad c_title; colorset_t *menu_cs = &Colorset[ST_CSET_MENU(ms)]; colorset_t *active_cs = &Colorset[ST_CSET_ACTIVE(ms)]; colorset_t *greyed_cs = &Colorset[ST_CSET_GREYED(ms)]; colorset_t *title_cs = &Colorset[ST_CSET_TITLE(ms)]; if (ST_USAGE_COUNT(ms) != 0) { fvwm_msg(ERR,"menustyle_update", "menu style %s is in use", ST_NAME(ms)); return; } ST_IS_UPDATED(ms) = 1; if (ST_USING_DEFAULT_FONT(ms)) { ST_PSTDFONT(ms) = Scr.DefaultFont; } if (ST_USING_DEFAULT_TITLEFONT(ms)) { ST_PTITLEFONT(ms) = ST_PSTDFONT(ms); } /* calculate colors based on foreground */ if (!ST_HAS_ACTIVE_FORE(ms)) { ST_MENU_ACTIVE_COLORS(ms).fore = ST_MENU_COLORS(ms).fore; } /* calculate colors based on background */ if (!ST_HAS_ACTIVE_BACK(ms)) { ST_MENU_ACTIVE_COLORS(ms).back = ST_MENU_COLORS(ms).back; } if (!ST_HAS_STIPPLE_FORE(ms)) { ST_MENU_STIPPLE_COLORS(ms).fore = ST_MENU_COLORS(ms).back; } ST_MENU_STIPPLE_COLORS(ms).back = ST_MENU_COLORS(ms).back; /* prepare colours for changing the gcs */ if (ST_HAS_MENU_CSET(ms)) { c_inactive.fore = menu_cs->fg; c_inactive.back = menu_cs->bg; c_inactive.hilight = menu_cs->hilite; c_inactive.shadow = menu_cs->shadow; } else { c_inactive.fore = ST_MENU_COLORS(ms).fore; c_inactive.back = ST_MENU_COLORS(ms).back; if (Pdepth > 2) { c_inactive.hilight = GetHilite(ST_MENU_COLORS(ms).back); c_inactive.shadow = GetShadow(ST_MENU_COLORS(ms).back); } else { c_inactive.hilight = GetColor(DEFAULT_HILIGHT_COLOR); c_inactive.shadow = GetColor(DEFAULT_SHADOW_COLOR); } } if (ST_HAS_ACTIVE_CSET(ms)) { c_active.fore = active_cs->fg; c_active.back = active_cs->bg; c_active.hilight = active_cs->hilite; c_active.shadow = active_cs->shadow; } else { c_active.fore = ST_MENU_ACTIVE_COLORS(ms).fore; c_active.back = ST_MENU_ACTIVE_COLORS(ms).back; if (Pdepth > 2) { c_active.hilight = GetHilite(ST_MENU_ACTIVE_COLORS(ms).back); c_active.shadow = GetShadow(ST_MENU_ACTIVE_COLORS(ms).back); } else { c_active.hilight = GetColor(DEFAULT_HILIGHT_COLOR); c_active.shadow = GetColor(DEFAULT_SHADOW_COLOR); } } if (ST_HAS_GREYED_CSET(ms)) { c_stipple.fore = greyed_cs->fg; c_stipple.back = greyed_cs->fg; } else { c_stipple.fore = ST_MENU_STIPPLE_COLORS(ms).fore; c_stipple.back = ST_MENU_STIPPLE_COLORS(ms).back; } if (ST_HAS_TITLE_CSET(ms)) { c_title.fore = title_cs->fg; c_title.back = title_cs->bg; c_title.hilight = title_cs->hilite; c_title.shadow = title_cs->shadow; } else { c_title.fore = c_inactive.fore; c_title.back = c_inactive.back; c_title.hilight = c_inactive.hilight; c_title.shadow = c_inactive.shadow; } /* override hilighting colours if necessary */ if (!ST_DO_HILIGHT_FORE(ms)) { c_active.fore = c_inactive.fore; } if (!ST_DO_HILIGHT_BACK(ms)) { c_active.back = c_inactive.back; c_active.hilight = c_inactive.hilight; c_active.shadow = c_inactive.shadow; } if (!ST_DO_HILIGHT_TITLE_BACK(ms)) { c_title.fore = c_inactive.fore; c_title.back = c_inactive.back; c_title.hilight = c_inactive.hilight; c_title.shadow = c_inactive.shadow; } /* make GC's */ gcm = GCFunction|GCLineWidth|GCForeground|GCBackground; if (ST_PSTDFONT(ms)->font != NULL) { gcm |= GCFont; gcv.font = ST_PSTDFONT(ms)->font->fid; } gcv.function = GXcopy; gcv.line_width = 0; /* update inactive menu gcs */ gcv.foreground = c_inactive.fore; gcv.background = c_inactive.back; change_or_make_gc(&FORE_GC(ST_MENU_INACTIVE_GCS(ms)), gcm, &gcv); BACK_GC(ST_MENU_INACTIVE_GCS(ms)) = FORE_GC(ST_MENU_INACTIVE_GCS(ms)); gcv.foreground = c_inactive.hilight; gcv.background = c_inactive.shadow; change_or_make_gc(&HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms)), gcm, &gcv); gcv.foreground = c_inactive.shadow; gcv.background = c_inactive.hilight; change_or_make_gc(&SHADOW_GC(ST_MENU_INACTIVE_GCS(ms)), gcm, &gcv); /* update active menu gcs */ gcv.foreground = c_active.fore; gcv.background = c_active.back; change_or_make_gc(&FORE_GC(ST_MENU_ACTIVE_GCS(ms)), gcm, &gcv); gcv.foreground = c_active.back; gcv.background = c_active.fore; if (ST_HAS_ACTIVE_CSET(ms) && active_cs->pixmap && active_cs->pixmap_type == PIXMAP_TILED) { gcv.tile = active_cs->pixmap; gcv.fill_style = FillTiled; change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms)), gcm | GCFillStyle | GCTile , &gcv); } else { gcv.fill_style = FillSolid; change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms)), gcm | GCFillStyle , &gcv); } gcv.foreground = c_active.hilight; gcv.background = c_active.shadow; change_or_make_gc(&HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms)), gcm, &gcv); gcv.foreground = c_active.shadow; gcv.background = c_active.hilight; change_or_make_gc(&SHADOW_GC(ST_MENU_ACTIVE_GCS(ms)), gcm, &gcv); /* update title gcs */ if (ST_PTITLEFONT(ms)->font != NULL && ST_PSTDFONT(ms)->font == NULL) { if (ST_PSTDFONT(ms)->font == NULL) { gcm |= GCFont; } gcv.font = ST_PTITLEFONT(ms)->font->fid; } gcv.foreground = c_title.fore; gcv.background = c_title.back; change_or_make_gc(&FORE_GC(ST_MENU_TITLE_GCS(ms)), gcm, &gcv); gcv.foreground = c_title.back; gcv.background = c_title.fore; if (ST_HAS_TITLE_CSET(ms) && title_cs->pixmap && title_cs->pixmap_type == PIXMAP_TILED) { gcv.tile = title_cs->pixmap; gcv.fill_style = FillTiled; change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms)), gcm | GCFillStyle | GCTile , &gcv); } else { gcv.fill_style = FillSolid; change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms)), gcm | GCFillStyle , &gcv); } gcv.foreground = c_title.hilight; gcv.background = c_title.shadow; change_or_make_gc(&HILIGHT_GC(ST_MENU_TITLE_GCS(ms)), gcm, &gcv); gcv.foreground = c_title.shadow; gcv.background = c_title.hilight; change_or_make_gc(&SHADOW_GC(ST_MENU_TITLE_GCS(ms)), gcm, &gcv); /* update stipple menu gcs */ SHADOW_GC(ST_MENU_STIPPLE_GCS(ms)) = SHADOW_GC(ST_MENU_INACTIVE_GCS(ms)); if (Pdepth < 2) { gcv.fill_style = FillStippled; gcv.stipple = Scr.gray_bitmap; /* no need to reset fg/bg, FillStipple wins */ gcm |= GCStipple | GCFillStyle; HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms)) = SHADOW_GC(ST_MENU_INACTIVE_GCS(ms)); } else { gcv.foreground = c_stipple.fore; gcv.background = c_stipple.back; HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms)) = HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms)); } change_or_make_gc(&FORE_GC(ST_MENU_STIPPLE_GCS(ms)), gcm, &gcv); BACK_GC(ST_MENU_STIPPLE_GCS(ms)) = BACK_GC(ST_MENU_INACTIVE_GCS(ms)); return; } MenuStyle *menustyle_parse_style(F_CMD_ARGS) { char *name; char *option = NULL; char *poption = NULL; char *optstring = NULL; char *args = NULL; char *arg1; int on; MenuStyle *ms; MenuStyle *tmpms; Bool is_initialised = True; Bool has_gc_changed = False; int val[2]; int n; FlocaleFont *new_font = NULL; int i; KeyCode keycode; FvwmPictureAttributes fpa; action = GetNextToken(action, &name); if (!name) { fvwm_msg(ERR, "NewMenuStyle", "error in %s style specification",action); return NULL; } ms = menustyle_find(name); if (ms && ST_USAGE_COUNT(ms) != 0) { fvwm_msg(ERR,"NewMenuStyle", "menu style %s is in use", name); return ms; } tmpms = (MenuStyle *)safemalloc(sizeof(MenuStyle)); if (ms) { /* copy the structure over our temporary menu face. */ memcpy(tmpms, ms, sizeof(MenuStyle)); free(name); } else { memset(tmpms, 0, sizeof(MenuStyle)); ST_NAME(tmpms) = name; is_initialised = False; } ST_IS_UPDATED(tmpms) = 1; /* Parse the options. */ while (!is_initialised || (action && *action)) { on = 1; if (!is_initialised) { /* some default configuration goes here for the new * menu style */ ST_MENU_COLORS(tmpms).back = GetColor(DEFAULT_BACK_COLOR); ST_MENU_COLORS(tmpms).fore = GetColor(DEFAULT_FORE_COLOR); ST_PSTDFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(tmpms) = True; ST_FACE(tmpms).type = SimpleMenu; ST_HAS_ACTIVE_FORE(tmpms) = 0; ST_HAS_ACTIVE_BACK(tmpms) = 0; ST_DO_POPUP_AS(tmpms) = MDP_POST_MENU; ST_DOUBLE_CLICK_TIME(tmpms) = DEFAULT_MENU_CLICKTIME; ST_POPUP_DELAY(tmpms) = DEFAULT_POPUP_DELAY; ST_POPDOWN_DELAY(tmpms) = DEFAULT_POPDOWN_DELAY; ST_MOUSE_WHEEL(tmpms) = MMW_POINTER; ST_SCROLL_OFF_PAGE(tmpms) = 1; ST_DO_HILIGHT_TITLE_BACK(tmpms) = 0; ST_USING_DEFAULT_TITLEFONT(tmpms) = True; has_gc_changed = True; option = "fvwm"; } else { /* Read next option specification (delimited by a comma * or \0). */ args = action; action = GetQuotedString( action, &optstring, ",", NULL, NULL, NULL); if (!optstring) { break; } args = GetNextToken(optstring, &option); if (!option) { free(optstring); break; } (void)GetNextToken(args, &arg1); } poption = option; while (poption[0] == '!') { on ^= 1; poption++; } switch((i = menustyle_get_styleopt_index(poption))) { case 0: /* fvwm */ case 1: /* mwm */ case 2: /* win */ if (i == 0) { ST_POPUP_OFFSET_PERCENT(tmpms) = 67; ST_POPUP_OFFSET_ADD(tmpms) = 0; ST_DO_POPUP_IMMEDIATELY(tmpms) = 0; ST_DO_WARP_TO_TITLE(tmpms) = 1; ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = 0; ST_RELIEF_THICKNESS(tmpms) = 1; ST_TITLE_UNDERLINES(tmpms) = 1; ST_HAS_LONG_SEPARATORS(tmpms) = 0; ST_HAS_TRIANGLE_RELIEF(tmpms) = 1; ST_DO_HILIGHT_BACK(tmpms) = 0; ST_DO_HILIGHT_FORE(tmpms) = 0; } else if (i == 1) { ST_POPUP_OFFSET_PERCENT(tmpms) = 100; ST_POPUP_OFFSET_ADD(tmpms) = -DEFAULT_MENU_BORDER_WIDTH - 1; ST_DO_POPUP_IMMEDIATELY(tmpms) = 1; ST_DO_WARP_TO_TITLE(tmpms) = 0; ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = 0; ST_RELIEF_THICKNESS(tmpms) = 2; ST_TITLE_UNDERLINES(tmpms) = 2; ST_HAS_LONG_SEPARATORS(tmpms) = 1; ST_HAS_TRIANGLE_RELIEF(tmpms) = 1; ST_DO_HILIGHT_BACK(tmpms) = 0; ST_DO_HILIGHT_FORE(tmpms) = 0; } else /* i == 2 */ { ST_POPUP_OFFSET_PERCENT(tmpms) = 100; ST_POPUP_OFFSET_ADD(tmpms) = -DEFAULT_MENU_BORDER_WIDTH - 3; ST_DO_POPUP_IMMEDIATELY(tmpms) = 1; ST_DO_WARP_TO_TITLE(tmpms) = 0; ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = 1; ST_RELIEF_THICKNESS(tmpms) = 0; ST_TITLE_UNDERLINES(tmpms) = 1; ST_HAS_LONG_SEPARATORS(tmpms) = 0; ST_HAS_TRIANGLE_RELIEF(tmpms) = 0; ST_DO_HILIGHT_BACK(tmpms) = 1; ST_DO_HILIGHT_FORE(tmpms) = 1; } /* common settings */ ST_VERTICAL_MARGIN_TOP(tmpms) = 0; ST_VERTICAL_MARGIN_BOTTOM(tmpms) = 0; ST_CSET_MENU(tmpms) = 0; ST_HAS_MENU_CSET(tmpms) = 0; ST_CSET_ACTIVE(tmpms) = 0; ST_HAS_ACTIVE_CSET(tmpms) = 0; ST_CSET_GREYED(tmpms) = 0; ST_HAS_GREYED_CSET(tmpms) = 0; ST_BORDER_WIDTH(tmpms) = DEFAULT_MENU_BORDER_WIDTH; ST_ACTIVE_AREA_PERCENT(tmpms) = DEFAULT_MENU_POPUP_NOW_RATIO; ST_ITEM_GAP_ABOVE(tmpms) = DEFAULT_MENU_ITEM_TEXT_Y_OFFSET; ST_ITEM_GAP_BELOW(tmpms) = DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2; ST_TITLE_GAP_ABOVE(tmpms) = DEFAULT_MENU_TITLE_TEXT_Y_OFFSET; ST_TITLE_GAP_BELOW(tmpms) = DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2; ST_USE_LEFT_SUBMENUS(tmpms) = 0; ST_IS_ANIMATED(tmpms) = 0; ST_USE_AUTOMATIC_HOTKEYS(tmpms) = 0; /* Pressing a hotkey on an item which only has a * single entry will activate that action; turning * those off will make the menu persist until enter or * space is pressed; the default behaviour is to * always close the menu and run the action. */ ST_HOTKEY_ACTIVATES_IMMEDIATE(tmpms) = 1; menustyle_free_face(&ST_FACE(tmpms)); ST_FACE(tmpms).type = SimpleMenu; if (ST_PSTDFONT(tmpms) && !ST_USING_DEFAULT_FONT(tmpms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(tmpms)); } ST_PSTDFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(tmpms) = True; has_gc_changed = True; if (ST_HAS_SIDE_COLOR(tmpms) == 1) { fvwmlib_free_colors( dpy, &ST_SIDE_COLOR(tmpms), 1, True); ST_HAS_SIDE_COLOR(tmpms) = 0; } ST_HAS_SIDE_COLOR(tmpms) = 0; if (ST_SIDEPIC(tmpms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(tmpms)); ST_SIDEPIC(tmpms) = NULL; } if (is_initialised == False) { /* now begin the real work */ is_initialised = True; continue; } break; case 3: /* Foreground */ fvwmlib_free_colors( dpy, &ST_MENU_COLORS(tmpms).fore, 1, True); if (arg1) { ST_MENU_COLORS(tmpms).fore = GetColor(arg1); } else { ST_MENU_COLORS(tmpms).fore = GetColor(DEFAULT_FORE_COLOR); } has_gc_changed = True; break; case 4: /* Background */ fvwmlib_free_colors( dpy, &ST_MENU_COLORS(tmpms).back, 1, True); if (arg1) { ST_MENU_COLORS(tmpms).back = GetColor(arg1); } else { ST_MENU_COLORS(tmpms).back = GetColor(DEFAULT_BACK_COLOR); } has_gc_changed = True; break; case 5: /* Greyed */ if (ST_HAS_STIPPLE_FORE(tmpms)) { fvwmlib_free_colors( dpy, &ST_MENU_STIPPLE_COLORS(tmpms).fore, 1, True); } if (arg1 == NULL) { ST_HAS_STIPPLE_FORE(tmpms) = 0; } else { ST_MENU_STIPPLE_COLORS(tmpms).fore = GetColor(arg1); ST_HAS_STIPPLE_FORE(tmpms) = 1; } has_gc_changed = True; break; case 7: /* HilightBackOff */ on ^= 1; /* fall throw */ case 6: /* HilightBack */ if (ST_HAS_ACTIVE_BACK(tmpms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(tmpms).back, 1, True); } if (arg1 == NULL || !on) { ST_HAS_ACTIVE_BACK(tmpms) = 0; } else { ST_MENU_ACTIVE_COLORS(tmpms).back = GetColor(arg1); ST_HAS_ACTIVE_BACK(tmpms) = 1; } ST_DO_HILIGHT_BACK(tmpms) = on; has_gc_changed = True; break; case 9: /* ActiveForeOff */ on ^= 1; /* fall throw */ case 8: /* ActiveFore */ if (ST_HAS_ACTIVE_FORE(tmpms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(tmpms).fore, 1, True); } if (arg1 == NULL || !on) { ST_HAS_ACTIVE_FORE(tmpms) = 0; } else { ST_MENU_ACTIVE_COLORS(tmpms).fore = GetColor(arg1); ST_HAS_ACTIVE_FORE(tmpms) = 1; } ST_DO_HILIGHT_FORE(tmpms) = on; has_gc_changed = True; break; case 10: /* Hilight3DThick */ ST_RELIEF_THICKNESS(tmpms) = 2; break; case 11: /* Hilight3DThin */ ST_RELIEF_THICKNESS(tmpms) = 1; break; case 12: /* Hilight3DOff */ ST_RELIEF_THICKNESS(tmpms) = 0; break; case 13: /* Animation */ ST_IS_ANIMATED(tmpms) = on; break; case 14: /* AnimationOff */ ST_IS_ANIMATED(tmpms) = !on; break; case 15: /* Font */ if (arg1 != NULL && !(new_font = FlocaleLoadFont(dpy, arg1, "fvwm"))) { fvwm_msg(ERR, "NewMenuStyle", "Couldn't load font '%s'\n", arg1); break; } if (ST_PSTDFONT(tmpms) && !ST_USING_DEFAULT_FONT(tmpms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(tmpms)); } if (arg1 == NULL) { /* reset to screen font */ ST_PSTDFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(tmpms) = True; } else { ST_PSTDFONT(tmpms) = new_font; ST_USING_DEFAULT_FONT(tmpms) = False; } has_gc_changed = True; break; case 16: /* MenuFace */ while (args && *args != '\0' && isspace((unsigned char)*args)) { args++; } menustyle_parse_face(args, &ST_FACE(tmpms), True); break; case 17: /* PopupDelay */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_POPUP_DELAY(tmpms) = DEFAULT_POPUP_DELAY; } else { ST_POPUP_DELAY(tmpms) = (*val+9)/10; } break; case 18: /* PopupOffset */ if ((n = GetIntegerArguments(args, NULL, val, 2)) == 0) { fvwm_msg(ERR,"NewMenuStyle", "PopupOffset requires one or two" " arguments"); } else { ST_POPUP_OFFSET_ADD(tmpms) = val[0]; if (n == 2 && val[1] <= 100 && val[1] >= 0) { ST_POPUP_OFFSET_PERCENT(tmpms) = val[1]; } else { ST_POPUP_OFFSET_PERCENT(tmpms) = 100; } } break; case 19: /* TitleWarp */ ST_DO_WARP_TO_TITLE(tmpms) = on; break; case 20: /* TitleWarpOff */ ST_DO_WARP_TO_TITLE(tmpms) = !on; break; case 21: /* TitleUnderlines0 */ ST_TITLE_UNDERLINES(tmpms) = 0; break; case 22: /* TitleUnderlines1 */ ST_TITLE_UNDERLINES(tmpms) = 1; break; case 23: /* TitleUnderlines2 */ ST_TITLE_UNDERLINES(tmpms) = 2; break; case 24: /* SeparatorsLong */ ST_HAS_LONG_SEPARATORS(tmpms) = on; break; case 25: /* SeparatorsShort */ ST_HAS_LONG_SEPARATORS(tmpms) = !on; break; case 26: /* TrianglesSolid */ ST_HAS_TRIANGLE_RELIEF(tmpms) = !on; break; case 27: /* TrianglesRelief */ ST_HAS_TRIANGLE_RELIEF(tmpms) = on; break; case 28: /* PopupImmediately */ ST_DO_POPUP_IMMEDIATELY(tmpms) = on; break; case 29: /* PopupDelayed */ ST_DO_POPUP_IMMEDIATELY(tmpms) = !on; break; case 30: /* DoubleClickTime */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_DOUBLE_CLICK_TIME(tmpms) = DEFAULT_MENU_CLICKTIME; } else { ST_DOUBLE_CLICK_TIME(tmpms) = *val; } break; case 31: /* SidePic */ if (ST_SIDEPIC(tmpms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(tmpms)); ST_SIDEPIC(tmpms) = NULL; } if (arg1) { fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; ST_SIDEPIC(tmpms) = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, arg1, fpa); if (!ST_SIDEPIC(tmpms)) { fvwm_msg(WARN, "NewMenuStyle", "Couldn't find pixmap %s", arg1); } } break; case 32: /* SideColor */ if (ST_HAS_SIDE_COLOR(tmpms) == 1) { fvwmlib_free_colors( dpy, &ST_SIDE_COLOR(tmpms), 1, True); ST_HAS_SIDE_COLOR(tmpms) = 0; } if (arg1) { ST_SIDE_COLOR(tmpms) = GetColor(arg1); ST_HAS_SIDE_COLOR(tmpms) = 1; } break; case 33: /* PopupAsRootmenu */ ST_DO_POPUP_AS(tmpms) = MDP_ROOT_MENU; break; case 34: /* PopupAsSubmenu */ ST_DO_POPUP_AS(tmpms) = MDP_POST_MENU; break; case 35: /* RemoveSubmenus */ ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = on; break; case 36: /* HoldSubmenus */ ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = !on; break; case 37: /* SubmenusRight */ ST_USE_LEFT_SUBMENUS(tmpms) = !on; break; case 38: /* SubmenusLeft */ ST_USE_LEFT_SUBMENUS(tmpms) = on; break; case 39: /* BorderWidth */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0 || *val > MAX_MENU_BORDER_WIDTH) { ST_BORDER_WIDTH(tmpms) = DEFAULT_MENU_BORDER_WIDTH; } else { ST_BORDER_WIDTH(tmpms) = *val; } break; case 40: /* Hilight3DThickness */ if (GetIntegerArguments(args, NULL, val, 1) > 0) { if (*val < 0) { *val = -*val; ST_IS_ITEM_RELIEF_REVERSED(tmpms) = 1; } else { ST_IS_ITEM_RELIEF_REVERSED(tmpms) = 0; } if (*val > MAX_MENU_ITEM_RELIEF_THICKNESS) *val = MAX_MENU_ITEM_RELIEF_THICKNESS; ST_RELIEF_THICKNESS(tmpms) = *val; } break; case 41: /* ItemFormat */ if (ST_ITEM_FORMAT(tmpms)) { free(ST_ITEM_FORMAT(tmpms)); ST_ITEM_FORMAT(tmpms) = NULL; } if (arg1) { ST_ITEM_FORMAT(tmpms) = safestrdup(arg1); } break; case 42: /* AutomaticHotkeys */ ST_USE_AUTOMATIC_HOTKEYS(tmpms) = on; break; case 43: /* AutomaticHotkeysOff */ ST_USE_AUTOMATIC_HOTKEYS(tmpms) = !on; break; case 44: /* VerticalItemSpacing */ parse_vertical_spacing_line( args, &ST_ITEM_GAP_ABOVE(tmpms), &ST_ITEM_GAP_BELOW(tmpms), DEFAULT_MENU_ITEM_TEXT_Y_OFFSET, DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2); break; case 45: /* VerticalTitleSpacing */ parse_vertical_spacing_line( args, &ST_TITLE_GAP_ABOVE(tmpms), &ST_TITLE_GAP_BELOW(tmpms), DEFAULT_MENU_TITLE_TEXT_Y_OFFSET, DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2); break; case 46: /* MenuColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_MENU_CSET(tmpms) = 0; ST_CSET_MENU(tmpms) = 0; } else { ST_HAS_MENU_CSET(tmpms) = 1; ST_CSET_MENU(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 47: /* ActiveColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_ACTIVE_CSET(tmpms) = 0; ST_CSET_ACTIVE(tmpms) = 0; } else { ST_HAS_ACTIVE_CSET(tmpms) = 1; ST_CSET_ACTIVE(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 48: /* GreyedColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_GREYED_CSET(tmpms) = 0; ST_CSET_GREYED(tmpms) = 0; } else { ST_HAS_GREYED_CSET(tmpms) = 1; ST_CSET_GREYED(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 49: /* SelectOnRelease */ keycode = 0; if (arg1) { keycode = XKeysymToKeycode( dpy, FvwmStringToKeysym(dpy, arg1)); } ST_SELECT_ON_RELEASE_KEY(tmpms) = keycode; break; case 50: /* PopdownImmediately */ ST_DO_POPDOWN_IMMEDIATELY(tmpms) = 1; break; case 51: /* PopdownDelayed */ ST_DO_POPDOWN_IMMEDIATELY(tmpms) = 0; break; case 52: /* PopdownDelay */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_POPDOWN_DELAY(tmpms) = DEFAULT_POPDOWN_DELAY; } else { ST_POPDOWN_DELAY(tmpms) = (*val+9)/10; } break; case 53: /* PopupActiveArea */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val <= 50 || *val > 100) { ST_ACTIVE_AREA_PERCENT(tmpms) = DEFAULT_MENU_POPUP_NOW_RATIO; } else { ST_ACTIVE_AREA_PERCENT(tmpms) = *val; } break; case 54: /* PopupIgnore */ ST_DO_POPUP_AS(tmpms) = MDP_IGNORE; break; case 55: /* PopupClose */ ST_DO_POPUP_AS(tmpms) = MDP_CLOSE; break; case 56: /* MouseWheel */ if (arg1) { if (StrEquals(arg1, "ActivatesItem")) { ST_MOUSE_WHEEL(tmpms) = MMW_OFF; } else if (StrEquals(arg1, "ScrollsMenuBackwards")) { ST_MOUSE_WHEEL(tmpms) = MMW_MENU_BACKWARDS; } else if (StrEquals(arg1, "ScrollsMenu")) { ST_MOUSE_WHEEL(tmpms) = MMW_MENU; } else if (StrEquals(arg1, "ScrollsPointer")) { ST_MOUSE_WHEEL(tmpms) = MMW_POINTER; } else { fvwm_msg( ERR, "NewMenuStyle", "unknown argument to" " MouseWheel '%s'", arg1); ST_MOUSE_WHEEL(tmpms) = MMW_POINTER; } } else { ST_MOUSE_WHEEL(tmpms) = (on) ? MMW_POINTER : MMW_OFF; } break; case 57: /* ScrollOffPage */ ST_SCROLL_OFF_PAGE(tmpms) = on; break; case 58: /* TrianglesUseFore */ ST_TRIANGLES_USE_FORE(tmpms) = on; break; case 59: /* TitleColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_TITLE_CSET(tmpms) = 0; ST_CSET_TITLE(tmpms) = 0; } else { ST_HAS_TITLE_CSET(tmpms) = 1; ST_CSET_TITLE(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 60: /* TitleHilightBack */ ST_DO_HILIGHT_TITLE_BACK(tmpms) = on; has_gc_changed = True; break; case 61: /* TitleFont */ if (arg1 != NULL && !(new_font = FlocaleLoadFont(dpy, arg1, "fvwm"))) { fvwm_msg(ERR, "NewMenuStyle", "Couldn't load font '%s'\n", arg1); break; } if ( ST_PTITLEFONT(tmpms) && !ST_USING_DEFAULT_TITLEFONT(tmpms)) { FlocaleUnloadFont(dpy, ST_PTITLEFONT(tmpms)); } if (arg1 == NULL) { /* reset to screen font */ ST_PTITLEFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_TITLEFONT(tmpms) = True; } else { ST_PTITLEFONT(tmpms) = new_font; ST_USING_DEFAULT_TITLEFONT(tmpms) = False; } has_gc_changed = True; break; case 62: /* VerticalMargins */ parse_vertical_margins_line( args, &ST_VERTICAL_MARGIN_TOP(tmpms), &ST_VERTICAL_MARGIN_BOTTOM(tmpms), 0, 0); break; case 63: /* UniqueHotKeyActivatesImmediate */ ST_HOTKEY_ACTIVATES_IMMEDIATE(tmpms) = on; break; #if 0 case 99: /* PositionHints */ /* to be implemented */ break; #endif default: fvwm_msg(ERR, "NewMenuStyle", "unknown option '%s'", poption); break; } /* switch */ if (option) { free(option); option = NULL; } free(optstring); optstring = NULL; if (arg1) { free(arg1); arg1 = NULL; } } /* while */ if (has_gc_changed) { menustyle_update(tmpms); } if (default_menu_style == NULL) { /* First MenuStyle MUST be the default style */ default_menu_style = tmpms; ST_NEXT_STYLE(tmpms) = NULL; } else if (ms) { /* copy our new menu face over the old one */ memcpy(ms, tmpms, sizeof(MenuStyle)); free(tmpms); return ms; } else { MenuStyle *before = default_menu_style; /* add a new menu face to list */ ST_NEXT_STYLE(tmpms) = NULL; while (ST_NEXT_STYLE(before)) before = ST_NEXT_STYLE(before); ST_NEXT_STYLE(before) = tmpms; } return tmpms; } void menustyle_copy(MenuStyle *origms, MenuStyle *destms) { FvwmPictureAttributes fpa; /* Copy origms to destms, be aware of all pointers in the MenuStyle strcture. Use the same order as in menustyle_parse_style */ /* menu colors */ fvwmlib_copy_color( dpy, &ST_MENU_COLORS(destms).fore, &ST_MENU_COLORS(origms).fore, True, True); fvwmlib_copy_color( dpy, &ST_MENU_COLORS(destms).back, &ST_MENU_COLORS(origms).back, True, True); /* Greyed */ fvwmlib_copy_color( dpy, &ST_MENU_STIPPLE_COLORS(destms).fore, &ST_MENU_STIPPLE_COLORS(origms).fore, ST_HAS_STIPPLE_FORE(destms), ST_HAS_STIPPLE_FORE(origms)); ST_MENU_STIPPLE_COLORS(destms).back = ST_MENU_STIPPLE_COLORS(origms).back; ST_HAS_STIPPLE_FORE(destms) = ST_HAS_STIPPLE_FORE(origms); /* HilightBack */ fvwmlib_copy_color( dpy, &ST_MENU_ACTIVE_COLORS(destms).back, &ST_MENU_ACTIVE_COLORS(origms).back, ST_HAS_ACTIVE_BACK(destms), ST_HAS_ACTIVE_BACK(origms)); ST_HAS_ACTIVE_BACK(destms) = ST_HAS_ACTIVE_BACK(origms); ST_DO_HILIGHT_BACK(destms) = ST_DO_HILIGHT_BACK(origms); /* ActiveFore */ fvwmlib_copy_color( dpy, &ST_MENU_ACTIVE_COLORS(destms).fore, &ST_MENU_ACTIVE_COLORS(origms).fore, ST_HAS_ACTIVE_FORE(destms), ST_HAS_ACTIVE_FORE(origms)); ST_HAS_ACTIVE_FORE(destms) = ST_HAS_ACTIVE_FORE(origms); ST_DO_HILIGHT_FORE(destms) = ST_DO_HILIGHT_FORE(origms); /* Hilight3D */ ST_RELIEF_THICKNESS(destms) = ST_RELIEF_THICKNESS(origms); /* Animation */ ST_IS_ANIMATED(destms) = ST_IS_ANIMATED(origms); /* font */ if (ST_PSTDFONT(destms) && !ST_USING_DEFAULT_FONT(destms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(destms)); } if (ST_PSTDFONT(origms) && !ST_USING_DEFAULT_FONT(origms)) { if (!(ST_PSTDFONT(destms) = FlocaleLoadFont(dpy, ST_PSTDFONT(origms)->name, "fvwm"))) { ST_PSTDFONT(destms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(destms) = True; fvwm_msg(ERR, "CopyMenuStyle", "Couldn't load font '%s' use Default Font\n", ST_PSTDFONT(origms)->name); } else { ST_USING_DEFAULT_FONT(destms) = False; } } else { ST_USING_DEFAULT_FONT(destms) = True; ST_PSTDFONT(destms) = Scr.DefaultFont; } /* TitleFont */ if (ST_PTITLEFONT(destms) && !ST_USING_DEFAULT_TITLEFONT(destms)) { FlocaleUnloadFont(dpy, ST_PTITLEFONT(destms)); } if (ST_PTITLEFONT(origms) && !ST_USING_DEFAULT_TITLEFONT(origms)) { if ( !(ST_PTITLEFONT(destms) = FlocaleLoadFont( dpy, ST_PTITLEFONT(origms)->name, "fvwm"))) { ST_PTITLEFONT(destms) = Scr.DefaultFont; ST_USING_DEFAULT_TITLEFONT(destms) = True; fvwm_msg(ERR, "CopyMenuStyle", "Couldn't load font '%s' use Default Font\n", ST_PTITLEFONT(origms)->name); } else { ST_USING_DEFAULT_TITLEFONT(destms) = False; } } else { ST_USING_DEFAULT_TITLEFONT(destms) = True; ST_PTITLEFONT(destms) = Scr.DefaultFont; } /* MenuFace */ menustyle_copy_face(&ST_FACE(destms), &ST_FACE(origms)); /* PopupDelay */ ST_POPUP_DELAY(destms) = ST_POPUP_DELAY(origms); /* PopupOffset */ ST_POPUP_OFFSET_PERCENT(destms) = ST_POPUP_OFFSET_PERCENT(origms); ST_POPUP_OFFSET_ADD(destms) = ST_POPUP_OFFSET_ADD(origms); /* TitleWarp */ ST_DO_WARP_TO_TITLE(destms) = ST_DO_WARP_TO_TITLE(origms); /* TitleUnderlines */ ST_TITLE_UNDERLINES(destms) = ST_TITLE_UNDERLINES(origms); /* Separators */ ST_HAS_LONG_SEPARATORS(destms) = ST_HAS_LONG_SEPARATORS(origms); /* Triangles */ ST_HAS_TRIANGLE_RELIEF(destms) = ST_HAS_TRIANGLE_RELIEF(origms); /* PopupDelayed */ ST_DO_POPUP_IMMEDIATELY(destms) = ST_DO_POPUP_IMMEDIATELY(origms); /* DoubleClickTime */ ST_DOUBLE_CLICK_TIME(destms) = ST_DOUBLE_CLICK_TIME(origms); /* VerticalMargins */ ST_VERTICAL_MARGIN_TOP(destms) = ST_VERTICAL_MARGIN_TOP(origms); ST_VERTICAL_MARGIN_BOTTOM(destms) = ST_VERTICAL_MARGIN_BOTTOM(origms); /* SidePic */ if (ST_SIDEPIC(destms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(destms)); ST_SIDEPIC(destms) = NULL; } if (ST_SIDEPIC(origms)) { fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; ST_SIDEPIC(destms) = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, ST_SIDEPIC(origms)->name, fpa); } /* side color */ fvwmlib_copy_color( dpy, &ST_SIDE_COLOR(destms), &ST_SIDE_COLOR(origms), ST_HAS_SIDE_COLOR(destms), ST_HAS_SIDE_COLOR(origms)); ST_HAS_SIDE_COLOR(destms) = ST_HAS_SIDE_COLOR(origms); /* PopupAsRootmenu */ ST_DO_POPUP_AS(destms) = ST_DO_POPUP_AS(origms); /* RemoveSubmenus */ ST_DO_UNMAP_SUBMENU_ON_POPDOWN(destms) = ST_DO_UNMAP_SUBMENU_ON_POPDOWN(origms); /* SubmenusRight */ ST_USE_LEFT_SUBMENUS(destms) = ST_USE_LEFT_SUBMENUS(origms); /* BorderWidth */ ST_BORDER_WIDTH(destms) = ST_BORDER_WIDTH(origms); /* Hilight3DThickness */ ST_IS_ITEM_RELIEF_REVERSED(destms) = ST_IS_ITEM_RELIEF_REVERSED(origms); /* ItemFormat */ if (ST_ITEM_FORMAT(destms)) { free(ST_ITEM_FORMAT(destms)); ST_ITEM_FORMAT(destms) = NULL; } if (ST_ITEM_FORMAT(origms)) { ST_ITEM_FORMAT(destms) = safestrdup(ST_ITEM_FORMAT(origms)); } /* AutomaticHotkeys */ ST_USE_AUTOMATIC_HOTKEYS(destms) = ST_USE_AUTOMATIC_HOTKEYS(origms); ST_HOTKEY_ACTIVATES_IMMEDIATE(destms) = ST_HOTKEY_ACTIVATES_IMMEDIATE(origms); /* Item and Title Spacing */ ST_ITEM_GAP_ABOVE(destms) = ST_ITEM_GAP_ABOVE(origms); ST_ITEM_GAP_BELOW(destms) = ST_ITEM_GAP_BELOW(origms); ST_TITLE_GAP_ABOVE(destms) = ST_TITLE_GAP_ABOVE(origms); ST_TITLE_GAP_BELOW(destms) = ST_TITLE_GAP_BELOW(origms); /* MenuColorset */ ST_HAS_MENU_CSET(destms) = ST_HAS_MENU_CSET(origms); ST_CSET_MENU(destms) = ST_CSET_MENU(origms); /* ActiveColorset */ ST_HAS_ACTIVE_CSET(destms) = ST_HAS_ACTIVE_CSET(origms); ST_CSET_ACTIVE(destms) = ST_CSET_ACTIVE(origms); /* MenuColorset */ ST_HAS_GREYED_CSET(destms) = ST_HAS_GREYED_CSET(origms); ST_CSET_GREYED(destms) = ST_CSET_GREYED(origms); /* TitleColorset */ ST_HAS_TITLE_CSET(destms) = ST_HAS_TITLE_CSET(origms); ST_CSET_TITLE(destms) = ST_CSET_TITLE(origms); /* SelectOnRelease */ ST_SELECT_ON_RELEASE_KEY(destms) = ST_SELECT_ON_RELEASE_KEY(origms); /* PopdownImmediately */ ST_DO_POPDOWN_IMMEDIATELY(destms) = ST_DO_POPDOWN_IMMEDIATELY(origms); /* PopdownDelay */ ST_POPDOWN_DELAY(destms) = ST_POPDOWN_DELAY(origms); /* Scroll */ ST_MOUSE_WHEEL(destms) = ST_MOUSE_WHEEL(origms); /* ScrollOffPage */ ST_SCROLL_OFF_PAGE(destms) = ST_SCROLL_OFF_PAGE(origms); /* TrianglesUseFore */ ST_TRIANGLES_USE_FORE(destms) = ST_TRIANGLES_USE_FORE(origms); /* Title */ ST_DO_HILIGHT_TITLE_BACK(destms) = ST_DO_HILIGHT_TITLE_BACK(origms); menustyle_update(destms); return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_CopyMenuStyle(F_CMD_ARGS) { char *origname = NULL; char *destname = NULL; char *buffer; MenuStyle *origms; MenuStyle *destms; origname = PeekToken(action, &action); if (origname == NULL) { fvwm_msg(ERR,"CopyMenuStyle", "need two arguments"); return; } origms = menustyle_find(origname); if (!origms) { fvwm_msg(ERR, "CopyMenuStyle", "%s: no such menu style", origname); return; } destname = PeekToken(action, &action); if (destname == NULL) { fvwm_msg(ERR,"CopyMenuStyle", "need two arguments"); return; } if (action && *action) { fvwm_msg(ERR,"CopyMenuStyle", "too many arguments"); return; } destms = menustyle_find(destname); if (!destms) { /* create destms menu style */ buffer = (char *)safemalloc(strlen(destname) + 3); sprintf(buffer,"\"%s\"",destname); action = buffer; destms = menustyle_parse_style(F_PASS_ARGS); free(buffer); if (!destms) { /* this must never happen */ fvwm_msg(ERR, "CopyMenuStyle", "impossible to create %s menu style", destname); return; } } if (strcasecmp("*",destname) == 0) { fvwm_msg(ERR, "CopyMenuStyle", "You cannot copy on the default menu style"); return; } if (strcasecmp(ST_NAME(origms),destname) == 0) { fvwm_msg(ERR, "CopyMenuStyle", "%s and %s identify the same menu style", ST_NAME(origms),destname); return; } if (ST_USAGE_COUNT(destms) != 0) { fvwm_msg(ERR, "CopyMenuStyle", "menu style %s is in use", destname); return; } menustyle_copy(origms, destms); return; } void CMD_MenuStyle(F_CMD_ARGS) { char *option; char *poption; GetNextSimpleOption(SkipNTokens(action, 1), &option); poption = option; while (poption && poption[0] == '!') { poption++; } if (option == NULL || menustyle_get_styleopt_index(poption) != -1) { (void)menustyle_parse_style(F_PASS_ARGS); } else { (void)menustyle_parse_old_style(F_PASS_ARGS); } if (option) { free(option); } return; } fvwm-2.6.7/fvwm/colorset.c0000644000175700017570000011746113001406607012430 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 the late Joey Shutup. * * http://www.streetmap.co.uk/streetmap.dll?postcode2map?BS24+9TZ * * No guarantees or warranties or anything are provided or implied in any way * whatsoever. Use this program at your own risk. Permission to use this * program for any purpose is given, as long as the copyright is kept intact. */ /* * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/PictureBase.h" #include "libs/FShape.h" #include "libs/ColorUtils.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/Graphics.h" #include "libs/PictureGraphics.h" #include "libs/FRenderInit.h" #include "libs/Strings.h" #include "libs/Grab.h" #include "colorset.h" #include "externs.h" #include "fvwm.h" #include "cursor.h" #include "functions.h" #include "commands.h" #include "misc.h" #include "screen.h" #include "module_interface.h" #include "execcontext.h" #include "builtins.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ extern int nColorsets; /* in libs/Colorset.c */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* When fvwm destroys pixmaps it puts them on a list and only destroys them * after some period of inactivity. This is necessary because changing colorset * options rapidly may result in a module redrawing itself due to the first * change while the second change is happening. If the module renders something * with the colorset affected by the second change there is a chance it may * reference pixmaps that FvwmTheme has destroyed, bad things would happen */ struct junklist { struct junklist *prev; Pixmap pixmap; }; struct root_pic { Pixmap pixmap; Pixmap old_pixmap; int width; int height; }; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static char *black = "black"; static char *white = "white"; static char *gray = "gray"; static struct junklist *junk = NULL; static Bool cleanup_scheduled = False; static struct root_pic root_pic = {None, None, 0, 0}; static char *csetopts[] = { "Foreground", "Fore", "fg", "Background", "Back", "bg", "Hilight", "Hilite", "hi", "Shadow", "Shade", "sh", "fgsh", "fg_alpha", "fgAlpha", /* these strings are used inside the cases in the switch below! */ "Pixmap", "TiledPixmap", "AspectPixmap", /* these strings are used inside the cases in the switch below! */ "Shape", "TiledShape", "AspectShape", /* switch off pixmaps and gradients */ "Plain", /* switch off shape */ "NoShape", /* Make the background transparent, copies the root window background */ "Transparent", "RootTransparent", /* tint for the Pixmap or the gradient */ "Tint", "PixmapTint", /* ~ Tint */ "ImageTint", /* ~ Tint */ "TintMask", /* ~ Tint (backward compatibility) */ "NoTint", /* ~ Tint without argument */ "fgTint", "bgTint", /* Dither the Pixmap or the gradient */ "Dither", "NoDither", /* alpha for the Pixmap or the gradient */ "Alpha", "PixmapAlpha", /* ~ Alpha */ "ImageAlpha", /* ~ Alpha */ /* Icon stuff */ "DitherIcon", "NoDitherIcon", "IconTint", "NoIconTint", "IconAlpha", NULL }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static Pixmap get_root_pixmap(Atom prop) { Atom type; int format; unsigned long length, after; unsigned char *reteval = NULL; int ret; Pixmap pix = None; ret = XGetWindowProperty( dpy, Scr.Root, prop, 0L, 1L, False, XA_PIXMAP, &type, &format, &length, &after, &reteval); if ( ret == Success && type == XA_PIXMAP && format == 32 && length == 1 && after == 0) { pix = (Pixmap)(*(long *)reteval); } if (reteval) { XFree(reteval); } return pix; } void update_root_pixmap(Atom prop) { static Atom a_rootpix = None; int w = 0; int h = 0; XID dummy; Pixmap pix; if (a_rootpix == None) { a_rootpix = XInternAtom(dpy,"_XROOTPMAP_ID", False); } XSync(dpy, False); if (prop != 0) { pix = get_root_pixmap(prop); if (pix && !XGetGeometry( dpy, pix, &dummy, (int *)&dummy, (int *)&dummy, (unsigned int *)&w, (unsigned int *)&h, (unsigned int *)&dummy, (unsigned int *)&dummy)) { pix = None; } } else { pix = get_root_pixmap(a_rootpix); if (pix && !XGetGeometry( dpy, pix, &dummy, (int *)&dummy, (int *)&dummy, (unsigned int *)&w, (unsigned int *)&h, (unsigned int *)&dummy, (unsigned int *)&dummy)) { pix = None; } } root_pic.pixmap = pix; root_pic.width = w; root_pic.height = h; #if 0 fprintf(stderr,"Get New Root Pixmap: 0x%lx %i,%i\n", root_pic.pixmap, w, h); #endif } static void add_to_junk(Pixmap pixmap) { struct junklist *oldjunk = junk; junk = (struct junklist *)safemalloc(sizeof(struct junklist)); junk->prev = oldjunk; junk->pixmap = pixmap; if (!cleanup_scheduled) { const exec_context_t *exc; exc = exc_create_null_context(); CMD_Schedule(NULL, exc, "3000 CleanupColorsets"); exc_destroy_context(exc); cleanup_scheduled = True; } return; } static char *get_simple_color( char *string, char **color, colorset_t *cs, int supplied_color, int special_flag, char *special_string) { char *rest; if (*color) { free(*color); *color = NULL; } rest = GetNextToken(string, color); if (*color) { if (special_string && StrEquals(*color, special_string)) { free(*color); *color = NULL; cs->color_flags |= special_flag; cs->color_flags &= ~supplied_color; } else { cs->color_flags |= supplied_color; cs->color_flags &= ~special_flag; } } else { cs->color_flags &= ~(supplied_color | special_flag); } return rest; } static void SafeDestroyPicture(Display *dpy, FvwmPicture *picture) { /* have to subvert destroy picture so that it doesn't free pixmaps, * these are added to the junk list to be cleaned up after a timeout */ if (picture->count < 2) { if (picture->picture) { add_to_junk(picture->picture); picture->picture = None; } if (picture->mask) { add_to_junk(picture->mask); picture->mask = None; } if (picture->alpha) { add_to_junk(picture->alpha); picture->alpha = None; } } /* all that this will now do is free the colors and the name */ PDestroyFvwmPicture(dpy, picture); return; } static void free_colorset_background(colorset_t *cs, Bool do_free_args) { if (cs->picture != NULL) { if (cs->picture->picture != cs->pixmap) { add_to_junk(cs->pixmap); } SafeDestroyPicture(dpy, cs->picture); cs->picture = NULL; cs->pixmap = None; cs->alpha_pixmap = None; /* alaways equal to picture->alpha */ } if (cs->pixmap && cs->pixmap != ParentRelative && cs->pixmap != root_pic.pixmap && cs->pixmap != root_pic.old_pixmap) { add_to_junk(cs->pixmap); } cs->pixmap = None; if (cs->mask) { add_to_junk(cs->mask); cs->mask = None; } if (cs->alpha_pixmap) { add_to_junk(cs->alpha_pixmap); cs->alpha_pixmap = None; } if (cs->pixels && cs->nalloc_pixels) { PictureFreeColors( dpy, Pcmap, cs->pixels, cs->nalloc_pixels, 0, False); free(cs->pixels); cs->pixels = NULL; cs->nalloc_pixels = 0; } if (do_free_args) { if (cs->pixmap_args != NULL) { free(cs->pixmap_args); cs->pixmap_args = NULL; } if (cs->gradient_args != NULL) { free(cs->gradient_args); cs->gradient_args = NULL; } cs->is_maybe_root_transparent = False; cs->pixmap_type = 0; } } static void reset_cs_pixmap(colorset_t *cs, GC gc) { if (Pdepth == cs->picture->depth) { XCopyArea(dpy, cs->picture->picture, cs->pixmap, gc, 0, 0, cs->width, cs->height, 0, 0); } else { XCopyPlane(dpy, cs->picture->picture, cs->pixmap, gc, 0, 0, cs->width, cs->height, 0, 0, 1); } return; } static void parse_pixmap( Window win, GC gc, colorset_t *cs, Bool *pixmap_is_a_bitmap) { static char *name = "parse_colorset(pixmap)"; FvwmPictureAttributes fpa; /* dither */ fpa.mask = 0; if (cs->dither) { fpa.mask = FPAM_DITHER; } /* read filename */ if (!cs->pixmap_args) { return; } /* load the file */ cs->picture = PCacheFvwmPicture(dpy, win, NULL, cs->pixmap_args, fpa); if (cs->picture == NULL) { fvwm_msg(ERR, name, "can't load picture %s", cs->pixmap_args); return; } if (cs->picture->depth != Pdepth) { *pixmap_is_a_bitmap = True; cs->pixmap = None; /* build cs->pixmap later */ } /* copy the picture pixmap into the public structure */ cs->width = cs->picture->width; cs->height = cs->picture->height; cs->alpha_pixmap = cs->picture->alpha; if (!*pixmap_is_a_bitmap) { cs->pixmap = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth); XSetClipMask(dpy, gc, cs->picture->mask); XCopyArea(dpy, cs->picture->picture, cs->pixmap, gc, 0, 0, cs->width, cs->height, 0, 0); XSetClipMask(dpy, gc, None); } if (cs->pixmap) { if (cs->picture->mask != None) { /* make an inverted copy of the mask */ cs->mask = XCreatePixmap(dpy, win, cs->width, cs->height, 1); if (cs->mask) { XCopyArea(dpy, cs->picture->mask, cs->mask, Scr.MonoGC, 0, 0, cs->width, cs->height, 0, 0); /* Invert the mask. We use it to draw the * background. */ XSetFunction(dpy, Scr.MonoGC, GXinvert); XFillRectangle(dpy, cs->mask, Scr.MonoGC, 0, 0, cs->width, cs->height); XSetFunction(dpy, Scr.MonoGC, GXcopy); } } } } static void parse_shape(Window win, colorset_t *cs, int i, char *args, int *has_shape_changed) { char *token; static char *name = "parse_colorset(shape)"; FvwmPicture *picture; FvwmPictureAttributes fpa; if (!FHaveShapeExtension) { cs->shape_mask = None; return; } /* read filename */ token = PeekToken(args, &args); *has_shape_changed = True; if (cs->shape_mask) { add_to_junk(cs->shape_mask); cs->shape_mask = None; } /* set the flags */ if (csetopts[i][0] == 'T') { cs->shape_type = SHAPE_TILED; } else if (csetopts[i][0] == 'A') { cs->shape_type = SHAPE_STRETCH_ASPECT; } else { cs->shape_type = SHAPE_STRETCH; } fpa.mask = FPAM_NO_ALPHA; /* try to load the shape mask */ if (!token) { return; } /* load the shape mask */ picture = PCacheFvwmPicture(dpy, win, NULL, token, fpa); if (!picture) { fvwm_msg(ERR, name, "can't load picture %s", token); } else if (picture->depth != 1 && picture->mask == None) { fvwm_msg(ERR, name, "shape pixmap must be of depth 1"); SafeDestroyPicture(dpy, picture); } else { Pixmap mask; /* okay, we have what we want */ if (picture->mask != None) { mask = picture->mask; } else { mask = picture->picture; } cs->shape_width = picture->width; cs->shape_height = picture->height; if (mask != None) { cs->shape_mask = XCreatePixmap( dpy, mask, picture->width, picture->height, 1); if (cs->shape_mask != None) { XCopyPlane(dpy, mask, cs->shape_mask, Scr.MonoGC, 0, 0, picture->width, picture->height, 0, 0, 1); } } } if (picture) { SafeDestroyPicture(dpy, picture); picture = None; } return; } static void parse_simple_tint( colorset_t *cs, char *args, char **tint, int supplied_color, int *changed, int *percent, char *cmd) { char *rest; static char *name = "parse_colorset (tint)"; *changed = False; rest = get_simple_color(args, tint, cs, supplied_color, 0, NULL); if (!(cs->color_flags & supplied_color)) { /* restore to default */ *percent = 0; *changed = True; cs->color_flags &= ~(supplied_color); } else if (!GetIntegerArguments(rest, NULL, percent, 1)) { fvwm_msg(WARN, name, "%s must have two arguments a color and an integer", cmd); return; } *changed = True; if (*percent > 100) { *percent = 100; } else if (*percent < 0) { *percent = 0; } } /* ---------------------------- interface functions ------------------------ */ void cleanup_colorsets(void) { struct junklist *oldjunk = junk; while (junk) { XFreePixmap(dpy, junk->pixmap); oldjunk = junk; junk = junk->prev; free(oldjunk); } cleanup_scheduled = False; } /* translate a colorset spec into a colorset structure */ void parse_colorset(int n, char *line) { int i; int w; int h; int tmp; int percent; colorset_t *cs; char *optstring; char *args; char *option; char *tmp_str; char *fg = NULL; char *bg = NULL; char *hi = NULL; char *sh = NULL; char *fgsh = NULL; char *tint = NULL; char *fg_tint = NULL; char *bg_tint = NULL; char *icon_tint = NULL; Bool have_pixels_changed = False; Bool has_icon_pixels_changed = False; Bool has_fg_changed = False; Bool has_bg_changed = False; Bool has_sh_changed = False; Bool has_hi_changed = False; Bool has_fgsh_changed = False; Bool has_fg_alpha_changed = False; Bool has_tint_changed = False; Bool has_fg_tint_changed = False; Bool has_bg_tint_changed = False; Bool has_icon_tint_changed = False; Bool has_pixmap_changed = False; Bool has_shape_changed = False; Bool has_image_alpha_changed = False; Bool pixmap_is_a_bitmap = False; Bool do_reload_pixmap = False; Bool is_server_grabbed = False; XColor color; XGCValues xgcv; static char *name = "parse_colorset"; Window win = Scr.NoFocusWin; static GC gc = None; /* initialize statics */ if (gc == None) { gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); } /* make sure it exists and has sensible contents */ alloc_colorset(n); cs = &Colorset[n]; /*** Parse the options ***/ while (line && *line) { /* Read next option specification delimited by a comma or \0. */ line = GetQuotedString( line, &optstring, ",", NULL, NULL, NULL); if (!optstring) break; args = GetNextToken(optstring, &option); if (!option) { free(optstring); break; } switch((i = GetTokenIndex(option, csetopts, 0, NULL))) { case 0: /* Foreground */ case 1: /* Fore */ case 2: /* fg */ get_simple_color( args, &fg, cs, FG_SUPPLIED, FG_CONTRAST, "contrast"); has_fg_changed = True; break; case 3: /* Background */ case 4: /* Back */ case 5: /* bg */ get_simple_color( args, &bg, cs, BG_SUPPLIED, BG_AVERAGE, "average"); has_bg_changed = True; break; case 6: /* Hilight */ case 7: /* Hilite */ case 8: /* hi */ get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL); has_hi_changed = True; break; case 9: /* Shadow */ case 10: /* Shade */ case 11: /* sh */ get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL); has_sh_changed = True; break; case 12: /* fgsh */ get_simple_color( args, &fgsh, cs, FGSH_SUPPLIED, 0,NULL); has_fgsh_changed = True; break; case 13: /* fg_alpha */ case 14: /* fgAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->fg_alpha_percent) { cs->fg_alpha_percent = tmp; has_fg_alpha_changed = True; } break; case 15: /* TiledPixmap */ case 16: /* Pixmap */ case 17: /* AspectPixmap */ has_pixmap_changed = True; free_colorset_background(cs, True); tmp_str = PeekToken(args, &args); if (tmp_str) { CopyString(&cs->pixmap_args, tmp_str); do_reload_pixmap = True; cs->gradient_type = 0; /* set the flags */ if (csetopts[i][0] == 'T') { cs->pixmap_type = PIXMAP_TILED; } else if (csetopts[i][0] == 'A') { cs->pixmap_type = PIXMAP_STRETCH_ASPECT; } else { cs->pixmap_type = PIXMAP_STRETCH; } } /* the pixmap is build later */ break; case 18: /* Shape */ case 19: /* TiledShape */ case 20: /* AspectShape */ parse_shape(win, cs, i, args, &has_shape_changed); break; case 21: /* Plain */ has_pixmap_changed = True; free_colorset_background(cs, True); break; case 22: /* NoShape */ has_shape_changed = True; if (cs->shape_mask) { add_to_junk(cs->shape_mask); cs->shape_mask = None; } break; case 23: /* Transparent */ /* This is only allowable when the root depth == fvwm * visual depth otherwise bad match errors happen, * it may be even more restrictive but my tests (on * exceed 6.2) show that only == depth is necessary */ if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy)))) { fvwm_msg( ERR, name, "can't do Transparent " "when root_depth!=fvwm_depth"); break; } has_pixmap_changed = True; free_colorset_background(cs, True); cs->pixmap = ParentRelative; cs->pixmap_type = PIXMAP_STRETCH; break; case 24: /* RootTransparent */ if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy)))) { fvwm_msg( ERR, name, "can't do RootTransparent " "when root_depth!=fvwm_depth"); break; } free_colorset_background(cs, True); has_pixmap_changed = True; cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE; do_reload_pixmap = True; tmp_str = PeekToken(args, &args); if (StrEquals(tmp_str, "buffer")) { cs->allows_buffered_transparency = True; } else { cs->allows_buffered_transparency = False; } cs->is_maybe_root_transparent = True; break; case 25: /* Tint */ case 26: /* PixmapTint */ case 27: /* ImageTint */ case 28: /* TintMask */ parse_simple_tint( cs, args, &tint, TINT_SUPPLIED, &has_tint_changed, &percent, "tint"); if (has_tint_changed) { cs->tint_percent = percent; } break; case 29: /* NoTint */ has_tint_changed = True; cs->tint_percent = 0; cs->color_flags &= ~TINT_SUPPLIED; break; case 30: /* fgTint */ parse_simple_tint( cs, args, &fg_tint, FG_TINT_SUPPLIED, &has_fg_tint_changed, &percent, "fgTint"); if (has_fg_tint_changed) { cs->fg_tint_percent = percent; } break; case 31: /* bgTint */ parse_simple_tint( cs, args, &bg_tint, BG_TINT_SUPPLIED, &has_bg_tint_changed, &percent, "bgTint"); if (has_bg_tint_changed) { cs->bg_tint_percent = percent; } break; case 32: /* dither */ if (cs->pixmap_args || cs->gradient_args) { has_pixmap_changed = True; do_reload_pixmap = True; } cs->dither = True; break; case 33: /* nodither */ if (cs->pixmap_args || cs->gradient_args) { has_pixmap_changed = True; do_reload_pixmap = True; } cs->dither = False; break; case 34: /* Alpha */ case 35: /* PixmapAlpha */ case 36: /* ImageAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->image_alpha_percent) { has_image_alpha_changed = True; cs->image_alpha_percent = tmp; } break; /* dither icon is not dynamic (yet) maybe a bad opt: default * to False ? */ case 37: /* ditherIcon */ cs->do_dither_icon = True; break; case 38: /* DoNotDitherIcon */ cs->do_dither_icon = False; break; case 39: /* IconTint */ parse_simple_tint( cs, args, &icon_tint, ICON_TINT_SUPPLIED, &has_icon_tint_changed, &percent, "IconTint"); if (has_icon_tint_changed) { cs->icon_tint_percent = percent; has_icon_pixels_changed = True; } break; case 40: /* NoIconTint */ has_icon_tint_changed = True; if (cs->icon_tint_percent != 0) { has_icon_pixels_changed = True; } cs->icon_tint_percent = 0; break; case 41: /* IconAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->icon_alpha_percent) { has_icon_pixels_changed = True; cs->icon_alpha_percent = tmp; } break; default: /* test for ?Gradient */ if (option[0] && StrEquals(&option[1], "Gradient")) { cs->gradient_type = toupper(option[0]); if (!IsGradientTypeSupported(cs->gradient_type)) break; has_pixmap_changed = True; free_colorset_background(cs, True); CopyString(&cs->gradient_args, args); do_reload_pixmap = True; if (cs->gradient_type == V_GRADIENT) { cs->pixmap_type = PIXMAP_STRETCH_Y; } else if (cs->gradient_type == H_GRADIENT) cs->pixmap_type = PIXMAP_STRETCH_X; else cs->pixmap_type = PIXMAP_STRETCH; } else { fvwm_msg( WARN, name, "bad colorset pixmap " "specifier %s %s", option, line); } break; } /* switch */ if (option) { free(option); option = NULL; } free(optstring); optstring = NULL; } /* while (line && *line) */ /* * ---------- change the "pixmap" tint colour ---------- */ if (has_tint_changed) { /* user specified colour */ if (tint != NULL) { Pixel old_tint = cs->tint; PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True); cs->tint = GetColor(tint); if (old_tint != cs->tint) { have_pixels_changed = True; } } else if (tint == NULL) { /* default */ Pixel old_tint = cs->tint; PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True); cs->tint = GetColor(black); if (old_tint != cs->tint) { have_pixels_changed = True; } } } /* * reload the gradient if the tint or the alpha have changed. * Do this too if we need to recompute the bg average and the * gradient is tinted (perforemence issue). */ if ((has_tint_changed || has_image_alpha_changed || (has_bg_changed && (cs->color_flags & BG_AVERAGE) && cs->tint_percent > 0)) && cs->gradient_args) { do_reload_pixmap = True; } /* * reset the pixmap if the tint or the alpha has changed */ if (!do_reload_pixmap && (has_tint_changed || has_image_alpha_changed || (has_bg_changed && cs->alpha_pixmap != None))) { if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE || cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) { do_reload_pixmap = True; } else if (cs->picture != NULL && cs->pixmap) { XSetClipMask(dpy, gc, cs->picture->mask); reset_cs_pixmap(cs, gc); XSetClipMask(dpy, gc, None); has_pixmap_changed = True; } } /* * (re)build the pixmap or the gradient */ if (do_reload_pixmap) { free_colorset_background(cs, False); has_pixmap_changed = True; if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE || cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) { cs->pixmap_type = 0; if (root_pic.pixmap) { cs->pixmap = root_pic.pixmap; cs->width = root_pic.width; cs->height = root_pic.height; cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE; #if 0 fprintf(stderr,"Cset %i LoadRoot 0x%lx\n", n, cs->pixmap); #endif } } else if (cs->pixmap_args) { parse_pixmap(win, gc, cs, &pixmap_is_a_bitmap); } else if (cs->gradient_args) { cs->pixmap = CreateGradientPixmapFromString( dpy, win, gc, cs->gradient_type, cs->gradient_args, &w, &h, &cs->pixels, &cs->nalloc_pixels, cs->dither); cs->width = w; cs->height = h; } has_pixmap_changed = True; } if (cs->picture != NULL && cs->picture->depth != Pdepth) { pixmap_is_a_bitmap = True; } /* * ---------- change the background colour ---------- */ if (has_bg_changed || (has_pixmap_changed && (cs->color_flags & BG_AVERAGE) && cs->pixmap != None && cs->pixmap != ParentRelative && !pixmap_is_a_bitmap)) { Bool do_set_default_background = False; Pixmap average_pix = None; if (cs->color_flags & BG_AVERAGE) { if (cs->picture != NULL && cs->picture->picture != None) { average_pix = cs->picture->picture; } else if (cs->pixmap != ParentRelative) { average_pix = cs->pixmap; } if (average_pix == root_pic.pixmap) { int w; int h; XID dummy; MyXGrabServer(dpy); is_server_grabbed = True; if (!XGetGeometry( dpy, average_pix, &dummy, (int *)&dummy, (int *)&dummy, (unsigned int *)&w, (unsigned int *)&h, (unsigned int *)&dummy, (unsigned int *)&dummy)) { average_pix = None; } else { if (w != cs->width || h != cs->height) { average_pix = None; } } if (average_pix == None) { MyXUngrabServer(dpy); is_server_grabbed = False; } } } /* note: no average for bitmap */ if ((cs->color_flags & BG_AVERAGE) && average_pix) { /* calculate average background color */ XColor *colors; XImage *image; XImage *mask_image = None; unsigned int i, j, k = 0; unsigned long red = 0, blue = 0, green = 0; unsigned long tred, tblue, tgreen; double dred = 0.0, dblue = 0.0, dgreen = 0.0; has_bg_changed = True; /* create an array to store all the pixmap colors in */ /* Note: this may allocate a lot of memory: * cs->width * cs->height * 12 and then the rest of the * procedure can take a lot of times */ colors = (XColor *)safemalloc( cs->width * cs->height * sizeof(XColor)); /* get the pixmap and mask into an image */ image = XGetImage( dpy, average_pix, 0, 0, cs->width, cs->height, AllPlanes, ZPixmap); if (cs->mask != None) { mask_image = XGetImage( dpy, cs->mask, 0, 0, cs->width, cs->height, AllPlanes, ZPixmap); } if (is_server_grabbed == True) { MyXUngrabServer(dpy); } if (image != None && mask_image != None) { /* only fetch the pixels that are not masked * out */ for (i = 0; i < cs->width; i++) { for (j = 0; j < cs->height; j++) { if ( cs->mask == None || XGetPixel( mask_image, i, j) == 0) { colors[k++].pixel = XGetPixel( image, i, j); } } } } if (image != None) { XDestroyImage(image); } if (mask_image != None) { XDestroyImage(mask_image); } if (k == 0) { do_set_default_background = True; } else { /* look them all up, XQueryColors() can't * handle more than 256 */ for (i = 0; i < k; i += 256) { XQueryColors( dpy, Pcmap, &colors[i], min(k - i, 256)); } /* calculate average, add overflows in a double * .red is short, red is long */ for (i = 0; i < k; i++) { tred = red; red += colors[i].red; if (red < tred) { dred += (double)tred; red = colors[i].red; } tgreen = green; green += colors[i].green; if (green < tgreen) { dgreen += (double)tgreen; green = colors[i].green; } tblue = blue; blue += colors[i].blue; if (blue < tblue) { dblue += (double)tblue; blue = colors[i].blue; } } dred += red; dgreen += green; dblue += blue; /* get it */ color.red = dred / k; color.green = dgreen / k; color.blue = dblue / k; { Pixel old_bg = cs->bg; PictureFreeColors( dpy, Pcmap, &cs->bg, 1, 0, True); PictureAllocColor( dpy, Pcmap, &color, True); cs->bg = color.pixel; if (old_bg != cs->bg) { have_pixels_changed = True; } } } free(colors); } /* average */ else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL) { /* user specified colour */ Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetColor(bg); if (old_bg != cs->bg) { have_pixels_changed = True; } } /* user specified */ else if (bg == NULL && has_bg_changed) { /* default */ do_set_default_background = True; } /* default */ if (do_set_default_background) { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetColor(white); if (old_bg != cs->bg) { have_pixels_changed = True; } has_bg_changed = True; } if (has_bg_changed) { /* save the bg color for tinting */ cs->bg_saved = cs->bg; } } /* has_bg_changed */ /* * ---------- setup the bg tint colour ---------- */ if (has_bg_tint_changed && cs->bg_tint_percent > 0 && bg_tint != NULL) { PictureFreeColors(dpy, Pcmap, &cs->bg_tint, 1, 0, True); cs->bg_tint = GetColor(bg_tint); } /* * ---------- tint the bg colour ---------- */ if (has_bg_tint_changed || (has_bg_changed && cs->bg_tint_percent > 0)) { if (cs->bg_tint_percent == 0) { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = cs->bg_saved; if (old_bg != cs->bg) { have_pixels_changed = True; has_bg_changed = True; } } else { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetTintedPixel( cs->bg_saved, cs->bg_tint, cs->bg_tint_percent); if (old_bg != cs->bg) { have_pixels_changed = True; has_bg_changed = True; } } } /* * ---------- setup the fg tint colour ---------- */ if (has_fg_tint_changed && cs->fg_tint_percent > 0 && fg_tint != NULL) { PictureFreeColors(dpy, Pcmap, &cs->fg_tint, 1, 0, True); cs->fg_tint = GetColor(fg_tint); } /* * ---------- change the foreground colour ---------- */ if (has_fg_changed || (has_bg_changed && (cs->color_flags & FG_CONTRAST))) { if (cs->color_flags & FG_CONTRAST) { Pixel old_fg = cs->fg; /* calculate contrasting foreground color */ color.pixel = cs->bg; XQueryColor(dpy, Pcmap, &color); color.red = (color.red > 32767) ? 0 : 65535; color.green = (color.green > 32767) ? 0 : 65535; color.blue = (color.blue > 32767) ? 0 : 65535; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); PictureAllocColor(dpy, Pcmap, &color, True); cs->fg = color.pixel; if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* contrast */ else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL) { /* user specified colour */ Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetColor(fg); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* user specified */ else if (fg == NULL) { /* default */ Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetColor(black); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* save the fg color for tinting */ cs->fg_saved = cs->fg; } /* has_fg_changed */ /* * ---------- tint the foreground colour ---------- */ if (has_fg_tint_changed || (has_fg_changed && cs->fg_tint_percent > 0)) { if (cs->fg_tint_percent == 0) { Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = cs->fg_saved; if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } else { Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetTintedPixel( cs->fg_saved, cs->fg_tint, cs->fg_tint_percent); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } } /* * ---------- change the hilight colour ---------- */ if (has_hi_changed || (has_bg_changed && !(cs->color_flags & HI_SUPPLIED))) { has_hi_changed = 1; if ((cs->color_flags & HI_SUPPLIED) && hi != NULL) { /* user specified colour */ Pixel old_hilite = cs->hilite; PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True); cs->hilite = GetColor(hi); if (old_hilite != cs->hilite) { have_pixels_changed = True; } } /* user specified */ else if (hi == NULL) { Pixel old_hilite = cs->hilite; PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True); cs->hilite = GetHilite(cs->bg); if (old_hilite != cs->hilite) { have_pixels_changed = True; } } } /* has_hi_changed */ /* * ---------- change the shadow colour ---------- */ if (has_sh_changed || (has_bg_changed && !(cs->color_flags & SH_SUPPLIED))) { has_sh_changed = 1; if ((cs->color_flags & SH_SUPPLIED) && sh != NULL) { /* user specified colour */ Pixel old_shadow = cs->shadow; PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True); cs->shadow = GetColor(sh); if (old_shadow != cs->shadow) { have_pixels_changed = True; } } /* user specified */ else if (sh == NULL) { Pixel old_shadow = cs->shadow; PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True); cs->shadow = GetShadow(cs->bg); if (old_shadow != cs->shadow) { have_pixels_changed = True; } } } /* has_sh_changed */ /* * ---------- change the shadow foreground colour ---------- */ if (has_fgsh_changed || ((has_fg_changed || has_bg_changed) && !(cs->color_flags & FGSH_SUPPLIED))) { has_fgsh_changed = 1; if ((cs->color_flags & FGSH_SUPPLIED) && fgsh != NULL) { /* user specified colour */ Pixel old_fgsh = cs->fgsh; PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True); cs->fgsh = GetColor(fgsh); if (old_fgsh != cs->fgsh) { have_pixels_changed = True; } } /* user specified */ else if (fgsh == NULL) { Pixel old_fgsh = cs->fgsh; PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True); cs->fgsh = GetForeShadow(cs->fg, cs->bg); if (old_fgsh != cs->fgsh) { have_pixels_changed = True; } } } /* has_fgsh_changed */ /* * ------- the pixmap is a bitmap: create here cs->pixmap ------- */ if (cs->picture != None && pixmap_is_a_bitmap && (has_pixmap_changed || has_bg_changed)) { cs->pixmap = XCreatePixmap( dpy, win, cs->width, cs->height, Pdepth); XSetBackground(dpy, gc, cs->bg); XSetForeground(dpy, gc, cs->fg); reset_cs_pixmap(cs, gc); } /* * ------- change the masked out parts of the background pixmap ------- */ if (cs->pixmap != None && cs->pixmap != ParentRelative && (!CSETS_IS_TRANSPARENT_ROOT(cs)|| cs->allows_buffered_transparency) && (cs->mask != None || cs->alpha_pixmap != None || cs->image_alpha_percent < 100 || cs->tint_percent > 0) && (has_pixmap_changed || has_bg_changed || has_image_alpha_changed || has_tint_changed)) { /* Now that we know the background colour we can update the * pixmap background. */ FvwmRenderAttributes fra; Pixmap temp, mask, alpha; memset(&fra, 0, sizeof(fra)); temp = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth); if (cs->picture != NULL) { mask = cs->picture->mask; alpha = cs->picture->alpha; } else { mask = None; alpha = None; } XSetForeground(dpy, gc, cs->bg); XFillRectangle( dpy, temp, gc, 0, 0, cs->width, cs->height); fra.mask = FRAM_HAVE_ADDED_ALPHA | FRAM_HAVE_TINT; fra.added_alpha_percent = cs->image_alpha_percent; fra.tint = cs->tint; fra.tint_percent = cs->tint_percent; PGraphicsRenderPixmaps( dpy, win, cs->pixmap, mask, alpha, Pdepth, &fra, temp, gc, Scr.MonoGC, Scr.AlphaGC, 0, 0, cs->width, cs->height, 0, 0, cs->width, cs->height, False); if (cs->pixmap != root_pic.pixmap) { add_to_junk(cs->pixmap); } cs->pixmap = temp; has_pixmap_changed = True; if (CSETS_IS_TRANSPARENT_ROOT(cs)) { cs->pixmap_type = PIXMAP_ROOT_PIXMAP_TRAN; } } /* has_pixmap_changed */ /* * ---------- change the icon tint colour ---------- */ if (has_icon_tint_changed) { /* user specified colour */ if (icon_tint != NULL) { Pixel old_tint = cs->icon_tint; PictureFreeColors( dpy, Pcmap, &cs->icon_tint, 1, 0, True); cs->icon_tint = GetColor(icon_tint); if (old_tint != cs->icon_tint) { has_icon_pixels_changed = True; } } else { /* default */ Pixel old_tint = cs->icon_tint; PictureFreeColors( dpy, Pcmap, &cs->icon_tint, 1, 0, True); cs->icon_tint = GetColor(black); if (old_tint != cs->icon_tint) { has_icon_pixels_changed = True; } } } /* * ---------- send new colorset to fvwm and clean up ---------- */ /* make sure the server has this to avoid races */ XSync(dpy, False); /* inform modules of the change */ if (have_pixels_changed || has_pixmap_changed || has_shape_changed || has_fg_alpha_changed || has_icon_pixels_changed) { BroadcastColorset(n); } if (fg) { free(fg); } if (bg) { free(bg); } if (hi) { free(hi); } if (sh) { free(sh); } if (fgsh) { free(fgsh); } if (tint) { free(tint); } if (fg_tint) { free(fg_tint); } if (bg_tint) { free(bg_tint); } if (icon_tint) { free(icon_tint); } return; } /* * alloc_colorset() grows the size of the Colorset array to include set n * colorset_t *Colorset will be altered * returns the address of the member */ void alloc_colorset(int n) { /* do nothing if it already exists */ if (n < nColorsets) { return; } else { Colorset = (colorset_t *)saferealloc( (char *)Colorset, (n + 1) * sizeof(colorset_t)); memset( &Colorset[nColorsets], 0, (n + 1 - nColorsets) * sizeof(colorset_t)); } if (n == 0) { update_root_pixmap(0); } /* initialize new colorsets to black on gray */ while (nColorsets <= n) { colorset_t *ncs = &Colorset[nColorsets]; if (PictureUseBWOnly()) { char g_bits[] = {0x0a, 0x05, 0x0a, 0x05, 0x08, 0x02, 0x08, 0x02, 0x01, 0x02, 0x04, 0x08}; /* monochrome monitors get black on white */ /* with a gray pixmap background */ ncs->fg = GetColor(black); ncs->bg = GetColor(white); ncs->hilite = GetColor(white); ncs->shadow = GetColor(black); ncs->fgsh = GetColor(white); ncs->tint = GetColor(black); ncs->icon_tint = GetColor(black); ncs->pixmap = XCreatePixmapFromBitmapData( dpy, Scr.NoFocusWin, &g_bits[4 * (nColorsets % 3)], 4, 4, PictureBlackPixel(), PictureWhitePixel(), Pdepth); ncs->width = 4; ncs->height = 4; } else { ncs->fg = GetColor(black); ncs->bg = GetColor(gray); ncs->hilite = GetHilite(ncs->bg); ncs->shadow = GetShadow(ncs->bg); ncs->fgsh = GetForeShadow(ncs->fg, ncs->bg); ncs->tint = GetColor(black); ncs->icon_tint = GetColor(black); } ncs->fg_tint = ncs->bg_tint = GetColor(black); /* set flags for fg contrast, bg average */ /* in case just a pixmap is given */ ncs->color_flags = FG_CONTRAST | BG_AVERAGE; ncs->fg_saved = ncs->fg; ncs->fg_alpha_percent = 100; ncs->image_alpha_percent = 100; ncs->icon_alpha_percent = 100; ncs->tint_percent = 0; ncs->icon_tint_percent = 0; ncs->fg_tint_percent = ncs->bg_tint_percent = 0; ncs->dither = (PictureDitherByDefault())? True:False; nColorsets++; } } void update_root_transparent_colorset(Atom prop) { int i; colorset_t *cs; root_pic.old_pixmap = root_pic.pixmap; update_root_pixmap(prop); #if 0 if (!root_pic.pixmap) { return; } #endif for (i=0; i < nColorsets; i++) { Bool root_trans = False; cs = &Colorset[i]; if (cs->is_maybe_root_transparent && cs->allows_buffered_transparency) { parse_colorset(i, "RootTransparent buffer"); root_trans = True; } else if (cs->is_maybe_root_transparent) { parse_colorset(i, "RootTransparent"); root_trans = True; } if (root_trans) { update_fvwm_colorset(i); } } } /* ---------------------------- builtin commands ---------------------------- */ void CMD_ReadWriteColors(F_CMD_ARGS) { fvwm_msg(WARN, "CMD_ReadWriteColors", "ReadWriteColors is obsolete"); return; } void CMD_Colorset(F_CMD_ARGS) { int n; char *token; if (GetIntegerArguments(action, &token, &n, 1) != 1) { return; } if (n < 0) { return; } if (token == NULL) { return; } parse_colorset(n, token); update_fvwm_colorset(n); return; } void CMD_CleanupColorsets(F_CMD_ARGS) { cleanup_colorsets(); } fvwm-2.6.7/fvwm/menubindings.c0000644000175700017570000005752612773467232013305 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/Parse.h" #include "libs/Bindings.h" #include "libs/charmap.h" #include "libs/Flocale.h" #include "libs/wcontext.h" #include "fvwm.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "misc.h" #include "screen.h" #include "bindings.h" #include "move_resize.h" #include "menudim.h" #include "menustyle.h" #include "menuitem.h" #include "menuroot.h" #include "menuparameters.h" #include "menugeometry.h" #include "menubindings.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* menu bindings are kept in a local binding list separate from other * bindings*/ static Binding *menu_bindings_regular = NULL; static Binding *menu_bindings_fallback = NULL; static Binding **menu_bindings = NULL; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* * Returns the position of the item in the menu, but counts * only items that can be selected (i.e. nor separators or * titles). The count begins with 0. */ static int get_selectable_item_index( MenuRoot *mr, MenuItem *mi_target, int *ret_sections) { int i = 0; int s = 0; MenuItem *mi; int is_last_selectable = 0; for (mi = MR_FIRST_ITEM(mr); mi && mi != mi_target; mi = MI_NEXT_ITEM(mi)) { if (MI_IS_SELECTABLE(mi)) { i++; is_last_selectable = 1; } else if (is_last_selectable == 1) { s++; is_last_selectable = 0; } } if (ret_sections) { *ret_sections = s; } if (mi == mi_target) { return i; } return -1; } static MenuItem *get_selectable_item_from_index(MenuRoot *mr, int index) { int i = -1; MenuItem *mi; MenuItem *mi_last_ok = NULL; for (mi = MR_FIRST_ITEM(mr); mi && (i < index || mi_last_ok == NULL); mi=MI_NEXT_ITEM(mi)) { if (MI_IS_SELECTABLE(mi)) { mi_last_ok = mi; i++; } } return mi_last_ok; } static MenuItem *get_selectable_item_from_section(MenuRoot *mr, int section) { int i = 0; MenuItem *mi; MenuItem *mi_last_ok = NULL; int is_last_selectable = 0; for ( mi = MR_FIRST_ITEM(mr); mi && (i <= section || mi_last_ok == NULL); mi=MI_NEXT_ITEM(mi)) { if (MI_IS_SELECTABLE(mi)) { if (!is_last_selectable) { mi_last_ok = mi; is_last_selectable = 1; } } else if (is_last_selectable) { i++; is_last_selectable = 0; } } return mi_last_ok; } static int get_selectable_item_count(MenuRoot *mr, int *ret_sections) { int count; count = get_selectable_item_index(mr, MR_LAST_ITEM(mr), ret_sections); if (MR_LAST_ITEM(mr) && MI_IS_SELECTABLE(MR_LAST_ITEM(mr))) { count++; } return count; } static Binding *__menu_binding_is_mouse( Binding *blist, XEvent* event, int context) { Binding *b; int real_mod; real_mod = event->xbutton.state - (1 << (7 + event->xbutton.button)); for (b = blist; b != NULL; b = b->NextBinding) { if ( BIND_IS_MOUSE_BINDING(b->type) && (b->Button_Key == 0 || event->xbutton.button == b->Button_Key) && (b->Modifier == AnyModifier || MaskUsedModifiers(b->Modifier) == MaskUsedModifiers(real_mod)) && (b->Context == C_MENU || (b->Context & context) != C_MENU)) { break; } } return b; } static void parse_menu_action( struct MenuRoot *mr, const char *action, menu_shortcut_action *saction, int *items_to_move, int *do_skip_section, char **ret_cmd) { char *optlist[] = { "MenuClose", "MenuEnterContinuation", "MenuEnterSubmenu", "MenuLeaveSubmenu", "MenuMoveCursor", "MenuCursorLeft", "MenuCursorRight", "MenuSelectItem", "MenuScroll", "MenuTearOff", "MenuCloseAndExec", NULL }; int index; char *options; int num; int suffix[2]; int count[2]; *ret_cmd = NULL; options = GetNextTokenIndex((char *)action, optlist, 0, &index); switch (index) { case 0: /* MenuClose */ *saction = SA_ABORT; break; case 1: /* MenuEnterContinuation */ *saction = (MR_CONTINUATION_MENU(mr) != NULL) ? SA_CONTINUE : SA_ENTER; break; case 2: /* MenuEnterSubmenu */ *saction = SA_ENTER; break; case 3: /* MenuLeaveSubmenu */ *saction = SA_LEAVE; break; case 4: /* MenuMoveCursor */ num = GetSuffixedIntegerArguments(options, NULL, count, 2, "s", suffix); if (num == 2) { if (suffix[0] != 0 || count[0] != 0) { fvwm_msg(ERR, "parse_menu_action", "invalid MenuMoveCursor arguments " "'%s'", options); *saction = SA_NONE; break; } if (count[1] < 0) { *saction = SA_LAST; *items_to_move = 1 + count[1]; } else { *saction = SA_FIRST; *items_to_move = count[1]; } if (suffix[1] == 1) { *do_skip_section = 1; } } else if (num == 1) { *saction = SA_MOVE_ITEMS; *items_to_move = count[0]; if (suffix[0] == 1) { *do_skip_section = 1; } } else { fvwm_msg(ERR, "parse_menu_action", "invalid MenuMoveCursor arguments '%s'", options); *saction = SA_NONE; break; } break; case 5: /* MenuCursorLeft */ *saction = (MST_USE_LEFT_SUBMENUS(mr)) ? SA_ENTER : SA_LEAVE; break; case 6: /* MenuCursorRight */ *saction = (MST_USE_LEFT_SUBMENUS(mr)) ? SA_LEAVE : SA_ENTER; break; case 7: /* MenuSelectItem */ *saction = SA_SELECT; break; case 8: /* MenuScroll */ if (MST_MOUSE_WHEEL(mr) == MMW_OFF) { *saction = SA_SELECT; } else { num = GetSuffixedIntegerArguments(options, NULL, count, 1, "s", suffix); if (num == 1) { *saction = SA_SCROLL; *items_to_move = count[0]; if (suffix[0] == 1) { *do_skip_section = 1; } } else { fvwm_msg(ERR, "parse_menu_action", "invalid MenuScroll arguments '%s'", options); *saction = SA_NONE; break; } } break; case 9: /* MenuTearOff */ *saction = SA_TEAROFF; break; case 10: /* MenuCloseAndExecute */ *saction = SA_EXEC_CMD; *ret_cmd = options; break; default: fvwm_msg( ERR, "parse_menu_action", "unknown action '%s'", action); *saction = SA_NONE; } return; } static Binding *__menu_binding_is_key( Binding *blist, XEvent* event, int context) { Binding *b; for (b = blist; b != NULL; b = b->NextBinding) { if ( BIND_IS_KEY_BINDING(b->type) && event->xkey.keycode == b->Button_Key && (b->Modifier == AnyModifier || MaskUsedModifiers(b->Modifier) == MaskUsedModifiers(event->xkey.state)) && (b->Context == C_MENU || (b->Context & context) != C_MENU)) { break; } } return b; } /* ---------------------------- interface functions ------------------------ */ void menu_bindings_startup_complete(void) { menu_bindings = &menu_bindings_regular; return; } Binding *menu_binding_is_mouse(XEvent* event, int context) { Binding *b; b = __menu_binding_is_mouse(menu_bindings_regular, event, context); if (b == NULL) { b = __menu_binding_is_mouse( menu_bindings_fallback, event, context); } return b; } Binding *menu_binding_is_key(XEvent* event, int context) { Binding *b; b = __menu_binding_is_key(menu_bindings_regular, event, context); if (b == NULL) { b = __menu_binding_is_key( menu_bindings_fallback, event, context); } return b; } int menu_binding( Display *dpy, binding_t type, int button, KeySym keysym, int context, int modifier, char *action, char *menu_style) { Binding *rmlist; int rc; Bool dummy; if (menu_bindings == NULL) { menu_bindings = &menu_bindings_fallback; } rmlist = NULL; if (~(~context | C_MENU | C_TITLE | C_MENU_ITEM | C_SIDEBAR) != 0) { fvwm_msg( ERR, "menu_binding", "invalid context in combination with menu context."); return 1; } if (menu_style != NULL) { /*!!! fixme - make either match a menu style or a menu name */ fvwm_msg( ERR, "menu_binding", "a window name may not be" " specified without a menu context."); return 1; } /* * Remove the "old" bindings if any */ /* BEGIN remove */ CollectBindingList( dpy, menu_bindings, &rmlist, &dummy, type, STROKE_ARG(NULL) button, keysym, modifier, context, menu_style); if (rmlist != NULL) { FreeBindingList(rmlist); } else if ( keysym == 0 && button != 0 && modifier == 0 && strcmp(action,"-") == 0 && context == C_MENU) { /* Warn if Mouse n M N - occurs without removing any binding. The user most likely want Mouse n MT A - instead. */ fvwm_msg( WARN, "menu_binding", "The syntax for disabling the tear off button has " "changed."); } if (strcmp(action,"-") == 0) { return 0; } /* END remove */ if ((modifier & AnyModifier) && (modifier & (~AnyModifier))) { fvwm_msg( WARN, "menu_binding", "Binding specified AnyModifier" " and other modifers too. Excess modifiers are" " ignored."); modifier = AnyModifier; } /* Warn about Mouse n M N TearOff. */ if ( keysym == 0 && button != 0 && modifier == 0 && strcasecmp(action,"tearoff") == 0 && context == C_MENU) { fvwm_msg(OLD, "menu_binding", "The syntax for disabling the tear off button has " "changed. The TearOff action is no longer possible " "in menu bindings."); } rc = AddBinding( dpy, menu_bindings, type, STROKE_ARG(NULL) button, keysym, NULL, modifier, context, (void *)action, NULL, menu_style); return rc; } void menu_shortcuts( struct MenuRoot *mr, struct MenuParameters *pmp, struct MenuReturn *pmret, XEvent *event, struct MenuItem **pmi_current, double_keypress *pdkp, int *ret_menu_x, int *ret_menu_y) { int with_control; int with_shift; int with_meta; KeySym keysym; char ckeychar; int ikeychar; MenuItem *new_item; MenuItem *mi_current; int index; int mx; int my; int menu_x; int menu_y; int menu_width; int menu_height; int items_to_move; int do_skip_section; menu_shortcut_action saction; Binding *binding; int context; int is_geometry_known; char *command; ckeychar = 0; new_item = NULL; mi_current = pmi_current ? *pmi_current : NULL; do_skip_section = 0; saction = SA_NONE; context = C_MENU; is_geometry_known = 0; context = C_MENU; command = 0; if (mi_current) { if (MI_IS_TITLE(mi_current)) { context |= C_TITLE; } else { /* menu item context, use I (icon) for it */ context |= C_MENU_ITEM; } } else { if ( menu_get_geometry( mr, &JunkRoot, &menu_x, &menu_y, &menu_width, &menu_height, &JunkBW, &JunkDepth)) { is_geometry_known = 1; if ( FQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, &mx, &my, &JunkX, &JunkY, &JunkMask) == 0) { /* pointer is on a different screen */ mx = 0; my = 0; } else if ( mx >= menu_x && mx < menu_x + menu_width && my >= menu_y && my < menu_y + menu_height) { /* pointer is on the meny somewhere not over * an item */ if (my < menu_y + MST_BORDER_WIDTH(mr)) { /* upper border context (-)*/ context |= C_SB_TOP; } else if ( my >= menu_y + menu_height - MST_BORDER_WIDTH(mr)) { /* lower border context (_) */ context |= C_SB_BOTTOM; } else if (mx < menu_x + MR_ITEM_X_OFFSET(mr)) { /* left border or left sidepic */ context |= C_SB_LEFT; } else if (mx < menu_x + MST_BORDER_WIDTH(mr)) { /* left border context ([)*/ context |= C_SB_LEFT; } else if ( mx >= menu_x + MR_ITEM_X_OFFSET(mr) + MR_ITEM_WIDTH(mr)) { /* right sidepic or right border */ context |= C_SB_RIGHT; } else if ( mx >= menu_x + menu_width - MST_BORDER_WIDTH(mr)) { /* right border context (])*/ context |= C_SB_RIGHT; } } } else { fvwm_msg( ERR, "menu_shortcuts", "can't get geometry of" " menu %s", MR_NAME(mr)); } } if (event->type == KeyRelease) { /* This function is only called with a KeyRelease event if the * user released the 'select' key (s)he configured. */ pmret->rc = MENU_SELECTED; return; } items_to_move = 0; pmret->rc = MENU_NOP; /*** handle mouse events ***/ if (event->type == ButtonRelease) { /*** Read the control keys stats ***/ with_control = event->xbutton.state & ControlMask ? 1 : 0; with_shift = event->xbutton.state & ShiftMask ? 1: 0; with_meta = event->xbutton.state & Mod1Mask ? 1: 0; /** handle menu bindings **/ binding = menu_binding_is_mouse(event, context); if (binding != NULL) { parse_menu_action( mr, binding->Action, &saction, &items_to_move, &do_skip_section, &command); } index = 0; ikeychar = 0; } else /* Should be KeyPressed */ { /*** Read the control keys stats ***/ with_control = event->xkey.state & ControlMask? 1 : 0; with_shift = event->xkey.state & ShiftMask? 1: 0; with_meta = event->xkey.state & Mod1Mask? 1: 0; /*** handle double-keypress ***/ if (pdkp->timestamp && fev_get_evtime() - pdkp->timestamp < MST_DOUBLE_CLICK_TIME(pmp->menu) && event->xkey.state == pdkp->keystate && event->xkey.keycode == pdkp->keycode) { *pmi_current = NULL; pmret->rc = MENU_DOUBLE_CLICKED; return; } pdkp->timestamp = 0; /*** find out the key ***/ /* Is it okay to treat keysym-s as Ascii? * No, because the keypad numbers don't work. * Use XlookupString */ index = XLookupString(&(event->xkey), &ckeychar, 1, &keysym, NULL); ikeychar = (int)ckeychar; } /*** Try to match hot keys ***/ /* Need isascii here - isgraph might coredump! */ if (index == 1 && isascii(ikeychar) && isgraph(ikeychar) && with_control == 0 && with_meta == 0) { /* allow any printable character to be a keysym, but be sure * control isn't pressed */ MenuItem *mi; MenuItem *mi1; int key; int countHotkey = 0; /* if this is a letter set it to lower case */ if (isupper(ikeychar)) { ikeychar = tolower(ikeychar) ; } /* MMH mikehan@best.com 2/7/99 * Multiple hotkeys per menu * Search menu for matching hotkey; * remember how many we found and where we found it */ mi = (mi_current == NULL || mi_current == MR_LAST_ITEM(mr)) ? MR_FIRST_ITEM(mr) : MI_NEXT_ITEM(mi_current); mi1 = mi; do { if (MI_HAS_HOTKEY(mi) && !MI_IS_TITLE(mi) && (!MI_IS_HOTKEY_AUTOMATIC(mi) || MST_USE_AUTOMATIC_HOTKEYS(mr))) { key = (MI_LABEL(mi)[(int)MI_HOTKEY_COLUMN(mi)]) [MI_HOTKEY_COFFSET(mi)]; key = tolower(key); if (ikeychar == key) { if (++countHotkey == 1) { new_item = mi; } } } mi = (mi == MR_LAST_ITEM(mr)) ? MR_FIRST_ITEM(mr) : MI_NEXT_ITEM(mi); } while (mi != mi1); /* For multiple instances of a single hotkey, just move the * selection */ /* TA: 2011-07-24: But if the user has turned off * "UniqueHotkeyActivatedImmediate", keep the menu open until * the user has asked for that entry to be enacted. This also * implies the style "TitleWarpOff" and we're not over a popup * item, in which case the pointer is warped to the submenu in * the usual way. */ if ((countHotkey > 1) || (countHotkey >=1 && ( (!MST_DO_WARP_TO_TITLE(mr) || !MI_IS_POPUP(new_item)) ) && !MST_HOTKEY_ACTIVATES_IMMEDIATE(mr))) { *pmi_current = new_item; pmret->rc = MENU_NEWITEM; return; } /* Do things the old way for unique hotkeys in the menu */ else if (countHotkey == 1) { *pmi_current = new_item; if (new_item && MI_IS_POPUP(new_item)) { pmret->rc = MENU_POPUP; } else { pmret->rc = MENU_SELECTED; } return; } /* MMH mikehan@best.com 2/7/99 */ } /*** now determine the action to take ***/ /** handle menu key bindings **/ if ( event->type == KeyPress && keysym == XK_Escape && with_control == 0 && with_shift == 0 && with_meta == 0) { /* Don't allow override of Escape with no modifiers */ saction = SA_ABORT; } else if (event->type == KeyPress) { binding = menu_binding_is_key(event, context); if (binding != NULL) { parse_menu_action( mr, binding->Action, &saction, &items_to_move, &do_skip_section, &command); } } if ( !mi_current && (saction == SA_ENTER || saction == SA_MOVE_ITEMS || saction == SA_SELECT || saction == SA_SCROLL)) { if (is_geometry_known) { if (my < menu_y + MST_BORDER_WIDTH(mr)) { saction = SA_FIRST; } else if (my > menu_y + menu_height - MST_BORDER_WIDTH(mr)) { saction = SA_LAST; } else { saction = SA_WARPBACK; } } else { saction = SA_FIRST; } } /*** execute the necessary actions ***/ switch (saction) { case SA_ENTER: if (mi_current && MI_IS_POPUP(mi_current)) { pmret->rc = MENU_POPUP; } else { pmret->rc = MENU_NOP; } break; case SA_LEAVE: pmret->rc = (MR_IS_TEAR_OFF_MENU(mr)) ? MENU_NOP : MENU_POPDOWN; break; case SA_FIRST: if (do_skip_section) { *pmi_current = get_selectable_item_from_section( mr, items_to_move); } else { *pmi_current = get_selectable_item_from_index( mr, items_to_move); } if (*pmi_current != NULL) { pmret->rc = MENU_NEWITEM; } else { pmret->rc = MENU_NOP; } break; case SA_LAST: if (do_skip_section) { get_selectable_item_count(mr, &index); index += items_to_move; if (index < 0) { index = 0; } *pmi_current = get_selectable_item_from_section( mr, index); if (*pmi_current != NULL) { pmret->rc = MENU_NEWITEM; } else { pmret->rc = MENU_NOP; } } else { index = get_selectable_item_count(mr, NULL); if (index > 0) { index += items_to_move; if (index < 0) { index = 0; } *pmi_current = get_selectable_item_from_index( mr, index); pmret->rc = (*pmi_current) ? MENU_NEWITEM : MENU_NOP; } else { pmret->rc = MENU_NOP; } } break; case SA_MOVE_ITEMS: if (do_skip_section) { int section; int count; get_selectable_item_count(mr, &count); get_selectable_item_index(mr, mi_current, §ion); section += items_to_move; if (section < 0) section = count; else if (section > count) section = 0; index = section; } else if (items_to_move < 0) { index = get_selectable_item_index( mr, mi_current, NULL); if (index == 0) /* wraparound */ index = get_selectable_item_count(mr, NULL); else { index += items_to_move; } } else { index = get_selectable_item_index( mr, mi_current, NULL) + items_to_move; /* correct for the case that we're between items */ if (!MI_IS_SELECTABLE(mi_current)) { index--; } } if (do_skip_section) { new_item = get_selectable_item_from_section(mr, index); } else { new_item = get_selectable_item_from_index(mr, index); if (items_to_move > 0 && new_item == mi_current) { new_item = get_selectable_item_from_index(mr, 0); } } if (new_item) { *pmi_current = new_item; pmret->rc = MENU_NEWITEM; } else { pmret->rc = MENU_NOP; } break; case SA_CONTINUE: *pmi_current = MR_LAST_ITEM(mr); if (*pmi_current && MI_IS_POPUP(*pmi_current)) { /* enter the submenu */ pmret->rc = MENU_POPUP; } else { /* do nothing */ *pmi_current = mi_current; pmret->rc = MENU_NOP; } break; case SA_WARPBACK: /* Warp the pointer back into the menu. */ FWarpPointer( dpy, 0, MR_WINDOW(mr), 0, 0, 0, 0, menudim_middle_x_offset(&MR_DIM(mr)), my - menu_y); pmret->rc = MENU_NEWITEM_FIND; break; case SA_SELECT: pmret->rc = MENU_SELECTED; return; case SA_ABORT: pmret->rc = (MR_IS_TEAR_OFF_MENU(mr)) ? MENU_KILL_TEAR_OFF_MENU : MENU_ABORTED; return; case SA_TEAROFF: pmret->rc = (MR_IS_TEAR_OFF_MENU(mr)) ? MENU_NOP : MENU_TEAR_OFF; return; case SA_SCROLL: if (MST_MOUSE_WHEEL(mr) == MMW_MENU) { items_to_move *= -1; } if ( !menu_get_outer_geometry( mr, pmp, &JunkRoot, &menu_x, &menu_y, &JunkWidth, &menu_height, &JunkBW, &JunkDepth)) { fvwm_msg( ERR, "menu_shortcuts", "can't get geometry of menu %s", MR_NAME(mr)); return; } if (do_skip_section) { int count; get_selectable_item_count(mr, &count); get_selectable_item_index(mr, mi_current, &index); index += items_to_move; if (index < 0) { index = 0; } else if (index > count) { index = count; } new_item = get_selectable_item_from_section(mr, index); } else { index = get_selectable_item_index( mr, mi_current, NULL); if (items_to_move > 0 && !MI_IS_SELECTABLE(mi_current)) { index--; } index += items_to_move; new_item = get_selectable_item_from_index(mr, index); } if ( new_item && ((items_to_move < 0 && MI_Y_OFFSET(new_item) > MI_Y_OFFSET(mi_current)) || (items_to_move > 0 && MI_Y_OFFSET(new_item) < MI_Y_OFFSET(mi_current)))) { /* never scroll in the "wrong" direction */ new_item = NULL; } if (new_item) { *pmi_current = new_item; pmret->rc = MENU_NEWITEM; /* Have to work with relative positions or tear off * menus will be hard to reposition */ if ( FQueryPointer( dpy, MR_WINDOW(mr), &JunkRoot, &JunkChild, &JunkX, &JunkY, &mx, &my, &JunkMask) == 0) { /* This should not happen */ mx = 0; my = 0; } if (MST_MOUSE_WHEEL(mr) == MMW_POINTER) { if (event->type == ButtonRelease) { FWarpPointer( dpy, 0, 0, 0, 0, 0, 0, 0, -my + menuitem_middle_y_offset( new_item, MR_STYLE(mr))); } /* pointer wrapped elsewhere for key events */ } else { int old_y = menu_y; menu_y += my - menuitem_middle_y_offset( new_item, MR_STYLE(mr)); if ( !MST_SCROLL_OFF_PAGE(mr) && menu_height < MR_SCREEN_HEIGHT(mr)) { if (menu_y < 0) { FWarpPointer(dpy, 0, 0, 0, 0, 0, 0, 0,-menu_y); menu_y=0; } if ( menu_y + menu_height > MR_SCREEN_HEIGHT(mr)) { FWarpPointer( dpy, 0, 0, 0, 0, 0, 0, 0, MR_SCREEN_HEIGHT(mr) - menu_y - menu_height); menu_y = MR_SCREEN_HEIGHT(mr) - menu_height; } } if (old_y != menu_y) { pmret->rc = MENU_NEWITEM_MOVEMENU; *ret_menu_x = menu_x; *ret_menu_y = menu_y; } else { pmret->rc = MENU_NEWITEM; } } } else { pmret->rc = MENU_NOP; } break; case SA_EXEC_CMD: pmret->rc = MENU_EXEC_CMD; *pmp->ret_paction = command; break; case SA_NONE: default: pmret->rc = MENU_NOP; break; } if (saction != SA_SCROLL && pmret->rc == MENU_NEWITEM) { if (!menu_get_outer_geometry( mr, pmp, &JunkRoot, &menu_x, &menu_y, &JunkWidth, &menu_height, &JunkBW, &JunkDepth)) { fvwm_msg( ERR, "menu_shortcuts", "can't get geometry of menu %s", MR_NAME(mr)); return; } if (menu_y < 0 || menu_y + menu_height > MR_SCREEN_HEIGHT(mr)) { menu_y = (menu_y < 0) ? 0 : MR_SCREEN_HEIGHT(mr) - menu_height; pmret->rc = MENU_NEWITEM_MOVEMENU; *ret_menu_x = menu_x; *ret_menu_y = menu_y; } } return; } fvwm-2.6.7/fvwm/windowshade.c0000644000175700017570000001343213001406607013103 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "misc.h" #include "commands.h" #include "screen.h" #include "module_list.h" #include "module_interface.h" #include "geometry.h" #include "ewmh.h" #include "borders.h" #include "frame.h" #include "focus.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* ---------------------------- builtin commands --------------------------- */ /* * * WindowShade -- shades or unshades a window (veliaa@rpi.edu) * * Args: 1 -- shade, 2 -- unshade No Arg: toggle * */ void CMD_WindowShade(F_CMD_ARGS) { direction_t shade_dir; int toggle; frame_move_resize_mode resize_mode; rectangle start_g; rectangle end_g; frame_move_resize_args mr_args; char *token; char *naction; Bool do_force_shading; Bool has_dir; FvwmWindow * const fw = exc->w.fw; if (IS_ICONIFIED(fw) || IS_EWMH_FULLSCREEN(fw)) { return; } token = PeekToken(action, &naction); if (StrEquals("shadeagain", token)) { do_force_shading = True; action = naction; token = PeekToken(action, &naction); } else { do_force_shading = False; } /* parse arguments */ if (StrEquals("Last", token)) { /* last given instead of a direction will make * fvwm to reuse the last used shading direction. * A new, nevershaded window will have * USED_TITLE_DIR_FOR_SHADING set (in add_window.c: * setup_window_structure) */ action = naction; if (!USED_TITLE_DIR_FOR_SHADING(fw)) { shade_dir = SHADED_DIR(fw); } else { shade_dir = DIR_NONE; } } else { /* parse normal direction if last was not given */ shade_dir = gravity_parse_dir_argument(action, NULL, -1); } if (shade_dir >= 0 && shade_dir <= DIR_MASK) { has_dir = True; toggle = (!IS_SHADED(fw) || SHADED_DIR(fw) != shade_dir); } else { has_dir = False; toggle = ParseToggleArgument(action, NULL, -1, 0); if (toggle == -1 && GetIntegerArguments(action, NULL, &toggle, 1) > 0) { if (toggle == 1) { toggle = 1; } else if (toggle == 2) { toggle = 0; } else { toggle = -1; } } if (toggle == -1) { toggle = !(IS_SHADED(fw)); } if (!IS_SHADED(fw) && toggle == 1) { shade_dir = GET_TITLE_DIR(fw); } else if (IS_SHADED(fw) && toggle == 0) { shade_dir = SHADED_DIR(fw); } else { shade_dir = -1; } } if (!IS_SHADED(fw) && toggle == 0) { /* nothing to do */ return; } if (IS_SHADED(fw) && toggle == 1) { if (has_dir == False) { /* nothing to do */ return; } else if (do_force_shading == False) { toggle = 0; } else if (shade_dir == SHADED_DIR(fw)) { return; } } if (toggle == 1) { SET_USED_TITLE_DIR_FOR_SHADING(fw, !has_dir); } /* draw the animation */ start_g = fw->g.frame; get_unshaded_geometry(fw, &end_g); if (toggle == 1) { get_shaded_geometry_with_dir(fw, &end_g, &end_g, shade_dir); } resize_mode = (DO_SHRINK_WINDOWSHADE(fw)) ? FRAME_MR_SHRINK : FRAME_MR_SCROLL; mr_args = frame_create_move_resize_args( fw, resize_mode, &start_g, &end_g, fw->shade_anim_steps, shade_dir); frame_move_resize(fw, mr_args); /* Set the new shade value before destroying the args but after the * animation. */ SET_SHADED(fw, toggle); if (toggle == 1) { SET_SHADED_DIR(fw, shade_dir); } frame_free_move_resize_args(fw, mr_args); border_draw_decorations( fw, PART_TITLEBAR, (fw == get_focus_window()) ? True : False, 0, CLEAR_BUTTONS, NULL, NULL); /* update hints and inform modules */ BroadcastConfig(M_CONFIGURE_WINDOW, fw); BroadcastPacket( (toggle == 1) ? M_WINDOWSHADE : M_DEWINDOWSHADE, 3, (long)FW_W(fw), (long)FW_W_FRAME(fw), (unsigned long)fw); FlushAllMessageQueues(); XFlush(dpy); EWMH_SetWMState(fw, False); return; } /* set the number or size of shade animation steps, N => steps, Np => pixels */ void CMD_WindowShadeAnimate(F_CMD_ARGS) { char *buf; if (!action) { action = ""; } fvwm_msg( ERR, "CMD_WindowShadeAnimate", "The WindowShadeAnimate command is obsolete. " "Please use 'Style * WindowShadeSteps %s' instead.", action); buf = safemalloc(strlen(action) + 32); sprintf(buf, "* WindowShadeSteps %s", action); action = buf; CMD_Style(F_PASS_ARGS); free(buf); return; } fvwm-2.6.7/fvwm/style.h0000644000175700017570000005417212773467232011762 00000000000000/* -*-c-*- */ #ifndef _STYLE_ #define _STYLE_ /* The default title in case the user doesn't supply one. */ #define DEFAULT_TITLE_FORMAT "%n" /* access to the special flags of a style */ /* call these with a pointer to a style_flags struct */ #define SDO_DECORATE_TRANSIENT(sf) \ ((sf)->do_decorate_transient) #define SDO_SAVE_UNDER(sf) \ ((sf)->do_save_under) #define SDO_START_LOWERED(sf) \ ((sf)->do_start_lowered) #define SDO_START_SHADED(sf) \ ((sf)->do_start_shaded) #define SHAS_BORDER_WIDTH(sf) \ ((sf)->has_border_width) #define SHAS_COLOR_BACK(sf) \ ((sf)->has_color_back) #define SHAS_COLOR_FORE(sf) \ ((sf)->has_color_fore) #define SHAS_HANDLE_WIDTH(sf) \ ((sf)->has_handle_width) #define SHAS_ICON(sf) \ ((sf)->has_icon) #define SHAS_ICON_BOXES(sf) \ ((sf)->has_icon_boxes) #define SHAS_ICON_SIZE_LIMITS(sf) \ ((sf)->has_icon_size_limits) #define SHAS_ICON_BACKGROUND_PADDING(sf) \ ((sf)->has_icon_background_padding) #define SHAS_ICON_BACKGROUND_RELIEF(sf) \ ((sf)->has_icon_background_relief) #define SHAS_ICON_TITLE_RELIEF(sf) \ ((sf)->has_icon_title_relief) #define SHAS_MIN_WINDOW_SIZE(sf) \ ((sf)->has_min_window_size) #define SHAS_MAX_WINDOW_SIZE(sf) \ ((sf)->has_max_window_size) #define SHAS_WINDOW_SHADE_STEPS(sf) \ ((sf)->has_window_shade_steps) #define SHAS_MINI_ICON(sf) \ ((sf)->has_mini_icon) #define SHAS_MWM_DECOR(sf) \ ((sf)->has_mwm_decor) #define SHAS_MWM_FUNCTIONS(sf) \ ((sf)->has_mwm_functions) #define SHAS_NO_HANDLES(sf) \ ((sf)->has_no_handles) #define SHAS_NO_TITLE(sf) \ ((sf)->has_no_title) #define SHAS_OL_DECOR(sf) \ ((sf)->has_ol_decor) #define SIS_BUTTON_DISABLED(sf) \ ((sf)->is_button_disabled) #define SIS_UNMANAGED(sf) \ ((sf)->is_unmanaged) #define SPLACEMENT_MODE(sf) \ ((sf)->placement_mode) #define SEWMH_PLACEMENT_MODE(sf) \ ((sf)->ewmh_placement_mode) #define SUSE_BACKING_STORE(sf) \ ((sf)->use_backing_store) #define SUSE_PARENT_RELATIVE(sf) \ ((sf)->use_parent_relative) #define SUSE_COLORSET(sf) \ ((sf)->use_colorset) #define SUSE_COLORSET_HI(sf) \ ((sf)->use_colorset_hi) #define SUSE_BORDER_COLORSET(sf) \ ((sf)->use_border_colorset) #define SUSE_BORDER_COLORSET_HI(sf) \ ((sf)->use_border_colorset_hi) #define SUSE_ICON_TITLE_COLORSET(sf) \ ((sf)->use_icon_title_colorset) #define SUSE_ICON_TITLE_COLORSET_HI(sf) \ ((sf)->use_icon_title_colorset_hi) #define SUSE_ICON_BACKGROUND_COLORSET(sf) \ ((sf)->use_icon_background_colorset) #define SUSE_LAYER(sf) \ ((sf)->use_layer) #define SUSE_NO_PPOSITION(sf) \ ((sf)->use_no_pposition) #define SUSE_NO_USPOSITION(sf) \ ((sf)->use_no_usposition) #define SUSE_NO_TRANSIENT_PPOSITION(sf) \ ((sf)->use_no_transient_pposition) #define SUSE_NO_TRANSIENT_USPOSITION(sf) \ ((sf)->use_no_transient_usposition) #define SUSE_START_ON_DESK(sf) \ ((sf)->use_start_on_desk) #define SUSE_START_ON_PAGE_FOR_TRANSIENT(sf) \ ((sf)->use_start_on_page_for_transient) #define SUSE_START_ON_SCREEN(sf) \ ((sf)->use_start_on_screen) #define SMANUAL_PLACEMENT_HONORS_STARTS_ON_PAGE(sf) \ ((sf)->manual_placement_honors_starts_on_page) #define SCAPTURE_HONORS_STARTS_ON_PAGE(sf) \ ((sf)->capture_honors_starts_on_page) #define SRECAPTURE_HONORS_STARTS_ON_PAGE(sf) \ ((sf)->recapture_honors_starts_on_page) #define SHAS_PLACEMENT_PENALTY(sf) \ ((sf)->has_placement_penalty) #define SHAS_PLACEMENT_PERCENTAGE_PENALTY(sf) \ ((sf)->has_placement_percentage_penalty) #define SHAS_PLACEMENT_POSITION_STRING(sf) \ ((sf)->has_placement_position_string #define SCR_MOTION_METHOD(sf) \ ((sf)->ws_cr_motion_method) /* access the various copies of the common flags structure. */ #define SCF(st) \ ((st).flags.common) #define SCFS(st) \ ((st).flags.common.s) #define SCM(st) \ ((st).flag_mask.common) #define SCMS(st) \ ((st).flag_mask.common.s) #define SCD(st) \ ((st).flag_default.common) #define SCDS(st) \ ((st).flag_default.common.s) #define SCC(st) \ ((st).change_mask.common) #define SCCS(st) \ ((st).change_mask.common.s) #define SFC(sf) \ ((sf).common) /* access to common flags */ #define S_FOCUS_POLICY(c) \ ((c).s.focus_policy) #define S_TITLE_DIR(c) \ ((c).title_dir) #define S_SET_TITLE_DIR(c,x) \ ((c).title_dir = (x)) #define S_USER_STATES(c) \ ((c).user_states) #define S_SET_USER_STATES(c,x) \ ((c).user_states = (x)) #define S_ADD_USER_STATES(c,x) \ ((c).user_states = ((c).user_states | (x))) #define S_IS_STICKY_ACROSS_PAGES(c) \ ((c).is_sticky_across_pages) #define S_SET_IS_STICKY_ACROSS_PAGES(c,x) \ ((c).is_sticky_across_pages = !!(x)) #define S_IS_STICKY_ACROSS_DESKS(c) \ ((c).is_sticky_across_desks) #define S_SET_IS_STICKY_ACROSS_DESKS(c,x) \ ((c).is_sticky_across_desks = !!(x)) #define S_DO_CIRCULATE_SKIP(c) \ ((c).s.do_circulate_skip) #define S_SET_DO_CIRCULATE_SKIP(c,x) \ ((c).s.do_circulate_skip = !!(x)) #define S_DO_CIRCULATE_SKIP_ICON(c) \ ((c).s.do_circulate_skip_icon) #define S_SET_DO_CIRCULATE_SKIP_ICON(c,x) \ ((c).s.do_circulate_skip_icon = !!(x)) #define S_DO_CIRCULATE_SKIP_SHADED(c) \ ((c).s.do_circulate_skip_shaded) #define S_SET_DO_CIRCULATE_SKIP_SHADED(c,x) \ ((c).s.do_circulate_skip_shaded = !!(x)) #define S_DO_ICONIFY_WINDOW_GROUPS(c) \ ((c).s.do_iconify_window_groups) #define S_SET_DO_ICONIFY_WINDOW_GROUPS(c,x) \ ((c).s.do_iconify_window_groups = !!(x)) #define S_DO_IGNORE_ICON_BOXES(c) \ ((c).s.do_ignore_icon_boxes) #define S_SET_DO_IGNORE_ICON_BOXES(c,x) \ ((c).s.do_ignore_icon_boxes = !!(x)) #define S_DO_IGNORE_RESTACK(c) \ ((c).s.do_ignore_restack) #define S_SET_DO_IGNORE_RESTACK(c,x) \ ((c).s.do_ignore_restack = !!(x)) #define S_DO_USE_WINDOW_GROUP_HINT(c) \ ((c).s.do_use_window_group_hint) #define S_SET_DO_USE_WINDOW_GROUP_HINT(c,x) \ ((c).s.do_use_window_group_hint = !!(x)) #define S_DO_LOWER_TRANSIENT(c) \ ((c).s.do_lower_transient) #define S_SET_DO_LOWER_TRANSIENT(c,x) \ ((c).s.do_lower_transient = !!(x)) #define S_DO_NOT_SHOW_ON_MAP(c) \ ((c).s.do_not_show_on_map) #define S_SET_DO_NOT_SHOW_ON_MAP(c,x) \ ((c).s.do_not_show_on_map = !!(x)) #define S_DO_RAISE_TRANSIENT(c) \ ((c).s.do_raise_transient) #define S_SET_DO_RAISE_TRANSIENT(c,x) \ ((c).s.do_raise_transient = !!(x)) #define S_DO_RESIZE_OPAQUE(c) \ ((c).s.do_resize_opaque) #define S_SET_DO_RESIZE_OPAQUE(c,x) \ ((c).s.do_resize_opaque = !!(x)) #define S_DO_SHRINK_WINDOWSHADE(c) \ ((c).s.do_shrink_windowshade) #define S_SET_DO_SHRINK_WINDOWSHADE(c,x) \ ((c).s.do_shrink_windowshade = !!(x)) #define S_DO_STACK_TRANSIENT_PARENT(c) \ ((c).s.do_stack_transient_parent) #define S_SET_DO_STACK_TRANSIENT_PARENT(c,x) \ ((c).s.do_stack_transient_parent = !!(x)) #define S_DO_WINDOW_LIST_SKIP(c) \ ((c).s.do_window_list_skip) #define S_SET_DO_WINDOW_LIST_SKIP(c,x) \ ((c).s.do_window_list_skip = !!(x)) #define S_HAS_NO_BORDER(c) \ ((c).has_no_border) #define S_SET_HAS_NO_BORDER(c,x) \ ((c).has_no_border = !!(x)) #define S_HAS_DEPRESSABLE_BORDER(c) \ ((c).s.has_depressable_border) #define S_SET_HAS_DEPRESSABLE_BORDER(c,x) \ ((c).s.has_depressable_border = !!(x)) #define S_HAS_ICON_FONT(c) \ ((c).has_icon_font) #define S_SET_HAS_ICON_FONT(c,x) \ ((c).has_icon_font = !!(x)) #define S_HAS_MWM_BORDER(c) \ ((c).s.has_mwm_border) #define S_SET_HAS_MWM_BORDER(c,x) \ ((c).s.has_mwm_border = !!(x)) #define S_HAS_MWM_BUTTONS(c) \ ((c).s.has_mwm_buttons) #define S_SET_HAS_MWM_BUTTONS(c,x) \ ((c).s.has_mwm_buttons = !!(x)) #define S_HAS_MWM_OVERRIDE(c) \ ((c).s.has_mwm_override) #define S_SET_HAS_MWM_OVERRIDE(c,x) \ ((c).s.has_mwm_override = !!(x)) #define S_HAS_NO_STICKY_STIPPLED_ICON_TITLE(c) \ ((c).s.has_no_sticky_stippled_icon_title) #define S_SET_HAS_NO_STICKY_STIPPLED_ICON_TITLE(c,x) \ ((c).s.has_no_sticky_stippled_icon_title = !!(x)) #define S_HAS_NO_ICON_TITLE(c) \ ((c).s.has_no_icon_title) #define S_SET_HAS_NO_ICON_TITLE(c,x) \ ((c).s.has_no_icon_title = !!(x)) #define S_HAS_OVERRIDE_SIZE(c) \ ((c).s.has_override_size) #define S_SET_HAS_OVERRIDE_SIZE(c,x) \ ((c).s.has_override_size = !!(x)) #define S_HAS_STIPPLED_TITLE(c) \ ((c).s.has_stippled_title) #define S_SET_HAS_STIPPLED_TITLE(c,x) \ ((c).s.has_stippled_title = !!(x)) #define S_HAS_NO_STICKY_STIPPLED_TITLE(c) \ ((c).s.has_no_sticky_stippled_title) #define S_SET_HAS_NO_STICKY_STIPPLED_TITLE(c,x) \ ((c).s.has_no_sticky_stippled_title = !!(x)) #define S_HAS_STIPPLED_ICON_TITLE(c) \ ((c).s.has_stippled_icon_title) #define S_SET_HAS_STIPPLED_ICON_TITLE(c,x) \ ((c).s.has_stippled_icon_title = !!(x)) #define S_HAS_WINDOW_FONT(c) \ ((c).has_window_font) #define S_SET_HAS_WINDOW_FONT(c,x) \ ((c).has_window_font = !!(x)) #define S_ICON_OVERRIDE(c) \ ((c).s.icon_override) #define S_SET_ICON_OVERRIDE(c,x) \ ((c).s.icon_override = (x)) #define S_IS_BOTTOM_TITLE_ROTATED(c) \ ((c).s.is_bottom_title_rotated) #define S_SET_IS_BOTTOM_TITLE_ROTATED(c,x) \ ((c).s.is_bottom_title_rotated = !!(x)) #define S_IS_FIXED(c) \ ((c).s.is_fixed) #define S_SET_IS_FIXED(c,x) \ ((c).s.is_fixed = !!(x)) #define S_IS_FIXED_PPOS(c) \ ((c).s.is_fixed_ppos) #define S_SET_IS_FIXED_PPOS(c,x) \ ((c).s.is_fixed_ppos = !!(x)) #define S_SET_IS_UNICONIFIABLE(c,x) \ ((c).s.is_uniconifiable = !!(x)) #define S_SET_IS_UNMAXIMIZABLE(c,x) \ ((c).s.is_unmaximizable = !!(x)) #define S_SET_IS_UNCLOSABLE(c,x) \ ((c).s.is_unclosable = !!(x)) #define S_SET_MAXIMIZE_FIXED_SIZE_DISALLOWED(c,x) \ ((c).s.is_maximize_fixed_size_disallowed = !!(x)) #define S_IS_ICON_STICKY_ACROSS_PAGES(c) \ ((c).s.is_icon_sticky_across_pages) #define S_SET_IS_ICON_STICKY_ACROSS_PAGES(c,x) \ ((c).s.is_icon_sticky_across_pages = !!(x)) #define S_IS_ICON_STICKY_ACROSS_DESKS(c) \ ((c).s.is_icon_sticky_across_desks) #define S_SET_IS_ICON_STICKY_ACROSS_DESKS(c,x) \ ((c).s.is_icon_sticky_across_desks = !!(x)) #define S_IS_ICON_SUPPRESSED(c) \ ((c).s.is_icon_suppressed) #define S_SET_IS_ICON_SUPPRESSED(c,x) \ ((c).s.is_icon_suppressed = !!(x)) #define S_IS_LEFT_TITLE_ROTATED_CW(c) \ ((c).s.is_left_title_rotated_cw) #define S_SET_IS_LEFT_TITLE_ROTATED_CW(c,x) \ ((c).s.is_left_title_rotated_cw = !!(x)) #define S_IS_SIZE_FIXED(c) \ ((c).s.is_size_fixed) #define S_SET_IS_SIZE_FIXED(c,x) \ ((c).s.is_size_fixed = !!(x)) #define S_IS_PSIZE_FIXED(c) \ ((c).s.is_psize_fixed) #define S_SET_IS_PSIZE_FIXED(c,x) \ ((c).s.is_psize_fixed = !!(x)) #define S_IS_RIGHT_TITLE_ROTATED_CW(c) \ ((c).s.is_right_title_rotated_cw) #define S_SET_IS_RIGHT_TITLE_ROTATED_CW(c,x) \ ((c).s.is_right_title_rotated_cw = !!(x)) #define S_IS_TOP_TITLE_ROTATED(c) \ ((c).s.is_top_title_rotated) #define S_SET_IS_TOP_TITLE_ROTATED(c,x) \ ((c).s.is_top_title_rotated = !!(x)) #define S_USE_ICON_POSITION_HINT(c) \ ((c).s.use_icon_position_hint) #define S_SET_USE_ICON_POSITION_HINT(c,x) \ ((c).s.use_icon_position_hint = !!(x)) #define S_USE_INDEXED_WINDOW_NAME(c) \ ((c).s.use_indexed_window_name) #define S_SET_USE_INDEXED_WINDOW_NAME(c,x) \ ((c).s.use_indexed_window_name = !!(x)) #define S_USE_INDEXED_ICON_NAME(c) \ ((c).s.use_indexed_icon_name) #define S_SET_USE_INDEXED_ICON_NAME(c,x) \ ((c).s.use_indexed_icon_name = !!(x)) #define S_WINDOWSHADE_LAZINESS(c) \ ((c).s.windowshade_laziness) #define S_SET_WINDOWSHADE_LAZINESS(c,x) \ ((c).s.windowshade_laziness = (x)) #define S_USE_TITLE_DECOR_ROTATION(c) \ ((c).s.use_title_decor_rotation) #define S_SET_USE_TITLE_DECOR_ROTATION(c,x) \ ((c).s.use_title_decor_rotation = !!(x)) #define S_DO_EWMH_MINI_ICON_OVERRIDE(c) \ ((c).s.do_ewmh_mini_icon_override) #define S_SET_DO_EWMH_MINI_ICON_OVERRIDE(c,x) \ ((c).s.do_ewmh_mini_icon_override = !!(x)) #define S_DO_EWMH_DONATE_ICON(c) \ ((c).s.do_ewmh_donate_icon) #define S_SET_DO_EWMH_DONATE_ICON(c,x) \ ((c).s.do_ewmh_donate_icon = !!(x)) #define S_DO_EWMH_DONATE_MINI_ICON(c) \ ((c).s.do_ewmh_donate_mini_icon) #define S_SET_DO_EWMH_DONATE_MINI_ICON(c,x) \ ((c).s.do_ewmh_donate_mini_icon = !!(x)) #define S_DO_EWMH_USE_STACKING_HINTS(c) \ ((c).s.do_ewmh_use_stacking_hints) #define S_SET_DO_EWMH_USE_STACKING_HINTS(c,x) \ ((c).s.do_ewmh_use_stacking_hints = !!(x)) #define S_DO_EWMH_IGNORE_STRUT_HINTS(c) \ ((c).s.do_ewmh_ignore_strut_hints) #define S_SET_DO_EWMH_IGNORE_STRUT_HINTS(c,x) \ ((c).s.do_ewmh_ignore_strut_hints = !!(x)) #define S_DO_EWMH_IGNORE_STATE_HINTS(c) \ ((c).s.do_ewmh_ignore_state_hints) #define S_SET_DO_EWMH_IGNORE_STATE_HINTS(c,x) \ ((c).s.do_ewmh_ignore_state_hints = !!(x)) #define S_DO_EWMH_IGNORE_WINDOW_TYPE(c) \ ((c).s.do_ewmh_ignore_window_type) #define S_SET_DO_EWMH_IGNORE_WINDOW_TYPE(c,x) \ ((c).s.do_ewmh_ignore_window_type = !!(x)) #define S_EWMH_MAXIMIZE_MODE(c) \ ((c).s.ewmh_maximize_mode) #define S_SET_EWMH_MAXIMIZE_MODE(c,x) \ ((c).s.ewmh_maximize_mode = (x)) /* access to style_id */ #define SID_GET_NAME(id) \ ((id).name) #define SID_SET_NAME(id,x) \ ((id).name = (x)) #define SID_GET_WINDOW_ID(id) \ ((id).window_id) #define SID_SET_WINDOW_ID(id,x) \ ((id).window_id = (x)) #define SID_SET_HAS_NAME(id,x) \ ((id).flags.has_name = !!(x)) #define SID_GET_HAS_NAME(id) \ ((id).flags.has_name) #define SID_SET_HAS_WINDOW_ID(id,x) \ ((id).flags.has_window_id = !!(x)) #define SID_GET_HAS_WINDOW_ID(id) \ ((id).flags.has_window_id) /* access to other parts of a style (call with the style itself) */ #define SGET_NEXT_STYLE(s) \ ((s).next) #define SSET_NEXT_STYLE(s,x) \ ((s).next = (x)) #define SGET_PREV_STYLE(s) \ ((s).prev) #define SSET_PREV_STYLE(s,x) \ ((s).prev = (x)) #define SGET_ID(s) \ ((s).id) #define SGET_NAME(s) \ SID_GET_NAME(SGET_ID(s)) #define SSET_NAME(s,x) \ SID_SET_NAME(SGET_ID(s),x) #define SGET_WINDOW_ID(s) \ SID_GET_WINDOW_ID(SGET_ID(s)) #define SSET_WINDOW_ID(s,x) \ SID_SET_WINDOW_ID(SGET_ID(s),x) #define SSET_ID_HAS_NAME(s,x) \ SID_SET_HAS_NAME(SGET_ID(s), x) #define SGET_ID_HAS_NAME(s) \ SID_GET_HAS_NAME(SGET_ID(s)) #define SSET_ID_HAS_WINDOW_ID(s,x) \ SID_SET_HAS_WINDOW_ID(SGET_ID(s),x) #define SGET_ID_HAS_WINDOW_ID(s) \ SID_GET_HAS_WINDOW_ID(SGET_ID(s)) #define SGET_ICON_NAME(s) \ ((s).icon_name) #define SSET_ICON_NAME(s,x) \ ((s).icon_name = (x)) #define SGET_MINI_ICON_NAME(s) \ ((s).mini_icon_name) #define SSET_MINI_ICON_NAME(s,x) \ ((s).mini_icon_name = (x)) #define SGET_DECOR_NAME(s) \ ((s).decor_name) #define SSET_DECOR_NAME(s,x) \ ((s).decor_name = (x)) #define SGET_FORE_COLOR_NAME(s) \ ((s).fore_color_name) #define SSET_FORE_COLOR_NAME(s,x) \ ((s).fore_color_name = (x)) #define SGET_BACK_COLOR_NAME(s) \ ((s).back_color_name) #define SSET_BACK_COLOR_NAME(s,x) \ ((s).back_color_name = (x)) #define SGET_FORE_COLOR_NAME_HI(s) \ ((s).fore_color_name_hi) #define SSET_FORE_COLOR_NAME_HI(s,x) \ ((s).fore_color_name_hi = (x)) #define SGET_BACK_COLOR_NAME_HI(s) \ ((s).back_color_name_hi) #define SSET_BACK_COLOR_NAME_HI(s,x) \ ((s).back_color_name_hi = (x)) #define SGET_ICON_FONT(s) \ ((s).icon_font) #define SSET_ICON_FONT(s,x) \ ((s).icon_font = (x)) #define SGET_WINDOW_FONT(s) \ ((s).window_font) #define SSET_WINDOW_FONT(s,x) \ ((s).window_font = (x)) #define SGET_COLORSET(s) \ ((s).colorset) #define SSET_COLORSET(s,x) \ ((s).colorset = (x)) #define SSET_BORDER_COLORSET(s,x) \ ((s).border_colorset = (x)) #define SGET_BORDER_COLORSET(s) \ ((s).border_colorset) #define SGET_COLORSET_HI(s) \ ((s).colorset_hi) #define SSET_COLORSET_HI(s,x) \ ((s).colorset_hi = (x)) #define SGET_BORDER_COLORSET_HI(s) \ ((s).border_colorset_hi) #define SSET_BORDER_COLORSET_HI(s,x) \ ((s).border_colorset_hi = (x)) #define SSET_ICON_TITLE_COLORSET(s,x) \ ((s).icon_title_colorset = (x)) #define SGET_ICON_TITLE_COLORSET(s) \ ((s).icon_title_colorset) #define SSET_ICON_TITLE_COLORSET_HI(s,x) \ ((s).icon_title_colorset_hi = (x)) #define SGET_ICON_TITLE_COLORSET_HI(s) \ ((s).icon_title_colorset_hi) #define SSET_ICON_BACKGROUND_COLORSET(s,x) \ ((s).icon_background_colorset = (x)) #define SGET_ICON_BACKGROUND_COLORSET(s) \ ((s).icon_background_colorset) #define SGET_FLAGS_POINTER(s) \ (&((s).flags)) #define SGET_BORDER_WIDTH(s) \ ((s).border_width) #define SSET_BORDER_WIDTH(s,x) \ ((s).border_width = (x)) #define SGET_HANDLE_WIDTH(s) \ ((s).handle_width) #define SSET_HANDLE_WIDTH(s,x) \ ((s).handle_width = (x)) #define SGET_LAYER(s) \ ((s).layer) #define SSET_LAYER(s,x) \ ((s).layer = (x)) #define SGET_START_DESK(s) \ ((s).start_desk) #define SSET_START_DESK(s,x) \ ((s).start_desk = (x)) #define SGET_START_PAGE_X(s) \ ((s).start_page_x) #define SSET_START_PAGE_X(s,x) \ ((s).start_page_x = (x)) #define SGET_START_PAGE_Y(s) \ ((s).start_page_y) #define SSET_START_PAGE_Y(s,x) \ ((s).start_page_y = (x)) #define SGET_START_SCREEN(s) \ ((s).start_screen) #define SSET_START_SCREEN(s,x) \ ((s).start_screen = (x)) #define SSET_STARTS_SHADED_DIR(s,x) \ ((s).flags.start_shaded_dir = (x)) #define SGET_STARTS_SHADED_DIR(s) \ ((s).flags.start_shaded_dir) #define SGET_MIN_ICON_WIDTH(s) \ ((s).min_icon_width) #define SSET_MIN_ICON_WIDTH(s,x) \ ((s).min_icon_width = (x)) #define SGET_MIN_ICON_HEIGHT(s) \ ((s).min_icon_height) #define SSET_MIN_ICON_HEIGHT(s,x) \ ((s).min_icon_height = (x)) #define SGET_MAX_ICON_WIDTH(s) \ ((s).max_icon_width) #define SSET_MAX_ICON_WIDTH(s,x) \ ((s).max_icon_width = (x)) #define SGET_MAX_ICON_HEIGHT(s) \ ((s).max_icon_height) #define SSET_MAX_ICON_HEIGHT(s,x) \ ((s).max_icon_height = (x)) #define SGET_ICON_RESIZE_TYPE(s) \ ((s).icon_resize_type) #define SSET_ICON_RESIZE_TYPE(s,x) \ ((s).icon_resize_type = (x)) #define SGET_ICON_BACKGROUND_RELIEF(s) \ ((s).icon_background_relief) #define SSET_ICON_BACKGROUND_RELIEF(s,x) \ ((s).icon_background_relief = (x)) #define SGET_ICON_BACKGROUND_PADDING(s) \ ((s).icon_background_padding) #define SSET_ICON_BACKGROUND_PADDING(s,x) \ ((s).icon_background_padding = (x)) #define SGET_ICON_TITLE_RELIEF(s) \ ((s).icon_title_relief) #define SSET_ICON_TITLE_RELIEF(s,x) \ ((s).icon_title_relief = (x)) #define SGET_MIN_WINDOW_WIDTH(s) \ ((s).min_window_width) #define SSET_MIN_WINDOW_WIDTH(s,x) \ ((s).min_window_width = (x)) #define SGET_MAX_WINDOW_WIDTH(s) \ ((s).max_window_width) #define SSET_MAX_WINDOW_WIDTH(s,x) \ ((s).max_window_width = (x)) #define SGET_MIN_WINDOW_HEIGHT(s) \ ((s).min_window_height) #define SSET_MIN_WINDOW_HEIGHT(s,x) \ ((s).min_window_height = (x)) #define SGET_MAX_WINDOW_HEIGHT(s) \ ((s).max_window_height) #define SSET_MAX_WINDOW_HEIGHT(s,x) \ ((s).max_window_height = (x)) #define SGET_WINDOW_SHADE_STEPS(s) \ ((s).shade_anim_steps) #define SSET_WINDOW_SHADE_STEPS(s,x) \ ((s).shade_anim_steps = (x)) #define SGET_SNAP_PROXIMITY(s) \ ((s).snap_attraction.proximity) #define SSET_SNAP_PROXIMITY(s,x) \ ((s).snap_attraction.proximity = (x)) #define SGET_SNAP_MODE(s) \ ((s).snap_attraction.mode) #define SSET_SNAP_MODE(s,x) \ ((s).snap_attraction.mode = (x)) #define SGET_SNAP_GRID_X(s) \ ((s).snap_grid_x) #define SSET_SNAP_GRID_X(s,x) \ ((s).snap_grid_x = (x)) #define SGET_SNAP_GRID_Y(s) \ ((s).snap_grid_y) #define SSET_SNAP_GRID_Y(s,x) \ ((s).snap_grid_y = (x)) #define SGET_EDGE_DELAY_MS_MOVE(s) \ ((s).edge_delay_ms_move) #define SSET_EDGE_DELAY_MS_MOVE(s,x) \ ((s).edge_delay_ms_move = (x)) #define SGET_EDGE_DELAY_MS_RESIZE(s) \ ((s).edge_delay_ms_resize) #define SSET_EDGE_DELAY_MS_RESIZE(s,x) \ ((s).edge_delay_ms_resize = (x)) #define SGET_EDGE_RESISTANCE_MOVE(s) \ ((s).edge_resistance_move) #define SSET_EDGE_RESISTANCE_MOVE(s,x) \ ((s).edge_resistance_move = (x)) #define SGET_EDGE_RESISTANCE_XINERAMA_MOVE(s) \ ((s).edge_resistance_xinerama_move) #define SSET_EDGE_RESISTANCE_XINERAMA_MOVE(s,x) \ ((s).edge_resistance_xinerama_move = (x)) #define SGET_ICON_BOXES(s) \ ((s).icon_boxes) #define SSET_ICON_BOXES(s,x) \ ((s).icon_boxes = (x)) #define SGET_PLACEMENT_PENALTY_PTR(s) \ (&(s).pl_penalty) #define SGET_NORMAL_PLACEMENT_PENALTY(s) \ ((s).pl_penalty.normal) #define SGET_ONTOP_PLACEMENT_PENALTY(s) \ ((s).pl_penalty.ontop) #define SGET_ICON_PLACEMENT_PENALTY(s) \ ((s).pl_penalty.icon) #define SGET_STICKY_PLACEMENT_PENALTY(s) \ ((s).pl_penalty.sticky) #define SGET_BELOW_PLACEMENT_PENALTY(s) \ ((s).pl_penalty.below) #define SGET_EWMH_STRUT_PLACEMENT_PENALTY(s) \ ((s).pl_penalty.strut) #define SSET_NORMAL_PLACEMENT_PENALTY(s,x) \ ((s).pl_penalty.normal = (x)) #define SSET_ONTOP_PLACEMENT_PENALTY(s,x) \ ((s).pl_penalty.ontop = (x)) #define SSET_ICON_PLACEMENT_PENALTY(s,x) \ ((s).pl_penalty.icon = (x)) #define SSET_STICKY_PLACEMENT_PENALTY(s,x) \ ((s).pl_penalty.sticky = (x)) #define SSET_BELOW_PLACEMENT_PENALTY(s,x) \ ((s).pl_penalty.below = (x)) #define SSET_EWMH_STRUT_PLACEMENT_PENALTY(s,x) \ ((s).pl_penalty.strut = (x)) #define SGET_PLACEMENT_PERCENTAGE_PENALTY_PTR(s) \ (&(s).pl_percent_penalty) #define SGET_99_PLACEMENT_PERCENTAGE_PENALTY(s) \ ((s).pl_percent_penalty.p99) #define SGET_95_PLACEMENT_PERCENTAGE_PENALTY(s) \ ((s).pl_percent_penalty.p95) #define SGET_85_PLACEMENT_PERCENTAGE_PENALTY(s) \ ((s).pl_percent_penalty.p85) #define SGET_75_PLACEMENT_PERCENTAGE_PENALTY(s) \ ((s).pl_percent_penalty.p75) #define SSET_99_PLACEMENT_PERCENTAGE_PENALTY(s,x) \ ((s).pl_percent_penalty.p99 = (x)) #define SSET_95_PLACEMENT_PERCENTAGE_PENALTY(s,x) \ ((s).pl_percent_penalty.p95 = (x)) #define SSET_85_PLACEMENT_PERCENTAGE_PENALTY(s,x) \ ((s).pl_percent_penalty.p85 = (x)) #define SSET_75_PLACEMENT_PERCENTAGE_PENALTY(s,x) \ ((s).pl_percent_penalty.p75 = (x)) #define SGET_PLACEMENT_POSITION_STRING(s) \ ((s).pl_position_string) #define SSET_PLACEMENT_POSITION_STRING(s,x) \ ((s).pl_position_string = (x)) #define SGET_INITIAL_MAP_COMMAND_STRING(s) \ ((s).initial_map_command_string) #define SSET_INITIAL_MAP_COMMAND_STRING(s,x) \ ((s).initial_map_command_string = (x)) #define SGET_TITLE_FORMAT_STRING(s) \ ((s).title_format_string) #define SSET_TITLE_FORMAT_STRING(s,x) \ ((s).title_format_string = (x)) #define SGET_ICON_TITLE_FORMAT_STRING(s) \ ((s).icon_title_format_string) #define SSET_ICON_TITLE_FORMAT_STRING(s,x) \ ((s).icon_title_format_string = (x)) /* function prototypes */ void lookup_style(FvwmWindow *fw, window_style *styles); Bool blockcmpmask(char *blk1, char *blk2, char *mask, int length); void check_window_style_change( FvwmWindow *t, update_win *flags, window_style *ret_style); void reset_style_changes(void); void update_style_colorset(int colorset); void update_window_color_style(FvwmWindow *fw, window_style *style); void update_window_color_hi_style(FvwmWindow *fw, window_style *style); void update_icon_title_cs_style(FvwmWindow *fw, window_style *pstyle); void update_icon_title_cs_hi_style(FvwmWindow *fw, window_style *pstyle); void update_icon_background_cs_style(FvwmWindow *fw, window_style *pstyle); void free_icon_boxes(icon_boxes *ib); void style_destroy_style(style_id_t s_id); void print_styles(int verbose); #endif /* _STYLE_ */ fvwm-2.6.7/aclocal.m40000644000175700017570000016437313010101113011277 00000000000000# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR # PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # ------------------------------------------- # Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])# PKG_CHECK_VAR # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # -*- Autoconf -*- # Obsolete and "removed" macros, that must however still report explicit # error messages when used, to smooth transition. # # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. AC_DEFUN([AM_CONFIG_HEADER], [AC_DIAGNOSE([obsolete], ['$0': this macro is obsolete. You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl AC_CONFIG_HEADERS($@)]) AC_DEFUN([AM_PROG_CC_STDC], [AC_PROG_CC am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc AC_DIAGNOSE([obsolete], ['$0': this macro is obsolete. You should simply use the 'AC][_PROG_CC' macro instead. Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', but upon 'ac_cv_prog_cc_stdc'.])]) AC_DEFUN([AM_C_PROTOTYPES], [AC_FATAL([automatic de-ANSI-fication support has been removed])]) AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version is >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([Python interpreter is too old])]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Getting [:3] seems to be dnl the best way to do this; it's what "site.py" does in the standard dnl library. AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made dnl distinct variables so they can be overridden if need be. However, dnl general consensus is that you shouldn't need this ability. AC_SUBST([PYTHON_PREFIX], ['${prefix}']) AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) dnl At times (like when building shared libraries) you may want dnl to know which OS platform Python thinks this is. AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) # Just factor out some code duplication. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: pass" dnl Set up 4 directories: dnl pythondir -- where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON script directory], [am_cv_python_pythondir], [if test "x$prefix" = xNONE then am_py_prefix=$ac_default_prefix else am_py_prefix=$prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl pkgpythondir -- $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl pyexecdir -- directory for installing python extension modules dnl (shared libraries) dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], [am_cv_python_pyexecdir], [if test "x$exec_prefix" = xNONE then am_py_exec_prefix=$am_py_prefix else am_py_exec_prefix=$exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) fvwm-2.6.7/docs/0000755000175700017570000000000013010103346010443 500000000000000fvwm-2.6.7/docs/Makefile.am0000644000175700017570000000020712773470550012441 00000000000000## This is a -*- Makefile -*- ## Process this file with automake to create Makefile.in EXTRA_DIST = COMMANDS DEVELOPERS.md PARSING.md fvwm-2.6.7/docs/COMMANDS0000644000175700017570000003074112750322651011530 00000000000000The recognized commands for fvwm 2.6.6 (from cvs) as of 09-Sep-2014: # - Comment line (ignored) * - Module configuration line (no space after asterisk) + - Continue the last AddToFunc, AddToMenu or AddToDecor AddButtonStyle - Add to a button style (see ButtonStyle) AddTitleStyle - Add to a title style (see TitleStyle) AddToDecor - Add a decor definition (will be obsolete) AddToFunc - Add a function definition AddToMenu - Add a menu definition All - Operate on all windows matching the given condition AnimatedMove - Like Move, but uses animation to move windows Any - Operate if there is any window matching the condition Beep - Produce a bell BorderStyle - Define a window border look (will be reworked) Break - Stop executing the current (but not parent) function BugOpts - Set some application bug workarounds BusyCursor - Show/don't show the wait cursor in certain operations ButtonState - Disable some titlebar button states (not recommended) ButtonStyle - Define a window button look (will be reworked) ChangeDecor - Attach decor to a window (will be obsolete) ChangeMenuStyle - Attach menu style to a menu (see MenuStyle) CleanupColorsets - Reset all used colorsets with the default gray colors ClickTime - Set a time in milliseconds for click and double click Close - Try to Delete a window, if this fails, Destroy it ColorLimit - Set limit on colors used (obsolete) ColormapFocus - Change the colormap behaviour for low-depth X servers Colorset - Manage colors used like fg, bg, image bg, gradient bg CopyMenuStyle - Copy the existing menu style to new or existing one Current - Operate on the currently focused window CursorMove - Move the cursor pointer non interactively CursorStyle - Define different cursor pointer shapes and colors DefaultColors - Set colors for the feedback window (will be obsolete) DefaultColorset - Set colors for the Move/Resize feedback window DefaultFont - The default font to use (mainly for feedback window) DefaultIcon - The default icon to use for iconified windows DefaultLayers - Set StaysOnBottom, StaysPut, StaysOnTop layer numbers Delete - Try to delete a window using the X delete protocol Deschedule - Remove commands sheduled earlier using Schedule Desk - (obsolete, use GotoDesk instead) DesktopName - Define the desktop names used in WindowList, modules DesktopSize - Set virtual desktop size in units of physical pages Destroy - Kill a window without any warning to an application DestroyDecor - Delete decor defined by AddToDecor (will be obsolete) DestroyFunc - Delete function defined using AddToFunc DestroyMenu - Delete menu defined using AddToMenu DestroyMenuStyle - Delete menu style defined using MenuStyle DestroyModuleConfig - Delete matching module config lines defined using "*" DestroyStyle - Delete style defined using Style DestroyWindowStyle - Delete style defined using WindowStyle Direction - Operate on the next window in the specified direction Echo - Print message to stderr, mainly for debugging EchoFuncDefinition - Print the definion of a function EdgeCommand - Bind one or another screen edge to an fvwm action EdgeLeaveCommand - Bind one or another screen edge to an fvwm action EdgeResistance - Control viewport scrolling and window move over edge EdgeScroll - Control how much of the viewport is scrolled if any EdgeThickness - Control how closely to edge to run command/scrolling Emulate - Only used to position the position/size window EscapeFunc - Abort a wait or ModuleSynchonous command EwmhBaseStruts - Define restricted areas of the screen EwmhNumberOfDesktops - For ewmh pager, define number of desktops Exec - Execute an external command ExecUseShell - The shell to use to execute an external command FakeClick - Generate a mouse click FakeKeypress - Send a keyboard event to a window FlipFocus - Focus a window without rotating windowlist order Focus - Give focus to a window FocusStyle - Configure focus and raise policy for windows Function - Execute a user defined function, see AddToFunc GlobalOpts - (obsolete, use corresponding Style * instead) GnomeButton - Pass mouse button presses on root to GNOME program GnomeShowDesks - Limit GNOME pager to the number of desks GotoDesk - Switch viewport to another desk same page GotoDeskAndPage - Switch viewport to another desk and page GotoPage - Switch viewport to another page same desk HideGeometryWindow - Hide/show the position/size window HilightColor - (obsolete, use Style * HighlightFore/Back) HilightColorset - (obsolete, use Style * HighlightColorset) IconFont - (obsolete, use Style * IconFont) Iconify - Change iconification status of a window (minimize) IconPath - (obsolete, use ImagePath instead) IgnoreModifiers - Modifiers to ignore on mouse and key bindings ImagePath - Directories to search for images InfoStoreAdd - Adds an entry (key/value pairs) to the infostore InfoStoreRemove - Removes an entry from the infostore - KeepRc - Do not modify the previous command return code Key - Bind or unbind a key to an fvwm action KillModule - Stops an fvwm module Layer - Change the layer of a window LocalePath - Directories/domains to search for locale data Lower - Lower a window within a layer Maximize - Toggle maximal-size status of a window Menu - Display (post) a menu MenuStyle - Control appearance and behavior of a menu Module - Invoke an fvwm module ModuleListenOnly - Invoke an fvwm module ModulePath - Modify the directories to search for an fvwm module ModuleSynchronous - Invoke an fvwm module synchronously ModuleTimeout - Set timeout value for response from module Mouse - Bind or unbind a mouse button press to an fvwm action Move - Move a window MoveThreshold - Set number of pixels in a click and a hold vs. a drag MoveToDesk - Move a window to another desk same page MoveToPage - Move a window to another page same desk MoveToScreen - Move a window to another Xinerama screen Next - Operate on the next window matching conditions None - Perform command if no window matches conditions Nop - Do nothing (used internally) NoWindow - Prefix that runs a command without a window context OpaqueMoveSize - Set maximum size window fvwm should move opaquely Pick - Prefix to force a window context, prompted if needed PipeRead - Exec system command interpret output as fvwm commands PixmapPath - (obsolete, use ImagePath instead) PlaceAgain - Replace a window using initial window placement logic PointerKey - Bind an action to a key based on pointer not focus PointerWindow - Operate on window under pointer if it meets conditions Popup - Display (pop-up) a menu, see also Menu Prev - Operate on the precious window matching conditions PrintInfo - Print information about the state of fvwm PropertyChange - Internal, used for inter-module communication Quit - Exit fvwm QuitScreen - Stop managing the specified screen QuitSession - Ask session manager to shut down itself and fvwm Raise - Raise a window in a layer RaiseLower - Alternately raise or lower a window in a layer Read - Read fvwm commands from a file ReadWriteColors - Used for colorset speed hacks (will be removed?) Recapture - Reapply styles to all windows (will be obsolete) RecaptureWindow - Reapply styles to one window (will be obsolete) Refresh - Cause all windows to redraw themselves RefreshWindow - Cause one window to redraw itself Repeat - Repeat (very unreliably) the last command, don't use Resize - Cause a window to be resized ResizeMaximize - Resize a window and mark window as maximized ResizeMove - Resize and move in one operation ResizeMoveMaximize - Resize and move in one operation and mark maximized RestackTransients - Regroup the window transients in the stack Restart - Restart itself or replace with another window manager SaveQuitSession - Cause session manager to save and shutdown fvwm SaveSession - Cause session manager to save the session ScanForWindow - Operate on the matching window in the given direction Schedule - Run an fvwm command after a delay Scroll - Scroll the desktop viewport Send_ConfigInfo - Internal, used for module communication Send_Reply - Internal, used for module communication Send_WindowList - Internal, used for module communication SendToModule - Send a string (action) to a module set_mask - Internal, used for module communication set_nograb_mask - Internal, used for module communication set_sync_mask - Internal, used for module communication SetAnimation - Control animated moves and menus SetEnv - Set an environment variable Silent - Suppress errors on command, avoid window selection SnapAttraction - Control attraction of windows during move SnapGrid - Control grid used with SnapAttraction State - Control user defined window states Stick - Change window stickyness StickAcrossDesks - Change window stickyness on a desk basis StickAcrossPages - Change window stickyness on a page basis Stroke - Bind a stroke to an fvwm action StrokeFunc - Record stroke and execute corresponding stroke action Style - Set attributes of windows that match a pattern TearMenuOff - Convert a menu to a window, for use in menu items Test - Execute command if conditions are met TestRc - Conditional switch (may be changed) ThisWindow - Operate on the context window if it meets conditions Title - Insert title into a menu TitleStyle - Control window title UnsetEnv - Remove an environment variable UpdateDecor - Update window decor (obsolete and not needed anymore) UpdateStyles - Cause styles to update while still in a function Wait - Pause until a matching window appears WarpToWindow - Warp the pointer to a window WindowFont - (obsolete, use Style * Font) WindowId - Execute command for window matching the windowid WindowList - Display the window list as a menu to select a window WindowShade - Shade/unshade a window WindowShadeAnimate - (obsolete, use Style * WindowShadeSteps) WindowStyle - Set styles on the selected window Xinerama - Control Xinerama support XineramaPrimaryScreen - Identify Xinerama primary screen XineramaSls - Control single logical screen support XineramaSlsScreens - Configure layout for single logical screen XineramaSlsSize - Configure layout for single logical screen sizes XorPixmap - Use a pixmap for move/resize rubber-band XorValue - Change bits used for move/resize rubber-band XSync - For debugging, send all pending requests to X server XSynchronize - For debugging, cause all X requests to be synchronous fvwm-2.6.7/docs/Makefile.in0000644000175700017570000003500213010103322012422 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = docs DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ EXTRA_DIST = COMMANDS DEVELOPERS.md PARSING.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign docs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign docs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/docs/DEVELOPERS.md0000644000175700017570000002203313003342500012354 00000000000000 Developing for FVWM =================== This document aims to help the developer with the expectations when dealing with the FVWM source code. The FVWM source conforms to the [Linux kernel style guide](https://www.kernel.org/doc/Documentation/CodingStyle). Command Parsing =============== The internal representation of how fvwm parses commands in undergoing a rewrite. [Some notes on how fvwm parses commands exists](PARSING.md). Branch Workflows / Submitting Code Changes ========================================== The main FVWM repository treats the `master` branch as stable, in that it's the branch which has the most tested code on it, and the branch from which releases are made. Formal releases of FVWM are tagged, in the form `x.y.z`, historical versions of FVWM are tagged as `version-x_y_z`. Untagged code may well accumulate on `master`, which will go to form the next release. Other branches in the repository will reflect on-going development from core fvwm-workers. As such, these branches are often in a state of flux, and likely to be rebased against other branches. *NO* code should be based off topic branches, unless explicitly agreed with other developers, who might need to collaborate. ### Branch naming Branch names are used to try and indicate the feature, and who is working on them. So for example, a topic-branch will be named as: `initials/rough-description-of-branch` For example: `ta/fix-clang-warnings` denotes that the branch is worked on by someone with the initials `TA` and that the branch is about fixing warnings from Clang. Sometimes, if more than one person is collaborating on a branch, the initials prefix might not be needed. ### Updating NEWS When submitting patches, please also update the NEWS file with relevant highlights as to new functionality and/or bug-fixes. For inspiration, GNU have a [list](https://www.gnu.org/prep/standards/standards.txt). ### Submitting Pull-requests External contributions are always welcomed and encouraged. If you're thinking of writing a new feature, it is worthwhile posting an email to the `fvwm-workers` mailing list to discuss whether it's a good idea, and to check no one else is working on that feature. Those wishing to submit code/bug-fixes should: * [Fork the FVWM-repository](https://github.com/fvwmorg/fvwm#fork-destination-box) * Add the [FVWM-repo](https://github.com/fvwmorg/fvwm.git) as an upstream remote: * `git remote add fvwmorg https://github.com/fvwmorg/fvwm.git && git fetch fvwmorg` * Create a topic-branch to house your work; * Rebase it against `fvwmorg/master` * Push the latest changes to your fork; * Open a pull-request Once a pull-request is opened, an email is sent to the `fvwm-workers` list so we can take a look at it. Alternatively, if pull-requests are not an option, then `git-send-email` can be used, sending the relevant patchsets to the `fvwm-workers` mailing list. ### Protected branches and the use of Travis-CI Pull-requests made will result in the use of Travis-CI being run against the branch. This builds the copy of the pushed code in a Ubuntu environment, with all the additional libraries FVWM could use, loaded in. Builds are made against `gcc` and `clang`, because both those compilers cover slightly different angles with respect to compiling. All warnings are treated as errors, and if a build does not succeeded, ensure the code is fixed, and pushed back out on the same branch. Rebasing is recommended; Travis-CI and Github handle this just fine. The FVWM repository also treats the `master` branch as protected. This is a [GitHub feature](https://help.github.com/articles/about-protected-branches/) which means the `master` branch in this case cannot have changes merged into it until Travis-CI has verified the builds do not fail. This has merit since not every developer will be using the same operating systems (Linux versus BSD for instance), and that `master` is meant to try and be as release-worthy as can be. **NOTE**: This means that no work can be commited to `master` directly. ALL work that needs to appear on `master`---including the release process---**MUST** go via a separate topic-branch, with a PR (pull-request). Not even fvwmorg owners are an exception to this. ### Merging changes / Pull Requests The history of `master` should be as linear as possible, therefore when merging changes to it the branch(es) in question should be rebased against master first of all. This will stop a merge commit from happening. If using github this process is easy, since the `Merge pull request` button has an option to `Rebase and Merge`. This is what should be used. See also [the documentation on Github](https://github.com/blog/2243-rebase-and-merge-pull-requests) If this is manual (which will only work when the Travis-CI checks have passed), then: ``` git checkout topic/branch git rebase origin/master git checkout master git merge topic/branch git push ``` Conventions ========== The following tries to list all the conventions that the fvwm developers adhere to, either by consensus through discussion, common practice or unspoken agreement. It is hopefully useful for the fvwm development newbie. Programming Languages -------------------- The following programming languages are allowed: - ANSI C - Perl - Portable /bin/sh scripts for examples. New Code Files -------------- - There are templates for new code files in the fvwm directory. Try to always use them as they provide a clean structure of the header and code files. Please honour the section titles. For example, put all static functions (and only static functions) under the "local functions" section. - All .c files *must* have ``` #include "config.h" ``` as the first non-comment line. Otherwise the settings made by the configure script may not be used. This can cause random problems. File Names ---------- - The names of the code files in the fvwm directory are in lower case. - Files in the libs directory may begin with a capital 'F'. This letter is reserved for wrapper files for third party libraries or modules. For example, FShape is an abstraction of the XShape X server extension and FBidi is a wrapper for the fribidi library. Do not use the 'F' for other purposes. Copyright Notices ----------------- - A copy of the GPL should be at the beginning of all code files (.c) and scripts, but not at the beginning of header files (.h). Maintaining Man Pages --------------------- - Every feature must be described with all options in the man page. Creating a release ================== Before deciding to make a new release, please check with the `fvwm-workers` mailing list that this is the right time to do so. This will give adequate warning for other developers to give status updates about any in-flight development that's happening which might impact a potential release. Make sure you have all optional libraries installed. **NOTE: as `master` is a protected branch, changes made to files during the release phase must be done on a separate branch, and not on master directly, as pushes to this branch are not allowed until checks have been done on it. This means the end result of the release-phase must have these changes issued as a pull-request against `master`.** 0. `git checkout master && git pull && git checkout -b release/x.y.z` **Where: `x.y.z` will be the next release**. 1. Change the dates in configure.ac and fill in the release dates. 2. Set `ISRELEASED` to `"yes"`. 3. Commit the results. 4. Run: `./autogen.sh && make clean` to get the tree into a clean slate. Because this is a release, the source needs compiling. To do that, run: ``` make CFLAGS="-g -O2 -Wall -Wpointer-arith -fno-strict-aliasing -Werror" ``` Fix all warnings and problems, commit the changes and repeat the previous command until no more warnings occur. 5. Tag the release: `git tag -a x.y.z` -- where `x.y.z` represents the appropriate version number for the release. 6. Build and test the release tarballs: Run: `make distcheck2` If that succeeds, check for `fvwm-x.y.z.tar.gz` in the current working directory. This is the release tarball which will be uploaded to Github. Unpack it to a temporary directory and build it; check the version as well, via: `./fvwm --version`. 7. Push the tag out: `git push origin x.y.z` -- where `x.y.z` is the specific tag created in step 5. 8. Set `ISRELEASED` to `"no"` in configure.ac and commit and push that out. 9. Issue a PR (pull-request) against `master` and mege that in assuming all checks pass. If not, fix the problems, and repeat this step. 10. Upload the `fvwm-x.y.z.tar.gz` tarball to Github against the tag just pushed. 11. Update the fvwm web site (see below) Updating fvwm-web ================= 1. Ensure you've a checkout of the repository: ``` git clone git@github.com:fvwmorg/fvwmorg.github.io.git ``` 2. Update the `RELEASE` variable in `Makefile` to the desired version which has been released. 3. Run `make`. This will update all relevant files. 4. `git commit -a` the result, and push it out. fvwm-2.6.7/docs/PARSING.md0000644000175700017570000016344112754306001012030 00000000000000Overview of fvwm2 parsing as of 16-Aug-2014 =========================================== Sources of input to parse ------------------------- * Configuration files and files read with the Read command - May be preprocessed by FvwmCpp or FvwmM4 * Input from the PipeRead command * Input from modules to fvwm through the module pipes - Fixed or generated strings from modules (e.g. FvwmPager, FvwmButtons etc.) - User input, e.g. from FvwmConsole or FvwmCommand. * Module input from fvwm through the module pipes is parsed by the receiving module. - Binary input in predefined packets is only partially parsed (packet type). The format and meaning of the packets is a property of the module protocol. - The payload of some string packets (e.g. generated by the SendToModule command) is a free form string that is interpreted by the receiving module. The module does any necessary parsing. Example: `SendToModule FvwmButtons changebutton 0 title foo, activetitle bar` * Commands generated internally by fvwm as the result of an external event, for example, an Ewmh message. This is used quite often; instead of calling the function to maximize a window directly, one may generate a command string that is passed to `execute_function()`. Examples are `virtual.c:CMD_EdgeResistance()` or `ewmh_events.c:ewmh_DesktopGeometry()`. Various properties of parser input and the communication channels ----------------------------------------------------------------- * Maximum length of of lines read from a file is hard coded ro 1024 bytes in `read.c:run_command_stream()`. This is applicable to configuration files and the Read and Piperead commands. * The maximum depth of nested files opened through the Read command is hard coded to 40 (read.c). * Input from files or the `PipeRead` command may have an unlimited number of lines. * The maximum length of packets that can be sent in one chunk from fvwm to the modules or back is hard coded to 256 including the packet header (`FvwmPacketMaxSize` in `libs/Module.h`). This is an artifact of module communication through pipes. 256 bytes is the size that all systems guarantee to be sent through the pipe in an atomic block. Anything larger than that may be split into multiple write calls, leading to mutilated messages in either direction. Packets from fvwm to the modules are simply truncated to 256 bytes (`module_interface.c:make_vpacket()`). Packets from the modules to fvwm are possibly sent in multiple pieces (write call in `Module.c:SendText()`). Fvwm can theoretically handle any size of module input (`module_list.c:module_receive()`). * Input from modules to fvwm is pre-parsed in `module_interface.c:module_input_execute()`, i.e. fvwm checks whether the command name of the packet is "popup" and does some special processing if that is the case (this command name is not to be confused with the command from the text to be executed by fvwm; its a fixed field in the packet). This is done before any regular processing of the input. * Input from the modules is not executed right away but stored in a queue and executed when fvwm can process it (this is important because otherwise module input might interfere with function execution) (`module_interface.c:ExecuteCommandQueue()`). Fvwm's central parsing function: execute_function() --------------------------------------------------- * All input to the parser is passed through `functions.c:__execute_command_line()`. NOTE: This function is called `__execute_function()` in fvwm. * `__execute_command_line` is called from two places: - `execute_function()` is just a wrapper exported rom functions.c. There are two more wrappers, `execute_function_override_wcontext()` and `execute_function_override_window()` which change the execution context of the command (see below) and then call `execute_function()`. - `__run_complex_function_items()` calls `__execute_command_line()` to process the individual commands of a complex function. In other words: The items of a complex function are passed twice through the parser. First when the complex function is defined, and a second time when they are executed (they are treated differently in both passes, see further down). * The call to `__execute_command_line()` is passed various pieces of information: ``` void __execute_command_line( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, char *args[], Bool has_ref_window_moved) ``` - `cond_rc` is a pointer to memory where the return code of command line execution is to be stored. This can be used in scripting through complex functions (`__run_complex_function_items()`) and by the internal caller of execute_function. It is also one of the parameters of the `CMD_...` functions, and it's important that cond_rc is passed around and not set to a NULL pointer except by the first call triggering command line processing. - exc is the execution context of the command line (`execcontext.h`). This is a vital data structure for command line processing and execution. It contains information about the originator of the command and the assiciated application (type (module, event, scheduler, ...), the actual X event, the module, the window). This data is used during command execution, e.g. to identify the window on which a command is executed or to determine the pointer position; some commands work differently when input comes from the mouse or the keyboard. It is also used during variable expansion (e.g. to expand window related extended parameters like `$[w.id]`). It is important to properly set the execution context whenever a command line is generated. Currently, some of the Ewmh code fails to do so for historical reasons which I won't explain here. This needs to be fixed eventually. - action is the command line to parse and execute. - `exec_flags` are flags that affect command parsing and execution that may become necessary in some contexts not related to the originator of the command. The flags are defined in the structure execute_flags_t in functions.h. - `FUNC_NEEDS_WINDOW` commands that need a context window are not executed if it's missing. - `FUNC_DONT_REPEAT` the command line is not repeatable (see `CMD_Repeat`). - `FUNC_ADD_TO` signals that the command is the addtofunc or `+` command. - `FUNC_DECOR` signals that the command is a decor related command. - `FUNC_ALLOW_UNMANAGED` allows running a command with an overrideredirect window. - `FUNC_IS_UNMANAGED` signals that the context window is an overrideredirect window. - `FUNC_DONT_EXPAND_COMMAND` suppresses expansion of variables on the command line. - `FUNC_DONT_DEFER` suppresses deferring execution of commands that need a target window (normally these are put into the queue and processed later). - args is the array of the positional arguments during complex function execution. For calls from `execute_function()` it's a NULL pointer. - `has_ref_window_moved` is a separate flag (hack) that triggers some special treatment of the execution of the command Move, Resize and AnimatedMove (but forgets the ResizeMove and ResizeMoveMaximize commands). This should ratehr be stored in exec_flags. Command line parsing -------------------- The command independent parsing of any command line is done by the `__execute_command_line()` call. The parsing procedure is as follows. Remember that `action` is the command line to be parsed. The pointer and the memory it points to are updated during the parsing process. * Step 1 Handle NULL pointer, whitespace and comments 1. Stop parsing and execute nothing if action is a NULL pointer. *DONE* 2. Strip all whitespace from the beginning of the command line. 3. Stop parsing and execute nothing if action is a NULL pointer or an empty string. (Note that some of the functions in libs/Parse.c never return an empty string but rather a NULL pointer. Parsing in the individual commands often relies on that.) *DONE* 4. If the first character is '#', is a comment. Stop parsing and execute nothing. *DONE* * Step 2 1. Increment the nested function depth. 2. If the function depth is too high, print an error message and stop. *DONE* 3. Determine the context window. * Step 3 Handle prefixes 1. If action begins with `-`, set the `FUNC_DONT_EXPAND_COMMAND` flag and skip the `-` character. 2. Peek the first token of action. 3. If the token is `silent`, set the global `Scr.flags.are_functions_silent` if not already set, strip the token from action and go back to (b). 4. If the token is `keeprc`, set the internal `do_keep_rc` flag, strip the token from action and go back to (b). (A dummy return code variable is used in the command execution.) * Step 4 Finish if there is no remaining action to execute. * Step 5 Parse the command token 1. Get (but not strip) the command token from the action. 2. Expand variables in the token (expand.c:expand_vars()). 3. If the token does not start with a '*': * strip all characters from and including the first whitespace from the command token. [Bug: Complex function names cannot have embedded whitespace because of this, see comment in the code.] [Note: If a command line begins with `*foo` (including the double quotes), the double quotes are removed by GetNextToken, and the remaining token does begin with `*`.] * find the internal command matching this token from the builtin function table. Note that any token _beginning_ with `+` or ` +` is treated as the `+` command. [What the heck is this good for?] * Step 6 If a we're currently adding to a decor, and the command token designates a builtin function that does not have the `FUNC_DECOR` flag set, generate a warning that the command cannot be added to the decor. * Step 7 If the `FUNC_DONT_EXPAND_COMMAND` flag is not set, expand variables in the action, including the part from which the command token was extracted above. (The ismod flag of the call to expand_vars() flag is set if the action begins with '*'). [Note: The command token was parsed before expansion in step 5. Now the whole line including the token is expanded before further processing. This may or may not cause subtle bugs with quoting and expansion.] * Step 8 If the expanded action begins with '*' treat it as a module configuration line. *GOTO step 10* [BUG: Contrary to step 5 (c), a line beginning with `*foo` is not recognized as a module configuration line because it begins with double quotes, not `*`.] * Step 9 Execute the action 1. Prepare the execution context. 2. If it's a builtin function other than `Function`, strip the first token from the expanded action and defer or execute the CMD_() function as necessary with the proper execution context. *GOTO step 10* 3. If it's the builtin command `Function`, strip the first token from the expanded action. [Note: this may again be a different substring than in step 5 (c) or step 8.] 4. Call `execute_complex_function` with the remaining expanded action. 5. If no complex function with that name can be found and it was not the builtin command `Function`, assume that the builtin command was `Module` and try to execute `CMD_Module` with the remaining expanded action as its arguments. * Step 10 Cleanup 1. Clear the `Scr.flags.are_functions_silent` flag if set in step 3 (c). 2. Store the number of pending breaks from the functions return code structure in the original cond_rc (which may be a different one in case the command was prefixed with keeprc). 3. Decrement the nested function depth. Tokenization ------------ The token parsing code is in `libs/Parse.c:DoPeekToken()` and CopyToken() (called by the former). `DoPeekToken` takes the input string, a pointer to memory where it stores the pointer to the resulting token, a pointer to memory to store the output string (buffer with hardcoded length `MAX_TOKEN_LENGTH = 1023` bytes (`libs/Parse.h`), and may be provided a string of additional characters to be treated as spaces, a string of input token delimiter characters, and a pointer where the character that ended the token is stored (output delimiter). By default, the set of space characters contains the character class determined by isspace(), and the set of input delimiter characters is empty * Step 1 (DoPeekToken) 1. Strip all space characters (see above) from the beginning of the input string. 2. Call `CopyToken()` with the remaining string. * Step 2 (CopyToken) 1. Set the src pointer to the beginning of the input string. The dest pointer is passed in as a function argument. 2. If src is at the end of the string, *GOTO stp 3* 3. If *src is a space character or an input delimiter, *GOTO stp 3* 4. If *src is a quote character (either a double quote chararcter, a single quote or a backtick), *GOTO step 2A* 5. Otherwise, *GOTO step 2B* * Step 2A 1. `c := *src` 2. Skip over the src quote character (`src++`) 3. If `*src` is `c` or the end of string, *GOTO (f)* 4. If `*src` is a backslash and the next character is not the end of the input string (null byte), skip over the backslash in the input (src++). 5. If there's still room in the output string, copy `*src` to `*dest` and increment both pointers, otherwise just skip over the input character (`src++`). *GOTO (c)* 6. If `*src` is `c`, skip over it (`src++`). *GOTO step 2 (b)* * Step 2B 1. If `*src` is a backslash and the next character is not the end of the input string (null byte), skip over the backslash in the input (`src++`). 2. If there's still room in the output string, copy `*src` to `*dest` and increment both pointers, otherwise just skip over the input character (`src++`). *GOTO step 2 (b)* * Step 3 1. Set the output delimiter to the character pointer to by src (i.e. the first character after the token). 2. Terminate the destination string with a null byte. 3. If src points to a string of zero or more spaces followed by an input delimiter, store the delimiter as the output delimiter and return a pointer to the character after that. 4. Otherwise, if src is not at the end of the string, return the character after src. 5. Otherwise src points to the end of the string; return src. Step 4 (DoPeekToken) 1. If the remaining string has the length zero, set the token pointer to NULL. 2. Return a pointer to the beginning of the next token in the input string. *DONE* Variable expansion ------------------ Variable expansion is done `expand.c:expand_vars()`. The function takes an input string, the execution context, `cond_rc` and an array of positional parameters and returns the string with the variables expanded. It also takes the flags addto (never set) and ismod (set in step 7 of the parsing algorithm if the command begins with `*`). [BUG: The addto flag is actually never set when the function is called but instead used as a bogus local variable.] * Step 1 1. l := length of input 2. If the input begins with '*', set the addto flag. 3. Calculate the length of the expanded string and allocate memory for it. * Step 2 (Scan for variables) 1. Begin at the start of the input and output strings. 2. Copy all character up to but excluding the next '$' character to the output string (stop at the end of string). 3. If we're at the end of the string, stop. *DONE* 4. Otherwise we're now at a `$` character. If the ismod flag set and the next character is a letter, copy both to the output string. *GOTO (b)* [Note: In module configuration lines, variable in the form `$` are not expanded. There are probably several bugs because of this logic.] * Step 3 (Expand a variable) 1. If the next character is a `$`, copy one `$` to the output, skip over two `$` in the input and *GOTO step 2 (b)* 2. If the next character is '[', *GOTO step 4* 3. If the `$` sequence does not designate a valid one character variable, copy it to the output and *GOTO step 2 (b)* 4. Otherwise, skip over the `$` and the next character in the input and copy the value of the one character variable to the output. *GOTO step 2 (b)* * Step 4 (Expand an extended variable) 1. If addto is set, copy the `$[` to the output and *GOTO step 2 (b)* 2. Determine the name of the extended variable. The name starts after the initial `[` character and ends before the final `]` character. The final `]` character is the first occurence of the character `]` after the `$`, where the number of `[` minus the number of `]` is zero (i.e., square brackets can be nested). If the end of string is encountered, just copy everything to the output and *GOTO step 2 (b)* 3. Otherwise, if the variable name contains at least one `$`, call expand vars with the name to expand nested variable references. The result of this expansion is taken as the new variable name. 4. If an extended variable with that name exists, copy its value into the output, skip the `$[...]` in the input and *GOTO step 2 (b)* 5. Otherwise copy the "$[...]" to the output and *GOTO step 2 (b)* The second level of parsing --------------------------- When `__execute_command_line()` has finished its work it either tries to execute a module, a builtin command or a complex function (or nothing at all and just returns). Module execution is treated like a call of `CMD_Module()`, so there are two different ways how parsing continues. A third context of parsing is, when a module receives a packet from fvwm. * Parsing of builtin commands is done individually by the `CMD_()` functions. * Parsing and of a complex function call and its items is handled by the function `functions.c:execute_complex_function()`. * Parsing of module configuration lines is done by the modules with help from libs/Modules.c. There is also an optional step of module variable expansion that is implemented in `Modules.c:module_expand_action()`. It replaces some module variables in the string that is going to be sent to fvwm, e.g. `$width` or `$x`. FvwmButtons, FvwmIconMan and FvwmTaskBar and use this mechanism. Parsing of complex function calls --------------------------------- Implemented in `functions.c:execute_complex_function()`. * Step 1 1. Peek the first token of the action. 2. Look it up in the list of complex functions. 3. If no such function exists, return an error. *DONE* 4. Split the action into tokens using GetNextToken. Store the original action (without the function name) followed by the first ten tokens in the positional arguments array. 5. Set up an execution context for the function items. 6. Call `__run_complex_function_items()`. * Step 2 (`__run_complex_function_items()`) 1. For each complec function iten, call `__execute_command_line()` with the `FUNC_DONT_DEFER` flag and the list of positional arguments. This causes the function item command text to be passed through the parser again. *DONE* Parsing needs of the builtin commands ------------------------------------- Note: Let's attempt to formulate the existing syntax in ABNF (rfc5234). Definitions that need defining for the below -------------------------------------------- * FLAG = !!!; * DECOR = !!!; * FONTNAME = !!!; * IMAGEFILE = !!!; * GRADIENT = !!!; * MOVEARGS = !!!; * MODULECONFIG = !!!; * CONDITION = !!!; * COLOUR_FG = !!!; * COLOUR_BG = !!!; * COMMAND = !!!; (builtin; can also be one of FUNCNAME) * FUNCNAME = !!!; (StartFunction | ExitFunction | etc, plus user-defined) * SHELL = !!!; * KEYNAME = !!!; * STYLEOPTION = !!!; (massive list of style options!!!) * TOKEN = !!! ; Same as string? * STRING = !!! ; Sequence of characters? * RESTOFLINE = !!! ; STRING? * RESTOFLINE_COMMAND = !!! ; COMMAND Types ----- ``` WSC = %x20 / %x09 WS = *WSC DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" SIGNPOS = "+" SIGNNEG = "-" SIGN = SIGNPOS / SIGNNEG POSINT = [SIGNPOS] 1*DIGIT INT = [SIGN] 1*DIGIT INTPERCENTAGE = 1DIGIT | 2DIGIT | ("0" / "1") 2DIGIT TRUE = "yes" / "y" / "1" / "t" / "true" FALSE = "no" / "n" / "0" / "f" / "false" BOOL = TRUE / FALSE TOGGLE = "toggle" BOOL_OR_TOGGLE = BOOL / TOGGLE MODIFIERS = "s" / "c" / "l" / "m" / "1" / "2" / "3" / "4" / "5" / "a" BINDINGMODIFIERS = "n" / 1*MODIFIERS PATH = ["/"] *(STRING "/") [STRING] VISIBLE_NAME = !!! CLASS = !!! RESOURCE = !!! NAME = !!! WINDOW_ID = !!! WINDOWSELECTOR = VISIBLE_NAME / CLASS / RESOURCE / NAME / WINDOW_ID BINDINGCONTEXT = "R" / "W" / "D" / "T" / "F" / "A" / "S" / "M" / "I" BINDINGCONTEXT = "[" / "]" / "-" / "_" BINDINGCONTEXT = "<" / "^" / ">" / "v" BINDINGCONTEXT = DIGIT MODULENAME = "MvwmAnimate" / "MvwmButtons" / ; etc... MODULALIAS = TOKEN TOKEN_DECORNAME = TOKEN FUNCNAME = TOKEN MENUNAME = TOKEN MENUSTYLENAME = TOKEN STYLENAME = TOKEN / "*" DIRS_MAIN = "North" / "N" DIRS_MAIN =/ "East" / "E" DIRS_MAIN =/ "South" / "S" DIRS_MAIN =/ "West" / "W" DIRS_DIAG = DIRS_MAIN DIRS_DIAG =/ "NorthEast" / "NW" DIRS_DIAG =/ "SouthEast" / "SE" DIRS_DIAG =/ "SouthWest" / "SW" DIRS_DIAG =/ "NorthWest" / "NW" DIRS_CENTER = DIRS_DIAG / "Center" / "C" COLORSET_NUM = POSINT BUTTON = 1*DIGIT VERSION = POSINT "." POSINT "." POSINT ``` Commands -------- ``` CMD_ADDBUTTONSTYLE = "AddButtonStyle" ADDBUTTONSTYLEBUTTON [ADDBUTTONSTYLESTATE] [ADDBUTTONSTYLESTYLE] [ADDBUTTONSTYLEFLAG] ADDBUTTONSTYLEBUTTON = POSINT ("All" / "Left" / "Right") ADDBUTTONSTYLESTATE = "ActiveUp" ADDBUTTONSTYLESTATE =/ "ActiveDown" ADDBUTTONSTYLESTATE =/ "InactiveUp" ADDBUTTONSTYLESTATE =/ "InactiveDown" ADDBUTTONSTYLESTATE =/ ADDBUTTONSTYLEACTIVE ADDBUTTONSTYLESTATE =/ "Inactive" ADDBUTTONSTYLESTATE =/ TOGGLE ADDBUTTONSTYLESTATE =/ "AllActive" ADDBUTTONSTYLESTATE =/ "AllInactive" ADDBUTTONSTYLESTATE =/ "AllNormal" ADDBUTTONSTYLESTATE =/ "AllToggled" ADDBUTTONSTYLESTATE =/ "AllUp" ADDBUTTONSTYLESTATE =/ "AllDown" ADDBUTTONSTYLESTATE =/ "AllActiveUp" ADDBUTTONSTYLESTATE =/ "AllActiveDown" ADDBUTTONSTYLESTATE =/ "AllInactiveUp" ADDBUTTONSTYLESTATE =/ "AllInactiveDown" ADDBUTTONSTYLEACTIVE = "Active" - implies FOCUSED_WINDOW ADDBUTTONSTYLEFLAG = ["!"]ADDBUTTONSTYLEKEYWORD *("," ["!"]ADDBUTTONSTYLEKEYWORD) ADDBUTTONSTYLEKEYWORD = 1*("UseTitleStyle" / "UseBorderStyle") *("Raised" / "Sunk" / "Flat") CMD_ADDTITLESTYLE = "AddTitleStyle" [ADDTITLESTYLESTATE] [ADDTITLESTYLESTYLE] [ADDTITLESTYLEFLAG] ADDTITLESTYLESTATE = "ActiveUp" ADDTITLESTYLESTATE =/ "ActiveDown" ADDTITLESTYLESTATE =/ "InactiveUp" ADDTITLESTYLESTATE =/ "InactiveDown" ADDTITLESTYLESTATE =/ ADDTITLESTYLEACTIVE ADDTITLESTYLESTATE =/ "Inactive" ADDTITLESTYLESTATE =/ "toggled" ADDTITLESTYLESTATE =/ "AllActive" ADDTITLESTYLESTATE =/ "AllInactive" ADDTITLESTYLEFLAG = ["!"] ADDTITLESTYLEFLAGKEYWORD *("," ["!"] ADDTITLESTYLEFLAGKEYWORD) ADDTITLESTYLEACTIVE = "Active" ; - implies FOCUSED_WINDOW ; (XXX = TitleStyle/ButtonStyle relationships here...) ``` ``` CMD_ADDTOFUNC = "AddToFunc" FUNCNAME ADDTOFUNCFUNCDEFS RESTOFLINE_COMMAND ADDTOFUNCFUNCDEFS = "I" ADDTOFUNCFUNCDEFS =/ "M" ADDTOFUNCFUNCDEFS =/ "C" ADDTOFUNCFUNCDEFS =/ "H" ADDTOFUNCFUNCDEFS =/ "D" ``` ``` CMD_ADDTOMENU = "AddToMenu" MENUNAME [ADDTOMENULABEL RESTOFLINE_COMMAND] ADDTOMENULABEL = STRING ``` ``` CMD_ANIMATEDMOVE = "AnimatedMove" ANIMATEMOVEARGS ANIMATEMOVEARGS [ANIMATEDMOVEKEYWORD] ANIMATEMOVEARGS = !!! ANIMATEDMOVEKEYWORD = "Warp" ``` ``` CMD_ASTERISK = "Asterisk" [MODULE_LINE] ``` ``` CMD_BEEP = "Beep" ``` ``` CMD_BORDERSTYLE = "BorderStyle" BORDERSTYLESTATE [BORDERSTYLESTYLE] [BORDERSTYLEFLAG] BORDERSTYLESTATE = "Active" / "Inactive" BORDERSTYLESTYLE = "TiledPixmap" / "Colorset" BORDERSTYLEFLAG = ["!"] BORDERSTYLEKEYWORD ("," ["!"] BORDERSTYLEKEYWORD) BORDERSTYLEKEYWORD = "HiddenHandles" BORDERSTYLEKEYWORD =/ "NoInset" BORDERSTYLEKEYWORD =/ "Raised" BORDERSTYLEKEYWORD =/ "Sunk" BORDERSTYLEKEYWORD =/ "Flat" BORDERSTYLEKEYWORD =/ "Simple" ``` ``` CMD_BUGOPTS = "BugOpts" BUGOPTSOPTION BUGOPTSOPTION = 1*(BUGOPTSKEYWORD [BOOL_OR_TOGGLE]) BUGOPTSKEYWORD = "FlickingMoveWorkaround" BUGOPTSKEYWORD =/ "MixedVisualWorkaround" BUGOPTSKEYWORD =/ "ModalityIsEvil" BUGOPTSKEYWORD =/ "RaiseOverNativeWindows" BUGOPTSKEYWORD =/ "RaiseOverUnmanaged" BUGOPTSKEYWORD =/ "FlickingQtDialogsWorkaround" BUGOPTSKEYWORD =/ "QtDragnDropWorkaround" BUGOPTSKEYWORD =/ "EWMHIconicStateWorkaround" BUGOPTSKEYWORD =/ "DisplayNewWindowNames" BUGOPTSKEYWORD =/ "ExplainWindowPlacement" BUGOPTSKEYWORD =/ "DebugCRMotionMethod" BUGOPTSKEYWORD =/ "TransliterateUtf8" ``` ``` CMD_BUSYCURSOR = "BusyCursor" BUSYCURSOROPTION *("," BUSYCURSOROPTION) BUSYCURSOROPTION = 1*(BUSYCURSORKEYWORD BOOL) BUSYCURSORKEYWORD = "DynamicMenu" BUSYCURSORKEYWORD =/ "ModuleSynchronous" BUSYCURSORKEYWORD =/ "Read" BUSYCURSORKEYWORD =/ "Wait" BUSYCURSORKEYWORD =/ "*" ``` ``` CMD_BUTTONSTATE = "ButtonState" BUTTONSTATEOPTION *("," BUTTONSTATEOPTION) BUTTONSTATEOPTION = BUTTONSTATEKEYWORD [BOOL] BUTTONSTATEKEYWORD = "ActiveUp" BUTTONSTATEKEYWORD =/ "ActiveDown" BUTTONSTATEKEYWORD =/ "InactiveUp" BUTTONSTATEKEYWORD =/ "InactiveDown" ``` ``` CMD_BUTTONSTYLE = "ButtonStyle" BUTTONSTYLEBUTTON [BUTTONSTYLESTATE] [BUTTONSTYLESTYLE] [FLAGS] BUTTONSTYLEBUTTON = 0-9 BUTTONSTYLEBUTTON =/ "All" BUTTONSTYLEBUTTON =/ "Left" BUTTONSTYLEBUTTON =/ "Right" BUTTONSTYLEBUTTON =/ "Reset" BUTTONSTYLEBUTTONSTATE = "ActiveUp" BUTTONSTYLEBUTTONSTATE =/ "ActiveDown" BUTTONSTYLEBUTTONSTATE =/ "InactiveUp" BUTTONSTYLEBUTTONSTATE =/ "InactiveDown" BUTTONSTYLEBUTTONSTATE =/ BUTTONSTYLEACTIVE BUTTONSTYLEBUTTONSTATE =/ "Inactive" BUTTONSTYLEBUTTONSTATE =/ TOGGLE BUTTONSTYLEBUTTONSTATE =/ "AllActive" BUTTONSTYLEBUTTONSTATE =/ "AllInactive" BUTTONSTYLEBUTTONSTATE =/ "AllNormal" BUTTONSTYLEBUTTONSTATE =/ "AllToggled" BUTTONSTYLEBUTTONSTATE =/ "AllUp" BUTTONSTYLEBUTTONSTATE =/ "AllDown" BUTTONSTYLEBUTTONSTATE =/ "AllActiveUp" BUTTONSTYLEBUTTONSTATE =/ "AllActiveDown" BUTTONSTYLEBUTTONSTATE =/ "AllInactiveUp" BUTTONSTYLEBUTTONSTATE =/ "AllInactiveDown" BUTTONSTYLEACTIVE = "Active" ; - implies FOCUSED_WINDOW BUTTONSTYLESTYLE = "Simple" BUTTONSTYLESTYLE =/ "Default" BUTTONSTYLESTYLE =/ "Solid" BUTTONSTYLESTYLE =/ "Colorset" BUTTONSTYLESTYLE =/ "Vector" BUTTONSTYLESTYLE =/ BUTTONSTYLEGRADIENT BUTTONSTYLESTYLE =/ "Pixmap" BUTTONSTYLESTYLE =/ AdjustedPixmap" BUTTONSTYLESTYLE =/ "ShrunkPixmap" BUTTONSTYLESTYLE =/ "StretchedPixmap" BUTTONSTYLESTYLE =/ "TiledPixmap" BUTTONSTYLESTYLE =/ "MiniIcon" BUTTONSTYLEGRADIENT = TYPE START-COLOUR END-COLOUR BUTTONSTYLESTYLEFLAG = ["!"] BUTTONSTYLESTYLEKEYWORD *("," ["!"] BUTTONSTYLESTYLEKEYWORD) BUTTONSTYLESTYLEKEYWORD = "Raised" BUTTONSTYLESTYLEKEYWORD =/ "Sunk" BUTTONSTYLESTYLEKEYWORD =/ "Flat" BUTTONSTYLESTYLEKEYWORD =/ "UseBorderStyle" BUTTONSTYLESTYLEKEYWORD =/ "UseTitleStyle" ; (XXX = "Raised, Sunk, and Flat" can only be used initially!!!") ``` ``` CMD_CHANGEMENUSTYLE = "ChangeMenuStyle" MENUSTYLENAME MENUNAME ``` ``` CMD_CLEANUPCOLORSETS = "CleanupColorsets" ``` ``` CMD_CLICKTIME = "ClickTime" POSINT ; (stores the negative value during startup> ``` ``` CMD_CMD_CLASS_CLOSE = "Close" / "Delete" / "Destroy" ; work on context window ``` ``` CMD_COLORMAPFOCUS = "ColormapFocus" ("FollowsMouse" / "FollowsFocus") ``` ``` CMD_COLORSET = "Colorset" COLORSET_NUM COLORSETOPTION *("," COLORSETOPTION) COLORSETOPTION = COLORSETKEYWORD [COLORSETVALUE] COLORSETKEYWORD = "fg" COLORSETKEYWORD =/ "Fore" COLORSETKEYWORD =/ "Foreground" COLORSETKEYWORD =/ "bg" COLORSETKEYWORD =/ "Back" COLORSETKEYWORD =/ "Background" COLORSETKEYWORD =/ "hi" COLORSETKEYWORD =/ "Hilite" COLORSETKEYWORD =/ "Hilight" COLORSETKEYWORD =/ "sh" COLORSETKEYWORD =/ "Shade" COLORSETKEYWORD =/ "Shadow" COLORSETKEYWORD =/ "fgsh" COLORSETKEYWORD =/ "Pixmap" COLORSETKEYWORD =/ "TiledPixmap" COLORSETKEYWORD =/ "AspectPixmap" COLORSETKEYWORD =/ "Transparent" COLORSETKEYWORD =/ "RootTransparent" COLORSETKEYWORD =/ "Shape" COLORSETKEYWORD =/ "TiledShape" COLORSETKEYWORD =/ "AspectShape" COLORSETKEYWORD =/ "NoShape" COLORSETKEYWORD =/ ("V" / "B" / "D" / "S" / "C" / "R" / "Y") "Gradient" COLORSETKEYWORD =/ "Tint" COLORSETKEYWORD =/ "fgTint" COLORSETKEYWORD =/ "bgTint" COLORSETKEYWORD =/ "Alpha" COLORSETKEYWORD =/ "fgAlpha" COLORSETKEYWORD =/ "Dither" COLORSETKEYWORD =/ "NoDither" COLORSETKEYWORD =/ "IconTint" COLORSETKEYWORD =/ "IconAlpha" COLORSETKEYWORD =/ "Plain" COLORSETVALUE = INT COLORSETVALUE =/ COLORNAME COLORSETVALUE =/ IMAGEFILENAME COLORSETVALUE =/ INTPERCENTAGE ; (memory usage depends on highest colorset number) ``` ``` COPYMENUSTYLE = "CopyMenuStyle" MENUSTYLENAME MENUSTYLENAME ``` ``` CMD_CURSORMOVE = "CursorMove" CURSORMOVEDIM[CURSORMOVESUFFIX] CURSORMOVEDIM[CURSORMOVESUFFIX] CURSORMOVEDIM = INT CURSORMOVESUFFIX = "p" ``` ``` CMD_CURSORSTYLE = "CursorStyle" CURSORSTYLECONTEXT [CURSORSTYLEXOPTION] CURSORSTYLECONTEXT = CURSORSTYLEKEYWORD / CURSORSTYLEX11NAME CURSORSTYLEKEYWORD = "POSITION" CURSORSTYLEKEYWORD =/ "TITLE" CURSORSTYLEKEYWORD =/ "DEFAULT" CURSORSTYLEKEYWORD =/ "SYS" CURSORSTYLEKEYWORD =/ "MOVE" CURSORSTYLEKEYWORD =/ "RESIZE" CURSORSTYLEKEYWORD =/ "WAIT" CURSORSTYLEKEYWORD =/ "MENU" CURSORSTYLEKEYWORD =/ "SELECT" CURSORSTYLEKEYWORD =/ "DESTROY" CURSORSTYLEKEYWORD =/ "TOP" CURSORSTYLEKEYWORD =/ "RIGHT" CURSORSTYLEKEYWORD =/ "BOTTOM" CURSORSTYLEKEYWORD =/ "LEFT" CURSORSTYLEKEYWORD =/ "TOP_LEFT" CURSORSTYLEKEYWORD =/ "TOP_RIGHT" CURSORSTYLEKEYWORD =/ "BOTTOM_LEFT" CURSORSTYLEKEYWORD =/ "BOTTOM_RIGHT" CURSORSTYLEKEYWORD =/ "TOP_EDGE" CURSORSTYLEKEYWORD =/ "RIGHT_EDGE" CURSORSTYLEKEYWORD =/ "BOTTOM_EDGE" CURSORSTYLEKEYWORD =/ "LEFT_EDGE" CURSORSTYLEKEYWORD =/ "ROOT" CURSORSTYLEKEYWORD =/ "STROKE" CURSORSTYLEKEYWORD =/ "None" CURSORSTYLEKEYWORD =/ "Tiny" CURSORSTYLEX11NAME = "top_left_corner" CURSORSTYLEX11NAME =/ "top_left_arrow" CURSORSTYLEX11NAME =/ "hand2" CURSORSTYLEX11NAME =/ "fleur" CURSORSTYLEX11NAME =/ "sizing" CURSORSTYLEX11NAME =/ "watch" CURSORSTYLEX11NAME =/ "crosshair" CURSORSTYLEX11NAME =/ "pirate" CURSORSTYLEX11NAME =/ "top_side" CURSORSTYLEX11NAME =/ "bottom_side" CURSORSTYLEX11NAME =/ "left_side" CURSORSTYLEX11NAME =/ "top_right_corner" CURSORSTYLEX11NAME =/ "bottom_left_corner" CURSORSTYLEX11NAME =/ "top_side" CURSORSTYLEX11NAME =/ "right_side" CURSORSTYLEX11NAME =/ "left_side" CURSORSTYLEX11NAME =/ "left_ptr" CURSORSTYLEX11NAME =/ "plus" CURSORSTYLEXOPTION = IMAGEFILE [INT] CURSORSTYLEXOPTION =/ "fg" CURSORSTYLEXOPTION =/ "bg" ``` ``` CMD_DEFAULTCOLORS = "DefaultColors" [(COLOUR_FG] / "-") [(COLOUR_BG - "/")] ; XXX - We need to represent colour values here --- RGB.txt, etc. ``` ``` CMD_DEFAULTCOLORSET = "DefaultColorset" (COLORSET_NUM / "-1") ``` ``` CMD_DEFAULTFONT = "DefaultFont" [FONTNAME] ``` ``` CMD_DEFAULTICON = "DefaultIcon" [IMAGEFILE] ``` ``` CMD_DEFAULTLAYERS = "DefaultLayers" INT INT INT ``` ``` CMD_DESCHEDULE = "Deschedule" [INT] ``` ``` CMD_DESKTOPNAME = "DesktopName" INT DESKTOPNAME DESKTOPNAME = 1*(ALPHA DIGIT) ``` ``` CMD_DESKTOPSIZE = "DesktopSize" DESKTOPSIZDIM "x" DESKTOPSIZDIM DESKTOPSIZEDIM = INT ``` ``` CMD_DESTROYFUNC = "DestroyFunc" [FUNCNAME] ``` ``` CMD_DESTROYMENU = "DestroyMenu" ["recreate"] MENUNAME ``` ``` CMD_DESTROYMENUSTYLE = "DestroyMenuStyle" MENUSTYLENAME ``` ``` CMD_DESTROYMODULECONFIG = "DestroyModuleConfig" MODULECONFIG ``` ``` CMD_DESTROYSTYLE = "DestroyStyle" STYLENAME ``` ``` CMD_DESTROYWINDOWSTYLE = "DestroyWindowStyle" ; operates on context window ``` ``` CMD_ECHO = "Echo" RESTOFLINE ``` ``` CMD_ECHOFUNCDEFINITION = "EchoFuncDefinition" FUNCNAME ``` ``` CMD_EDGECOMMAND = "EdgeCommand" [DIRS_MAIN [RESTOFLINE_COMMAND]] ``` ``` CMD_EDGELEAVECOMMAND = "EdgeLeaveCommand" [DIRS_MAIN [RESTOFLINE_COMMAND]] ``` ``` CMD_EDGESCROLL = "EdgeScroll" EDGESCROLLDIM[EDGESCROLLSUFFIX] EDGESCROLLDIM[EDGESCROLLSUFFIX] [EDGESCROLLOPTION] EDGESCROLLDIM = INT EDGESCROLLSUFFIX = "p" EDGESCROLLOPTION = "Wrap" EDGESCROLLOPTION =/ "WrapX" EDGESCROLLOPTION =/ "WrapY" ``` ``` CMD_EDGETHICKNESS = "EdgeThickness" EDGETHICKNESSVAL EDGETHICKNESSVAL = "0" / "1" / "2" ``` ``` CMD_EMULATE = "Emulate" EMULATEVAL EMULATEVAL = "Mvwm" EMULATEVAL =/ "Mwm" EMULATEVAL =/ "Win" ``` ``` CMD_ESCAPEFUNC = "EscapeFunc" ``` ``` CMD_EWMHBASESTRUTS = "EwmhBaseStruts" ["screen" XRANDRMONITORNAME] INT INT INT INT ``` ``` CMD_EWMHNUMBEROFDESKTOPS = "EwmhNumberOfDesktops" ["screen" XRANDRMONITORNAME] INT INT ``` ``` CMD_EXEC = "Exec" RESTOFLINE_COMMAND ``` ``` CMD_EXECUSESHELL = "ExecUseShell" EXECUSESHELLSHELL ; Could technically be any external command; assume a value from /etc/shells EXECUSESHELLSHELL = !!! ``` ``` CMD_FAKECLICK = "FakeClick" FAKECLICKACTION *("," FAKECLICKACTION) FAKECLICKACTION = FAKECLICKCOMMAND FAKECLICKVALUE FAKECLICKCOMMAND = (FAKECLICKKEYWORD, FAKECLICKVALUE) FAKECLICKKEYWORD = "press" FAKECLICKKEYWORD =/ "release" FAKECLICKKEYWORD =/ "modifiers" FAKECLICKKEYWORD =/ "wait" FAKECLICKKEYWORD =/ FAKECLICKDEPTH FAKECLICKVALUE = "1" FAKECLICKVALUE =/ "2" FAKECLICKVALUE =/ "3" FAKECLICKVALUE =/ "4" FAKECLICKVALUE =/ "5" FAKECLICKVALUE =/ "Mod1" FAKECLICKVALUE =/ "Mod2" FAKECLICKVALUE =/ "Mod3" FAKECLICKVALUE =/ "Mod4" FAKECLICKVALUE =/ "Mod5" FAKECLICKVALUE =/ "6" FAKECLICKVALUE =/ "7" FAKECLICKVALUE =/ "8" FAKECLICKVALUE =/ "Shift" FAKECLICKVALUE =/ "Lock" FAKECLICKVALUE =/ "Control" FAKECLICKDEPTH = "depth" FAKECLICKDEPTH =/ "0" FAKECLICKDEPTH =/ "1" FAKECLICKDEPTH =/ "2" FAKECLICKDEPTH =/ "3" FAKECLICKDEPTH =/ INT ``` ``` CMD_FAKEKEYPRESS = "FakeKeypress" FAKEKEYPRESSACTION *("," FAKEKEYPRESSACTION) FAKEKEYPRESSACTION = FAKEKEYPRESSCOMMAND FAKEKEYPRESSVALUE FAKEKEYPRESSKEYWORD = "press" FAKEKEYPRESSKEYWORD =/ "release" FAKEKEYPRESSKEYWORD =/ "modifiers" FAKEKEYPRESSKEYWORD =/ "wait" FAKEKEYPRESSKEYWORD =/ DEPTH FAKEKEYPRESSVALUE = KEYNAME FAKEKEYPRESSDEPTH = "depth" FAKEKEYPRESSDEPTH =/ "0" FAKEKEYPRESSDEPTH =/ "1" FAKEKEYPRESSDEPTH =/ "2" FAKEKEYPRESSDEPTH =/ "3" FAKEKEYPRESSDEPTH =/ INT ``` ``` CMD_FLIPFOCUS = "FlipFocus" ["nowarp"] ``` ``` CMD_FOCUS = "Focus" ["nowarp"] ``` ``` CMD_FOCUSSTYLE = "FocusStyle" STYLEOPTIONS ``` ``` CMD_FUNCTION = "Function" [FUNCNAME] ``` ``` CMD_GOTODESK = "GotoDesk" DESKNUMBER DESKNUMBER = ["prev" / (INT [INT [INT [INT]]])] ``` ``` CMD_GOTODESKANDPAGE = "GotoDeskAndPage" "prev" / (INT INT INT) ``` ``` CMD_GOTOPAGE = "GotoPage" PAGE_ARGUMENTS PAGE_ARGUMENTS = ["prev" / ([OPTIONS] 2(PAGECCORD[PAGESUFFIX]) OPTIONS = ["!"] ("wrapx" / "wrapy" / "nodesklimitx" / "nodesklimity") PAGECOORD = INT PAGESUFFIX = "p" ``` ``` CMD_HIDEGEOMETRYWINDOW = "HideGeometryWindow" [HIDEGEOMETRYWINDOWCOMMAND] HIDEGEOMETRYWINDOWCOMMAND = "Never" HIDEGEOMETRYWINDOWCOMMAND =/ "Move" HIDEGEOMETRYWINDOWCOMMAND =/ "Resize" ``` ``` CMD_HILIGHTCOLORSET = "HilightColorset" [COLORSET_NUM] ``` ``` CMD_ICONIFY = "Iconify" BOOL_OR_TOGGLE ``` ``` CMD_IGNOREMODIFIERS = "IgnoreModifiers" [ BINDINGMODIFIERS ] ``` ``` CMD_IMAGEPATH = "ImagePath" [PATH] ``` ``` CMD_INFOSTOREADD = "InfoStoreAdd" INFOSTOREKEY INFOSTOREVALUE INFOSTOREKEY = STRING INFOSTOREVALUE = STRING ``` ``` CMD_INFOSTOREREMOVE = "InfoStoreRemove" [INFOSTOREREKEY] ``` ``` CMD_KEEPRC = "KeepRc" [RESTOFLINE_COMMAND] ``` ``` CMD_CLASS_KEY = ("Key" / "PointerKey") ["(" WINDOWSELECTOR ")"] KEYNAME BINDINGCONTEXT BINDINGMODIFIERS RESTOFLINE_COMMAND ``` ``` CMD_KILLMODULE = "KillModule" [MODULENAME] [MODULEALIAS] ``` ``` CMD_LAYER = "Layer" [INT INT] / "default" ``` ``` CMD_LOCALEPATH = "LocalePath" [PATH] ``` ``` CMD_CLASS_RAISELOWER = ("Lower" / "Raise" / "RaiseLower") ; operates on context window ``` ``` CMD_MAXIMIZE = "Maximize" [MAXIMIZEFLAGS] [BOOL_OR_TOGGLE / "forget"] [[MAXIMIZEDIM[MAXIMIZESUFFIX]] MAXIMIZEDIM[MAXIMIZESUFFIX]] MAXIMIZEGROWOPTS = "grow" MAXIMIZEGROWOPTS =/ "growleft" MAXIMIZEGROWOPTS =/ "growright" MAXIMIZEGROWOPTS =/ "growup" MAXIMIZEGROWOPTS =/ "growdown" MAXIMIZEDIM = INT MAXIMIZEDIM =/ MAXIMIZEGROWOPTS MAXIMIZESUFFIX = "p" MAXIMIZEFLAGS = "ewmhiwa" MAXIMIZEFLAGS =/ "growonwindowlayer" MAXIMIZEFLAGS =/ "growonlayers" MAXIMIZEFLAGS =/ ("screen" / XINERAMASCR) ``` ``` CMD_CLASS_MENU = ("Menu" / "Popup") MENUNAME [MENUPOSITION] [MENUCOMMAND] MENUPOSITION = MENUCONTEXT_RECTANGLE INT INT [MENUOPTIONS] MENUCONTEXT_RECTANGLE = "Root" !!! MENUCONTEXT = "XineramaRoot" MENUCONTEXT =/ "Mouse" MENUCONTEXT =/ "Window" MENUCONTEXT =/ "Interior" MENUCONTEXT =/ "Title" MENUCONTEXT =/ ("Button" INT) "Icon" MENUCONTEXT =/ "Item" MENUCONTEXT =/ "Context" MENUCONTEXT =/ "This" MENUCONTEXT =/ ("Rectangle" MENUCONTEXTGEOMETRY) MENUOPTIONS = "TearoffImmediately" MENUOPTIONS =/ "SelectInPlace" MENUOPTIONS = !!! MENUCONTEXTGEOMETRY = !!! ``` ``` CMD_MENUSTYLE = "MenuStyle" MENUSTYLENAME *(["!"] MENUSTYLEOPTIONS) MENUSTYLEOPTIONS = "Mvwm" MENUSTYLEOPTIONS =/ "Mwm" MENUSTYLEOPTIONS =/ "Win" MENUSTYLEOPTIONS =/ "BorderWidth" MENUSTYLEOPTIONS =/ "Foreground" MENUSTYLEOPTIONS =/ "Background" MENUSTYLEOPTIONS =/ "Greyed" MENUSTYLEOPTIONS =/ "HilightBack" MENUSTYLEOPTIONS =/ "HilightTitleBack" MENUSTYLEOPTIONS =/ "ActiveFore" MENUSTYLEOPTIONS =/ "MenuColorset" MENUSTYLEOPTIONS =/ "ActiveColorset" MENUSTYLEOPTIONS =/ "GreyedColorset" MENUSTYLEOPTIONS =/ "TitleColorset" MENUSTYLEOPTIONS =/ "Hilight3DThick" MENUSTYLEOPTIONS =/ "Hilight3DThin" MENUSTYLEOPTIONS =/ "Hilight3DOff" MENUSTYLEOPTIONS =/ "Hilight3DThickness" MENUSTYLEOPTIONS =/ "Animation" MENUSTYLEOPTIONS =/ "Font" MENUSTYLEOPTIONS =/ "TitleFont" MENUSTYLEOPTIONS =/ "MenuFace" MENUSTYLEOPTIONS =/ "PopupDelay" MENUSTYLEOPTIONS =/ "PopupOffset" MENUSTYLEOPTIONS =/ "TitleWarp" MENUSTYLEOPTIONS =/ "TitleUnderlines0" MENUSTYLEOPTIONS =/ "TitleUnderlines1" MENUSTYLEOPTIONS =/ "TitleUnderlines2" MENUSTYLEOPTIONS =/ "SeparatorsLong" MENUSTYLEOPTIONS =/ "SeparatorsShort" MENUSTYLEOPTIONS =/ "TrianglesSolid" MENUSTYLEOPTIONS =/ "TrianglesRelief" MENUSTYLEOPTIONS =/ "PopupImmediately" MENUSTYLEOPTIONS =/ "PopupDelayed" MENUSTYLEOPTIONS =/ "PopdownImmediately" MENUSTYLEOPTIONS =/ "PopdownDelayed" MENUSTYLEOPTIONS =/ "PopupActiveArea" MENUSTYLEOPTIONS =/ "DoubleClickTime" MENUSTYLEOPTIONS =/ "SidePic" MENUSTYLEOPTIONS =/ "SideColor" MENUSTYLEOPTIONS =/ "PopupAsRootMenu" MENUSTYLEOPTIONS =/ "PopupAsSubmenu" MENUSTYLEOPTIONS =/ "PopupIgnore" MENUSTYLEOPTIONS =/ "PopupClose" MENUSTYLEOPTIONS =/ "RemoveSubmenus" MENUSTYLEOPTIONS =/ "HoldSubmenus" MENUSTYLEOPTIONS =/ "SubmenusRight" MENUSTYLEOPTIONS =/ "SubmenusLeft" MENUSTYLEOPTIONS =/ "SelectOnRelease" MENUSTYLEOPTIONS =/ "ItemFormat" MENUSTYLEOPTIONS =/ "VerticalItemSpacing" MENUSTYLEOPTIONS =/ "VerticalMargins" MENUSTYLEOPTIONS =/ "VerticalTitleSpacing" MENUSTYLEOPTIONS =/ "AutomaticHotkeys" MENUSTYLEOPTIONS =/ "UniqueHotkeyActivatesImmediate" MENUSTYLEOPTIONS =/ "MouseWheel" MENUSTYLEOPTIONS =/ "ScrollOffPage" MENUSTYLEOPTIONS =/ "TrianglesUseFore" ; add option syntax ``` ``` CMD_CLASS_MODULE = ("Module" / "ModuleListenOnly") CMDMODULEARGS CMDMODULEARGS = MODULENAME [MODULEALIAS] ``` ``` CMD_MODULEPATH = "ModulePath" PATH ``` ``` CMD_MODULESYNCHRONOUS = "ModuleSynchronous" ["Expect" STRING] ["Timeout" INT] CMDMODULEARGS ``` ``` CMD_MODULETIMEOUT = "ModuleTimeout" INT ``` ``` CMD_MOUSE = "Mouse" ["(" WINDOWSELECTOR ")"] BUTTON BINDINGCONTEXT BINDINGMODIFIERS COMMAND ``` ``` CMD_MOVE = "Move" [MOVEARGS] MOVEARGS = !!! ``` ``` CMD_MOVETHRESHOLD = "MoveThreshold" [INT] ``` ``` CMD_MOVETODESK = "MoveToDesk" DESKNUMBER ``` ``` CMD_MOVETOPAGE = "MoveToPage" ["prev"] [MOVETOPAGEOPTIONS] 2(MOVETOPAGECOORD[MOVETOPAGESUFFIX]) MOVETOPAGEOPTIONS = "wrapx" / "wrapy" / "nodesklimitx" / "nodesklimity" MOVETOPAGECOORD = INT MOVETOPAGESUFFIX = "p" / "w" ``` ``` CMD_MOVETOSCREEN = "MoveToScreen" [XRANDRMONITORNAME] XRANDRMONITORNAME = !!! ``` ``` CMD_NOP = "Nop" ``` ``` CMD_OPAQUEMOVESIZE = "OpaqueMoveSize" [INT] ``` ``` CMD_PIPEREAD = "PipeRead" TOKEN ["quiet"] ``` ``` CMD_PLACEAGAIN = "PlaceAgain" *("Anim" "Icon") ``` ``` CMD_PLUS = "Plus" RESTOFLINE ``` ``` CMD_PRINTINFO = "PrintInfo" PRINTINFOSUBJECT PRINTINFOSUBJECT = (PRINTINFOKEYWORD [PRINTINFOVAL]) PRINTINFOVAL = "0" PRINTINFOVAL =/ "1" PRINTINFOVAL =/ "2" PRINTINFOKEYWORD = "Colors" PRINTINFOKEYWORD =/ "ImageCache" PRINTINFOKEYWORD =/ "Locale" PRINTINFOKEYWORD =/ "NLS" PRINTINFOKEYWORD =/ "Style" PRINTINFOKEYWORD =/ "Bindings" PRINTINFOKEYWORD =/ "Infostore" ``` ``` CMD_QUIT = "Quit" ``` ``` CMD_QUITSCREEN = "QuitScreen" ``` ``` CMD_READ = "Read" FILENAME ["quiet"] ``` ``` CMD_CLASS_RECAPTURE = ("Recapture" / "RecaptureWindow") ``` ``` CMD_CLASS_REFRESH = ("Refresh" / "RefreshWindow") ``` ``` CMD_REPEAT = "Repeat" ["command"] ``` ``` CMD_CLASS_RESIZE = ("Resize" / "ResizeMaximize") [RESIZEOPTS] RESIZEOPTS = (RESIZEOPTS_BR / RESIZEOPTS_OTHER) [2RESIZEARG] RESIZEOPTS_BR = ("bottomright" / "br") MOVEARGS RESIZEOPTS_OTHER = ("frame" / "fixeddirection" / ("direction" (DIRS_CENTER / "automatic")) / ("warptoborder" ["automatic"])) RESIZEARG = "keep" / (RESIZEARG_2 [RESIZEARGSUFFIX]) RESIZEARG_2 = "w" / (["w"] RESIZEARGVAL) RESIZEARGVAL = (SIGN INT) / POSINT RESIZEARGSUFFIX = "p" / "c" ``` ``` CMD_CLASS_RESIZEMOVE = ("ResizeMove" / "ResizeMoveMaximize") RESIZEOPTS MOVEARGS ``` ``` CMD_RESTACKTRANSIENTS = "RestackTransients" ``` ``` CMD_RESTART = "Restart" [STRING] ``` ``` CMD_SCHEDULE = "Schedule" ["periodic"] INT [INT] RESTOFLINE_COMMAND ``` ``` CMD_SCROLL = "Scroll" [(SCROLLDIM[SCROLLSUFFIX] SCROLLDIM[SCROLLSUFFIX]) / OPTION] SCROLLDIM = INT OPTION = "reverse" SCROLLSUFFIX = "p" ``` ``` CMD_SENDTOMODULE = "SendToModule" [MODULENAME] [STRING] ``` ``` CMD_SETANIMATION = "SetAnimation" INT [INT] ``` ``` CMD_SILENT = "Silent" RESTOFLINE_COMMAND ``` ``` CMD_STATE = "State" STATENUM [BOOL] ``` ``` CMD_CLASS_STICK = ("Stick" / "StickAcrossDesks" / "StickAcrossPages") [BOOL_OR_TOGGLE] ``` ``` CMD_CLASS_STYLE = ("Style" / "WindowStyle") [STYLENAME] [STYLEOPTIONS] ; note: WindowStyle operates on context window STYLEOPTIONS = STYLEOPTION ("," STYLEOPTION) STYLEOPTION = !!! ``` ``` CMD_TEARMENUOFF = "TearMenuOff" ; note: applies to menu context only ; note: ignores all arguments ; note: syntax description complete ``` ``` CMD_TITLE = "Title" ; note: applies to menu context only ; note: ignores all arguments ; note: syntax description complete ``` ``` CMD_TITLESTYLE = "TitleStyle" ;!!! ``` ``` CMD_SETENV = "SetEnv" [TOKEN_ENVVAR [TOKEN_ENVVAL]] TOKEN_ENVVAR = TOKEN TOKEN_ENVVAL = TOKEN ; note: does nothing if no arguments are given ; note: uses an empty value string if the second argument is missing ; note: ignores rest of line ; note: syntax description complete ``` ``` CMD_UNSETENV = "UnsetEnv" [TOKEN_ENVVAR] ; note: does nothing if argument is missing ; note: ignores rest of line ; note: syntax description complete ``` ``` CMD_UPDATESTYLES = "UpdateStyles" ; note: ignores rest of line ; note: syntax description complete ``` ``` CMD_WAIT = "Wait" [TOKEN_WAIT_PATTERN [STRIPPED_RESTOFLINE]] ; Note: The first argument, or - if present - the rest of the line is used as ; the pattern to wait for. ; note: the syntax with more than one argument is not documented. Comment in ; the sources call it the "old syntax". ; note: syntax description complete ``` ``` CMD_WARPTOWINDOW = "WarpToWindow" [PERCENT_ARG_PAIR] ; note: arguments not used when used on an unmanaged window ; note: arguments are ignored if not valid ; note: ignores rest of line ; note: syntax description complete ``` ``` ;!!!todo CMD_WINDOWLIST = "WindowList" ["(" WINDOWLISTCONDITIONS ")"] [WINDOWLISTPOSITION] [WINDOWLLISTOPTIONS] [COMMAND] WINDOWLISTPOSITION = WINDOWLISTCONTEXT_RECTANGLE INT INT [WINDOWLISTCONTEXTOPTIONS] WINDOWLISTCONTEXT_RECTANGLE = "Root" WINDOWLISTCONTEXT_RECTANGLE =/ "XineramaRoot" WINDOWLISTCONTEXT_RECTANGLE =/ "Mouse" WINDOWLISTCONTEXT_RECTANGLE =/ "Window" WINDOWLISTCONTEXT_RECTANGLE =/ "Interior" WINDOWLISTCONTEXT_RECTANGLE =/ "Tiitle" WINDOWLISTCONTEXT_RECTANGLE =/ ("Button" INT) WINDOWLISTCONTEXT_RECTANGLE =/ "Icon" WINDOWLISTCONTEXT_RECTANGLE =/ "Item" WINDOWLISTCONTEXT_RECTANGLE =/ "Context" WINDOWLISTCONTEXT_RECTANGLE =/ "This" WINDOWLISTCONTEXT_RECTANGLE =/ ("Rectangle" GEOMETRY) WINDOWLISTCONTEXTOPTIONS = "TearoffImmediately" WINDOWLISTCONTEXTOPTIONS =/ "SelectInPlace" WINDOWLISTOPTIONS = (WINDOWLISTKEYWORD [WINDOWLISTVALUE]) WINDOWLISTOPTIONS = "Geometry" WINDOWLISTOPTIONS =/ "NoGeometry" WINDOWLISTOPTIONS =/ "NoGeometryWithInfo" WINDOWLISTOPTIONS =/ "NoDeskNum" WINDOWLISTOPTIONS =/ "NoLayer" WINDOWLISTOPTIONS =/ "NoNumInDeskTitle" WINDOWLISTOPTIONS =/ "NoCurrentDeskTitle" WINDOWLISTOPTIONS =/ ("MaxLabelWidth" INT) WINDOWLISTOPTIONS =/ "TitleForAllDesks" WINDOWLISTOPTIONS =/ ("Function" FUNCNAME) WINDOWLISTOPTIONS =/ ("Desk" INT) WINDOWLISTOPTIONS =/ "CurrentDesk" WINDOWLISTOPTIONS =/ "NoIcons" WINDOWLISTOPTIONS =/ "Icons" WINDOWLISTOPTIONS =/ "OnlyIcons" WINDOWLISTOPTIONS =/ "NoNormal" WINDOWLISTOPTIONS =/ "Normal" WINDOWLISTOPTIONS =/ "OnlyNormal" WINDOWLISTOPTIONS =/ "NoSticky" WINDOWLISTOPTIONS =/ "Sticky" WINDOWLISTOPTIONS =/ "OnlySticky" WINDOWLISTOPTIONS =/ "NoStickyAcrossPages" WINDOWLISTOPTIONS =/ "StickyAcrossPages" WINDOWLISTOPTIONS =/ "OnlyStickyAcrossPages" WINDOWLISTOPTIONS =/ "NoStickyAcrossDesks" WINDOWLISTOPTIONS =/ "StickyAcrossDesks" WINDOWLISTOPTIONS =/ "OnlyStickyAcrossDesks" WINDOWLISTOPTIONS =/ "NoOnTop" WINDOWLISTOPTIONS =/ "OnTop" WINDOWLISTOPTIONS =/ "OnlyOnTop" WINDOWLISTOPTIONS =/ "NoOnBottom" WINDOWLISTOPTIONS =/ "OnlyOnBottom" WINDOWLISTOPTIONS =/ (Layer INT [INT]) WINDOWLISTOPTIONS =/ "UseSkipList" WINDOWLISTOPTIONS =/ "OnlySkipList" WINDOWLISTOPTIONS =/ "SortByResource" WINDOWLISTOPTIONS =/ "SortByClass" WINDOWLISTOPTIONS =/ "NoHotKeys" WINDOWLISTOPTIONS =/ "SelectOnRelease" WINDOWLISTOPTIONS =/ "ReverseOrder" WINDOWLISTOPTIONS =/ "NoDeskSort" WINDOWLISTOPTIONS =/ "CurrentAtEnd" WINDOWLISTOPTIONS =/ "IconifiedAtEnd" WINDOWLISTOPTIONS =/ "UseIconName" WINDOWLISTOPTIONS =/ "Alphabetic" WINDOWLISTOPTIONS =/ "NotAlphabetic" WINDOWLISTKEYWORD = !!! WINDOWLISTVALUE = !!! ; note: !!! to do ``` ``` CMD_WINDOWSHADE = "WindowShade" ["shadeagain"] ["last" / DIRS_MINOR] [WINDOWSHADEMODE] WINDOWSHADEMODE = WINDOWSHADETOGGLE / WINDOWSHADEON / WINDOWSHADEOFF WINDOWSHADETOGGLE = () / TOGGLE WINDOWSHADEON = TRUE WINDOWSHADEOFF = FALSE / "2" ; note: defaults to toggle ; note: if "last" or DIRS_MINOR is present and valid, ignore the ; WINDOWSHADEMODE argument if present ; note: ignores rest of line ; note: syntax description complete ``` ``` CMD_XSYNC = "XSync" ; note: ignores all arguments ; note: syntax description complete ``` ``` CMD_XSYNCHRONIZE = "XSynchronize" [BOOL_OR_TOGGLE_DEFAULT_TOGGLE] ; note: argument defaults to toggle if missing or invalid ; note: ignores rest of line ; note: syntax description complete ``` ``` CMD_XORPIXMAP = "XorPixmap" [IMAGEFILE] ; note: if argument is missing, maps to "XorValue 0" ; note: ignores rest of line ; note: syntax description complete ``` ``` CMD_XORVALUE = "XorValue" [INTEGER_ARGUMENT] ; note: argument defaults to 0 if missing or malformed ; note: argument is converted to unsinged long before use ; note: argument should be parsed as unsigned long to prevent misinterpretation ; note: ignores rest of line ; note: syntax description complete ``` ``` ;; decor commands CMD_ADDTODECOR = "AddToDecor" [TOKEN_DECORNAME] RESTOFLINE_COMMAND ; note: does nothing if the decor name is missing ; note: if no decor with that name exists, creates a new one ; note: adds the command to the decor ; note: syntax description complete CMD_CHANGEDECOR = "ChangeDecor" [TOKEN_DECORNAME] ; note: does nothing if no decor name is given ; note: ignores rest of line ; note: syntax description complete ; note: operates on current window CMD_DESTROYDECOR = "DestroyDecor" ["recreate"] [TOKEN_DECORNAME] ; note: does nothing if no decor name is given ; note: ignores rest of line ; note: syntax description complete CMD_UPDATEDECOR = "UpdateDecor" [TOKEN_DECORNAME] ; note: updates all decors if decor name is missing ; note: ignores rest of line ; note: syntax description complete ``` ``` ;; conditional commands CMD_BREAK = "Break" [BREAKLEVELS] BREAKLEVELS = INT ; note: uses -1 if BREAKLEVELS is missing or invalid (<= 0) ; note: syntax description complete ``` ``` CMD_CLASS_PICK = ("ThisWindow" / "Pick" / "PointerWIndow" ) [SELECTCMDCONDITION] RESTOFLINE_COMMAND ; note: syntax description complete ``` ``` CMD_ALL = "All" [ALLOPTIONS] [SELECTCMDCONDITION] RESTOFLINE_COMMAND ALLOPTIONS = "Reverse" ALLOPTIONS =/ "UseStack" ; note: syntax description complete ``` ``` CMD_NOWINDOW = "NoWindow" RESTOFLINE_COMMAND ; note: executes the command without a window context ; note: syntax description complete ``` ``` CMD_CLASS_CIRCULATE = ("Any" / "Current" / "Next" / "None" / "Prev") [SELECTCMDCONDITION] RESTOFLINE_COMMAND ; note: syntax description complete ``` ``` CMD_DIRECTION = "Direction" ["FromPointer"] DIRS_CENTER [SELECTCMDCONDITION] RESTOFLINE_COMMAND ; note: syntax description complete ``` ``` CMD_SCANFORWINDOW = "ScanForWindow" ["FromPointer"] DIRS_MAIN DIRS_MAIN [SELECTCMDCONDITION] RESTOFLINE_COMMAND ; note: syntax description complete ``` ``` CMD_WINDOWID = "WindowId" [("root" [WINDOWIDSCREENNUM]) / (WINDOWID [SELECTCMDCONDITION])] RESTOFLINE_COMMAND ; does nothing if no argument is given of the window id is invalid ; note: syntax description complete WINDOWIDSCREENNUM = POSINT ; note: valid range is 0 to ; note: mvwm has replaced Xinerama with XRandr, therfore using integets to ; refer to monitors won't work. WINDOWID = LONGINT ; note: long value parsed by strtol without error checking ``` ``` CMD_TEST = "Test" TESTCMDCONDITION RESTOFLINE_COMMAND TESTCMDCONDITIONSTRING = [STRING_IN_BRACES / STRING_IN_PARENTHESES] ; note: the STRING_IN_... is then parsed with the TESTCMDCONDITIONS rule TESTCMDCONDITIONS = STRING_COMMA_TERMINATED *["," STRING_COMMA_TERMINATED] ; note: the TESTCMDCONDITIONS is then parsed with the TESTCMDCONDNEG rule TESTCMDCONDNEG = ["!"] TESTCMDCOND TESTCMDCOND = ("version" ((TOKEN_TESTCMDOPERATOR VERSION) / TOKEN_VERSIONPATTERN)) TESTCMDCOND =/ ("EnvIsSet" TOKEN_ENVVAR) TESTCMDCOND =/ ("EnvMatch" ENVMATCHARG) TESTCMDCOND =/ (("EdgeHasPointer" / "EdgeIsActive") (DIRS_MAIN / "Any")) TESTCMDCOND =/ ("Start" / "Init" / "Restart" / "Exit" / "Quit" / "ToRestart") TESTCMDCOND =/ ("True" / "False") TESTCMDCOND =/ (("F" / "R" / "W" / "X" / "I") "," FILENAME) TOKEN_TESTCMDOPERATOR = ">=" / ">" / "<=" / "==" / "!=" ENVMATCHARG = ("infostore."INFOSTOREKEY) / TOKEN_ENVVAR TESTCMDVERSIONPATTERN = TOKEN ; note: TESTCMDVERSIONPATTERN is compared to the version string (x.y.z) and may ; contain wildcards. ``` ``` CMD_TESTRC = "TestRc" [STRING_IN_BRACES / STRING_IN_PARENTHESES] RESTOFLINE_COMMAND TESRRCRCNEG = ["!"] TESTRCRC TESTRCRC = "1" / "match" TESTRCRC =/ "0" / "nomatch" TESTRCRC =/ "-1" / "error" TESTRCRC =/ "-2" / "break" ; note: the STRING_IN_... is then parsed with the TESTRCRC rule ; note: does nothing if no command is given : note: the condition inside the braces or parentheses may contain quoted ; note: syntax description complete ``` ``` ;; !!! more common rules ; Integer arguments as parsed by GetIntegerArguments() INTEGER_ARGUMENT = INT ; Loaded by PictureFindImageFile IMAGEFILE = TOKEN ; note: if file not found, try again with IMAGEFILE ".gz" ``` ``` ; parsed by parse_gravity_argument DIR_N = "-" / "N" / "North" / "Top" / "t" / "Up" / "u" DIR_E = "]" / "E" / "East" / "Right" / "r" / "Right" / "r" DIR_S = "_" / "S" / "South" / "Bottom" / "b" / "Down" / "d" DIR_W = "[" / "W" / "West" / "Left" / "l" / "Left" / "l" DIR_NE = "^" / "NE" / "NorthEast" / "TopRight" / "tr" / "UpRight" / "ur" DIR_SE = ">" / "SE" / "SouthEast" / "BottomRight" / "br" / "DownRight" / "dr" DIR_SW = "v" / "SW" / "SouthWest" / "BottomLeft" / "bl" / "DownLeft" / "dl" DIR_NE = "<" / "NW" / "NorthWest" / "TopLeft" / "tl" / "UpLeft" / "ul" DIR_C = "." / "C" / "Center" / "Centre" DIRS_MAJOR = DIR_N / DIR_E / DIR_S / DIR_W DIRS_MINOR = DIRS_MAIN / DIR_NE / DIR_SE / DIR_SW / DIR_NW DIRS_ALL = DIRS_MAIN / DIRS_DIAG / DIR_C ``` ``` ; Parsed by ParseToggleArgument BOOL_OR_TOGGLE_DEFAULT_TOGGLE = BOOL / TOGGLE BOOL_OR_TOGGLE_DEFAULT_TRUE = BOOL / TOGGLE BOOL_OR_TOGGLE_DEFAULT_FALSE = BOOL / TOGGLE BOOL_DEFAULT_TRUE = BOOL BOOL_DEFAULT_FALSE = BOOL ``` ``` ; parsed by strtol LONGINT = INT ``` ``` ; parsed by select_cmd() SELECTCMDCONDITION = [STRING_IN_BRACES / STRING_IN_PARENTHESES] ; note: the STRING_IN_... is then parsed with the CONDITIONMASK rule ``` ``` ; parsed by CreateFlagString CONDITIONMASK = [CM_COND_NEG *("," CM_COND_NEG)] CM_COND_NEG = ["!"] CM_COND CM_COND = ("AcceptsFocus") CM_COND =/ ("Focused") CM_COND =/ ("HasPointer") CM_COND =/ ("Iconic") CM_COND =/ ("Visible") CM_COND =/ ("Overlapped") CM_COND =/ ("PlacedByButton" [BUTTON]) CM_COND =/ ("PlacedByButton3") CM_COND =/ ("Raised") CM_COND =/ ("Sticky") CM_COND =/ ("StickyAcrossPages") CM_COND =/ ("StickyAcrossDesks") CM_COND =/ ("StickyIcon") CM_COND =/ ("StickyAcrossPagesIcon") CM_COND =/ ("StickyAcrossDesksIcon") CM_COND =/ ("Maximized") CM_COND =/ ("FixedSize") CM_COND =/ ("FixedPosition") CM_COND =/ ("HasHandles") CM_COND =/ ("Iconifiable") CM_COND =/ ("Maximizable") CM_COND =/ ("Closable") CM_COND =/ ("Shaded") CM_COND =/ ("Transient") CM_COND =/ ("PlacedByMvwm") CM_COND =/ ("CurrentDesk") CM_COND =/ ("CurrentPage") CM_COND =/ ("CurrentGlobalPage") CM_COND =/ ("CurrentPageAnyDesk") CM_COND =/ ("CurrentScreen") CM_COND =/ ("AnyScreen") CM_COND =/ ("CurrentGlobalPageAnyDesk") CM_COND =/ ("CirculateHit") CM_COND =/ ("CirculateHitIcon") CM_COND =/ ("CirculateHitShaded") CM_COND =/ ("State" STATENUM) CM_COND =/ ("Layer" [INT]) ; argument is the layer number; negative values are silently ignored CM_COND =/ NAMELIST CM_NAMELIST = NAME *["|" NAME] CM_NAME = STRING ; up to and excluding next "|" ``` ``` QUOTED_TOKEN = TOKEN ``` ``` STATENUM = DIGIT / ("1" DIGIT) / ("2" DIGIT) / "30" / "31" ``` ``` ; Parsed by GetOnePercentArgument() PERCENT_ARG = INT [PERCENT_ARG_SUFFIX] PERCENT_ARG_SUFFIX = "p" / "P" ; Parsed by GetTwoPercentArguments() PERCENT_ARG_PAIR = 2PERCENT_ARG / RECTANGLE_ARGS ; Parsed by GetRectangleArguments() RECTANGLE_ARGS = INT RECT_CHARACTER INT RECT_CHARACTER = %x01-09 / %x0b-4f / %x51-6f / %x71-ff ; note: any character except p, P and \n. DQ_RECT_CHARACTER = %x01-09 / %x0b-4f / %x51-6f / %x71-ff ``` ``` ;; string rules DQUOTE = %x22 ; " SQUOTE = %x27 ; ' BQUOTE = %x60 ; ` CQUOTE = %x5c ; \ ; any character except \, ", ', `, whitespace, newline SCHAR_UNQ = %x01-08 SCHAR_UNQ =/ %x0b-1f SCHAR_UNQ =/ %x21 SCHAR_UNQ =/ %x23-26 SCHAR_UNQ =/ %x28-5b SCHAR_UNQ =/ %x5d-5f SCHAR_UNQ =/ %x61-ff ; any character except \, ", ', `, ), whitespace, newline SCHAR_UNQ_NO_CPAREN = %x01-08 SCHAR_UNQ_NO_CPAREN =/ %x0b-1f SCHAR_UNQ_NO_CPAREN =/ %x21 SCHAR_UNQ_NO_CPAREN =/ %x23-26 SCHAR_UNQ_NO_CPAREN =/ %x28 SCHAR_UNQ_NO_CPAREN =/ %x2a-5b SCHAR_UNQ_NO_CPAREN =/ %x5d-5f SCHAR_UNQ_NO_CPAREN =/ %x61-ff ; any character except \, ", ', `, ], whitespace, newline SCHAR_UNQ_NO_CBRACE = %x01-08 SCHAR_UNQ_NO_CBRACE =/ %x0b-1f SCHAR_UNQ_NO_CBRACE =/ %x21 SCHAR_UNQ_NO_CBRACE =/ %x23-26 SCHAR_UNQ_NO_CBRACE =/ %x28-5b SCHAR_UNQ_NO_CBRACE =/ %x5e-5f SCHAR_UNQ_NO_CBRACE =/ %x61-ff ; any character except \, ", ', `, comma, whitespace, newline SCHAR_UNQ_NO_COMMA = %x01-08 SCHAR_UNQ_NO_COMMA =/ %x0b-1f SCHAR_UNQ_NO_COMMA =/ %x21 SCHAR_UNQ_NO_COMMA =/ %x23-26 SCHAR_UNQ_NO_COMMA =/ %x28-2b SCHAR_UNQ_NO_COMMA =/ %x2d-5b SCHAR_UNQ_NO_COMMA =/ %x5d-5f SCHAR_UNQ_NO_COMMA =/ %x61-ff ; \ followed by any character except newline SCHAR_CQ_CHAR = "\" (%x01-09 /%x0b-ff) ; any character except ", whitespace, newline (\ quotes resolved) SCHAR_DQ = SCHAR_UNQ SCHAR_DQ =/ SQUOTE SCHAR_DQ =/ BQUOTE SCHAR_DQ =/ SCHAR_CQ_CHAR ; any character except ', whitespace, newline (\ quotes resolved) SCHAR_SQ = SCHAR_UNQ SCHAR_SQ =/ DQUOTE SCHAR_SQ =/ BQUOTE SCHAR_SQ =/ SCHAR_CQ_CHAR ; any character except `, whitespace, newline (\ quotes resolved) SCHAR_BQ = SCHAR_UNQ SCHAR_BQ =/ DQUOTE SCHAR_BQ =/ SQUOTE SCHAR_BQ =/ SCHAR_CQ_CHAR ; any simple character or one quoted with \ SCHAR_CQ = SCHAR_UNQ SCHAR_CQ =/ SCHAR_CQ_CHAR ``` ``` ; unquoted string STRING_UNQ = 1*SCHAR_UNQ STRING_UNQ_NO_CPAREN = 1*SCHAR_UNQ_NO_CPAREN STRING_UNQ_NO_CBRACE = 1*SCHAR_UNQ_NO_CBRACE STRING_UNQ_NO_COMMASTRING_UNQ_NO_COMMA = 1*SCHAR_UNQ_NO_COMMA ; strings quoted with ", ', ` STRING_DQ = DQUOTE 1*SCHAR_DQ DQUOTE STRING_SQ = SQUOTE 1*SCHAR_SQ SQUOTE STRING_BQ = BQUOTE 1*SCHAR_BQ BQUOTE STRING_Q_PAIR = STRING_DQ / STRING_SQ / STRING_BQ STRING = 1*(STRING_UNQ / STRING_DQ / STRING_SQ / STRING_BQ) TOKEN = STRING ; a string with embedded whitespace enclosed in [] used in condigions STRING_IN_BRACES = *WS "[" *(STRING_UNQ_NO_CBRACE / STRING_Q_PAIR / 1*WSC) "]" ; a string with embedded whitespace enclosed in () used in conditions STRING_IN_PARENTHESES = *WS "[" *(STRING_UNQ_NO_CPAREN / STRING_Q_PAIR / 1*WSC) "]" ; a string with embedded whitespace terminated by an unquoted comma STRING_COMMA_TERMINATED = *(STRING_UNQ_NO_COMMA / STRING_Q_PAIR / 1*WSC) ``` ``` ;; !!! obsolete commands removed in mvwm CMD_GNOMEBUTTON = "GnomeButton" CMD_GNOMESHOWDESKS = "GnomeShowDesks" CMD_SAVESESSION = "SaveSession" CMD_SAVEQUITSESSION = "SaveQuitSession" CMD_STROKE = "Stroke" CMD_STROKEFUNC = "StrokeFunc" CMD_QUITSESSION = "QuitSession" CMD_XINERAMA = "Xinerama" CMD_XINERAMAPRIMARYSCREEN = "XineramaPrimaryScreen" CMD_XINERAMASLS = "XineramaSls" CMD_XINERAMASLSSCREENS = "XineramaSlsScreens" CMD_XINERAMASLSSIZE = "XineramaSlsSize" ;; !!! obsolete commands in fvwm2 CMD_COLORLIMIT = "ColorLimit" CMD_WINDOWFONT = "WindowFont" ; Style * Font ... CMD_WINDOWSHADEANIMATE = "WindowShadeAnimate" ; Style * WindowShadeSteps CMD_WINDOWSDESK = "WindowsDesk" ; See 'MoveToDesk' CMD_DESK = "Desk" ; See 'Gotodesk' CMD_EDGERESISTANCE = "EdgeResistance" ; Style * EdgeMoveDelay, EdgeMoveResistance CMD_GLOBALOPTS = "GlobalOpts" ; Various Style options CMD_HILIGHTCOLOR = "HilightColor" ; Style CMD_ICONFONT = "IconFont" FONTNAME ; Style CMD_ICONPATH = "IconPath" ; ImagePath CMD_PIXMAPPATH = "PixmapPath" ; ImagePath CMD_SNAPATTRACTION = "SnapAttraction" ; Style * SnapAttraction CMD_SNAPGRID = "SnapGrid" ; Style * SnapGrid ``` fvwm-2.6.7/config.h.in0000644000175700017570000003743313010101115011460 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Old AIX systems (3.2.5) don't define some common keysyms. */ #undef COMPAT_OLD_KEYSYMDEF /* Old libstroke <= 0.4 does not use STROKE_ prefix for constants. */ #undef COMPAT_OLD_LIBSTROKE /* Support fribidi-0.10.4 and older with "CHARSET" spelling. */ #undef FRIBIDI_CHARSET_SPELLING /* Suffix for old (to be deprecated) config filenames */ #undef FVWM2RC /* Produces a log of all executed commands and their times on stderr. */ #undef FVWM_COMMAND_LOG /* Name of config filenames in FVWM_USERDIR and FVWM_DATADIR */ #undef FVWM_CONFIG /* if you would like to see lots of debug messages from fvwm, for debugging purposes, uncomment the next line */ #undef FVWM_DEBUG_MSGS /* Where to search for images. */ #undef FVWM_IMAGEPATH /* Define if gdk-imlib is used */ #undef GDK_IMLIB /* Define if fribidi library is used. */ #undef HAVE_BIDI /* Define to 1 if you have the `bindtextdomain' function. */ #undef HAVE_BINDTEXTDOMAIN /* Have nl_langinfo (CODESET) */ #undef HAVE_CODESET /* Define to 1 if you have the `dgettext' function. */ #undef HAVE_DGETTEXT /* Define to 1 if you have the `div' function. */ #undef HAVE_DIV /* Define to 1 if you have the header file. */ #undef HAVE_DMALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getpwuid' function. */ #undef HAVE_GETPWUID /* Define to 1 if you have the `gettext' function. */ #undef HAVE_GETTEXT /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define if readline has full GNU interface */ #undef HAVE_GNU_READLINE /* Define if iconv (in the libc) or libiconv is available */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dmalloc' library (-ldmalloc). */ #undef HAVE_LIBDMALLOC /* Define to 1 if you have the `efence' library (-lefence). */ #undef HAVE_LIBEFENCE /* Define to 1 if you have the `intl' library (-lintl). */ #undef HAVE_LIBINTL /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the `lstat' function. */ #undef HAVE_LSTAT /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mkfifo' function. */ #undef HAVE_MKFIFO /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef HAVE_NLS /* Define PNG */ #undef HAVE_PNG /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define if readline is available. */ #undef HAVE_READLINE /* Define if rplay library is used. */ #undef HAVE_RPLAY /* Define if librsvg library is used. */ #undef HAVE_RSVG /* Enable the use of mkstemp */ #undef HAVE_SAFETY_MKSTEMP /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setpgid' function. */ #undef HAVE_SETPGID /* Define to 1 if you have the `setpgrp' function. */ #undef HAVE_SETPGRP /* Define to 1 if you have the `setvbuf' function. */ #undef HAVE_SETVBUF /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* Define to 1 if you have the `siginterrupt' function. */ #undef HAVE_SIGINTERRUPT /* Define to 1 if you have the `siglongjmp' function. */ #undef HAVE_SIGLONGJMP /* Define to 1 if you have the `sigsetjmp' function. */ #undef HAVE_SIGSETJMP /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define if Solaris' Xinerama calls are being used. (Solaris 7 11/99 and later) */ #undef HAVE_SOLARIS_XINERAMA /* Define if Solaris' X11/extensions/xinerama.h header is provided. (Solaris 9 and later) */ #undef HAVE_SOLARIS_XINERAMA_H /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define if stroke library is used. */ #undef HAVE_STROKE /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSTEMINFO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the `textdomain' function. */ #undef HAVE_TEXTDOMAIN /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vfprintf' function. */ #undef HAVE_VFPRINTF /* Define to 1 if you have the `wait3' function. */ #undef HAVE_WAIT3 /* Define to 1 if you have the `wait4' function. */ #undef HAVE_WAIT4 /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID /* Define if Xkb extension is used. */ #undef HAVE_X11_XKBLIB_H /* Define if Xcursor library is used. */ #undef HAVE_XCURSOR /* Define if Xft library is used. */ #undef HAVE_XFT /* Define if Xft 2 library is used. */ #undef HAVE_XFT2 /* Define if Xft library can handle utf8 encoding */ #undef HAVE_XFT_UTF8 /* Define if Xinerama library is used. */ #undef HAVE_XINERAMA /* Enable X output method */ #undef HAVE_XOUTPUT_METHOD /* Define if Xrender library is used. */ #undef HAVE_XRENDER /* Define if MIT Shared Memory extension is used. */ #undef HAVE_XSHM /* define if second arg of iconv use const */ #undef ICONV_ARG_CONST /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define a suitable cast for arguments 2-4 of `select'. On most systems, this will be the empty string, as select usually takes pointers to fd_set. */ #undef SELECT_FD_SET_CAST /* Enables session management functionality. */ #undef SESSION /* Define to 1 if the `setpgrp' function takes no argument. */ #undef SETPGRP_VOID /* Define if you want the Shaped window extensions. Shaped window extensions seem to increase the window managers RSS by about 60 Kbytes. They provide for leaving a title-bar on the window without a border. If you don't use shaped window extension, you can either make your shaped windows undecorated, or live with a border and backdrop around all your shaped windows (oclock, xeyes) If you normally use a shaped window (xeyes or oclock), you might as well compile this extension in, since the memory cost is minimal in this case (The shaped window shared libs will be loaded anyway). If you don't normally use a shaped window, you have to decide for yourself. Note: if it is compiled in, run time detection is used to make sure that the currently running X server supports it. */ #undef SHAPE /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `Pixel', as computed by sizeof. */ #undef SIZEOF_PIXEL /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P /* The size of `Window', as computed by sizeof. */ #undef SIZEOF_WINDOW /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* define if we use libiconv (not needed in general: for example iconv is native with recent glibc) */ #undef USE_LIBICONV /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Define if Xinerama should be emulated on a single screen. */ #undef USE_XINERAMA_EMULATION /* Version number of package */ #undef VERSION /* Additional version information, like date */ #undef VERSIONINFO /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define if Xpm library is used. */ #undef XPM /* Define to 1 if the X Window System is missing or not being used. */ #undef X_DISPLAY_MISSING /* Enables to use setlocale() provided by X */ #undef X_LOCALE #ifdef COMPAT_OLD_KEYSYMDEF # define XK_Page_Up XK_Prior # define XK_Page_Down XK_Next #endif #ifdef COMPAT_OLD_LIBSTROKE /* currently we only use one constant */ # define STROKE_MAX_SEQUENCE MAX_SEQUENCE #endif #ifdef FRIBIDI_CHARSET_SPELLING # define FRIBIDI_CHAR_SET_NOT_FOUND FRIBIDI_CHARSET_NOT_FOUND #endif #ifdef FVWM_COMMAND_LOG # define FVWM_DEBUG_TIME 1 #endif #ifdef FVWM_DEBUG_MSGS # define DBUG(x,y) fvwm_msg(DBG,x,y) #else # define DBUG(x,y) /* no messages */ #endif #ifdef USE_LIBICONV /* define to use locale_charset in the place of nl_langinfog if libiconv * is used */ #undef HAVE_LIBCHARSET #endif #ifdef HAVE_STROKE # define STROKE_ARG(x) x, # define STROKE_CODE(x) x #else # define STROKE_ARG(x) # define STROKE_CODE(x) #endif /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE /** * The next few defines are options that are only changed from their values * shown here on systems that _don't_ use the configure script. **/ /* Enable tests for missing too many XEvents. Usually you want this. */ #define WORRY_ABOUT_MISSED_XEVENTS 1 /* Define if the X11 ConnectionNumber is actually a file descriptor. */ #define HAVE_X11_FD 1 /* Define if fork() has unix semantics. On VMS, no child process is created until after a successful exec(). */ #define FORK_CREATES_CHILD 1 /* Suffix for executable filenames; NULL if no extension needed. */ #define EXECUTABLE_EXTENSION NULL /* Define to remove the extension from executable pathnames before calling exec(). */ #undef REMOVE_EXECUTABLE_EXTENSION /* Enables the "MiniIcon" Style option to specify a small pixmap which * can be used as one of the title-bar buttons, shown in window list, * utilized by modules, etc. Requires PIXMAP_BUTTONS to be defined * (see below). */ /* #undef MINI_ICONS */ /* NOTE: hard coded to 1 */ #if 1 #define FMiniIconsSupported 1 #else #define FMiniIconsSupported 0 #endif #if RETSIGTYPE != void #define SIGNAL_RETURN return 0 #else #define SIGNAL_RETURN return #endif /* Allow GCC extensions to work, if you have GCC. */ #ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ # define __attribute__(x) # endif /* The __-protected variants of `format' and `printf' attributes * are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) # define __format__ format # define __printf__ printf # endif #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_MEMORY_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #if defined (HAVE_MALLOC_H) && !defined (__FreeBSD__) && !defined (__OpenBSD__) && !defined(__NetBSD__) # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifndef HAVE_STRCHR # define strchr(_s,_c) index((_s),(_c)) # define strrchr(_s,_c) rindex((_s),(_c)) #endif #ifndef HAVE_MEMCPY # define memcpy(_d,_s,_l) bcopy((_s),(_d),(_l)) #endif #ifndef HAVE_MEMMOVE # define memmove(_d,_s,_l) bcopy((_s),(_d),(_l)) #endif #if HAVE_SYS_TYPES_H # include #endif #if HAVE_UNISTD_H # include #endif #ifndef min # define min(a,b) (((a)<(b)) ? (a) : (b)) #endif #ifndef max # define max(a,b) (((a)>(b)) ? (a) : (b)) #endif #ifndef abs # define abs(a) (((a)>=0)?(a):-(a)) #endif #include "libs/defaults.h" #ifndef FEVENT_C #include #include #include "libs/FEvent.h" #endif #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif #ifdef HAVE_LSTAT #define DO_USE_LSTAT 1 #define fvwm_lstat(x,y) lstat(x,y) #else #define DO_USE_LSTAT 0 #define fvwm_lstat(x,y) -1 #endif #ifdef HAVE_X11_XKBLIB_H #include #define fvwm_KeycodeToKeysym(d, k, l, g) \ (XkbKeycodeToKeysym((d), (k), (g), (l))) #else #define fvwm_KeycodeToKeysym(d, k, x, i) (XKeycodeToKeysym((d), (k), (i))) #endif /* A macro that touches a variable in a compiler independent way to suppress * warnings. */ #define SUPPRESS_UNUSED_VAR_WARNING(x) \ do { void *p; p = (void *)&x; (void)p; } while (0); /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to the type used in arguments 2-4 of `select', if not set by system headers. */ #undef fd_set /* Define to the type used in argument 1 `select'. Usually this is an `int'. */ #undef fd_set_size_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to the type of a signed integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef int16_t /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Specify a type for sig_atomic_t if it's not available. */ #undef sig_atomic_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to the type of an unsigned integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef uint16_t fvwm-2.6.7/utils/0000755000175700017570000000000013010103344010651 500000000000000fvwm-2.6.7/utils/fvwm_make_directory_menu.sh0000755000175700017570000000440712673746443016254 00000000000000#!/bin/sh # ### # This script demonstates the fvwm menu MissingSubmenuFunction functionality. # You can use a more configurable fvwm-menu-directory instead. # The line below almost exactly simulates this script: # fvwm-menu-directory --links --order 4 --exec-file vi --dir DIR ### # # Modification History # # Created on 06/07/99 by Dominik Vogt (domivogt): # # provides output to read in with PipeRead to build a menu # containing a directory listing. # # You should put these lines into your fvwm configuration file to invoke # this script: # # AddToFunc MakeMissingDirectoryMenu # + i piperead 'fvwm_make_directory_menu.sh '$0 # # And put these lines in the menu from which you want to pop up the # directory menus: # # AddToMenu SomeMenu MissingSubmenuFunction MakeMissingDirectoryMenu # + "my directory item" Popup /whatever/path/you/like # # Note: please use absolute path names. # # configuration section # # If you want to optimize for speed, unset this variable. Warning: speed # optimization takes up a lot of memory that is never free'd again while fvwm # is running. OPTIMIZE_SPACE=yes # you may use the absolute path here if you have an alias like ls="ls -F" LS="/bin/ls -LF" SED=sed # the name of our menu MENU=`echo $1 | $SED -e 's://*:/:g'` PMENU=`echo "$MENU" | $SED -e s:\"::g` # the command to execute on plain files ACTION=vi # the terminal program to invoke TERMINAL="xterm -e" TERMINALSHELL="xterm" # # you may customize this script below here. # # dump all menu items echo DestroyMenu recreate \""$PMENU"\" # add a new title echo AddToMenu \""$PMENU"\" \""$PMENU"\" Exec "echo cd $MENU\; $TERMINALSHELL | $SHELL" # add a separator echo AddToMenu \""$PMENU"\" \"\" nop # destroy the menu after it is popped down if [ "$OPTIMIZE_SPACE" = yes ] ; then echo AddToMenu \""$PMENU"\" DynamicPopDownAction DestroyMenu \""$PMENU"\" fi # set the 'missing submenu function' echo AddToMenu \""$PMENU"\" MissingSubmenuFunction MakeMissingDirectoryMenu # add directory contents $LS "$MENU" 2> /dev/null | $SED -n ' /\/$/ bdirectory s:[=*@|]$::1 s:"::g s:^\(.*\)$:AddToMenu "'"$PMENU"'" "\1" Exec '"$TERMINAL $ACTION"' "'"$MENU"'/\1":1 bnext :directory s:^\(.*\)/$:AddToMenu "'"$PMENU"'" "\1" Popup "'"$PMENU"'/\1" item +100 c:1 :next s://*:/:g p ' fvwm-2.6.7/utils/fvwm-version-str.sh0000755000175700017570000000102313010100253014370 00000000000000#!/bin/sh # # fvwm-version-str: emits the version of fvwm which is building. # If this is a release build, then the tag name is chomped # to remove extraneous git information. # # If it's a developer build, it's left as-is. # # # # Intended to be called from configure.ac (via autogen.sh) if grep -q -i '^ISRELEASED="yes"' ./configure.ac; then # A release build. Strip the git information off the tag name. git describe --tags --abbrev=0 2>/dev/null || echo "2.6.7" else git describe --always --long --dirty fi fvwm-2.6.7/utils/Makefile.am0000644000175700017570000000053113010050227012625 00000000000000## Process this file with automake to create Makefile.in EXTRA_DIST = fvwm_make_browse_menu.sh fvwm_make_directory_menu.sh \ fvwm-version-str.sh LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm $(xpm_LIBS) \ $(X_PRE_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) $(png_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(X_CFLAGS) $(png_CFLAGS) fvwm-2.6.7/utils/Makefile.in0000644000175700017570000003536613010103323012650 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = utils DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ EXTRA_DIST = fvwm_make_browse_menu.sh fvwm_make_directory_menu.sh \ fvwm-version-str.sh LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm $(xpm_LIBS) \ $(X_PRE_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) $(png_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(X_CFLAGS) $(png_CFLAGS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign utils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign utils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/utils/fvwm_make_browse_menu.sh0000755000175700017570000000447612673746443015557 00000000000000#!/bin/sh # ### # This script demonstrates the fvwm menu DynamicPopupAction functionality. # You can use a more configurable fvwm-menu-directory instead. # The line below almost exactly simulates this script: # fvwm-menu-directory --reuse --links --order 4 --name \ # --exec-file vi --exec-title - --special-dirs ### # # Modification History # # Created on 05/06/99 by Dominik Vogt (domivogt): # # provides output to read in with PipeRead to build a menu # containing a directory listing. # # You should put these lines into your fvwm configuration file to invoke # this script: # # AddToMenu # + DynamicPopupAction Piperead 'fvwm_make_browse_menu.sh ' # # configuration section # # the file containing the desired directory name DIRFILE="$HOME/.fvwm_browse_menu_cwd" # you may use the absolute path here if you have an alias like ls="ls -F" LS=ls SED=sed # the name of our menu MENU=`echo "$1" | $SED -e s:\"::g` # the command to execute on plain files ACTION=vi # the terminal program to invoke TERMINAL="xterm -e" # # you may customize this script below here. # # create a file containing the current working directory if [ ! -f "$DIRFILE" ] ; then echo "$HOME" > "$DIRFILE" fi # get desired directory DIR="`cat "$DIRFILE"`" if [ ! -d "$DIR" ] ; then DIR="$HOME" fi # dump all menu items echo DestroyMenu recreate \""$MENU"\" # add a new title echo AddToMenu \""$MENU"\" \"`cat "$DIRFILE"`\" Title # add '..' entry cd "$DIR"/.. echo AddToMenu \""$MENU"\" \"..\" PipeRead \'echo \""`/bin/pwd`"\" \> "$DIRFILE" ';' echo Menu \\\""$MENU"\\\" WarpTitle\' # add separator echo AddToMenu \""$MENU"\" \"\" Nop # add $HOME entry echo AddToMenu \""$MENU"\" \"~\" PipeRead \'echo \""$HOME"\" \> "$DIRFILE" ';' echo Menu \\\""$MENU"\\\" WarpTitle\' # add separator echo AddToMenu \""$MENU"\" \"\" Nop # add directory contents for i in `"$LS" "$DIR"` ; do if [ -d "$DIR/$i" ] ; then # it's a directory cd "$DIR/$i" # put new path in $DIRFILE and invoke the menu again echo AddToMenu \""$MENU"\" \""$i/"\" PipeRead \'echo \"`echo $DIR/$i|$SED -e s://:/:g`\" \> "$DIRFILE" ';' echo Menu \\\""$MENU"\\\" WarpTitle\' else # something else, apply $ACTION to it echo AddToMenu \""$MENU"\" \""$i"\" Exec $TERMINAL $ACTION \""$DIR/$i"\" fi done fvwm-2.6.7/libs/0000755000175700017570000000000013010103342010440 500000000000000fvwm-2.6.7/libs/Module.h0000644000175700017570000001661312773467232012017 00000000000000/* -*-c-*- */ #ifndef LIBS_MODULE_H #define LIBS_MODULE_H /* ** Module.c: code for modules to communicate with fvwm */ #include #include "libs/fvwmlib.h" /** * fvwm sends packets of this type to modules. **/ typedef struct { /* always holds START_FLAG value */ unsigned long start_pattern; /* one of the M_xxx values, below */ unsigned long type; /* number of unsigned longs in entire packet, *including* header */ unsigned long size; /* last time stamp received from the X server, in milliseconds */ unsigned long timestamp; /* variable size -- use FvwmPacketBodySize to get size */ unsigned long body[1]; } FvwmPacket; typedef struct { Window w; Window frame; void *fvwmwin; } FvwmWinPacketBodyHeader; /* * If you modify constants here, please regenerate Constants.pm in perllib. */ /** All size values in units of "unsigned long" **/ #define FvwmPacketHeaderSize 4 #define FvwmPacketBodySize(p) ((p).size - FvwmPacketHeaderSize) #define FvwmPacketMaxSize 256 #define FvwmPacketBodyMaxSize (FvwmPacketMaxSize - FvwmPacketHeaderSize) /** There seems to be some movement afoot to measure packet sizes in bytes. See fvwm/module_interface.c **/ #define FvwmPacketHeaderSize_byte \ (FvwmPacketHeaderSize * sizeof(unsigned long)) #define FvwmPacketBodySize_byte(p) \ (FvwmPacketBodySize(p) * sizeof(unsigned long)) #define FvwmPacketMaxSize_byte \ (FvwmPacketMaxSize * sizeof(unsigned long)) #define FvwmPacketBodyMaxSize_byte \ (FvwmPacketBodyMaxSize * sizeof(unsigned long)) /* Value of start_pattern */ #define START_FLAG 0xffffffff #define ModuleFinishedStartupResponse "NOP FINISHED STARTUP" #define ModuleUnlockResponse "NOP UNLOCK" /* Possible values of type */ #define M_NEW_PAGE (1) #define M_NEW_DESK (1<<1) #define M_OLD_ADD_WINDOW (1<<2) #define M_RAISE_WINDOW (1<<3) #define M_LOWER_WINDOW (1<<4) #define M_OLD_CONFIGURE_WINDOW (1<<5) #define M_FOCUS_CHANGE (1<<6) #define M_DESTROY_WINDOW (1<<7) #define M_ICONIFY (1<<8) #define M_DEICONIFY (1<<9) #define M_WINDOW_NAME (1<<10) #define M_ICON_NAME (1<<11) #define M_RES_CLASS (1<<12) #define M_RES_NAME (1<<13) #define M_END_WINDOWLIST (1<<14) #define M_ICON_LOCATION (1<<15) #define M_MAP (1<<16) /* It turns out this is defined by on Solaris 2.6. I suspect that simply redefining this will lead to trouble; at some point, these should probably be renamed (FVWM_MSG_ERROR?). */ #ifdef M_ERROR # undef M_ERROR #endif #define M_ERROR (1<<17) #define M_CONFIG_INFO (1<<18) #define M_END_CONFIG_INFO (1<<19) #define M_ICON_FILE (1<<20) #define M_DEFAULTICON (1<<21) #define M_STRING (1<<22) #define M_MINI_ICON (1<<23) #define M_WINDOWSHADE (1<<24) #define M_DEWINDOWSHADE (1<<25) #define M_VISIBLE_NAME (1<<26) #define M_SENDCONFIG (1<<27) #define M_RESTACK (1<<28) #define M_ADD_WINDOW (1<<29) #define M_CONFIGURE_WINDOW (1<<30) #define M_EXTENDED_MSG (1<<31) #define MAX_MESSAGES 31 #define MAX_MSG_MASK 0x7fffffff /* to get more than the old maximum of 32 messages, the 32nd bit is reserved to * mark another 31 messages that have this bit and another one set. * When handling received messages, the message type can be compared to the * MX_... macro. When using one of the calls that accepts a message mask, a * separate call has to be made that ors the MX_... macros. The normal * M_... and MX_... macros must *never* be or'ed in one of these operations' */ #define MX_VISIBLE_ICON_NAME ((1<<0) | M_EXTENDED_MSG) #define MX_ENTER_WINDOW ((1<<1) | M_EXTENDED_MSG) #define MX_LEAVE_WINDOW ((1<<2) | M_EXTENDED_MSG) #define MX_PROPERTY_CHANGE ((1<<3) | M_EXTENDED_MSG) #define MX_REPLY ((1<<4) | M_EXTENDED_MSG) #define MAX_EXTENDED_MESSAGES 5 #define DEFAULT_XMSG_MASK 0x00000000 #define MAX_XMSG_MASK 0x0000001f #define MAX_TOTAL_MESSAGES (MAX_MESSAGES + MAX_EXTENDED_MESSAGES) /* for MX_PROPERTY_CHANGE */ #define MX_PROPERTY_CHANGE_NONE 0 #define MX_PROPERTY_CHANGE_BACKGROUND 1 #define MX_PROPERTY_CHANGE_SWALLOW 2 /** * Reads a single packet of info from fvwm. * The packet is stored into static memory that is reused during * the next call to ReadFvwmPacket. Callers, therefore, must copy * needed data before the next call to ReadFvwmPacket. **/ FvwmPacket* ReadFvwmPacket( int fd ); /* * * SendFinishedStartupNotification - informs fvwm that the module has * finished its startup procedures and is fully operational now. * */ void SendFinishedStartupNotification(int *fd); /* * * SendText - Sends arbitrary text/command back to fvwm * */ void SendText(int *fd, const char *message, unsigned long window); /** Compatibility **/ #define SendInfo SendText /* * * SendUnlockNotification - informs fvwm that the module has * finished it's procedures and fvwm may proceed. * */ void SendUnlockNotification(int *fd); /* * * SendQuitNotification - informs fvwm that the module has * finished and may be killed. * */ void SendQuitNotification(int *fd); /* * * SendFvwmPipe - Sends message to fvwm: The message is a comma-delimited * string separated into its component sections and sent one by one to fvwm. * It is discouraged to use this function with a "synchronous" module. * (Form FvwmIconMan) * */ void SendFvwmPipe(int *fd, const char *message, unsigned long window); /* * * Sets the which-message-types-do-I-want mask for modules * */ void SetMessageMask(int *fd, unsigned long mask); /* * * Sets the which-message-types-do-I-want to be lock on send for modules * */ void SetSyncMask(int *fd, unsigned long mask); /* * * Sets the which-message-types-I-do-not-want while the server is grabbed * and module transmission is locked at the same time. * */ void SetNoGrabMask(int *fd, unsigned long mask); /* * Used to ask for subset of module configuration lines. * Allows modules to get configuration lines more than once. */ void InitGetConfigLine(int *fd, char *match); /** * Gets a module configuration line from fvwm. Returns NULL if there are * no more lines to be had. "line" is a pointer to a char *. **/ void GetConfigLine(int *fd, char **line); /* expands certain variables in a command to be sent by a module */ char *module_expand_action( Display *dpy, int screen , char *in_action, rectangle *r, char *forecolor, char *backcolor); /** * Parse the command line arguments given to the module by fvwm. * Input is the argc & argv from main(), and a flag to indicate * if we accept a module alias as argument #6. * * Returns a pointer to a ModuleArgs structure, or NULL if something * is not kosher. The returned memory is a static buffer. **/ typedef struct { /* module name */ char* name; /* length of the module name */ int namelen; /* file descriptor to send info back to fvwm */ int to_fvwm; /* file descriptor to read packets from fvwm */ int from_fvwm; /* window context of module */ Window window; /* decoration context of module */ unsigned long decoration; /* number of user-specified arguments */ int user_argc; /* vector of user-specified arguments */ char** user_argv; } ModuleArgs; ModuleArgs* ParseModuleArgs( int argc, char* argv[], int use_arg6_as_alias ); #endif fvwm-2.6.7/libs/fsm.h0000644000175700017570000000162612773467232011355 00000000000000/* -*-c-*- */ #ifndef FSM_H #define FSM_H /* ---------------------------- included header files ---------------------- */ #include "FSMlib.h" /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct { FSmsConn smsConn; FIceConn ice_conn; char *clientId; } fsm_client_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ int fsm_init(char *module); void fsm_fdset(fd_set *in_fdset); Bool fsm_process(fd_set *in_fdset); void fsm_proxy(Display *dpy, Window win, char *sm); void fsm_close(void); #endif /* FSM_H */ fvwm-2.6.7/libs/Flocale.c0000644000175700017570000016042113001406607012107 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* FlocaleRotateDrawString is strongly inspired by some part of xvertext * taken from wmx */ /* Here the copyright for this function: */ /* xvertext, Copyright (c) 1992 Alan Richardson (mppa3@uk.ac.sussex.syma) * * 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 the * copyright notice and this permission notice appear in supporting * documentation. All work developed as a consequence of the use of * this program should duly acknowledge such use. No representations are * made about the suitability of this software for any purpose. It is * provided "as is" without express or implied warranty. * * Minor modifications by Chris Cannam for wm2/wmx * Major modifications by Kazushi (Jam) Marukawa for wm2/wmx i18n patch * Simplification and complications by olicha for use with fvwm */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include #include #include "defaults.h" #include "fvwmlib.h" #include "Graphics.h" #include "ColorUtils.h" #include "Strings.h" #include "Parse.h" #include "PictureBase.h" #include "Flocale.h" #include "FlocaleCharset.h" #include "FBidi.h" #include "FftInterface.h" #include "Colorset.h" #include "Ficonv.h" #include "CombineChars.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ #define FSwitchDrawString(use_16, dpy, d, gc, x, y, s8, s16, l) \ (use_16) ? \ XDrawString16(dpy, d, gc, x, y, s16, l) : \ XDrawString(dpy, d, gc, x, y, s8, l) #define FSwitchDrawImageString(use_16, dpy, d, gc, x, y, s8, s16, l) \ (use_16) ? \ XDrawImageString16(dpy, d, gc, x, y, s16, l) : \ XDrawImageString(dpy, d, gc, x, y, s8, l) /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static FlocaleFont *FlocaleFontList = NULL; static char *Flocale = NULL; static char *Fmodifiers = NULL; /* TODO: make these (static const char *) */ static char *fft_fallback_font = FLOCALE_FFT_FALLBACK_FONT; static char *mb_fallback_font = FLOCALE_MB_FALLBACK_FONT; static char *fallback_font = FLOCALE_FALLBACK_FONT; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* * shadow local functions */ static void FlocaleParseShadow(char *str, int *shadow_size, int *shadow_offset, int *direction, char * fontname, char *module) { char *dir_str; char *token; multi_direction_t dir; *direction = MULTI_DIR_NONE; token = PeekToken(str, &dir_str); if (token == NULL || *token == 0 || (GetIntegerArguments(token, NULL, shadow_size, 1) != 1) || *shadow_size < 0) { *shadow_size = 0; fprintf(stderr,"[%s][FlocaleParseShadow]: WARNING -- bad " "shadow size in font name:\n\t'%s'\n", (module)? module: "fvwm", fontname); return; } if (*shadow_size == 0) { return; } /* some offset ? */ if (dir_str && *dir_str && (GetIntegerArguments(dir_str, NULL, shadow_offset, 1) == 1)) { if (*shadow_offset < 0) { *shadow_offset = 0; fprintf(stderr,"[%s][FlocaleParseShadow]: WARNING -- " "bad shadow offset in font name:\n\t'%s'\n", (module)? module: "fvwmlibs", fontname); } PeekToken(dir_str, &dir_str); } while (dir_str && *dir_str && *dir_str != '\n') { dir = gravity_parse_multi_dir_argument(dir_str, &dir_str); if (dir == MULTI_DIR_NONE) { fprintf(stderr,"[%s][FlocaleParseShadow]: WARNING -- " "bad shadow direction in font description:\n" "\t%s\n", (module)? module: "fvwmlibs", fontname); PeekToken(dir_str, &dir_str); /* skip it */ } else { *direction |= dir; } } if (*direction == MULTI_DIR_NONE) *direction = MULTI_DIR_SE; } /* * some simple converters */ static int FlocaleChar2bOneCharToUtf8(XChar2b c, char *buf) { int len; char byte1 = c.byte1; char byte2 = c.byte2; unsigned short ucs2 = ((unsigned short)byte1 << 8) + byte2; if(ucs2 <= 0x7f) { len = 1; buf[0] = (char)ucs2; buf[1] = 0; } else if(ucs2 <= 0x7ff) { len = 2; buf[0] = (ucs2 >> 6) | 0xc0; buf[1] = (ucs2 & 0x3f) | 0x80; buf[2] = 0; } else { len = 3; buf[0] = (ucs2 >> 12) | 0xe0; buf[1] = ((ucs2 & 0xfff) >> 6) | 0x80; buf[2] = (ucs2 & 0x3f) | 0x80; buf[3] = 0; } return len; } /* return number of bytes of character at current position (pointed to by str) */ int FlocaleStringNumberOfBytes(FlocaleFont *flf, const char *str) { int bytes = 0; if(FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { /* handle UTF-8 */ if ((str[0] & 0x80) == 0) { bytes = 1; } else if((str[0] & ~0xdf) == 0) { bytes = 2; } else { /* this handles only 16-bit Unicode */ bytes = 3; } } else if(flf->flags.is_mb) { /* non-UTF-8 multibyte encoding */ if ((str[0] & 0x80) == 0) { bytes = 1; } else { bytes = 2; } } else { /* we must be using an "ordinary" 8-bit encoding */ bytes = 1; } return bytes; } /* given a string, font specifying its locale and a byte offset gives character offset */ int FlocaleStringByteToCharOffset(FlocaleFont *flf, const char *str, int offset) { const char *curr_ptr = str; int i = 0; int len = strlen(str); int coffset = 0; int curr_len; for(i = 0 ; i < offset && i < len ; i += curr_len, curr_ptr += curr_len, coffset++) { curr_len = FlocaleStringNumberOfBytes(flf, curr_ptr); } return coffset; } /* like above but reversed, ie. return byte offset corresponding to given charater offset */ int FlocaleStringCharToByteOffset(FlocaleFont *flf, const char *str, int coffset) { const char *curr_ptr = str; int i; int len = strlen(str); int offset = 0; int curr_len; for(i = 0 ; i < coffset && i < len ; offset += curr_len, curr_ptr += curr_len, i++) { curr_len = FlocaleStringNumberOfBytes(flf, curr_ptr); } return offset; } /* return length of string in characters */ int FlocaleStringCharLength(FlocaleFont *flf, const char *str) { int i, len; int str_len = strlen(str); for(i = 0, len = 0 ; i < str_len ; i += FlocaleStringNumberOfBytes(flf, str+i), len++); return len; } static XChar2b *FlocaleUtf8ToUnicodeStr2b(char *str, int len, int *nl) { XChar2b *str2b = NULL; int i = 0, j = 0, t; str2b = (XChar2b *)safemalloc((len+1)*sizeof(XChar2b)); while (i < len && str[i] != 0) { if ((str[i] & 0x80) == 0) { str2b[j].byte2 = str[i]; str2b[j].byte1 = 0; } else if ((str[i] & ~0xdf) == 0 && i+1 < len) { t = ((str[i] & 0x1f) << 6) + (str[i+1] & 0x3f); str2b[j].byte2 = (unsigned char)(t & 0xff); str2b[j].byte1 = (unsigned char)(t >> 8); i++; } else if (i+2 > 8); i += 2; } i++; j++; } *nl = j; return str2b; } /* Note: this function is not expected to work; good mb rendering * should be (and is) done using Xmb functions and not XDrawString16 * (or with iso10646-1 fonts and setting the encoding). * This function is used when the locale does not correspond to the font. * It works with "EUC fonts": ksc5601.1987-0, gb2312 and maybe also * cns11643-*. It works patially with jisx* and big5-0. Should try gbk-0, * big5hkscs-0, and cns-11643- */ static XChar2b *FlocaleStringToString2b( Display *dpy, FlocaleFont *flf, char *str, int len, int *nl) { XChar2b *str2b = NULL; char *tmp = NULL; Bool free_str = False; int i = 0, j = 0; Bool euc = True; /* KSC5601 (EUC-KR), GB2312 (EUC-CN), CNS11643-1986-1 * (EUC-TW) and converted jisx (EUC-JP) */ if (flf->fc && StrEquals(flf->fc->x,"jisx0208.1983-0")) { tmp = FiconvCharsetToCharset( dpy, flf->fc, FlocaleCharsetGetEUCJPCharset(), str, len); if (tmp != NULL) { free_str = True; str = tmp; len = strlen(tmp); } } else if (flf->fc && StrEquals(flf->fc->x,"big5-0")) { euc = False; } str2b = (XChar2b *)safemalloc((len+1)*sizeof(XChar2b)); if (euc) { while (i < len && str[i] != 0) { if ((str[i] & 0x80) == 0) { /* seems ok with KSC5601 and GB2312 as we get * almost the ascii. I do no try * CNS11643-1986-1. Should convert to ascii * with jisx */ str2b[j].byte1 = 0x23; /* magic number! */ str2b[j].byte2 = str[i++]; } else if (i+1 < len) { /* mb gl (for gr replace & 0x7f by | 0x80 ...) */ str2b[j].byte1 = str[i++] & 0x7f; str2b[j].byte2 = str[i++] & 0x7f; } else { str2b[j].byte1 = 0; str2b[j].byte2 = 0; i++; } j++; } } else /* big5 and others not yet tested */ { while (i < len && str[i] != 0) { if ((str[i] & 0x80) == 0) { /* we should convert to ascii */ #if 0 str2b[j].byte1 = 0xa2; /* magic number! */ str2b[j].byte2 = str[i++]; #endif /* a blanck char ... */ str2b[j].byte1 = 0x21; str2b[j].byte2 = 0x21; } else if (i+1 < len) { str2b[j].byte1 = str[i++]; str2b[j].byte2 = str[i++]; } else { str2b[j].byte1 = 0; str2b[j].byte2 = 0; i++; } j++; } } *nl = j; if (free_str) free(str); return str2b; } static char *FlocaleEncodeString( Display *dpy, FlocaleFont *flf, char *str, int *do_free, int len, int *nl, int *is_rtl, superimpose_char_t **comb_chars, int **l_to_v) { char *str1, *str2, *str3; int len1; int len2; int i; Bool do_iconv = True; const char *bidi_charset; len1 = len; len2 = 0; if (is_rtl != NULL) *is_rtl = False; *do_free = False; *nl = len; if (flf->str_fc == NULL || flf->fc == NULL || flf->fc == flf->str_fc) { do_iconv = False; } str1 = str; if (FiconvSupport) { char *tmp_str; /* first process combining characters */ tmp_str = FiconvCharsetToUtf8( dpy, flf->str_fc, (const char *)str,len); /* if conversion to UTF-8 failed str1 will be NULL */ if(tmp_str != NULL) { /* do combining */ len = CombineChars((unsigned char *)tmp_str, strlen(tmp_str), comb_chars, l_to_v); /* returns the length of the resulting UTF-8 string */ /* convert back to current charset */ str1 = FiconvUtf8ToCharset( dpy, flf->str_fc, (const char *)tmp_str,len); if (tmp_str != str1) { free(tmp_str); } if (str1) { *nl = len = strlen(str1); *do_free = True; } else { /* convert back to current charset fail */ len = strlen(str); str1 = str; } } } if (FiconvSupport && do_iconv) { str2 = FiconvCharsetToCharset( dpy, flf->str_fc, flf->fc, (const char *)str1, len); if (str2 == NULL) { /* fail to convert */ return str1; } if (str2 != str1) { if (*do_free && str1) { free(str1); str1 = str2; } *do_free = True; len1 = strlen(str2); } } else { str2 = str1; len1 = len; /* initialise array with composing characters (empty) */ if(comb_chars != NULL && *comb_chars == NULL) { *comb_chars = (superimpose_char_t *) safemalloc(sizeof(superimpose_char_t)); (*comb_chars)[0].position = -1; (*comb_chars)[0].c.byte1 = 0; (*comb_chars)[0].c.byte2 = 0; } /* initialise logic to visual mapping here if that is demanded (this is default when no combining has been done (1-to-1)) */ if(l_to_v != NULL && *l_to_v == NULL) { *l_to_v = (int*)safemalloc((len + 1) * sizeof(int)); for(i = 0 ; i < len ; i++) (*l_to_v)[i] = i; (*l_to_v)[len] = -1; } } if (FlocaleGetBidiCharset(dpy, flf->str_fc) != NULL && (bidi_charset = FlocaleGetBidiCharset(dpy, flf->fc)) != NULL) { str3 = FBidiConvert(str2, bidi_charset, len1, is_rtl, &len2, comb_chars != NULL ? *comb_chars : NULL, l_to_v != NULL ? *l_to_v : NULL); if (str3 != NULL && str3 != str2) { if (*do_free) { free(str2); } *do_free = True; len1 = len2; str1 = str3; } /* if we failed to do BIDI convert, return string string from combining phase */ else { str1 = str2; /* we already have the logical to visual mapping from combining phase */ } } *nl = len1; return str1; } static void FlocaleEncodeWinString( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, int *do_free, int *len, superimpose_char_t **comb_chars, int **l_to_v) { int len2b; fws->e_str = FlocaleEncodeString( dpy, flf, fws->str, do_free, *len, len, NULL, comb_chars, l_to_v); fws->str2b = NULL; if (flf->font != None) { if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { fws->str2b = FlocaleUtf8ToUnicodeStr2b( fws->e_str, *len, &len2b); } else if (flf->flags.is_mb) { fws->str2b = FlocaleStringToString2b( dpy, flf, fws->e_str, *len, &len2b); } } } /* * Text Drawing with a FontStruct */ static void FlocaleFontStructDrawString( Display *dpy, FlocaleFont *flf, Drawable d, GC gc, int x, int y, Pixel fg, Pixel fgsh, Bool has_fg_pixels, FlocaleWinString *fws, int len, Bool image) { int xt = x; int yt = y; int is_string16; flocale_gstp_args gstp_args; is_string16 = (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc) || flf->flags.is_mb); if (is_string16 && fws->str2b == NULL) { return; } if (image) { /* for rotated drawing */ FSwitchDrawImageString( is_string16, dpy, d, gc, x, y, fws->e_str, fws->str2b, len); } else { FlocaleInitGstpArgs(&gstp_args, flf, fws, x, y); /* normal drawing */ if (flf->shadow_size != 0 && has_fg_pixels == True) { XSetForeground(dpy, fws->gc, fgsh); while (FlocaleGetShadowTextPosition( &xt, &yt, &gstp_args)) { FSwitchDrawString( is_string16, dpy, d, gc, xt, yt, fws->e_str, fws->str2b, len); } } if (has_fg_pixels == True) { XSetForeground(dpy, gc, fg); } xt = gstp_args.orig_x; yt = gstp_args.orig_y; FSwitchDrawString( is_string16, dpy, d, gc, xt,yt, fws->e_str, fws->str2b, len); } return; } /* * Rotated Text Drawing with a FontStruct or a FontSet */ static void FlocaleRotateDrawString( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, Pixel fg, Pixel fgsh, Bool has_fg_pixels, int len, superimpose_char_t *comb_chars, int *pixel_pos) { static GC my_gc = None; static GC font_gc = None; int j, i, xpfg, ypfg, xpsh, ypsh; unsigned char *normal_data, *rotated_data; unsigned int normal_w, normal_h, normal_len; unsigned int rotated_w, rotated_h, rotated_len; char val; int width, height, descent, min_offset; XImage *image, *rotated_image; Pixmap canvas_pix, rotated_pix; flocale_gstp_args gstp_args; char buf[4]; if (fws->str == NULL || len < 1) { return; } if (fws->flags.text_rotation == ROTATION_0) { return; /* should not happen */ } if (my_gc == None) { my_gc = fvwmlib_XCreateGC(dpy, fws->win, 0, NULL); } XCopyGC(dpy, fws->gc, GCForeground|GCBackground, my_gc); /* width and height (no shadow!) */ width = FlocaleTextWidth(flf, fws->str, len) - FLF_SHADOW_WIDTH(flf); height = flf->height - FLF_SHADOW_HEIGHT(flf); descent = flf->descent - FLF_SHADOW_DESCENT(flf);; if (width < 1) width = 1; if (height < 1) height = 1; /* glyph width and height of the normal text */ normal_w = width; normal_h = height; /* width in bytes */ normal_len = (normal_w - 1) / 8 + 1; /* create and clear the canvas */ canvas_pix = XCreatePixmap(dpy, fws->win, width, height, 1); if (font_gc == None) { font_gc = fvwmlib_XCreateGC(dpy, canvas_pix, 0, NULL); } XSetBackground(dpy, font_gc, 0); XSetForeground(dpy, font_gc, 0); XFillRectangle(dpy, canvas_pix, font_gc, 0, 0, width, height); /* draw the character center top right on canvas */ XSetForeground(dpy, font_gc, 1); if (flf->font != NULL) { XSetFont(dpy, font_gc, flf->font->fid); FlocaleFontStructDrawString(dpy, flf, canvas_pix, font_gc, 0, height - descent, fg, fgsh, has_fg_pixels, fws, len, True); } else if (flf->fontset != None) { XmbDrawString( dpy, canvas_pix, flf->fontset, font_gc, 0, height - descent, fws->e_str, len); } /* here take care of superimposing chars */ i = 0; if(comb_chars != NULL) { while(comb_chars[i].c.byte1 != 0 && comb_chars[i].c.byte2 != 0) { /* draw composing character on top of corresponding "real" character */ FlocaleWinString tmp_fws = *fws; int offset = pixel_pos[comb_chars[i].position]; int curr_len = FlocaleChar2bOneCharToUtf8( comb_chars[i].c, buf); int out_len; char *buf2 = FiconvUtf8ToCharset( dpy, flf->str_fc, (const char *)buf,curr_len); if(buf2 == NULL) { /* if conversion failed, combinational char is not representable in current charset */ /* just replace with empty string */ buf2 = (char *)safemalloc(sizeof(char)); buf2[0] = 0; } tmp_fws.e_str = buf2; tmp_fws.str2b = NULL; if(flf->fontset != None) { XmbDrawString(dpy, canvas_pix, flf->fontset, fws->gc, offset, height - descent, buf2, strlen(buf2)); } else if(flf->font != None) { if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { tmp_fws.str2b = (XChar2b *) safemalloc(2 * sizeof(XChar2b)); tmp_fws.str2b[0] = comb_chars[i].c; tmp_fws.str2b[1].byte1 = 0; tmp_fws.str2b[1].byte2 = 0; out_len = 1; } else if (flf->flags.is_mb) { tmp_fws.str2b = FlocaleStringToString2b( dpy, flf, tmp_fws.e_str, curr_len, &out_len); } else { out_len = strlen(buf2); } XSetFont(dpy, font_gc, flf->font->fid); FlocaleFontStructDrawString( dpy, flf, canvas_pix, font_gc, offset, height - descent, fg, fgsh, has_fg_pixels, &tmp_fws, out_len, True); } free(buf2); if(tmp_fws.str2b != NULL) { free(tmp_fws.str2b); } i++; } } /* reserve memory for the first XImage */ normal_data = (unsigned char *)safemalloc(normal_len * normal_h); /* create depth 1 XImage */ if ((image = XCreateImage( dpy, Pvisual, 1, XYBitmap, 0, (char *)normal_data, normal_w, normal_h, 8, 0)) == NULL) { return; } image->byte_order = image->bitmap_bit_order = MSBFirst; /* extract character from canvas */ XGetSubImage( dpy, canvas_pix, 0, 0, normal_w, normal_h, 1, XYPixmap, image, 0, 0); image->format = XYBitmap; /* width, height of the rotated text */ if (fws->flags.text_rotation == ROTATION_180) { rotated_w = normal_w; rotated_h = normal_h; } else /* vertical text */ { rotated_w = normal_h; rotated_h = normal_w; } /* width in bytes */ rotated_len = (rotated_w - 1) / 8 + 1; /* reserve memory for the rotated image */ rotated_data = (unsigned char *)safecalloc(rotated_h * rotated_len, 1); /* create the rotated X image */ if ((rotated_image = XCreateImage( dpy, Pvisual, 1, XYBitmap, 0, (char *)rotated_data, rotated_w, rotated_h, 8, 0)) == NULL) { return; } rotated_image->byte_order = rotated_image->bitmap_bit_order = MSBFirst; /* map normal text data to rotated text data */ for (j = 0; j < rotated_h; j++) { for (i = 0; i < rotated_w; i++) { /* map bits ... */ if (fws->flags.text_rotation == ROTATION_270) val = normal_data[ i * normal_len + (normal_w - j - 1) / 8 ] & (128 >> ((normal_w - j - 1) % 8)); else if (fws->flags.text_rotation == ROTATION_180) val = normal_data[ (normal_h - j - 1) * normal_len + (normal_w - i - 1) / 8 ] & (128 >> ((normal_w - i - 1) % 8)); else /* ROTATION_90 */ val = normal_data[ (normal_h - i - 1) * normal_len + j / 8] & (128 >> (j % 8)); if (val) rotated_data[j * rotated_len + i / 8] |= (128 >> (i % 8)); } } /* create the character's bitmap and put the image on it */ rotated_pix = XCreatePixmap(dpy, fws->win, rotated_w, rotated_h, 1); XPutImage( dpy, rotated_pix, font_gc, rotated_image, 0, 0, 0, 0, rotated_w, rotated_h); /* free the image and data */ XDestroyImage(image); XDestroyImage(rotated_image); /* free pixmap and GC */ XFreePixmap(dpy, canvas_pix); /* x and y corrections: we fill a rectangle! */ min_offset = FlocaleGetMinOffset(flf, fws->flags.text_rotation); switch (fws->flags.text_rotation) { case ROTATION_90: /* CW */ xpfg = fws->x - min_offset; ypfg = fws->y; break; case ROTATION_180: xpfg = fws->x; ypfg = fws->y - min_offset + FLF_SHADOW_BOTTOM_SIZE(flf); break; case ROTATION_270: /* CCW */ xpfg = fws->x - min_offset; ypfg = fws->y; break; case ROTATION_0: default: xpfg = fws->x; ypfg = fws->y - min_offset; break; } xpsh = xpfg; ypsh = ypfg; /* write the image on the window */ XSetFillStyle(dpy, my_gc, FillStippled); XSetStipple(dpy, my_gc, rotated_pix); FlocaleInitGstpArgs(&gstp_args, flf, fws, xpfg, ypfg); if (flf->shadow_size != 0 && has_fg_pixels == True) { XSetForeground(dpy, my_gc, fgsh); while (FlocaleGetShadowTextPosition(&xpsh, &ypsh, &gstp_args)) { XSetTSOrigin(dpy, my_gc, xpsh, ypsh); XFillRectangle( dpy, fws->win, my_gc, xpsh, ypsh, rotated_w, rotated_h); } } xpsh = gstp_args.orig_x; ypsh = gstp_args.orig_y; XSetTSOrigin(dpy, my_gc, xpsh, ypsh); XFillRectangle(dpy, fws->win, my_gc, xpsh, ypsh, rotated_w, rotated_h); XFreePixmap(dpy, rotated_pix); return; } /* * Fonts info and checking */ static char *FlocaleGetFullNameOfFontStruct(Display *dpy, XFontStruct *font) { char *full_name = NULL; unsigned long value; if (XGetFontProperty(font, XA_FONT, &value)) { full_name = XGetAtomName(dpy, value); } return full_name; } static char *FlocaleGetCharsetOfFontStruct(Display *dpy, XFontStruct *font) { int i = 0; int count = 0; char *charset = NULL; char *full_name; full_name = FlocaleGetFullNameOfFontStruct(dpy, font); if (full_name == NULL) { return NULL; } while(full_name[i] != '\0' && count < 13) { if (full_name[i] == '-') { count++; } i++; } if (count != 13) { return NULL; } CopyString(&charset, full_name+i); XFree(full_name); return charset; } static char *FlocaleGetCharsetFromName(char *name) { int l,i,e; char *charset; l = strlen(name); i = l-1; while(i >= 0 && name[i] != '-') { i--; } if (i == 0 || i == l-1) { return NULL; } i--; e = i; while(i >= 0 && name[i] != '-') { i--; } if (i <= 0 || e == i) { return NULL; } CopyString(&charset, name + i + 1); return charset; } /* return NULL if it is not reasonable to load a FontSet. * Currently return name if it is reasonable to load a FontSet, but in the * future we may want to transform name for faster FontSet loading */ static char *FlocaleFixNameForFontSet(Display *dpy, char *name, char *module) { char *new_name; char *charset; XFontStruct *test_font = NULL; if (!name) { return NULL; } new_name = name; if (strchr(name, ',')) { /* tmp, do not handle "," separated list */ return name; } charset = FlocaleGetCharsetFromName(name); if (charset == NULL && !strchr(name, '*') && !strchr(name, '?')) { /* probably a font alias! */ if ((test_font = XLoadQueryFont(dpy, name))) { charset = FlocaleGetCharsetOfFontStruct(dpy, test_font); XFreeFont(dpy, test_font); } } if (charset != NULL) { if (!strchr(charset, '*') && !strchr(charset, '?') && !FlocaleCharsetIsCharsetXLocale(dpy, charset, module)) { /* if the charset is fully specified and do not match * one of the X locale charset */ new_name = NULL; #if 0 fprintf(stderr,"[%s][FlocaleGetFontSet]: WARNING -- " "Use of a non X locale charset '%s' when " "loading font: %s\n", (module)? module:"fvwmlibs", charset, name); #endif } free(charset); } return new_name; } /* * Fonts loading */ static FlocaleFont *FlocaleGetFftFont( Display *dpy, char *fontname, char *encoding, char *module) { FftFontType *fftf = NULL; FlocaleFont *flf = NULL; char *fn, *hints = NULL; hints = GetQuotedString(fontname, &fn, "/", NULL, NULL, NULL); if (fn == NULL) { fn = fft_fallback_font; } else if (*fn == '\0') { free(fn); fn = fft_fallback_font; } fftf = FftGetFont(dpy, fn, module); if (fftf == NULL) { if (fn != NULL && fn != fft_fallback_font) { free(fn); } return NULL; } flf = (FlocaleFont *)safemalloc(sizeof(FlocaleFont)); memset(flf, '\0', sizeof(FlocaleFont)); flf->count = 1; flf->fftf = *fftf; FlocaleCharsetSetFlocaleCharset(dpy, flf, hints, encoding, module); FftGetFontHeights( &flf->fftf, &flf->height, &flf->ascent, &flf->descent); FftGetFontWidths(flf, &flf->max_char_width); free(fftf); if (fn != NULL && fn != fft_fallback_font) { free(fn); } return flf; } static FlocaleFont *FlocaleGetFontSet( Display *dpy, char *fontname, char *encoding, char *module) { static int mc_errors = 0; FlocaleFont *flf = NULL; XFontSet fontset = NULL; char **ml; int mc,i; char *ds; XFontSetExtents *fset_extents; char *fn, *hints = NULL, *fn_fixed = NULL; hints = GetQuotedString(fontname, &fn, "/", NULL, NULL, NULL); if (*fn == '\0') { free(fn); fn = fn_fixed = mb_fallback_font; } else if (!(fn_fixed = FlocaleFixNameForFontSet(dpy, fn, module))) { if (fn != NULL && fn != mb_fallback_font) { free(fn); } return NULL; } if (!(fontset = XCreateFontSet(dpy, fn_fixed, &ml, &mc, &ds))) { if (fn_fixed && fn_fixed != fn) { free(fn_fixed); } if (fn != NULL && fn != mb_fallback_font) { free(fn); } return NULL; } if (mc > 0) { if (mc_errors <= FLOCALE_NUMBER_MISS_CSET_ERR_MSG) { mc_errors++; fprintf(stderr, "[%s][FlocaleGetFontSet]: (%s)" " Missing font charsets:\n", (module)? module: "fvwmlibs", fontname); for (i = 0; i < mc; i++) { fprintf(stderr, "%s", ml[i]); if (i < mc - 1) fprintf(stderr, ", "); } fprintf(stderr, "\n"); if (mc_errors == FLOCALE_NUMBER_MISS_CSET_ERR_MSG) { fprintf(stderr, "[%s][FlocaleGetFontSet]: No more" " missing charset reportings\n", (module)? module: "fvwmlibs"); } } XFreeStringList(ml); } flf = (FlocaleFont *)safemalloc(sizeof(FlocaleFont)); memset(flf, '\0', sizeof(FlocaleFont)); flf->count = 1; flf->fontset = fontset; FlocaleCharsetSetFlocaleCharset(dpy, flf, hints, encoding, module); fset_extents = XExtentsOfFontSet(fontset); flf->height = fset_extents->max_ink_extent.height; flf->ascent = - fset_extents->max_ink_extent.y; flf->descent = fset_extents->max_ink_extent.height + fset_extents->max_ink_extent.y; flf->max_char_width = fset_extents->max_ink_extent.width; if (fn_fixed && fn_fixed != fn) { free(fn_fixed); } if (fn != NULL && fn != mb_fallback_font) { free(fn); } return flf; } static FlocaleFont *FlocaleGetFont( Display *dpy, char *fontname, char *encoding, char *module) { XFontStruct *font = NULL; FlocaleFont *flf; char *str,*fn,*tmp; char *hints = NULL; hints = GetQuotedString(fontname, &tmp, "/", NULL, NULL, NULL); str = GetQuotedString(tmp, &fn, ",", NULL, NULL, NULL); while (!font && fn) { if (*fn == '\0') { free(fn); fn = fallback_font; } font = XLoadQueryFont(dpy, fn); if (fn != NULL && fn != fallback_font) { free(fn); fn = NULL; } if (!font && str && *str) { str = GetQuotedString(str, &fn, ",", NULL, NULL, NULL); } } if (font == NULL) { if (fn != NULL && fn != fallback_font) { free(fn); } if (tmp != NULL) { free(tmp); } return NULL; } flf = (FlocaleFont *)safemalloc(sizeof(FlocaleFont)); memset(flf, '\0', sizeof(FlocaleFont)); flf->count = 1; flf->fontset = None; flf->fftf.fftfont = NULL; flf->font = font; FlocaleCharsetSetFlocaleCharset(dpy, flf, hints, encoding, module); flf->height = font->max_bounds.ascent + font->max_bounds.descent; flf->ascent = font->max_bounds.ascent; flf->descent = font->max_bounds.descent; flf->max_char_width = font->max_bounds.width; if (flf->font->max_byte1 > 0) flf->flags.is_mb = True; if (fn != NULL && fn != fallback_font) { free(fn); } if (tmp != NULL) { free(tmp); } return flf; } static FlocaleFont *FlocaleGetFontOrFontSet( Display *dpy, char *fontname, char *encoding, char *fullname, char *module) { FlocaleFont *flf = NULL; if (fontname && strlen(fontname) > 3 && strncasecmp("xft:", fontname, 4) == 0) { if (FftSupport) { flf = FlocaleGetFftFont( dpy, fontname+4, encoding, module); } if (flf) { CopyString(&flf->name, fullname); } return flf; } if (flf == NULL && Flocale != NULL && fontname) { flf = FlocaleGetFontSet(dpy, fontname, encoding, module); } if (flf == NULL && fontname) { flf = FlocaleGetFont(dpy, fontname, encoding, module); } if (flf && fontname) { if (StrEquals(fullname, mb_fallback_font)) { flf->name = mb_fallback_font; } else if (StrEquals(fullname, fallback_font)) { flf->name = fallback_font; } else { CopyString(&flf->name, fullname); } return flf; } return NULL; } /* * locale local functions */ static void FlocaleSetlocaleForX( int category, const char *locale, const char *module) { if ((Flocale = setlocale(category, locale)) == NULL) { fprintf(stderr, "[%s][%s]: ERROR -- Cannot set locale. Please check" " your $LC_CTYPE or $LANG.\n", (module == NULL)? "" : module, "FlocaleSetlocaleForX"); return; } if (!XSupportsLocale()) { fprintf(stderr, "[%s][%s]: WARNING -- X does not support locale %s\n", (module == NULL)? "": module, "FlocaleSetlocaleForX", Flocale); Flocale = NULL; } } /* ---------------------------- interface functions ------------------------ */ /* * locale initialisation */ void FlocaleInit( int category, const char *locale, const char *modifiers, const char *module) { FlocaleSetlocaleForX(category, locale, module); if (Flocale == NULL) return; if (modifiers != NULL && (Fmodifiers = XSetLocaleModifiers(modifiers)) == NULL) { fprintf(stderr, "[%s][%s]: WARNING -- Cannot set locale modifiers\n", (module == NULL)? "": module, "FlocaleInit"); } #if FLOCALE_DEBUG_SETLOCALE fprintf(stderr,"[%s][FlocaleInit] locale: %s, modifier: %s\n", module, Flocale, Fmodifiers); #endif } /* * fonts loading */ char *prefix_list[] = { "Shadow=", "StringEncoding=", NULL }; FlocaleFont *FlocaleLoadFont(Display *dpy, char *fontname, char *module) { FlocaleFont *flf = FlocaleFontList; Bool ask_default = False; char *t; char *str, *opt_str, *encoding= NULL, *fn = NULL; int shadow_size = 0; int shadow_offset = 0; int shadow_dir = MULTI_DIR_SE; int i; /* removing quoting for modules */ if (fontname && (t = strchr("\"'`", *fontname))) { char c = *t; fontname++; if (fontname[strlen(fontname)-1] == c) fontname[strlen(fontname)-1] = 0; } if (fontname == NULL || *fontname == 0) { ask_default = True; fontname = mb_fallback_font; } while (flf) { char *c1, *c2; for (c1 = fontname, c2 = flf->name; *c1 && *c2; ++c1, ++c2) { if (*c1 != *c2) { break; } } if (!*c1 && !*c2) { flf->count++; return flf; } flf = flf->next; } /* not cached load the font as a ";" separated list */ /* But first see if we have a shadow relief and/or an encoding */ str = fontname; while ((i = GetTokenIndex(str, prefix_list, -1, &str)) > -1) { str = GetQuotedString(str, &opt_str, ":", NULL, NULL, NULL); switch(i) { case 0: /* shadow= */ FlocaleParseShadow( opt_str, &shadow_size, &shadow_offset, &shadow_dir, fontname, module); break; case 1: /* encoding= */ if (encoding != NULL) { free(encoding); encoding = NULL; } if (opt_str && *opt_str) { CopyString(&encoding, opt_str); } break; default: break; } if (opt_str != NULL) free(opt_str); } if (str && *str) { str = GetQuotedString(str, &fn, ";", NULL, NULL, NULL); } else { fn = mb_fallback_font; } while (!flf && (fn && *fn)) { flf = FlocaleGetFontOrFontSet( dpy, fn, encoding, fontname, module); if (fn != NULL && fn != mb_fallback_font && fn != fallback_font) { free(fn); fn = NULL; } if (!flf && str && *str) { str = GetQuotedString(str, &fn, ";", NULL, NULL, NULL); } } if (fn != NULL && fn != mb_fallback_font && fn != fallback_font) { free(fn); } if (flf == NULL) { /* loading failed, try default font */ if (!ask_default) { fprintf(stderr,"[%s][FlocaleLoadFont]: " "WARNING -- can't load font '%s'," " trying default:\n", (module)? module: "fvwmlibs", fontname); } else { /* we already tried default fonts: try again? yes */ } if (Flocale != NULL) { if (!ask_default) { fprintf(stderr, "\t%s\n", mb_fallback_font); } if ((flf = FlocaleGetFontSet( dpy, mb_fallback_font, NULL, module)) != NULL) { flf->name = mb_fallback_font; } } if (flf == NULL) { if (!ask_default) { fprintf(stderr,"\t%s\n", fallback_font); } if ((flf = FlocaleGetFont( dpy, fallback_font, NULL, module)) != NULL) { flf->name = fallback_font; } else if (!ask_default) { fprintf(stderr, "[%s][FlocaleLoadFont]:" " ERROR -- can't load font.\n", (module)? module: "fvwmlibs"); } else { fprintf(stderr, "[%s][FlocaleLoadFont]: ERROR" " -- can't load default font:\n", (module)? module: "fvwmlibs"); fprintf(stderr, "\t%s\n", mb_fallback_font); fprintf(stderr, "\t%s\n", fallback_font); } } } if (flf != NULL) { if (shadow_size > 0) { flf->shadow_size = shadow_size; flf->flags.shadow_dir = shadow_dir; flf->shadow_offset = shadow_offset; flf->descent += FLF_SHADOW_DESCENT(flf); flf->ascent += FLF_SHADOW_ASCENT(flf); flf->height += FLF_SHADOW_HEIGHT(flf); flf->max_char_width += FLF_SHADOW_WIDTH(flf); } if (flf->fc == FlocaleCharsetGetUnknownCharset()) { fprintf(stderr,"[%s][FlocaleLoadFont]: " "WARNING -- Unknown charset for font\n\t'%s'\n", (module)? module: "fvwmlibs", flf->name); flf->fc = FlocaleCharsetGetDefaultCharset(dpy, module); } else if (flf->str_fc == FlocaleCharsetGetUnknownCharset() && (encoding != NULL || (FftSupport && flf->fftf.fftfont != NULL && flf->fftf.str_encoding != NULL))) { fprintf(stderr,"[%s][FlocaleLoadFont]: " "WARNING -- Unknown string encoding for font\n" "\t'%s'\n", (module)? module: "fvwmlibs", flf->name); } if (flf->str_fc == FlocaleCharsetGetUnknownCharset()) { flf->str_fc = FlocaleCharsetGetDefaultCharset(dpy, module); } flf->next = FlocaleFontList; FlocaleFontList = flf; } if (encoding != NULL) { free(encoding); } return flf; } void FlocaleUnloadFont(Display *dpy, FlocaleFont *flf) { FlocaleFont *list = FlocaleFontList; int i = 0; if (!flf) { return; } /* Remove a weight, still too heavy? */ if (--(flf->count) > 0) { return; } if (flf->name != NULL && !StrEquals(flf->name, mb_fallback_font) && !StrEquals(flf->name, fallback_font)) { free(flf->name); } if (FftSupport && flf->fftf.fftfont != NULL) { FftFontClose(dpy, flf->fftf.fftfont); if (flf->fftf.fftfont_rotated_90 != NULL) FftFontClose(dpy, flf->fftf.fftfont_rotated_90); if (flf->fftf.fftfont_rotated_180 != NULL) FftFontClose(dpy, flf->fftf.fftfont_rotated_180); if (flf->fftf.fftfont_rotated_270 != NULL) FftFontClose(dpy, flf->fftf.fftfont_rotated_270); } if (flf->fontset != NULL) { XFreeFontSet(dpy, flf->fontset); } if (flf->font != NULL) { XFreeFont(dpy, flf->font); } if (flf->flags.must_free_fc) { if (flf->fc->x) free(flf->fc->x); if (flf->fc->bidi) free(flf->fc->bidi); if (flf->fc->locale != NULL) { while (FLC_GET_LOCALE_CHARSET(flf->fc,i) != NULL) { free(FLC_GET_LOCALE_CHARSET(flf->fc,i)); i++; } free(flf->fc->locale); } free(flf->fc); } /* Link it out of the list (it might not be there) */ if (flf == list) /* in head? simple */ { FlocaleFontList = flf->next; } else { while (list && list->next != flf) { /* fast forward until end or found */ list = list->next; } /* not end? means we found it in there, possibly at end */ if (list) { /* link around it */ list->next = flf->next; } } free(flf); } /* * Width and Drawing Text */ void FlocaleInitGstpArgs( flocale_gstp_args *args, FlocaleFont *flf, FlocaleWinString *fws, int start_x, int start_y) { args->step = 0; args->offset = flf->shadow_offset + 1; args->outer_offset = flf->shadow_offset + flf->shadow_size; args->size = flf->shadow_size; args->sdir = flf->flags.shadow_dir; switch (fws->flags.text_rotation) { case ROTATION_270: /* CCW */ args->orig_x = start_x + FLF_SHADOW_UPPER_SIZE(flf); args->orig_y = start_y + FLF_SHADOW_RIGHT_SIZE(flf); break; case ROTATION_180: args->orig_x = start_x + FLF_SHADOW_RIGHT_SIZE(flf); args->orig_y = start_y; break; case ROTATION_90: /* CW */ args->orig_x = start_x + FLF_SHADOW_BOTTOM_SIZE(flf); args->orig_y = start_y + FLF_SHADOW_LEFT_SIZE(flf); break; case ROTATION_0: default: args->orig_x = start_x + FLF_SHADOW_LEFT_SIZE(flf); args->orig_y = start_y; break; } args->rot = fws->flags.text_rotation; return; } Bool FlocaleGetShadowTextPosition( int *x, int *y, flocale_gstp_args *args) { if (args->step == 0) { args->direction = MULTI_DIR_NONE; args->inter_step = 0; } if ((args->step == 0 || args->inter_step >= args->num_inter_steps) && args->size != 0) { /* setup a new direction */ args->inter_step = 0; gravity_get_next_multi_dir(args->sdir, &args->direction); if (args->direction == MULTI_DIR_C) { int size; size = 2 * (args->outer_offset) + 1; args->num_inter_steps = size * size; } else { args->num_inter_steps = args->size; } } if (args->direction == MULTI_DIR_NONE || args->size == 0) { *x = args->orig_x; *y = args->orig_y; return False; } if (args->direction == MULTI_DIR_C) { int tx; int ty; int size; int is_finished; size = 2 * (args->outer_offset) + 1; tx = args->inter_step % size - args->outer_offset; ty = args->inter_step / size - args->outer_offset; for (is_finished = 0; ty <= args->outer_offset; ty++, tx = -args->outer_offset) { for (; tx <= args->outer_offset; tx++) { if (tx <= -args->offset || tx >= args->offset || ty <= -args->offset || ty >= args->offset) { is_finished = 1; break; } } if (is_finished) { break; } } args->inter_step = (tx + args->outer_offset) + (ty + args->outer_offset) * size; if (!is_finished) { tx = 0; ty = 0; } *x = args->orig_x + tx; *y = args->orig_y + ty; } else if (args->inter_step > 0) { /* into a directional drawing */ (*x) += args->x_sign; (*y) += args->y_sign; } else { direction_t dir; direction_t dir_x; direction_t dir_y; dir = gravity_multi_dir_to_dir(args->direction); gravity_split_xy_dir(&dir_x, &dir_y, dir); args->x_sign = gravity_dir_to_sign_one_axis(dir_x); args->y_sign = gravity_dir_to_sign_one_axis(dir_y); gravity_rotate_xy( args->rot, args->x_sign, args->y_sign, &args->x_sign, &args->y_sign); *x = args->orig_x + args->x_sign * args->offset; *y = args->orig_y + args->y_sign * args->offset; } args->inter_step++; args->step++; return True; } void FlocaleDrawString( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, unsigned long flags) { int len; Bool do_free = False; Pixel fg = 0, fgsh = 0; Bool has_fg_pixels = False; flocale_gstp_args gstp_args; superimpose_char_t *comb_chars = NULL; char *curr_str; int char_len; /* length in number of chars */ int *pixel_pos = NULL; int i; int j; char buf[4]; int curr_pixel_pos; int curr_len; if (!fws || !fws->str) { return; } if (flags & FWS_HAVE_LENGTH) { len = fws->len; } else { len = strlen(fws->str); } /* encode the string */ FlocaleEncodeWinString( dpy, flf, fws, &do_free, &len, &comb_chars, NULL); curr_str = fws->e_str; for(char_len = 0, i = 0 ; i < len && curr_str[i] != 0 ; char_len++, i += curr_len) { curr_len = FlocaleStringNumberOfBytes(flf, curr_str + i); } /* for superimposition calculate the character positions in pixels */ if (comb_chars != NULL && ( comb_chars[0].c.byte1 != 0 || comb_chars[0].c.byte2 != 0)) { /* the second condition is actually redundant, but there for clarity, ending at 0 is what's expected in a correct string */ pixel_pos = (int *)safemalloc( (char_len != 0 ? char_len : 1) * sizeof(int)); /* if there is 0 bytes in the encoded string, there might still be combining character to draw (at position 0) */ if(char_len == 0) { pixel_pos[0] = 0; } for( i = 0, curr_pixel_pos = 0 ; i < char_len ; i++, curr_str += curr_len) { curr_len = FlocaleStringNumberOfBytes(flf, curr_str); for (j = 0 ; j < curr_len ; j++) { buf[j] = curr_str[j]; } buf[j] = 0; pixel_pos[i] = curr_pixel_pos; /* need to compensate for shadow width (if any) */ curr_pixel_pos += FlocaleTextWidth(flf, buf, curr_len) - FLF_SHADOW_WIDTH(flf); } } /* get the pixels */ if (fws->flags.has_colorset) { fg = fws->colorset->fg; fgsh = fws->colorset->fgsh; has_fg_pixels = True; } else if (flf->shadow_size != 0) { XGCValues xgcv; if (XGetGCValues(dpy, fws->gc, GCForeground, &xgcv) != 0) { fg = xgcv.foreground; } else { fg = PictureBlackPixel(); } fgsh = GetShadow(fg); has_fg_pixels = True; } if(flf->font != None && (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc) || flf->flags.is_mb)) { /* in this case, length is number of 2-byte chars */ len = char_len; } if (fws->flags.text_rotation != ROTATION_0 && flf->fftf.fftfont == NULL) { /* pass in information to perform superimposition */ FlocaleRotateDrawString( dpy, flf, fws, fg, fgsh, has_fg_pixels, len, comb_chars, pixel_pos); } else if (FftSupport && flf->fftf.fftfont != NULL) { FftDrawString( dpy, flf, fws, fg, fgsh, has_fg_pixels, len, flags); } else if (flf->fontset != None) { int xt = fws->x; int yt = fws->y; FlocaleInitGstpArgs(&gstp_args, flf, fws, fws->x, fws->y); if (flf->shadow_size != 0) { XSetForeground(dpy, fws->gc, fgsh); while (FlocaleGetShadowTextPosition( &xt, &yt, &gstp_args)) { XmbDrawString( dpy, fws->win, flf->fontset, fws->gc, xt, yt, fws->e_str, len); } } if (has_fg_pixels == True) { XSetForeground(dpy, fws->gc, fg); } xt = gstp_args.orig_x; yt = gstp_args.orig_y; XmbDrawString( dpy, fws->win, flf->fontset, fws->gc, xt, yt, fws->e_str, len); } else if (flf->font != None) { FlocaleFontStructDrawString( dpy, flf, fws->win, fws->gc, fws->x, fws->y, fg, fgsh, has_fg_pixels, fws, len, False); } /* here take care of superimposing chars */ i = 0; if (comb_chars != NULL) { while(comb_chars[i].c.byte1 != 0 && comb_chars[i].c.byte2 != 0) { /* draw composing character on top of corresponding "real" character */ FlocaleWinString tmp_fws = *fws; int offset = pixel_pos[comb_chars[i].position]; char *buf2; int out_len; curr_len = FlocaleChar2bOneCharToUtf8(comb_chars[i].c, buf); buf2 = FiconvUtf8ToCharset( dpy, flf->str_fc, (const char *)buf, curr_len); if(buf2 == NULL) { /* if conversion failed, combinational char is not representable in current charset */ /* just replace with empty string */ buf2 = (char *)safemalloc(sizeof(char)); buf2[0] = 0; } tmp_fws.e_str = buf2; tmp_fws.str2b = NULL; if(FftSupport && flf->fftf.fftfont != NULL) { tmp_fws.x = fws->x + offset; FftDrawString( dpy, flf, &tmp_fws, fg, fgsh, has_fg_pixels, strlen(buf2), flags); } else if(flf->fontset != None) { int xt = fws->x; int yt = fws->y; FlocaleInitGstpArgs( &gstp_args, flf, fws, fws->x, fws->y); if (flf->shadow_size != 0) { XSetForeground(dpy, fws->gc, fgsh); while (FlocaleGetShadowTextPosition( &xt, &yt, &gstp_args)) { XmbDrawString( dpy, fws->win, flf->fontset, fws->gc, xt, yt, buf2, strlen(buf2)); } } XSetForeground(dpy, fws->gc, fg); xt = gstp_args.orig_x; yt = gstp_args.orig_y; XmbDrawString( dpy, fws->win, flf->fontset, fws->gc, xt + offset, yt, buf2, strlen(buf2)); } else if (flf->font != None) { if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { tmp_fws.str2b = (XChar2b *) safemalloc(2 * sizeof(XChar2b)); tmp_fws.str2b[0] = comb_chars[i].c; tmp_fws.str2b[1].byte1 = 0; tmp_fws.str2b[1].byte2 = 0; out_len = 1; /*tmp_fws.str2b = FlocaleUtf8ToUnicodeStr2b( tmp_fws.e_str, curr_len, &out_len);*/ } else if (flf->flags.is_mb) { tmp_fws.str2b = FlocaleStringToString2b( dpy, flf, tmp_fws.e_str, curr_len, &out_len); } else { out_len = strlen(buf2); } FlocaleFontStructDrawString( dpy, flf, fws->win, fws->gc, fws->x + offset, fws->y, fg, fgsh, has_fg_pixels, &tmp_fws, out_len, False); } free(buf2); if(tmp_fws.str2b != NULL) { free(tmp_fws.str2b); } i++; } } if (do_free) { if (fws->e_str != NULL) { free(fws->e_str); fws->e_str = NULL; } } if (fws->str2b != NULL) { free(fws->str2b); fws->str2b = NULL; } if(comb_chars != NULL) { free(comb_chars); if(pixel_pos) free(pixel_pos); } return; } void FlocaleDrawUnderline( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, int offset) { int off1, off2, y, x_s, x_e; superimpose_char_t *comb_chars = NULL; int *l_to_v = NULL; Bool do_free = True; int len = strlen(fws->str); int l_coffset; int v_coffset; int voffset; if (fws == NULL || fws->str == NULL) { return; } /* need to encode the string first to get BIDI and combining chars */ FlocaleEncodeWinString(dpy, flf, fws, &do_free, &len, &comb_chars, &l_to_v); /* we don't need this, only interested in char mapping */ free(comb_chars); /* now calculate char offset (in bytes) in visual string corresponding to coffset */ /* calculate absolute position in string (in characters) */ l_coffset = FlocaleStringByteToCharOffset(flf, fws->str, offset); /* map to an offset in the visual string */ v_coffset = l_to_v[l_coffset]; /* calculate byte offset into visual string */ voffset = FlocaleStringCharToByteOffset(flf, fws->e_str, v_coffset); off1 = FlocaleTextWidth(flf, fws->e_str, voffset) + ((voffset == 0)? FLF_SHADOW_LEFT_SIZE(flf) : - FLF_SHADOW_RIGHT_SIZE(flf) ); off2 = FlocaleTextWidth(flf, fws->e_str + voffset, FlocaleStringNumberOfBytes(flf, fws->e_str + voffset)) - FLF_SHADOW_WIDTH(flf) - 1 + off1; y = fws->y + 2; x_s = fws->x + off1; x_e = fws->x + off2; /* No shadow */ XDrawLine(dpy, fws->win, fws->gc, x_s, y, x_e, y); /* free encoded string if it isn't the same as input string */ if(fws->e_str != fws->str) { free(fws->e_str); fws->e_str = NULL; } if(fws->str2b != NULL) { free(fws->str2b); fws->str2b = NULL; } free(l_to_v); return; } int FlocaleTextWidth(FlocaleFont *flf, char *str, int sl) { int result = 0; char *tmp_str; int new_l,do_free; superimpose_char_t *comb_chars = NULL; if (!str || sl == 0) return 0; if (sl < 0) { /* a vertical string: nothing to do! */ sl = -sl; } /* FIXME */ /* to avoid eccesive calls iconv (slow in Solaris 8) don't bother to encode if string is one byte when drawing a string this function is used to calculate position of each character (for superimposition) */ if(sl == 1) { tmp_str = str; new_l = sl; do_free = False; } else { tmp_str = FlocaleEncodeString( Pdpy, flf, str, &do_free, sl, &new_l, NULL, &comb_chars, NULL); } /* if we get zero-length, check to to see if there if there's any combining chars, if so use an imagninary space as a "base character" */ if (strlen(tmp_str) == 0 && comb_chars && (comb_chars[0].c.byte1 != 0 || comb_chars[0].c.byte2 != 0)) { if(do_free) { free(tmp_str); } if(comb_chars) { free(comb_chars); } return FlocaleTextWidth(flf, " ", 1); } else if (FftSupport && flf->fftf.fftfont != NULL) { result = FftTextWidth(flf, tmp_str, new_l); } else if (flf->fontset != None) { result = XmbTextEscapement(flf->fontset, tmp_str, new_l); } else if (flf->font != None) { if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc) || flf->flags.is_mb) { XChar2b *str2b; int nl; if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) str2b = FlocaleUtf8ToUnicodeStr2b( tmp_str, new_l, &nl); else str2b = FlocaleStringToString2b( Pdpy, flf, tmp_str, new_l, &nl); if (str2b != NULL) { result = XTextWidth16(flf->font, str2b, nl); free(str2b); } } else { result = XTextWidth(flf->font, tmp_str, new_l); } } if (do_free) { free(tmp_str); } if (comb_chars) { free(comb_chars); } return result + ((result != 0)? FLF_SHADOW_WIDTH(flf):0); } int FlocaleGetMinOffset( FlocaleFont *flf, rotation_t rotation) { int min_offset; #ifdef FFT_BUGGY_FREETYPE switch(rotation) { case ROTATION_270: case ROTATION_180: /* better than descent */ min_offset = (flf->descent + flf->height - flf->ascent)/2; break; case ROTATION_0: case ROTATION_90: default: /* better than ascent */ min_offset = (flf->ascent + flf->height - flf->descent)/2; break; } #else switch(rotation) { case ROTATION_180: case ROTATION_90: /* better than descent */ min_offset = (flf->descent + flf->height - flf->ascent)/2; break; case ROTATION_270: case ROTATION_0: default: /* better than ascent */ min_offset = (flf->ascent + flf->height - flf->descent)/2; break; } #endif return min_offset; } void FlocaleAllocateWinString(FlocaleWinString **pfws) { *pfws = (FlocaleWinString *)safemalloc(sizeof(FlocaleWinString)); memset(*pfws, '\0', sizeof(FlocaleWinString)); } /* * Text properties */ void FlocaleGetNameProperty( Status (func)(Display *, Window, XTextProperty *), Display *dpy, Window w, FlocaleNameString *ret_name) { char **list; int num; XTextProperty text_prop; list = NULL; if (func(dpy, w, &text_prop) == 0) { return; } if (text_prop.encoding == XA_STRING) { /* STRING encoding, use this as it is */ ret_name->name = (char *)text_prop.value; ret_name->name_list = NULL; return; } /* not STRING encoding, try to convert XA_COMPOUND_TEXT */ if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success && num > 0 && *list) { /* Does not consider the conversion is REALLY succeeded: * XmbTextPropertyToTextList return 0 (== Success) on success, * a negative int if it fails (and in this case we are not * here), the number of unconvertible char on "partial" * success*/ XFree(text_prop.value); /* return of XGetWM(Icon)Name() */ ret_name->name = *list; ret_name->name_list = list; } else { if (list) { XFreeStringList(list); } ret_name->name = (char *)text_prop.value; ret_name->name_list = NULL; } } void FlocaleFreeNameProperty(FlocaleNameString *ptext) { if (ptext->name_list != NULL) { if (ptext->name != NULL && ptext->name != *ptext->name_list) XFree(ptext->name); XFreeStringList(ptext->name_list); ptext->name_list = NULL; } else if (ptext->name != NULL /* Sorry, this is pretty ugly. in fvwm/events.c we have: FlocaleNameString new_name = { NoName, NULL }; NoName is a global extern I don't want to add to to this libary module. So, this check comes close enough: */ && strcmp("Untitled",ptext->name) != 0) { XFree(ptext->name); } ptext->name = NULL; return; } Bool FlocaleTextListToTextProperty( Display *dpy, char **list, int count, XICCEncodingStyle style, XTextProperty *text_prop_return) { int ret = False; if (Flocale != NULL) { ret = XmbTextListToTextProperty( dpy, list, count, style, text_prop_return); if (ret == XNoMemory) { ret = False; } else { /* ret == Success or the number of unconvertible * characters. ret should be != XLocaleNotSupported * because in this case Flocale == NULL */ ret = True; } } if (!ret) { if (XStringListToTextProperty( list, count, text_prop_return) == 0) { ret = False; } else { ret = True; } } return ret; } /* * Info */ void FlocalePrintLocaleInfo(Display *dpy, int verbose) { FlocaleFont *flf = FlocaleFontList; int count = 0; FlocaleCharset *cs; fflush(stderr); fflush(stdout); fprintf(stderr,"fvwm info on locale:\n"); fprintf(stderr," locale: %s, Modifier: %s\n", (Flocale)? Flocale:"", (Fmodifiers)? Fmodifiers:""); cs = FlocaleCharsetGetDefaultCharset(dpy, NULL); fprintf(stderr," Default Charset: X: %s, Iconv: %s, Bidi: %s\n", cs->x, (cs->iconv_index >= 0)? cs->locale[cs->iconv_index]:"Not defined", (cs->bidi)? "Yes":"No"); FlocaleCharsetPrintXOMInfo(); while (flf) { count++; flf = flf->next; } fprintf(stderr," Number of loaded font: %i\n", count); if (verbose) { count = 0; flf = FlocaleFontList; while(flf) { cs = flf->fc; fprintf(stderr," * Font number %i\n", count); fprintf(stderr," fvwm info:\n"); fprintf(stderr," Name: %s\n", (flf->name)? flf->name:""); fprintf(stderr," Cache count: %i\n", flf->count); fprintf(stderr," Type: "); if (flf->font) { fprintf(stderr,"FontStruct\n"); } else if (flf->fontset) { fprintf(stderr,"FontSet\n"); } else { fprintf(stderr,"XftFont\n"); } fprintf(stderr, " Charset: X: %s, Iconv: %s, " "Bidi: %s\n", cs->x, (cs->iconv_index >= 0)? cs->locale[cs->iconv_index]:"Not defined", (cs->bidi)? "Yes":"No"); fprintf(stderr," height: %i, ascent: %i, " "descent: %i\n", flf->height, flf->ascent, flf->descent); fprintf(stderr," shadow size: %i, " "shadow offset: %i, shadow direction:%i\n", flf->shadow_size, flf->shadow_offset, flf->flags.shadow_dir); if (verbose >= 2) { if (flf->fftf.fftfont != NULL) { FftFontType *fftf; fftf = &flf->fftf; fprintf(stderr, " Xft info:\n" " - Vertical font:"); FftPrintPatternInfo( fftf->fftfont, False); fprintf(stderr, " " "- Rotated font 90:"); if (fftf->fftfont_rotated_90) FftPrintPatternInfo( fftf-> fftfont_rotated_90, True); else fprintf(stderr, " None\n"); fprintf(stderr, " " "- Rotated font 270:"); if (fftf->fftfont_rotated_270) FftPrintPatternInfo( fftf-> fftfont_rotated_270, True); else fprintf(stderr, " None\n"); fprintf(stderr, " " "- Rotated font 180:"); if (fftf->fftfont_rotated_180) FftPrintPatternInfo( fftf-> fftfont_rotated_180, True); else fprintf(stderr, " None\n"); } else if (flf->font != NULL) { char *full_name; full_name = FlocaleGetFullNameOfFontStruct( dpy, flf->font); fprintf(stderr, " X info:\n" " %s\n", (full_name)? full_name:"?"); if (full_name != NULL) { XFree(full_name); } } else if (flf->fontset != NULL) { int n,i; XFontStruct **font_struct_list; char **font_name_list; fprintf(stderr, " X info:\n"); n = XFontsOfFontSet( flf->fontset, &font_struct_list, &font_name_list); for(i = 0; i < n; i++) { fprintf(stderr, " %s\n", font_name_list[i]); } } } count++; flf = flf->next; } } } fvwm-2.6.7/libs/Strings.h0000644000175700017570000000421512773467232012216 00000000000000/* -*-c-*- */ #ifndef FVWMLIB_STRINGS_H #define FVWMLIB_STRINGS_H /** * Concatenate three strings. * * Parameters may be NULL to signify the empty string. * * Returns pointer to static storage, overwritten on the next call. **/ char *CatString3(const char *a, const char *b, const char *c); #define CatString2(a,b) CatString3(a,b,NULL) /** * Copy string into newly-malloced memory, stripping leading and * trailing spaces. The string is terminated by either a NUL or * a newline character. **/ void CopyString(char **dest, const char *source); /** * Like CopyString, but strips leading and trailing (double) quotes if any. **/ void CopyStringWithQuotes(char **dest, const char *src); /** * Copy string into newly-malloced memory, stripping leading and * trailing spaces. The difference between this and CopyString() * is that newlines are treated as whitespace by stripcpy(), whereas * CopyString() treats a newline as a string terminator (like the NUL * character. **/ char *stripcpy( const char *source ); /** * Return 1 if the two strings are equal. Case is ignored. **/ int StrEquals( const char *s1, const char *s2 ); /** * Return 1 if the string has the given prefix. Case is ignored. **/ int StrHasPrefix( const char* string, const char* prefix ); /** * Adds single quotes arround the string and escapes single quotes with * backslashes. The result is placed in the given dest, not allocated. * The end of destination, i.e. pointer to '\0' is returned. * You should allocate dest yourself, at least strlen(source) * 2 + 3. **/ char *QuoteString(char *dest, const char *source); /** * Adds delim around the source and escapes all characters in escape with * the corresponding escaper. The dest string must be preallocated. * delim should be included in escape with a proper escaper. * Returns a pointer to the end of dest. **/ char *QuoteEscapeString(char *dest, const char *source, char delim, const char *escape, const char *escaper); /** * Calculates the lenght needed by a escaped by QuoteEscapeString * the corresponding escaper. **/ unsigned int QuoteEscapeStringLength(const char *source, const char *escape); #endif fvwm-2.6.7/libs/Bindings.h0000644000175700017570000000776612773467232012340 00000000000000/* -*-c-*- */ #include /* XClassHint */ #ifndef FVWMLIB_BINDINGS_H_H #define FVWMLIB_BINDINGS_H_H /* ---------------------------- global definitions ------------------------- */ #define binding_t_t unsigned char /* ---------------------------- global macros ------------------------------ */ #define BIND_IS_KEY_PRESS(t) ((t) == BIND_KEYPRESS || (t) == BIND_PKEYPRESS) #define BIND_IS_KEY_BINDING(t) ((t) == BIND_KEYPRESS || (t) == BIND_PKEYPRESS) #define BIND_IS_PKEY_BINDING(t) ((t) == BIND_PKEYPRESS) #define BIND_IS_MOUSE_BINDING(t) \ ((t) == BIND_BUTTONPRESS || (t) == BIND_BUTTONRELEASE) #define BIND_IS_STROKE_BINDING(t) ((t) == BIND_STROKE) /* ---------------------------- type definitions --------------------------- */ typedef enum { /* press = even number, release = press + 1 */ BIND_BUTTONPRESS = 0, BIND_BUTTONRELEASE = 1, BIND_KEYPRESS = 2, BIND_PKEYPRESS = 4, BIND_STROKE = 6 } binding_t; typedef struct Binding { binding_t_t type; /* Is it a mouse, key, or stroke binding */ STROKE_CODE(void *Stroke_Seq;) /* stroke sequence */ int Button_Key; /* Mouse Button number or Keycode */ char *key_name; /* In case of keycode, give the key_name too */ int Context; /* Fvwm context, ie titlebar, frame, etc */ int Modifier; /* Modifiers for keyboard state */ void *Action; /* What to do? */ void *Action2; /* This one can be used too */ char *windowName; /* Name of window (regex pattern) this binding applies to. NULL means all windows. */ struct Binding *NextBinding; } Binding; /* ---------------------------- interface functions ------------------------ */ void CollectBindingList( Display *dpy, Binding **pblist_src, Binding **pblist_dest, Bool *ret_are_similar_bindings_left, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, int modifiers, int contexts, char *windowName); int AddBinding( Display *dpy, Binding **pblist, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, char *key_name, int modifiers, int contexts, void *action, void *action2, char *windowName); void FreeBindingStruct(Binding *b); void FreeBindingList(Binding *b); void RemoveBinding(Binding **pblist, Binding *b, Binding *prev); Bool RemoveMatchingBinding( Display *dpy, Binding **pblist, binding_t type, STROKE_ARG(char *stroke) int button, KeySym keysym, int modifiers, int contexts); void *CheckBinding( Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier, unsigned int dead_modifiers, int Context, binding_t type, const XClassHint *win_class, const char *win_name); void *CheckTwoBindings( Bool *ret_is_second_binding, Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier,unsigned int dead_modifiers, int Context, binding_t type, const XClassHint *win_class, const char *win_name, int Context2, binding_t type2, const XClassHint *win_class2, const char *win_name2); void GrabWindowKey( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Bool fGrab); void GrabAllWindowKeys( Display *dpy, Window w, Binding *blist, unsigned int contexts, unsigned int dead_modifiers, Bool fGrab); void GrabWindowButton( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab); void GrabAllWindowButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab); void GrabAllWindowKeysAndButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab); void GrabWindowKeyOrButton( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab); KeySym FvwmStringToKeysym(Display *dpy, char *key); Bool bindingAppliesToWindow(Binding *binding, const XClassHint *win_class, const char *win_name); Bool is_pass_through_action(const char *action); #endif /* FVWMLIB_BINDINGS_H_H */ fvwm-2.6.7/libs/fvwmlib.h0000644000175700017570000000110012773467232012221 00000000000000/* -*-c-*- */ #ifndef FVWMLIB_H #define FVWMLIB_H #include #include #include #include /* needed for xpm.h and Pixel defn */ #include #include "fvwmrect.h" #include "safemalloc.h" /* Convenience function ti init all the graphics subsystems */ void flib_init_graphics(Display *dpy); /* Set up heap debugging library dmalloc. */ #ifdef HAVE_DMALLOC_H #include #endif /* Set up mtrace from glibc 2.1.x for x > ? */ #ifdef MTRACE_DEBUGGING #include #endif #endif fvwm-2.6.7/libs/Makefile.am0000644000175700017570000000333313001416601012423 00000000000000## Process this file with automake to create Makefile.in noinst_LIBRARIES = libfvwm.a ## please keep .c files in largest first order to speed up parallel makes libfvwm_a_SOURCES = \ BidiJoin.h Bindings.h ClientMsg.h ColorUtils.h Colorset.h \ CombineChars.h Cursor.h Event.h FBidi.h FEvent.h FGettext.h FImage.h \ FRender.h FRenderInit.h FRenderInterface.h FSMlib.h FScreen.h \ FShape.h FShm.h FTips.h Fcursor.h Fft.h FftInterface.h Ficonv.h \ Flocale.h FlocaleCharset.h Fplay.h Fpng.h Fsvg.h Fxpm.h Grab.h \ Graphics.h Module.h Parse.h Picture.h PictureBase.h \ PictureDitherMatrice.h PictureGraphics.h PictureImageLoader.h \ PictureUtils.h Rectangles.h Strings.h System.h Target.h WinMagic.h \ XError.h XResource.h charmap.h defaults.h envvar.h fio.h flist.h \ fsm.h ftime.h fvwm_sys_stat.h fvwmlib.h fvwmrect.h fvwmsignal.h \ gravity.c gravity.h lang-strings.h modifiers.h queue.h safemalloc.h \ setpgrp.h timeout.h vpacket.h wcontext.h wild.h \ \ BidiJoin.c Flocale.c PictureUtils.c FScreen.c Graphics.c \ PictureGraphics.c Bindings.c FlocaleCharset.c Parse.c \ PictureImageLoader.c Colorset.c ColorUtils.c CombineChars.c Module.c \ FRender.c Ficonv.c envvar.c Fft.c gravity.c \ XResource.c FEvent.c FImage.c WinMagic.c Target.c Picture.c XError.c \ queue.c fvwmsignal.c System.c PictureBase.c Cursor.c Strings.c \ fvwmrect.c FRenderInit.c safemalloc.c FBidi.c \ wild.c Grab.c Event.c ClientMsg.c setpgrp.c FShape.c \ FGettext.c Rectangles.c timeout.c flist.c charmap.c wcontext.c \ modifiers.c fsm.c FTips.c fio.c fvwmlib.c libfvwm_a_LIBADD = @LIBOBJS@ AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(Xft_CFLAGS) $(X_CFLAGS) \ $(iconv_CFLAGS) $(Xrender_CFLAGS) $(Bidi_CFLAGS) $(png_CFLAGS) \ $(rsvg_CFLAGS) $(intl_CFLAGS) fvwm-2.6.7/libs/FRenderInterface.h0000644000175700017570000000110312773467232013724 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef F_RENDER_INTERFACE_H #define F_RENDER_INTERFACE_H Bool FRenderTintRectangle( Display *dpy, Window win, Pixmap mask, Pixel tint, int shade_percent, Drawable d, int dest_x, int dest_y, int dest_w, int dest_h); int FRenderRender( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, int shade_percent, Pixel tint, int tint_percent, Drawable d, GC gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, Bool do_repeat); #endif fvwm-2.6.7/libs/defaults.h0000644000175700017570000004020212773467232012370 00000000000000/* -*-c-*- */ /* File: defaults.h * * Description: * #defines for default values shall go into this file as well as tunable * parameters. */ #ifndef _DEFAULTS_ #define _DEFAULTS_ /*** event handling ***/ #define CLOCK_SKEW_MS 30000 /* ms */ /*** grabbing the pointer ***/ #define NUMBER_OF_GRAB_ATTEMPTS 100 #define TIME_BETWEEN_GRAB_ATTEMPTS 10 /* ms */ /*** bindings and mouse buttons ***/ /* Fvwm needs at least 3 buttons. X currently supports up to 5 buttons, so you * can use 3, 4 or 5 here. Do not set this to values higher than 5! Use the * next macro for that. */ #define NUMBER_OF_MOUSE_BUTTONS 5 /* The "extended" buttons do not provide the full functionality because X has * no bit mask value for them. Things like dragging windows don't work with * them. */ #define NUMBER_OF_EXTENDED_MOUSE_BUTTONS 9 #if NUMBER_OF_EXTENDED_MOUSE_BUTTONS > 31 #error No more than 31 mouse buttons can be supported on 32 bit platforms #endif #define DEFAULT_ALL_BUTTONS_MASK \ ((Button1Mask * ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1))) #define DEFAULT_ALL_BUTTONS_MOTION_MASK \ ((Button1MotionMask * ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1))) #define DEFAULT_MODS_UNUSED LockMask /* * These values may be adjusted to fine tune the menu looks. */ /* The first option of the default menu style must be fvwm/win/mwm/.... * fvwm may crash if not. */ #define DEFAULT_MENU_STYLE \ "MenuStyle * fvwm, Foreground black, Background grey, " \ "Greyed slategrey, MenuColorset, ActiveColorset, GreyedColorset" #define DEFAULT_CLICKTIME 150 /* ms */ #define DEFAULT_POPUP_DELAY 15 /* ms*10 */ #define DEFAULT_POPDOWN_DELAY 15 /* ms*10 */ #define DEFAULT_MENU_CLICKTIME (3*DEFAULT_CLICKTIME) #define DEFAULT_MOVE_THRESHOLD 3 /* pixels */ #define MAX_MENU_COPIES 10 /* menu copies */ #define MAX_MENU_ITEM_LABELS 3 /* labels (max. 15) */ #define MAX_MENU_ITEM_MINI_ICONS 2 /* mini icons (max. 15) */ #define DEFAULT_MENU_BORDER_WIDTH 2 /* pixels */ #define MAX_MENU_BORDER_WIDTH 50 /* pixels */ #define MAX_MENU_ITEM_RELIEF_THICKNESS 50 /* pixels */ #define PARENT_MENU_FORCE_VISIBLE_WIDTH 20 /* pixels */ #define DEFAULT_MENU_POPUP_NOW_RATIO 75 /* % of item width */ /* default item formats for left and right submenus. */ #define DEFAULT_MENU_ITEM_FORMAT "%s%.1|%.5i%.5l%.5l%.5r%.5i%2.3>%1|" #define DEFAULT_LEFT_MENU_ITEM_FORMAT "%.1|%3.2<%5i%5l%5l%5r%5i%1|%s" /* size of the submenu triangle. */ #define MENU_TRIANGLE_WIDTH 5 /* pixels */ #define MENU_TRIANGLE_HEIGHT 9 /* pixels */ /* menu underline parameters */ #define MENU_UNDERLINE_THICKNESS 1 /* pixels */ #define MENU_UNDERLINE_GAP 1 /* pixels */ #define MENU_UNDERLINE_HEIGHT (MENU_UNDERLINE_THICKNESS + MENU_UNDERLINE_GAP) /* menu separator parameters */ #define MENU_SEPARATOR_SHORT_X_OFFSET 5 /* pixels */ #define MENU_SEPARATOR_Y_OFFSET 2 /* pixels */ #define MENU_SEPARATOR_HEIGHT 2 /* pixels */ #define MENU_SEPARATOR_TOTAL_HEIGHT \ (MENU_SEPARATOR_HEIGHT + MENU_SEPARATOR_Y_OFFSET) /* menu tear off bar parameters */ #define MENU_TEAR_OFF_BAR_X_OFFSET 1 /* pixels */ #define MENU_TEAR_OFF_BAR_Y_OFFSET 1 /* pixels */ #define MENU_TEAR_OFF_BAR_HEIGHT 4 /* pixels */ #define MENU_TEAR_OFF_BAR_DASH_WIDTH 5 /* pixels */ /* gap above item text */ #define DEFAULT_MENU_ITEM_TEXT_Y_OFFSET 1 /* pixels */ /* gap below item text */ #define DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2 2 /* pixels */ /* same for titles */ #define DEFAULT_MENU_TITLE_TEXT_Y_OFFSET (DEFAULT_MENU_ITEM_TEXT_Y_OFFSET) #define DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2 (DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2) /* minimum for above value */ #define MIN_VERTICAL_SPACING -100 /* pixels */ /* maximum for above value */ #define MAX_VERTICAL_SPACING 100 /* pixels */ /* maximum for above value */ #define MAX_MENU_MARGIN 50 /* pixels */ /* width of a tab in the item format of a menu */ #define MENU_TAB_WIDTH 8 /* spaces */ /* This is the tile width or height for V and H gradients. I guess this should * better be a power of two. A value of 5 definitely causes XFree 3.3.3.1 to * screw up the V_GRADIENT on an 8 bit display, but 4, 6, 7 etc. work well. */ #define DEFAULT_MENU_GRADIENT_PIXMAP_THICKNESS 4 /*** colours ***/ #define DEFAULT_FORE_COLOR "black" #define DEFAULT_BACK_COLOR "gray" #define DEFAULT_HILIGHT_COLOR "white" #define DEFAULT_SHADOW_COLOR "black" #define DEFAULT_CURSOR_FORE_COLOR "black" #define DEFAULT_CURSOR_BACK_COLOR "white" /*** pager ***/ #define DEFAULT_MOVE_THRESHOLD 3 /* pixels */ #define DEFAULT_PAGER_WINDOW_BORDER_WIDTH 1 /* pixels */ /*** fonts ***/ #define EXTRA_TITLE_FONT_HEIGHT 3 /* pixels */ #define EXTRA_TITLE_FONT_WIDTH 3 /* pixels */ #define MIN_FONT_HEIGHT (EXTRA_TITLE_FONT_HEIGHT + 2) #define MAX_FONT_HEIGHT 256 /* pixels */ /*** Flocale ***/ /* adding the good number of "*" speed-up font loading with certain X * server */ #define FLOCALE_MB_FALLBACK_FONT \ "-*-fixed-medium-r-semicondensed-*-13-*-*-*-*-*-*-*," \ "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*," \ "-*-*-medium-r-normal-*-16-*-*-*-*-*-*-*" /* rationale: -*-fixed-medium-r-semicondensed-*-13-* should gives "fixed" in most non multibyte charset (?). -*-fixed-medium-r-normal-*-14-* is ok for jsx -*-medium-r-normal-*-16-* is for gb Of course this is for XFree. Any help for other X server basic font set is welcome. */ #define FLOCALE_FALLBACK_FONT "fixed" #define FLOCALE_FFT_FALLBACK_FONT "MonoSpace" #define FLOCALE_NUMBER_MISS_CSET_ERR_MSG 5 /*** window geometry ***/ #define DEFAULT_MIN_MAX_WINDOW_WIDTH 100 /* pixels */ #define DEFAULT_MIN_MAX_WINDOW_HEIGHT 100 /* pixels */ #define DEFAULT_MAX_MAX_WINDOW_WIDTH 32767 /* pixels */ #define DEFAULT_MAX_MAX_WINDOW_HEIGHT 32767 /* pixels */ /*** icon geometry ***/ #define UNSPECIFIED_ICON_DIMENSION -1 #define MIN_ALLOWABLE_ICON_DIMENSION 0 /* pixels */ #define MAX_ALLOWABLE_ICON_DIMENSION 255 /* pixels */ /* this value is used in a bugfix */ #define WINDOW_FREAKED_OUT_SIZE 65500 /* pixels */ /* Used in Workaround for broken min and max size hints vs a size request */ #define BROKEN_MAXSIZE_LIMIT 1 #define BROKEN_MINSIZE_LIMIT 30000 /* geometry window */ #define GEOMETRY_WINDOW_BW 2 /* pixels */ #define GEOMETRY_WINDOW_STRING " +8888 x +8888 " #define GEOMETRY_WINDOW_POS_STRING " %+-4d %+-4d " #define GEOMETRY_WINDOW_SIZE_STRING " %4d x %-4d " /* * window title layout */ /* the title buttons are shrunk if the title would become smaller than this * number of pixels */ #define MIN_WINDOW_TITLE_LENGTH 10 /* pixels */ /* title bar buttons that get smaller than this size are hidden */ #define MIN_WINDOW_TITLEBUTTON_LENGTH 2 /* pixels */ /* height of stick lines */ #define WINDOW_TITLE_STICK_HEIGHT 1 /* pixels */ /* vertical distance between stick lines */ #define WINDOW_TITLE_STICK_VERT_DIST 4 /* pixels */ /* minimum width of stick lines */ #define WINDOW_TITLE_STICK_MIN_WIDTH 1 /* pixels */ /* gap between border of title window and stick lines */ #define WINDOW_TITLE_STICK_OFFSET 4 /* pixels */ /* gap between title and stick lines */ #define WINDOW_TITLE_TO_STICK_GAP 4 /* pixels */ /* gap between border of title window and text */ #define WINDOW_TITLE_TEXT_OFFSET 10 /* pixels */ /* minimal gap between border of title window and text */ #define MIN_WINDOW_TITLE_TEXT_OFFSET 2 /* pixels */ /* left and right padding for the text into under text area (MultiPixmap)*/ #define TBMP_TITLE_PADDING 5 /* minimal left and right area vs left/right of text/end (MultiPixmap) */ #define TBMP_MIN_RL_TITLE_LENGTH 7 /* maximum number of segemnts in a vector button */ #define MAX_TITLE_BUTTON_VECTOR_LINES 10000 /*** window placement ***/ /** MinOverlap(Percent)Placement **/ /** Now these values are configurable by using styles **/ /* The following factors represent the amount of area that these types of * windows are counted as. For example, by default the area of ONTOP windows * is counted 5 times as much as normal windows. So CleverPlacement will * cover 5 times as much area of another window before it will cover an ONTOP * window. To treat ONTOP windows the same as other windows, set this to 1. * To really, really avoid putting windows under ONTOP windows, set this to a * high value, say 1000. A value of 5 will try to avoid ONTOP windows if * practical, but if it saves a reasonable amount of area elsewhere, it will * place one there. The same rules apply for the other "AVOID" factors. */ /* With the advent of layers, the meaning of ONTOP in the following explanation has changed to mean any window in a higher layer. */ #define PLACEMENT_AVOID_BELOW 0.05 #define PLACEMENT_AVOID_STICKY 1.0 #define PLACEMENT_AVOID_ONTOP 5 #define PLACEMENT_AVOID_ICON 10 #define PLACEMENT_AVOID_EWMH_STRUT 50 /* used in MinOverlap*Placement to forbid complete covering (99%, 95% 85% and 75%) of windows */ #define PLACEMENT_AVOID_COVER_99 12 #define PLACEMENT_AVOID_COVER_95 6 #define PLACEMENT_AVOID_COVER_85 4 #define PLACEMENT_AVOID_COVER_75 1 #define PLACEMENT_FALLBACK_CASCADE_STEP 20 /** Other placement related values **/ /* default string for position placement */ #define DEFAULT_PLACEMENT_POSITION_STRING "0 0" #define DEFAULT_PLACEMENT_POS_CENTER_STRING "50-50w 50-50w" #define DEFAULT_PLACEMENT_POS_MOUSE_STRING "m-50w m-50w" /*** icon layout ***/ /* width of the relief around the icon and icon title */ #define ICON_RELIEF_WIDTH 2 /* pixels */ /* height of stick lines */ #define ICON_TITLE_STICK_HEIGHT WINDOW_TITLE_STICK_HEIGHT /* vertical distance between stick lines */ #define ICON_TITLE_STICK_VERT_DIST WINDOW_TITLE_STICK_VERT_DIST /* vertical offset for icon title */ #define ICON_TITLE_VERT_TEXT_OFFSET -3 /* pixels */ /* minimum width of stick lines */ #define ICON_TITLE_STICK_MIN_WIDTH 3 /* pixels */ /* number of blank pixels before and after a collapsed title */ #define ICON_TITLE_TEXT_GAP_COLLAPSED 1 /* pixels */ /* number of blank pixels before and after an expanded title */ #define ICON_TITLE_TEXT_GAP_EXPANDED 4 /* pixels */ /* extra blank pixels if the icon is sticky */ #define ICON_TITLE_TO_STICK_EXTRA_GAP 1 /* pixels */ /* minimum distance of icons in icon box */ #define MIN_ICON_BOX_DIST 3 /* pixels */ /* padding for the icon into its background */ #define ICON_BACKGROUND_PADDING 0 /* pixels */ /*** general keyboard shortcuts used in move, resize, ... ***/ #define DEFAULT_KDB_SHORTCUT_MOVE_DISTANCE 5 /* pixels */ #define KDB_SHORTCUT_MOVE_DISTANCE_SMALL 1 /* pixels */ #define KDB_SHORTCUT_MOVE_DISTANCE_BIG 100 /* pixels */ /*** movement ***/ #define DEFAULT_OPAQUE_MOVE_SIZE 5 /* percent of window area */ #define DEFAULT_SNAP_ATTRACTION 0 /* snap nothing */ #define DEFAULT_SNAP_ATTRACTION_MODE 0x3 /* snap all */ #define DEFAULT_SNAP_GRID_X 1 /* pixels */ #define DEFAULT_SNAP_GRID_Y 1 /* pixels */ /*** paging ***/ #define DEFAULT_EDGE_SCROLL 100 /* % of screen width/height */ /* Don't page if the pointer has moved for more than this many pixels between * two samples */ #define MAX_PAGING_MOVE_DISTANCE 5 /* pixels */ #define DEFAULT_MOVE_DELAY 0 /* ms */ #define DEFAULT_RESIZE_DELAY -1 /* pixels */ #define DEFAULT_SCROLL_DELAY 0 /* ms */ /*** layers ***/ #define DEFAULT_BOTTOM_LAYER 2 #define DEFAULT_DEFAULT_LAYER 4 #define DEFAULT_TOP_LAYER 6 #define DEFAULT_ROOT_WINDOW_LAYER -1 /*** decorations ***/ /* The number of left and right buttons must be equal. A maximum of 32 buttons * can be handled (16 left and 16 right). */ #define NR_LEFT_BUTTONS 5 #define NR_RIGHT_BUTTONS NR_LEFT_BUTTONS #define NUMBER_OF_TITLE_BUTTONS (NR_LEFT_BUTTONS + NR_RIGHT_BUTTONS) /*** window borders ***/ #define DEFAULT_BORDER_WIDTH 1 /* pixels */ #define DEFAULT_HANDLE_WIDTH 7 /* pixels */ #define MAX_BORDER_WIDTH 500 /* pixels */ #define MAX_HANDLE_WIDTH (MAX_BORDER_WIDTH) /*** module configuration ***/ #define MAX_MODULE_ALIAS_LEN 250 /* bytes */ #define DEFAULT_MODULE_TIMEOUT 30 /* seconds */ #define MAX_MODULE_INPUT_TEXT_LEN 1000 /* bytes */ /*** FvwmConsole configuration */ /* Maximum time FvwmConsole waits for the client to connect. */ #define FVWMCONSOLE_CONNECTION_TO_SECS 60 /* seconds */ /*** misc ***/ #define DEFAULT_EMULATE_MWM False #define DEFAULT_EMULATE_WIN False #define DEFAULT_USE_ACTIVE_DOWN_BUTTONS True #define DEFAULT_USE_INACTIVE_BUTTONS True #define DEFAULT_USE_INACTIVE_DOWN_BUTTONS True /*** Gradients ***/ #define MAX_GRADIENT_SEGMENTS 1000 #define MAX_GRADIENT_COLORS 10000 /*** Xinerama ***/ #define DEFAULT_XINERAMA_ENABLED True /* Xinerama on by default */ #define XINERAMA_CONFIG_STRING "XineramaConfig" /* Replace with -1 to switch off "primary screen" concept by default */ #define DEFAULT_PRIMARY_SCREEN 0 /*** Very long window names (600000 characters or more) seem to hang the X *** server. ***/ #define MAX_WINDOW_NAME_LEN 200 /* characters */ #define MAX_ICON_NAME_LEN 200 /* characters */ /* not tested if this hangs the server too */ #define MAX_RESOURCE_LEN 200 /* characters */ #define MAX_CLASS_LEN 200 /* characters */ /* Set the maximum size a visible name can be. */ #define MAX_VISIBLE_NAME_LEN 4096 /*** numbered window names ***/ #define MAX_WINDOW_NAME_NUMBER 999 #define MAX_WINDOW_NAME_NUMBER_DIGITS 3 /* number/digits of above number */ /* focus policy style defaults */ #define DEF_FP_FOCUS_ENTER 1 #define DEF_FP_UNFOCUS_LEAVE 1 #define DEF_FP_FOCUS_CLICK_CLIENT 0 #define DEF_FP_FOCUS_CLICK_DECOR 0 #define DEF_FP_FOCUS_BY_PROGRAM 1 #define DEF_FP_FOCUS_BY_FUNCTION 1 #define DEF_FP_WARP_POINTER_ON_FOCUS_FUNC 0 #define DEF_FP_LENIENT 0 #define DEF_FP_RAISE_FOCUSED_CLIENT_CLICK 0 #define DEF_FP_RAISE_UNFOCUSED_CLIENT_CLICK 1 #define DEF_FP_RAISE_FOCUSED_DECOR_CLICK 0 #define DEF_FP_RAISE_UNFOCUSED_DECOR_CLICK 0 #define DEF_FP_RAISE_FOCUSED_ICON_CLICK 0 #define DEF_FP_RAISE_UNFOCUSED_ICON_CLICK 0 /* use first three buttons by default */ #define DEF_FP_MOUSE_BUTTONS ( \ ((1 << 0) | (1 << 1) | (1 << 2)) & \ ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1)) #define DEF_FP_MODIFIERS 0 #define DEF_FP_PASS_FOCUS_CLICK 1 #define DEF_FP_PASS_RAISE_CLICK 1 #define DEF_FP_IGNORE_FOCUS_CLICK_MOTION 0 #define DEF_FP_IGNORE_RAISE_CLICK_MOTION 0 #define DEF_FP_ALLOW_FUNC_FOCUS_CLICK 1 #define DEF_FP_ALLOW_FUNC_RAISE_CLICK 1 #define DEF_FP_GRAB_FOCUS 0 #define DEF_FP_GRAB_FOCUS_TRANSIENT 1 #define DEF_FP_OVERRIDE_GRAB_FOCUS 0 #define DEF_FP_RELEASE_FOCUS 0 #define DEF_FP_RELEASE_FOCUS_TRANSIENT 1 #define DEF_FP_OVERRIDE_RELEASE_FOCUS 0 #define DEF_FP_SORT_WINDOWLIST_BY 0 /* Function execution */ #define MAX_FUNCTION_DEPTH 512 /* Tips */ #define FTIPS_DEFAULT_PLACEMENT FTIPS_PLACEMENT_AUTO_UPDOWN #define FTIPS_DEFAULT_JUSTIFICATION FTIPS_JUSTIFICATION_LEFT_UP #define FTIPS_DEFAULT_PLACEMENT_OFFSET 3 #define FTIPS_DEFAULT_JUSTIFICATION_OFFSET 2 #define FTIPS_DEFAULT_BORDER_WIDTH 1 #endif /* _DEFAULTS_ */ fvwm-2.6.7/libs/Picture.c0000644000175700017570000001557613001406607012167 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* Changed 02/12/97 by Dan Espen: - added routines to determine color closeness, for color use reduction. Some of the logic comes from pixy2, so the copyright is below. */ /* * Copyright 1996, Romano Giannetti. No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. * * Romano Giannetti - Dipartimento di Ingegneria dell'Informazione * via Diotisalvi, 2 PISA * mailto:romano@iet.unipi.it * http://www.iet.unipi.it/~romano * */ /* * * Routines to handle initialization, loading, and removing of xpm's or mono- * icon images. * */ #include "config.h" #include #include #include #include "ftime.h" #include #include #include #include "fvwmlib.h" #include "System.h" #include "Colorset.h" #include "Picture.h" #include "PictureUtils.h" #include "Fsvg.h" static FvwmPicture *FvwmPictureList=NULL; FvwmPicture *PGetFvwmPicture( Display *dpy, Window win, char *ImagePath, const char *name, FvwmPictureAttributes fpa) { char *path = PictureFindImageFile(name, ImagePath, R_OK); FvwmPicture *p; if (path == NULL) { return NULL; } p = PImageLoadFvwmPictureFromFile(dpy, win, path, fpa); if (p == NULL) { free(path); } return p; } void PFreeFvwmPictureData(FvwmPicture *p) { if (!p) { return; } if (p->alloc_pixels != NULL) { free(p->alloc_pixels); } if(p->name!=NULL) { free(p->name); } free(p); return; } FvwmPicture *PCacheFvwmPicture( Display *dpy, Window win, char *ImagePath, const char *name, FvwmPictureAttributes fpa) { char *path; char *real_path; FvwmPicture *p = FvwmPictureList; /* First find the full pathname */ if ((path = PictureFindImageFile(name, ImagePath, R_OK)) == NULL) { return NULL; } /* Remove any svg rendering options from real_path */ if (USE_SVG && *path == ':' && (real_path = strchr(path + 1, ':'))) { real_path++; } else { real_path = path; } /* See if the picture is already cached */ while (p) { register char *p1, *p2; for (p1 = path, p2 = p->name; *p1 && *p2; ++p1, ++p2) { if (*p1 != *p2) { break; } } /* If we have found a picture with the wanted name and stamp */ if (!*p1 && !*p2 && !isFileStampChanged(&p->stamp, real_path) && PICTURE_FPA_AGREE(p,fpa)) { p->count++; /* Put another weight on the picture */ free(path); return p; } p=p->next; } /* Not previously cached, have to load it ourself. Put it first in list */ p = PImageLoadFvwmPictureFromFile(dpy, win, path, fpa); if(p) { p->next=FvwmPictureList; FvwmPictureList=p; } else { free(path); } return p; } void PDestroyFvwmPicture(Display *dpy, FvwmPicture *p) { FvwmPicture *q = FvwmPictureList; if (!p) { return; } /* Remove a weight */ if(--(p->count)>0) { /* still too heavy? */ return; } /* Let it fly */ if (p->alloc_pixels != NULL) { if (p->nalloc_pixels != 0) { PictureFreeColors( dpy, Pcmap, p->alloc_pixels, p->nalloc_pixels, 0, p->no_limit); } free(p->alloc_pixels); } if(p->name!=NULL) { free(p->name); } if(p->picture!=None) { XFreePixmap(dpy,p->picture); } if(p->mask!=None) { XFreePixmap(dpy,p->mask); } if(p->alpha != None) { XFreePixmap(dpy, p->alpha); } /* Link it out of the list (it might not be there) */ if(p==q) /* in head? simple */ { FvwmPictureList = p->next; } else { while(q && q->next!=p) /* fast forward until end or found */ { q = q->next; } if(q) /* not end? means we found it in there, possibly at end */ { q->next = p->next; /* link around it */ } } free(p); return; } FvwmPicture *PLoadFvwmPictureFromPixmap( Display *dpy, Window win, char *name, Pixmap pixmap, Pixmap mask, Pixmap alpha, int width, int height, int nalloc_pixels, Pixel *alloc_pixels, int no_limit) { FvwmPicture *q; q = (FvwmPicture*)safemalloc(sizeof(FvwmPicture)); memset(q, 0, sizeof(FvwmPicture)); q->count = 1; q->name = name; q->next = NULL; q->stamp = pixmap; q->picture = pixmap; q->mask = mask; q->alpha = alpha; q->width = width; q->height = height; q->depth = Pdepth; q->nalloc_pixels = nalloc_pixels; q->alloc_pixels = alloc_pixels; q->no_limit = no_limit; return q; } FvwmPicture *PCacheFvwmPictureFromPixmap( Display *dpy, Window win, char *name, Pixmap pixmap, Pixmap mask, Pixmap alpha, int width, int height, int nalloc_pixels, Pixel *alloc_pixels, int no_limit) { FvwmPicture *p = FvwmPictureList; /* See if the picture is already cached */ for(; p != NULL; p = p->next) { #if 0 /* at th present time no good way to cache a pixmap */ if (!strcmp(p->name,name)) { p->count++; return p; } #endif } /* Not previously cached, have to load. Put it first in list */ p = PLoadFvwmPictureFromPixmap( dpy, win, name, pixmap, mask, alpha, width, height, nalloc_pixels, alloc_pixels, no_limit); if(p) { p->next = FvwmPictureList; FvwmPictureList = p; } return p; } FvwmPicture *PCloneFvwmPicture(FvwmPicture *pic) { if (pic != NULL) { pic->count++; } return pic; } void PicturePrintImageCache(int verbose) { FvwmPicture *p; unsigned int count = 0; unsigned int hits = 0; unsigned int num_alpha = 0; unsigned int num_mask = 0; fflush(stderr); fflush(stdout); fprintf(stderr, "fvwm info on Image cache:\n"); for (p = FvwmPictureList; p != NULL; p = p->next) { int num_pixmaps = 1; if (p->mask != None) { num_mask++; num_pixmaps++; } if (p->alpha != None) { num_alpha++; num_pixmaps++; } if (verbose > 0) { fprintf(stderr, "Image: %s (%d pixmaps; used %d times)\n", p->name, num_pixmaps, p->count); } count++; hits += p->count-1; } fprintf(stderr, "%u images in cache (%d reuses) " "(%u masks, %u alpha channels => %u pixmaps)\n", count, hits, num_mask, num_alpha, count + num_mask + num_alpha); fflush(stderr); } fvwm-2.6.7/libs/queue.h0000644000175700017570000000333713001406607011675 00000000000000/* -*-c-*- */ #ifndef QUEUE_H #define QUEUE_H /* * type definitions */ typedef struct { /* do not read or write any members of this structure outside queue.c! */ struct fqueue_record *first; struct fqueue_record *last; unsigned int lock_level; struct { unsigned is_dirty : 1; } flags; } fqueue; #define FQUEUE_INIT { NULL, NULL, 0 } typedef int (*check_fqueue_object_t)(void *object, void *operate_args); typedef void (*operate_fqueue_object_t)(void *object, void *operate_args); typedef int (*cmp_objects_t)(void *object1, void *object2, void *args); typedef void (*destroy_fqueue_object_t)(void *object); /* * Basic queue management */ void fqueue_init(fqueue *fq); unsigned int fqueue_get_length(fqueue *fq); #define FQUEUE_IS_EMPTY(fq) ((fq)->first == NULL) /* * Add record to queue */ void fqueue_add_at_front(fqueue *fq, void *object); void fqueue_add_at_end(fqueue *fq, void *object); void fqueue_add_inside( fqueue *fq, void *object, cmp_objects_t cmp_objects, void *cmp_args); /* * Fetch queue objects */ int fqueue_get_first(fqueue *fq, void **ret_object); /* * Operate on queue objects and possibly remove them from the queue */ void fqueue_remove_or_operate_from_front( fqueue *fq, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, destroy_fqueue_object_t destroy_func, void *operate_args); void fqueue_remove_or_operate_from_end( fqueue *fq, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, destroy_fqueue_object_t destroy_func, void *operate_args); void fqueue_remove_or_operate_all( fqueue *fq, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, destroy_fqueue_object_t destroy_func, void *operate_args); #endif /* QUEUE_H */ fvwm-2.6.7/libs/fvwmsignal.c0000644000175700017570000001406512773467232012741 00000000000000/* -*-c-*- */ /* 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 */ /* * fvwmsignal.c * Written by Chris Rankin, rankinc@zipworld.com.au * */ #include "config.h" #include #include #include #include "fvwmsignal.h" #define true 1 #define false 0 typedef enum { SIG_INIT=0, SIG_DONE } SIG_STATUS; volatile sig_atomic_t isTerminated = false; static volatile sig_atomic_t canJump = false; #ifdef HAVE_SIGSETJMP static sigjmp_buf deadJump; #define SIGSETJMP(env, savesigs) sigsetjmp(env, savesigs) #else static jmp_buf deadJump; #define SIGSETJMP(env, savesigs) setjmp(env) #endif #if defined(HAVE_SIGLONGJMP) && defined(HAVE_SIGSETJMP) #define SIGLONGJMP(env, val) siglongjmp(env, val) #else #define SIGLONGJMP(env, val) longjmp(env, val) #endif /* * Reap child processes, preventing them from becoming zombies. * We do this asynchronously within the SIGCHLD handler so that * "it just happens". */ RETSIGTYPE fvwmReapChildren(int sig) { (void)sig; BSD_BLOCK_SIGNALS; /* * This is a signal handler, AND SO MUST BE REENTRANT! * Now the wait() functions are safe here, but please don't * add anything unless you're SURE that the new functions * (plus EVERYTHING they call) are also reentrant. There * are very few functions which are truly safe. */ #if HAVE_WAITPID while (waitpid(-1, NULL, WNOHANG) > 0) { /* nothing to do here */ } #elif HAVE_WAIT3 while (wait3(NULL, WNOHANG, NULL) > 0) { /* nothing to do here */ } #else # error One of waitpid or wait3 is needed. #endif BSD_UNBLOCK_SIGNALS; SIGNAL_RETURN; } #ifdef USE_BSD_SIGNALS static int term_sigs; /* * fvwmSetSignalMask - store the set of mutually exclusive signals * away for future reference. This prevents different signals from * trying to access the same static data at the same time. * * NOTE: We don't need this if we have POSIX.1 since we can install * a signal mask automatically using sigaction() */ void fvwmSetSignalMask(int sigmask) { term_sigs = sigmask; } /* * fvwmGetSignalMask - get the set of signals that will terminate fvwm * * NOTE: We don't need this if we have POSIX.1 since we can install * a signal mask automatically using sigaction() */ int fvwmGetSignalMask(void) { return term_sigs; } #endif /* * fvwmSetTerminate - set the "end-of-execution" flag. * This function should ONLY be called at the end of a * signal handler. It is an integral part of the mechanism * to stop system calls from blocking once the process is * finished. * * NOTE: This is NOT a signal handler function in its own right! */ void fvwmSetTerminate(int sig) { BSD_BLOCK_SIGNALS; isTerminated = true; if (canJump) { canJump = false; /* * This non-local jump is safe ONLY because we haven't called * any non-reentrant functions in the short period where the * "canJump" variable is true. * * NOTE: No need to restore the signal mask, since siglongjmp * is designed to do that for us. */ SIGLONGJMP(deadJump, SIG_DONE); } BSD_UNBLOCK_SIGNALS; } #ifdef HAVE_SELECT /* * fvwmSelect - wrapper around the select() system call. * This system call may block indefinitely. We don't want * to block at all if the "terminate" flag is set - we * just want it to fail as quickly as possible. */ int fvwmSelect(fd_set_size_t nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { volatile int iRet = -1; /* This variable MUST NOT be in a register */ #ifdef C_ALLOCA /* If we're using the C version of alloca, see if anything needs to be * freed up. */ alloca(0); #endif /* * Yes, we trash errno here, but you're only supposed to check * errno immediately after a function fails anyway. If we fail, * then it's because we received a signal. If we succeed, we * shouldn't be checking errno. And if somebody calls us expecting * us to preserve errno then that's their bug. * * NOTE: We mustn't call any function that might trash errno * ourselves, except select() itself of course. I believe * that sigsetjmp() does NOT trash errno. */ errno = EINTR; /* * Now initialise the non-local jump. Between here and the end of * the routine (more-or-less) we must NOT call any non-reentrant * functions! This is because we might need to abandon them half * way through execution and return here! */ if ( SIGSETJMP(deadJump, 1) == SIG_INIT ) { /* * Activate the non-local jump. Between now and when we turn the * jump off again, we must NOT call any non-reentrant functions * because we could be interrupted halfway through ... */ canJump = true; /* * If we have already been told to terminate then we will not * execute the select() because the flag will be set. If a * "terminate" signal arrives between testing the flag and * calling select() then we will jump back to the non-local * jump point ... */ if ( !isTerminated ) { /* * The "die" signal will interrupt this system call: * that IS the whole point, after all :-) */ iRet = select(nfds, SELECT_FD_SET_CAST readfds, SELECT_FD_SET_CAST writefds, SELECT_FD_SET_CAST exceptfds, timeout); } /* * The non-local jump is about to go out of scope, * so we must deactivate it. Note that the return- * value from select() will be safely stored in the * local variable before the jump is disabled. */ canJump = false; } return iRet; } #endif /* HAVE_SELECT */ fvwm-2.6.7/libs/BidiJoin.h0000644000175700017570000000075512773467232012261 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Nadim Shaikli */ /* * FBidiJoin.h * * Interface to character shaping/joining that is required by most Bidi * (bidirectional) languages. */ #ifndef BIDIJOIN_H #define BIDIJOIN_H #include "config.h" #if HAVE_BIDI #include /* * Shape/Join a passed-in visual string */ int shape_n_join(FriBidiChar *str_visual, int str_len); #else /* !HAVE_BIDI */ #define shape_n_join(a, b) 0 #endif /* HAVE_BIDI */ #endif /* BIDIJOIN_H */ fvwm-2.6.7/libs/fsm.c0000644000175700017570000006015013003342500011316 00000000000000/* -*-c-*- */ /* Copyright (C) 2003 Olivier Chapuis * some code taken from the xsm: Copyright 1993, 1998 The Open Group */ /* 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 set of functions for implementing a dummy sm. The code is based on xsm */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #ifdef HAVE_GETPWUID #include #endif #include #include #include #include #include #include #include "fvwmlib.h" #include "System.h" #include "flist.h" #include "fsm.h" /* #define FVWM_DEBUG_FSM */ /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { FIceConn ice_conn; int fd; } fsm_ice_conn_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static FIceAuthDataEntry *authDataEntries = NULL; static FIceIOErrorHandler prev_handler; static FIceListenObj *listenObjs; static char *addAuthFile = NULL; static char *remAuthFile = NULL; static flist *fsm_ice_conn_list = NULL; static flist *pending_ice_conn_list = NULL; static int numTransports = 0; static char *networkIds = NULL; static int *ice_fd = NULL; static char *module_name = NULL; static flist *running_list = NULL; static Bool fsm_init_succeed = False; static Atom _XA_WM_CLIENT_LEADER = None; static Atom _XA_SM_CLIENT_ID = None; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* * client list stuff */ static void free_fsm_client(fsm_client_t *client) { if (!SessionSupport) { return; } if (client->clientId) { free(client->clientId); } free(client); } /* * auth stuff */ static void fprintfhex(register FILE *fp, unsigned int len, char *cp) { static const char hexchars[] = "0123456789abcdef"; for (; len > 0; len--, cp++) { unsigned char s = *cp; putc(hexchars[s >> 4], fp); putc(hexchars[s & 0x0f], fp); } } /* * Host Based Authentication Callback. This callback is invoked if * the connecting client can't offer any authentication methods that * we can accept. We can accept/reject based on the hostname. */ static Bool HostBasedAuthProc(char *hostname) { return (0); /* For now, we don't support host based authentication */ } /* * We use temporary files which contain commands to add/remove entries from * the .ICEauthority file. */ static void write_iceauth(FILE *addfp, FILE *removefp, FIceAuthDataEntry *entry) { if (!SessionSupport) { return; } fprintf(addfp, "add %s \"\" %s %s ", entry->protocol_name, entry->network_id, entry->auth_name); fprintfhex(addfp, entry->auth_data_length, entry->auth_data); fprintf(addfp, "\n"); fprintf( removefp, "remove protoname=%s protodata=\"\" netid=%s authname=%s\n", entry->protocol_name, entry->network_id, entry->auth_name); } static char * unique_filename(char *path, char *prefix, int *pFd) { char *tempFile; tempFile = (char *)safemalloc(strlen(path) + strlen(prefix) + 8); sprintf(tempFile, "%s/%sXXXXXX", path, prefix); *pFd = fvwm_mkstemp(tempFile); if (*pFd == -1) { free(tempFile); tempFile = NULL; } return tempFile; } /* * Provide authentication data to clients that wish to connect */ #define MAGIC_COOKIE_LEN 16 static Status SetAuthentication( int count,FIceListenObj *listenObjs,FIceAuthDataEntry **authDataEntries) { FILE *addfp = NULL; FILE *removefp = NULL; char *path; int original_umask; char command[256]; int i; int fd; if (!SessionSupport) { return 0; } original_umask = umask (0077); /* disallow non-owner access */ path = (char *)getenv("SM_SAVE_DIR"); if (!path) { path = getenv("HOME"); } #ifdef HAVE_GETPWUID if (!path) { struct passwd *pwd; pwd = getpwuid(getuid()); if (pwd) { path = pwd->pw_dir; } } #endif if (!path) { path = "."; } if ((addAuthFile = unique_filename (path, ".fsm-", &fd)) == NULL) { goto bad; } if (!(addfp = fdopen(fd, "wb"))) { goto bad; } if ((remAuthFile = unique_filename (path, ".fsm-", &fd)) == NULL) { goto bad; } if (!(removefp = fdopen(fd, "wb"))) { goto bad; } *authDataEntries = (FIceAuthDataEntry *) safemalloc( count * 2 * sizeof (FIceAuthDataEntry)); for (i = 0; i < count * 2; i += 2) { (*authDataEntries)[i].network_id = FIceGetListenConnectionString(listenObjs[i/2]); (*authDataEntries)[i].protocol_name = "ICE"; (*authDataEntries)[i].auth_name = "MIT-MAGIC-COOKIE-1"; (*authDataEntries)[i].auth_data = FIceGenerateMagicCookie (MAGIC_COOKIE_LEN); (*authDataEntries)[i].auth_data_length = MAGIC_COOKIE_LEN; (*authDataEntries)[i+1].network_id = FIceGetListenConnectionString(listenObjs[i/2]); (*authDataEntries)[i+1].protocol_name = "XSMP"; (*authDataEntries)[i+1].auth_name = "MIT-MAGIC-COOKIE-1"; (*authDataEntries)[i+1].auth_data = FIceGenerateMagicCookie (MAGIC_COOKIE_LEN); (*authDataEntries)[i+1].auth_data_length = MAGIC_COOKIE_LEN; write_iceauth(addfp, removefp, &(*authDataEntries)[i]); write_iceauth(addfp, removefp, &(*authDataEntries)[i+1]); FIceSetPaAuthData(2, &(*authDataEntries)[i]); FIceSetHostBasedAuthProc(listenObjs[i/2], HostBasedAuthProc); } fclose(addfp); fclose(removefp); umask (original_umask); sprintf (command, "iceauth source %s", addAuthFile); { int n; n = system(command); (void)n; } unlink (addAuthFile); return 1; bad: if (addfp) { fclose (addfp); } if (removefp) { fclose (removefp); } if (addAuthFile) { unlink (addAuthFile); free (addAuthFile); } if (remAuthFile) { unlink (remAuthFile); free (remAuthFile); } return 0; } static void FreeAuthenticationData(int count, FIceAuthDataEntry *authDataEntries) { /* Each transport has entries for ICE and XSMP */ char command[256]; int i; if (!SessionSupport) { return; } for (i = 0; i < count * 2; i++) { free(authDataEntries[i].network_id); free(authDataEntries[i].auth_data); } free ((char *) authDataEntries); sprintf (command, "iceauth source %s", remAuthFile); { int n; n = system(command); (void)n; } unlink (remAuthFile); free (addAuthFile); free (remAuthFile); } /* * ice stuff */ static void MyIoErrorHandler(FIceConn ice_conn) { if (!SessionSupport) { return; } if (prev_handler) { (*prev_handler) (ice_conn); } } static void InstallIOErrorHandler(void) { FIceIOErrorHandler default_handler; if (!SessionSupport) { return; } prev_handler = FIceSetIOErrorHandler(NULL); default_handler = FIceSetIOErrorHandler(MyIoErrorHandler); if (prev_handler == default_handler) { prev_handler = NULL; } } static void CloseListeners(void) { if (!SessionSupport) { return; } FIceFreeListenObjs(numTransports, listenObjs); } static void ice_watch_fd( FIceConn conn, FIcePointer client_data, Bool opening, FIcePointer *watch_data) { fsm_ice_conn_t *fice_conn; if (!SessionSupport) { return; } if (opening) { fice_conn = (fsm_ice_conn_t *)safemalloc(sizeof(fsm_ice_conn_t)); fice_conn->ice_conn = conn; fice_conn->fd = FIceConnectionNumber(conn); *watch_data = (FIcePointer) fice_conn; fsm_ice_conn_list = flist_append_obj(fsm_ice_conn_list, fice_conn); fcntl(fice_conn->fd, F_SETFD, FD_CLOEXEC); } else { fice_conn = (fsm_ice_conn_t *)*watch_data; fsm_ice_conn_list = flist_remove_obj(fsm_ice_conn_list, fice_conn); free(fice_conn); } } /* * Session Manager callbacks */ static Status RegisterClientProc( FSmsConn smsConn, FSmPointer managerData, char *previousId) { fsm_client_t *client = (fsm_client_t *) managerData; char *id; int send_save = 0; if (!SessionSupport) { return 0; } #ifdef FVWM_DEBUG_FSM fprintf (stderr, "[%s][RegisterClientProc] On FIceConn fd = %d, received " "REGISTER CLIENT [Previous Id = %s]\n", module_name, FIceConnectionNumber (client->ice_conn), previousId ? previousId : "NULL"); #endif /* ignore previousID!! (we are dummy) */ id = FSmsGenerateClientID(smsConn); if (!FSmsRegisterClientReply(smsConn, id)) { /* cannot happen ? */ if (id) { free(id); } fprintf( stderr, "[%s][RegisterClientProc] ERR -- fail to register " "client", module_name); return 0; } #ifdef FVWM_DEBUG_FSM fprintf (stderr, "[%s][RegisterClientProc] On FIceConn fd = %d, sent " "REGISTER CLIENT REPLY [Client Id = %s]\n", module_name, FIceConnectionNumber (client->ice_conn), id); #endif client->clientId = id; /* client->clientHostname = FSmsClientHostName (smsConn); */ /* we are dummy ... do not do that */ if (send_save) { FSmsSaveYourself( smsConn, FSmSaveLocal, False, FSmInteractStyleNone, False); } return 1; } static void InteractRequestProc(FSmsConn smsConn, FSmPointer managerData, int dialogType) { if (!SessionSupport) { return; } /* no intercation! */ #if 0 FSmsInteract (client->smsConn); #endif } static void InteractDoneProc(FSmsConn smsConn, FSmPointer managerData, Bool cancelShutdown) { /* no intercation! */ } static void SaveYourselfReqProc(FSmsConn smsConn, FSmPointer managerData, int saveType, Bool shutdown, int interactStyle, Bool fast, Bool global) { /* no session to save */ } static void SaveYourselfPhase2ReqProc(FSmsConn smsConn, FSmPointer managerData) { fsm_client_t *client; if (!SessionSupport) { return; } client = (fsm_client_t *)managerData; SUPPRESS_UNUSED_VAR_WARNING(client); FSmsSaveYourselfPhase2(client->smsConn); } static void SaveYourselfDoneProc(FSmsConn smsConn, FSmPointer managerData, Bool success) { fsm_client_t *client; if (!SessionSupport) { return; } client = (fsm_client_t *) managerData; SUPPRESS_UNUSED_VAR_WARNING(client); FSmsSaveComplete(client->smsConn); } static void CloseDownClient(fsm_client_t *client) { if (!SessionSupport) { return; } #ifdef FVWM_DEBUG_FSM fprintf( stderr, "[%s][CloseDownClient] ICE Connection closed, " "FIceConn fd = %d\n", module_name, FIceConnectionNumber (client->ice_conn)); #endif FSmsCleanUp(client->smsConn); FIceSetShutdownNegotiation(client->ice_conn, False); if ((!FIceCloseConnection(client->ice_conn)) != FIceClosedNow) { /* do not care */ } client->ice_conn = NULL; client->smsConn = NULL; running_list = flist_remove_obj(running_list, client); free_fsm_client(client); } static void CloseConnectionProc(FSmsConn smsConn, FSmPointer managerData, int count, char **reasonMsgs) { fsm_client_t *client = (fsm_client_t *) managerData; if (!SessionSupport) { return; } FSmFreeReasons(count, reasonMsgs); CloseDownClient(client); } static void SetPropertiesProc( FSmsConn smsConn, FSmPointer managerData, int numProps, FSmProp **props) { int i; if (!SessionSupport) { return; } for (i = 0; i < numProps; i++) { FSmFreeProperty(props[i]); } free ((char *) props); } static void DeletePropertiesProc( FSmsConn smsConn, FSmPointer managerData, int numProps, char **propNames) { int i; if (!SessionSupport) { return; } for (i = 0; i < numProps; i++) { free (propNames[i]); } free ((char *) propNames); } static void GetPropertiesProc(FSmsConn smsConn, FSmPointer managerData) { } static Status NewClientProc( FSmsConn smsConn, FSmPointer managerData, unsigned long *maskRet, FSmsCallbacks *callbacksRet, char **failureReasonRet) { fsm_client_t *nc; if (!SessionSupport) { return 0; } nc = (fsm_client_t *)safemalloc(sizeof (fsm_client_t)); *maskRet = 0; nc->smsConn = smsConn; nc->ice_conn = FSmsGetIceConnection(smsConn); nc->clientId = NULL; running_list = flist_append_obj(running_list, nc); #ifdef FVWM_DEBUG_FSM fprintf( stderr, "[%s][NewClientProc] On FIceConn fd = %d, client " "set up session mngmt protocol\n", module_name, FIceConnectionNumber (nc->ice_conn)); #endif /* * Set up session manager callbacks. */ *maskRet |= FSmsRegisterClientProcMask; callbacksRet->register_client.callback = RegisterClientProc; callbacksRet->register_client.manager_data = (FSmPointer) nc; *maskRet |= FSmsInteractRequestProcMask; callbacksRet->interact_request.callback = InteractRequestProc; callbacksRet->interact_request.manager_data = (FSmPointer) nc; *maskRet |= FSmsInteractDoneProcMask; callbacksRet->interact_done.callback = InteractDoneProc; callbacksRet->interact_done.manager_data = (FSmPointer) nc; *maskRet |= FSmsSaveYourselfRequestProcMask; callbacksRet->save_yourself_request.callback = SaveYourselfReqProc; callbacksRet->save_yourself_request.manager_data = (FSmPointer) nc; *maskRet |= FSmsSaveYourselfP2RequestProcMask; callbacksRet->save_yourself_phase2_request.callback = SaveYourselfPhase2ReqProc; callbacksRet->save_yourself_phase2_request.manager_data = (FSmPointer) nc; *maskRet |= FSmsSaveYourselfDoneProcMask; callbacksRet->save_yourself_done.callback = SaveYourselfDoneProc; callbacksRet->save_yourself_done.manager_data = (FSmPointer) nc; *maskRet |= FSmsCloseConnectionProcMask; callbacksRet->close_connection.callback = CloseConnectionProc; callbacksRet->close_connection.manager_data = (FSmPointer) nc; *maskRet |= FSmsSetPropertiesProcMask; callbacksRet->set_properties.callback = SetPropertiesProc; callbacksRet->set_properties.manager_data = (FSmPointer) nc; *maskRet |= FSmsDeletePropertiesProcMask; callbacksRet->delete_properties.callback = DeletePropertiesProc; callbacksRet->delete_properties.manager_data = (FSmPointer) nc; *maskRet |= FSmsGetPropertiesProcMask; callbacksRet->get_properties.callback = GetPropertiesProc; callbacksRet->get_properties.manager_data = (FSmPointer) nc; return 1; } /* * */ static void CompletNewConnectionMsg(void) { flist *l = pending_ice_conn_list; FIceConn ice_conn; FIceAcceptStatus cstatus; if (!SessionSupport) { return; } while(l != NULL) { ice_conn = (FIceConn)l->object; cstatus = (FIceAcceptStatus)FIceConnectionStatus(ice_conn); if (cstatus == (int)FIceConnectPending) { l = l->next; } else if (cstatus == (int)FIceConnectAccepted) { l = l->next; pending_ice_conn_list = flist_remove_obj( pending_ice_conn_list, ice_conn); #ifdef FVWM_DEBUG_FSM char *connstr; connstr = FIceConnectionString (ice_conn); fprintf(stderr, "[%s][NewConnection] ICE Connection " "opened by client, FIceConn fd = %d, Accept at " "networkId %s\n", module_name, FIceConnectionNumber (ice_conn), connstr); free (connstr); #endif } else { if (FIceCloseConnection (ice_conn) != FIceClosedNow) { /* don't care */ } pending_ice_conn_list = flist_remove_obj( pending_ice_conn_list, ice_conn); #ifdef FVWM_DEBUG_FSM if (cstatus == FIceConnectIOError) { fprintf(stderr, "[%s][NewConnection] IO error " "opening ICE Connection!\n", module_name); } else { fprintf(stderr, "[%s][NewConnection] ICE " "Connection rejected!\n", module_name); } #endif } } } static void NewConnectionMsg(int i) { FIceConn ice_conn; FIceAcceptStatus status; if (!SessionSupport) { return; } SUPPRESS_UNUSED_VAR_WARNING(status); ice_conn = FIceAcceptConnection(listenObjs[i], &status); #ifdef FVWM_DEBUG_FSM fprintf(stderr, "[%s][NewConnection] %i\n", module_name, i); #endif if (!ice_conn) { #ifdef FVWM_DEBUG_FSM fprintf(stderr, "[%s][NewConnection] " "FIceAcceptConnection failed\n", module_name); #endif } else { pending_ice_conn_list = flist_append_obj(pending_ice_conn_list, ice_conn); CompletNewConnectionMsg(); } } static void ProcessIceMsg(fsm_ice_conn_t *fic) { FIceProcessMessagesStatus status; if (!SessionSupport) { return; } #ifdef FVWM_DEBUG_FSM fprintf(stderr, "[%s][ProcessIceMsg] %i\n", module_name, (int)fic->fd); #endif status = FIceProcessMessages(fic->ice_conn, NULL, NULL); if (status == FIceProcessMessagesIOError) { flist *cl; int found = 0; #ifdef FVWM_DEBUG_FSM fprintf(stderr, "[%s][ProcessIceMsg] IO error on connection\n", module_name); #endif for (cl = running_list; cl; cl = cl->next) { fsm_client_t *client = (fsm_client_t *) cl->object; if (client->ice_conn == fic->ice_conn) { CloseDownClient (client); found = 1; break; } } if (!found) { /* * The client must have disconnected before it was added * to the session manager's running list (i.e. before the * NewClientProc callback was invoked). */ FIceSetShutdownNegotiation (fic->ice_conn, False); if ((!FIceCloseConnection(fic->ice_conn)) != FIceClosedNow) { /* do not care */ } } } } /* * proxy stuff */ static char *GetClientID(Display *dpy, Window window) { char *client_id = NULL; Window client_leader = None; XTextProperty tp; Atom actual_type; int actual_format; unsigned long nitems; unsigned long bytes_after; unsigned char *prop = NULL; if (!SessionSupport) { return NULL; } if (!_XA_WM_CLIENT_LEADER) { _XA_WM_CLIENT_LEADER = XInternAtom( dpy, "WM_CLIENT_LEADER", False); } if (!_XA_SM_CLIENT_ID) { _XA_SM_CLIENT_ID = XInternAtom(dpy, "SM_CLIENT_ID", False); } if (XGetWindowProperty( dpy, window, _XA_WM_CLIENT_LEADER, 0L, 1L, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success) { if (actual_type == XA_WINDOW && actual_format == 32 && nitems == 1 && bytes_after == 0) { client_leader = (Window)(*(long *)prop); } } if (!client_leader) { client_leader = window; } if (client_leader) { if (XGetTextProperty(dpy, client_leader, &tp, _XA_SM_CLIENT_ID)) { if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0) { client_id = (char *) tp.value; } } } if (prop) { XFree (prop); } return client_id; } static void set_session_manager(Display *dpy, Window window, char *sm) { Window client_leader = None; Atom actual_type; int actual_format; unsigned long nitems; unsigned long bytes_after; unsigned char *prop = NULL; char *dummy_id; static Atom _XA_SESSION_MANAGER = None; if (!SessionSupport) { return; } dummy_id = "0"; if (!_XA_SESSION_MANAGER) { _XA_SESSION_MANAGER = XInternAtom ( dpy, "SESSION_MANAGER", False); } if (!_XA_WM_CLIENT_LEADER) { _XA_WM_CLIENT_LEADER = XInternAtom( dpy, "WM_CLIENT_LEADER", False); } if (!_XA_SM_CLIENT_ID) { _XA_SM_CLIENT_ID = XInternAtom(dpy, "SM_CLIENT_ID", False); } if (XGetWindowProperty( dpy, window, _XA_WM_CLIENT_LEADER, 0L, 1L, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success) { if (actual_type == XA_WINDOW && actual_format == 32 && nitems == 1 && bytes_after == 0) { client_leader = (Window)(*(long *)prop); } } if (!client_leader) { client_leader = window; } #ifdef FVWM_DEBUG_FSM fprintf( stderr, "[%s][fsm_init] Proxy %s window 0x%lx\n", module_name, (sm)? "On":"Off", client_leader); #endif /* set the client id for ksmserver */ if (sm) { XChangeProperty( dpy, client_leader, _XA_SESSION_MANAGER, XA_STRING, 8, PropModeReplace, (unsigned char *)sm, strlen(sm)); XChangeProperty( dpy, client_leader, _XA_SM_CLIENT_ID, XA_STRING, 8, PropModeReplace, (unsigned char *)dummy_id, strlen(dummy_id)); } else { XDeleteProperty(dpy, client_leader, _XA_SESSION_MANAGER); XDeleteProperty(dpy, client_leader, _XA_SM_CLIENT_ID); } } /* ---------------------------- interface functions ------------------------ */ int fsm_init(char *module) { char errormsg[256]; int i; char *p; if (!SessionSupport) { /* -Wall fix */ MyIoErrorHandler(NULL); HostBasedAuthProc(NULL); ice_watch_fd(0, NULL, 0, NULL); NewClientProc(0, NULL, 0, NULL, NULL); #ifdef FVWM_DEBUG_FSM fprintf( stderr, "[%s][fsm_init] No Session Support\n", module_name); #endif return 0; } if (fsm_init_succeed) { fprintf( stderr, "[%s][fsm_init] <> -- " "Session already Initialized!\n", module_name); return 1; } module_name = module; InstallIOErrorHandler (); #ifdef FVWM_DEBUG_FSM fprintf(stderr, "[%s][fsm_init] FSmsInitialize\n", module_name); #endif if (!FSmsInitialize( module, "1.0", NewClientProc, NULL, HostBasedAuthProc, 256, errormsg)) { fprintf( stderr, "[%s][fsm_init] <> -- " "FSmsInitialize failed: %s\n", module_name, errormsg); return 0; } if (!FIceListenForConnections ( &numTransports, &listenObjs, 256, errormsg)) { fprintf( stderr, "[%s][fsm_init] <> -- " "FIceListenForConnections failed:\n" "%s\n", module_name, errormsg); return 0; } atexit(CloseListeners); if (!SetAuthentication(numTransports, listenObjs, &authDataEntries)) { fprintf( stderr, "[%s][fsm_init] <> -- " "Could not set authorization\n", module_name); return 0; } if (FIceAddConnectionWatch(&ice_watch_fd, NULL) == 0) { fprintf(stderr, "[%s][fsm_init] <> -- " "FIceAddConnectionWatch failed\n", module_name); return 0; } ice_fd = (int *)safemalloc(sizeof(int) * numTransports + 1); for (i = 0; i < numTransports; i++) { ice_fd[i] = FIceGetListenConnectionNumber(listenObjs[i]); } networkIds = FIceComposeNetworkIdList(numTransports, listenObjs); p = (char *)safemalloc( 16 + strlen(networkIds) + 1); sprintf(p, "SESSION_MANAGER=%s", networkIds); putenv(p); #ifdef FVWM_DEBUG_FSM fprintf(stderr,"[%s][fsm_init] OK: %i\n", module_name, numTransports); fprintf(stderr,"\t%s\n", p); #endif fsm_init_succeed = True; return 1; } void fsm_fdset(fd_set *in_fdset) { int i; flist *l = fsm_ice_conn_list; fsm_ice_conn_t *fic; if (!SessionSupport || !fsm_init_succeed) { return; } for (i = 0; i < numTransports; i++) { FD_SET(ice_fd[i], in_fdset); } while(l != NULL) { fic = (fsm_ice_conn_t *)l->object; FD_SET(fic->fd, in_fdset); l = l->next; } } Bool fsm_process(fd_set *in_fdset) { int i; flist *l = fsm_ice_conn_list; fsm_ice_conn_t *fic; if (!SessionSupport || !fsm_init_succeed) { return False; } if (pending_ice_conn_list != NULL) { CompletNewConnectionMsg(); } while(l != NULL) { fic = (fsm_ice_conn_t *)l->object; if (FD_ISSET(fic->fd, in_fdset)) { ProcessIceMsg(fic); } l = l->next; } for (i = 0; i < numTransports; i++) { if (FD_ISSET(ice_fd[i], in_fdset)) { NewConnectionMsg(i); } } if (pending_ice_conn_list != NULL) { return True; } return False; } /* this try to explain to ksmserver and various sm poxies that they should not * connect our non XSMP award leader window to the top level sm */ void fsm_proxy(Display *dpy, Window win, char *sm) { char *client_id; flist *l = running_list; Bool found = False; if (!SessionSupport || !fsm_init_succeed) { return; } client_id = GetClientID(dpy, win); if (client_id != NULL && strcmp("0", client_id) != 0) { for (l = running_list; l; l = l->next) { fsm_client_t *client = (fsm_client_t *) l->object; if (client->clientId && strcmp(client->clientId, client_id) == 0) { found = 1; break; } } } if (found) { return; } set_session_manager(dpy, win, sm); } void fsm_close(void) { if (!SessionSupport || !fsm_init_succeed) { return; } FreeAuthenticationData(numTransports, authDataEntries); } fvwm-2.6.7/libs/Ficonv.h0000644000175700017570000000250412773467232012010 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef FICONV_H #define FICONV_H /* ---------------------------- included header files ---------------------- */ #include "config.h" /* ---------------------------- global definitions ------------------------- */ #ifdef HAVE_ICONV #define FiconvSupport 1 #else #define FiconvSupport 0 #endif #if FiconvSupport #define Ficonv_open(a,b) iconv_open(a,b) #define Ficonv_close(a) iconv_close(a) #define Ficonv(a,b,c,d,e) iconv(a,b,c,d,e) #else #define Ficonv_open(a,b) (Ficonv_t)-1 #define Ficonv_close(a) -1 #define Ficonv(a,b,c,d,e) -1 #endif /* ---------------------------- global macros ------------------------------ */ #define FICONV_CONVERSION_MAX_NUMBER_OF_WARNING 10 /* ---------------------------- type definitions --------------------------- */ typedef void* Ficonv_t; /* ---------------------------- interface functions ------------------------ */ void FiconvSetTransliterateUtf8(int toggle); char *FiconvUtf8ToCharset( Display *dpy, FlocaleCharset *fc, const char *in, unsigned int in_size); char *FiconvCharsetToUtf8( Display *dpy, FlocaleCharset *fc, const char *in, unsigned int in_size); char *FiconvCharsetToCharset( Display *dpy, FlocaleCharset *in_fc, FlocaleCharset *out_fc, const char *in, unsigned int in_size); #endif /* FICONV_H */ fvwm-2.6.7/libs/ColorUtils.c0000644000175700017570000003164612773467232012667 00000000000000/* -*-c-*- */ /* * Around 12/20/99 we did the 3rd rewrite of the shadow/hilite stuff. * (That I know about (dje). * The first stuff I saw just applied a percentage. * Then we got some code from SCWM. * This stuff comes from "Visual.c" which is part of Lesstif. * Here's their copyright: * * Copyright (C) 1995 Free Software Foundation, Inc. * * This file is part of the GNU LessTif Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * The routine at the bottom "pixel_to_color_string" was not from Lesstif. * * Port by Dan Espen, no additional copyright */ #include "config.h" /* must be first */ #include #include /* for X functions in general */ #include "fvwmlib.h" /* prototype GetShadow GetHilit */ #include "Parse.h" #include "Colorset.h" #include "PictureBase.h" #include "PictureUtils.h" #include "ColorUtils.h" #define PCT_BRIGHTNESS (6 * 0xffff / 100) /* How much lighter/darker to make things in default routine */ #define PCT_DARK_BOTTOM 70 /* lighter (less dark, actually) */ #define PCT_DARK_TOP 50 /* lighter */ #define PCT_LIGHT_BOTTOM 55 /* darker */ #define PCT_LIGHT_TOP 80 /* darker */ #define PCT_MEDIUM_BOTTOM_BASE 40 /* darker */ #define PCT_MEDIUM_BOTTOM_RANGE 25 #define PCT_MEDIUM_TOP_BASE 60 /* lighter */ #define PCT_MEDIUM_TOP_RANGE -30 /* The "brightness" of an RGB color. The "right" way seems to use * empirical values like the default thresholds below, but it boils down * to red is twice as bright as blue and green is thrice blue. */ #define BRIGHTNESS(r,g,b) (2*(int)(r) + 3*(int)(g) + 1*(int)(b)) /* From Xm.h on Solaris */ #define XmDEFAULT_DARK_THRESHOLD 15 #define XmDEFAULT_LIGHT_THRESHOLD 85 static XColor color; /**** This part is the old fvwm way to calculate colours. Still used for **** 'medium' brigness colours. */ #define DARKNESS_FACTOR 0.5 #define BRIGHTNESS_FACTOR 1.4 #define SCALE 65535.0 #define HALF_SCALE (SCALE / 2) typedef enum { R_MAX_G_MIN, R_MAX_B_MIN, G_MAX_B_MIN, G_MAX_R_MIN, B_MAX_R_MIN, B_MAX_G_MIN } MinMaxState; static void color_mult (unsigned short *red, unsigned short *green, unsigned short *blue, double k) { if (*red == *green && *red == *blue) { double temp; /* A shade of gray */ temp = k * (double) (*red); if (temp > SCALE) { temp = SCALE; } *red = (unsigned short)(temp); *green = *red; *blue = *red; } else { /* Non-zero saturation */ double r, g, b; double min, max; double a, l, s; double delta; double middle; MinMaxState min_max_state; r = (double) *red; g = (double) *green; b = (double) *blue; if (r > g) { if (r > b) { max = r; if (g < b) { min = g; min_max_state = R_MAX_G_MIN; a = b - g; } else { min = b; min_max_state = R_MAX_B_MIN; a = g - b; } } else { max = b; min = g; min_max_state = B_MAX_G_MIN; a = r - g; } } else { if (g > b) { max = g; if (b < r) { min = b; min_max_state = G_MAX_B_MIN; a = r - b; } else { min = r; min_max_state = G_MAX_R_MIN; a = b - r; } } else { max = b; min = r; min_max_state = B_MAX_R_MIN; a = g - r; } } delta = max - min; a = a / delta; l = (max + min) / 2; if (l <= HALF_SCALE) { s = max + min; } else { s = 2.0 * SCALE - (max + min); } s = delta/s; l *= k; if (l > SCALE) { l = SCALE; } s *= k; if (s > 1.0) { s = 1.0; } if (l <= HALF_SCALE) { max = l * (1 + s); } else { max = s * SCALE + l - s * l; } min = 2 * l - max; delta = max - min; middle = min + delta * a; switch (min_max_state) { case R_MAX_G_MIN: r = max; g = min; b = middle; break; case R_MAX_B_MIN: r = max; g = middle; b = min; break; case G_MAX_B_MIN: r = middle; g = max; b = min; break; case G_MAX_R_MIN: r = min; g = max; b = middle; break; case B_MAX_G_MIN: r = middle; g = min; b = max; break; case B_MAX_R_MIN: r = min; g = middle; b = max; break; } *red = (unsigned short) r; *green = (unsigned short) g; *blue = (unsigned short) b; } } /**** End of original fvwm code. ****/ static XColor *GetShadowOrHiliteColor( Pixel background, float light, float dark, float factor) { long brightness; unsigned int red, green, blue; memset(&color, 0, sizeof(color)); color.pixel = background; XQueryColor(Pdpy, Pcmap, &color); red = color.red; green = color.green; blue = color.blue; brightness = BRIGHTNESS(red, green, blue); /* For "dark" backgrounds, make everything a fixed %age lighter */ if (brightness < XmDEFAULT_DARK_THRESHOLD * PCT_BRIGHTNESS) { color.red = (unsigned short) (0xffff - ((0xffff - red) * dark + 50) / 100); color.green = (unsigned short) (0xffff - ((0xffff - green) * dark + 50) / 100); color.blue = (unsigned short) (0xffff - ((0xffff - blue) * dark + 50) / 100); } /* For "light" background, make everything a fixed %age darker */ else if (brightness > XmDEFAULT_LIGHT_THRESHOLD * PCT_BRIGHTNESS) { color.red = (unsigned short)((red * light + 50) / 100); color.green = (unsigned short)((green * light + 50) / 100); color.blue = (unsigned short)((blue * light + 50) / 100); } /* For "medium" background, select is a fixed %age darker; * top (lighter) and bottom (darker) are a variable %age * based on the background's brightness */ else { color_mult(&color.red, &color.green, &color.blue, factor); } return &color; } XColor *GetShadowColor(Pixel background) { return GetShadowOrHiliteColor( background, PCT_LIGHT_BOTTOM, PCT_DARK_BOTTOM, DARKNESS_FACTOR); } Pixel GetShadow(Pixel background) { XColor *colorp; colorp = GetShadowColor(background); PictureAllocColor(Pdpy, Pcmap, colorp, True); if (colorp->pixel == background) { colorp->pixel = PictureGetNextColor(colorp->pixel, 1); } return colorp->pixel; } XColor *GetHiliteColor(Pixel background) { return GetShadowOrHiliteColor( background, PCT_LIGHT_TOP, PCT_DARK_TOP, BRIGHTNESS_FACTOR); } Pixel GetHilite(Pixel background) { XColor *colorp; colorp = GetHiliteColor(background); PictureAllocColor(Pdpy, Pcmap, colorp, True); if (colorp->pixel == background) { colorp->pixel = PictureGetNextColor(colorp->pixel, -1); } return colorp->pixel; } XColor *GetForeShadowColor(Pixel foreground, Pixel background) { XColor bg_color; float fg[3], bg[3]; int result[3]; int i; memset(&color, 0, sizeof(color)); memset(&bg_color, 0, sizeof(bg_color)); color.pixel = foreground; bg_color.pixel = background; XQueryColor(Pdpy, Pcmap, &color); XQueryColor(Pdpy, Pcmap, &bg_color); fg[0] = color.red; fg[1] = color.green; fg[2] = color.blue; bg[0] = bg_color.red; bg[1]= bg_color.green; bg[2] = bg_color.blue; for (i=0; i<3; i++) { if (fg[i] - bg[i] < 8192 && fg[i] - bg[i] > -8192) { result[i] = 0; } else { result[i] = (int)((5 * bg[i] - fg[i]) / 4); if (fg[i] < bg[i] || result[i] < 0) { result[i] = (int)((3 * bg[i] + fg[i]) / 4); } } } color.red = result[0]; color.green = result[1]; color.blue = result[2]; return &color; } Pixel GetForeShadow(Pixel foreground, Pixel background) { XColor *colorp; colorp = GetForeShadowColor(foreground, background); PictureAllocColor(Pdpy, Pcmap, colorp, True); if (colorp->pixel == background) { colorp->pixel = PictureGetNextColor(colorp->pixel, 1); } return colorp->pixel; } XColor *GetTintedColor(Pixel in, Pixel tint, int percent) { XColor tint_color; memset(&color, 0, sizeof(color)); memset(&tint_color, 0, sizeof(tint_color)); color.pixel = in; XQueryColor(Pdpy, Pcmap, &color); tint_color.pixel = tint; XQueryColor(Pdpy, Pcmap, &tint_color); color.red = (unsigned short) (((100-percent)*color.red + tint_color.red * percent) / 100); color.green = (unsigned short) (((100-percent)*color.green + tint_color.green * percent) / 100); color.blue = (unsigned short) (((100-percent)*color.blue + tint_color.blue * percent) / 100); return &color; } Pixel GetTintedPixel(Pixel in, Pixel tint, int percent) { XColor *colorp; colorp = GetTintedColor(in, tint, percent); PictureAllocColor(Pdpy, Pcmap, colorp, True); return colorp->pixel; } /* This function converts the colour stored in a colorcell (pixel) into the * string representation of a colour. The output is printed at the * address 'output'. It is either in rgb format ("rgb:rrrr/gggg/bbbb") if * use_hash is False or in hash notation ("#rrrrggggbbbb") if use_hash is true. * The return value is the number of characters used by the string. The * rgb values of the output are undefined if the colorcell is invalid. The * memory area pointed at by 'output' must be at least 64 bytes (in case of * future extensions and multibyte characters).*/ int pixel_to_color_string( Display *dpy, Colormap cmap, Pixel pixel, char *output, Bool use_hash) { XColor color; int n; color.pixel = pixel; color.red = 0; color.green = 0; color.blue = 0; XQueryColor(dpy, cmap, &color); if (!use_hash) { sprintf( output, "rgb:%04x/%04x/%04x%n", (int)color.red, (int)color.green, (int)color.blue, &n); } else { sprintf( output, "#%04x%04x%04x%n", (int)color.red, (int)color.green, (int)color.blue, &n); } return n; } static char *colorset_names[] = { "$[fg.cs", "$[bg.cs", "$[hilight.cs", "$[shadow.cs", NULL }; Pixel GetSimpleColor(char *name) { XColor color; Bool is_illegal_rgb = False; memset(&color, 0, sizeof(color)); /* This is necessary because some X servers coredump when presented a * malformed rgb colour name. */ if (name && strncasecmp(name, "rgb:", 4) == 0) { int i; char *s; for (i = 0, s = name + 4; *s; s++) { if (*s == '/') i++; } if (i != 2) is_illegal_rgb = True; } if (is_illegal_rgb) { fprintf(stderr, "Illegal RGB format \"%s\"\n", name); } else if (!XParseColor (Pdpy, Pcmap, name, &color)) { fprintf(stderr, "Cannot parse color \"%s\"\n", name ? name : ""); } else if (!PictureAllocColor(Pdpy, Pcmap, &color, True)) { fprintf(stderr, "Cannot allocate color \"%s\"\n", name); } return color.pixel; } Pixel GetColor(char *name) { int i; int n; int cs; char *rest; XColor color; switch ((i = GetTokenIndex(name, colorset_names, -1, &rest))) { case 0: case 1: case 2: case 3: if (!isdigit(*rest) || (*rest == '0' && *(rest + 1) != 0)) { /* not a non-negative integer without leading zeros */ fprintf(stderr, "Invalid colorset number in color '%s'\n", name); return 0; } sscanf(rest, "%d%n", &cs, &n); if (*(rest + n) != ']') { fprintf(stderr, "No closing brace after '%d' in color '%s'\n", cs, name); return 0; } if (*(rest + n + 1) != 0) { fprintf(stderr, "Trailing characters after brace in" " color '%s'\n", name); return 0; } AllocColorset(cs); switch (i) { case 0: color.pixel = Colorset[cs].fg; break; case 1: color.pixel = Colorset[cs].bg; break; case 2: color.pixel = Colorset[cs].hilite; break; case 3: color.pixel = Colorset[cs].shadow; break; } if (!PictureAllocColor(Pdpy, Pcmap, &color, True)) { fprintf(stderr, "Cannot allocate color %d from" " colorset %d\n", i, cs); return 0; } return color.pixel; default: break; } return GetSimpleColor(name); } /* Allocates the color from the input Pixel again */ Pixel fvwmlib_clone_color(Pixel p) { XColor c; c.pixel = p; XQueryColor(Pdpy, Pcmap, &c); if (!PictureAllocColor(Pdpy, Pcmap, &c, True)) { fprintf(stderr, "Cannot allocate clone Pixel %d\n", (int)p); return 0; } return c.pixel; } /* Free an array of colours (n colours), never free black */ void fvwmlib_free_colors(Display *dpy, Pixel *pixels, int n, Bool no_limit) { int i; /* We don't ever free black - dirty hack to allow freeing colours at * all */ /* olicha: ???? */ for (i = 0; i < n; i++) { if (pixels[i] != 0) { PictureFreeColors( dpy, Pcmap, pixels + i, 1, 0, no_limit); } } return; } /* Copy one color and reallocate it */ void fvwmlib_copy_color( Display *dpy, Pixel *dst_color, Pixel *src_color, Bool do_free_dest, Bool do_copy_src) { if (do_free_dest) { fvwmlib_free_colors(dpy, dst_color, 1, True); } if (do_copy_src) { *dst_color = fvwmlib_clone_color(*src_color); } } fvwm-2.6.7/libs/FScreen.c0000644000175700017570000010515313003342500012061 00000000000000/* -*-c-*- */ /* 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 */ /* * FScreen.c * Xinerama abstraction support for window manager. * * This module is all original code * by Dmitry Yu. Bolkhovityanov * Copyright 2001, Dmitry Bolkhovityanov * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* * Brief description of used concept: * * This code is always used by client, regardless of if Xinerama is * available or not (either because -lXinerama was missing or * because Xinerama extension is missing on display). * * If Xinerama is available, this module maintains a list of screens, * from [1] to [num_screens]. screens[0] is always the "global" screen, * so if Xinerama is unavailable or disabled, the module performs * all checks on screens[0] instead of screens[1..num_screens]. * * The client should first call the FScreenInit(), passing * it the opened display descriptor. During this call the list of * Xinerama screens is retrieved and 'dpy' is saved for future * reference. * * If the client wishes to hard-disable Xinerama support (e.g. if * Xinerama extension is present but is broken on display), it should * call FScreenDisable() *before* FScreenInit(). * * Using real Xinerama screens info may be switched on/off "on the * fly" by calling FScreenSetState(0=off/else=on). * * Modules with Xinerama support should listen to the XineramaEnable * and XineramaDisable strings coming over the module pipe as * M_CONFIG_INFO packets and call FScreenEnable() or * FScreenDisable in response. * */ #include "config.h" #include #include #include "defaults.h" #include "fvwmlib.h" #include "Parse.h" #include "FScreen.h" #include "PictureBase.h" #ifdef HAVE_XINERAMA # undef FSCREEN_NEED_SCREENINFO # define FScreenHaveXinerama 1 # ifdef HAVE_SOLARIS_XINERAMA # define FScreenHaveSolarisXinerama 1 # ifdef HAVE_SOLARIS_XINERAMA_H # include # else # define FSCREEN_NEED_SOLARIS_PROTOTYPES # endif # define FSCREEN_NEED_SCREENINFO # else # define FScreenHaveSolarisXinerama 0 # include # endif #else # define FSCREEN_NEED_SCREENINFO # define FScreenHaveXinerama 0 # define FScreenHaveSolarisXinerama 0 #endif #ifdef FSCREEN_NEED_SCREENINFO typedef struct { int screen_number; short x_org; short y_org; unsigned short width; unsigned short height; } XineramaScreenInfo; #endif #ifdef FSCREEN_NEED_SOLARIS_PROTOTYPES /* Copied from Solaris 9's X11/extensions/xinerama.h */ Bool XineramaGetState(Display*, int); Status XineramaGetInfo(Display*, int, XRectangle*, unsigned char*, int*); Status XineramaGetCenterHint(Display*, int, int*, int*); #endif #if FScreenHaveSolarisXinerama == 0 #define XineramaGetInfo(a,b,c,d,e) 0 #endif #if FScreenHaveXinerama # if FScreenHaveSolarisXinerama # define XineramaQueryExtension(d,b,c) 1 /* Lie, for now */ # define XineramaIsActive(d) XineramaGetState((d),0) # define XineramaQueryScreens(d,s) (*(s)) = 0, NULL # endif #else # define XineramaQueryExtension(da, b, c) 0 # define XineramaIsActive(a) 0 # define XineramaQueryScreens(d,s) (*(s)) = 0, NULL #endif #ifndef MAXFRAMEBUFFERS #define MAXFRAMEBUFFERS 16 #endif #ifdef USE_XINERAMA_EMULATION #define FScreenXineramaEmulation 1 #else #define FScreenXineramaEmulation 0 #endif #if 0 #ifdef HAVE_RANDR #include #include #endif #endif enum { /* Replace with FSCREEN_GLOBAL to restore default behaviour */ DEFAULT_GEOMETRY_SCREEN = FSCREEN_PRIMARY }; /* In fact, only corners matter -- there will never be GRAV_NONE */ enum {GRAV_POS = 0, GRAV_NONE = 1, GRAV_NEG = 2}; static int grav_matrix[3][3] = { { NorthWestGravity, NorthGravity, NorthEastGravity }, { WestGravity, CenterGravity, EastGravity }, { SouthWestGravity, SouthGravity, SouthEastGravity } }; #define DEFAULT_GRAVITY NorthWestGravity static Display *disp = NULL; static Bool is_xinerama_enabled = DEFAULT_XINERAMA_ENABLED; static Bool is_sls_enabled = False; static Bool have_sls_screen_list = False; static XineramaScreenInfo *screens; static XineramaScreenInfo *screens_xi; static XineramaScreenInfo *screens_sls = NULL; /* # of Xinerama screens, *not* counting the global, 0 if disabled */ static int num_screens = 0; /* # of Xinerama screens, *not* counting the global */ static int total_screens = 0; static int total_screens_xi = 0; static int total_screens_sls = 1; static int total_sls_width = 1; static int total_sls_height = 1; static int first_to_check = 0; static int last_to_check = 0; static int default_geometry_scr = FSCREEN_PRIMARY; /* only to be accessed vie the set/get functions! */ static int primary_scr = DEFAULT_PRIMARY_SCREEN; #if 0 #ifdef HAVE_RANDR static Bool randr_disabled = 0; static Bool randr_active = 0; static int randr_event_base = -1; static int randr_error_base = -1; #endif #endif static Window blank_w, vert_w, blank2_w, blank3_w; static int FScreenParseScreenBit(char *arg, char default_screen); static int FindScreenOfXY(int x, int y); static XineramaScreenInfo * solaris_XineramaQueryScreens(Display *d, int *nscreens) { if (FScreenHaveSolarisXinerama) { XineramaScreenInfo *screens = NULL; XRectangle monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; int result; /* dummy instructions to keep -Wall happy */ hints[0] = hints[0]; result = XineramaGetInfo( d, DefaultScreen(d), monitors, hints, nscreens); if (result) { int m; /* Note, malloced area later freed by XFree() */ screens = (XineramaScreenInfo *)malloc( sizeof(XineramaScreenInfo) * (*nscreens)); for (m = 0; m < *nscreens; ++m) { screens[m].screen_number = m; screens[m].x_org = monitors[m].x; screens[m].y_org = monitors[m].y; screens[m].width = monitors[m].width; screens[m].height = monitors[m].height; } } else { fprintf( stderr, "Error getting Xinerama information\n"); *nscreens = 0; } return screens; } else { return NULL; } } static XineramaScreenInfo *FXineramaQueryScreens(Display *d, int *nscreens) { if (FScreenHaveXinerama == 0) { *nscreens = 0; return NULL; } if (FScreenHaveSolarisXinerama == 1) { return solaris_XineramaQueryScreens(d, nscreens); } else { return XineramaQueryScreens(d, nscreens); } } static void GetMouseXY(XEvent *eventp, int *x, int *y) { if (!is_xinerama_enabled || last_to_check == first_to_check) { /* We use .x_org,.y_org because nothing prevents a screen to be * not at (0,0) */ *x = screens[first_to_check].x_org; *y = screens[first_to_check].y_org; } else { XEvent e; if (eventp == NULL) { eventp = &e; e.type = 0; } fev_get_evpos_or_query( disp, DefaultRootWindow(disp), eventp, x, y); } return; } Bool FScreenIsEnabled(void) { return (!is_xinerama_enabled || num_screens == 0) ? False : True; } Bool FScreenIsSLSEnabled(void) { return is_sls_enabled; } static void FScreenUpdateEmulationMapState(void) { static Bool is_mapped = False; if (!FScreenXineramaEmulation) { return; } if (is_xinerama_enabled && !is_sls_enabled) { if (!is_mapped) { XMapRaised(disp, blank_w); XMapRaised(disp, blank2_w); XMapRaised(disp, blank3_w); XMapRaised(disp, vert_w); is_mapped = True; } } else { if (is_mapped) { XUnmapWindow(disp, blank_w); XUnmapWindow(disp, blank2_w); XUnmapWindow(disp, blank3_w); XUnmapWindow(disp, vert_w); is_mapped = False; } } } static void FScreenSetState(Bool do_enable) { is_xinerama_enabled = do_enable; if (do_enable && total_screens > 0) { num_screens = total_screens; first_to_check = 1; last_to_check = total_screens; } else { num_screens = 0; first_to_check = 0; last_to_check = 0; } FScreenUpdateEmulationMapState(); } void FScreenInit(Display *dpy) { static Bool is_initialised = False; int dummy_rc; SUPPRESS_UNUSED_VAR_WARNING(dummy_rc); if (is_initialised) { return; } is_initialised = True; disp = dpy; if (FScreenXineramaEmulation) { int count; int w; int h; int ws; unsigned long scr; Window root; XSetWindowAttributes attributes; scr = DefaultScreen(disp); root = RootWindow(disp, scr); /* xinerama emulation simulates xinerama on a single screen: * * actual screen * +---------------------+--------------+ * | | | * | | | * | | | * | | simulated | * | | screen 2 | * | simulated screen 1 | | * | | | * | | | * | | | * | | | * +---------------------+ | * | blank area | | * | | | * +---------------------+--------------+ */ count = 2; total_screens_xi = count; screens_xi = (XineramaScreenInfo *) safemalloc(sizeof(XineramaScreenInfo) * (1 + count)); /* calculate the faked sub screen dimensions */ w = DisplayWidth(disp, scr); ws = 3 * w / 5; h = DisplayHeight(disp, scr); screens_xi[1].screen_number = 0; screens_xi[1].x_org = 0; screens_xi[1].y_org = h / 16; screens_xi[1].width = ws; screens_xi[1].height = 7 * h / 8; screens_xi[2].screen_number = 1; screens_xi[2].x_org = ws; screens_xi[2].y_org = 0; screens_xi[2].width = w - ws; screens_xi[2].height = 7 * h / 8; /* add delimiter */ attributes.background_pixel = PictureWhitePixel(); attributes.override_redirect = True; blank_w = XCreateWindow( disp, root, 0, screens_xi[1].y_org - 1, screens_xi[1].width, 2, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); blank2_w = XCreateWindow( disp, root, 0, screens_xi[1].y_org + screens_xi[1].height - 1, screens_xi[1].width, 2, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); blank3_w = XCreateWindow( disp, root, screens_xi[2].x_org, screens_xi[2].height - 1, w - screens_xi[2].x_org, 2, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); vert_w = XCreateWindow( disp, root, screens_xi[2].x_org - 1, 0, 2, h, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel|CWOverrideRedirect, &attributes); } else if (FScreenHaveXinerama && XineramaQueryExtension(disp, &dummy_rc, &dummy_rc) && XineramaIsActive(disp)) { int count; XineramaScreenInfo *info; info = FXineramaQueryScreens(disp, &count); total_screens_xi = count; screens_xi = (XineramaScreenInfo *) safemalloc(sizeof(XineramaScreenInfo) * (1 + count)); memcpy(screens_xi + 1, info, sizeof(XineramaScreenInfo) * count); XFree(info); } else { total_screens_xi = 0; screens_xi = (XineramaScreenInfo *)safemalloc( sizeof(XineramaScreenInfo)*1); } total_screens = total_screens_xi; screens = screens_xi; /* Now, fill screens[0] with global screen parameters */ screens_xi[0].screen_number = -1; screens_xi[0].x_org = 0; screens_xi[0].y_org = 0; screens_xi[0].width = DisplayWidth (disp, DefaultScreen(disp)); screens_xi[0].height = DisplayHeight(disp, DefaultScreen(disp)); /* Fill in the screen range */ FScreenSetState(is_xinerama_enabled); return; } void FScreenOnOff(Bool do_enable) { FScreenSetState(do_enable); } void FScreenSLSOnOff(Bool do_enable) { is_sls_enabled = do_enable; if (do_enable) { total_screens = total_screens_sls; if (!screens_sls) { /* Sls not configured yet, use whole screen by default */ FScreenConfigureSLSSize(1, 1); } screens = screens_sls; } else { total_screens = total_screens_xi; screens = screens_xi; } FScreenSetState(is_xinerama_enabled); } Bool FScreenConfigureSLSSize(int width, int height) { unsigned long scr = DefaultScreen(disp); int w = DisplayWidth(disp, scr); int h = DisplayHeight(disp, scr); if (width <= 1) { width = 1; } else if (width > w) { width = w; } if (height <= 1) { height = 1; } else if (height > h) { height = h; } if (total_sls_width == width && total_sls_height == height && screens_sls) { return False; } if (screens_sls) { free(screens_sls); screens_sls = NULL; } /* calculate the screens */ { int row, col, sn; int ws; int hs; total_screens_sls = width * height; total_sls_width = width; total_sls_height = height; ws = w / total_sls_width; hs = h / total_sls_height; screens_sls = (XineramaScreenInfo *) safemalloc(sizeof(XineramaScreenInfo) * (1 + total_screens_sls)); /* calculate the faked sub screen dimensions */ screens_sls[0] = screens_xi[0]; sn = 1; for (row = 0; row < total_sls_height; row++) { for (col = 0; col < total_sls_width; col++, sn++) { screens_sls[sn].screen_number = sn - 1; screens_sls[sn].x_org = col * ws; screens_sls[sn].y_org = row * hs; screens_sls[sn].width = ws; screens_sls[sn].height = hs; } } } have_sls_screen_list = False; FScreenSLSOnOff(is_sls_enabled); return True; } Bool FScreenConfigureSLSScreens(int nscreens, char *args) { int sn; char *next; if (nscreens == 0 || args == NULL) { return FScreenConfigureSLSSize(1, 1); } if (nscreens == 1 && screens_sls) { return False; } if (screens_sls) { free(screens_sls); screens_sls = NULL; } screens_sls = (XineramaScreenInfo *) safemalloc(sizeof(XineramaScreenInfo) * (nscreens + 1)); screens_sls[0] = screens_xi[0]; for (sn = 1; sn <= nscreens; sn++, args = next) { char *token; int val[4]; /* read next screen spec */ token = PeekToken(args, &next); if (!token) { break; } if (XParseGeometry(token, &val[0], &val[1], (unsigned int *)&val[2], (unsigned int *)&val[3]) == (XValue|YValue|WidthValue|HeightValue) || GetIntegerArguments(args, &next, val, 4) == 4) { if (val[0] < 0 || val[1] < 0 || val[2] < 1 || val[3] < 1) { /* illegal spec */ break; } screens_sls[sn].screen_number = sn - 1; screens_sls[sn].x_org = val[0]; screens_sls[sn].y_org = val[1]; screens_sls[sn].width = val[2]; screens_sls[sn].height = val[3]; } else { /* illegal spec */ break; } } total_screens_sls = sn - 1; have_sls_screen_list = True; FScreenSLSOnOff(is_sls_enabled); return True; } #if 0 void FScreenDisableRandR(void) { if (disp != NULL) { fprintf(stderr, "FScreen: WARNING: FScreenDisableRandR()" " called after FScreenInit()!\n"); } randr_disabled = 1; return; } #endif static int FScreenGetPrimaryScreen(XEvent *ev) { if (!is_xinerama_enabled) { return 0; } if (primary_scr == FSCREEN_GLOBAL) { return 0; } else if (primary_scr == FSCREEN_CURRENT) { int mx; int my; /* use current screen as primary screen */ GetMouseXY(ev, &mx, &my); return FindScreenOfXY(mx, my); } else if (primary_scr < 0 || primary_scr >= last_to_check) { /* out of range */ return 0; } return primary_scr + 1; } void FScreenSetPrimaryScreen(int scr) { primary_scr = scr; } /* Intended to be called by modules. Simply pass in the parameter from the * config string sent by fvwm. */ void FScreenConfigureModule(char *args) { int val[6]; int n; char *next; n = GetIntegerArguments(args, &next, val, 4); if (n != 4) { /* ignore broken line */ return; } FScreenSetPrimaryScreen(val[1]); if (val[3]) { /* SLS screen coordinates follow */ n = GetIntegerArguments(next, &next, val + 4, 1); if (n != 1) { /* ignore broken line */ return; } FScreenConfigureSLSScreens(val[4], next); } else { /* simple SLS line */ n = GetIntegerArguments(next, NULL, val + 4, 2); if (n != 2) { /* ignore broken line */ return; } FScreenConfigureSLSSize(val[4], val[5]); } FScreenSLSOnOff(val[2]); FScreenOnOff(val[0]); return; } /* Here's the function used by fvwm to generate the string which * FScreenConfigureModule expects to receive back as its argument. */ const char *FScreenGetConfiguration(void) { int i; int l; int l2; static char msg[MAX_MODULE_INPUT_TEXT_LEN]; char buf[64]; sprintf( msg, XINERAMA_CONFIG_STRING" %d %d %d %d", FScreenIsEnabled(), primary_scr, FScreenIsSLSEnabled(), have_sls_screen_list); l = strlen(msg); if (have_sls_screen_list) { sprintf(msg + l, " %d", total_screens_sls); for (i = 0; i < total_screens_sls; i++) { sprintf(buf, " %d %d %d %d", screens_sls[i].x_org, screens_sls[i].y_org, screens_sls[i].width, screens_sls[i].height); l2 = strlen(buf); if (l + l2 > MAX_MODULE_INPUT_TEXT_LEN) { break; } strcat(msg + l, buf); l += l2; } } else { sprintf(msg + l, " %d %d", total_sls_width, total_sls_height); } return msg; } /* Sets the default screen for ...ParseGeometry if no screen spec is given. * Usually this is FSCREEN_SPEC_PRIMARY, but this won't allow modules to appear * under the pointer. */ void FScreenSetDefaultModuleScreen(char *scr_spec) { default_geometry_scr = FScreenParseScreenBit(scr_spec, FSCREEN_SPEC_PRIMARY); return; } static int FindScreenOfXY(int x, int y) { int i; x = x % screens_xi[0].width; while (x < 0) { x += screens_xi[0].width; } y = y % screens_xi[0].height; while (y < 0) { y += screens_xi[0].height; } for (i = first_to_check; i <= last_to_check; i++) { if (x >= screens[i].x_org && x < screens[i].x_org + screens[i].width && y >= screens[i].y_org && y < screens[i].y_org + screens[i].height) { return i; } } /* Ouch! A "black hole" coords? As for now, return global screen */ return 0; } static int FindScreen( fscreen_scr_arg *arg, fscreen_scr_t screen) { fscreen_scr_arg tmp; if (num_screens == 0) { screen = FSCREEN_GLOBAL; } switch (screen) { case FSCREEN_GLOBAL: screen = 0; break; case FSCREEN_PRIMARY: screen = FScreenGetPrimaryScreen( (arg && arg->mouse_ev) ? arg->mouse_ev : NULL); break; case FSCREEN_CURRENT: /* translate to xypos format */ if (!arg) { tmp.mouse_ev = NULL; arg = &tmp; } GetMouseXY(arg->mouse_ev, &arg->xypos.x, &arg->xypos.y); /* fall through */ case FSCREEN_XYPOS: /* translate to screen number */ if (!arg) { tmp.xypos.x = 0; tmp.xypos.y = 0; arg = &tmp; } screen = FindScreenOfXY(arg->xypos.x, arg->xypos.y); break; default: /* screen is given counting from 0; translate to counting from * 1 */ screen++; break; } return screen; } /* Given pointer coordinates, return the screen the pointer is on. * * Perhaps most useful with $[pointer.screen] */ int FScreenOfPointerXY(int x, int y) { int pscreen; pscreen = FindScreenOfXY(x, y); return (pscreen > 0) ? --pscreen : pscreen; } /* Returns the specified screens geometry rectangle. screen can be a screen * number or any of the values FSCREEN_GLOBAL, FSCREEN_CURRENT, * FSCREEN_PRIMARY or FSCREEN_XYPOS. The arg union only has a meaning for * FSCREEN_CURRENT and FSCREEN_XYARG. For FSCREEN_CURRENT its mouse_ev member * may be given. It is tried to find out the pointer position from the event * first before querying the pointer. For FSCREEN_XYPOS the xpos member is used * to fetch the x/y position of the point on the screen. If arg is NULL, the * position 0 0 is assumed instead. * * Any of the arguments arg, x, y, w and h may be NULL. * * FSCREEN_GLOBAL: return the global screen dimensions * FSCREEN_CURRENT: return dimensions of the screen with the pointer * FSCREEN_PRIMARY: return the primary screen dimensions * FSCREEN_XYPOS: return dimensions of the screen with the given coordinates * * The function returns False if the global screen was returned and more than * one screen is configured. Otherwise it returns True. */ Bool FScreenGetScrRect( fscreen_scr_arg *arg, fscreen_scr_t screen, int *x, int *y, int *w, int *h) { screen = FindScreen(arg, screen); if (screen < first_to_check || screen > last_to_check) { screen = 0; } if (x) { *x = screens[screen].x_org; } if (y) { *y = screens[screen].y_org; } if (w) { *w = screens[screen].width; } if (h) { *h = screens[screen].height; } return !(screen == 0 && num_screens > 1); } /* returns the screen id */ Bool FScreenGetScrId( fscreen_scr_arg *arg, fscreen_scr_t screen) { screen = FindScreen(arg, screen); if (screen < 0) { screen = FSCREEN_GLOBAL; } return screen; } /* Translates the coodinates *x *y from the screen specified by arg_src and * screen_src to coordinates on the screen specified by arg_dest and * screen_dest. (see FScreenGetScrRect for more details). */ void FScreenTranslateCoordinates( fscreen_scr_arg *arg_src, fscreen_scr_t screen_src, fscreen_scr_arg *arg_dest, fscreen_scr_t screen_dest, int *x, int *y) { int x_src; int y_src; int x_dest; int y_dest; FScreenGetScrRect(arg_src, screen_src, &x_src, &y_src, NULL, NULL); FScreenGetScrRect(arg_dest, screen_dest, &x_dest, &y_dest, NULL, NULL); if (x) { *x = *x + x_src - x_dest; } if (y) { *y = *y + y_src - y_dest; } return; } /* Arguments work exactly like for FScreenGetScrRect() */ int FScreenClipToScreen( fscreen_scr_arg *arg, fscreen_scr_t screen, int *x, int *y, int w, int h) { int sx; int sy; int sw; int sh; int lx = (x) ? *x : 0; int ly = (y) ? *y : 0; int x_grav = GRAV_POS; int y_grav = GRAV_POS; FScreenGetScrRect(arg, screen, &sx, &sy, &sw, &sh); if (lx + w > sx + sw) { lx = sx + sw - w; x_grav = GRAV_NEG; } if (ly + h > sy + sh) { ly = sy + sh - h; y_grav = GRAV_NEG; } if (lx < sx) { lx = sx; x_grav = GRAV_POS; } if (ly < sy) { ly = sy; y_grav = GRAV_POS; } if (x) { *x = lx; } if (y) { *y = ly; } return grav_matrix[y_grav][x_grav]; } /* Arguments work exactly like for FScreenGetScrRect() */ void FScreenCenterOnScreen( fscreen_scr_arg *arg, fscreen_scr_t screen, int *x, int *y, int w, int h) { int sx; int sy; int sw; int sh; int lx; int ly; FScreenGetScrRect(arg, screen, &sx, &sy, &sw, &sh); lx = (sw - w) / 2; ly = (sh - h) / 2; if (lx < 0) lx = 0; if (ly < 0) ly = 0; lx += sx; ly += sy; if (x) { *x = lx; } if (y) { *y = ly; } return; } void FScreenGetResistanceRect( int wx, int wy, unsigned int ww, unsigned int wh, int *x0, int *y0, int *x1, int *y1) { fscreen_scr_arg arg; arg.xypos.x = wx + ww / 2; arg.xypos.y = wy + wh / 2; FScreenGetScrRect(&arg, FSCREEN_XYPOS, x0, y0, x1, y1); *x1 += *x0; *y1 += *y0; return; } /* Arguments work exactly like for FScreenGetScrRect() */ Bool FScreenIsRectangleOnScreen( fscreen_scr_arg *arg, fscreen_scr_t screen, rectangle *rec) { int sx; int sy; int sw; int sh; FScreenGetScrRect(arg, screen, &sx, &sy, &sw, &sh); return (rec->x + rec->width > sx && rec->x < sx + sw && rec->y + rec->height > sy && rec->y < sy + sh) ? True : False; } void FScreenSpecToString(char *dest, int space, fscreen_scr_t screen) { char s[32]; if (space <= 0) { return; } switch (screen) { case FSCREEN_GLOBAL: strcpy(s, "global screen"); break; case FSCREEN_CURRENT: strcpy(s, "current screen"); break; case FSCREEN_PRIMARY: strcpy(s, "primary screen"); break; case FSCREEN_XYPOS: strcpy(s, "screen specified by xy"); break; default: sprintf(s, "%d", screen); break; } strncpy(dest, s, space); dest[space - 1] = 0; return; } static int FScreenParseScreenBit(char *scr_spec, char default_screen) { int scr = default_geometry_scr; char c; c = (scr_spec) ? tolower(*scr_spec) : tolower(default_screen); if (c == FSCREEN_SPEC_GLOBAL) { scr = FSCREEN_GLOBAL; } else if (c == FSCREEN_SPEC_CURRENT) { scr = FSCREEN_CURRENT; } else if (c == FSCREEN_SPEC_PRIMARY) { scr = FSCREEN_PRIMARY; } else if (c == FSCREEN_SPEC_WINDOW) { scr = FSCREEN_XYPOS; } else if (isdigit(c)) { scr = atoi(scr_spec); } else { c = tolower(default_screen); if (c == FSCREEN_SPEC_GLOBAL) { scr = FSCREEN_GLOBAL; } else if (c == FSCREEN_SPEC_CURRENT) { scr = FSCREEN_CURRENT; } else if (c == FSCREEN_SPEC_PRIMARY) { scr = FSCREEN_PRIMARY; } else if (c == FSCREEN_SPEC_WINDOW) { scr = FSCREEN_XYPOS; } else if (isdigit(c)) { scr = atoi(scr_spec); } } return scr; } int FScreenGetScreenArgument(char *scr_spec, fscreen_scr_spec_t default_screen) { while (scr_spec && isspace(*scr_spec)) { scr_spec++; } return FScreenParseScreenBit(scr_spec, default_screen); } /* * FScreenParseGeometry * Does the same as XParseGeometry, but handles additional "@scr". * Since it isn't safe to define "ScreenValue" constant (actual values * of other "XXXValue" are specified in Xutil.h, not by us, so there can * be a clash), the screen value is always returned, even if it wasn't * present in `parse_string' (set to default in that case). * */ int FScreenParseGeometryWithScreen( char *parsestring, int *x_return, int *y_return, unsigned int *width_return, unsigned int *height_return, int *screen_return) { int ret; char *copy, *scr_p; int s_size; int scr; /* Safety net */ if (parsestring == NULL || *parsestring == '\0') { return 0; } /* Make a local copy devoid of "@scr" */ s_size = strlen(parsestring) + 1; copy = safemalloc(s_size); memcpy(copy, parsestring, s_size); scr_p = strchr(copy, '@'); if (scr_p != NULL) { *scr_p++ = '\0'; } /* Do the parsing */ ret = XParseGeometry( copy, x_return, y_return, width_return, height_return); /* Parse the "@scr", if any */ scr = FScreenParseScreenBit(scr_p, FSCREEN_SPEC_PRIMARY); *screen_return = scr; /* We don't need the string any more */ free(copy); return ret; } /* Same as above, but dump screen return value to keep compatible with the X * function. */ int FScreenParseGeometry( char *parsestring, int *x_return, int *y_return, unsigned int *width_return, unsigned int *height_return) { int scr; int rc; int mx; int my; rc = FScreenParseGeometryWithScreen( parsestring, x_return, y_return, width_return, height_return, &scr); if (rc == 0) { return 0; } switch (scr) { case FSCREEN_GLOBAL: scr = 0; break; case FSCREEN_CURRENT: GetMouseXY(NULL, &mx, &my); scr = FindScreenOfXY(mx, my); break; case FSCREEN_PRIMARY: scr = FScreenGetPrimaryScreen(NULL); break; default: scr++; break; } if (scr <= 0 || scr > last_to_check) { scr = 0; } else { /* adapt geometry to selected screen */ if (rc & XValue) { if (rc & XNegative) { *x_return -= (screens[0].width - screens[scr].width - screens[scr].x_org); } else { *x_return += screens[scr].x_org; } } if (rc & YValue) { if (rc & YNegative) { *y_return -= (screens[0].height - screens[scr].height - screens[scr].y_org); } else { *y_return += screens[scr].y_org; } } } return rc; } /* FScreenGetGeometry * Parses the geometry in a form: XGeometry[@screen], i.e. * [=][{xX}][{+-}{+-}][@] * where is either a number or "G" (global) "C" (current) * or "P" (primary) * * Args: * parsestring, x_r, y_r, w_r, h_r the same as in XParseGeometry * hints window hints structure, may be NULL * flags bitmask of allowed flags (XValue, WidthValue, XNegative...) * * Note1: * hints->width and hints->height will be used to calc negative geometry * if width/height isn't specified in the geometry itself. * * Note2: * This function's behaviour is crafted to sutisfy/emulate the * FvwmWinList::MakeMeWindow()'s behaviour. * * Note3: * A special value of `flags' when [XY]Value are there but [XY]Negative * aren't, means that in case of negative geometry specification * x_r/y_r values will be promoted to the screen border, but w/h * wouldn't be subtracted, so that the program can do x-=w later * ([XY]Negative *will* be returned, albeit absent in `flags'). * This option is supposed for proggies like FvwmButtons, which * receive geometry specification long before they are able to actually * use it (and which calculate w/h themselves). * (The same effect can't be obtained with omitting {Width,Height}Value * in the flags, since the app may wish to get the dimensions but apply * some constraints later (as FvwmButtons do, BTW...).) * This option can be also useful in cases where dimensions are * specified not in pixels but in some other units (e.g., charcells). */ int FScreenGetGeometry( char *parsestring, int *x_return, int *y_return, int *width_return, int *height_return, XSizeHints *hints, int flags) { int ret; int saved; int x, y; unsigned int w = 0, h = 0; int grav, x_grav, y_grav; int scr = default_geometry_scr; int scr_x, scr_y; int scr_w, scr_h; /* I. Do the parsing and strip off extra bits */ ret = FScreenParseGeometryWithScreen(parsestring, &x, &y, &w, &h, &scr); saved = ret & (XNegative | YNegative); ret &= flags; /* II. Get the screen rectangle */ switch (scr) { case FSCREEN_GLOBAL: case FSCREEN_CURRENT: case FSCREEN_PRIMARY: case FSCREEN_XYPOS: FScreenGetScrRect(NULL, scr, &scr_x, &scr_y, &scr_w, &scr_h); break; default: scr++; if (scr < first_to_check || scr > last_to_check) scr = first_to_check; scr_x = screens[scr].x_org; scr_y = screens[scr].y_org; scr_w = screens[scr].width; scr_h = screens[scr].height; } /* III. Interpret and fill in the values */ /* Fill in dimensions for future negative calculations if * omitted/forbidden */ /* Maybe should use *x_return,*y_return if hints==NULL? * Unreliable... */ if (hints != NULL && hints->flags & PSize) { if ((ret & WidthValue) == 0) { w = hints->width; } if ((ret & HeightValue) == 0) { h = hints->height; } } else { /* This branch is required for case when size *is* specified, * but masked off */ if ((ret & WidthValue) == 0) { w = 0; } if ((ret & HeightValue) == 0) { h = 0; } } /* Advance coords to the screen... */ x += scr_x; y += scr_y; /* ...and process negative geometries */ if (saved & XNegative) { x += scr_w; } if (saved & YNegative) { y += scr_h; } if (ret & XNegative) { x -= w; } if (ret & YNegative) { y -= h; } /* Restore negative bits */ ret |= saved; /* Guess orientation */ x_grav = (ret & XNegative)? GRAV_NEG : GRAV_POS; y_grav = (ret & YNegative)? GRAV_NEG : GRAV_POS; grav = grav_matrix[y_grav][x_grav]; /* Return the values */ if (ret & XValue) { *x_return = x; if (hints != NULL) { hints->x = x; } } if (ret & YValue) { *y_return = y; if (hints != NULL) { hints->y = y; } } if (ret & WidthValue) { *width_return = w; if (hints != NULL) { hints->width = w; } } if (ret & HeightValue) { *height_return = h; if (hints != NULL) { hints->height = h; } } if (1 /*flags & GravityValue*/ && grav != DEFAULT_GRAVITY) { if (hints != NULL && hints->flags & PWinGravity) { hints->win_gravity = grav; } } if (hints != NULL && ret & XValue && ret & YValue) hints->flags |= USPosition; return ret; } /* FScreenMangleScreenIntoUSPosHints * A hack to mangle the screen number into the XSizeHints structure. * If the USPosition flag is set, hints->x is set to the magic number and * hints->y is set to the screen number. If the USPosition flag is clear, * x and y are set to zero. * * Note: This is a *hack* to allow modules to specify the target screen for * their windows and have the StartsOnScreen style set for them at the same * time. Do *not* rely on the mechanism described above. */ void FScreenMangleScreenIntoUSPosHints(fscreen_scr_t screen, XSizeHints *hints) { if (hints->flags & USPosition) { hints->x = FSCREEN_MANGLE_USPOS_HINTS_MAGIC; hints->y = (short)screen; } else { hints->x = 0; hints->y = 0; } return; } /* FScreenMangleScreenIntoUSPosHints * A hack to mangle the screen number into the XSizeHints structure. * If the USPosition flag is set, hints->x is set to the magic number and * hints->y is set to the screen spec. If the USPosition flag is clear, * x and y are set to zero. * * Note: This is a *hack* to allow modules to specify the target screen for * their windows and have the StartsOnScreen style set for them at the same * time. Do *not* rely on the mechanism described above. */ fscreen_scr_t FScreenFetchMangledScreenFromUSPosHints(XSizeHints *hints) { fscreen_scr_t screen; if ((hints->flags & USPosition) && hints->x == FSCREEN_MANGLE_USPOS_HINTS_MAGIC) { screen = (fscreen_scr_t)(hints->y); } else { screen = FSCREEN_GLOBAL; } return screen; } /* no rand_r for now */ # if 0 int FScreenGetRandrEventType(void) { #ifdef HAVE_RANDR return randr_active? randr_event_base + RRScreenChangeNotify : 0; #else return 0; #endif } Bool FScreenHandleRandrEvent( XEvent *event, int *old_w, int *old_h, int *new_w, int *new_h) { #ifndef HAVE_RANDR return 0; #else XRRScreenChangeNotifyEvent *ev = (XRRScreenChangeNotifyEvent *)event; int nw, nh, tmp; if (!randr_active || event->type != randr_event_base + RRScreenChangeNotify) { return 0; } nw = ev->width; nh = ev->height; /* * Note1: this check is not very good, since the right way is to * obtain a list of possible rotations and ... * * Note2: as to WM's point of view, I'm unsure if rotation should be * treated exactly as resizing (i.e. that it should reposition * windows in the same fashion). */ if (ev->rotation & (1<<1 | 1<<3)) { tmp = nw; nw = nh; nh = tmp; } *old_w = screens[0].width; *old_h = screens[0].height; screens[0].width = nw; *new_w = nw; screens[0].height = nh; *new_h = nh; return (nw != *old_w || nh != *old_h); #endif } #endif fvwm-2.6.7/libs/XResource.h0000644000175700017570000000103012773467232012474 00000000000000#ifndef LIB_XRESOURCE_H #define LIB_XRESOURCE_H /* * Wrappers around Xrm routines (XResources.c) */ void MergeXResources(Display *dpy, XrmDatabase *pdb, Bool override); void MergeCmdLineResources( XrmDatabase *pdb, XrmOptionDescList opts, int num_opts, char *name, int *pargc, char **argv, Bool fNoDefaults); Bool MergeConfigLineResource( XrmDatabase *pdb, char *line, char *prefix, char *bindstr); Bool GetResourceString( XrmDatabase db, const char *resource, const char *prefix, XrmValue *xval); #endif /* LIB_XRESOURCE_H */ fvwm-2.6.7/libs/Makefile.in0000644000175700017570000006245713010103322012441 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = libs DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libfvwm_a_AR = $(AR) $(ARFLAGS) libfvwm_a_DEPENDENCIES = @LIBOBJS@ am_libfvwm_a_OBJECTS = gravity.$(OBJEXT) BidiJoin.$(OBJEXT) \ Flocale.$(OBJEXT) PictureUtils.$(OBJEXT) FScreen.$(OBJEXT) \ Graphics.$(OBJEXT) PictureGraphics.$(OBJEXT) \ Bindings.$(OBJEXT) FlocaleCharset.$(OBJEXT) Parse.$(OBJEXT) \ PictureImageLoader.$(OBJEXT) Colorset.$(OBJEXT) \ ColorUtils.$(OBJEXT) CombineChars.$(OBJEXT) Module.$(OBJEXT) \ FRender.$(OBJEXT) Ficonv.$(OBJEXT) envvar.$(OBJEXT) \ Fft.$(OBJEXT) gravity.$(OBJEXT) XResource.$(OBJEXT) \ FEvent.$(OBJEXT) FImage.$(OBJEXT) WinMagic.$(OBJEXT) \ Target.$(OBJEXT) Picture.$(OBJEXT) XError.$(OBJEXT) \ queue.$(OBJEXT) fvwmsignal.$(OBJEXT) System.$(OBJEXT) \ PictureBase.$(OBJEXT) Cursor.$(OBJEXT) Strings.$(OBJEXT) \ fvwmrect.$(OBJEXT) FRenderInit.$(OBJEXT) safemalloc.$(OBJEXT) \ FBidi.$(OBJEXT) wild.$(OBJEXT) Grab.$(OBJEXT) Event.$(OBJEXT) \ ClientMsg.$(OBJEXT) setpgrp.$(OBJEXT) FShape.$(OBJEXT) \ FGettext.$(OBJEXT) Rectangles.$(OBJEXT) timeout.$(OBJEXT) \ flist.$(OBJEXT) charmap.$(OBJEXT) wcontext.$(OBJEXT) \ modifiers.$(OBJEXT) fsm.$(OBJEXT) FTips.$(OBJEXT) \ fio.$(OBJEXT) fvwmlib.$(OBJEXT) libfvwm_a_OBJECTS = $(am_libfvwm_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libfvwm_a_SOURCES) DIST_SOURCES = $(libfvwm_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ noinst_LIBRARIES = libfvwm.a libfvwm_a_SOURCES = \ BidiJoin.h Bindings.h ClientMsg.h ColorUtils.h Colorset.h \ CombineChars.h Cursor.h Event.h FBidi.h FEvent.h FGettext.h FImage.h \ FRender.h FRenderInit.h FRenderInterface.h FSMlib.h FScreen.h \ FShape.h FShm.h FTips.h Fcursor.h Fft.h FftInterface.h Ficonv.h \ Flocale.h FlocaleCharset.h Fplay.h Fpng.h Fsvg.h Fxpm.h Grab.h \ Graphics.h Module.h Parse.h Picture.h PictureBase.h \ PictureDitherMatrice.h PictureGraphics.h PictureImageLoader.h \ PictureUtils.h Rectangles.h Strings.h System.h Target.h WinMagic.h \ XError.h XResource.h charmap.h defaults.h envvar.h fio.h flist.h \ fsm.h ftime.h fvwm_sys_stat.h fvwmlib.h fvwmrect.h fvwmsignal.h \ gravity.c gravity.h lang-strings.h modifiers.h queue.h safemalloc.h \ setpgrp.h timeout.h vpacket.h wcontext.h wild.h \ \ BidiJoin.c Flocale.c PictureUtils.c FScreen.c Graphics.c \ PictureGraphics.c Bindings.c FlocaleCharset.c Parse.c \ PictureImageLoader.c Colorset.c ColorUtils.c CombineChars.c Module.c \ FRender.c Ficonv.c envvar.c Fft.c gravity.c \ XResource.c FEvent.c FImage.c WinMagic.c Target.c Picture.c XError.c \ queue.c fvwmsignal.c System.c PictureBase.c Cursor.c Strings.c \ fvwmrect.c FRenderInit.c safemalloc.c FBidi.c \ wild.c Grab.c Event.c ClientMsg.c setpgrp.c FShape.c \ FGettext.c Rectangles.c timeout.c flist.c charmap.c wcontext.c \ modifiers.c fsm.c FTips.c fio.c fvwmlib.c libfvwm_a_LIBADD = @LIBOBJS@ AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(Xft_CFLAGS) $(X_CFLAGS) \ $(iconv_CFLAGS) $(Xrender_CFLAGS) $(Bidi_CFLAGS) $(png_CFLAGS) \ $(rsvg_CFLAGS) $(intl_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libfvwm.a: $(libfvwm_a_OBJECTS) $(libfvwm_a_DEPENDENCIES) $(EXTRA_libfvwm_a_DEPENDENCIES) $(AM_V_at)-rm -f libfvwm.a $(AM_V_AR)$(libfvwm_a_AR) libfvwm.a $(libfvwm_a_OBJECTS) $(libfvwm_a_LIBADD) $(AM_V_at)$(RANLIB) libfvwm.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BidiJoin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Bindings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientMsg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ColorUtils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Colorset.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CombineChars.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cursor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FBidi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FEvent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FGettext.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FImage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FRender.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FRenderInit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FScreen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FShape.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FTips.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Fft.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Ficonv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Flocale.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FlocaleCharset.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Grab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Graphics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Module.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Picture.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PictureBase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PictureGraphics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PictureImageLoader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PictureUtils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Rectangles.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Strings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/System.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Target.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WinMagic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XError.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XResource.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/charmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/envvar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fvwmlib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fvwmrect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fvwmsignal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gravity.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modifiers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safemalloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setpgrp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeout.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcontext.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wild.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/libs/fvwm_sys_stat.h0000644000175700017570000000313412773467232013474 00000000000000#ifdef HAVE_SYS_STAT_H #include #endif #ifndef S_IRWXO # define FVWM_S_IRWXO 0007 #else # define FVWM_S_IRWXO S_IRWXO #endif #ifndef S_ISUID # define FVWM_S_ISUID 0004000 #else # define FVWM_S_ISUID S_ISUID #endif #ifndef S_ISGID # define FVWM_S_ISGID 0002000 #else # define FVWM_S_ISGID S_ISGID #endif #ifndef S_ISVTX # define FVWM_S_ISVTX 0001000 #else # define FVWM_S_ISVTX S_ISVTX #endif #ifndef S_IRWXU # define FVWM_S_IRWXU 00700 #else # define FVWM_S_IRWXU S_IRWXU #endif #ifndef S_IRUSR # define FVWM_S_IRUSR 00400 #else # define FVWM_S_IRUSR S_IRUSR #endif #ifndef S_IWUSR # define FVWM_S_IWUSR 00200 #else # define FVWM_S_IWUSR S_IWUSR #endif #ifndef S_IXUSR # define FVWM_S_IXUSR 00100 #else # define FVWM_S_IXUSR S_IXUSR #endif #ifndef S_IRWXG # define FVWM_S_IRWXG 00070 #else # define FVWM_S_IRWXG S_IRWXG #endif #ifndef S_IRGRP # define FVWM_S_IRGRP 00040 #else # define FVWM_S_IRGRP S_IRGRP #endif #ifndef S_IWGRP # define FVWM_S_IWGRP 00020 #else # define FVWM_S_IWGRP S_IWGRP #endif #ifndef S_IXGRP # define FVWM_S_IXGRP 00010 #else # define FVWM_S_IXGRP S_IXGRP #endif #ifndef S_IRWXO # define FVWM_S_IRWXO 00007 #else # define FVWM_S_IRWXO S_IRWXO #endif #ifndef S_IROTH # define FVWM_S_IROTH 00004 #else # define FVWM_S_IROTH S_IROTH #endif #ifndef S_IWOTH # define FVWM_S_IWOTH 00002 #else # define FVWM_S_IWOTH S_IWOTH #endif #ifndef S_IXOTH # define FVWM_S_IXOTH 00001 #else # define FVWM_S_IXOTH S_IXOTH #endif #ifndef S_ISLNK # define FVWM_S_ISLNK(x) 0 #else # define FVWM_S_ISLNK(x) S_ISLNK(x) #endif #ifndef S_IFLNK # define FVWM_S_IFLNK 00000 #else # define FVWM_S_IFLNK S_IFLNK #endif fvwm-2.6.7/libs/PictureUtils.c0000644000175700017570000015341013001406607013176 00000000000000/* -*-c-*- */ /* Copyright (C) 1993, Robert Nation * Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include #include #include #include "fvwmlib.h" #include "envvar.h" #include "Grab.h" #include "Parse.h" #include "ftime.h" #include "PictureBase.h" #include "PictureUtils.h" #include "PictureDitherMatrice.h" /* ---------------------------- local definitions and macro ----------------- */ #if 0 /* dv: unused */ /* form alloc_in_cmap from the xpm lib */ #define XPM_DIST(r1,g1,b1,r2,g2,b2) (long)\ (3*(abs((long)r1-(long)r2) + \ abs((long)g1-(long)g2) + \ abs((long)b1-(long)b2)) + \ abs((long)r1 + (long)g1 + (long)b1 - \ ((long)r2 + (long)g2 + (long)b2))) #define XPM_COLOR_CLOSENESS 40000 #endif #define SQUARE(X) ((X)*(X)) #define TRUE_DIST(r1,g1,b1,r2,g2,b2) (long)\ (SQUARE((long)((r1 - r2)>>8)) \ + SQUARE((long)((g1 - g2)>>8)) \ + SQUARE((long)((b1 - b2)>>8))) #define FAST_DIST(r1,g1,b1,r2,g2,b2) (long)\ (abs((long)(r1 - r2)) \ + abs((long)(g1 - g2)) \ + abs((long)(b1 - b2))) #define FVWM_DIST(r1,g1,b1,r2,g2,b2) \ (abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) \ + 2*abs(abs(r1-g1) + abs(g1-b1) + abs(r1-b1) \ - abs(r2-g2) - abs(g2-b2) - abs(r2-b2))) #define USED_DIST(r1,g1,b1,r2,g2,b2) FVWM_DIST(r1,g1,b1,r2,g2,b2) #define PICTURE_COLOR_CLOSENESS USED_DIST(3,3,3,0,0,0) #define PICTURE_PAllocTable 1000000 #define PICTURE_PUseDynamicColors 100000 #define PICTURE_PStrictColorLimit 10000 #define PICTURE_use_named 1000 #define PICTURE_TABLETYPE_LENGHT 7 /* humm ... dither is probably borken with gamma correction. Anyway I do * do think that using gamma correction for the colors cubes is a good * idea */ #define USE_GAMMA_CORECTION 0 /* 2.2 is recommanded by the Poynon colors FAQ, some others suggest 1.5 and 2 * Use float constants!*/ #define COLOR_GAMMA 1.5 #define GREY_GAMMA 2.0 /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { XColor color; /* rgb color info */ unsigned long alloc_count; /* nbr of allocation */ } PColor; typedef struct { /* * info for colors table (depth <= 8) */ /* color cube used */ short nr; short ng; short nb; short ngrey; /* grey palette def, nbr of grey = 2^grey_bits */ short grey_bits; /* color cube used for dithering with the named table */ short d_nr; short d_ng; short d_nb; short d_ngrey_bits; /* do we found a pre-allocated pallet ? */ Bool pre_allocated_pallet; /* info for depth > 8 */ int red_shift; int green_shift; int blue_shift; int red_prec; int green_prec; int blue_prec; /* for dithering in depth 15 and 16 */ unsigned short *red_dither; unsigned short *green_dither; unsigned short *blue_dither; /* colors allocation function */ int (*alloc_color)(Display *dpy, Colormap cmap, XColor *c); int (*alloc_color_no_limit)(Display *dpy, Colormap cmap, XColor *c); int (*alloc_color_dither)( Display *dpy, Colormap cmap, XColor *c, int x, int y); void (*free_colors)( Display *dpy, Colormap cmap, Pixel *pixels, int n, unsigned long planes); void (*free_colors_no_limit)( Display *dpy, Colormap cmap, Pixel *pixels, int n, unsigned long planes); } PColorsInfo; typedef struct { int cols_index; long closeness; } CloseColor; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static int PColorLimit = 0; static PColor *Pct = NULL; static PColor *Pac = NULL; static short *PMappingTable = NULL; static short *PDitherMappingTable = NULL; static Bool PStrictColorLimit = 0; static Bool PAllocTable = 0; static PColorsInfo Pcsi = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* * get shift and prec from a mask */ static void decompose_mask( unsigned long mask, int *shift, int *prec) { *shift = 0; *prec = 0; while (!(mask & 0x1)) { (*shift)++; mask >>= 1; } while (mask & 0x1) { (*prec)++; mask >>= 1; } } /* * color allocation in the colormap. strongly inspired by SetCloseColor from * the Xpm library (depth <= 8) */ static int closeness_cmp(const void *a, const void *b) { CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b; /* cast to int as qsort requires */ return (int) (x->closeness - y->closeness); } static int alloc_color_in_cmap(XColor *c, Bool force) { static XColor colors[256]; CloseColor closenesses[256]; XColor tmp; int i,j; int map_entries = (Pvisual->class == DirectColor)? (1 << Pdepth) : Pvisual->map_entries; time_t current_time; time_t last_time = 0; map_entries = (map_entries > 256)? 256:map_entries; current_time = time(NULL); if (current_time - last_time >= 2 || force) { last_time = current_time; for (i = 0; i < map_entries; i++) { colors[i].pixel = i; } XQueryColors(Pdpy, Pcmap, colors, map_entries); } for(i = 0; i < map_entries; i++) { closenesses[i].cols_index = i; closenesses[i].closeness = USED_DIST( (int)(c->red), (int)(c->green), (int)(c->blue), (int)(colors[i].red), (int)(colors[i].green), (int)(colors[i].blue)); } qsort(closenesses, map_entries, sizeof(CloseColor), closeness_cmp); i = 0; j = closenesses[i].cols_index; while (force || (abs((long)c->red - (long)colors[j].red) <= PICTURE_COLOR_CLOSENESS && abs((long)c->green - (long)colors[j].green) <= PICTURE_COLOR_CLOSENESS && abs((long)c->blue - (long)colors[j].blue) <= PICTURE_COLOR_CLOSENESS)) { tmp.red = colors[j].red; tmp.green = colors[j].green; tmp.blue = colors[j].blue; if (XAllocColor(Pdpy, Pcmap, &tmp)) { c->red = tmp.red; c->green = tmp.green; c->blue = tmp.blue; c->pixel = tmp.pixel; return 1; } else { i++; if (i == map_entries) break; j = closenesses[i].cols_index; } } return 0; } /* * dithering */ static int my_dither(int x, int y, XColor *c) { /* the dither matrice */ static const char DM[128][128] = DITHER_MATRICE; int index; const char *dmp; if (Pcsi.grey_bits != 0) { /* Grey Scale */ int prec = Pcsi.grey_bits; if (Pcsi.grey_bits == 1) { /* FIXME, can we do a better dithering */ prec = 2; } dmp = DM[(0 + y) & (DM_HEIGHT - 1)]; index = (c->green + ((c->blue + c->red) >> 1)) >> 1; index += (dmp[(0 + x) & (DM_WIDTH - 1)] << 2) >> prec; index = (index - (index >> prec)); index = index >> (8 - Pcsi.grey_bits); } else { /* color cube */ int dith, rs, gs, bs, gb, b; int tr,tb,tg; rs = Pcsi.d_nr - 1; gs = Pcsi.d_ng - 1; bs = Pcsi.d_nb - 1; gb = Pcsi.d_ng*Pcsi.d_nb; b = Pcsi.d_nb; dmp = DM[(0 + y) & (DM_HEIGHT - 1)]; dith = (dmp[(0 + x) & (DM_WIDTH - 1)] << 2) | 7; tr = ((c->red * rs) + dith) >> 8; tg = ((c->green * gs) + (262 - dith)) >> 8; tb = ((c->blue * bs) + dith) >> 8; index = tr * gb + tg * b + tb; #if 0 /* try to use the additonal grey. Not easy, good for * certain image/gradient bad for others */ if (Pcsi.d_ngrey_bits) { int g_index; /* dither in the Pcsi.ngrey^3 cc */ tr = ((c->red * (Pcsi.ngrey-1)) + dith) >> 8; tg = ((c->green * (Pcsi.ngrey-1)) + (262 - dith)) >> 8; tb = ((c->blue * (Pcsi.ngrey-1)) + dith) >> 8; /* get the grey */ fprintf(stderr, "%i,%i,%i(%i/%i) ", tr,tg,tb, abs(tr-tg) + abs(tb-tg) + abs(tb-tr),Pcsi.ngrey); g_index = ((tr + tg + tb)/3); if (g_index != 0 && g_index != Pcsi.ngrey-1 && abs(tr-tg) + abs(tb-tg) + abs(tb-tr) <= Pcsi.d_ngrey_bits) { g_index = g_index + Pcsi.ng*Pcsi.nb*Pcsi.ng -1; index = g_index; } } #endif if (PDitherMappingTable != NULL) { index = PDitherMappingTable[index]; } } return index; } static int my_dither_depth_15_16_init(void) { const unsigned char _dither_44[4][4] = { {0, 4, 1, 5}, {6, 2, 7, 3}, {1, 5, 0, 4}, {7, 3, 6, 2} }; int y,x,i; int rm = 0xf8, re = 0x7, gm = 0xfc, ge = 0x3, bm = 0xf8, be = 0x7; if (Pdepth == 16 && (Pvisual->red_mask == 0xf800) && (Pvisual->green_mask == 0x7e0) && (Pvisual->blue_mask == 0x1f)) { /* ok */ } else if (Pdepth == 15 && (Pvisual->red_mask == 0x7c00) && (Pvisual->green_mask == 0x3e0) && (Pvisual->blue_mask == 0x1f)) { gm = 0xf8; ge = 0x7; } else { return 0; /* fail */ } Pcsi.red_dither = (unsigned short *)safemalloc(4*4*256*sizeof(unsigned short)); Pcsi.green_dither = (unsigned short *)safemalloc(4*4*256*sizeof(unsigned short)); Pcsi.blue_dither = (unsigned short *)safemalloc(4*4*256*sizeof(unsigned short)); for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { for (i = 0; i < 256; i++) { if ((_dither_44[x][y] < (i & re)) && (i < (256 - 8))) { Pcsi.red_dither[ (x << 10) | (y << 8) | i] = ((i + 8) & rm) << 8; } else { Pcsi.red_dither[ (x << 10) | (y << 8) | i] = (i & rm) << 8; } if ((_dither_44[x][y] < ((i & ge) << 1)) && (i < (256 - 4))) { Pcsi.green_dither[ (x << 10) | (y << 8) | i] = ((i + 4) & gm) << 8; } else { Pcsi.green_dither[ (x << 10) | (y << 8) | i] = (i & gm) << 8; } if ((_dither_44[x][y] < (i & be)) && (i < (256 - 8))) { Pcsi.blue_dither[ (x << 10) | (y << 8) | i] = ((i + 8) & bm) << 8; } else { Pcsi.blue_dither[ (x << 10) | (y << 8) | i] = (i & bm) << 8; } } } } return 1; } /* * Color allocation in the "palette" */ static int alloc_color_in_pct(XColor *c, int index) { if (Pct[index].alloc_count == 0) { int s = PStrictColorLimit; PStrictColorLimit = 0; c->red = Pct[index].color.red; c->green = Pct[index].color.green; c->blue = Pct[index].color.blue; PictureAllocColor(Pdpy, Pcmap, c, True); /* WARN (rec) */ Pct[index].color.pixel = c->pixel; Pct[index].alloc_count = 1; PStrictColorLimit = s; } else { c->red = Pct[index].color.red; c->green = Pct[index].color.green; c->blue = Pct[index].color.blue; c->pixel = Pct[index].color.pixel; if (Pct[index].alloc_count < 0xffffffff) (Pct[index].alloc_count)++; } return 1; } static int get_color_index(int r, int g, int b, int is_8) { int index; if (!is_8) { r= r >> 8; g= g >> 8; b= b >> 8; } if (Pcsi.grey_bits > 0) { /* FIXME: Use other proporition ? */ index = ((r+g+b)/3) >> (8 - Pcsi.grey_bits); } else { #if 1 /* "exact" computation (corrected linear dist) */ float fr,fg,fb; int ir, ig, ib; /* map to the cube */ fr = ((float)r * (Pcsi.nr-1))/255; fg = ((float)g * (Pcsi.ng-1))/255; fb = ((float)b * (Pcsi.nb-1))/255; if (PMappingTable != NULL) { ir = (int)fr + (fr - (int)fr > 0.5); ig = (int)fg + (fg - (int)fg > 0.5); ib = (int)fb + (fb - (int)fb > 0.5); index = ir * Pcsi.ng*Pcsi.nb + ig * Pcsi.nb + ib; } else { /* found the best of the 8 linear closest points */ int lr,lg,lb,tr,tg,tb,best_dist = -1,i,d; index = 0; lr = min((int)fr+1,Pcsi.nr-1); lg = min((int)fg+1,Pcsi.ng-1); lb = min((int)fb+1,Pcsi.nb-1); for(tr =(int)fr; tr<=lr; tr++) { for(tg =(int)fg; tg<=lg; tg++) { for(tb =(int)fb; tb<=lb; tb++) { i = tr * Pcsi.ng*Pcsi.nb + tg * Pcsi.nb + tb; d = USED_DIST( r,g,b, (Pct[i].color.red>>8), (Pct[i].color.green>>8), (Pct[i].color.blue>>8)); if (best_dist == -1 || d < best_dist) { index = i; best_dist = d; } } } } /* now found the best grey */ if (Pcsi.ngrey - 2 > 0) { /* FIXME: speedup this with more than 8 grey */ int start = Pcsi.nr*Pcsi.ng*Pcsi.nb; for(i=start; i < start+Pcsi.ngrey-2; i++) { d = USED_DIST( r,g,b, (Pct[i].color.red>>8), (Pct[i].color.green>>8), (Pct[i].color.blue>>8)); if (d < best_dist) { index = i; best_dist = d; } } } return index; } #else /* approximation; faster */ index = ((r * Pcsi.nr)>>8) * Pcsi.ng*Pcsi.nb + ((g * Pcsi.ng)>>8) * Pcsi.nb + ((b * Pcsi.nb)>>8); #endif if (PMappingTable != NULL) { index = PMappingTable[index]; } } return index; } /* * Main colors allocator */ static int alloc_color_proportion(Display *dpy, Colormap cmap, XColor *c) { c->pixel = (Pixel)( ((c->red >> (16 - Pcsi.red_prec))<< Pcsi.red_shift) + ((c->green >> (16 - Pcsi.green_prec))<< Pcsi.green_shift) + ((c->blue >> (16 - Pcsi.blue_prec))<< Pcsi.blue_shift) ); return 1; } static int alloc_color_proportion_dither( Display *dpy, Colormap cmap, XColor *c, int x, int y) { /* 8 bit colors !! */ c->red = Pcsi.red_dither[ (((x + 0) & 0x3) << 10) | ((y & 0x3) << 8) | ((c->red) & 0xff)] * 257; c->green = Pcsi.green_dither[ (((x + 0) & 0x3) << 10) | ((y & 0x3) << 8) | ((c->green) & 0xff)] * 257; c->blue = Pcsi.blue_dither[ (((x + 0) & 0x3) << 10) | ((y & 0x3) << 8) | ((c->blue) & 0xff)] * 257; c->pixel = (Pixel)( ((c->red >> (16 - Pcsi.red_prec)) << Pcsi.red_shift) + ((c->green >> (16 - Pcsi.green_prec)) << Pcsi.green_shift) + ((c->blue >> (16 - Pcsi.blue_prec)) << Pcsi.blue_shift) ); return 1; } static int alloc_color_proportion_grey( Display *dpy, Colormap cmap, XColor *c) { /* FIXME: is this ok in general? */ c->pixel = ((c->red + c->green + c->blue)/3); if (Pdepth < 16) { c->pixel = c->pixel >> (16 - Pdepth); } return 1; } static int alloc_color_in_table(Display *dpy, Colormap cmap, XColor *c) { int index = get_color_index(c->red,c->green,c->blue, False); return alloc_color_in_pct(c, index); } static int alloc_color_in_table_dither( Display *dpy, Colormap cmap, XColor *c, int x, int y) { int index; /* 8 bit colors !! */ index = my_dither(x, y, c); return alloc_color_in_pct(c, index); } static int alloc_color_dynamic_no_limit( Display *dpy, Colormap cmap, XColor *c) { int r = 0; if (XAllocColor(dpy, cmap, c)) { r = 1; } else if (!alloc_color_in_cmap(c, False)) { MyXGrabServer(dpy); r = alloc_color_in_cmap(c, True); MyXUngrabServer(dpy); } else { r = 1; } if (r && Pac != NULL && (c->pixel <= (1 << Pdepth) /* always true*/)) { Pac[c->pixel].alloc_count++; Pac[c->pixel].color.red = c->red; Pac[c->pixel].color.green = c->green; Pac[c->pixel].color.blue = c->blue; Pac[c->pixel].color.pixel = c->pixel; } return r; } static int alloc_color_x( Display *dpy, Colormap cmap, XColor *c) { return XAllocColor(dpy, cmap, c); } static void free_colors_in_table( Display *dpy, Colormap cmap, Pixel *pixels, int n, unsigned long planes) { Pixel *p; int i,j,do_free; int m = 0; if (!Pct || !PUseDynamicColors) { return; } p = (Pixel *)safemalloc(n*sizeof(Pixel)); for(i= 0; i < n; i++) { do_free = 1; for(j=0; j 0) { XFreeColors(dpy, cmap, p, m, planes); } free(p); return; } static void free_colors_x( Display *dpy, Colormap cmap, Pixel *pixels, int n, unsigned long planes) { XFreeColors(dpy, cmap, pixels, n, planes); if (Pac != NULL) { int nbr_colors = (1 << Pdepth); int i; for(i= 0; i < n; i++) { if (pixels[i] <= nbr_colors) { Pac[pixels[i]].alloc_count--; } } } } /* * local function for building pallet (dynamic colors, private DirectColor * cmap) */ static XColor *build_mapping_colors(int nr, int ng, int nb) { int r, g, b, i; XColor *colors; colors = (XColor *)safemalloc(nr*ng*nb * sizeof(XColor)); i = 0; for (r = 0; r < nr; r++) { for (g = 0; g < ng; g++) { for (b = 0; b < nb; b++) { colors[i].red = r * 65535 / (nr - 1); colors[i].green = g * 65535 / (ng - 1); colors[i].blue = b * 65535 / (nb - 1); i++; } } } return colors; } static short *build_mapping_table(int nr, int ng, int nb, Bool use_named) { int size = nr*ng*nb; XColor *colors_map; short *Table; int i,j, minind; double mindst = 40000; double dst; colors_map = build_mapping_colors(nr, ng, nb); Table = (short *)safemalloc((size+1) * sizeof(short)); for(i=0; i 0) { for(i = 0; i < npixels; i++) { if (color_table[i].alloc_count) { pixels[n++] = color_table[i].color.pixel; } color_table[i].alloc_count = 0; } if (n > 0) { XFreeColors(Pdpy, Pcmap, pixels, n, 0); } } } /* FIXME: the DirectColor case */ static int get_nbr_of_free_colors(int max_check) { int check = 1; Pixel Pixels[256]; int map_entries = (Pvisual->class == DirectColor)? (1 << Pdepth):Pvisual->map_entries; if (max_check < 1) return 0; if (map_entries > 256) { max_check = 256; } max_check = (max_check > map_entries) ? map_entries:max_check; while(1) { if (XAllocColorCells( Pdpy, Pcmap, False, NULL, 0, Pixels, check)) { XFreeColors(Pdpy, Pcmap, Pixels, check, 0); check++; } else { return check-1; } if (check > max_check) { return check-1; } } return check-1; } static PColor *alloc_color_cube( int nr, int ng, int nb, int ngrey, int grey_bits, Bool do_allocate) { int r, g, b, grey, i, start_grey, end_grey; PColor *color_table; XColor color; int size; size = nr*ng*nb + ngrey + (1 << grey_bits)*(grey_bits != 0); if (grey_bits) { ngrey = (1 << grey_bits); } if (nr > 0 && ngrey > 0) { start_grey = 1; end_grey = ngrey - 1; size = size - 2; } else { start_grey = 0; end_grey = ngrey; } color_table = (PColor *)safemalloc((size+1) * sizeof(PColor)); i = 0; #if USE_GAMMA_CORECTION #define CG(x) 65535.0 * pow((x)/65535.0,1/COLOR_GAMMA) #define GG(x) 65535.0 * pow((x)/65535.0,1/GREY_GAMMA) #else #define CG(x) x #define GG(x) x #endif if (nr > 0) { for (r = 0; r < nr; r++) { for (g = 0; g < ng; g++) { for (b = 0; b < nb; b++) { color.red = CG(r * 65535 / (nr - 1)); color.green = CG(g * 65535 / (ng - 1)); color.blue = CG(b * 65535 / (nb - 1)); if (do_allocate) { if (!XAllocColor(Pdpy, Pcmap, &color)) { free_table_colors( color_table, i); free(color_table); return NULL; } color_table[i].color.pixel = color.pixel; color_table[i].alloc_count = 1; } else { color_table[i].alloc_count = 0; } color_table[i].color.red = color.red; color_table[i].color.green = color.green; color_table[i].color.blue = color.blue; i++; } } } } if (ngrey > 0) { for (grey = start_grey; grey < end_grey; grey++) { color.red = color.green = color.blue = GG(grey * 65535 / (ngrey - 1)); if (do_allocate) { if (!XAllocColor(Pdpy, Pcmap, &color)) { free_table_colors(color_table, i); free(color_table); return NULL; } color_table[i].color.pixel = color.pixel; color_table[i].alloc_count = 1; } else { color_table[i].alloc_count = 0; } color_table[i].color.red = color.red; color_table[i].color.green = color.green; color_table[i].color.blue = color.blue; i++; } } color_table[size].color.red = color_table[size-1].color.red; color_table[size].color.green = color_table[size-1].color.green; color_table[size].color.blue = color_table[size-1].color.blue; color_table[size].color.pixel = color_table[size-1].color.pixel; color_table[size].alloc_count = 0; PColorLimit = size; return color_table; } static PColor *alloc_named_ct(int *limit, Bool do_allocate) { /* First thing in base array are colors probably already in the color map because they have familiar names. I pasted them into a xpm and spread them out so that similar colors are spread out. Toward the end are some colors to fill in the gaps. Currently 61 colors in this list. */ char *color_names[] = { "black", "white", "grey", "green", "blue", "red", "cyan", "yellow", "magenta", "DodgerBlue", "SteelBlue", "chartreuse", "wheat", "turquoise", "CadetBlue", "gray87", "CornflowerBlue", "YellowGreen", "NavyBlue", "MediumBlue", "plum", "aquamarine", "orchid", "ForestGreen", "lightyellow", "brown", "orange", "red3", "HotPink", "LightBlue", "gray47", "pink", "red4", "violet", "purple", "gray63", "gray94", "plum1", "PeachPuff", "maroon", "lavender", "salmon", /* for peachpuff, orange gap */ "blue4", /* for navyblue/mediumblue gap */ "PaleGreen4", /* for forestgreen, yellowgreen gap */ "#AA7700", /* brick, no close named color */ "#11EE88", /* light green, no close named color */ "#884466", /* dark brown, no close named color */ "#CC8888", /* light brick, no close named color */ "#EECC44", /* gold, no close named color */ "#AAAA44", /* dull green, no close named color */ "#FF1188", /* pinkish red */ "#992299", /* purple */ "#CCFFAA", /* light green */ "#664400", /* dark brown*/ "#AADD99", /* light green */ "#66CCFF", /* light blue */ "#CC2299", /* dark red */ "#FF11CC", /* bright pink */ "#11CC99", /* grey/green */ "#AA77AA", /* purple/red */ "#EEBB77" /* orange/yellow */ }; int NColors = sizeof(color_names)/sizeof(char *); int i,rc; PColor *color_table; XColor color; *limit = (*limit > NColors)? NColors: *limit; color_table = (PColor *)safemalloc((*limit+1) * sizeof(PColor)); for(i=0; i<*limit; i++) { rc=XParseColor(Pdpy, Pcmap, color_names[i], &color); if (rc==0) { fprintf(stderr,"color_to_rgb: can't parse color %s," " rc %d\n", color_names[i], rc); free_table_colors(color_table, i); free(color_table); return NULL; } if (do_allocate) { if (!XAllocColor(Pdpy, Pcmap, &color)) { free_table_colors(color_table, i); free(color_table); return NULL; } color_table[i].color.pixel = color.pixel; color_table[i].alloc_count = 1; } else { color_table[i].alloc_count = 0; } color_table[i].color.red = color.red; color_table[i].color.green = color.green; color_table[i].color.blue = color.blue; } color_table[*limit].color.red = color_table[*limit-1].color.red; color_table[*limit].color.green = color_table[*limit-1].color.green; color_table[*limit].color.blue = color_table[*limit-1].color.blue; color_table[*limit].color.pixel = color_table[*limit-1].color.pixel; color_table[*limit].alloc_count = 0; PColorLimit = *limit; return color_table; } static void create_mapping_table( int nr, int ng, int nb, int ngrey, int grey_bits, Bool non_regular_pallet) { Pcsi.grey_bits = 0; /* initialize dithering colors numbers */ if (!non_regular_pallet) { /* */ Pcsi.d_nr = nr; Pcsi.d_ng = ng; Pcsi.d_nb = nb; Pcsi.d_ngrey_bits = 2; while((1< 0) { Pcsi.nr = 0; Pcsi.ng = 0; Pcsi.nb = 0; Pcsi.ngrey = 0; Pcsi.grey_bits = grey_bits; } else if (non_regular_pallet || (0&&ngrey>0)) { /* note: using these table with !used_named && ngrey>0 will * probably leads to faster image loading. But I see nothing * of significative. On the others hands not using it gives * maybe better colors approximation. */ if (PColorLimit <= 9) { Pcsi.nr = 8; Pcsi.ng = 8; Pcsi.nb = 8; Pcsi.ngrey = 0; } else { Pcsi.nr = 16; Pcsi.ng = 16; Pcsi.nb = 16; Pcsi.ngrey = 0; } PMappingTable = build_mapping_table( Pcsi.nr, Pcsi.ng, Pcsi.nb, non_regular_pallet); } else { Pcsi.nr = nr; Pcsi.ng = ng; Pcsi.nb = nb; Pcsi.ngrey = ngrey; Pcsi.grey_bits = 0; } } static void finish_ct_init( int call_type, int ctt, int nr, int ng, int nb, int ngrey, int grey_bits, Bool use_named) { if (call_type == PICTURE_CALLED_BY_FVWM) { char *env; if (PAllocTable) { ctt = PICTURE_PAllocTable + ctt; } if (PUseDynamicColors) { ctt = PICTURE_PUseDynamicColors + ctt; } if (PStrictColorLimit) { ctt = PICTURE_PStrictColorLimit + ctt; } if (use_named) { ctt = PICTURE_use_named + ctt; } else { ctt++; } env = safemalloc(PICTURE_TABLETYPE_LENGHT + 1); sprintf(env, "%i", ctt); flib_putenv("FVWM_COLORTABLE_TYPE", env); free(env); if (Pdepth <= 8) { Pac = (PColor *)safecalloc( (1 << Pdepth), sizeof(PColor)); } } if (Pct) { if (!PAllocTable && call_type == PICTURE_CALLED_BY_FVWM) { free_table_colors(Pct, PColorLimit); } create_mapping_table(nr,ng,nb,ngrey,grey_bits,use_named); } } #define PA_COLOR_CUBE (1 << 1) #define FVWM_COLOR_CUBE (1 << 2) #define PA_GRAY_SCALE (1 << 3) #define FVWM_GRAY_SCALE (1 << 4) #define ANY_COLOR_CUBE (PA_COLOR_CUBE|FVWM_COLOR_CUBE) #define ANY_GRAY_SCALE (PA_GRAY_SCALE|FVWM_GRAY_SCALE) static int PictureAllocColorTable( PictureColorLimitOption *opt, int call_type, Bool use_my_color_limit) { char *envp; int free_colors, nbr_of_color, limit, cc_nbr, i, size; int use_named_table = 0; int do_allocate = 0; int use_default = 1; int private_cmap = !(Pdefault); int color_limit; int pa_type = (Pvisual->class != GrayScale) ? PA_COLOR_CUBE : PA_GRAY_SCALE; int fvwm_type = (Pvisual->class != GrayScale) ? FVWM_COLOR_CUBE : FVWM_GRAY_SCALE; int cc[][6] = { /* {nr,ng,nb,ngrey,grey_bits,logic} */ /* 5 first for direct colors and Pdepth > 8*/ /* 8192 colors depth 13, a reasonable max for a color table */ {16, 32, 16, 0, 0, FVWM_COLOR_CUBE}, /* 4096 colors depth 12 */ {16, 16, 16, 0, 0, FVWM_COLOR_CUBE}, /* 1024 colors depth 10 */ {8, 16, 8, 0, 0, FVWM_COLOR_CUBE}, /* 512 colors depth 9 */ {8, 8, 8, 0, 0, FVWM_COLOR_CUBE}, /* 256 colors 3/3/2 standard colormap */ {8, 8, 4, 0, 0, FVWM_COLOR_CUBE}, /* 256 grey scale */ {0, 0, 0, 0, 8, ANY_GRAY_SCALE}, /* 244 Xrender XFree-4.2 */ {6, 6, 6, 30, 0, ANY_COLOR_CUBE}, /* 216 Xrender XFree-4.2,GTK/QT "default cc" */ {6, 6, 6, 0, 0, ANY_COLOR_CUBE}, /* 180 (GTK) */ {6, 6, 5, 0, 0, ANY_COLOR_CUBE}, /* 144 (GTK) */ {6, 6, 4, 0, 0, ANY_COLOR_CUBE}, /* 128 grey scale */ {0, 0, 0, 0, 7, ANY_GRAY_SCALE}, /* 125 GTK mini default cc (may change? 444) */ {5, 5, 5, 0, 0, ANY_COLOR_CUBE}, /* 100 (GTK with color limit) */ {5, 5, 4, 0, 0, ANY_COLOR_CUBE}, /* 85 Xrender XFree-4.3 */ {4, 4, 4, 23, 0, ANY_COLOR_CUBE}, /* 78 (in fact 76) a good default ??*/ {4, 4, 4, 16, 0, FVWM_COLOR_CUBE}, /* 70 a good default ?? */ {4, 4, 4, 8, 0, ANY_COLOR_CUBE}, /* 68 a good default ?? */ {4, 4, 4, 6, 0, ANY_COLOR_CUBE}, /* 64 Xrender XFree-4.3 (GTK wcl) */ {4, 4, 4, 0, 0, ANY_COLOR_CUBE}, /* 64 grey scale */ {0, 0, 0, 0, 6, ANY_GRAY_SCALE}, /* 54, maybe a good default? */ {4, 4, 3, 8, 0, FVWM_COLOR_CUBE}, /* 48, (GTK wcl) no grey but ok */ {4, 4, 3, 0, 0, FVWM_COLOR_CUBE}, /* 32, 2/2/1 standard colormap */ {4, 4, 2, 0, 0, FVWM_COLOR_CUBE}, /* 32 xrender xfree-4.2 */ {0, 0, 0, 0, 6, ANY_GRAY_SCALE}, /* 29 */ {3, 3, 3, 4, 0, FVWM_COLOR_CUBE}, /* 27 (xrender in depth 6&7(hypo) GTK wcl) */ {3, 3, 3, 0, 0, FVWM_COLOR_CUBE|PA_COLOR_CUBE*(Pdepth<8)}, /* 16 grey scale */ {0, 0, 0, 0, 4, FVWM_GRAY_SCALE}, /* 10 */ {2, 2, 2, 4, 0, FVWM_COLOR_CUBE}, /* 8 (xrender/qt/gtk wcl) */ {2, 2, 2, 0, 0, FVWM_COLOR_CUBE}, /* 8 grey scale Xrender depth 4 and XFree-4.3 */ {0, 0, 0, 0, 3, FVWM_GRAY_SCALE|PA_GRAY_SCALE*(Pdepth<5)}, /* 4 grey scale*/ {0, 0, 0, 0, 2, FVWM_GRAY_SCALE|FVWM_COLOR_CUBE|PA_COLOR_CUBE*(Pdepth<4)}, /* 2 */ {0, 0, 0, 0, 1, FVWM_COLOR_CUBE|FVWM_GRAY_SCALE} }; cc_nbr = sizeof(cc)/(sizeof(cc[0])); /* set up default */ PStrictColorLimit = 0; PUseDynamicColors = 1; PAllocTable = 0; use_named_table = False; color_limit = 0; use_default = True; /* use fvwm color limit */ if (!use_my_color_limit && (envp = getenv("FVWM_COLORTABLE_TYPE")) != NULL) { int nr = 0, ng = 0, nb = 0, grey_bits = 0, ngrey = 0; int ctt = atoi(envp); if (ctt >= PICTURE_PAllocTable) { ctt -= PICTURE_PAllocTable; PAllocTable = 1; /* not useful for a module !*/ } if (ctt >= PICTURE_PUseDynamicColors) { PUseDynamicColors = 1; ctt -= PICTURE_PUseDynamicColors; } if (ctt >= PICTURE_PStrictColorLimit) { PStrictColorLimit = 1; ctt -= PICTURE_PStrictColorLimit; } if (ctt >= PICTURE_use_named) { ctt -= PICTURE_use_named; Pct = alloc_named_ct(&ctt, False); use_named_table = True; } else if (ctt == 0) { /* depth <= 8 and no colors limit ! */ PColorLimit = 0; return 0; } else if (ctt <= cc_nbr) { ctt--; Pct = alloc_color_cube( cc[ctt][0], cc[ctt][1], cc[ctt][2], cc[ctt][3], cc[ctt][4], False); nr = cc[ctt][0]; ng = cc[ctt][1]; nb = cc[ctt][2]; ngrey = cc[ctt][3]; grey_bits = cc[ctt][4]; } if (Pct != NULL) { /* should always happen */ finish_ct_init( call_type, ctt, nr, ng, nb, ngrey, grey_bits, use_named_table); return PColorLimit; } } nbr_of_color = (1 << Pdepth); color_limit = 0; /* parse the color limit env variable */ if ((envp = getenv("FVWM_COLORLIMIT")) != NULL) { char *rest, *l; rest = GetQuotedString(envp, &l, ":", NULL, NULL, NULL); if (l && *l != '\0' && (color_limit = atoi(l)) >= 0) { use_default = 0; } if (l != NULL) { free(l); } if (color_limit == 9 || color_limit == 61) { use_named_table = 1; } if (rest && *rest != '\0') { if (rest[0] == '1') { PStrictColorLimit = 1; } else { PStrictColorLimit = 0; } if (strlen(rest) > 1 && rest[1] == '1') { use_named_table = 1; } else { use_named_table = 0; } if (strlen(rest) > 2 && rest[2] == '1') { PUseDynamicColors = 1; } else { PUseDynamicColors = 0; } if (strlen(rest) > 3 && rest[3] == '1') { PAllocTable = 1; } else { PAllocTable = 0; } } } else if (opt != NULL) /* use the option */ { if (opt->color_limit > 0) { use_default = 0; color_limit = opt->color_limit; } if (color_limit == 9 || color_limit == 61) { use_named_table = 1; } if (opt->strict > 0) { PStrictColorLimit = 1; } else if (opt->strict == 0) { PStrictColorLimit = 0; } if (opt->use_named_table > 0) { use_named_table = 1; } else if (opt->use_named_table == 0) { use_named_table = 0; } if (opt->not_dynamic > 0) { PUseDynamicColors = 0; } else if (opt->not_dynamic == 0) { PUseDynamicColors = 0; } if (opt->allocate > 0) { PAllocTable = 1; } else if (opt->allocate == 0) { PAllocTable = 0; } } if (color_limit <= 0) { use_default = 1; color_limit = nbr_of_color; } /* first try to see if we have a "pre-allocated" color cube. * The bultin RENDER X extension pre-allocate a color cube plus * some grey's (xc/programs/Xserver/render/miindex) * See gdk/gdkrgb.c for the cubes used by gtk+-2, 666 is the default, * 555 is the minimal cc (this may change): if gtk cannot allocate * the 555 cc (or better) a private cmap is used. * for qt-3: see src/kernel/{qapplication.cpp,qimage.cpp,qcolor_x11.c} * the 666 cube is used by default (with approx in the cmap if some * color allocation fail), and some qt app may accept an * --ncols option to limit the nbr of colors, then some "2:3:1" * proportions color cube are used (222, 232, ..., 252, 342, ..., 362, * 452, ...,693, ...) * imlib2 try to allocate the 666 cube if this fail it try more * exotic table (see rend.c and rgba.c) */ i = 0; free_colors = 0; if (Pdepth <= 8 && !private_cmap && use_default && i < cc_nbr && Pct == NULL && (Pvisual->class & 1)) { free_colors = get_nbr_of_free_colors(nbr_of_color); } while(Pdepth <= 8 && !private_cmap && use_default && i < cc_nbr && Pct == NULL && (Pvisual->class & 1)) { size = cc[i][0]*cc[i][1]*cc[i][2] + cc[i][3] - 2*(cc[i][3] > 0) + (1 << cc[i][4])*(cc[i][4] != 0); if (size > nbr_of_color || !(cc[i][5] & pa_type)) { i++; continue; } if (free_colors <= nbr_of_color - size) { Pct = alloc_color_cube( cc[i][0], cc[i][1], cc[i][2], cc[i][3], cc[i][4], True); } if (Pct != NULL) { if (free_colors <= get_nbr_of_free_colors(nbr_of_color)) { /* done */ } else { free_table_colors(Pct, PColorLimit); free(Pct); Pct = NULL; } } i++; } if (Pct != NULL) { PUseDynamicColors = 0; PAllocTable = 1; Pcsi.pre_allocated_pallet = 1; i = i - 1; finish_ct_init( call_type, i, cc[i][0], cc[i][1], cc[i][2], cc[i][3], cc[i][4], 0); return PColorLimit; } /* * now use "our" table */ limit = (color_limit >= nbr_of_color)? nbr_of_color:color_limit; if (use_default && !private_cmap) { /* XRender cvs default: */ #if 0 if (limit > 100) limit = nbr_of_color/3; else limit = nbr_of_color/2; /* depth 8: 85 */ /* depth 4: 8 */ #endif if (limit > 256) { /* direct colors & Pdepth > 8 */ if (Pdepth >= 16) { limit = 8192; } else if (Pdepth >= 15) { limit = 4096; } else { limit = 512; } } else if (limit == 256) { if (Pvisual->class == GrayScale) { limit = 64; } else if (Pvisual->class == DirectColor) { limit = 32; } else { limit = 68; /* candidate: * limit = 54; 4x4x3 + 6 grey * limit = 61 (named table) * limit = 85 current XRender default 4cc + 21 * limit = 76 future(?) XRender default 4cc + 16 * limit = 68 4x4x4 + 4 * limit = 64 4x4x4 + 0 */ } } else if (limit == 128 || limit == 64) { if (Pvisual->class == GrayScale) { limit = 32; } else { limit = 31; } } else if (limit >= 16) { if (Pvisual->class == GrayScale) { limit = 8; } else { limit = 10; } } else if (limit >= 8) { limit = 4; } else { limit = 2; } } if (limit < 2) { limit = 2; } if (Pvisual->class == DirectColor) { /* humm ... Any way this case should never happen in real life: * DirectColor default colormap! */ PUseDynamicColors = 0; PAllocTable = 1; PStrictColorLimit = 1; } if (PAllocTable) { do_allocate = 1; } else { do_allocate = 0; } /* use the named table ? */ if (use_named_table) { i = limit; while(Pct == NULL && i >= 2) { Pct = alloc_named_ct(&i, do_allocate); i--; } } if (Pct != NULL) { finish_ct_init( call_type, PColorLimit, 0, 0, 0, 0, 0, 1); return PColorLimit; } /* color cube or regular grey scale */ i = 0; while(i < cc_nbr && Pct == NULL) { if ((cc[i][5] & fvwm_type) && cc[i][0]*cc[i][1]*cc[i][2] + cc[i][3] - 2*(cc[i][3] > 0) + (1 << cc[i][4])*(cc[i][4] != 0) <= limit) { Pct = alloc_color_cube( cc[i][0], cc[i][1], cc[i][2], cc[i][3], cc[i][4], do_allocate); } i++; } if (Pct != NULL) { i = i-1; finish_ct_init( call_type, i, cc[i][0], cc[i][1], cc[i][2], cc[i][3], cc[i][4], 0); return PColorLimit; } /* I do not think we can be here */ Pct = alloc_color_cube(0, 0, 0, 0, 1, False); finish_ct_init(call_type, cc_nbr-1, 0, 0, 0, 0, 1, 0); if (Pct == NULL) { fprintf(stderr, "[fvwm] ERR -- Cannot get Black and White. exiting!\n"); exit(2); } return PColorLimit; } /* * Allocation of a private DirectColor cmap this is broken for depth > 16 */ static Bool alloc_direct_colors(int *limit, Bool use_my_color_limit) { unsigned long nr,ng,nb,r,g,b,cr,cg,cf,pr,pg; unsigned long red_mask, green_mask, blue_mask; XColor *colors; if (Pdepth <= 16) { red_mask = Pvisual->red_mask; green_mask = Pvisual->green_mask; blue_mask = Pvisual->blue_mask; } else { /* Use a standard depth 16 colormap. This is broken FIXME! */ red_mask = 0xf800; green_mask = 0x7e0; blue_mask = 0x1f; } decompose_mask( red_mask, &Pcsi.red_shift, &Pcsi.red_prec); decompose_mask( green_mask, &Pcsi.green_shift, &Pcsi.green_prec); decompose_mask( blue_mask, &Pcsi.blue_shift, &Pcsi.blue_prec); if (!use_my_color_limit) { /* colors allocated by fvwm we can return */ return 1; } nr = 1 << Pcsi.red_prec; ng = 1 << Pcsi.green_prec; nb = 1 << Pcsi.blue_prec; colors = (XColor *)safemalloc(nb*sizeof(XColor)); cf = DoRed|DoBlue|DoGreen; for (r=0; r> (16 - Pcsi.red_prec)) << Pcsi.red_shift; for (g = 0; g < ng; g++) { cg = g * 65535 / (ng - 1); pg = (cg >> (16 - Pcsi.green_prec)) << Pcsi.green_shift; for (b = 0; b < nb; b++) { colors[b].flags = cf; colors[b].red = cr; colors[b].green = cg; colors[b].blue = b * 65535 / (nb - 1); colors[b].pixel = (Pixel)(pr + pg + ((colors[b].blue >> (16 - Pcsi.blue_prec)) << Pcsi.blue_shift)); } XStoreColors(Pdpy, Pcmap, colors, nb); } } free(colors); return 1; } /* * Init the table for Static Colors */ static void init_static_colors_table(void) { XColor colors[256]; int i; int nbr_of_colors = min(256, (1 << Pdepth)); PColorLimit = nbr_of_colors; Pct = (PColor *)safemalloc((nbr_of_colors+1) * sizeof(PColor)); for (i = 0; i < nbr_of_colors; i++) { colors[i].pixel = Pct[i].color.pixel = i; } XQueryColors(Pdpy, Pcmap, colors, nbr_of_colors); for (i = 0; i < nbr_of_colors; i++) { Pct[i].color.red = colors[i].red; Pct[i].color.green = colors[i].green; Pct[i].color.blue = colors[i].blue; Pct[i].alloc_count = 1; } Pct[PColorLimit].color.red = Pct[PColorLimit-1].color.red; Pct[PColorLimit].color.green = Pct[PColorLimit-1].color.green; Pct[PColorLimit].color.blue = Pct[PColorLimit-1].color.blue; Pct[PColorLimit].alloc_count = 1; create_mapping_table(0, 0, 0, 0, 0, True); } /* * misc local functions */ static void print_colormap(Colormap cmap) { XColor colors[256]; int i; int nbr_of_colors = max(256, (1 << Pdepth)); for (i = 0; i < nbr_of_colors; i++) { colors[i].pixel = i; } XQueryColors(Pdpy, cmap, colors, nbr_of_colors); for (i = 0; i < nbr_of_colors; i++) { fprintf(stderr," rgb(%.3i): %.3i/%.3i/%.3i\n", i, colors[i].red >> 8, colors[i].green >> 8, colors[i].blue >> 8); } } /* ---------------------------- interface functions ------------------------ */ int PictureAllocColor(Display *dpy, Colormap cmap, XColor *c, int no_limit) { if (PStrictColorLimit && Pct != NULL) { no_limit = 0; } if (no_limit) { return Pcsi.alloc_color_no_limit(dpy, cmap, c); } else { return Pcsi.alloc_color(dpy, cmap, c); } return 0; } int PictureAllocColorAllProp( Display *dpy, Colormap cmap, XColor *c, int x, int y, Bool no_limit, Bool is_8, Bool do_dither) { if (!no_limit && do_dither && Pcsi.alloc_color_dither != NULL) { if (!is_8) { c->red = c->red >> 8; c->green = c->green >> 8; c->blue = c->blue >> 8; } return Pcsi.alloc_color_dither(dpy, cmap, c, x, y); } else { if (is_8) { c->red = c->red << 8; c->green = c->green << 8; c->blue = c->blue << 8; } return PictureAllocColor(dpy, cmap, c, False); } return 0; } int PictureAllocColorImage( Display *dpy, PictureImageColorAllocator *pica, XColor *c, int x, int y) { int r; r = PictureAllocColorAllProp( dpy, pica->cmap, c, x, y, pica->no_limit, pica->is_8, pica->dither); if (r && pica->pixels_table != NULL && pica->pixels_table_size && c->pixel < pica->pixels_table_size) { pica->pixels_table[c->pixel]++; } return r; } PictureImageColorAllocator *PictureOpenImageColorAllocator( Display *dpy, Colormap cmap, int x, int y, Bool no_limit, Bool do_not_save_pixels, int dither, Bool is_8) { PictureImageColorAllocator *pica; Bool do_save_pixels = False; pica = (PictureImageColorAllocator *)safemalloc( sizeof(PictureImageColorAllocator)); if (Pdepth <= 8 && !do_not_save_pixels && (Pvisual->class & 1) && ((PUseDynamicColors && Pct) || no_limit)) { int s = 1 << Pdepth; pica->pixels_table = (unsigned long *)safecalloc( s, sizeof(unsigned long)); pica->pixels_table_size = s; do_save_pixels = True; } if (!do_save_pixels) { pica->pixels_table = NULL; pica->pixels_table_size = 0; } pica->is_8 = is_8; if (dither && Pdepth <= 16) { pica->dither = dither; } else { pica->dither = dither; } pica->no_limit = no_limit; pica->cmap = cmap; return pica; } void PictureCloseImageColorAllocator( Display *dpy, PictureImageColorAllocator *pica, int *nalloc_pixels, Pixel **alloc_pixels, Bool *no_limit) { if (nalloc_pixels) { *nalloc_pixels = 0; } if (alloc_pixels != NULL) { *alloc_pixels = NULL; } if (no_limit != NULL) { *no_limit = 0; } if (pica->pixels_table) { int i,j; int k = 0, l = 0; unsigned int np = 0; int free_num = 0; Pixel *free_pixels = NULL; Pixel *save_pixels = NULL; for(i = 0; i < pica->pixels_table_size; i++) { if (pica->pixels_table[i]) { free_num += (pica->pixels_table[i]-1); np++; } } if (free_num) { free_pixels = (Pixel *)safemalloc( free_num * sizeof(Pixel)); } if (np && nalloc_pixels != NULL && alloc_pixels != NULL) { save_pixels = (Pixel *)safemalloc(np * sizeof(Pixel)); } for(i = 0; i < pica->pixels_table_size; i++) { if (pica->pixels_table[i]) { if (save_pixels) { save_pixels[k++] = i; } for(j=1; j < pica->pixels_table[i]; j++) { free_pixels[l++] = i; } } } if (free_num) { PictureFreeColors( dpy, pica->cmap, free_pixels, free_num, 0, pica->no_limit); free(free_pixels); } if (nalloc_pixels != NULL && alloc_pixels != NULL) { *nalloc_pixels = np; *alloc_pixels = save_pixels; if (no_limit != NULL) { *no_limit = pica->no_limit; } } else if (save_pixels) { free(save_pixels); } free(pica->pixels_table); } free(pica); return; } void PictureFreeColors( Display *dpy, Colormap cmap, Pixel *pixels, int n, unsigned long planes, Bool no_limit) { if (no_limit) { if (Pcsi.free_colors_no_limit != NULL) { Pcsi.free_colors_no_limit( dpy, cmap, pixels, n, planes); } } else { if (Pcsi.free_colors != NULL) { Pcsi.free_colors(dpy, cmap, pixels, n, planes); } } return; } Pixel PictureGetNextColor(Pixel p, int n) { int i; XColor c; if (n >= 0) n = 1; else n = -1; if (Pct == NULL) { return p; } for(i=0; i 0) { c = Pct[0].color; alloc_color_in_pct(&c, 0); return Pct[0].color.pixel; } else { c = Pct[i+n].color; alloc_color_in_pct(&c, i+n); return Pct[i+n].color.pixel; } } } return p; } /* Replace the color in my_color by the closest matching color from base_table */ void PictureReduceColorName(char **my_color) { int index; XColor rgb; /* place to calc rgb for each color in xpm */ if (!XpmSupport) return; if (!strcasecmp(*my_color,"none")) { return; /* do not substitute the "none" color */ } if (!XParseColor(Pdpy, Pcmap, *my_color, &rgb)) { fprintf(stderr,"color_to_rgb: can't parse color %s\n", *my_color); } index = get_color_index(rgb.red,rgb.green,rgb.blue, False); /* Finally: replace the color string by the newly determined color * string */ free(*my_color); /* free old color */ /* area for new color */ *my_color = safemalloc(8); sprintf(*my_color,"#%x%x%x", Pct[index].color.red >> 8, Pct[index].color.green >> 8, Pct[index].color.blue >> 8); /* put it there */ return; } Bool PictureDitherByDefault(void) { if (Pct != NULL) { return True; } return False; } Bool PictureUseBWOnly(void) { if (Pdepth < 2 || (PStrictColorLimit && PColorLimit == 2)) { return True; } return False; } int PictureInitColors( int call_type, Bool init_color_limit, PictureColorLimitOption *opt, Bool use_my_color_limit, Bool init_dither) { Bool dither_ok = False; switch (Pvisual->class) { case DirectColor: /* direct colors is more or less broken */ decompose_mask( Pvisual->red_mask, &Pcsi.red_shift, &Pcsi.red_prec); decompose_mask( Pvisual->green_mask, &Pcsi.green_shift, &Pcsi.green_prec); decompose_mask( Pvisual->blue_mask, &Pcsi.blue_shift, &Pcsi.blue_prec); Pcsi.alloc_color_no_limit = alloc_color_proportion; Pcsi.alloc_color = alloc_color_proportion; Pcsi.alloc_color_dither = alloc_color_proportion_dither; Pcsi.free_colors_no_limit = NULL; Pcsi.free_colors = NULL; PColorLimit = 0; break; case TrueColor: decompose_mask( Pvisual->red_mask, &Pcsi.red_shift, &Pcsi.red_prec); decompose_mask( Pvisual->green_mask, &Pcsi.green_shift, &Pcsi.green_prec); decompose_mask( Pvisual->blue_mask, &Pcsi.blue_shift, &Pcsi.blue_prec); Pcsi.alloc_color_no_limit = alloc_color_proportion; Pcsi.alloc_color = alloc_color_proportion; Pcsi.free_colors_no_limit = NULL; Pcsi.free_colors = NULL; PColorLimit = 0; if (init_dither && (Pdepth == 15 || Pdepth == 16)) { dither_ok = my_dither_depth_15_16_init(); } if (dither_ok) { Pcsi.alloc_color_dither = alloc_color_proportion_dither; } else { Pcsi.alloc_color_dither = NULL; } break; case StaticColor: if (0 && Pvisual->red_mask != 0 && Pvisual->green_mask != 0 && Pvisual->blue_mask != 0) { decompose_mask( Pvisual->red_mask, &Pcsi.red_shift, &Pcsi.red_prec); decompose_mask( Pvisual->green_mask, &Pcsi.green_shift, &Pcsi.green_prec); decompose_mask( Pvisual->blue_mask, &Pcsi.blue_shift, &Pcsi.blue_prec); Pcsi.alloc_color_no_limit = alloc_color_proportion; Pcsi.alloc_color = alloc_color_proportion; PColorLimit = 0; } else { if (init_color_limit) { Pcsi.alloc_color = alloc_color_in_table; Pcsi.alloc_color_dither = alloc_color_in_table_dither; Pcsi.alloc_color_no_limit = alloc_color_x; init_static_colors_table(); } else { Pcsi.alloc_color = alloc_color_x; Pcsi.alloc_color_dither = NULL; Pcsi.alloc_color_no_limit = alloc_color_x; } } Pcsi.free_colors_no_limit = NULL; Pcsi.free_colors = NULL; break; case StaticGray: /* FIXME: we assume that we have a regular grey ramp */ if (0) { Pcsi.alloc_color_no_limit = alloc_color_proportion_grey; Pcsi.alloc_color = alloc_color_proportion; PColorLimit = 0; } else { if (init_color_limit) { Pcsi.alloc_color = alloc_color_in_table; Pcsi.alloc_color_dither = alloc_color_in_table_dither; Pcsi.alloc_color_no_limit = alloc_color_x; init_static_colors_table(); } else { Pcsi.alloc_color = alloc_color_x; Pcsi.alloc_color_dither = NULL; Pcsi.alloc_color_no_limit = alloc_color_x; } } Pcsi.free_colors_no_limit = NULL; Pcsi.free_colors = NULL; break; case PseudoColor: case GrayScale: default: Pcsi.alloc_color_no_limit = alloc_color_dynamic_no_limit; Pcsi.free_colors_no_limit = free_colors_x; break; } if (!(Pvisual->class & 1)) { /* static classes */ PUseDynamicColors = 0; if (call_type == PICTURE_CALLED_BY_FVWM && getenv("FVWM_COLORTABLE_TYPE") != NULL) { flib_putenv("FVWM_COLORTABLE_TYPE", ""); } return PColorLimit; } /* dynamic classes */ if (!Pdefault && Pvisual->class == DirectColor) { PColorLimit = 0; PUseDynamicColors = 0; alloc_direct_colors(0, use_my_color_limit); if (call_type == PICTURE_CALLED_BY_FVWM && getenv("FVWM_COLORTABLE_TYPE") != NULL) { flib_putenv("FVWM_COLORTABLE_TYPE", ""); } return 0; } if (init_color_limit) { Pcsi.alloc_color = alloc_color_in_table; Pcsi.alloc_color_dither = alloc_color_in_table_dither; PictureAllocColorTable(opt, call_type, use_my_color_limit); if (PUseDynamicColors) { Pcsi.free_colors = free_colors_in_table; } else { Pcsi.free_colors = NULL; } } else { Pcsi.alloc_color = alloc_color_dynamic_no_limit; Pcsi.free_colors = free_colors_x; Pcsi.alloc_color_dither = NULL; } return PColorLimit; } void PicturePrintColorInfo(int verbose) { unsigned long nbr_of_colors = 1 << Pdepth; fprintf(stderr, "fvwm info on colors\n"); fprintf(stderr, " Visual ID: 0x%x, Default?: %s, Class: ", (int)(Pvisual->visualid), (Pdefault)? "Yes":"No"); if (Pvisual->class == TrueColor) { fprintf(stderr,"TrueColor"); } else if (Pvisual->class == PseudoColor) { fprintf(stderr,"PseudoColor"); } else if (Pvisual->class == DirectColor) { fprintf(stderr,"DirectColor"); } else if (Pvisual->class == StaticColor) { fprintf(stderr,"StaticColor"); } else if (Pvisual->class == GrayScale) { fprintf(stderr,"GrayScale"); } else if (Pvisual->class == StaticGray) { fprintf(stderr,"StaticGray"); } fprintf(stderr, "\n"); fprintf(stderr, " Depth: %i, Number of colors: %lu", Pdepth, (unsigned long)nbr_of_colors); if (Pct != NULL) { fprintf(stderr,"\n Pallet with %i colors", PColorLimit); if (Pvisual->class & 1) { fprintf(stderr,", Number of free colors: %i\n", get_nbr_of_free_colors((1 << Pdepth))); fprintf(stderr, " Auto Detected: %s, Strict: %s, Allocated: %s," " Dynamic: %s\n", (Pcsi.pre_allocated_pallet)? "Yes":"No", (PStrictColorLimit)? "Yes":"No", (PAllocTable)? "Yes":"No", (PUseDynamicColors)? "Yes":"No"); } else { fprintf(stderr," (default colormap)\n"); } if (PColorLimit <= 256) { int i; int count = 0; int count_alloc = 0; if (verbose) { fprintf(stderr," The fvwm colors table:\n"); } for (i = 0; i < PColorLimit; i++) { if (verbose) { fprintf( stderr, " rgb:%.3i/%.3i/%.3i\t%lu\n", Pct[i].color.red >> 8, Pct[i].color.green >> 8, Pct[i].color.blue >> 8, Pct[i].alloc_count); } if (Pct[i].alloc_count) { count++; } } if ((Pvisual->class & 1) && Pac != NULL) { if (verbose) { fprintf(stderr," fvwm colors not in" " the table:\n"); } for(i=0; i < nbr_of_colors; i++) { int j = 0; Bool found = False; if (!Pac[i].alloc_count) continue; while(j < PColorLimit && !found) { if (i == Pct[j].color.pixel) { found = True; } j++; } if (found) continue; count_alloc++; if (verbose) { fprintf( stderr, " rgb:" "%.3i/%.3i/%.3i\t%lu\n", Pac[i].color.red >> 8, Pac[i].color.green >> 8, Pac[i].color.blue >> 8, Pac[i].alloc_count); } } if (verbose && count_alloc == 0) { if (verbose) { fprintf(stderr," None\n"); } } } if (Pvisual->class & 1) { fprintf(stderr, " Number of colours used by fvwm:\n"); fprintf(stderr, " In the table: %i\n", count); fprintf( stderr, " Out of the table: %i\n", count_alloc); fprintf(stderr, " Total: %i\n", count_alloc+count); } } } else { if (Pvisual->class == DirectColor) { fprintf(stderr, ", Pseudo Pallet with: %i colors\n", (1 << Pcsi.red_prec)*(1 << Pcsi.green_prec)* (1 << Pcsi.blue_prec)); } else { fprintf(stderr, ", No Pallet (static colors)\n"); } fprintf(stderr, " red: %i, green: %i, blue %i\n", 1 << Pcsi.red_prec, 1 << Pcsi.green_prec, 1 << Pcsi.blue_prec); if (verbose && Pdepth <= 8) { if (Pvisual->class == DirectColor) { fprintf(stderr, " Colormap:\n"); } else { fprintf(stderr, " Static Colormap used by fvwm:\n"); } print_colormap(Pcmap); } } if (Pdepth <= 8 && verbose >= 2) { fprintf(stderr,"\n Default Colormap:\n"); print_colormap(DefaultColormap(Pdpy,DefaultScreen(Pdpy))); } } fvwm-2.6.7/libs/FlocaleCharset.c0000644000175700017570000005732313001406607013427 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "Strings.h" #include "Parse.h" #include "Flocale.h" #include "FlocaleCharset.h" #include "Ficonv.h" #if FlocaleLibcharsetSupport #include #endif #if FlocaleCodesetSupport #include #endif /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* X locale charset */ static FlocaleCharset *FLCXOMCharset = NULL; /* list of XOM locale charset */ static FlocaleCharset **FLCXOMCharsetList = NULL; static int FLCXOMCharsetList_num = 0; /* UTF-8 charset */ static FlocaleCharset *FLCUtf8Charset = NULL; /* locale charset from the locale not X */ static FlocaleCharset *FLCLocaleCharset = NULL; static char *nullsl[] = {NULL}; #if FiconvSupport /* from hpux iconv man page: The fromcode and tocode names can be any length, * but only the first four and the last letter are used to identify the code * set. */ /* the first name is the gnu canonical name */ char *armscii_8[] = {"ARMSCII-8", NULL}; char *big5_0[] = {"BIG5", "big5", /* aix, hpux, osf */ "zh_TW-big5", /* solaris 9? */ NULL}; char *big5hkscs_0[] = {"BIG5-HKSCS", "BIG5", "big5", /* aix, hpux, osf */ "zh_TW-big5", /* solaris 9? */ NULL}; char *cns11643[] = {"EUCTW", "EUC-TW", "eucTW", "euc-tw", "euctw", NULL}; char *dosencoding_cp437[] = {"CP437", NULL}; char *dosencoding_cp850[] = {"CP850", "cp850", /* osf */ "IBM-850", /* aix */ NULL}; char *gb2312_1980_0[] = {"EUC-CN", "GB2312", "gb2312", /* solaris */ "dechanzi", /* osf */ "hp15CN", /* hpux */ "IBM-eucCN", /* aix */ "eucCN", /* irix */ NULL}; char *gbk_0[] = {"GBK", NULL}; char *georgian_academy[] = {"GEORGIAN-ACADEMY", NULL}; char *georgian_ps[] = {"GEORGIAN-PS", NULL}; char *ibm_cp1133[] = {"CP850" , NULL}; char *isiri_3342[] = {"ISIRI-3342", NULL}; /* embed ascii into ISO-8859-1*/ char *iso8859_1[] = {"ISO-8859-1", /* gnu */ "ISO8859-1", /* aix, irix, osf, solaris */ "iso8859-1", /* aix, irix, osf */ "iso88591", /* hpux */ "8859-1", /* solaris ? */ "iso81", /* hpux */ "ascii", "ASCII", "646", /* solaris */ "ANSI_X3.4-1968", "ISO_646.IRV:1983", /* old glibc */ "american_e", NULL}; char *iso8859_2[] = {"ISO-8859-2", "ISO8859-2", "iso8859-2", "iso88592", "8859-2", "iso82", NULL}; char *iso8859_3[] = {"ISO-8859-3", "ISO8859-3", "iso8859-3", "iso88593", "8859-3", "iso83", NULL}; char *iso8859_4[] = {"ISO-8859-4", "ISO8859-4", "iso8859-4", "iso88594", "8859-4", "iso84", NULL}; char *iso8859_5[] = {"ISO-8859-5", "ISO8859-5", "iso8859-5", "iso88595", "8859-5", "iso85", NULL}; char *iso8859_6[] = {"ISO-8859-6", "ISO8859-6", "iso8859-6", "iso88596", "8859-6", "iso86", NULL}; char *iso8859_7[] = {"ISO-8859-7", "ISO8859-7", "iso8859-7", "iso88597", "8859-7", "iso87", NULL}; char *iso8859_8[] = {"ISO-8859-8", "ISO8859-8", "iso88859-8", "iso88598", "8859-8", "iso88", NULL}; char *iso8859_9[] = {"ISO-8859-9", "ISO8859-9", "iso8859-9", "iso88599", "8859-9", "iso89", NULL}; char *iso8859_10[] = {"ISO-8859-10", "ISO8859-10", "iso8859-10", "iso885910", "8859-10", "iso80", /*?*/ "iso10", NULL}; char *iso8859_13[] = {"ISO-8859-13", "ISO8859-13", "iso8859-13", "iso885913", "8859-13", "IBM-921", /* aix */ "iso813", /*?*/ "iso13", NULL}; char *iso8859_14[] = {"ISO-8859-14", "ISO8859-14", "iso8859-14", "iso885914", "8859-14", "iso814", "iso14", NULL}; char *iso8859_15[] = {"ISO-8859-15", "ISO88859-15", "iso88859-15", "iso885915", "8859-15", "iso815", "iso15", NULL}; char *iso8859_16[] = {"ISO-8859-16", "ISO8859-16", "iso8859-16", "iso885916", "8859-16", "iso80", "iso16", NULL}; char *jisx0201_1976_0[] = {"JIS_X0201", "ISO-IR-14", "jis", /* hpux */ NULL}; char *jisx0208_1983_0[] = {"JIS_X0208", NULL}; char *jisx0208_1990_0[] = {"JIS_X0208", NULL}; char *jisx0212_1990_0[] = {"JIS_X0212", NULL}; char *koi8_r[] = {"KOI8-R", /* gnu, solaris */ NULL}; char *koi8_u[] = {"KOI8-U", NULL}; char *ksc5601[] = {"KSC5636", "ko_KR-johap", /* solaris */ "ko_KR-johap92", "ko_KR-euc", "eucKR", "EUC-KR", "EUCKR", "euc-kr", "CP949", /* osf */ NULL}; char *microsoft_cp1251[] = {"CP1251", NULL}; char *microsoft_cp1255[] = {"CP1255", NULL}; char *microsoft_cp1256[] = {"CP1256", NULL}; char *mulelao_1[] = {"MULELAO-1", "MULELAO", NULL}; char *sjisx_1[] = {"SHIFT_JIS", "SJIS", /* solaris, osf */ "sjis", /* hpux */ "PCK", /* solaris */ NULL}; char *tatar_cyr[] = {NULL}; char *tcvn_5712[] = {"TCVN", NULL}; char *tis620_0[] = {"TIS-620", "tis620", /* hpux */ "TACTIS", /* osf */ NULL}; char *viscii1_1_1[] = {"VISCII", NULL}; /* encofing only ...*/ char *utf_8[] = {"UTF-8", /* gnu, solaris */ "UTF8", "utf8", "utf_8", NULL}; char *usc_2[] = {"USC-2", "USC2", "usc2", "usc-2", "usc_2", NULL}; char *usc_4[] = {"USC-4", "USC4", "usc4", "usc-4", "usc_4", NULL}; char *utf_16[] = {"UTF-16", "UTF16", "utf16", "utf_16", NULL}; char *euc_jp[] = {"EUC-JP", "EUCJP", "euc_jp", "euc-jp", "eucjp", NULL}; #endif #if FiconvSupport #ifdef HAVE_BIDI #define CT_ENTRY(x,y,z) \ {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, z, FLC_ENCODING_TYPE_FONT} #define CT_ENTRY_WET(x,y,z,t) \ {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, z, t} #else #define CT_ENTRY(x,y,z) \ {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, NULL, FLC_ENCODING_TYPE_FONT} #define CT_ENTRY_WET(x,y,z,t) \ {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, NULL, t} #endif #else /* !FlocaleIconvSupport */ #ifdef HAVE_BIDI #define CT_ENTRY(x,y,z) \ {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, z, FLC_ENCODING_TYPE_FONT} #define CT_ENTRY_WET(x,y,z,t) \ {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, z, t} #else #define CT_ENTRY(x,y,z) \ {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, NULL, FLC_ENCODING_TYPE_FONT} #define CT_ENTRY_WET(x,y,z,t) \ {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, NULL, t} #endif #endif static FlocaleCharset UnknownCharset = {"Unknown", nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, NULL}; /* the table contains all Xorg "charset" plus some others */ FlocaleCharset FlocaleCharsetTable[] = { CT_ENTRY("ARMSCII-8", armscii_8, NULL), CT_ENTRY("BIG5-0", big5_0, NULL), CT_ENTRY("BIG5HKSCS-0", big5hkscs_0, NULL), CT_ENTRY("CNS11643.1986-1", cns11643, NULL), CT_ENTRY("CNS11643.1986-2", cns11643, NULL), CT_ENTRY("CNS11643.1992-3", cns11643, NULL), CT_ENTRY("CNS11643.1992-4", cns11643, NULL), CT_ENTRY("CNS11643.1992-5", cns11643, NULL), CT_ENTRY("CNS11643.1992-6", cns11643, NULL), CT_ENTRY("CNS11643.1992-7", cns11643, NULL), CT_ENTRY("DOSENCODING-CP437", dosencoding_cp437, NULL), CT_ENTRY("DOSENCODING-CP850", dosencoding_cp850, NULL), CT_ENTRY("EUC-JP", euc_jp, NULL), CT_ENTRY("GB2312.1980-0", gb2312_1980_0, NULL), CT_ENTRY("GBK-0", gbk_0, NULL), CT_ENTRY("GEORGIAN-ACADEMY", georgian_academy, NULL), CT_ENTRY("GEORGIAN-PS", georgian_ps, NULL), CT_ENTRY("IBM-CP1133", ibm_cp1133, NULL), CT_ENTRY("ISIRI-3342", isiri_3342, "ISIRI-3342"), /* exception ISO10646-1 implies UTF-8 and not USC-2 ! */ CT_ENTRY_WET("ISO10646-1", utf_8, "UTF-8", FLC_ENCODING_TYPE_UTF_8), CT_ENTRY("ISO8859-1", iso8859_1, NULL), CT_ENTRY("ISO8859-2", iso8859_2, NULL), CT_ENTRY("ISO8859-3", iso8859_3, NULL), CT_ENTRY("ISO8859-4", iso8859_4, NULL), CT_ENTRY("ISO8859-5", iso8859_5, NULL), CT_ENTRY("ISO8859-6", iso8859_6, "ISO8859-6"), CT_ENTRY("ISO8859-6.8X", iso8859_6, "ISO8859-6"), CT_ENTRY("ISO8859-7", iso8859_7, NULL), CT_ENTRY("ISO8859-8", iso8859_8, "ISO8859-8"), CT_ENTRY("ISO8859-9", iso8859_9, NULL), CT_ENTRY("ISO8859-9E", iso8859_9, NULL), CT_ENTRY("ISO8859-10", iso8859_10, NULL), CT_ENTRY("ISO8859-13", iso8859_13, NULL), CT_ENTRY("ISO8859-14", iso8859_14, NULL), CT_ENTRY("ISO8859-15", iso8859_15, NULL), CT_ENTRY("ISO8859-16", iso8859_16, NULL), CT_ENTRY("JISX.UDC-1", jisx0201_1976_0, NULL), /* ? */ CT_ENTRY("JISX0201.1976-0", jisx0201_1976_0, NULL), CT_ENTRY("JISX0208.1983-0", jisx0208_1983_0, NULL), CT_ENTRY("JISX0208.1990-0", jisx0208_1990_0, NULL), CT_ENTRY("JISX0212.1990-0", jisx0212_1990_0, NULL), CT_ENTRY("KOI8-C", koi8_r, NULL), CT_ENTRY("KOI8-R", koi8_r, NULL), CT_ENTRY("KOI8-U", koi8_u, NULL), CT_ENTRY("KSC5601.1987-0", ksc5601, NULL), CT_ENTRY("KSC5601.1992-0", ksc5601, NULL), CT_ENTRY("MICROSOFT-CP1251", microsoft_cp1251, NULL), CT_ENTRY("MICROSOFT-CP1255", microsoft_cp1255, "CP1255"), CT_ENTRY("MICROSOFT-CP1256", microsoft_cp1256, "CP1256"), CT_ENTRY("MULELAO-1", mulelao_1, NULL), CT_ENTRY("SJISX-1", sjisx_1, NULL), CT_ENTRY("TATAR-CYR", tatar_cyr, NULL), CT_ENTRY("TCVN-5712", tcvn_5712, NULL), CT_ENTRY("TIS620-0", tis620_0, NULL), CT_ENTRY("VISCII1.1-1", viscii1_1_1, NULL), /* aliases */ /* CT_ENTRY("ADOBE-STANDARD", iso8859_1, NULL), no! */ CT_ENTRY("ASCII-0", iso8859_1, NULL), CT_ENTRY("BIBIG5HKSCS", big5_0, NULL), /* ? */ CT_ENTRY("BIG5-E0", big5_0, NULL), /* emacs */ CT_ENTRY("BIG5-E1", big5_0, NULL), /* emacs */ CT_ENTRY("BIG5-1", big5_0, NULL), CT_ENTRY("ISO646.1991-IRV", iso8859_1, NULL), CT_ENTRY("TIS620.2533-1", tis620_0, NULL), CT_ENTRY_WET("UTF-8", utf_8, "UTF-8", FLC_ENCODING_TYPE_UTF_8), CT_ENTRY_WET("USC-2", usc_2, "USC-2", FLC_ENCODING_TYPE_USC_2), CT_ENTRY_WET("USC-4", usc_4, NULL, FLC_ENCODING_TYPE_USC_4), CT_ENTRY_WET("UTF-16", utf_16, NULL, FLC_ENCODING_TYPE_UTF_16), CT_ENTRY(NULL, nullsl, NULL) }; /* to be supported: ADOBE-STANDARD, some Xft1 charset */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static FlocaleCharset *FlocaleCharsetOfXCharset(char *x) { int j = 0; while(FlocaleCharsetTable[j].x != NULL) { if (StrEquals(x,FlocaleCharsetTable[j].x)) { return &FlocaleCharsetTable[j]; } j++; } return NULL; } static FlocaleCharset *FlocaleCharsetOfLocaleCharset(char *l) { int j = 0, i = 0; while(FlocaleCharsetTable[j].x != NULL) { if (StrEquals(l, FlocaleCharsetTable[j].x)) { return &FlocaleCharsetTable[j]; } i = 0; while(FlocaleCharsetTable[j].locale[i] != NULL) { if (StrEquals(l, FlocaleCharsetTable[j].locale[i])) { return &FlocaleCharsetTable[j]; } i++; } j++; } return NULL; } static FlocaleCharset *FlocaleCharsetOfFontStruct(Display *dpy, XFontStruct *fs) { unsigned long value = 0; char *name,*tmp; FlocaleCharset *fc; int count = 0; if (fs == NULL) return NULL; if (!XGetFontProperty(fs, XA_FONT, &value)) { return NULL; } if ((name = XGetAtomName(dpy, value)) == NULL) { return NULL; } tmp = name; while (*tmp != '\0' && count < 13) { if (*tmp == '-') { count++; } tmp++; if (count == 13) { fc = FlocaleCharsetOfXCharset(tmp); XFree(name); return fc; } } XFree(name); return NULL; } static void FlocaleInit_X_Charset(Display *dpy, const char *module) { #ifdef HAVE_XOUTPUT_METHOD XOM om; XOMCharSetList cs; int i; om = XOpenOM(dpy, NULL, NULL, NULL); if (om && XGetOMValues(om, XNRequiredCharSet, &cs, NULL) == NULL) { if (cs.charset_count > 0) { if (FLCXOMCharsetList != NULL) { free(FLCXOMCharsetList); } FLCXOMCharsetList_num = cs.charset_count; FLCXOMCharsetList = (FlocaleCharset **)safemalloc( sizeof(FlocaleCharset) * cs.charset_count); for (i = 0; i < FLCXOMCharsetList_num; i++) { FLCXOMCharsetList[i] = FlocaleCharsetOfXCharset( cs.charset_list[i]); #if FLOCALE_DEBUG_CHARSET fprintf(stderr, "[FlocaleInitCharset] XOM charset " "%i: %s, bidi:%s\n", i, FLC_DEBUG_GET_X_CHARSET( FLCXOMCharsetList[i]), FLC_DEBUG_GET_BIDI_CHARSET ( FLCXOMCharsetList[i])); #endif } } } if (om) { XCloseOM(om); } if (FLCXOMCharsetList_num > 0 && FLCXOMCharsetList[0]) { char *best_charset; if (FLCLocaleCharset != NULL) { best_charset = FLCLocaleCharset->x; #if FLOCALE_DEBUG_CHARSET fprintf(stderr, "[FlocaleInitCharset] FLCLocaleCharset: %s\n", best_charset); #endif } else { best_charset = FLOCALE_FALLBACK_XCHARSET; #if FLOCALE_DEBUG_CHARSET fprintf(stderr, "[FlocaleInitCharset] FALLBACK: %s\n", best_charset); #endif } FLCXOMCharset = FLCXOMCharsetList[0]; if (best_charset == NULL) { /* should not happen */ } else { for(i = 0; i < FLCXOMCharsetList_num; i++) { if (StrEquals( best_charset, FLC_DEBUG_GET_X_CHARSET( FLCXOMCharsetList[i]))) { FLCXOMCharset = FLCXOMCharsetList[i]; break; } } } #if FLOCALE_DEBUG_CHARSET fprintf(stderr, "[FlocaleInitCharset] XOM charset " "%i: %s\n", i, FLC_DEBUG_GET_X_CHARSET(FLCXOMCharset)); #endif } #endif } /* ---------------------------- interface functions ------------------------ */ void FlocaleCharsetInit(Display *dpy, const char *module) { static Bool initialized = False; char *charset; if (initialized == True) { return; } initialized = True; /* try to find the regular charset */ charset = getenv("CHARSET"); #if FLOCALE_DEBUG_CHARSET fprintf(stderr, "[FlocaleInitCharset] CHARSET: %s\n", (!charset)? "null":charset); #endif if ((!charset || strlen(charset) < 3) && FlocaleLibcharsetSupport) { charset = (char *)Flocale_charset(); #if FLOCALE_DEBUG_CHARSET fprintf( stderr, "[FlocaleInitCharset] FlocaleLibcharsetSupport: %s\n", (!charset)? "null":charset); #endif } if ((!charset || strlen(charset) < 3) && FlocaleCodesetSupport) { charset = Fnl_langinfo(FCODESET); #if FLOCALE_DEBUG_CHARSET fprintf( stderr, "[FlocaleInitCharset] Fnl_langinfo: %s\n", (!charset)? "null":charset); #endif } if (charset != NULL && strlen(charset) > 2) { FLCLocaleCharset = FlocaleCharsetOfLocaleCharset(charset); #if FLOCALE_DEBUG_CHARSET fprintf( stderr, "[FlocaleInitCharset] FLCLocaleCharset: %s\n", charset); #endif } /* set the defaults X locale charsets */ FlocaleInit_X_Charset(dpy, module); /* never null */ FLCUtf8Charset = FlocaleCharsetOfXCharset(FLOCALE_UTF8_XCHARSET); #if FLOCALE_DEBUG_CHARSET fprintf(stderr,"[FlocaleCharsetInit] locale charset: x:%s, bidi:%s\n", FLC_DEBUG_GET_X_CHARSET(FLCXOMCharset), FLC_DEBUG_GET_BIDI_CHARSET (FLCXOMCharset)); fprintf(stderr,"[FlocaleCharsetInit] locale charset: x:%s, bidi:%s\n", FLC_DEBUG_GET_X_CHARSET(FLCLocaleCharset), FLC_DEBUG_GET_BIDI_CHARSET (FLCLocaleCharset)); #endif return; } void FlocaleCharsetSetFlocaleCharset( Display *dpy, FlocaleFont *flf, char *hints, char *encoding, char *module) { char *charset = NULL; char *iconv = NULL; Bool iconv_found = False; int i = 0; FlocaleCharsetInit(dpy, module); if (hints && *hints) { iconv = GetQuotedString( hints, &charset, "/", NULL, NULL, NULL); if (charset && *charset && *charset != '*' ) { flf->fc = FlocaleCharsetOfXCharset(charset); } if (flf->fc == NULL && charset && *charset && *charset != '*') { flf->fc = FlocaleCharsetOfLocaleCharset(charset); } if (flf->fc == NULL && iconv && *iconv) { flf->fc = FlocaleCharsetOfLocaleCharset(iconv); } } if (flf->fc == NULL) { if (FftSupport && flf->fftf.fftfont != NULL) { flf->fc = FlocaleCharsetOfXCharset(flf->fftf.encoding); } else if (flf->fontset != None) { if (FLCXOMCharset != NULL) { flf->fc = FLCXOMCharset; } else { /* we are here if !HAVE_XOUTPUT_METHOD */ XFontStruct **fs_list; char **ml; if (XFontsOfFontSet( flf->fontset, &fs_list, &ml) > 0) { flf->fc = FLCXOMCharset = FlocaleCharsetOfFontStruct( dpy, fs_list[0]); } } } else if (flf->font != NULL) { flf->fc = FlocaleCharsetOfFontStruct(dpy, flf->font); } } if (flf->fc != NULL && iconv && *iconv) { /* the user has specified an iconv converter name: * check if we have it and force user choice */ while(!iconv_found && FLC_GET_LOCALE_CHARSET(flf->fc,i) != NULL) { if ( strcmp( iconv, FLC_GET_LOCALE_CHARSET(flf->fc,i)) == 0) { iconv_found = True; /* Trust the user? yes ... */ FLC_SET_ICONV_INDEX(flf->fc,i); } i++; } } if (iconv && *iconv && !iconv_found) { FlocaleCharset *fc; /* the user has specified an iconv converter name and we do not * have it: must create a FlocaleCharset */ flf->flags.must_free_fc = True; fc = (FlocaleCharset *)safemalloc(sizeof(FlocaleCharset)); if (flf->fc != NULL) { CopyString(&fc->x, flf->fc->x); fc->encoding_type = flf->fc->encoding_type; if (flf->fc->bidi) CopyString(&fc->bidi, flf->fc->bidi); else fc->bidi = NULL; } else { CopyString(&fc->x, "Unknown"); /* for simplicity */ fc->bidi = NULL; fc->encoding_type = FLC_ENCODING_TYPE_FONT; } fc->locale = (char **)safemalloc(2*sizeof(char *)); CopyString(&fc->locale[0], iconv); fc->locale[1] = NULL; fc->iconv_index = FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED; flf->fc = fc; } if (charset != NULL) { free(charset); } if (flf->fc == NULL) { flf->fc = &UnknownCharset; } /* now the string charset */ if (encoding != NULL) { flf->str_fc = FlocaleCharsetOfXCharset(encoding); if (flf->str_fc == NULL) { flf->str_fc = FlocaleCharsetOfLocaleCharset(encoding); } if (flf->str_fc == NULL) { flf->str_fc = &UnknownCharset; } } else if (FftSupport && flf->fftf.fftfont != NULL) { if (flf->fftf.str_encoding != NULL) { flf->str_fc = FlocaleCharsetOfXCharset( flf->fftf.str_encoding); if (flf->str_fc == NULL) { flf->str_fc = FlocaleCharsetOfLocaleCharset( flf->fftf.str_encoding); } if (flf->str_fc == NULL) { flf->str_fc = &UnknownCharset; } } else { flf->str_fc = FlocaleCharsetGetDefaultCharset(dpy, module); } } if (flf->str_fc == NULL) { if (flf->fc != &UnknownCharset) { flf->str_fc = flf->fc; } else { flf->str_fc = FlocaleCharsetGetDefaultCharset(dpy, module); } } } FlocaleCharset *FlocaleCharsetGetDefaultCharset(Display *dpy, char *module) { static int warn = True; FlocaleCharsetInit(dpy, module); if (FLCXOMCharset != NULL) return FLCXOMCharset; if (FLCLocaleCharset != NULL) return FLCLocaleCharset; if (warn) { warn = False; fprintf(stderr, "[%s][%s]: WARN -- Cannot find default locale " "charset with:\n\t", (module != NULL)? module:"FVWMlibs", "FlocaleGetDefaultCharset"); fprintf(stderr,"X Output Method "); fprintf(stderr,", CHARSET env variable"); if (FlocaleLibcharsetSupport) fprintf(stderr,", locale_charset"); if (FlocaleCodesetSupport) fprintf(stderr,", nl_langinfo"); fprintf(stderr,"\n"); /* never null */ FLCLocaleCharset = FlocaleCharsetOfXCharset(FLOCALE_FALLBACK_XCHARSET); fprintf(stderr,"\tUse default charset: %s\n", FLOCALE_FALLBACK_XCHARSET); } return FLCLocaleCharset; } FlocaleCharset *FlocaleCharsetGetFLCXOMCharset(void) { return FLCXOMCharset; } FlocaleCharset *FlocaleCharsetGetUtf8Charset(void) { return FLCUtf8Charset; } FlocaleCharset *FlocaleCharsetGetLocaleCharset(void) { return FLCLocaleCharset; } FlocaleCharset *FlocaleCharsetGetUnknownCharset(void) { return &UnknownCharset; } const char *FlocaleGetBidiCharset(Display *dpy, FlocaleCharset *fc) { if (fc == NULL || fc == FlocaleCharsetGetUnknownCharset() || fc->bidi == NULL) { return NULL; } return (const char *)fc->bidi; } FlocaleCharset *FlocaleCharsetGetEUCJPCharset(void) { static FlocaleCharset *fc = NULL; if (fc != NULL) return fc; /* never null */ fc = FlocaleCharsetOfXCharset("EUC-JP"); return fc; } Bool FlocaleCharsetIsCharsetXLocale(Display *dpy, char *charset, char *module) { #ifdef HAVE_XOUTPUT_METHOD int i; FlocaleCharsetInit(dpy, module); if (FLCXOMCharsetList_num > 0) { for(i = 0; i < FLCXOMCharsetList_num; i++) { if (StrEquals( FLC_DEBUG_GET_X_CHARSET( FLCXOMCharsetList[i]), charset)) { return True; } } } return False; #else return True; /* Hum */ #endif } void FlocaleCharsetPrintXOMInfo(void) { #ifdef HAVE_XOUTPUT_METHOD int i; fprintf(stderr," XOM Charsets: "); if (FLCXOMCharsetList_num > 0) { for(i = 0; i < FLCXOMCharsetList_num; i++) { fprintf( stderr, "%s ", FLC_DEBUG_GET_X_CHARSET(FLCXOMCharsetList[i])); } } fprintf(stderr,"\n"); #endif } fvwm-2.6.7/libs/Target.h0000644000175700017570000000062312773467232012012 00000000000000#ifndef LIB_TARGET_H #define LIB_TARGET_H void fvwmlib_keyboard_shortcuts( Display *dpy, int screen, XEvent *Event, int x_move_size, int y_move_size, int *x_defect, int *y_defect, int ReturnEvent); void fvwmlib_get_target_window( Display *dpy, int screen, char *MyName, Window *app_win, Bool return_subwindow); Window fvwmlib_client_window(Display *dpy, Window input); #endif /* LIB_TARGET_H */ fvwm-2.6.7/libs/wcontext.h0000644000175700017570000000366412773467232012447 00000000000000/* -*-c-*- */ #ifndef WCONTEXT_H #define WCONTEXT_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { /* contexts for button presses */ C_NO_CONTEXT = 0x00, C_WINDOW = 0x01, C_TITLE = 0x02, C_ICON = 0x04, C_ROOT = 0x08, C_MENU = 0x10, C_PLACEMENT = 0x20, C_L1 = 0x40, C_R1 = 0x80, C_L2 = 0x100, C_R2 = 0x200, C_L3 = 0x400, C_R3 = 0x800, C_L4 = 0x1000, C_R4 = 0x2000, C_L5 = 0x4000, C_R5 = 0x8000, C_UNMANAGED = 0x10000, C_EWMH_DESKTOP = 0x20000, C_F_TOPLEFT = 0x100000, C_F_TOPRIGHT = 0x200000, C_F_BOTTOMLEFT = 0x400000, C_F_BOTTOMRIGHT = 0x800000, C_SB_LEFT = 0x1000000, C_SB_RIGHT = 0x2000000, C_SB_TOP = 0x4000000, C_SB_BOTTOM = 0x8000000, /* C_ = 0x10000000, */ /* C_ = 0x20000000, */ /* C_ = 0x40000000, */ C_IGNORE_ALL = (int)0x80000000, C_FRAME = (C_F_TOPLEFT|C_F_TOPRIGHT|C_F_BOTTOMLEFT|C_F_BOTTOMRIGHT), C_SIDEBAR = (C_SB_LEFT|C_SB_RIGHT|C_SB_TOP|C_SB_BOTTOM), C_RALL = (C_R1|C_R2|C_R3|C_R4|C_R5), C_LALL = (C_L1|C_L2|C_L3|C_L4|C_L5), C_DECOR = (C_LALL|C_RALL|C_TITLE|C_FRAME|C_SIDEBAR), C_ALL = (C_WINDOW|C_TITLE|C_ICON|C_ROOT|C_FRAME|C_SIDEBAR|\ C_LALL|C_RALL|C_EWMH_DESKTOP), C_MENU_ITEM = (C_ICON|C_MENU) } win_context_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ extern charmap_t win_contexts[]; /* ---------------------------- interface functions ------------------------ */ int wcontext_string_to_wcontext(char *in_context, int *out_context_mask); char wcontext_wcontext_to_char(win_context_t wcontext); win_context_t wcontext_merge_border_wcontext(win_context_t wcontext); #endif /* WCONTEXT_H */ fvwm-2.6.7/libs/flist.h0000644000175700017570000000161512773467232011707 00000000000000/* -*-c-*- */ #ifndef FLIST_H #define FLIST_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct _flist { void *object; struct _flist *next; struct _flist *prev; } flist; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ flist *flist_append_obj(flist *list, void *object); flist *flist_prepend_obj(flist *list, void *object); flist *flist_insert_obj(flist *list, void *object, int position); flist *flist_remove_obj(flist *list, void *object); flist *flist_free_list(flist *list); #endif /* FLIST_H */ fvwm-2.6.7/libs/System.h0000644000175700017570000000123412773467232012047 00000000000000#ifndef LIB_SYSTEM_H #define LIB_SYSTEM_H fd_set_size_t GetFdWidth(void); extern fd_set_size_t fvwmlib_max_fd; void fvwmlib_init_max_fd(void); int getostype(char *buf, int max); void setPath(char **p_path, const char *newpath, int free_old_path); char *searchPath( const char *pathlist, const char *filename, const char *suffix, int type); /* An interface for verifying cached files. */ typedef unsigned long FileStamp; FileStamp getFileStamp(const char *name); void setFileStamp(FileStamp *stamp, const char *name); Bool isFileStampChanged(const FileStamp *stamp, const char *name); /* mkstemp */ int fvwm_mkstemp (char *TEMPLATE); #endif /* LIB_SYSTEM_H */ fvwm-2.6.7/libs/ClientMsg.h0000644000175700017570000000102112773467232012442 00000000000000/* -*-c-*- */ /* * 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 */ #include #include #include void send_clientmessage(Display *disp, Window w, Atom a, Time timestamp); extern Atom _XA_WM_PROTOCOLS; fvwm-2.6.7/libs/PictureBase.h0000644000175700017570000001407113002513336012753 00000000000000/* -*-c-*- */ #ifndef Picture_Base_H #define Picture_Base_H #include "config.h" #ifdef HAVE_XRENDER #define XRenderSupport 1 #else #define XRenderSupport 0 #endif #ifdef XPM #define XpmSupport 1 #else #define XpmSupport 0 #endif #ifdef HAVE_PNG #define PngSupport 1 #else #define PngSupport 0 #endif extern Bool Pdefault; extern Visual *Pvisual; extern Colormap Pcmap; extern unsigned int Pdepth; extern Display *Pdpy; /* Save area for display pointer */ extern Bool PUseDynamicColors; typedef struct { int color_limit; int strict; int allocate; int not_dynamic; int use_named_table; } PictureColorLimitOption; /** * Set a colon-separated path, with environment variable expansions. * Expand '+' to be the value of the previous path. * * Parameters: * p_path pointer to the path variable * newpath new value for *p_path * free_old_path set true if we should free the memory pointed to * by p_path on entry * * The value of newpath is copied into a newly-allocated place, to which * '*p_path' will point to upon return. The memory region pointed to by * '*p_path' upon entry will be freed if 'free_old_path' is true. * **/ void setPath(char** p_path, const char* newpath, int free_old_path); /** * Search along colon-separated path for filename, with optional suffix. * * Parameters: * path colon-separated path of directory names * filename basename of file to search for * suffix if non-NULL, filename may have this suffix * type mode sought for file * * For each DIR in the path, search for DIR/filename then * DIR/ (if suffix is non-NULL). Return the full path of * the first found. * * The parameter type is a mask consisting of one or more of R_OK, W_OK, X_OK * and F_OK. R_OK, W_OK and X_OK request checking whether the file exists and * has read, write and execute permissions, respectively. F_OK just requests * checking for the existence of the file. * * Returns: full pathname of sought-after file, or NULL. The return value * points to allocated memory that the caller must free. * **/ char* searchPath( const char* path, const char* filename, const char* suffix, int type); /* This routine called during modules initialization. Fvwm has its own code * in fvwm.c */ void PictureInitCMap(Display *dpy); /* as above but force to use the default visual. If use_my_color_limit is True * also enable color limitation (independent than the fvwm one). */ void PictureInitCMapRoot( Display *dpy, Bool init_color_limit, PictureColorLimitOption *opt, Bool use_my_color_limit, Bool init_dither); /* Analogue of the Xlib WhitePixel and BlackPixel functions but use the Pvisual */ Pixel PictureWhitePixel(void); Pixel PictureBlackPixel(void); /* for initialization of the white and black pixel (for fvwm as PictureInitCMap* * do this) */ void PictureSetupWhiteAndBlack(void); /* Analogue of the Xlib DefaultGC function but take care of the Pdepth: - If Pdepth == DefaultDepth return the DefaultGC - If Pdepth != DefaultDepth and first call create a static gc with the win and return the gc - If Pdepth != DefaultDepth and already called return the static gc */ GC PictureDefaultGC(Display *dpy, Window win); /* these can be used to switch visuals before calling GetPicture */ /* do NOT use with CachePicture */ void PictureUseDefaultVisual(void); void PictureUseFvwmVisual(void); void PictureSaveFvwmVisual(void); /** Returns current setting of the image path **/ char* PictureGetImagePath(void); /** Sets image path to newpath. Environment variables are expanded, and '+' is expanded to previous value of imagepath. The new path is in newly-allocated memory, so newpath may be freed or re-used. **/ void PictureSetImagePath(const char* newpath); /** Search for file along pathlist. If pathlist is NULL, will use the current imagepath setting. If filename is not found, but filename.gz is found, will return the latter. Mode is typically R_OK. See searchPath() for more details. **/ char* PictureFindImageFile( const char* filename, const char* pathlist, int mode); typedef struct FvwmPictureThing { struct FvwmPictureThing *next; char *name; unsigned long stamp; /* should be FileStamp */ unsigned long fpa_mask; Pixmap picture; Pixmap mask; Pixmap alpha; unsigned int depth; unsigned int width; unsigned int height; unsigned int count; Pixel *alloc_pixels; int nalloc_pixels; Bool no_limit; } FvwmPicture; typedef struct { unsigned alpha : 1; unsigned alloc_pixels : 1; } FvwmPictureFlags; #define FPAM_NO_ALLOC_PIXELS (1) /* do not return the allocated pixels * this is used only if PUseDynamicColors, * if not the allocated pixels are never * returned */ #define FPAM_NO_COLOR_LIMIT (1 << 1) /* do not use color limitation */ #define FPAM_NO_ALPHA (1 << 2) /* do not return the alpha channel */ #define FPAM_DITHER (1 << 3) /* dither the image */ #define FPAM_TINT (1 << 4) /* tint the image */ #define FPAM_MONOCHROME (1 << 5) /* reduce the color depth to 1-bit */ typedef struct { unsigned mask : 6; XColor tint; int tint_percent; } FvwmPictureAttributes; /* tint no yet implemented */ #define PICTURE_FPA_AGREE(p,fpa) (p->fpa_mask == fpa.mask) #define FRAM_HAVE_ADDED_ALPHA (1) #define FRAM_HAVE_TINT (1 << 1) #define FRAM_HAVE_UNIFORM_COLOR (1 << 2) #define FRAM_DEST_IS_A_WINDOW (1 << 3) #define FRAM_HAVE_ICON_CSET (1 << 4) #include "Colorset.h" typedef struct { unsigned mask : 5; int added_alpha_percent; Pixel tint; int tint_percent; Pixel uniform_pixel; colorset_t *colorset; } FvwmRenderAttributes; #define PICTURE_HAS_ALPHA(picture,cset) \ ((picture && picture->alpha != None) || \ (cset >= 0 && Colorset[cset].icon_alpha_percent < 100)) /* alpha limit if we cannot use the alpha channel */ #define PICTURE_ALPHA_LIMIT 130 typedef struct { Colormap cmap; int dither; int no_limit; Bool is_8; unsigned long *pixels_table; int pixels_table_size; } PictureImageColorAllocator; #endif /* Picture_Base_H */ fvwm-2.6.7/libs/FTips.c0000644000175700017570000003406213001406607011570 00000000000000/* -*-c-*- */ /* Copyright (C) 2004 Olivier Chapuis */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/ftime.h" #include #include #include "defaults.h" #include "fvwmlib.h" #include "Strings.h" #include "PictureBase.h" #include "Flocale.h" #include "Graphics.h" #include "Colorset.h" #include "libs/FScreen.h" #include "FTips.h" /* ---------------------------- local definitions -------------------------- */ #define FVWM_TIPS_NOTHING 0 #define FVWM_TIPS_WAITING 1 #define FVWM_TIPS_MAPPED 2 /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Window win = None; static GC gc = None; static Window win_for; static ftips_config *current_config, *default_config; static char *label; static int state = FVWM_TIPS_NOTHING; static void *boxID = NULL; static FlocaleWinString fwin_string; static rectangle box; static unsigned long timeOut; static unsigned long onTime; static Atom _net_um_for = None; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static unsigned long __get_time(void) { struct timeval t; gettimeofday(&t, NULL); return (1000*t.tv_sec + t.tv_usec/1000); } static void __initialize_window(Display *dpy) { XGCValues xgcv; unsigned long valuemask; XSetWindowAttributes attributes; Atom _net_um_window_type; long _net_um_window_type_tooltips; valuemask = CWOverrideRedirect | CWEventMask | CWColormap; attributes.override_redirect = True; attributes.event_mask = ExposureMask; attributes.colormap = Pcmap; win = XCreateWindow( dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, current_config->border_width, Pdepth, InputOutput, Pvisual, valuemask, &attributes); _net_um_window_type = XInternAtom( dpy, "_NET_UM_WINDOW_TYPE", False); _net_um_window_type_tooltips = XInternAtom( dpy, "_NET_UM_WINDOW_TYPE_TOOLTIPS", False); XChangeProperty( dpy, win, _net_um_window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &_net_um_window_type_tooltips, 1); _net_um_for = XInternAtom(dpy, "_NET_UM_FOR", False); gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); return; } static void __setup_cs(Display *dpy) { XSetWindowAttributes xswa; unsigned long valuemask = 0; if (current_config->colorset > -1) { xswa.border_pixel = Colorset[current_config->colorset].fg; xswa.background_pixel = Colorset[current_config->colorset].bg; if (Colorset[current_config->colorset].pixmap) { /* set later */ xswa.background_pixmap = None; valuemask = CWBackPixmap | CWBorderPixel;; } else { valuemask = CWBackPixel | CWBorderPixel; } } else { xswa.border_pixel = current_config->border_pixel; xswa.background_pixel = current_config->bg; valuemask = CWBackPixel | CWBorderPixel; } XChangeWindowAttributes(dpy, win, valuemask, &xswa); } static void __setup_gc(Display *dpy) { XGCValues xgcv; unsigned long valuemask; valuemask = GCForeground; if (current_config->colorset > -1) { xgcv.foreground = Colorset[current_config->colorset].fg; } else { xgcv.foreground = current_config->fg; } if (current_config->Ffont && current_config->Ffont->font != NULL) { xgcv.font = current_config->Ffont->font->fid; valuemask |= GCFont; } XChangeGC(dpy, gc, valuemask, &xgcv); return; } static void __draw(Display *dpy) { if (!current_config->Ffont) { return; } fwin_string.str = label; fwin_string.win = win; fwin_string.gc = gc; if (current_config->colorset > -1) { fwin_string.colorset = &Colorset[current_config->colorset]; fwin_string.flags.has_colorset = True; } else { fwin_string.flags.has_colorset = False; } fwin_string.x = 2; fwin_string.y = current_config->Ffont->ascent; FlocaleDrawString(dpy, current_config->Ffont, &fwin_string, 0); return; } static void __map_window(Display *dpy) { rectangle new_g; rectangle screen_g; Window dummy; fscreen_scr_arg *fsarg = NULL; /* for now no xinerama support */ ftips_placement_t placement; int x,y; static int border_width = 1; static Window win_f = None; if (border_width != current_config->border_width) { XSetWindowBorderWidth(dpy, win, current_config->border_width); border_width = current_config->border_width; } FScreenGetScrRect( fsarg, FSCREEN_GLOBAL, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); new_g.height = ((current_config->Ffont)? current_config->Ffont->height:0) + 1; new_g.width = 4; if (label && current_config->Ffont) { new_g.width += FlocaleTextWidth( current_config->Ffont, label, strlen(label)); } if (current_config->placement != FTIPS_PLACEMENT_AUTO_UPDOWN && current_config->placement != FTIPS_PLACEMENT_AUTO_LEFTRIGHT) { placement = current_config->placement; } else { XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), box.x, box.y, &x, &y, &dummy); if (current_config->placement == FTIPS_PLACEMENT_AUTO_UPDOWN) { if (y + box.height/2 >= screen_g.height/2) { placement = FTIPS_PLACEMENT_UP; } else { placement = FTIPS_PLACEMENT_DOWN; } } else { if (x + box.width/2 >= screen_g.width/2) { placement = FTIPS_PLACEMENT_LEFT; } else { placement = FTIPS_PLACEMENT_RIGHT; } } } if (placement == FTIPS_PLACEMENT_RIGHT || placement == FTIPS_PLACEMENT_LEFT) { if (current_config->justification == FTIPS_JUSTIFICATION_CENTER) { y = box.y + (box.height / 2) - (new_g.height / 2) - current_config->border_width; } else if (current_config->justification == FTIPS_JUSTIFICATION_RIGHT_DOWN) { y = box.y + box.height - new_g.height - (2 * current_config->border_width) - current_config->justification_offset; } else /* LEFT_UP */ { y = box.y + current_config->justification_offset; } } else /* placement == FTIPS_PLACEMENT_DOWN || placement == FTIPS_PLACEMENT_UP */ { if (current_config->justification == FTIPS_JUSTIFICATION_CENTER) { x = box.x + (box.width / 2) - (new_g.width / 2) - current_config->border_width; } else if (current_config->justification == FTIPS_JUSTIFICATION_RIGHT_DOWN) { x = box.x + box.width - new_g.width - (2 * current_config->border_width) - current_config->justification_offset; } else /* LEFT_UP */ { x = box.x + current_config->justification_offset; } } if (placement == FTIPS_PLACEMENT_RIGHT) { x = box.x + box.width + current_config->placement_offset + 1; } else if (placement == FTIPS_PLACEMENT_LEFT) { x = box.x - current_config->placement_offset - new_g.width - (2 * current_config->border_width) - 1; } else if (placement == FTIPS_PLACEMENT_DOWN) { y = box.y + box.height + current_config->placement_offset - 0; } else /* UP */ { y = box.y - current_config->placement_offset - new_g.height + 0 - (2 * current_config->border_width); } XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &new_g.x, &new_g.y, &dummy); if (placement == FTIPS_PLACEMENT_RIGHT || placement == FTIPS_PLACEMENT_LEFT) { int x1,y1,l1,l2; if (new_g.x < 2) { x = box.x + box.width + current_config->placement_offset + 1; XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &x1, &y1, &dummy); /* */ l1 = new_g.width + new_g.x - 2; l2 = screen_g.width - (x1 + new_g.width) - current_config->border_width - 2; if (l2 > l1) { new_g.x = x1; } } else if (new_g.x + new_g.width > screen_g.width - (2 * current_config->border_width) - 2) { x = box.x - current_config->placement_offset - new_g.width - (2 * current_config->border_width) - 1; XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &x1, &y1, &dummy); /* */ l1 = new_g.width + x1 - 2; l2 = screen_g.width - (new_g.x + new_g.width) - (2 * current_config->border_width) - 2; if (l1 > l2) { new_g.x = x1; } } if ( new_g.y < 2 ) { new_g.y = 2; } else if (new_g.y + new_g.height > screen_g.height - (2 * current_config->border_width) - 2) { new_g.y = screen_g.height - new_g.height - (2 * current_config->border_width) - 2; } } else /* placement == FTIPS_PLACEMENT_DOWN || placement == FTIPS_PLACEMENT_UP */ { if (new_g.y < 2) { y = box.y + box.height + current_config->placement_offset - 0; XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &new_g.x, &new_g.y, &dummy); } else if (new_g.y + new_g.height > screen_g.height - (2 * current_config->border_width) - 2) { y = box.y - current_config->placement_offset - new_g.height + 0 - (2 * current_config->border_width); XTranslateCoordinates( dpy, win_for, DefaultRootWindow(dpy), x, y, &new_g.x, &new_g.y, &dummy); } if ( new_g.x < 2 ) { new_g.x = 2; } else if (new_g.x + new_g.width > screen_g.width - (2 * current_config->border_width) - 2) { new_g.x = screen_g.width - new_g.width - (2 * current_config->border_width) - 2; } } /* make changes to window */ XMoveResizeWindow( dpy, win, new_g.x, new_g.y, new_g.width, new_g.height); __setup_gc(dpy); if (current_config->colorset > -1) { SetWindowBackground( dpy, win, new_g.width, new_g.height, &Colorset[current_config->colorset], Pdepth, gc, True); } else { XSetWindowBackground (dpy, win, current_config->bg); } if (current_config->border_width > 0) { XSetWindowBorder( dpy, win, Colorset[current_config->colorset].fg); } if (state != FVWM_TIPS_MAPPED && win_f != win_for) { long l_win_for; l_win_for = win_for; XChangeProperty( dpy, win, _net_um_for, XA_WINDOW, 32, PropModeReplace, (unsigned char *) &l_win_for, 1); win_f = win_for; } XMapRaised(dpy, win); state = FVWM_TIPS_MAPPED; return; } /* ---------------------------- interface functions ------------------------ */ Bool FTipsInit(Display *dpy) { current_config = default_config = FTipsNewConfig(); __initialize_window(dpy); if (gc == None || win == None) { return False; } __setup_cs(dpy); __setup_gc(dpy); memset(&fwin_string, 0, sizeof(fwin_string)); return True; } ftips_config *FTipsNewConfig(void) { ftips_config *fc; fc = (ftips_config *)safemalloc(sizeof(ftips_config)); memset(fc, 0, sizeof(ftips_config)); /* use colorset 0 as default */ fc->border_width = FTIPS_DEFAULT_BORDER_WIDTH; fc->placement = FTIPS_DEFAULT_PLACEMENT; fc->justification = FTIPS_DEFAULT_JUSTIFICATION; fc->placement_offset = FTIPS_DEFAULT_PLACEMENT_OFFSET; fc->justification_offset = FTIPS_DEFAULT_JUSTIFICATION_OFFSET; fc->delay = 1000; fc->mapped_delay = 300; return fc; } void FTipsOn( Display *dpy, Window win_f, ftips_config *fc, void *id, char *str, int x, int y, int w, int h) { unsigned long delay; box.x = x; box.y = y; box.width = w; box.height = h; if (fc == NULL) { fc = default_config; } current_config = fc; if (label != NULL) { free(label); } CopyString(&label, str); win_for = win_f; if (id == boxID) { if (id && state == FVWM_TIPS_WAITING) { FTipsCheck(dpy); } return; } onTime = __get_time(); if (state == FVWM_TIPS_MAPPED) { FTipsCancel(dpy); delay = fc->mapped_delay; } else { delay = fc->delay; } boxID = id; timeOut = onTime + delay; state = FVWM_TIPS_WAITING; if (delay == 0) { FTipsCheck(dpy); } return; } void FTipsCancel(Display *dpy) { if (state == FVWM_TIPS_MAPPED && win != None) { XUnmapWindow(dpy, win); } boxID = 0; state = FVWM_TIPS_NOTHING; } unsigned long FTipsCheck(Display *dpy) { unsigned long ct; if (state != FVWM_TIPS_WAITING || win == None) { return 0; } ct = __get_time(); if (ct >= timeOut) { __map_window(dpy); XFlush(dpy); state = FVWM_TIPS_MAPPED; return 0; } else { XFlush(dpy); return timeOut - ct; } } Bool FTipsExpose(Display *dpy, XEvent *ev) { int ex,ey,ex2,ey2; if (win == None || ev->xany.window != win) { return False; } ex = ev->xexpose.x; ey = ev->xexpose.y; ex2 = ev->xexpose.x + ev->xexpose.width; ey2= ev->xexpose.y + ev->xexpose.height; while (FCheckTypedWindowEvent(dpy, ev->xany.window, Expose, ev)) { ex = min(ex, ev->xexpose.x); ey = min(ey, ev->xexpose.y); ex2 = max(ex2, ev->xexpose.x + ev->xexpose.width); ey2= max(ey2 , ev->xexpose.y + ev->xexpose.height); } #if 0 fprintf ( stderr, "\tExpose: %i,%i,%i,%i %i\n", ex, ey, ex2-ex, ey2-ey, ev->xexpose.count); #endif __draw(dpy); return True; } Bool FTipsHandleEvents(Display *dpy, XEvent *ev) { if (ev->xany.window != win) { return False; } switch(ev->type) { case Expose: FTipsExpose(dpy, ev); break; default: break; } return True; } void FTipsUpdateLabel(Display *dpy, char *str) { if (state != FVWM_TIPS_MAPPED && state != FVWM_TIPS_WAITING) { return; } if (label) { free(label); } CopyString(&label, str); if (state == FVWM_TIPS_MAPPED) { __map_window(dpy); __draw(dpy); } } void FTipsColorsetChanged(Display *dpy, int cs) { if (state != FVWM_TIPS_MAPPED || cs != current_config->colorset) { return; } __map_window(dpy); __draw(dpy); } fvwm-2.6.7/libs/fvwmlib.c0000644000175700017570000000374612773467232012236 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include "fvwmlib.h" #include "FScreen.h" #include "FShape.h" #include "Fsvg.h" #include "FRenderInit.h" #include "Graphics.h" #include "PictureBase.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ void flib_init_graphics(Display *dpy) { PictureInitCMap(dpy); FScreenInit(dpy); /* Initialise default colorset */ AllocColorset(0); FShapeInit(dpy); FRenderInit(dpy); #ifdef Frsvg_init Frsvg_init(); #endif return; } fvwm-2.6.7/libs/FRender.c0000644000175700017570000003452213003342500012062 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "PictureBase.h" #include "Graphics.h" #include "PictureGraphics.h" #include "FRenderInit.h" #include "FRender.h" #include "FRenderInterface.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static FRenderPictFormat *PFrenderVisualFormat = NULL; static FRenderPictFormat *PFrenderAlphaFormat = NULL; static FRenderPictFormat *PFrenderMaskFormat = NULL; static FRenderPictFormat *PFrenderDirectFormat = NULL; static FRenderPictFormat *PFrenderAbsoluteFormat = NULL; Bool FRenderVisualInitialized = False; /* #define USE_ABSOLUTE_FORMAT 1*/ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void FRenderVisualInit(Display *dpy) { FRenderPictFormat pf; if (!XRenderSupport || !FRenderGetExtensionSupported()) { return; } PFrenderVisualFormat = FRenderFindVisualFormat (dpy, Pvisual); if (!PFrenderVisualFormat) { fprintf(stderr,"[fvwmlibs][FRenderInit] -- ERROR: " "fail to create XRender Visual Format\n"); return; } pf.depth = 8; pf.type = FRenderPictTypeDirect; pf.direct.alpha = 0; pf.direct.alphaMask = 0xff; SUPPRESS_UNUSED_VAR_WARNING(pf); PFrenderAlphaFormat = FRenderFindFormat( dpy, FRenderPictFormatType| FRenderPictFormatDepth| FRenderPictFormatAlpha| FRenderPictFormatAlphaMask, &pf, 0); if (!PFrenderAlphaFormat) { fprintf(stderr,"[fvwmlibs][FRenderInit] -- ERROR: " "fail to create XRender Alpha Format\n"); return; } pf.depth = 1; pf.type = FRenderPictTypeDirect; pf.direct.alpha = 0; pf.direct.alphaMask = 1; PFrenderMaskFormat = FRenderFindFormat( dpy, FRenderPictFormatType| FRenderPictFormatDepth| FRenderPictFormatAlpha| FRenderPictFormatAlphaMask, &pf, 0); if (!PFrenderMaskFormat) { fprintf(stderr,"[fvwmlibs][FRenderInit] -- ERROR: " "fail to create XRender Mask Format\n"); return; } pf.depth = 24; pf.type = FRenderPictTypeDirect; pf.direct.alpha = 0; pf.direct.alphaMask = 0; pf.direct.red = 16; pf.direct.redMask = 0xff; pf.direct.green = 8; pf.direct.greenMask = 0xff; pf.direct.blue = 0; pf.direct.blueMask = 0xff; PFrenderDirectFormat = FRenderFindFormat( dpy, FRenderPictFormatType| FRenderPictFormatDepth| FRenderPictFormatRed| FRenderPictFormatRedMask| FRenderPictFormatGreen| FRenderPictFormatGreenMask| FRenderPictFormatBlue| FRenderPictFormatBlueMask| FRenderPictFormatAlpha| FRenderPictFormatAlphaMask, &pf, 0); if (!PFrenderDirectFormat) { fprintf(stderr,"[fvwmlibs][FRenderInit] -- ERROR: " "fail to create XRender Direct Format\n"); return; } pf.depth = 32; pf.type = FRenderPictTypeDirect; pf.direct.alpha = 24; pf.direct.alphaMask = 0xff; pf.direct.red = 16; pf.direct.redMask = 0xff; pf.direct.green = 8; pf.direct.greenMask = 0xff; pf.direct.blue = 0; pf.direct.blueMask = 0xff; PFrenderAbsoluteFormat = FRenderFindFormat( dpy, FRenderPictFormatType| FRenderPictFormatDepth| FRenderPictFormatRed| FRenderPictFormatRedMask| FRenderPictFormatGreen| FRenderPictFormatGreenMask| FRenderPictFormatBlue| FRenderPictFormatBlueMask| FRenderPictFormatAlpha| FRenderPictFormatAlphaMask, &pf, 0); if (!PFrenderAbsoluteFormat) { fprintf(stderr,"[fvwmlibs][FRenderInit] -- ERROR: " "fail to create XRender Absolute Format\n"); return; } } static Bool FRenderCompositeAndCheck( Display *dpy, int op, FRenderPicture src, FRenderPicture alpha, FRenderPicture dest, int x, int y, int a_x, int a_y, int d_x, int d_y, int d_w, int d_h) { FRenderComposite( dpy, op, src, alpha, dest, x, y, a_x, a_y, d_x, d_y, d_w, d_h); return True; } static Bool FRenderCreateShadePicture( Display *dpy, Window win, int alpha_percent) { static Pixmap shade_pixmap = None; static FRenderPicture shade_picture = None; static int saved_alpha_percent = 0; Bool force_update = False; FRenderColor frc; if (!XRenderSupport || !FRenderGetExtensionSupported()) { return 0; } /* FRender Visuals should be already initialized */ if (!shade_pixmap || !shade_picture) { FRenderPictureAttributes pa; if (!shade_pixmap) { shade_pixmap = XCreatePixmap(dpy, win, 1, 1, 8); } pa.repeat = True; if (shade_pixmap) { SUPPRESS_UNUSED_VAR_WARNING(pa); shade_picture = FRenderCreatePicture( dpy, shade_pixmap, PFrenderAlphaFormat, FRenderCPRepeat, &pa); } force_update = True; } if (shade_picture && (alpha_percent != saved_alpha_percent || force_update)) { frc.red = frc.green = frc.blue = 0; frc.alpha = 0xffff * (alpha_percent)/100; FRenderFillRectangle( dpy, FRenderPictOpSrc, shade_picture, &frc, 0, 0, 1, 1); saved_alpha_percent = alpha_percent; } return shade_picture; } static Bool FRenderTintPicture( Display *dpy, Window win, Pixel tint, int tint_percent, FRenderPicture dest_picture, int dest_x, int dest_y, int dest_w, int dest_h) { static Pixel saved_tint = 0; static int saved_tint_percent = 0; static Pixmap tint_pixmap = None; static FRenderPicture tint_picture = None; FRenderPicture shade_picture = None; Bool force_update = False; FRenderPictureAttributes pa; int rv = 0; if (!XRenderSupport) { return 0; } if (!tint_pixmap || !tint_picture) { pa.repeat = True; if (!tint_pixmap) { tint_pixmap = XCreatePixmap(dpy, win, 1, 1, 32); } if (tint_pixmap) { tint_picture = FRenderCreatePicture( dpy, tint_pixmap, PFrenderAbsoluteFormat, FRenderCPRepeat, &pa); if (!tint_picture) { goto bail; } } else { goto bail; } force_update = True; } if (tint_picture && (tint != saved_tint || tint_percent != saved_tint_percent || force_update)) { XColor color; float alpha_factor = (float)tint_percent/100; FRenderColor frc_tint; force_update = False; color.pixel = tint; XQueryColor(dpy, Pcmap, &color); frc_tint.red = color.red * alpha_factor; frc_tint.green = color.green * alpha_factor; frc_tint.blue = color.blue * alpha_factor; frc_tint.alpha = 0xffff * alpha_factor; SUPPRESS_UNUSED_VAR_WARNING(frc_tint); FRenderFillRectangle( dpy, FRenderPictOpSrc, tint_picture, &frc_tint, 0, 0, 1, 1); saved_tint = tint; saved_tint_percent = tint_percent; } if (!shade_picture) { shade_picture = FRenderCreateShadePicture(dpy, win, 100); } rv = FRenderCompositeAndCheck( dpy, FRenderPictOpOver, tint_picture, shade_picture, dest_picture, 0, 0, 0, 0, dest_x, dest_y, dest_w, dest_h); SUPPRESS_UNUSED_VAR_WARNING(pa); bail: return rv; } /* ---------------------------- interface functions ------------------------ */ Bool FRenderTintRectangle( Display *dpy, Window win, Pixmap mask, Pixel tint, int tint_percent, Drawable d, int dest_x, int dest_y, int dest_w, int dest_h) { FRenderPicture dest_picture = None; FRenderPictureAttributes pa; unsigned int val; Bool rv = True; if (!XRenderSupport || !FRenderGetExtensionSupported()) { return 0; } if (!FRenderVisualInitialized) { FRenderVisualInitialized = True; FRenderVisualInit(dpy); } if (!PFrenderVisualFormat || !PFrenderAlphaFormat || !PFrenderAbsoluteFormat || !PFrenderMaskFormat) { return 0; } pa.clip_mask = mask; val = FRenderCPClipMask; SUPPRESS_UNUSED_VAR_WARNING(val); SUPPRESS_UNUSED_VAR_WARNING(pa); if (!(dest_picture = FRenderCreatePicture( dpy, d, PFrenderVisualFormat, val, &pa))) { return 0; } rv = FRenderTintPicture( dpy, win, tint_percent, tint, dest_picture, dest_x, dest_y, dest_w, dest_h); FRenderFreePicture(dpy, dest_picture); return rv; } int FRenderRender( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, int added_alpha_percent, Pixel tint, int tint_percent, Drawable d, GC gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, Bool do_repeat) { FRenderColor frc; Pixmap pixmap_copy = None; Pixmap alpha_copy = None; FRenderPicture shade_picture = None; FRenderPicture alpha_picture = None; FRenderPicture mask_picture = None; FRenderPicture src_picture = None; FRenderPicture dest_picture = None; FRenderPicture root_picture = None; FRenderPictureAttributes pa; unsigned long pam = 0; int alpha_x = src_x; int alpha_y = src_y; Bool rv = False; Bool free_alpha_gc = False; if (!XRenderSupport || !FRenderGetExtensionSupported()) { return 0; } if (!FRenderVisualInitialized) { FRenderVisualInitialized = True; FRenderVisualInit(dpy); } if (!PFrenderVisualFormat || !PFrenderAlphaFormat || !PFrenderAbsoluteFormat || !PFrenderMaskFormat) { return 0; } /* it is a bitmap ? */ if (Pdepth != depth && pixmap) { pixmap_copy = PictureBitmapToPixmap( dpy, win, pixmap, Pdepth, gc, src_x, src_y, src_w, src_h); src_x = src_y = 0; } pam = FRenderCPRepeat; if (do_repeat) { pa.repeat = True; } else { pa.repeat = False; } /* * build the src_picture */ if (pixmap == ParentRelative) { /* need backing store and good preparation of the win */ if (gc == None) { gc = PictureDefaultGC(dpy, win); } pixmap_copy = XCreatePixmap(dpy, win, src_w, src_h, Pdepth); if (pixmap_copy && gc) { XCopyArea( dpy, win, pixmap_copy, gc, src_x, src_y, src_w, src_h, 0, 0); } src_x = src_y = 0; } else if (tint_percent > 0 && !pixmap_copy) { if (gc == None) { gc = PictureDefaultGC(dpy, win); } pixmap_copy = XCreatePixmap(dpy, win, src_w, src_h, Pdepth); if (pixmap_copy && gc) { XCopyArea( dpy, pixmap, pixmap_copy, gc, src_x, src_y, src_w, src_h, 0, 0); } src_x = src_y = 0; } else if (!pixmap_copy) { SUPPRESS_UNUSED_VAR_WARNING(pa); SUPPRESS_UNUSED_VAR_WARNING(pam); src_picture = FRenderCreatePicture( dpy, pixmap, PFrenderVisualFormat, pam, &pa); } if (!src_picture && pixmap_copy) { src_picture = FRenderCreatePicture( dpy, pixmap_copy, PFrenderVisualFormat, pam, &pa); } if (!src_picture) { goto bail; } /* tint the src, it is why we have done a pixmap copy */ if (tint_percent > 0) { FRenderTintPicture( dpy, win, tint, tint_percent, src_picture, src_x, src_y, src_w, src_h); } if (added_alpha_percent >= 100) { if (alpha != None) { alpha_picture = FRenderCreatePicture( dpy, alpha, PFrenderAlphaFormat, pam, &pa); } else if (mask != None) { alpha_picture = FRenderCreatePicture( dpy, mask, PFrenderMaskFormat, pam, &pa); } else { /* fix a bug in certain XRender server implementation? */ if (!(shade_picture = FRenderCreateShadePicture( dpy, win, 100))) { goto bail; } alpha_x = alpha_y = 0; } } else { if (alpha != None) { alpha_copy = XCreatePixmap(dpy, win, src_w, src_h, 8); if (!alpha_gc) { alpha_gc = fvwmlib_XCreateGC( dpy, alpha, 0, NULL); free_alpha_gc = True; } if (alpha_copy && alpha_gc) { XCopyArea(dpy, alpha, alpha_copy, alpha_gc, alpha_x, alpha_y, src_w, src_h, 0, 0); alpha_picture = FRenderCreatePicture( dpy, alpha_copy, PFrenderAlphaFormat, pam, &pa); } if (alpha_gc && free_alpha_gc) { XFreeGC(dpy, alpha_gc); } alpha_x = alpha_y = 0; } else if (mask != None) { alpha_copy = XCreatePixmap(dpy, win, src_w, src_h, 8); if (alpha_copy) { alpha_picture = FRenderCreatePicture( dpy, alpha_copy, PFrenderAlphaFormat, pam, &pa); } if (alpha_picture) { frc.red = frc.green = frc.blue = frc.alpha = 0; FRenderFillRectangle( dpy, FRenderPictOpSrc, alpha_picture, &frc, 0, 0, src_w, src_h); } mask_picture = FRenderCreatePicture( dpy, mask, PFrenderMaskFormat, pam, &pa); } else { alpha_x = alpha_y = 0; } if (!(shade_picture = FRenderCreateShadePicture( dpy, win, added_alpha_percent))) { goto bail; } if (alpha != None && alpha_picture && shade_picture) { if (!FRenderCompositeAndCheck( dpy, FRenderPictOpAtopReverse, shade_picture, alpha_picture, alpha_picture, 0, 0, alpha_x, alpha_y, 0, 0, src_w, src_h)) { goto bail; } alpha_x = alpha_y = 0; } else if (mask != None && alpha_picture && shade_picture) { if (!FRenderCompositeAndCheck( dpy, FRenderPictOpAtopReverse, shade_picture, mask_picture, alpha_picture, 0, 0, alpha_x, alpha_y, 0, 0, src_w, src_h)) { goto bail; } alpha_x = alpha_y = 0; } } if (alpha_picture == None) { alpha_picture = shade_picture; } dest_picture = FRenderCreatePicture( dpy, d, PFrenderVisualFormat, 0, &pa); if (dest_picture) { rv = FRenderCompositeAndCheck( dpy, FRenderPictOpOver, src_picture, alpha_picture, dest_picture, src_x, src_y, alpha_x, alpha_y, dest_x, dest_y, dest_w, dest_h); } bail: if (dest_picture) { FRenderFreePicture(dpy, dest_picture); } if (src_picture) { FRenderFreePicture(dpy, src_picture); } if (alpha_picture && alpha_picture != shade_picture) { FRenderFreePicture(dpy, alpha_picture); } if (mask_picture) { FRenderFreePicture(dpy, mask_picture); } if (root_picture) { FRenderFreePicture(dpy, root_picture); } if (alpha_copy) { XFreePixmap(dpy, alpha_copy); } if (pixmap_copy) { XFreePixmap(dpy, pixmap_copy); } return rv; } fvwm-2.6.7/libs/wcontext.c0000644000175700017570000000560212773467232012434 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/charmap.h" #include "libs/wcontext.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* The keys must be in lower case! Put more common contexts toward the front. */ charmap_t win_contexts[] = { {'r', C_ROOT}, {'t', C_TITLE}, {'w', C_WINDOW}, {'f', C_FRAME}, {'i', C_ICON}, {'a', C_ALL}, {'1', C_L1}, {'2', C_R1}, {'3', C_L2}, {'4', C_R2}, {'5', C_L3}, {'6', C_R3}, {'7', C_L4}, {'8', C_R4}, {'9', C_L5}, {'0', C_R5}, {'d', C_EWMH_DESKTOP}, {'<', C_F_TOPLEFT}, {'^', C_F_TOPRIGHT}, {'>', C_F_BOTTOMRIGHT}, {'v', C_F_BOTTOMLEFT}, {'s', C_SIDEBAR}, {'[', C_SB_LEFT}, {']', C_SB_RIGHT}, {'-', C_SB_TOP}, {'_', C_SB_BOTTOM}, {'m', C_MENU}, {'p', C_PLACEMENT}, {0, 0} }; /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Converts the input string into a mask with bits for the contexts */ int wcontext_string_to_wcontext(char *in_context, int *out_context_mask) { int error; error = charmap_string_to_mask( out_context_mask, in_context, win_contexts, "bad context"); return error; } char wcontext_wcontext_to_char(win_context_t wcontext) { char c; c = charmap_mask_to_char((int)wcontext, win_contexts); return c; } win_context_t wcontext_merge_border_wcontext(win_context_t wcontext) { if (wcontext & C_FRAME) { wcontext |= C_FRAME; } if (wcontext & C_SIDEBAR) { wcontext |= C_SIDEBAR; } return wcontext; } fvwm-2.6.7/libs/Cursor.c0000644000175700017570000001027712773467232012042 00000000000000/* -*-c-*- */ /* 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 */ /* Modification History */ /* Created on 10/05/01 by Dan Espen (dane): Extracted from fvwm/cursor.c. Contains common routine to verify and convert a cursor name into a cursor number from X11/cursorfont.h. Used by fvwm CursorStyle command and FvwmForm. */ #include "config.h" #include #include "fvwmlib.h" #include #include "Cursor.h" /* * fvwmCursorNameToIndex: return the number of a X11 cursor from its * name, if not found return -1. */ int fvwmCursorNameToIndex (char *cursor_name) { static const struct CursorNameIndex { const char *name; unsigned int number; } cursor_table[] = { {"arrow", XC_arrow}, {"based_arrow_down", XC_based_arrow_down}, {"based_arrow_up", XC_based_arrow_up}, {"boat", XC_boat}, {"bogosity", XC_bogosity}, {"bottom_left_corner", XC_bottom_left_corner}, {"bottom_right_corner", XC_bottom_right_corner}, {"bottom_side", XC_bottom_side}, {"bottom_tee", XC_bottom_tee}, {"box_spiral", XC_box_spiral}, {"center_ptr", XC_center_ptr}, {"circle", XC_circle}, {"clock", XC_clock}, {"coffee_mug", XC_coffee_mug}, {"cross", XC_cross}, {"cross_reverse", XC_cross_reverse}, {"crosshair", XC_crosshair}, {"diamond_cross", XC_diamond_cross}, {"dot", XC_dot}, {"dotbox", XC_dotbox}, {"double_arrow", XC_double_arrow}, {"draft_large", XC_draft_large}, {"draft_small", XC_draft_small}, {"draped_box", XC_draped_box}, {"exchange", XC_exchange}, {"fleur", XC_fleur}, {"gobbler", XC_gobbler}, {"gumby", XC_gumby}, {"hand1", XC_hand1}, {"hand2", XC_hand2}, {"heart", XC_heart}, {"icon", XC_icon}, {"iron_cross", XC_iron_cross}, {"left_ptr", XC_left_ptr}, {"left_side", XC_left_side}, {"left_tee", XC_left_tee}, {"leftbutton", XC_leftbutton}, {"ll_angle", XC_ll_angle}, {"lr_angle", XC_lr_angle}, {"man", XC_man}, {"middlebutton", XC_middlebutton}, {"mouse", XC_mouse}, {"pencil", XC_pencil}, {"pirate", XC_pirate}, {"plus", XC_plus}, {"question_arrow", XC_question_arrow}, {"right_ptr", XC_right_ptr}, {"right_side", XC_right_side}, {"right_tee", XC_right_tee}, {"rightbutton", XC_rightbutton}, {"rtl_logo", XC_rtl_logo}, {"sailboat", XC_sailboat}, {"sb_down_arrow", XC_sb_down_arrow}, {"sb_h_double_arrow", XC_sb_h_double_arrow}, {"sb_left_arrow", XC_sb_left_arrow}, {"sb_right_arrow", XC_sb_right_arrow}, {"sb_up_arrow", XC_sb_up_arrow}, {"sb_v_double_arrow", XC_sb_v_double_arrow}, {"sizing", XC_sizing}, {"spider", XC_spider}, {"spraycan", XC_spraycan}, {"star", XC_star}, {"target", XC_target}, {"tcross", XC_tcross}, {"top_left_arrow", XC_top_left_arrow}, {"top_left_corner", XC_top_left_corner}, {"top_right_corner", XC_top_right_corner}, {"top_side", XC_top_side}, {"top_tee", XC_top_tee}, {"trek", XC_trek}, {"ul_angle", XC_ul_angle}, {"umbrella", XC_umbrella}, {"ur_angle", XC_ur_angle}, {"watch", XC_watch}, {"x_cursor", XC_X_cursor}, {"xterm", XC_xterm}, }; int cond; int down = 0; int up = (sizeof cursor_table / sizeof cursor_table[0]) - 1; int middle; char temp[20]; char *s; if (!cursor_name || cursor_name[0] == 0 || strlen(cursor_name) >= sizeof temp) return -1; strcpy(temp, cursor_name); for (s = temp; *s != 0; s++) if (isupper(*s)) *s = tolower(*s); while (down <= up) { middle= (down + up) / 2; if ((cond = strcmp(temp, cursor_table[middle].name)) < 0) up = middle - 1; else if (cond > 0) down = middle + 1; else return cursor_table[middle].number; } return -1; } fvwm-2.6.7/libs/WinMagic.h0000644000175700017570000000071112773467232012260 00000000000000#ifndef LIB_WINMAGIC #define LIB_WINMAGIC void SlideWindow( Display *dpy, Window win, int s_x, int s_y, int s_w, int s_h, int e_x, int e_y, int e_w, int e_h, int steps, int delay_ms, float *ppctMovement, Bool do_sync, Bool use_hints); Window GetTopAncestorWindow(Display *dpy, Window child); int GetEqualSizeChildren( Display *dpy, Window parent, int depth, VisualID visualid, Colormap colormap, Window **ret_children); #endif /* LIB_WINMAGIC */ fvwm-2.6.7/libs/charmap.c0000644000175700017570000000675213001406607012163 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "charmap.h" #include "wcontext.h" #include "safemalloc.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Turns a string context of context or modifier values into an array of * true/false values (bits). */ int charmap_string_to_mask( int *ret, const char *string, charmap_t *table, char *errstring) { int len = strlen(string); int error = 0; int i; *ret = 0; for (i = 0; i < len; ++i) { int found_match; int j; char c; c = tolower(string[i]); for (j = 0, found_match = 0; table[j].key != 0; j++) { if (table[j].key == c) { *ret |= table[j].value; found_match = 1; break; } } if (!found_match) { fputs("charmap_string_to_mask: ", stderr); if (errstring != NULL) { fputs(errstring, stderr); } fputc(' ', stderr); fputc(c, stderr); fputc('\n', stderr); error = 1; } } return error; } /* Reverse function of above. Returns zero if no matching mask is found in the * table. */ char charmap_mask_to_char(int mask, charmap_t *table) { char c; for (c = 0; table->key != 0; table++) { if (mask == table->value) { c = table->key; break; } } return c; } /* Used from "PrintInfo Bindings". */ char *charmap_table_to_string(int mask, charmap_t *table) { char *allmods; int modmask; char c[2]; c[1] = 0; modmask = mask; allmods = safemalloc(sizeof(table->value) * 8 + 1); *allmods = 0; for (; table->key !=0; table++) { c[0] = toupper(table->key); /* Don't explicitly match "A" for any context as doing so * means we never see the individual bindings. Incremental * matching here for AnyContext is disasterous.*/ if ((modmask & table->value) && (table->value != C_ALL)) { /* incremental match */ strcat(allmods, c); modmask &= ~table->value; } else if (mask == table->value) { /* exact match */ strcpy(allmods, c); break; } } return allmods; } fvwm-2.6.7/libs/XError.h0000644000175700017570000000070512773467232012006 00000000000000#ifndef FERROR_H #define FERROR_H void do_coredump(void); /* not really a wrapper, but useful and X related */ void PrintXErrorAndCoredump(Display *dpy, XErrorEvent *error, char *MyName); typedef int (*ferror_handler_t)(Display *, XErrorEvent *); void ferror_set_temp_error_handler(ferror_handler_t new_handler); void ferror_reset_temp_error_handler(void); int ferror_call_next_error_handler(Display *dpy, XErrorEvent *error); #endif /* FERROR_H */ fvwm-2.6.7/libs/Grab.c0000644000175700017570000000365112773467232011436 00000000000000/* -*-c-*- */ /* 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 */ /* ** MyXGrabServer & MyXUngrabServer - to handle nested grab server calls */ #include "config.h" #include "Grab.h" /* Made into global for module interface. See module.c. */ int myxgrabcount = 0; static unsigned int keyboard_grab_count = 0; static unsigned int key_grab_count = 0; void MyXGrabServer(Display *disp) { if (myxgrabcount == 0) { XSync(disp, 0); XGrabServer(disp); } XSync(disp, 0); ++myxgrabcount; } void MyXUngrabServer(Display *disp) { if (--myxgrabcount < 0) /* should never happen */ { myxgrabcount = 0; } if (myxgrabcount == 0) { XUngrabServer(disp); } XSync(disp, 0); } void MyXGrabKeyboard(Display *dpy) { keyboard_grab_count++; XGrabKeyboard( dpy, RootWindow(dpy, DefaultScreen(dpy)), False, GrabModeAsync, GrabModeAsync, CurrentTime); return; } void MyXUngrabKeyboard(Display *dpy) { if (keyboard_grab_count > 0) { keyboard_grab_count--; } if (keyboard_grab_count == 0 && key_grab_count == 0) { XUngrabKeyboard(dpy, CurrentTime); } return; } void MyXGrabKey(Display *disp) { key_grab_count++; return; } void MyXUngrabKey(Display *disp) { if (key_grab_count > 0) { key_grab_count--; keyboard_grab_count++; MyXUngrabKeyboard(disp); } return; } fvwm-2.6.7/libs/FRenderInit.c0000644000175700017570000000631212773467232012731 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwmlib.h" #include "PictureBase.h" #include "FRenderInit.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ Bool FRenderExtensionSupported = False; int FRenderErrorBase = -10000; int FRenderMajorOpCode = -10000; int FRenderAlphaDepth = 0; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ void FRenderInit(Display *dpy) { int event_basep; FRenderAlphaDepth = 8; if (!XRenderSupport || !(FRenderExtensionSupported = XQueryExtension( dpy, "RENDER", &FRenderMajorOpCode, &event_basep, &FRenderErrorBase))) { int *pmf = NULL; int i,n; int alpha_depth = 0; FRenderErrorBase = -10000; FRenderMajorOpCode = -10000; FRenderExtensionSupported = 0; pmf = XListDepths(dpy, DefaultScreen(dpy), &n); if (pmf) { i = 0; while(i < n) { if (pmf[i] == 8) { alpha_depth = 8; i = n-1; } else if (pmf[i] >= 8 && (pmf[i] < alpha_depth || alpha_depth == 0)) { alpha_depth = pmf[i]; } i++; } XFree(pmf); } FRenderAlphaDepth = alpha_depth; } } int FRenderGetErrorCodeBase(void) { return FRenderErrorBase; } int FRenderGetMajorOpCode(void) { return FRenderMajorOpCode; } Bool FRenderGetExtensionSupported(void) { return FRenderExtensionSupported; } int FRenderGetAlphaDepth(void) { return FRenderAlphaDepth; } Bool FRenderGetErrorText(int code, char *msg) { if (XRenderSupport) { static char *error_names[] = { "BadPictFormat", "BadPicture", "BadPictOp", "BadGlyphSet", "BadGlyph" }; if (code >= FRenderErrorBase && code <= FRenderErrorBase + (sizeof(error_names) / sizeof(char *)) -1) { sprintf(msg, "%s\n", error_names[code - FRenderErrorBase]); return 1; } } return 0; } fvwm-2.6.7/libs/safemalloc.c0000644000175700017570000000533213001406607012647 00000000000000/* -*-c-*- */ /* 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 #include "safemalloc.h" static void alloc_failed(char *c, int length) { fprintf(stderr, "%s of %d bytes failed. Exiting\n", c, length); exit(1); } /*********************************************************************** * * Procedure: * safemalloc - mallocs specified space or exits if there's a * problem * ***********************************************************************/ char *safemalloc(int length) { char *ptr; if(length <= 0) length = 1; ptr = malloc(length); if(ptr == (char *)0) { /* doesn't return */ alloc_failed("malloc", length); } return ptr; } /*********************************************************************** * * Procedure: * safecalloc - callocs specified space or exits if there's a * problem * ***********************************************************************/ char *safecalloc(int num, int length) { char *ptr; ptr = calloc(num, length); if(ptr == (char *)0) { /* doesn't return */ alloc_failed("calloc", length); } return ptr; } /*********************************************************************** * * Procedure: * saferealloc - reallocs specified space or exits if there's a * problem * ***********************************************************************/ char *saferealloc(char *src, int length) { char *ptr; if (src) ptr = realloc((void *)src, length); else ptr = malloc(length); if(ptr == (char *)0) { /* doesn't return */ alloc_failed("realloc", length); } return ptr; } /*********************************************************************** * * Procedure: * safestrdup - duplicates a string or exits if there's a * problem * ***********************************************************************/ char *safestrdup(const char *src) { char *cpy = strdup(src); if (cpy == (char *)0) { /* doesn't return */ alloc_failed("strdup", strlen(src) + (size_t)1); } return cpy; } fvwm-2.6.7/libs/FSMlib.h0000644000175700017570000006136012773467232011705 00000000000000/* -*-c-*- */ #ifndef FSMlib_H #define FSMlib_H /* ---------------------------- included header files ---------------------- */ #include "config.h" #ifdef SESSION #define SessionSupport 1 #else #define SessionSupport 0 #endif #if SessionSupport #include #include #endif /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ #if SessionSupport /* SM.h */ #define FSmProtoMajor SmProtoMajor #define FSmProtoMinor SmProtoMinor #define FSmInteractStyleNone SmInteractStyleNone #define FSmInteractStyleErrors SmInteractStyleErrors #define FSmInteractStyleAny SmInteractStyleAny #define FSmDialogError SmDialogError #define FSmDialogNormal SmDialogNormal #define FSmSaveGlobal SmSaveGlobal #define FSmSaveLocal SmSaveLocal #define FSmSaveBoth SmSaveBoth #define FSmRestartIfRunning SmRestartIfRunning #define FSmRestartAnyway SmRestartAnyway #define FSmRestartImmediately SmRestartImmediately #define FSmRestartNever SmRestartNever #define FSmCloneCommand SmCloneCommand #define FSmCurrentDirectory SmCurrentDirectory #define FSmDiscardCommand SmDiscardCommand #define FSmEnvironment SmEnvironment #define FSmProcessID SmProcessID #define FSmProgram SmProgram #define FSmRestartCommand SmRestartCommand #define FSmResignCommand SmResignCommand #define FSmRestartStyleHint SmRestartStyleHint #define FSmShutdownCommand SmShutdownCommand #define FSmUserID SmUserID #define FSmCARD8 SmCARD8 #define FSmARRAY8 SmARRAY8 #define FSmLISTofARRAY8 SmLISTofARRAY8 #define FSM_Error SM_Error #define FSM_RegisterClient SM_RegisterClient #define FSM_RegisterClientReply SM_RegisterClientReply #define FSM_SaveYourself SM_SaveYourself #define FSM_SaveYourselfRequest SM_SaveYourselfRequest #define FSM_InteractRequest SM_InteractRequest #define FSM_Interact SM_Interact #define FSM_InteractDone SM_InteractDone #define FSM_SaveYourselfDone SM_SaveYourselfDone #define FSM_Die SM_Die #define FSM_ShutdownCancelled SM_ShutdownCancelled #define FSM_CloseConnection SM_CloseConnection #define FSM_SetProperties SM_SetProperties #define FSM_DeleteProperties SM_DeleteProperties #define FSM_GetProperties SM_GetProperties #define FSM_PropertiesReply SM_PropertiesReply #define FSM_SaveYourselfPhase2Request SM_SaveYourselfPhase2Request #define FSM_SaveYourselfPhase2 SM_SaveYourselfPhase2 #define FSM_SaveComplete SM_SaveComplete /* ICE.h */ #define FIceProtoMajor IceProtoMajor #define FIceProtoMinor IceProtoMinor #define FIceLSBfirst IceLSBfirst #define FIceMSBfirst IceMSBfirst #define FICE_Error ICE_Error #define FICE_ByteOrder ICE_ByteOrder #define FICE_ConnectionSetup ICE_ConnectionSetup #define FICE_AuthRequired ICE_AuthRequired #define FICE_AuthReply ICE_AuthReply #define FICE_AuthNextPhase ICE_AuthNextPhase #define FICE_ConnectionReply ICE_ConnectionReply #define FICE_ProtocolSetup ICE_ProtocolSetup #define FICE_ProtocolReply ICE_ProtocolReply #define FICE_Ping ICE_Ping #define FICE_PingReply ICE_PingReply #define FICE_WantToClose ICE_WantToClose #define FICE_NoClose ICE_NoClose #define FIceCanContinue IceCanContinue #define FIceFatalToProtocol IceFatalToProtocol #define FIceFatalToConnection IceFatalToConnection #define FIceBadMinor IceBadMinor #define FIceBadState IceBadState #define FIceBadLength IceBadLength #define FIceBadValue IceBadValue #define FIceBadMajor IceBadMajor #define FIceNoAuth IceNoAuth #define FIceNoVersion IceNoVersion #define FIceSetupFailed IceSetupFailed #define FIceAuthRejected IceAuthRejected #define FIceAuthFailed IceAuthFailed #define FIceProtocolDuplicate IceProtocolDuplicate #define FIceMajorOpcodeDuplicate IceMajorOpcodeDuplicate #define FIceUnknownProtocol IceUnknownProtocol /* SMlib.h */ #define FSmsRegisterClientProcMask SmsRegisterClientProcMask #define FSmsInteractRequestProcMask SmsInteractRequestProcMask #define FSmsInteractDoneProcMask SmsInteractDoneProcMask #define FSmsSaveYourselfRequestProcMask SmsSaveYourselfRequestProcMask #define FSmsSaveYourselfP2RequestProcMask SmsSaveYourselfP2RequestProcMask #define FSmsSaveYourselfDoneProcMask SmsSaveYourselfDoneProcMask #define FSmsCloseConnectionProcMask SmsCloseConnectionProcMask #define FSmsSetPropertiesProcMask SmsSetPropertiesProcMask #define FSmsDeletePropertiesProcMask SmsDeletePropertiesProcMask #define FSmsGetPropertiesProcMask SmsGetPropertiesProcMask #define FSmcSaveYourselfProcMask SmcSaveYourselfProcMask #define FSmcDieProcMask SmcDieProcMask #define FSmcSaveCompleteProcMask SmcSaveCompleteProcMask #define FSmcShutdownCancelledProcMask SmcShutdownCancelledProcMask /* ICEutil.h */ #define FIceAuthLockSuccess IceAuthLockSuccess #define FIceAuthLockError IceAuthLockError #define FIceAuthLockTimeout IceAuthLockTimeout #else /* !SessionSupport */ /* SM.h */ #define FSmProtoMajor 1 #define FSmProtoMinor 0 #define FSmInteractStyleNone 0 #define FSmInteractStyleErrors 1 #define FSmInteractStyleAny 2 #define FSmDialogError 0 #define FSmDialogNormal 1 #define FSmSaveGlobal 0 #define FSmSaveLocal 1 #define FSmSaveBoth 2 #define FSmRestartIfRunning 0 #define FSmRestartAnyway 1 #define FSmRestartImmediately 2 #define FSmRestartNever 3 #define FSmCloneCommand "CloneCommand" #define FSmCurrentDirectory "CurrentDirectory" #define FSmDiscardCommand "DiscardCommand" #define FSmEnvironment "Environment" #define FSmProcessID "ProcessID" #define FSmProgram "Program" #define FSmRestartCommand "RestartCommand" #define FSmResignCommand "ResignCommand" #define FSmRestartStyleHint "RestartStyleHint" #define FSmShutdownCommand "ShutdownCommand" #define FSmUserID "UserID" #define FSmCARD8 "CARD8" #define FSmARRAY8 "ARRAY8" #define FSmLISTofARRAY8 "LISTofARRAY8" #define FSM_Error 0 #define FSM_RegisterClient 1 #define FSM_RegisterClientReply 2 #define FSM_SaveYourself 3 #define FSM_SaveYourselfRequest 4 #define FSM_InteractRequest 5 #define FSM_Interact 6 #define FSM_InteractDone 7 #define FSM_SaveYourselfDone 8 #define FSM_Die 9 #define FSM_ShutdownCancelled 10 #define FSM_CloseConnection 11 #define FSM_SetProperties 12 #define FSM_DeleteProperties 13 #define FSM_GetProperties 14 #define FSM_PropertiesReply 15 #define FSM_SaveYourselfPhase2Request 16 #define FSM_SaveYourselfPhase2 17 #define FSM_SaveComplete 18 /* ICE.h */ #define FIceProtoMajor 1 #define FIceProtoMinor 0 #define FIceLSBfirst 0 #define FIceMSBfirst 1 #define FICE_Error 0 #define FICE_ByteOrder 1 #define FICE_ConnectionSetup 2 #define FICE_AuthRequired 3 #define FICE_AuthReply 4 #define FICE_AuthNextPhase 5 #define FICE_ConnectionReply 6 #define FICE_ProtocolSetup 7 #define FICE_ProtocolReply 8 #define FICE_Ping 9 #define FICE_PingReply 10 #define FICE_WantToClose 11 #define FICE_NoClose 12 #define FIceCanContinue 0 #define FIceFatalToProtocol 1 #define FIceFatalToConnection 2 #define FIceBadMinor 0x8000 #define FIceBadState 0x8001 #define FIceBadLength 0x8002 #define FIceBadValue 0x8003 #define FIceBadMajor 0 #define FIceNoAuth 1 #define FIceNoVersion 2 #define FIceSetupFailed 3 #define FIceAuthRejected 4 #define FIceAuthFailed 5 #define FIceProtocolDuplicate 6 #define FIceMajorOpcodeDuplicate 7 #define FIceUnknownProtocol 8 /* SMlib.h */ #define FSmsRegisterClientProcMask (1L << 0) #define FSmsInteractRequestProcMask (1L << 1) #define FSmsInteractDoneProcMask (1L << 2) #define FSmsSaveYourselfRequestProcMask (1L << 3) #define FSmsSaveYourselfP2RequestProcMask (1L << 4) #define FSmsSaveYourselfDoneProcMask (1L << 5) #define FSmsCloseConnectionProcMask (1L << 6) #define FSmsSetPropertiesProcMask (1L << 7) #define FSmsDeletePropertiesProcMask (1L << 8) #define FSmsGetPropertiesProcMask (1L << 9) #define FSmcSaveYourselfProcMask (1L << 0) #define FSmcDieProcMask (1L << 1) #define FSmcSaveCompleteProcMask (1L << 2) #define FSmcShutdownCancelledProcMask (1L << 3) /* ICEutil.h */ #define IceAuthLockSuccess 0 #define IceAuthLockError 1 #define IceAuthLockTimeout 2 #endif /* SessionSupport */ /* ---------------------------- type definitions --------------------------- */ #if SessionSupport /* ICElib.h */ typedef IcePointer FIcePointer; #define FIcePoAuthHaveReply IcePoAuthHaveReply #define FIcePoAuthRejected IcePoAuthRejected #define FIcePoAuthFailed IcePoAuthFailed #define FIcePoAuthDoneCleanup IcePoAuthDoneCleanup typedef IcePoAuthStatus FIcePoAuthStatus; #define FIcePaAuthContinue IcePaAuthContinue #define FIcePaAuthAccepted IcePaAuthAccepted #define FIcePaAuthRejected IcePaAuthRejected #define FIcePaAuthFailed IcePaAuthFailed typedef IcePaAuthStatus FIcePaAuthStatus; #define FIceConnectPending IceConnectPending #define FIceConnectAccepted IceConnectAccepted #define FIceConnectRejected IceConnectRejected #define FIceConnectIOError IceConnectIOError typedef IceConnectStatus FIceConnectStatus; #define FIceProtocolSetupSuccess IceProtocolSetupSuccess #define FIceProtocolSetupFailure IceProtocolSetupFailure #define FIceProtocolSetupIOError IceProtocolSetupIOError #define FIceProtocolAlreadyActive IceProtocolAlreadyActive typedef IceProtocolSetupStatus FIceProtocolSetupStatus; #define FIceAcceptSuccess IceAcceptSuccess #define FIceAcceptFailure IceAcceptFailure #define FIceAcceptBadMalloc IceAcceptBadMalloc typedef IceAcceptStatus FIceAcceptStatus; #define FIceClosedNow IceClosedNow #define FIceClosedASAP IceClosedASAP #define FIceConnectionInUse IceConnectionInUse #define FIceStartedShutdownNegotiation IceStartedShutdownNegotiation typedef IceCloseStatus FIceCloseStatus; #define FIceProcessMessagesSuccess IceProcessMessagesSuccess #define FIceProcessMessagesIOError IceProcessMessagesIOError #define FIceProcessMessagesConnectionClosed IceProcessMessagesConnectionClosed typedef IceProcessMessagesStatus FIceProcessMessagesStatus; typedef IceReplyWaitInfo FIceReplyWaitInfo; typedef IceConn FIceConn; typedef IceListenObj FIceListenObj; typedef IceWatchProc FIceWatchProc; typedef IcePoProcessMsgProc FIcePoProcessMsgProc; typedef IcePaProcessMsgProc FIcePaProcessMsgProc; typedef IcePoVersionRec FIcePoVersionRec; typedef IcePaVersionRec FIcePaVersionRec; typedef IcePoAuthProc FIcePoAuthProc; typedef IcePaAuthProc FIcePaAuthProc; typedef IceHostBasedAuthProc FIceHostBasedAuthProc; typedef IceProtocolSetupProc FIceProtocolSetupProc; typedef IceProtocolActivateProc FIceProtocolActivateProc; typedef IceIOErrorProc FIceIOErrorProc; typedef IcePingReplyProc FIcePingReplyProc; typedef IceErrorHandler FIceErrorHandler; typedef IceIOErrorHandler FIceIOErrorHandler; /* SMlib.h */ typedef SmPointer FSmPointer; typedef SmcConn FSmcConn; typedef SmsConn FSmsConn; typedef SmPropValue FSmPropValue; typedef SmProp FSmProp; #define FSmcClosedNow SmcClosedNow #define FSmcClosedASAP FSmcClosedASAP #define FSmcConnectionInUse FSmcConnectionInUse typedef SmcCloseStatus FSmcCloseStatus; typedef SmcSaveYourselfProc FSmcSaveYourselfProc; typedef SmcSaveYourselfPhase2Proc FSmcSaveYourselfPhase2Proc; typedef SmcInteractProc FSmcInteractProc; typedef SmcDieProc FSmcDieProc; typedef SmcShutdownCancelledProc FSmcShutdownCancelledProc; typedef SmcSaveCompleteProc FSmcSaveCompleteProc; typedef SmcPropReplyProc FSmcPropReplyProc; typedef SmcCallbacks FSmcCallbacks; typedef SmsRegisterClientProc FSmsRegisterClientProc; typedef SmsInteractRequestProc FSmsInteractRequestProc; typedef SmsInteractDoneProc FSmsInteractDoneProc; typedef SmsSaveYourselfRequestProc FSmsSaveYourselfRequestProc; typedef SmsSaveYourselfPhase2RequestProc FSmsSaveYourselfPhase2RequestProc; typedef SmsSaveYourselfDoneProc FSmsSaveYourselfDoneProc; typedef SmsCloseConnectionProc FSmsCloseConnectionProc; typedef SmsSetPropertiesProc FSmsSetPropertiesProc; typedef SmsDeletePropertiesProc FSmsDeletePropertiesProc; typedef SmsGetPropertiesProc FSmsGetPropertiesProc; typedef SmsCallbacks FSmsCallbacks; typedef SmsNewClientProc FSmsNewClientProc; typedef SmcErrorHandler FSmcErrorHandler; typedef SmsErrorHandler FSmsErrorHandler; /* ICEutil.h */ typedef IceAuthFileEntry FIceAuthFileEntry; typedef IceAuthDataEntry FIceAuthDataEntry; #else /* !SessionSupport */ #ifdef __STDC__ typedef void *FIcePointer; #else typedef char *FIcePointer; #endif /* ICElib.h */ typedef enum { FIcePoAuthHaveReply, FIcePoAuthRejected, FIcePoAuthFailed, FIcePoAuthDoneCleanup } FIcePoAuthStatus; typedef enum { FIcePaAuthContinue, FIcePaAuthAccepted, FIcePaAuthRejected, FIcePaAuthFailed } FIcePaAuthStatus; typedef enum { FIceConnectPending,FIceConnectAccepted,FIceConnectRejected,FIceConnectIOError } FIceConnectStatus; typedef enum { FIceProtocolSetupSuccess,FIceProtocolSetupFailure,FIceProtocolSetupIOError, FIceProtocolAlreadyActive } FIceProtocolSetupStatus; typedef enum { FIceAcceptSuccess,FIceAcceptFailure,FIceAcceptBadMalloc } FIceAcceptStatus; typedef enum { FIceClosedNow,FIceClosedASAP,FIceConnectionInUse, FIceStartedShutdownNegotiation } FIceCloseStatus; typedef enum { FIceProcessMessagesSuccess,FIceProcessMessagesIOError, FIceProcessMessagesConnectionClosed } FIceProcessMessagesStatus; typedef struct { unsigned long sequence_of_request; int major_opcode_of_request; int minor_opcode_of_request; FIcePointer reply; } FIceReplyWaitInfo; typedef void *FIceConn; typedef void *FIceListenObj; typedef void (*FIceWatchProc) ( #ifdef __STDC__ FIceConn, FIcePointer, Bool, FIcePointer * #endif ); typedef void (*FIcePoProcessMsgProc) ( #ifdef __STDC__ FIceConn, FIcePointer, int, unsigned long, Bool, FIceReplyWaitInfo *, Bool * #endif ); typedef void (*FIcePaProcessMsgProc) ( #ifdef __STDC__ FIceConn, FIcePointer, int, unsigned long, Bool #endif ); typedef struct { int major_version; int minor_version; FIcePoProcessMsgProc process_msg_proc; } FIcePoVersionRec; typedef struct { int major_version; int minor_version; FIcePaProcessMsgProc process_msg_proc; } FIcePaVersionRec; typedef FIcePoAuthStatus (*FIcePoAuthProc) ( #ifdef __STDC__ FIceConn, FIcePointer *, Bool, Bool, int, FIcePointer, int *, FIcePointer *, char ** #endif ); typedef FIcePaAuthStatus (*FIcePaAuthProc) ( #ifdef __STDC__ FIceConn, FIcePointer *, Bool, int, FIcePointer, int *, FIcePointer *, char ** #endif ); typedef Bool (*FIceHostBasedAuthProc) ( #ifdef __STDC__ char * #endif ); typedef Status (*FIceProtocolSetupProc) ( #ifdef __STDC__ FIceConn, int, int, char *, char *, FIcePointer *, char ** #endif ); typedef void (*FIceProtocolActivateProc) ( #ifdef __STDC__ FIceConn, FIcePointer #endif ); typedef void (*FIceIOErrorProc) ( #ifdef __STDC__ FIceConn #endif ); typedef void (*FIcePingReplyProc) ( #ifdef __STDC__ FIceConn, FIcePointer #endif ); typedef void (*FIceErrorHandler) ( #ifdef __STDC__ FIceConn, Bool, int, unsigned long, int, int, FIcePointer #endif ); typedef void (*FIceIOErrorHandler) ( #ifdef __STDC__ FIceConn /* iceConn */ #endif ); /* SMlib.h */ typedef FIcePointer FSmPointer; typedef void *FSmcConn; typedef void *FSmsConn; typedef struct { int length; FSmPointer value; } FSmPropValue; typedef struct { char *name; char *type; int num_vals; FSmPropValue *vals; } FSmProp; typedef enum { FSmcClosedNow, FSmcClosedASAP, FSmcConnectionInUse } FSmcCloseStatus; typedef void (*FSmcSaveYourselfProc) ( #ifdef __STDC__ FSmcConn, FSmPointer, int, Bool, int, Bool #endif ); typedef void (*FSmcSaveYourselfPhase2Proc) ( #ifdef __STDC__ FSmcConn, FSmPointer #endif ); typedef void (*FSmcInteractProc) ( #ifdef __STDC__ FSmcConn, FSmPointer #endif ); typedef void (*FSmcDieProc) ( #ifdef __STDC__ FSmcConn, FSmPointer #endif ); typedef void (*FSmcShutdownCancelledProc) ( #ifdef __STDC__ FSmcConn, FSmPointer #endif ); typedef void (*FSmcSaveCompleteProc) ( #ifdef __STDC__ FSmcConn, FSmPointer #endif ); typedef void (*FSmcPropReplyProc) ( #ifdef __STDC__ FSmcConn, FSmPointer, int, FSmProp ** #endif ); typedef struct { struct { FSmcSaveYourselfProc callback; FSmPointer client_data; } save_yourself; struct { FSmcDieProc callback; FSmPointer client_data; } die; struct { FSmcSaveCompleteProc callback; FSmPointer client_data; } save_complete; struct { FSmcShutdownCancelledProc callback; FSmPointer client_data; } shutdown_cancelled; } FSmcCallbacks; typedef Status (*FSmsRegisterClientProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, char * #endif ); typedef void (*FSmsInteractRequestProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, int #endif ); typedef void (*FSmsInteractDoneProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, Bool #endif ); typedef void (*FSmsSaveYourselfRequestProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, int, Bool, int, Bool, Bool #endif ); typedef void (*FSmsSaveYourselfPhase2RequestProc) ( #ifdef __STDC__ FSmsConn, FSmPointer #endif ); typedef void (*FSmsSaveYourselfDoneProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, Bool #endif ); typedef void (*FSmsCloseConnectionProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, int, char ** #endif ); typedef void (*FSmsSetPropertiesProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, int, FSmProp ** #endif ); typedef void (*FSmsDeletePropertiesProc) ( #ifdef __STDC__ FSmsConn, FSmPointer, int, char ** #endif ); typedef void (*FSmsGetPropertiesProc) ( #ifdef __STDC__ FSmsConn, FSmPointer #endif ); typedef struct { struct { FSmsRegisterClientProc callback; FSmPointer manager_data; } register_client; struct { FSmsInteractRequestProc callback; FSmPointer manager_data; } interact_request; struct { FSmsInteractDoneProc callback; FSmPointer manager_data; } interact_done; struct { FSmsSaveYourselfRequestProc callback; FSmPointer manager_data; } save_yourself_request; struct { FSmsSaveYourselfPhase2RequestProc callback; FSmPointer manager_data; } save_yourself_phase2_request; struct { FSmsSaveYourselfDoneProc callback; FSmPointer manager_data; } save_yourself_done; struct { FSmsCloseConnectionProc callback; FSmPointer manager_data; } close_connection; struct { FSmsSetPropertiesProc callback; FSmPointer manager_data; } set_properties; struct { FSmsDeletePropertiesProc callback; FSmPointer manager_data; } delete_properties; struct { FSmsGetPropertiesProc callback; FSmPointer manager_data; } get_properties; } FSmsCallbacks; typedef Status (*FSmsNewClientProc) ( #ifdef __STDC__ FSmsConn,FSmPointer, unsigned long *, FSmsCallbacks *, char ** #endif ); typedef void (*FSmcErrorHandler) ( #ifdef __STDC__ FSmcConn, Bool, int, unsigned long, int, int, FSmPointer #endif ); typedef void (*FSmsErrorHandler) ( #ifdef __STDC__ FSmsConn, Bool, int, unsigned long, int, int, FSmPointer #endif ); /* ICEutil.h */ typedef struct { char *protocol_name; unsigned short protocol_data_length; char *protocol_data; char *network_id; char *auth_name; unsigned short auth_data_length; char *auth_data; } FIceAuthFileEntry; typedef struct { char *protocol_name; char *network_id; char *auth_name; unsigned short auth_data_length; char *auth_data; } FIceAuthDataEntry; #endif /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ #if SessionSupport /* ICElib.h (no all) */ #define FIceSetIOErrorHandler(a) IceSetIOErrorHandler(a) #define FIceFreeListenObjs(a,b) IceFreeListenObjs(a,b) #define FIceConnectionNumber(a) IceConnectionNumber(a) #define FIceSetShutdownNegotiation(a,b) IceSetShutdownNegotiation(a,b) #define FIceCloseConnection(a) IceCloseConnection(a) #define FIceConnectionStatus(a) IceConnectionStatus(a) #define FIceAcceptConnection(a,b) IceAcceptConnection(a,b) #define FIceProcessMessages(a,b,c) IceProcessMessages(a,b,c) #define FIceListenForConnections(a,b,c,d) IceListenForConnections(a,b,c,d) #define FIceAddConnectionWatch(a,b) IceAddConnectionWatch(a,b) #define FIceGetListenConnectionNumber(a) IceGetListenConnectionNumber(a) #define FIceComposeNetworkIdList(a,b) IceComposeNetworkIdList(a,b) #define FIceGetListenConnectionString(a) IceGetListenConnectionString(a) #define FIceSetHostBasedAuthProc(a,b) IceSetHostBasedAuthProc(a,b) #define FIceConnectionString(a) IceConnectionString(a) /* SMlib.h */ #define FSmcOpenConnection(a,b,c,d,e,f,g,h,i,k) \ SmcOpenConnection(a,b,c,d,e,f,g,h,i,k) #define FSmcCloseConnection(a,b,c) SmcCloseConnection(a,b,c) #define FSmcModifyCallbacks(a,b,c) SmcModifyCallbacks(a,b,c) #define FSmcSetProperties(a,b,c) SmcSetProperties(a,b,c) #define FSmcDeleteProperties(a,b,c) SmcDeleteProperties(a,b,c) #define FSmcGetProperties(a,b,c) SmcGetProperties(a,b,c) #define FSmcInteractRequest(a,b,c,d) SmcInteractRequest(a,b,c,d) #define FSmcInteractDone(a,b) SmcInteractDone(a,b) #define FSmcRequestSaveYourself(a,b,c,d,e,f) SmcRequestSaveYourself(a,b,c,d,e,f) #define FSmcRequestSaveYourselfPhase2(a,b,c) SmcRequestSaveYourselfPhase2(a,b,c) #define FSmcSaveYourselfDone(a,b) SmcSaveYourselfDone(a,b) #define FSmcProtocolVersion(a) SmcProtocolVersion(a) #define FSmcProtocolRevision(a) SmcProtocolRevision(a) #define FSmcVendor(a) SmcVendor(a) #define FSmcRelease(a) SmcRelease(a) #define FSmcClientID(a) SmcClientID(a) #define FSmcGetIceConnection(a) SmcGetIceConnection(a) #define FSmsInitialize(a,b,c,d,e,f,g) SmsInitialize(a,b,c,d,e,f,g) #define FSmsClientHostName(a) SmsClientHostName(a) #define FSmsGenerateClientID(a) SmsGenerateClientID(a) #define FSmsRegisterClientReply(a,b) SmsRegisterClientReply(a,b) #define FSmsSaveYourself(a,b,c,d,e) SmsSaveYourself(a,b,c,d,e) #define FSmsSaveYourselfPhase2(a) SmsSaveYourselfPhase2(a) #define FSmsInteract(a) SmsInteract(a) #define FSmsDie(a) SmsDie(a) #define FSmsSaveComplete(a) SmsSaveComplete(a) #define FSmsShutdownCancelled(a) SmsShutdownCancelled(a) #define FSmsReturnProperties(a,b,c) SmsReturnProperties(a,b,c) #define FSmsCleanUp(a) SmsCleanUp(a) #define FSmsProtocolVersion(a) SmsProtocolVersion(a) #define FSmsProtocolRevision(a) SmsProtocolRevision(a) #define FSmsClientID(a) SmsClientID(a) #define FSmsGetIceConnection(a) SmsGetIceConnection(a) #define FSmcSetErrorHandler(a) SmcSetErrorHandler(a) #define FSmsSetErrorHandler(a) SmsSetErrorHandler(a) #define FSmFreeProperty(a) SmFreeProperty(a) #define FSmFreeReasons(a,b) SmFreeReasons(a,b) /* ICEutils.h */ #define FIceAuthFileName(a) IceAuthFileName(a) #define FIceLockAuthFile(a,b,c,d) IceLockAuthFile(a,b,c,d) #define FIceUnlockAuthFile(a) IceUnlockAuthFile(a) #define FIceReadAuthFileEntry(a) IceReadAuthFileEntry(a) #define FIceFreeAuthFileEntry(a) IceFreeAuthFileEntry(a) #define FIceWriteAuthFileEntry(a,b) IceWriteAuthFileEntry(a,b) #define FIceGetAuthFileEntry(a,b,c) IceGetAuthFileEntry(a,b,c) #define FIceGenerateMagicCookie(a) IceGenerateMagicCookie(a) #define FIceSetPaAuthData(a,b) IceSetPaAuthData(a,b) #else /* ICElib.h (no all) */ #define FIceSetIOErrorHandler(a) NULL #define FIceFreeListenObjs(a,b) #define FIceConnectionNumber(a) 0 #define FIceSetShutdownNegotiation(a,b) #define FIceCloseConnection(a) 0 #define FIceConnectionStatus(a) 0 #define FIceAcceptConnection(a,b) NULL #define FIceProcessMessages(a,b,c) 0 #define FIceListenForConnections(a,b,c,d) 0 #define FIceAddConnectionWatch(a,b) 0 #define FIceGetListenConnectionNumber(a) 0 #define FIceComposeNetworkIdList(a,b) NULL #define FIceGetListenConnectionString(a) NULL #define FIceSetHostBasedAuthProc(a,b) #define FIceConnectionString(a) NULL /* SMlib.h */ #define FSmcOpenConnection(a,b,c,d,e,f,g,h,i,k) NULL #define FSmcCloseConnection(a,b,c) 0 #define FSmcModifyCallbacks(a,b,c) #define FSmcSetProperties(a,b,c) #define FSmcDeleteProperties(a,b,c) #define FSmcGetProperties(a,b,c) 0 #define FSmcInteractRequest(a,b,c,d) 0 #define FSmcInteractDone(a,b) #define FSmcRequestSaveYourself(a,b,c,d,e,f) #define FSmcRequestSaveYourselfPhase2(a,b,c) 0 #define FSmcSaveYourselfDone(a,b) #define FSmcProtocolVersion(a) 0 #define FSmcProtocolRevision(a) 0 #define FSmcVendor(a) NULL #define FSmcRelease(a) NULL #define FSmcClientID(a) NULL #define FSmcGetIceConnection(a) NULL #define FSmsInitialize(a,b,c,d,e,f,g) 0 #define FSmsClientHostName(a) NULL #define FSmsGenerateClientID(a) NULL #define FSmsRegisterClientReply(a,b) 0 #define FSmsSaveYourself(a,b,c,d,e) #define FSmsSaveYourselfPhase2(a) #define FSmsInteract(a) #define FSmsDie(a) #define FSmsSaveComplete(a) #define FSmsShutdownCancelled(a) #define FSmsReturnProperties(a,b,c) #define FSmsCleanUp(a) #define FSmsProtocolVersion(a) 0 #define FSmsProtocolRevision(a) 0 #define FSmsClientID(a) NULL #define FSmsGetIceConnection(a) NULL #define FSmcSetErrorHandler(a) NULL #define FSmsSetErrorHandler(a) NULL #define FSmFreeProperty(a) #define FSmFreeReasons(a,b) /* ICEutils.h */ #define FIceAuthFileName(a) NULL #define FIceLockAuthFile(a,b,c,d) 0 #define FIceUnlockAuthFile(a) #define FIceReadAuthFileEntry(a) NULL #define FIceFreeAuthFileEntry(a) #define FIceWriteAuthFileEntry(a,b) 0 #define FIceGetAuthFileEntry(a,b,c) NULL #define FIceGenerateMagicCookie(a) NULL #define FIceSetPaAuthData(a,b) #endif #endif /* FSMlib_H */ fvwm-2.6.7/libs/Fft.c0000644000175700017570000003357113003342500011257 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwmlib.h" #include "wild.h" #include "Strings.h" #include "Flocale.h" #include "Fft.h" #include "FlocaleCharset.h" #include "FftInterface.h" #include "FRenderInit.h" #include "PictureBase.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ #define FFT_SET_ROTATED_90_MATRIX(m) \ ((m)->xx = (m)->yy = 0, (m)->xy = 1, (m)->yx = -1) #define FFT_SET_ROTATED_270_MATRIX(m) \ ((m)->xx = (m)->yy = 0, (m)->xy = -1, (m)->yx = 1) #define FFT_SET_ROTATED_180_MATRIX(m) \ ((m)->xx = (m)->yy = -1, (m)->xy = (m)->yx = 0) /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Display *fftdpy = NULL; static int fftscreen; static int fft_initialized = False; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void init_fft(Display *dpy) { fftdpy = dpy; fftscreen = DefaultScreen(dpy); fft_initialized = True; } static FftChar16 *FftUtf8ToFftString16(unsigned char *str, int len, int *nl) { FftChar16 *new; int i = 0, j= 0; new = (FftChar16 *)safemalloc((len+1)*sizeof(FftChar16)); while(i < len && str[i] != 0) { if (str[i] <= 0x7f) { new[j] = str[i]; } else if (str[i] <= 0xdf && i+1 < len) { new[j] = ((str[i] & 0x1f) << 6) + (str[i+1] & 0x3f); i++; } else if (i+2 < len) { new[j] = ((str[i] & 0x0f) << 12) + ((str[i+1] & 0x3f) << 6) + (str[i+2] & 0x3f); i += 2; } i++; j++; } *nl = j; return new; } static void FftSetupEncoding( Display *dpy, FftFontType *fftf, char *encoding, char *module) { FlocaleCharset *fc; if (!FftSupport || fftf == NULL) return; fftf->encoding = NULL; fftf->str_encoding = NULL; if (encoding != NULL) { fftf->str_encoding = encoding; } if (FftSupportUseXft2) { if (encoding != NULL) { fftf->encoding = encoding; } else if ((fc = FlocaleCharsetGetDefaultCharset(dpy,NULL)) != NULL && StrEquals(fc->x,FLC_FFT_ENCODING_ISO8859_1)) { fftf->encoding = FLC_FFT_ENCODING_ISO8859_1; } else { fftf->encoding = FLC_FFT_ENCODING_ISO10646_1; } } else if (FftSupport) { int i = 0; FftPatternElt *e; Fft1Font *f; f = (Fft1Font *)fftf->fftfont; while(i < f->pattern->num) { e = &f->pattern->elts[i]; if (StrEquals(e->object, FFT_ENCODING) && e->values->value.u.s != NULL) { fftf->encoding = e->values->value.u.s; return; } i++; } } } static FftFont *FftGetRotatedFont( Display *dpy, FftFont *f, rotation_t rotation) { FftPattern *rotated_pat; FftMatrix r,b; FftMatrix *pm = NULL; FftFont *rf = NULL; if (f == NULL) return NULL; memset(&b, 0, sizeof(FftMatrix)); rotated_pat = FftPatternDuplicate(f->pattern); if (rotated_pat == NULL) { return NULL; } if (rotation == ROTATION_90) { FFT_SET_ROTATED_90_MATRIX(&r); } else if (rotation == ROTATION_180) { FFT_SET_ROTATED_180_MATRIX(&r); } else if (rotation == ROTATION_270) { FFT_SET_ROTATED_270_MATRIX(&r); } else { goto bail; } if ((FftPatternGetMatrix( rotated_pat, FFT_MATRIX, 0, &pm) == FftResultMatch) && pm) { /* rotate the matrice */ b.xx = r.xx * pm->xx + r.xy * pm->yx; b.xy = r.xx * pm->xy + r.xy * pm->yy; b.yx = r.yx * pm->xx + r.yy * pm->yx; b.yy = r.yx * pm->xy + r.yy * pm->yy; } else { b.xx = r.xx; b.xy = r.xy; b.yx = r.yx; b.yy = r.yy; } if (FftPatternDel(rotated_pat, FFT_MATRIX)) { /* nothing */ } if (!FftPatternAddMatrix(rotated_pat, FFT_MATRIX, &b)) { goto bail; } rf = FftFontOpenPattern(dpy, rotated_pat); bail: if (!rf && rotated_pat) { FftPatternDestroy(rotated_pat); } return rf; } void FftPDumyFunc(void) { } /* ---------------------------- interface functions ------------------------ */ void FftGetFontHeights( FftFontType *fftf, int *height, int *ascent, int *descent) { /* fft font height may be > fftfont->ascent + fftfont->descent, this * depends on the minspace value */ *height = fftf->fftfont->height; *ascent = fftf->fftfont->ascent; *descent = fftf->fftfont->descent; return; } void FftGetFontWidths( FlocaleFont *flf, int *max_char_width) { FGlyphInfo extents; memset(&extents, 0, sizeof(FGlyphInfo)); /* FIXME: max_char_width should not be use in the all fvwm! */ if (FftUtf8Support && FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { FftTextExtentsUtf8(fftdpy, flf->fftf.fftfont, (FftChar8*)"W", 1, &extents); } else { FftTextExtents8(fftdpy, flf->fftf.fftfont, (FftChar8*)"W", 1, &extents); } *max_char_width = extents.xOff; return; } FftFontType *FftGetFont(Display *dpy, char *fontname, char *module) { FftFont *fftfont = NULL; FftFontType *fftf = NULL; char *fn = NULL, *str_enc = NULL; FlocaleCharset *fc; FftPattern *src_pat = NULL, *load_pat = NULL; FftMatrix *a = NULL; FftResult result = 0; if (!FftSupport || !(FRenderGetExtensionSupported() || 1)) { return NULL; } if (!fontname) { return NULL; } if (!fft_initialized) { init_fft(dpy); } /* Xft2 always load an USC-4 fonts, that we consider as an USC-2 font * (i.e., an ISO106464-1 font) or an ISO8859-1 if the user ask for this * or the locale charset is ISO8859-1. * Xft1 support ISO106464-1, ISO8859-1 and others we load an * ISO8859-1 font by default if the locale charset is ISO8859-1 and * an ISO106464-1 one if this not the case */ if (matchWildcards("*?8859-1*", fontname)) { str_enc = FLC_FFT_ENCODING_ISO8859_1; } else if (matchWildcards("*?10646-1*", fontname)) { str_enc = FLC_FFT_ENCODING_ISO10646_1; } if (!FftSupportUseXft2 && str_enc == NULL) { if ((fc = FlocaleCharsetGetFLCXOMCharset()) != NULL && StrEquals(fc->x,FLC_FFT_ENCODING_ISO8859_1)) { fn = CatString2(fontname,":encoding=ISO8859-1"); } else { fn = CatString2(fontname,":encoding=ISO10646-1"); } } else { fn = fontname; } SUPPRESS_UNUSED_VAR_WARNING(fn); if ((src_pat = FftNameParse(fn)) == NULL) { goto bail; } SUPPRESS_UNUSED_VAR_WARNING(result); if ((load_pat = FftFontMatch(dpy, fftscreen, src_pat, &result)) == NULL) { goto bail; } /* safety check */ if (FftPatternGetMatrix( load_pat, FFT_MATRIX, 0, &a) == FftResultMatch && a) { FftMatrix b; Bool cm = False; memset(&b, 0, sizeof(FftMatrix)); if (a->xx < 0) { a->xx = -a->xx; cm = True; } if (a->yx != 0) { a->yx = 0; cm = True; } if (cm) { b.xx = a->xx; b.xy = a->xy; b.yx = a->yx; b.yy = a->yy; if (FftPatternDel(load_pat, FFT_MATRIX)) { /* nothing */ } if (!FftPatternAddMatrix(load_pat, FFT_MATRIX, &b)) { goto bail; } } } /* FIXME: other safety checking ? */ fftfont = FftFontOpenPattern(dpy, load_pat); if (!fftfont) { goto bail; } fftf = (FftFontType *)safemalloc(sizeof(FftFontType)); fftf->fftfont = fftfont; fftf->fftfont_rotated_90 = NULL; fftf->fftfont_rotated_180 = NULL; fftf->fftfont_rotated_270 = NULL; FftSetupEncoding(dpy, fftf, str_enc, module); bail: if (src_pat) { FftPatternDestroy(src_pat); } if (!fftf && load_pat) { FftPatternDestroy(load_pat); } return fftf; } void FftDrawString( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, Pixel fg, Pixel fgsh, Bool has_fg_pixels, int len, unsigned long flags) { FftDraw *fftdraw = NULL; typedef void (*DrawStringFuncType)( FftDraw *fftdraw, FftColor *fft_fg, FftFont *uf, int xt, int yt, char *str, int len); DrawStringFuncType DrawStringFunc; char *str; Bool free_str = False; XGCValues vr; XColor xfg, xfgsh; FftColor fft_fg, fft_fgsh; FftFontType *fftf; FftFont *uf; int x,y, xt,yt; float alpha_factor; flocale_gstp_args gstp_args; if (!FftSupport) { return; } fftf = &flf->fftf; if (fws->flags.text_rotation == ROTATION_90) /* CW */ { if (fftf->fftfont_rotated_90 == NULL) { fftf->fftfont_rotated_90 = FftGetRotatedFont(dpy, fftf->fftfont, fws->flags.text_rotation); } uf = fftf->fftfont_rotated_90; #ifdef FFT_BUGGY_FREETYPE y = fws->y + FftTextWidth(flf, fws->e_str, len); #else y = fws->y; #endif x = fws->x - FLF_SHADOW_BOTTOM_SIZE(flf); } else if (fws->flags.text_rotation == ROTATION_180) { if (fftf->fftfont_rotated_180 == NULL) { fftf->fftfont_rotated_180 = FftGetRotatedFont(dpy, fftf->fftfont, fws->flags.text_rotation); } uf = fftf->fftfont_rotated_180; y = fws->y; x = fws->x + FftTextWidth(flf, fws->e_str, len); } else if (fws->flags.text_rotation == ROTATION_270) { if (fftf->fftfont_rotated_270 == NULL) { fftf->fftfont_rotated_270 = FftGetRotatedFont(dpy, fftf->fftfont, fws->flags.text_rotation); } uf = fftf->fftfont_rotated_270; #ifdef FFT_BUGGY_FREETYPE y = fws->y; #else y = fws->y + FftTextWidth(flf, fws->e_str, len); #endif x = fws->x - FLF_SHADOW_UPPER_SIZE(flf); } else { uf = fftf->fftfont; y = fws->y; x = fws->x; } if (uf == NULL) return; fftdraw = FftDrawCreate(dpy, (Drawable)fws->win, Pvisual, Pcmap); if (fws->flags.has_clip_region) { if (FftDrawSetClip(fftdraw, fws->clip_region) == False) { /* just to suppress a compiler warning */ } } if (has_fg_pixels) { xfg.pixel = fg; xfgsh.pixel = fgsh; } else if (fws->gc && XGetGCValues(dpy, fws->gc, GCForeground, &vr)) { xfg.pixel = vr.foreground; } else { #if 0 fprintf(stderr, "[fvwmlibs][FftDrawString]: ERROR --" " cannot find color\n"); #endif xfg.pixel = PictureBlackPixel(); } XQueryColor(dpy, Pcmap, &xfg); alpha_factor = ((fws->flags.has_colorset)? ((float)fws->colorset->fg_alpha_percent/100) : 1); /* Render uses premultiplied alpha */ fft_fg.color.red = xfg.red * alpha_factor; fft_fg.color.green = xfg.green * alpha_factor; fft_fg.color.blue = xfg.blue * alpha_factor; fft_fg.color.alpha = 0xffff * alpha_factor; fft_fg.pixel = xfg.pixel; if (flf->shadow_size != 0 && has_fg_pixels) { XQueryColor(dpy, Pcmap, &xfgsh); fft_fgsh.color.red = xfgsh.red * alpha_factor; fft_fgsh.color.green = xfgsh.green * alpha_factor; fft_fgsh.color.blue = xfgsh.blue * alpha_factor; fft_fgsh.color.alpha = 0xffff * alpha_factor; fft_fgsh.pixel = xfgsh.pixel; } xt = x; yt = y; str = fws->e_str; if (FftUtf8Support && FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { DrawStringFunc = (DrawStringFuncType)FftPDrawStringUtf8; } else if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { DrawStringFunc = (DrawStringFuncType)FftPDrawString16; str = (char *)FftUtf8ToFftString16( (unsigned char *)fws->e_str, len, &len); free_str = True; } else if (FLC_ENCODING_TYPE_IS_USC_2(flf->fc)) { DrawStringFunc = (DrawStringFuncType)FftPDrawString16; } else if (FLC_ENCODING_TYPE_IS_USC_4(flf->fc)) { DrawStringFunc = (DrawStringFuncType)FftPDrawString32; } else { DrawStringFunc = (DrawStringFuncType)FftPDrawString8; } FlocaleInitGstpArgs(&gstp_args, flf, fws, x, y); if (flf->shadow_size != 0 && has_fg_pixels) { while (FlocaleGetShadowTextPosition(&xt, &yt, &gstp_args)) { DrawStringFunc( fftdraw, &fft_fgsh, uf, xt, yt, str, len); } } xt = gstp_args.orig_x; yt = gstp_args.orig_y; DrawStringFunc(fftdraw, &fft_fg, uf, xt, yt, str, len); if (free_str && str != NULL) { free(str); } FftDrawDestroy(fftdraw); return; } int FftTextWidth(FlocaleFont *flf, char *str, int len) { FGlyphInfo extents; int result = 0; if (!FftSupport) { return 0; } if (FftUtf8Support && FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { FftTextExtentsUtf8( fftdpy, flf->fftf.fftfont, (FftChar8*)str, len, &extents); result = extents.xOff; } else if (FLC_ENCODING_TYPE_IS_UTF_8(flf->fc)) { FftChar16 *new; int nl; new = FftUtf8ToFftString16((unsigned char *)str, len, &nl); if (new != NULL) { FftTextExtents16( fftdpy, flf->fftf.fftfont, new, nl, &extents); result = extents.xOff; free(new); } } else if (FLC_ENCODING_TYPE_IS_USC_2(flf->fc)) { FftTextExtents16( fftdpy, flf->fftf.fftfont, (FftChar16 *)str, len, &extents); result = extents.xOff; } else if (FLC_ENCODING_TYPE_IS_USC_4(flf->fc)) { FftTextExtents32( fftdpy, flf->fftf.fftfont, (FftChar32 *)str, len, &extents); result = extents.xOff; } else { FftTextExtents8( fftdpy, flf->fftf.fftfont, (FftChar8 *)str, len, &extents); result = extents.xOff; } return result; } void FftPrintPatternInfo(FftFont *f, Bool vertical) { /* FftPatternPrint use stdout */ fflush (stderr); printf("\n height: %i, ascent: %i, descent: %i, maw: %i\n", f->height, f->ascent, f->descent, f->max_advance_width); if (!vertical) { printf(" "); FftPatternPrint(f->pattern); } else { FftMatrix *pm = NULL; if (FftPatternGetMatrix( f->pattern, FFT_MATRIX, 0, &pm) == FftResultMatch && pm) { printf(" matrix: (%f %f %f %f)\n", pm->xx, pm->xy, pm->yx, pm->yy); } } fflush (stdout); return; } fvwm-2.6.7/libs/PictureUtils.h0000644000175700017570000000243012773467232013216 00000000000000/* -*-c-*- */ #ifndef Picture_Utils_H #define Picture_Utils_H #define PICTURE_CALLED_BY_FVWM 0 #define PICTURE_CALLED_BY_MODULE 1 void PictureReduceColorName(char **my_color); void PictureAllocColors( Display *dpy, Colormap cmap, XColor *colors, int size, Bool no_limit); int PictureAllocColor(Display *dpy, Colormap cmap, XColor *c, int no_limit); int PictureAllocColorAllProp( Display *dpy, Colormap cmap, XColor *c, int x, int y, Bool no_limit, Bool is_8, Bool do_dither); int PictureAllocColorImage( Display *dpy, PictureImageColorAllocator *pica, XColor *c, int x, int y); PictureImageColorAllocator *PictureOpenImageColorAllocator( Display *dpy, Colormap cmap, int x, int y, Bool no_limit, Bool save_pixels, int dither, Bool is_8); void PictureCloseImageColorAllocator( Display *dpy, PictureImageColorAllocator *pica, int *nalloc_pixels, Pixel **alloc_pixels, int *no_limit); void PictureFreeColors( Display *dpy, Colormap cmap, Pixel *pixels, int n, unsigned long planes, Bool no_limit); Pixel PictureGetNextColor(Pixel p, int n); Bool PictureDitherByDefault(void); Bool PictureUseBWOnly(void); int PictureInitColors( int call_type, Bool init_color_limit, PictureColorLimitOption *opt, Bool use_my_color_limit, Bool init_dither); void PicturePrintColorInfo(int verbose); #endif fvwm-2.6.7/libs/FShape.c0000644000175700017570000000216012773467232011723 00000000000000/* -*-c-*- */ /* 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 */ /* ** FShape.c: drop in replacements for the X shape library encapsulation */ #include "config.h" #ifdef SHAPE #include #include #include "FShape.h" int FShapeEventBase = 0; int FShapeErrorBase = 0; Bool FShapesSupported = False; void FShapeInit(Display *dpy) { FShapesSupported = FShapeQueryExtension(dpy, &FShapeEventBase, &FShapeErrorBase); } #endif /* SHAPE */ fvwm-2.6.7/libs/Module.c0000644000175700017570000002612013001406607011764 00000000000000/* -*-c-*- */ /* 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 */ /* ** Module.c: code for modules to communicate with fvwm */ #include "config.h" #include #include #include "libs/defaults.h" #include "Module.h" #include "Parse.h" /* * Loop until count bytes are read, unless an error or end-of-file * condition occurs. */ inline static int positive_read(int fd, char *buf, int count) { while (count > 0) { int n_read = read(fd, buf, count); if (n_read <= 0) { return -1; } buf += n_read; count -= n_read; } return 0; } /* * Reads a single packet of info from fvwm. * The packet is stored in static memory that is reused during * the next call. */ FvwmPacket *ReadFvwmPacket(int fd) { static unsigned long buffer[FvwmPacketMaxSize]; FvwmPacket *packet = (FvwmPacket *)buffer; unsigned long length; /* The `start flag' value supposedly exists to synchronize the * fvwm -> module communication. However, the communication goes * through a pipe. I don't see how any data could ever get lost, * so how would fvwm & the module become unsynchronized? */ do { if (positive_read(fd, (char *)buffer, sizeof(unsigned long)) < 0) { return NULL; } } while (packet->start_pattern != START_FLAG); /* Now read the rest of the header */ if (positive_read(fd, (char *)(&buffer[1]), 3 * sizeof(unsigned long)) < 0) { return NULL; } length = FvwmPacketBodySize_byte(*packet); if (length > FvwmPacketMaxSize_byte - FvwmPacketHeaderSize_byte) { /* packet too long */ return NULL; } /* Finally, read the body, and we're done */ if (positive_read(fd, (char *)(&buffer[4]), length) < 0) { return NULL; } return packet; } /* * * SendFinishedStartupNotification - informs fvwm that the module has * finished its startup procedures and is fully operational now. * */ void SendFinishedStartupNotification(int *fd) { SendText(fd, ModuleFinishedStartupResponse, 0); } /* * * SendUnlockNotification - informs fvwm that the module has * finished it's procedures and fvwm may proceed. * */ void SendUnlockNotification(int *fd) { SendText(fd, ModuleUnlockResponse, 0); } /* * * SendQuitNotification - informs fvwm that the module has * finished and may be killed. * */ static unsigned long ModuleContinue = 1; void SendQuitNotification(int *fd) { ModuleContinue = 0; SendText(fd, ModuleUnlockResponse, 0); /* unlock just in case */ } /* * * SendText - Sends arbitrary text/command back to fvwm * */ void SendText(int *fd, const char *message, unsigned long window) { char *p, *buf; unsigned int len; if (!message) { return; } /* Get enough memory to store the entire message. */ len = strlen(message); p = buf = alloca(sizeof(long) * (3 + 1 + (len / sizeof(long)))); /* Put the message in the buffer, and... */ *((unsigned long *)p) = window; p += sizeof(unsigned long); *((unsigned long *)p) = len; p += sizeof(unsigned long); strcpy(p, message); p += len; memcpy(p, &ModuleContinue, sizeof(unsigned long)); p += sizeof(unsigned long); /* Send it! */ { int n; n = write(fd[0], buf, p - buf); (void)n; } } /* * * SendFvwmPipe - Sends message to fvwm: The message is a comma-delimited * string separated into its component sections and sent one by one to fvwm. * It is discouraged to use this function with a "synchronous" module. * (Form FvwmIconMan) * */ void SendFvwmPipe(int *fd, const char *message, unsigned long window) { const char *hold = message; const char *temp; while ((temp = strchr(hold, ',')) != NULL) { char *temp_msg = (char*)alloca(temp - hold + 1); strncpy(temp_msg, hold, (temp - hold)); temp_msg[(temp - hold)] = '\0'; hold = temp + 1; SendText(fd, temp_msg, window); } /* * Send the last part of the string : * we don't need to copy this into separate * storage because we don't need to modify it ... * * NOTE: this makes this second call to SendText() * distinct from the first call. Two calls is * cleaner than hacking the loop to make only * one call. */ SendText(fd, hold, window); } void SetMessageMask(int *fd, unsigned long mask) { char set_mask_mesg[50]; sprintf(set_mask_mesg, "SET_MASK %lu", mask); SendText(fd, set_mask_mesg, 0); } void SetSyncMask(int *fd, unsigned long mask) { char set_syncmask_mesg[50]; sprintf(set_syncmask_mesg, "SET_SYNC_MASK %lu", mask); SendText(fd, set_syncmask_mesg, 0); } void SetNoGrabMask(int *fd, unsigned long mask) { char set_nograbmask_mesg[50]; sprintf(set_nograbmask_mesg, "SET_NOGRAB_MASK %lu", mask); SendText(fd, set_nograbmask_mesg, 0); } /* * Optional routine that sets the matching criteria for config lines * that should be sent to a module by way of the GetConfigLine function. * * If this routine is not called, all module config lines are sent. */ static int first_pass = 1; void InitGetConfigLine(int *fd, char *match) { char *buffer = (char *)alloca(strlen(match) + 32); first_pass = 0; /* make sure get wont do this */ sprintf(buffer, "Send_ConfigInfo %s", match); SendText(fd, buffer, 0); } /* * Gets a module configuration line from fvwm. Returns NULL if there are * no more lines to be had. "line" is a pointer to a char *. * * Changed 10/19/98 by Dan Espen: * * - The "isspace" call was referring to memory beyond the end of the * input area. This could have led to the creation of a core file. Added * "body_size" to keep it in bounds. */ void GetConfigLine(int *fd, char **tline) { FvwmPacket *packet; int body_count; if (first_pass) { SendText(fd, "Send_ConfigInfo", 0); first_pass = 0; } do { packet = ReadFvwmPacket(fd[1]); if (packet == NULL || packet->type == M_END_CONFIG_INFO) { *tline = NULL; return; } } while (packet->type != M_CONFIG_INFO); /* For whatever reason CONFIG_INFO packets start with three * (unsigned long) zeros. Skip the zeros and any whitespace that * follows */ *tline = (char *)&(packet->body[3]); body_count = FvwmPacketBodySize(*packet) * sizeof(unsigned long); while (body_count > 0 && isspace((unsigned char)**tline)) { (*tline)++; --body_count; } } ModuleArgs *ParseModuleArgs(int argc, char *argv[], int use_arg6_as_alias) { static ModuleArgs ma; /* Need at least six arguments: [0] name of executable [1] file descriptor of module->fvwm pipe (write end) [2] file descriptor of fvwm->module pipe (read end) [3] pathname of last config file read (ignored, use Send_ConfigInfo) [4] application window context [5] window decoration context Optionally (left column used if use_arg6_as_alias is true): [6] alias or user argument 0 [7] user arg 0 or user arg 1 ... */ if (argc < 6) { return NULL; } /* Module name is (last component of) argv[0] or possibly an alias passed on the command line. */ if (use_arg6_as_alias && argc >= 7) { ma.name = argv[6]; ma.user_argc = argc - 7; ma.user_argv = &(argv[7]); } else { char *p = strrchr(argv[0], '/'); if (p == NULL) { ma.name = argv[0]; } else { ma.name = ++p; } ma.user_argc = argc - 6; ma.user_argv = &(argv[6]); } ma.namelen=strlen(ma.name); if (ma.user_argc == 0) { ma.user_argv = NULL; } /* File descriptors for the pipes */ ma.to_fvwm = atoi(argv[1]); ma.from_fvwm = atoi(argv[2]); /* Ignore argv[3] */ /* These two are generated as long hex strings */ ma.window = strtoul(argv[4], NULL, 16); ma.decoration = strtoul(argv[5], NULL, 16); return &ma; } /* expands certain variables in a command to be sent by a module */ char *module_expand_action( Display *dpy, int screen , char *in_action, rectangle *r, char *forecolor, char *backcolor) { char *variables[] = { "$", "fg", "bg", "left", "-left", "right", "-right", "top", "-top", "bottom", "-bottom", "width", "height", NULL }; char *action = NULL; char *src; char *dest; char *string = NULL; char *rest; int val = 0; int offset; int i; char *dest_org; Bool is_string; Bool is_value; Bool has_geom; Bool has_fg; Bool has_bg; rectangle tmpr = { 0, 0, 0, 0 }; has_geom = (r == NULL) ? False : True; has_fg = (forecolor == NULL) ? False : True; has_bg = (backcolor == NULL) ? False : True; if (r == NULL) { r = &tmpr; } /* create a temporary storage for expanding */ action = (char *)safemalloc(MAX_MODULE_INPUT_TEXT_LEN); for (src = in_action, dest = action; *src != 0; src++) { if (*src != '$') { *(dest++) = *src; continue; } /* it's a variable */ dest_org = dest; is_string = False; is_value = False; *(dest++) = *(src++); i = GetTokenIndex(src, variables, -1, &rest); if (i == -1) { src--; continue; } switch (i) { case 0: /* $ */ continue; case 1: /* fg */ string = forecolor; is_string = has_fg; break; case 2: /* bg */ if (backcolor == NULL) { continue; } string = backcolor; is_string = has_bg; break; case 3: /* left */ val = r->x; is_value = has_geom; break; case 4: /* -left */ val = DisplayWidth(dpy, screen) - r->x - 1; is_value = has_geom; break; case 5: /* right */ val = r->x + r->width; is_value = has_geom; break; case 6: /* -right */ val = DisplayWidth(dpy, screen) - r->x - r->width - 1; is_value = has_geom; break; case 7: /* top */ val = r->y; is_value = has_geom; break; case 8: /* -top */ val = DisplayHeight(dpy, screen) - r->y - 1; is_value = has_geom; break; case 9: /* bottom */ val = r->y + r->height; is_value = has_geom; break; case 10: /* -bottom */ val = DisplayHeight(dpy, screen) - r->y - r->height - 1; is_value = has_geom; break; case 11: /* width */ val = r->width; is_value = has_geom; break; case 12: /* height */ val = r->height; is_value = has_geom; break; default: /* unknown */ src--; continue; } /* switch */ if (is_value == False && is_string == False) { src--; continue; } dest = dest_org; src = --rest; if (is_value) { if (MAX_MODULE_INPUT_TEXT_LEN - (dest - action) <= 16) { /* out of space */ free(action); return NULL; } /* print the number into the string */ sprintf(dest, "%d%n", val, &offset); dest += offset; } else if (is_string) { if (MAX_MODULE_INPUT_TEXT_LEN - (dest - action) <= strlen(string)) { /* out of space */ free(action); return NULL; } /* print the colour name into the string */ if (string) { sprintf(dest, "%s%n", string, &offset); dest += offset; } } } /* for */ *dest = 0; return action; } fvwm-2.6.7/libs/FftInterface.h0000644000175700017570000000104512773467232013123 00000000000000/* -*-c-*- */ #ifndef FFT_INTERFACE_H #define FFT_INTERFACE_H void FftGetFontHeights( FftFontType *fftf, int *height, int *ascent, int *descent); void FftGetFontWidths( FlocaleFont *flf, int *max_char_width); FftFontType *FftGetFont(Display *dpy, char *fontname, char *module); void FftDrawString( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, Pixel fg, Pixel fgsh, Bool has_fg_pixels, int len, unsigned long flags); int FftTextWidth(FlocaleFont *flf, char *str, int len); void FftPrintPatternInfo(FftFont *f, Bool vertical); #endif fvwm-2.6.7/libs/FShm.h0000644000175700017570000000275712773467232011433 00000000000000/* -*-c-*- */ #ifndef FSHM_H #define FSHM_H /* ---------------------------- included header files ---------------------- */ #include "config.h" #ifdef HAVE_XSHM #define XShmSupport 1 #else #define XShmSupport 0 #endif #if XShmSupport #include #include #include #endif /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ #if XShmSupport /* XShm */ typedef ShmSeg FShmSeg; typedef XShmSegmentInfo FShmSegmentInfo; #define FShmAttach XShmAttach #define FShmDetach XShmDetach #define FShmPutImage XShmPutImage #define FShmGetImage XShmGetImage #define FShmCreateImage XShmCreateImage /* shm */ #define Fshmget shmget #define Fshmat shmat #define Fshmdt shmdt #define Fshmctl shmctl #define Fshmget shmget #else /* XShm */ typedef unsigned long FhmSeg; typedef struct { FhmSeg shmseg; int shmid; char *shmaddr; Bool readOnly; } FShmSegmentInfo; #define FShmAttach(a, b) 0 #define FShmDetach(a, b) 0 #define FShmPutImage(a, b, c, d, e, f, g, h, i, j, k) 0 #define FShmGetImage(a, b, c, d, e, f) 0 #define FShmCreateImage(a, b, c, d, e, f, g, h) NULL /* shm */ #define Fshmget(a, b, c) 0 #define Fshmat(a, b, c) NULL; #define Fshmdt(a) #define Fshmctl(a, b, c) #endif #endif /* FSHM_H */ fvwm-2.6.7/libs/Event.h0000644000175700017570000000032212773467232011641 00000000000000#ifndef LIB_EVENT_H #define LIB_EVENT_H /* * Return the subwindow member of an event if the event type has one. */ Window GetSubwindowFromEvent(Display *dpy, const XEvent *eventp); #endif /* LIB_EVENT_H */ fvwm-2.6.7/libs/charmap.h0000644000175700017570000000161412773467232012200 00000000000000/* -*-c-*- */ #ifndef CHARMAP_H #define CHARMAP_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct { char key; int value; } charmap_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ int charmap_string_to_mask( int *ret, const char *string, charmap_t *table, char *errstring); char charmap_mask_to_char(int mask, charmap_t *table); char *charmap_table_to_string(int mask, charmap_t *table); #endif /* CHARMAP_H */ fvwm-2.6.7/libs/Grab.h0000644000175700017570000000051312773467232011435 00000000000000/* -*-c-*- */ /* ** MyXGrabServer & MyXUngrabServer - to handle nested grab server calls */ #include void MyXGrabServer(Display *disp); void MyXUngrabServer(Display *disp); void MyXUngrabKeyboard(Display *disp); void MyXGrabKeyboard(Display *disp); void MyXGrabKey(Display *disp); void MyXUngrabKey(Display *disp); fvwm-2.6.7/libs/PictureImageLoader.h0000644000175700017570000000373012773467232014273 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef PICTURE_IMAGE_LOADER_H #define PICTURE_IMAGE_LOADER_H /* ---------------------------- included header files ---------------------- */ #include /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* * PImageCreatePixmapFromArgbData * * Create a pixmap with its mask and alpha channel from ARGB data. * */ Bool PImageCreatePixmapFromArgbData( Display *dpy, Window win, CARD32 *data, int start, int width, int height, Pixmap *pixmap, Pixmap *mask, Pixmap *alpha, int *nalloc_pixels, Pixel **alloc_pixels, int *no_limit, FvwmPictureAttributes fpa); /* * PImageLoadPixmapFromFile * * Create a pixmap with its mask and alpha channel from a file. * */ Bool PImageLoadPixmapFromFile( Display *dpy, Window win, char *file, Pixmap *pixmap, Pixmap *mask, Pixmap *alpha, int *width, int *height, int *depth, int *nalloc_pixels, Pixel **alloc_pixels, int *no_limit, FvwmPictureAttributes fpa); /* * PImageLoadPixmapFromFile * * Create a FvwmPicture from a file. * */ FvwmPicture *PImageLoadFvwmPictureFromFile( Display *dpy, Window win, char *path, FvwmPictureAttributes fpa); /* * PImageLoadPixmapFromFile * * Create a cursor from a file. * */ Cursor PImageLoadCursorFromFile( Display *dpy, Window win, char *path, int x_hot, int y_hot); /* * PImageLoadPixmapFromFile * * Create a pixmap with its mask from xpm data. * */ Bool PImageLoadPixmapFromXpmData( Display *dpy, Window win, int color_limit, char **data, Pixmap *pixmap, Pixmap *mask, int *width, int *height, int *depth); #endif /* PICTURE_IMAGE_LOADER_H */ fvwm-2.6.7/libs/Target.c0000644000175700017570000001630712773467232012013 00000000000000/* -*-c-*- */ /* 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 */ /* ** fvwmlib_get_target_window and fvwmlib_keyboard_shortcuts - handle window ** selection from modules and fvwm. */ #include "config.h" #include #include #include #include #include #include #include #include #include "fvwmlib.h" #include "Grab.h" #include "Target.h" void fvwmlib_keyboard_shortcuts( Display *dpy, int screen, XEvent *Event, int x_move_size, int y_move_size, int *x_defect, int *y_defect, int ReturnEvent) { int x; int y; int x_root; int y_root; int x_move; int y_move; KeySym keysym; Window JunkRoot; unsigned int JunkMask; if (y_move_size < DEFAULT_KDB_SHORTCUT_MOVE_DISTANCE) { y_move_size = DEFAULT_KDB_SHORTCUT_MOVE_DISTANCE; } if (x_move_size < DEFAULT_KDB_SHORTCUT_MOVE_DISTANCE) { x_move_size = DEFAULT_KDB_SHORTCUT_MOVE_DISTANCE; } if (Event->xkey.state & ControlMask) { x_move_size = y_move_size = KDB_SHORTCUT_MOVE_DISTANCE_SMALL; } if (Event->xkey.state & ShiftMask) { x_move_size = y_move_size = KDB_SHORTCUT_MOVE_DISTANCE_BIG; } keysym = XLookupKeysym(&Event->xkey,0); x_move = 0; y_move = 0; switch(keysym) { case XK_Up: case XK_KP_8: case XK_k: case XK_p: y_move = -y_move_size; break; case XK_Down: case XK_KP_2: case XK_n: case XK_j: y_move = y_move_size; break; case XK_Left: case XK_KP_4: case XK_b: case XK_h: x_move = -x_move_size; break; case XK_Right: case XK_KP_6: case XK_f: case XK_l: x_move = x_move_size; break; case XK_KP_1: x_move = -x_move_size; y_move = y_move_size; break; case XK_KP_3: x_move = x_move_size; y_move = y_move_size; break; case XK_KP_7: x_move = -x_move_size; y_move = -y_move_size; break; case XK_KP_9: x_move = x_move_size; y_move = -y_move_size; break; case XK_Return: case XK_KP_Enter: case XK_space: /* beat up the event */ Event->type = ReturnEvent; break; case XK_Escape: /* simple code to bag out of move - CKH */ /* return keypress event instead */ Event->type = KeyPress; Event->xkey.keycode = XKeysymToKeycode( Event->xkey.display,keysym); break; default: break; } if (x_move || y_move) { int x_def_new = 0; int y_def_new = 0; if (FQueryPointer( dpy, RootWindow(dpy, screen), &JunkRoot, &Event->xany.window, &x_root, &y_root, &x, &y, &JunkMask) == False) { /* pointer is on a different screen - do nothing */ return; } if (x + x_move < 0) { x_def_new = x + x_move; x_move = -x; } else if (x + x_move >= DisplayWidth(dpy, DefaultScreen(dpy))) { x_def_new = x + x_move - DisplayWidth( dpy, DefaultScreen(dpy)); x_move = DisplayWidth(dpy, DefaultScreen(dpy)) - x - 1; } if (y + y_move < 0) { y_def_new = y + y_move; y_move = -y; } else if (y + y_move >= DisplayHeight(dpy, DefaultScreen(dpy))) { y_def_new = y + y_move - DisplayHeight( dpy, DefaultScreen(dpy)); y_move = DisplayHeight( dpy, DefaultScreen(dpy)) - y - 1; } if (x_defect) { int diff = 0; *x_defect += x_def_new; if (*x_defect > 0 && x_move < 0) { diff = min(*x_defect, -x_move); } else if (*x_defect < 0 && x_move > 0) { diff = max(*x_defect, -x_move); } *x_defect -= diff; x_move += diff; } if (y_defect) { int diff = 0; *y_defect += y_def_new; if (*y_defect > 0 && y_move < 0) { diff = min(*y_defect, -y_move); } else if (*y_defect < 0 && y_move > 0) { diff = max(*y_defect, -y_move); } *y_defect -= diff; y_move += diff; } if (x_move || y_move) { FWarpPointer( dpy, None, RootWindow(dpy, screen), 0, 0, 0, 0, x_root + x_move, y_root + y_move); } /* beat up the event */ Event->type = MotionNotify; Event->xkey.x += x_move; Event->xkey.y += y_move; Event->xkey.x_root += x_move; Event->xkey.y_root += y_move; } } void fvwmlib_get_target_window( Display *dpy, int screen, char *MyName, Window *app_win, Bool return_subwindow) { XEvent eventp; int val = -10,trials; Bool finished = False; Bool canceled = False; Window Root = RootWindow(dpy, screen); int is_key_pressed = 0; int is_button_pressed = 0; KeySym keysym; trials = 0; while((trials <10)&&(val != GrabSuccess)) { val=XGrabPointer(dpy, Root, True, ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, Root, XCreateFontCursor(dpy,XC_crosshair), CurrentTime); switch (val) { case GrabInvalidTime: case GrabNotViewable: /* give up */ trials += 100000; break; case GrabSuccess: break; case AlreadyGrabbed: case GrabFrozen: default: usleep(10000); trials++; break; } } if(val != GrabSuccess) { fprintf(stderr,"%s: Couldn't grab the cursor!\n",MyName); exit(1); } MyXGrabKeyboard(dpy); while (!finished && !canceled) { FMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask, &eventp); switch (eventp.type) { case KeyPress: is_key_pressed++; break; case KeyRelease: keysym = XLookupKeysym(&eventp.xkey,0); if( !is_key_pressed ) break; switch (keysym) { case XK_Escape: canceled = True; break; case XK_space: case XK_Return: case XK_KP_Enter: finished = True; break; default: fvwmlib_keyboard_shortcuts( dpy, screen, &eventp, 0, 0, NULL, NULL, 0); break; } break; case ButtonPress: is_button_pressed++; break; case ButtonRelease: if( is_button_pressed ) finished = True; break; } } MyXUngrabKeyboard(dpy); XUngrabPointer(dpy, CurrentTime); XSync(dpy,0); if (canceled) { *app_win = None; return; } *app_win = eventp.xany.window; if(return_subwindow && eventp.xbutton.subwindow != None) *app_win = eventp.xbutton.subwindow; return; } Window fvwmlib_client_window(Display *dpy, Window input) { Atom _XA_WM_STATE; unsigned int nchildren; Window root, parent, *children,target; unsigned long nitems, bytesafter; unsigned char *prop; Atom atype; int aformat; int i; _XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False); if ( XGetWindowProperty( dpy, input, _XA_WM_STATE , 0L, 3L , False, _XA_WM_STATE, &atype, &aformat, &nitems, &bytesafter, &prop) == Success) { if(prop != NULL) { XFree(prop); return input; } } if (!XQueryTree(dpy, input, &root, &parent, &children, &nchildren)) return None; for (i = 0; i < nchildren; i++) { target = fvwmlib_client_window(dpy, children[i]); if(target != None) { XFree((char *)children); return target; } } XFree((char *)children); return None; } fvwm-2.6.7/libs/ColorUtils.h0000644000175700017570000000277112773467232012671 00000000000000#ifndef LIB_COLORUTILS_H #define LIB_COLORUTILS_H /* * Stuff for dealing w/ bitmaps & pixmaps: */ XColor *GetShadowColor(Pixel); XColor *GetHiliteColor(Pixel); Pixel GetShadow(Pixel); Pixel GetHilite(Pixel); XColor *GetForeShadowColor(Pixel foreground, Pixel background); Pixel GetForeShadow(Pixel foreground, Pixel background); XColor *GetTintedColor(Pixel in, Pixel tint, int percent); Pixel GetTintedPixel(Pixel in, Pixel tint, int percent); /* This function converts the colour stored in a colorcell (pixel) into the * string representation of a colour. The output is printed at the * address 'output'. It is either in rgb format ("rgb:rrrr/gggg/bbbb") if * use_hash is False or in hash notation ("#rrrrggggbbbb") if use_hash is true. * The return value is the number of characters used by the string. The * rgb values of the output are undefined if the colorcell is invalid. The * memory area pointed at by 'output' must be at least 64 bytes (in case of * future extensions and multibyte characters).*/ int pixel_to_color_string( Display *dpy, Colormap cmap, Pixel pixel, char *output, Bool use_hash); Pixel GetSimpleColor(char *name); /* handles colorset color names too */ Pixel GetColor(char *name); /* duplicate an already allocated color */ Pixel fvwmlib_clone_color(Pixel p); void fvwmlib_free_colors(Display *dpy, Pixel *pixels, int n, Bool no_limit); void fvwmlib_copy_color( Display *dpy, Pixel *dst_color, Pixel *src_color, Bool do_free_dest, Bool do_copy_src); #endif /* LIB_COLORUTILS_H */ fvwm-2.6.7/libs/FBidi.c0000644000175700017570000001010613001406607011511 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Mikhael Goikhman */ /* 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 */ /* * FBidi.c - interface to Bidi, we use fribidi implementation here. * See FBidi.h for some comments on this interface. */ #include "config.h" #include "FBidi.h" #if HAVE_BIDI #include "safemalloc.h" #include "BidiJoin.h" #include #include Bool FBidiIsApplicable(const char *charset) { if (fribidi_parse_charset((char *)charset) == FRIBIDI_CHAR_SET_NOT_FOUND) { return False; } return True; } char *FBidiConvert( const char *logical_str, const char *charset, int str_len, Bool *is_rtl, int *out_len, superimpose_char_t *comb_chars, int *l_to_v) { char *visual_str; FriBidiCharSet fribidi_charset; FriBidiChar *logical_unicode_str; FriBidiChar *visual_unicode_str; FriBidiParType pbase_dir = FRIBIDI_TYPE_ON; FriBidiStrIndex *pos_l_to_v; int i; if (logical_str == NULL || charset == NULL) { return NULL; } if (str_len < 0) { str_len = strlen(logical_str); } if (is_rtl != NULL) { *is_rtl = False; } fribidi_charset = fribidi_parse_charset((char *)charset); if (fribidi_charset == FRIBIDI_CHAR_SET_NOT_FOUND) { return NULL; } /* it is possible that we allocate a bit more here, if utf-8 */ logical_unicode_str = (FriBidiChar *)safemalloc((str_len + 1) * sizeof(FriBidiChar)); /* convert to unicode first */ str_len = fribidi_charset_to_unicode( fribidi_charset, (char *)logical_str, str_len, logical_unicode_str); visual_unicode_str = (FriBidiChar *)safemalloc((str_len + 1) * sizeof(FriBidiChar)); /* apply bidi algorithm, convert logical string to visual string */ /* also keep track of how characters are reordered here, to reorder combing characters accordingly */ pos_l_to_v = (FriBidiStrIndex *)safemalloc((str_len + 1) * sizeof(FriBidiStrIndex)); fribidi_log2vis( logical_unicode_str, str_len, &pbase_dir, visual_unicode_str, pos_l_to_v, NULL, NULL); /* remap mapping from logical to visual to "compensate" for BIDI */ if (comb_chars != NULL) { for (i = 0; comb_chars[i].c.byte1 != 0 || comb_chars[i].c.byte2 != 0; i++) { /* if input string is zero characters => only combining chars, set position to zero */ comb_chars[i].position = str_len != 0 ? pos_l_to_v[comb_chars[i].position] : 0; } } if (l_to_v != NULL) { /* values in the previuos mapping gives the position of input characters after combining step */ /* mapping from BIDI conversion maps from the positions in the output from combining */ int orig_len; int *l_to_v_temp; for (i = 0; l_to_v[i] != -1; i++) { } orig_len = i; l_to_v_temp = (int *)safemalloc(orig_len * sizeof(int)); for (i = 0; i < orig_len; i++) { l_to_v_temp[i] = pos_l_to_v[l_to_v[i]]; } for (i = 0; i < orig_len; i++) { l_to_v[i] = l_to_v_temp[i]; } free(l_to_v_temp); } free(pos_l_to_v); /* character shape/join - will get pulled into fribidi with time */ str_len = shape_n_join(visual_unicode_str, str_len); visual_str = (char *)safemalloc((4 * str_len + 1) * sizeof(char)); /* convert from unicode finally */ *out_len = fribidi_unicode_to_charset( fribidi_charset, visual_unicode_str, str_len, visual_str); if (is_rtl != NULL && fribidi_get_bidi_type(*visual_unicode_str) == FRIBIDI_TYPE_RTL) { *is_rtl = True; } free(logical_unicode_str); free(visual_unicode_str); return visual_str; } #endif /* HAVE_BIDI */ fvwm-2.6.7/libs/envvar.h0000644000175700017570000000604512773467232012071 00000000000000/* -*-c-*- */ #ifndef FVWMLIB_ENVVAR_H #define FVWMLIB_ENVVAR_H /* * SYNOPSIS #include "envvar.h" * int envExpand(char *s, int maxstrlen); * * INPUT s string to expand environment variables in. * maxstrlen max length of string, including '\0'. * * OUTPUT s the string with environment variables expanded. * * RETURNS Number of changes done. * * NOTES A non-existing variable is substituted with the empty * string. * */ int envExpand(char *s, int maxstrlen); /* * FUNCTION Expand environment variables into a new string. * * SYNOPSIS #include "envvar.h" * char *envDupExpand(const char *s, int extra); * * INPUT s string to expand environment variables in. * extra number of extra bytes to allocate in the * string, in addition to the string contents * and the terminating '\0'. * * RETURNS A dynamically allocated string with environment * variables expanded. * Use free() to deallocate the buffer when it is no * longer needed. * NULL is returned if there is not enough memory. * * NOTES A non-existing variable is substituted with the empty * string. * */ char *envDupExpand(const char *s, int extra); /* * FUNCTION Search for the first environment variable and return * its contents and coordinates in the given string. * * INPUT s the string to scan. * may include $ and { } that introduce variable. * * OUTPUT beg index in the string of matching $. * end index in the string, first after matching var. * * RETURNS The variable contents; "" if env variable has legal name, * but does not exist; or NULL if no env variables found. * Returned constant string must not be deallocated. * * NOTE This function will only return `legal' variables. There * may be $'s in the string that are not followed by what * is considered a legal variable name introducer. Such * occurrences are skipped. * If nothing is found returns NULL and sets beg and end to 0. * * EXAMPLE getFirstEnv("echo $HOME/.fvwm/config", &beg, &end) * returns "/home/username" and beg=5, end=10. * */ const char* getFirstEnv(const char *s, int *beg, int *end); /* This function keeps a list of all strings that were set in the environment. * If a variable is written again, the old memory is freed. This function * should be called instead of putenv(). * * var - environement variable name * env - environment string ("variable=value") * * Both arguments are copied internally and should be freed after calling this * function. */ void flib_putenv(char *var, char *env); /* Replacement for unsetenv(). */ void flib_unsetenv(const char *name); #endif fvwm-2.6.7/libs/PictureGraphics.c0000644000175700017570000007675213001406607013653 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "PictureBase.h" #include "Colorset.h" #include "FRenderInit.h" #include "FRenderInterface.h" #include "Graphics.h" #include "PictureGraphics.h" #include "PictureUtils.h" #include "FImage.h" #include "Grab.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Bool PGrabImageError = True; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static int FSetBackingStore(Display *dpy, Window win, int backing_store) { XWindowAttributes attributes; XSetWindowAttributes set_attributes; int old_bs; XGetWindowAttributes(dpy, win, &attributes); if (attributes.backing_store == backing_store) { return -1; } old_bs = attributes.backing_store; set_attributes.backing_store = backing_store; XChangeWindowAttributes(dpy, win, CWBackingStore, &set_attributes); return old_bs; } static void PCopyArea(Display *dpy, Pixmap pixmap, Pixmap mask, int depth, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y) { XGCValues gcv; unsigned long gcm; GC my_gc = None; if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, d, 0, NULL); } gcm = GCClipMask | GCClipXOrigin | GCClipYOrigin; gcv.clip_x_origin = dest_x - src_x; /* */ gcv.clip_y_origin = dest_y - src_y; /* */ if (depth == Pdepth) { gcv.clip_mask = mask; if (my_gc != None) { XChangeGC(dpy,my_gc,gcm,&gcv); } else { XChangeGC(dpy,gc,gcm,&gcv); } XCopyArea(dpy, pixmap, d, (my_gc != None)? my_gc:gc, src_x, src_y, src_w, src_h, dest_x, dest_y); } else { /* monochrome bitmap */ gcv.clip_mask = mask; if (my_gc != None) { gcv.foreground = PictureWhitePixel(); gcv.background = PictureBlackPixel(); gcm |= GCBackground|GCForeground; XChangeGC(dpy,my_gc,gcm,&gcv); } else { XChangeGC(dpy,gc,gcm,&gcv); } XCopyPlane(dpy, pixmap, d, (my_gc != None)? my_gc:gc, src_x, src_y, src_w, src_h, dest_x, dest_y, 1); } if (my_gc != None) { XFreeGC(dpy, my_gc); } else { gcm = GCClipMask; gcv.clip_mask = None; XChangeGC(dpy, gc, gcm, &gcv); } } static void PTileRectangle(Display *dpy, Window win, Pixmap pixmap, Pixmap mask, int depth, int src_x, int src_y, Drawable d, GC gc, GC mono_gc, int dest_x, int dest_y, int dest_w, int dest_h) { Pixmap tile_mask = None; XGCValues gcv; unsigned long gcm; GC my_gc = None; GC my_mono_gc = None; if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, d, 0, NULL); } if (mono_gc == None && (mask != None || Pdepth != depth)) { if (mask != None) my_mono_gc = fvwmlib_XCreateGC(dpy, mask, 0, NULL); else if (depth != Pdepth) my_mono_gc = fvwmlib_XCreateGC(dpy, pixmap, 0, NULL); } gcm = 0; if (mask != None) { /* create a till mask */ tile_mask = XCreatePixmap(dpy, win, dest_w, dest_h, 1); gcv.tile = mask; gcv.ts_x_origin = src_x; gcv.ts_y_origin = src_y; gcv.fill_style = FillTiled; gcm = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile; if (mono_gc != None) { XChangeGC(dpy, mono_gc, gcm, &gcv); } else { gcv.foreground = 1; gcv.background = 0; gcm |= GCBackground|GCForeground; XChangeGC(dpy, my_mono_gc, gcm, &gcv); } XFillRectangle(dpy, tile_mask, (mono_gc != None)? mono_gc:my_mono_gc, src_x, src_y, dest_w, dest_h); if (mono_gc != None) { gcv.fill_style = FillSolid; gcm = GCFillStyle; XChangeGC(dpy, mono_gc, gcm, &gcv); } } gcv.tile = pixmap; gcv.ts_x_origin = dest_x - src_x; gcv.ts_y_origin = dest_y - src_y; gcv.fill_style = FillTiled; gcm = GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; gcv.clip_mask = tile_mask; gcv.clip_x_origin = dest_x; gcv.clip_y_origin = dest_y;; gcm |= GCClipMask | GCClipXOrigin | GCClipYOrigin; if (depth != Pdepth) { Pixmap my_pixmap = None; XChangeGC(dpy, (mono_gc != None)? mono_gc:my_mono_gc, gcm, &gcv); my_pixmap = XCreatePixmap(dpy, win, dest_w, dest_h, 1); XFillRectangle(dpy, my_pixmap, (mono_gc != None)? mono_gc:my_mono_gc, 0, 0, dest_w, dest_h); gcv.clip_mask = my_pixmap; gcv.fill_style = FillSolid; gcm = GCFillStyle | GCClipMask; XChangeGC(dpy, (mono_gc != None)? mono_gc:my_mono_gc, gcm, &gcv); XCopyPlane(dpy, my_pixmap, d, (my_gc != None)? my_gc:gc, 0, 0, dest_w, dest_h, dest_x, dest_y, 1); if (my_pixmap != None) { XFreePixmap(dpy, my_pixmap); } } else { XChangeGC(dpy, (gc != None)? gc:my_gc, gcm, &gcv); XFillRectangle(dpy, d, (gc != None)? gc:my_gc, dest_x, dest_y, dest_w, dest_h); } if (my_gc != None) { XFreeGC(dpy, my_gc); } else { gcv.clip_mask = None; gcv.fill_style = FillSolid; gcm = GCFillStyle | GCClipMask; XChangeGC(dpy, gc, gcm, &gcv); } if (my_mono_gc != None) { XFreeGC(dpy, my_mono_gc); } else if (mono_gc != None) { gcv.clip_mask = None; gcv.fill_style = FillSolid; gcm = GCFillStyle | GCClipMask; XChangeGC(dpy, mono_gc, gcm, &gcv); } if (tile_mask != None) { XFreePixmap(dpy, tile_mask); } } static void PGrabImageErrorHandler(void) { PGrabImageError = True; } static FImage *PGrabXImage( Display *dpy, Drawable d, int x, int y, int w, int h, Bool d_is_a_window) { Bool try_to_grab = True; XWindowAttributes xwa; XErrorHandler saved_eh = NULL; FImage *fim = NULL; PGrabImageError = 0; if (d_is_a_window) { MyXGrabServer(dpy); XGetWindowAttributes(dpy, d, &xwa); XSync(dpy, False); if (xwa.map_state != IsViewable && xwa.backing_store == NotUseful) { try_to_grab = False; #if 0 fprintf(stderr, "Bad attribute! %i,%i\n", xwa.map_state != IsViewable, xwa.backing_store == NotUseful); #endif } else { saved_eh = XSetErrorHandler( (XErrorHandler) PGrabImageErrorHandler); #if 0 fprintf(stderr, "Attribute ok! %i,%i\n", xwa.map_state != IsViewable, xwa.backing_store == NotUseful); #endif } } if (try_to_grab) { fim = FGetFImage(dpy, d, Pvisual, Pdepth, x, y, w, h, AllPlanes, ZPixmap); if (PGrabImageError) { #if 0 fprintf(stderr, "XGetImage error during the grab\n"); #endif if (fim != NULL) { FDestroyFImage(dpy, fim); fim = NULL; } } if (d_is_a_window) { XSetErrorHandler((XErrorHandler) saved_eh); } } if (d_is_a_window) { MyXUngrabServer(dpy); } return fim; } static Pixmap PCreateRenderPixmap( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, int added_alpha_percent, Pixel tint, int tint_percent, Bool d_is_a_window, Drawable d, GC gc, GC mono_gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, Bool do_repeat, int *new_w, int *new_h, Bool *new_do_repeat, Pixmap *new_mask) { FImage *pixmap_fim = NULL; FImage *mask_fim = NULL; FImage *alpha_fim = NULL; FImage *dest_fim = NULL; FImage *new_mask_fim = NULL; FImage *out_fim = NULL; Pixmap pixmap_copy = None; Pixmap src_pix = None; Pixmap out_pix = None; unsigned short *am = NULL; XColor *colors = NULL, *dest_colors = NULL; XColor tint_color, c; int w ,h, n_src_w, n_src_h; int j, i, j1, i1, m = 0, k = 0, l = 0; Bool do_free_mono_gc = False; Bool make_new_mask = False; Bool error = False; *new_mask = None; *new_do_repeat = do_repeat; if (depth != Pdepth) { pixmap_copy = XCreatePixmap(dpy, win, src_w, src_h, Pdepth); if (gc == None) { gc = PictureDefaultGC(dpy, win); } if (pixmap_copy && gc) { XCopyPlane( dpy, pixmap, pixmap_copy, gc, src_x, src_y, src_w, src_h, 0, 0, 1); } else { error = True; goto bail; } src_x = src_y = 0; } src_pix = (pixmap_copy)? pixmap_copy:pixmap; if (src_pix == ParentRelative) { pixmap_fim = PGrabXImage( dpy, d, dest_x, dest_y, dest_w, dest_h, d_is_a_window); } else { pixmap_fim = FGetFImage( dpy, src_pix, Pvisual, Pdepth, src_x, src_y, src_w, src_h, AllPlanes, ZPixmap); } if (!pixmap_fim) { error = True; goto bail; } if (mask != None) { mask_fim = FGetFImage( dpy, mask, Pvisual, 1, src_x, src_y, src_w, src_h, AllPlanes, ZPixmap); if (!mask_fim) { error = True; goto bail; } if (src_x != 0 || src_y != 0) make_new_mask = True; } if (alpha != None) { alpha_fim = FGetFImage( dpy, alpha, Pvisual, FRenderGetAlphaDepth(), src_x, src_y, src_w, src_h, AllPlanes, ZPixmap); if (!alpha_fim) { error = True; goto bail; } } if (alpha != None || added_alpha_percent < 100) { dest_fim = PGrabXImage( dpy, d, dest_x, dest_y, dest_w, dest_h, d_is_a_window); /* accept this error */ } if (dest_fim && do_repeat && (dest_w > src_w || dest_h > src_h)) { *new_do_repeat = False; if (mask) { make_new_mask = True; } w = dest_w; h = dest_h; n_src_w = (w < src_w)? w:src_w; n_src_h = (h < src_h)? h:src_h; } else { n_src_w = w = (dest_w < src_w)? dest_w:src_w; n_src_h = h = (dest_h < src_h)? dest_h:src_h; } *new_w = w; *new_h = h; out_pix = XCreatePixmap(dpy, win, w, h, Pdepth); out_fim = FCreateFImage( dpy, Pvisual, Pdepth, ZPixmap, w, h); if (gc == None) { gc = PictureDefaultGC(dpy, win); } if (!out_pix || !out_fim || !gc) { error = True; goto bail; } colors = (XColor *)safemalloc(n_src_w * n_src_h * sizeof(XColor)); if (dest_fim) { dest_colors = (XColor *)safemalloc(w * h * sizeof(XColor)); } am = (unsigned short *)safemalloc( n_src_w * n_src_h * sizeof(unsigned short)); if (tint_percent > 0) { tint_color.pixel = tint; XQueryColor(dpy, Pcmap, &tint_color); } for (j = 0; j < n_src_h; j++) { for (i = 0; i < n_src_w; i++, m++) { if (mask_fim != NULL && (XGetPixel(mask_fim->im, i, j) == 0)) { am[m] = 0; } else if (alpha_fim != NULL) { am[m] = XGetPixel(alpha_fim->im, i, j); if (am[m] == 0 && !dest_fim) { make_new_mask = True; } } else { am[m] = 255; } if (added_alpha_percent < 100) { am[m] = (unsigned short) ((am[m] * added_alpha_percent) / 100); } if (am[m] > 0) { if (!dest_fim) { if (am[m] < 130) { am[m] = 0; make_new_mask = True; } else { am[m] = 255; } } else if (am[m] < 255) { dest_colors[l++].pixel = XGetPixel(dest_fim->im, i, j); } if (am[m] > 0) { colors[k++].pixel = XGetPixel(pixmap_fim->im, i, j); } } } } for (i = 0; i < k; i += 256) XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256)); if (do_repeat && dest_fim && (n_src_h < h || n_src_w < w)) { for (j1 = 0; j1 < h+n_src_h; j1 +=n_src_h) { for (i1 = 0; i1 < w+n_src_w; i1 += n_src_w) { for(j = 0; !(i1==0 && j1==0) && j < n_src_h && j+j1 < h; j++) { for(i = 0; i < n_src_w && i+i1 < w; i++) { m = j*n_src_w + i; if (am[m] > 0 && am[m] < 255) { dest_colors[l++].pixel = XGetPixel( dest_fim ->im, i1+i, j1+j); } } } } } } for (i = 0; i < l; i += 256) XQueryColors(dpy, Pcmap, &dest_colors[i], min(l - i, 256)); if (make_new_mask) { *new_mask = XCreatePixmap(dpy, win, w, h, 1); if (*new_mask) { new_mask_fim = FCreateFImage( dpy, Pvisual, 1, ZPixmap, w, h); if (mono_gc == None) { mono_gc = fvwmlib_XCreateGC( dpy, *new_mask, 0, NULL); do_free_mono_gc = True; } } } l = 0; m = 0; k = 0; c.flags = DoRed | DoGreen | DoBlue; for (j = 0; j < n_src_h; j++) { for (i = 0; i < n_src_w; i++, m++) { if (am[m] > 0) { if (*new_mask) { XPutPixel(new_mask_fim->im, i, j, 1); } if (tint_percent > 0) { colors[k].blue = (unsigned short) (((100-tint_percent)* colors[k].blue + tint_color.blue * tint_percent) / 100); colors[k].green = (unsigned short) (((100-tint_percent)* colors[k].green + tint_color.green * tint_percent) / 100); colors[k].red = (unsigned short) (((100-tint_percent)* colors[k].red + tint_color.red * tint_percent) / 100); } c.blue = colors[k].blue; c.green = colors[k].green; c.red = colors[k].red; if (am[m] < 255 && dest_fim) { c.blue = (unsigned short) (((255 - am[m])* dest_colors[l].blue + c.blue * am[m]) / 255); c.green = (unsigned short) (((255 - am[m])* dest_colors[l].green + c.green * am[m]) / 255); c.red = (unsigned short) (((255 - am[m])* dest_colors[l].red + c.red * am[m]) / 255); l++; } PictureAllocColor(Pdpy, Pcmap, &c, False); colors[k].pixel = c.pixel; k++; } else { if (dest_fim) { c.pixel = XGetPixel(dest_fim->im, i, j); } else { c.pixel = XGetPixel( pixmap_fim->im, i, j); } if (*new_mask) { XPutPixel(new_mask_fim->im, i, j, 0); } } XPutPixel(out_fim->im, i, j, c.pixel); } } /* tile: editor ligne width limit 107 !!*/ if (do_repeat && dest_fim && (n_src_h < h || n_src_w < w)) { for (j1 = 0; j1 < h+n_src_h; j1 +=n_src_h) { for (i1 = 0; i1 < w+n_src_w; i1 += n_src_w) { k = 0; for(j = 0; !(i1==0 && j1==0) && j < n_src_h; j++) { for(i = 0; i < n_src_w; i++) { m = j*n_src_w + i; if (!(i+i1 < w && j+j1 < h)) { if (am[m] > 0) { k++; } } else { if (am[m] > 0) { if (*new_mask) { XPutPixel( new_mask_fim->im, i+i1, j+j1, 1); } c.blue = colors[k].blue; c.green = colors[k].green; c.red = colors[k].red; c.pixel = colors[k].pixel; k++; if (am[m] < 255) { c.blue = (unsigned short) (((255 - am[m])* dest_colors[l].blue + c.blue * am[m]) / 255); c.green = (unsigned short) (((255 - am[m])* dest_colors[l].green + c.green * am[m]) / 255); c.red = (unsigned short) (((255 - am[m])* dest_colors[l].red + c.red * am[m]) / 255); l++; PictureAllocColor( Pdpy, Pcmap, &c, False); } } else { c.pixel = XGetPixel( dest_fim->im, i+i1, j+j1); if (*new_mask) { XPutPixel( new_mask_fim->im, i+i1, j+j1, 0); } } XPutPixel(out_fim->im, i+i1, j+j1, c.pixel); } } } } } } FPutFImage(dpy, out_pix, gc, out_fim, 0, 0, 0, 0, w, h); if (*new_mask && mono_gc) { FPutFImage( dpy, *new_mask, mono_gc, new_mask_fim, 0, 0, 0, 0, w, h); } bail: if (colors) { free(colors); } if (dest_colors) { free(dest_colors); } if (am) { free(am); } if (pixmap_copy) { XFreePixmap(dpy, pixmap_copy); } if (pixmap_fim) { FDestroyFImage(dpy, pixmap_fim); } if (mask_fim) { FDestroyFImage(dpy, mask_fim); } if (alpha_fim) { FDestroyFImage(dpy, alpha_fim); } if (dest_fim) { FDestroyFImage(dpy, dest_fim); } if (new_mask_fim) { FDestroyFImage(dpy, new_mask_fim); } if (do_free_mono_gc && mono_gc) { XFreeGC(dpy, mono_gc); } if (out_fim) { FDestroyFImage(dpy, out_fim); } if (error) { if (out_pix != None) { XFreePixmap(dpy, out_pix); out_pix = None; } if (*new_mask != None) { XFreePixmap(dpy, *new_mask); *new_mask = None; } } return out_pix; } /* never used and tested */ static Pixmap PCreateDitherPixmap( Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc, int in_width, int in_height, int out_width, int out_height) { FImage *src_fim; FImage *mask_fim = NULL; FImage *out_fim; Pixmap out_pix = None; unsigned char *cm; XColor *colors; XColor c; int j, i, m = 0, k = 0, x = 0, y = 0; if (depth != Pdepth) return None; if (!(src_fim = FGetFImage( dpy, src, Pvisual, depth, 0, 0, in_width, in_height, AllPlanes, ZPixmap))) { return None; } if (mask != None) { mask_fim = FGetFImage( dpy, mask, Pvisual, 1, 0, 0, in_width, in_height, AllPlanes, ZPixmap); if (!mask_fim) { FDestroyFImage(dpy, mask_fim); return None; } } out_pix = XCreatePixmap(dpy, win, out_width, out_height, Pdepth); out_fim = FCreateFImage( dpy, Pvisual, Pdepth, ZPixmap, out_width, out_height); if (gc == None) { gc = PictureDefaultGC(dpy, win); } if (!out_pix || !out_fim || !gc) { FDestroyFImage(dpy, src_fim); if (mask_fim) { FDestroyFImage(dpy, mask_fim); } if (out_pix) { XFreePixmap(dpy, out_pix); } if (out_fim) { FDestroyFImage(dpy, out_fim); } return None; } colors = (XColor *)safemalloc(out_width * out_height * sizeof(XColor)); cm = (unsigned char *)safemalloc(out_width * out_height * sizeof(char)); x = y = 0; for (j = 0; j < out_height; j++,y++) { if (y == in_height) y = 0; for (i = 0; i < out_width; i++,x++) { if (x == in_width) x = 0; if (mask_fim != NULL && (XGetPixel(mask_fim->im, x, y) == 0)) { cm[m++] = 0; } else { cm[m++] = 255; colors[k++].pixel = XGetPixel(src_fim->im, x, y); } } } for (i = 0; i < k; i += 256) XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256)); k = 0;m = 0; for (j = 0; j < out_height; j++) { for (i = 0; i < out_width; i++) { if (cm[m] > 0) { c = colors[k++]; PictureAllocColorAllProp( Pdpy, Pcmap, &c, i, j, False, False, True); } else { c.pixel = XGetPixel(src_fim->im, i, j); } XPutPixel(out_fim->im, i, j, c.pixel); m++; } } free(colors); free(cm); FDestroyFImage(dpy, src_fim); if (mask_fim) { FDestroyFImage(dpy, mask_fim); } FPutFImage( dpy, out_pix, gc, out_fim, 0, 0, 0, 0, out_width, out_height); FDestroyFImage(dpy, out_fim); return out_pix; } /* ---------------------------- interface functions ------------------------ */ Pixmap PictureBitmapToPixmap( Display *dpy, Window win, Pixmap src, int depth, GC gc, int src_x, int src_y, int src_w, int src_h) { Pixmap dest = None; dest = XCreatePixmap(dpy, win, src_w, src_h, depth); if (dest && gc == None) { gc = PictureDefaultGC(dpy, win); } if (dest && gc) { XCopyPlane( dpy, src, dest, gc, src_x, src_y, src_w, src_h, 0, 0, 1); } return dest; } void PGraphicsRenderPixmaps( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, FvwmRenderAttributes *fra, Drawable d, GC gc, GC mono_gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat) { FvwmRenderAttributes t_fra; Pixmap xrs_pixmap = None; Pixmap xrs_mask = None; Pixmap tmp_pixmap, tmp_mask; Bool d_is_a_window; t_fra.added_alpha_percent = 100; t_fra.tint_percent = 0; t_fra.mask = 0; t_fra.tint = None; if (fra) { t_fra.mask = fra->mask; if (fra->mask & FRAM_HAVE_ICON_CSET) { t_fra.added_alpha_percent = fra->colorset->icon_alpha_percent; t_fra.tint_percent = fra->colorset->icon_tint_percent; t_fra.tint = fra->colorset->icon_tint; } if (fra->mask & FRAM_HAVE_ADDED_ALPHA) { t_fra.added_alpha_percent = fra->added_alpha_percent; } if (fra->mask & FRAM_HAVE_TINT) { t_fra.tint_percent = fra->tint_percent; t_fra.tint = fra->tint; } } if (dest_w == 0 && dest_h == 0) { dest_w = src_w; dest_h = src_h; } /* use XRender only when "needed" (backing store pbs) */ if (t_fra.tint_percent > 0 || t_fra.added_alpha_percent < 100 || alpha != None) { /* for testing XRender simulation add && 0 */ if (FRenderRender( dpy, win, pixmap, mask, alpha, depth, t_fra.added_alpha_percent, t_fra.tint, t_fra.tint_percent, d, gc, alpha_gc, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, dest_h, do_repeat)) { return; } } /* no render extension or something strange happen */ if (t_fra.tint_percent > 0 || t_fra.added_alpha_percent < 100 || alpha != None) { int new_w, new_h, new_do_repeat; d_is_a_window = !!(t_fra.mask & FRAM_DEST_IS_A_WINDOW); xrs_pixmap = PCreateRenderPixmap( dpy, win, pixmap, mask, alpha, depth, t_fra.added_alpha_percent, t_fra.tint, t_fra.tint_percent, d_is_a_window, d, gc, mono_gc, alpha_gc, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, dest_h, do_repeat, &new_w, &new_h, &new_do_repeat, &xrs_mask); if (xrs_pixmap) { src_x = 0; src_y = 0; src_w = new_w; src_h = new_h; depth = Pdepth; do_repeat = new_do_repeat; } } tmp_pixmap = (xrs_pixmap != None)? xrs_pixmap:pixmap; tmp_mask = (xrs_mask != None)? xrs_mask:mask; if (do_repeat) { PTileRectangle( dpy, win, tmp_pixmap, tmp_mask, depth, src_x, src_y, d, gc, mono_gc, dest_x, dest_y, dest_w, dest_h); } else { PCopyArea( dpy, tmp_pixmap, tmp_mask, depth, d, gc, src_x, src_y, src_w, src_h, dest_x, dest_y); } if (xrs_pixmap) { XFreePixmap(dpy, xrs_pixmap); } if (xrs_mask) { XFreePixmap(dpy, xrs_mask); } } void PGraphicsRenderPicture( Display *dpy, Window win, FvwmPicture *p, FvwmRenderAttributes *fra, Drawable d, GC gc, GC mono_gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat) { PGraphicsRenderPixmaps( dpy, win, p->picture, p->mask, p->alpha, p->depth, fra, d, gc, mono_gc, alpha_gc, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w, dest_h, do_repeat); } void PGraphicsCopyPixmaps( Display *dpy, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y) { PGraphicsRenderPixmaps( dpy, None, pixmap, mask, alpha, depth, 0, d, gc, None, None, src_x, src_y, src_w, src_h, dest_x, dest_y, src_w, src_h, False); } void PGraphicsCopyFvwmPicture( Display *dpy, FvwmPicture *p, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y) { PGraphicsRenderPicture( dpy, None, p, 0, d, gc, None, None, src_x, src_y, src_w, src_h, dest_x, dest_y, src_w, src_h, False); } void PGraphicsTileRectangle( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, Drawable d, GC gc, GC mono_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h) { PGraphicsRenderPixmaps( dpy, win, pixmap, mask, alpha, depth, 0, d, gc, mono_gc, None, src_x, src_y, dest_w, dest_h, dest_x, dest_y, dest_w, dest_h, True); } FvwmPicture *PGraphicsCreateStretchPicture( Display *dpy, Window win, FvwmPicture *src, int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc) { Pixmap pixmap = None, mask = None, alpha = None; FvwmPicture *q; if (src == NULL || src->picture == None) { return NULL; } pixmap = CreateStretchPixmap( dpy, src->picture, src->width, src->height, src->depth, dest_width, dest_height, gc); if (!pixmap) { return NULL; } if (src->mask) { mask = CreateStretchPixmap( dpy, src->mask, src->width, src->height, 1, dest_width, dest_height, mono_gc); } if (src->alpha) { alpha = CreateStretchPixmap( dpy, src->alpha, src->width, src->height, FRenderGetAlphaDepth(), dest_width, dest_height, alpha_gc); } q = (FvwmPicture*)safemalloc(sizeof(FvwmPicture)); memset(q, 0, sizeof(FvwmPicture)); q->count = 1; q->name = NULL; q->next = NULL; q->stamp = pixmap; q->picture = pixmap; q->mask = mask; q->alpha = alpha; q->width = dest_width; q->height = dest_height; q->depth = src->depth; q->alloc_pixels = 0; q->nalloc_pixels = 0; return q; } FvwmPicture *PGraphicsCreateTiledPicture( Display *dpy, Window win, FvwmPicture *src, int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc) { Pixmap pixmap = None, mask = None, alpha = None; FvwmPicture *q; if (src == NULL || src->picture == None) { return NULL; } pixmap = CreateTiledPixmap( dpy, src->picture, src->width, src->height, dest_width, dest_height, src->depth, gc); if (!pixmap) { return NULL; } if (src->mask) { mask = CreateTiledPixmap( dpy, src->mask, src->width, src->height, dest_width, dest_height, 1, mono_gc); } if (src->alpha) { alpha = CreateTiledPixmap( dpy, src->alpha, src->width, src->height, dest_width, dest_height, FRenderGetAlphaDepth(), alpha_gc); } q = (FvwmPicture*)safemalloc(sizeof(FvwmPicture)); memset(q, 0, sizeof(FvwmPicture)); q->count = 1; q->name = NULL; q->next = NULL; q->stamp = pixmap; q->picture = pixmap; q->mask = mask; q->alpha = alpha; q->width = dest_width; q->height = dest_height; q->depth = src->depth; q->alloc_pixels = 0; q->nalloc_pixels = 0; return q; } Pixmap PGraphicsCreateTransparency( Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc, int x, int y, int width, int height, Bool parent_relative) { Pixmap r = None, dp = None; XID junk; XID root; int dummy, sx, sy, sw, sh; int gx = x, gy = y, gh = height, gw = width; int old_backing_store = -1; if (parent_relative) { old_backing_store = FSetBackingStore(dpy, win, Always); XSetWindowBackgroundPixmap(dpy, win, ParentRelative); XClearArea(dpy, win, x, y, width, height, False); XSync(dpy, False); } if (parent_relative) { /* this block is not useful if backing store ... */ if (!XGetGeometry( dpy, win, &root, (int *)&junk, (int *)&junk, (unsigned int *)&sw, (unsigned int *)&sh, (unsigned int *)&junk, (unsigned int *)&junk)) { goto bail; } XTranslateCoordinates( dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy, &junk); if (sx >= DisplayWidth(dpy, DefaultScreen(dpy))) { goto bail; } if (sy >= DisplayHeight(dpy, DefaultScreen(dpy))) { goto bail; } if (sx < 0) { gx = gx - sx; gw = width + sx; sx = 0; if (gw <= 0) { goto bail; } } if (sy < 0) { gy = gy - sy; gh = height + sy; sy = 0; if (gh <= 0) { goto bail; } } if (sx + gw > DisplayWidth(dpy, DefaultScreen(dpy))) { gw = DisplayWidth(dpy, DefaultScreen(dpy)) - sx; } if (sy + gh > DisplayHeight(dpy, DefaultScreen(dpy))) { gh = DisplayHeight(dpy, DefaultScreen(dpy)) - sy; } } #if 0 fprintf( stderr,"Geo: %i,%i,%i,%i / %i,%i,%i,%i / %i,%i,%i,%i\n", gx,gy,gw,gh, x,y,width,height, sx,sy,sw,sh); #endif if (XRenderSupport && FRenderGetExtensionSupported()) { r = XCreatePixmap(dpy, win, gw, gh, Pdepth); if (FRenderRender( dpy, win, ParentRelative, None, None, Pdepth, 100, fra->tint, fra->tint_percent, r, gc, None, gx, gy, gw, gh, 0, 0, gw, gh, False)) { goto bail; } XFreePixmap(dpy, r); } r = PCreateRenderPixmap( dpy, win, ParentRelative, None, None, Pdepth, 100, fra->tint, fra->tint_percent, True, win, gc, None, None, gx, gy, gw, gh, gx, gy, gw, gh, False, &dummy, &dummy, &dummy, &dp); bail: if (old_backing_store >= 0) { FSetBackingStore(dpy, win, old_backing_store); } return r; } void PGraphicsTintRectangle( Display *dpy, Window win, Pixel tint, int tint_percent, Drawable dest, Bool dest_is_a_window, GC gc, GC mono_gc, GC alpha_gc, int dest_x, int dest_y, int dest_w, int dest_h) { Pixmap p; FvwmRenderAttributes fra; #if 0 /* this does not work. why? */ if (FRenderTintRectangle( dpy, win, None, tint, tint_percent, dest, dest_x, dest_y, dest_w, dest_h)) { return; } #else if (FRenderRender( dpy, win, ParentRelative, None, None, Pdepth, 100, tint, tint_percent, win, gc, None, dest_x, dest_y, dest_w, dest_h, dest_x, dest_y, dest_w, dest_h, False)) { return; } #endif if (dest_is_a_window) { fra.tint = tint; fra.tint_percent = tint_percent; fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT; p = PGraphicsCreateTransparency( dpy, dest, &fra, gc, dest_x, dest_y, dest_w, dest_h, False); if (p) { XCopyArea( dpy, p, dest, gc, 0, 0, dest_w, dest_h, dest_x, dest_y); XFreePixmap(dpy, p); } } } #if 0 /* humm... maybe useful one day with menus */ Pixmap PGraphicsCreateTranslucent( Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc, int x, int y, int width, int height) { Pixmap r = None; int gx = x, gy = y, gh = height, gw = width; FvwmRenderAttributes t_fra; Pixmap root_pix = None; Pixmap dp = None; int dummy; t_fra.added_alpha_percent = 100; t_fra.tint_percent = 0; t_fra.tint = 0; t_fra.mask = 0; if (fra) { if (fra->mask & FRAM_HAVE_TINT) { t_fra.tint_percent = fra->tint_percent; t_fra.tint = fra->tint; t_fra.mask = FRAM_HAVE_TINT; } } if (x >= DisplayWidth(dpy, DefaultScreen(dpy))) { goto bail; } if (y >= DisplayHeight(dpy, DefaultScreen(dpy))) { goto bail; } if (x < 0) { gx = 0; gw = width + x; if (gw <= 0) { goto bail; } } if (y < 0) { gy = 0; gh = gh+y; if (gh <= 0) { goto bail; } } if (gx + gw > DisplayWidth(dpy, DefaultScreen(dpy))) { gw = DisplayWidth(dpy, DefaultScreen(dpy)) - gx; } if (gy + gh > DisplayHeight(dpy, DefaultScreen(dpy))) { gh = DisplayHeight(dpy, DefaultScreen(dpy)) - gy; } { /* make a screen shoot */ GC my_gc; unsigned long valuemask = GCSubwindowMode; XGCValues values; values.subwindow_mode = IncludeInferiors; root_pix = XCreatePixmap(dpy, win, gw, gh, Pdepth); my_gc = fvwmlib_XCreateGC(dpy, win, 0, NULL); XChangeGC(dpy, my_gc, valuemask, &values); MyXGrabServer(dpy); XCopyArea( dpy, DefaultRootWindow(dpy), root_pix, my_gc, gx, gy, gw, gh, 0, 0); MyXUngrabServer(dpy); XFreeGC(dpy,my_gc); } if (XRenderSupport && FRenderGetExtensionSupported()) { r = XCreatePixmap(dpy, win, gw, gh, Pdepth); if (FRenderRender( dpy, win, root_pix, None, None, Pdepth, t_fra.added_alpha_percent, t_fra.tint, t_fra.tint_percent, r, gc, None, 0, 0, gw, gh, 0, 0, gw, gh, False)) { goto bail; } XFreePixmap(dpy, r); r = None; } r = PCreateRenderPixmap( dpy, win, root_pix, None, None, Pdepth, 100, fra->tint, fra->tint_percent, True, win, gc, None, None, 0, 0, gw, gh, gx, gy, gw, gh, False, &dummy, &dummy, &dummy, &dp); bail: if (root_pix) { XFreePixmap(dpy, root_pix); } if (dp) { XFreePixmap(dpy, dp); } return r; } #endif /* never tested and used ! */ Pixmap PGraphicsCreateDitherPixmap( Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc, int in_width, int in_height, int out_width, int out_height) { return PCreateDitherPixmap( dpy, win, src, mask, depth, gc, in_width, in_height, out_width, out_height); } fvwm-2.6.7/libs/System.c0000644000175700017570000001717313001406607012033 00000000000000/* -*-c-*- */ /* 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 */ /* * System.c: code for dealing with various OS system call variants */ #include "config.h" #include "fvwmlib.h" #include "envvar.h" #include "System.h" #include "Strings.h" #if HAVE_UNAME #include #endif #include "libs/fvwm_sys_stat.h" #if HAVE_SYS_SELECT_H #include #endif /* * just in case... */ #ifndef FD_SETSIZE #define FD_SETSIZE 2048 #endif fd_set_size_t fvwmlib_max_fd = (fd_set_size_t)-9999999; fd_set_size_t GetFdWidth(void) { #if HAVE_SYSCONF return min(sysconf(_SC_OPEN_MAX),FD_SETSIZE); #else return min(getdtablesize(),FD_SETSIZE); #endif } void fvwmlib_init_max_fd(void) { fvwmlib_max_fd = GetFdWidth(); return; } /* return a string indicating the OS type (i.e. "Linux", "SINIX-D", ... ) */ int getostype(char *buf, int max) { #if HAVE_UNAME struct utsname sysname; if (uname( &sysname ) >= 0) { buf[0] = '\0'; strncat(buf, sysname.sysname, max); return 0; } #endif strcpy (buf, ""); return -1; } /* * Set a colon-separated path, with environment variable expansions, * and expand '+' to be the value of the previous path. */ void setPath(char **p_path, const char *newpath, int free_old_path) { char *oldpath = *p_path; int oldlen = strlen(oldpath); char *stripped_path = stripcpy(newpath); int found_plus = strchr(newpath, '+') != NULL; /* Leave room for the old path, if we find a '+' in newpath */ *p_path = envDupExpand(stripped_path, found_plus ? oldlen - 1 : 0); free(stripped_path); if (found_plus) { char *p = strchr(*p_path, '+'); memmove(p + oldlen, p + 1, strlen(p + 1) + 1); memmove(p, oldpath, oldlen); } if (free_old_path) { free(oldpath); } } /* * * Find the specified file somewhere along the given path. * * There is a possible race condition here: We check the file and later * do something with it. By then, the file might not be accessible. * Oh well. * */ #include char *searchPath( const char *pathlist, const char *filename, const char *suffix, int type) { char *path; int filename_len; int maxpath_len; if (filename == NULL || *filename == 0) { return NULL; } if (pathlist == NULL || *pathlist == 0) { /* use pwd if no path list is given */ pathlist = "."; } filename_len = strlen(filename); maxpath_len = (pathlist) ? strlen(pathlist) : 0; maxpath_len += (suffix) ? strlen(suffix) : 0; /* +1 for extra / and +1 for null termination */ path = safemalloc(maxpath_len + filename_len + 2); *path = '\0'; if (*filename == '/') { /* No search if filename begins with a slash */ strcpy(path, filename); /* test if the path is accessable -- the module code assumes * this is done */ if (access(filename, type) == 0) { return path; } /* the file is not accessable (don't test suffixes with full * path), return NULL */ free(path); return NULL; } /* Search each element of the pathlist for the file */ while (pathlist && *pathlist) { char *path_end = strchr(pathlist, ':'); char *curr_end; if (path_end != NULL) { strncpy(path, pathlist, path_end - pathlist); path[path_end - pathlist] = '\0'; } else { strcpy(path, pathlist); } /* handle specially the path extention using semicolon */ curr_end = strchr(path, ';'); if (curr_end != NULL) { char *dot = strrchr(filename, '.'); int filebase_len; /* count a leading nil in newext_len too */ int newext_len = path + strlen(path) - curr_end; if (dot != NULL) { filebase_len = dot - filename; } else { filebase_len = filename_len; } *(curr_end++) = '/'; memmove(curr_end + filebase_len, curr_end, newext_len); strncpy(curr_end, filename, filebase_len); } else { strcat(path, "/"); strcat(path, filename); } if (access(path, type) == 0) { return path; } if (suffix && *suffix != '\0') { strcat(path, suffix); if (access(path, type) == 0) { return path; } } /* Point to next element of the path */ if (path_end == NULL) { break; } else { pathlist = path_end + 1; } } /* Hmm, couldn't find the file. Return NULL */ free(path); return NULL; } /* * void setFileStamp(FileStamp *stamp, const char *name); * Bool isFileStampChanged(const FileStamp *stamp, const char *name); * * An interface for verifying cached files. * The first function associates a file stamp with file (named by name). * The second function returns True or False in case the file was changed * from the time the stamp was associated. * * FileStamp can be a structure; try to save memory by evaluating a checksum. */ FileStamp getFileStamp(const char *name) { static struct stat buf; if (!name || stat(name, &buf)) { return 0; } return ((FileStamp)buf.st_mtime << 13) + (FileStamp)buf.st_size; } void setFileStamp(FileStamp *stamp, const char *name) { *stamp = getFileStamp(name); } Bool isFileStampChanged(const FileStamp *stamp, const char *name) { return *stamp != getFileStamp(name); } #ifdef HAVE_SAFETY_MKSTEMP int fvwm_mkstemp (char *TEMPLATE) { return mkstemp(TEMPLATE); } #else /* This function is an adaptation of the mkstemp() function included * in the Gnu C Library, version 2.2.2. The Gnu C library, in turn, * adapted the function from OpenBSD. * Michael Han */ #include #include #include #include #include #include #include "ftime.h" #define __set_errno(val) errno = (val) /* These are the characters used in temporary filenames. */ static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; /* Generate a unique temporary file name from TEMPLATE. The last six characters of TEMPLATE must be "XXXXXX"; they are replaced with a string that makes the filename unique. Then open the file and return a fd. */ int fvwm_mkstemp (char *template) { int len; char *XXXXXX; static unsigned long value; struct timeval tv; int count, fd = -1; int save_errno = errno; len = strlen (template); if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) { __set_errno (EINVAL); return -1; } /* This is where the Xs start. */ XXXXXX = &template[len - 6]; /* Get some more or less random data. */ gettimeofday (&tv, NULL); value = ((unsigned long) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); for (count = 0; count < TMP_MAX; value = 7777, count) { unsigned long v = value; /* Fill in the random bits. */ XXXXXX[0] = letters[v % 62]; v /= 62; XXXXXX[1] = letters[v % 62]; v /= 62; XXXXXX[2] = letters[v % 62]; v /= 62; XXXXXX[3] = letters[v % 62]; v /= 62; XXXXXX[4] = letters[v % 62]; v /= 62; XXXXXX[5] = letters[v % 62]; fd = open( template, O_RDWR | O_CREAT | O_EXCL, FVWM_S_IRUSR | FVWM_S_IWUSR); if (fd >= 0) { __set_errno (save_errno); return fd; } else if (errno != EEXIST) { return -1; } } /* We got out of the loop because we ran out of combinations to try. */ __set_errno (EEXIST); return -1; } #endif /* HAVE_SAFETY_MKSTEMP */ fvwm-2.6.7/libs/Fpng.h0000644000175700017570000003113012773467232011453 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef FPNG_H #define FPNG_H /* ---------------------------- included header files ---------------------- */ #include "PictureBase.h" #if PngSupport #include #else #include #endif /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ #ifndef _ZLIB_H typedef unsigned char FzByte; typedef unsigned int FzuInt; typedef unsigned long FzuLong; typedef FzByte FzBytef; #ifdef __STDC__ typedef void *Fzvoidpf; typedef void *Fzvoidp; #else typedef FzByte *Fzvoidpf; typedef FzByte *Fzvoidp; #endif typedef Fzvoidpf (*Fzalloc_func) ( #ifdef __STDC__ Fzvoidpf opaque, FzuInt items, FzuInt size #endif ); typedef Fzvoidp (*Fzfree_func) ( #ifdef __STDC__ Fzvoidpf opaque, Fzvoidpf address #endif ); typedef struct Fz_stream_s { FzBytef *next_in; FzuInt avail_in; FzuLong total_in; FzBytef *next_out; FzuInt avail_out; FzuLong total_out; char *msg; struct internal_state *state; Fzalloc_func zalloc; Fzfree_func zfree; Fzvoidpf opaque; int data_type; FzuLong adler; FzuLong reserved; } Fz_stream; typedef Fz_stream *Fz_streamp; #else /* _ZLIB_H */ #ifdef Z_PREFIX typedef z_Byte FzByte; typedef z_uInt FzuInt; typedef z_uLong FzuLong; typedef z_Bytef FzBytef; typedef z_voidp Fzvoidp; typedef z_voidpf Fzvoidpf; typedef z_stream Fz_stream; #else typedef Byte FzByte; typedef uInt FzuInt; typedef uLong FzuLong; typedef Bytef FzBytef; typedef voidp Fzvoidp; typedef voidpf Fzvoidpf; typedef z_stream Fz_stream; #endif #endif /* !_ZLIB_H */ #if PngSupport typedef png_uint_32 Fpng_uint_32; typedef png_int_32 Fpng_int_32; typedef png_uint_16 Fpng_uint_16; typedef png_int_16 Fpng_int_16; typedef png_byte Fpng_byte; typedef png_size_t Fpng_size_t; typedef png_struct Fpng_struct; typedef png_structp Fpng_structp; typedef png_structpp Fpng_structpp; typedef png_info Fpng_info; typedef png_infop Fpng_infop; typedef png_infopp Fpng_infopp; #else typedef unsigned long Fpng_uint_32; typedef long Fpng_int_32; typedef unsigned short Fpng_uint_16; typedef short Fpng_int_16; typedef unsigned char Fpng_byte; typedef size_t Fpng_size_t; typedef void *Fpng_voidp; typedef Fpng_byte *Fpng_bytep; typedef Fpng_uint_32 *Fpng_uint_32p; typedef Fpng_int_32 *Fpng_int_32p; typedef Fpng_uint_16 *Fpng_uint_16p; typedef Fpng_int_16 *Fpng_int_16p; typedef const char *Fpng_const_charp; typedef char *Fpng_charp; typedef double *Fpng_doublep; typedef Fpng_byte **Fpng_bytepp; typedef Fpng_uint_32 **Fpng_uint_32pp; typedef Fpng_int_32 **Fpng_int_32pp; typedef Fpng_uint_16 **Fpng_uint_16pp; typedef Fpng_int_16 **Fpng_int_16pp; typedef const char **Fpng_const_charpp; typedef char **Fpng_charpp; typedef double **Fpng_doublepp; typedef char ** *Fpng_charppp; typedef struct Fpng_color_struct { Fpng_byte red; Fpng_byte green; Fpng_byte blue; } Fpng_color; typedef Fpng_color *Fpng_colorp; typedef Fpng_color **Fpng_colorpp; typedef struct Fpng_color_16_struct { Fpng_byte index; Fpng_uint_16 red; Fpng_uint_16 green; Fpng_uint_16 blue; Fpng_uint_16 gray; } Fpng_color_16; typedef Fpng_color_16 *Fpng_color_16p; typedef Fpng_color_16 **Fpng_color_16pp; typedef struct Fpng_color_8_struct { Fpng_byte red; Fpng_byte green; Fpng_byte blue; Fpng_byte gray; Fpng_byte alpha; } Fpng_color_8; typedef Fpng_color_8 *Fpng_color_8p; typedef Fpng_color_8 **Fpng_color_8pp; typedef struct Fpng_text_struct { int compression; Fpng_charp key; Fpng_charp text; Fpng_size_t text_length; } Fpng_text; typedef Fpng_text *Fpng_textp; typedef Fpng_text **Fpng_textpp; typedef struct Fpng_time_struct { Fpng_uint_16 year; Fpng_byte month; Fpng_byte day; Fpng_byte hour; Fpng_byte minute; Fpng_byte second; } Fpng_time; typedef Fpng_time *Fpng_timep; typedef Fpng_time **Fpng_timepp; typedef struct Fpng_info_struct { Fpng_uint_32 width; Fpng_uint_32 height; Fpng_uint_32 valid; Fpng_uint_32 rowbytes; Fpng_colorp palette; Fpng_uint_16 num_palette; Fpng_uint_16 num_trans; Fpng_byte bit_depth; Fpng_byte color_type; Fpng_byte compression_type; Fpng_byte filter_type; Fpng_byte interlace_type; Fpng_byte channels; Fpng_byte pixel_depth; Fpng_byte spare_byte; Fpng_byte signature[8]; float gamma; Fpng_byte srgb_intent; int num_text; int max_text; Fpng_textp text; Fpng_time mod_time; Fpng_color_8 sig_bit; Fpng_bytep trans; Fpng_color_16 trans_values; Fpng_color_16 background; Fpng_uint_32 x_offset; Fpng_uint_32 y_offset; Fpng_byte offset_unit_type; Fpng_uint_32 x_pixels_per_unit; Fpng_uint_32 y_pixels_per_unit; Fpng_byte phys_unit_type; Fpng_uint_16p hist; float x_white; float y_white; float x_red; float y_red; float x_green; float y_green; float x_blue; float y_blue; Fpng_charp pcal_purpose; Fpng_int_32 pcal_X0; Fpng_int_32 pcal_X1; Fpng_charp pcal_units; Fpng_charpp pcal_params; Fpng_byte pcal_type; Fpng_byte pcal_nparams; } Fpng_info; typedef Fpng_info *Fpng_infop; typedef Fpng_info **Fpng_infopp; typedef struct Fpng_struct_def Fpng_struct; typedef Fpng_struct *Fpng_structp; typedef struct Fpng_row_info_struct { Fpng_uint_32 width; Fpng_uint_32 rowbytes; Fpng_byte color_type; Fpng_byte bit_depth; Fpng_byte channels; Fpng_byte pixel_depth; } Fpng_row_info; typedef Fpng_row_info *Fpng_row_infop; typedef Fpng_row_info **Fpng_row_infopp; typedef void (*Fpng_error_ptr)( #ifdef __STDC__ Fpng_structp, Fpng_const_charp #endif ); typedef void (*Fpng_rw_ptr)( #ifdef __STDC__ Fpng_structp, Fpng_bytep, Fpng_size_t #endif ); typedef void (*Fpng_flush_ptr) ( #ifdef __STDC__ Fpng_structp #endif ); typedef void (*Fpng_read_status_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_uint_32, int #endif ); typedef void (*Fpng_write_status_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_uint_32, int #endif ); typedef void (*Fpng_progressive_info_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_infop #endif ); typedef void (*Fpng_progressive_end_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_infop #endif ); typedef void (*Fpng_progressive_row_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_bytep,Fpng_uint_32, int #endif ); typedef void (*Fpng_user_transform_ptr)( #ifdef __STDC__ Fpng_structp, Fpng_row_infop, Fpng_bytep #endif ); typedef Fpng_voidp (*Fpng_malloc_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_size_t #endif ); typedef void (*Fpng_free_ptr) ( #ifdef __STDC__ Fpng_structp, Fpng_voidp #endif ); struct png_struct_def { jmp_buf jmpbuf; Fpng_error_ptr error_fn; Fpng_error_ptr warning_fn; Fpng_voidp error_ptr; Fpng_rw_ptr write_data_fn; Fpng_rw_ptr read_data_fn; Fpng_voidp io_ptr; Fpng_user_transform_ptr read_user_transform_fn; Fpng_user_transform_ptr write_user_transform_fn; Fpng_voidp user_transform_ptr; Fpng_byte user_transform_depth; Fpng_byte user_transform_channels; Fpng_uint_32 mode; Fpng_uint_32 flags; Fpng_uint_32 transformations; Fz_stream zstream; Fpng_bytep zbuf; Fpng_size_t zbuf_size; int zlib_level; int zlib_method; int zlib_window_bits; int zlib_mem_level; int zlib_strategy; Fpng_uint_32 width; Fpng_uint_32 height; Fpng_uint_32 num_rows; Fpng_uint_32 usr_width; Fpng_uint_32 rowbytes; Fpng_uint_32 irowbytes; Fpng_uint_32 iwidth; Fpng_uint_32 row_number; Fpng_bytep prev_row; Fpng_bytep row_buf; Fpng_bytep sub_row; Fpng_bytep up_row; Fpng_bytep avg_row; Fpng_bytep paeth_row; Fpng_row_info row_info; Fpng_uint_32 idat_size; Fpng_uint_32 crc; Fpng_colorp palette; Fpng_uint_16 num_palette; Fpng_uint_16 num_trans; Fpng_byte chunk_name[5]; Fpng_byte compression; Fpng_byte filter; Fpng_byte interlaced; Fpng_byte pass; Fpng_byte do_filter; Fpng_byte color_type; Fpng_byte bit_depth; Fpng_byte usr_bit_depth; Fpng_byte pixel_depth; Fpng_byte channels; Fpng_byte usr_channels; Fpng_byte sig_bytes; Fpng_uint_16 filler; Fpng_byte background_gamma_type; float background_gamma; Fpng_color_16 background; Fpng_color_16 background_1; Fpng_flush_ptr output_flush_fn; Fpng_uint_32 flush_dist; Fpng_uint_32 flush_rows; int gamma_shift; float gamma; float screen_gamma; Fpng_bytep gamma_table; Fpng_bytep gamma_from_1; Fpng_bytep gamma_to_1; Fpng_uint_16pp gamma_16_table; Fpng_uint_16pp gamma_16_from_1; Fpng_uint_16pp gamma_16_to_1; Fpng_color_8 sig_bit; Fpng_color_8 shift; Fpng_bytep trans; Fpng_color_16 trans_values; Fpng_read_status_ptr read_row_fn; Fpng_write_status_ptr write_row_fn; Fpng_progressive_info_ptr info_fn; Fpng_progressive_row_ptr row_fn; Fpng_progressive_end_ptr end_fn; Fpng_bytep save_buffer_ptr; Fpng_bytep save_buffer; Fpng_bytep current_buffer_ptr; Fpng_bytep current_buffer; Fpng_uint_32 push_length; Fpng_uint_32 skip_length; Fpng_size_t save_buffer_size; Fpng_size_t save_buffer_max; Fpng_size_t buffer_size; Fpng_size_t current_buffer_size; int process_mode; int cur_palette; Fpng_size_t current_text_size; Fpng_size_t current_text_left; Fpng_charp current_text; Fpng_charp current_text_ptr; Fpng_bytepp offset_table_ptr; Fpng_bytep offset_table; Fpng_uint_16 offset_table_number; Fpng_uint_16 offset_table_count; Fpng_uint_16 offset_table_count_free; Fpng_bytep palette_lookup; Fpng_bytep dither_index; Fpng_uint_16p hist; Fpng_byte heuristic_method; Fpng_byte num_prev_filters; Fpng_bytep prev_filters; Fpng_uint_16p filter_weights; Fpng_uint_16p inv_filter_weights; Fpng_uint_16p filter_costs; Fpng_uint_16p inv_filter_costs; Fpng_charp time_buffer; Fpng_voidp mem_ptr; Fpng_malloc_ptr malloc_fn; Fpng_free_ptr free_fn; Fpng_byte rgb_to_gray_status; Fpng_byte rgb_to_gray_red_coeff; Fpng_byte rgb_to_gray_green_coeff; Fpng_byte rgb_to_gray_blue_coeff; Fpng_byte empty_plte_permitted; }; typedef Fpng_struct **Fpng_structpp; #endif /* ---------------------------- global definitions ------------------------- */ #define FPNG_BYTES_TO_CHECK 4 #if PngSupport #define FPNG_LIBPNG_VER_STRING PNG_LIBPNG_VER_STRING #define FPNG_COLOR_TYPE_PALETTE PNG_COLOR_TYPE_PALETTE #define FPNG_COLOR_TYPE_RGB_ALPHA PNG_COLOR_TYPE_RGB_ALPHA #define FPNG_COLOR_TYPE_GRAY_ALPHA PNG_COLOR_TYPE_GRAY_ALPHA #define FPNG_COLOR_TYPE_GRAY PNG_COLOR_TYPE_GRAY #define FPNG_FILLER_BEFORE PNG_FILLER_BEFORE #define FPNG_FILLER_AFTER PNG_FILLER_AFTER #define FPNG_INFO_tRNS PNG_INFO_tRNS #if PNG_LIBPNG_VER >= 10400 #define Fpng_check_sig(a,b) (!png_sig_cmp(a,0,b)) #else #define Fpng_check_sig(a,b) png_check_sig(a,b) #endif #define Fpng_create_read_struct(a,b,c,d) png_create_read_struct(a,b,c,d) #define Fpng_create_info_struct(a) png_create_info_struct(a) #define Fpng_destroy_read_struct(a,b,c) png_destroy_read_struct(a,b,c) #define Fpng_init_io(a,b) png_init_io(a,b) #define Fpng_read_info(a,b) png_read_info(a,b) #define Fpng_get_IHDR(a,b,c,d,e,f,g,h,i) png_get_IHDR(a,b,c,d,e,f,g,h,i) #define Fpng_set_expand(a) png_set_expand(a) #define Fpng_set_swap_alpha(a) png_set_swap_alpha(a) #define Fpng_set_filler(a,b,c) png_set_filler(a,b,c) #define Fpng_set_bgr(a) png_set_bgr(a) #define Fpng_set_strip_16(a) png_set_strip_16(a) #define Fpng_set_packing(a) png_set_packing(a) #define Fpng_set_gray_to_rgb(a) png_set_gray_to_rgb(a) #define Fpng_get_bit_depth(a,b) png_get_bit_depth(a,b) #if PNG_LIBPNG_VER >= 10400 #define Fpng_set_gray_1_2_4_to_8(a) png_set_expand_gray_1_2_4_to_8(a) #else #define Fpng_set_gray_1_2_4_to_8(a) png_set_gray_1_2_4_to_8(a) #endif #define Fpng_get_valid(a,b,c) png_get_valid(a,b,c) #define Fpng_read_end(a,b) png_read_end(a,b) #define Fpng_set_interlace_handling(a) png_set_interlace_handling(a) #define Fpng_read_rows(a,b,c,d) png_read_rows(a,b,c,d) #define Fpng_read_image(a,b) png_read_image(a,b) #else #define FPNG_LIBPNG_VER_STRING "" #define FPNG_COLOR_TYPE_PALETTE 0 #define FPNG_COLOR_TYPE_RGB_ALPHA 1 #define FPNG_COLOR_TYPE_GRAY_ALPHA 2 #define FPNG_COLOR_TYPE_GRAY 3 #define FPNG_FILLER_BEFORE 6 #define FPNG_FILLER_AFTER 5 #define FPNG_INFO_tRNS 7 #define Fpng_check_sig(a,b) 0 #define Fpng_create_read_struct(a,b,c,d) NULL #define Fpng_create_info_struct(a) NULL #define Fpng_destroy_read_struct(a,b,c) #define Fpng_init_io(a,b) #define Fpng_read_info(a,b) #define Fpng_get_IHDR(a,b,c,d,e,f,g,h,i) #define Fpng_set_expand(a) #define Fpng_set_swap_alpha(a) #define Fpng_set_filler(a,b,c) #define Fpng_set_bgr(a) #define Fpng_set_strip_16(a) #define Fpng_set_packing(a) #define Fpng_set_gray_to_rgb(a) #define Fpng_get_bit_depth(a,b) 0 #define Fpng_set_gray_1_2_4_to_8(a) #define Fpng_get_valid(a,b,c) 0 #define Fpng_read_end(a,b) #define Fpng_set_interlace_handling(a) 0 #define Fpng_read_rows(a,b,c,d) #define Fpng_read_image(a,b) #endif #endif /* FPNG_H */ fvwm-2.6.7/libs/fio.c0000644000175700017570000000305012773467232011331 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "fio.h" /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- interface functions ------------------------ */ ssize_t fvwm_send(int s, const void *buf, size_t len, int flags) { int rc; size_t offset; const char *data; data = buf; offset = 0; do { rc = send(s, (char *)data + offset, len - offset, flags); if (rc > 0) { offset += rc; } } while ((rc > 0 && (offset < len)) || (rc == -1 && errno == EINTR)); return rc; } ssize_t fvwm_recv(int s, void *buf, size_t len, int flags) { int rc; do { rc = recv(s, buf, len, flags); } while (rc == -1 && errno == EINTR); return rc; } fvwm-2.6.7/libs/envvar.c0000644000175700017570000003011513001406607012037 00000000000000/* -*-c-*- */ /* 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 */ /* * MODULE OF fvwm * * DESCRIPTION Routines to expand environment-variables into strings. * Will understand both $ENV and ${ENV} -type variables. * * WRITTEN BY Sverre H. Huseby * sverrehu@ifi.uio.no * * CREATED 1995/10/3 * * UPDATED migo - 21/Jun/1999 - added getFirstEnv, some changes * */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwmlib.h" #include "envvar.h" /* ---------------------------- local definitions -------------------------- */ #ifdef HAVE_UNSETENV #define FHaveUnsetenv 1 #else #define unsetenv(x) do { } while (0) #define FHaveUnsetenv 0 #endif /* ---------------------------- local macros ------------------------------- */ #define ENV_LIST_INC 10 #ifndef NULL #define NULL 0 #endif /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { char *var; char *env; } env_list_item; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /*------------------------------------------------------------------------- * * NAME strDel * * FUNCTION Delete characters from a string. * * INPUT s the string to delete characters from. * idx index of first character to delete. * n number of characters to delete. * * OUTPUT s string with characters deleted. * * DESCRIPTION Deletes characters from a string by moving following * characters back. * */ static void strDel(char *s, int idx, int n) { int l; char *p; if (idx >= (l = strlen(s))) return; if (idx + n > l) n = l - idx; s += idx; p = s + n; do { *s++ = *p; } while (*p++); } /*------------------------------------------------------------------------- * * NAME strIns * * FUNCTION Insert a string into a string. * * INPUT s the string to insert into. * ins the string to insert. * idx index of where to insert the string. * maxstrlen max length of s, including '\0'. * * OUTPUT s string with characters inserted. * * DESCRIPTION The insertion will be done even if the string gets to * long, but characters will be sacrificed at the end of s. * The string is always '\0'-terminated. * */ static void strIns(char *s, const char *ins, int idx, int maxstrlen) { int l, li, move; char *p1, *p2; if (idx > (l = strlen(s))) { idx = l; } li = strlen(ins); move = l - idx + 1; /* include '\0' in move */ p1 = s + l; p2 = p1 + li; while (p2 >= s + maxstrlen) { --p1; --p2; --move; } while (move-- > 0) *p2-- = *p1--; p1 = s + idx; if (idx + li >= maxstrlen) { li = maxstrlen - idx - 1; } while (li-- > 0) *p1++ = *ins++; s[maxstrlen - 1] = '\0'; } /*------------------------------------------------------------------------- * * NAME findEnvVar * * FUNCTION Find first environment variable in a string. * * INPUT s the string to scan. * * OUTPUT len length of variable, including $ and { }. * * RETURNS Pointer to the $ that introduces the variable, or NULL * if no variable is found. * * DESCRIPTION Searches for matches like $NAME and ${NAME}, where NAME is * a sequence of characters, digits and underscores, of which * the first can not be a digit. * * NOTE This function will only return `legal' variables. There * may be $'s in the string that are not followed by what * is considered a legal variable name introducer. Such * occurrences are skipped. * */ static char *findEnvVar(const char *s, int *len) { int brace = 0; char *ret = NULL; const char *next; if (!s) return NULL; while (*s) { next = s + 1; if (*s == '$' && (isalpha(*next) || *next == '_' || *next == '{')) { ret = (char *) s++; if (*s == '{') { brace = 1; ++s; } while (*s && (isalnum(*s) || *s == '_')) ++s; *len = s - ret; if (brace) { if (*s == '}') { ++*len; break; } ret = NULL; } else break; } ++s; } return ret; } /*------------------------------------------------------------------------- * * FUNCTION Look up environment variable. * * INPUT name name of environment variable to look up. This * may include $ and { }. * len length for environment variable name (0 - ignore). * * RETURNS The variable contents, or "" if not found. * */ static const char *getEnv(const char *name, int len) { static char *empty = ""; char *ret = NULL, *tmp, *p, *p2; if ((tmp = safestrdup(name)) == NULL) return empty; /* better than no test at all. */ p = tmp; if (*p == '$') ++p; if (*p == '{') { ++p; if ((p2 = strchr(p, '}')) != NULL) *p2 = '\0'; } if (len > 0 && len < strlen(tmp)) tmp[len] = '\0'; if ((ret = getenv(p)) == NULL) ret = empty; free(tmp); return ret; } /* ---------------------------- interface functions ------------------------ */ /* * FUNCTION Expand environment variables in a string. * * SYNOPSIS #include "envvar.h" * int envExpand(char *s, int maxstrlen); * * INPUT s string to expand environment variables in. * maxstrlen max length of string, including '\0'. * * OUTPUT s the string with environment variables expanded. * * RETURNS Number of changes done. * * NOTES A non-existing variable is substituted with the empty * string. * */ int envExpand(char *s, int maxstrlen) { char *var, *s2; const char *env; int len, ret = 0; s2 = s; while ((var = findEnvVar(s2, &len)) != NULL) { ++ret; env = getEnv(var, len); strDel(s, var - s, len); strIns(s, env, var - s, maxstrlen); s2 = var + strlen(env); } return ret; } /* * FUNCTION Expand environment variables into a new string. * * SYNOPSIS #include "envvar.h" * char *envDupExpand(const char *s, int extra); * * INPUT s string to expand environment variables in. * extra number of extra bytes to allocate in the * string, in addition to the string contents * and the terminating '\0'. * * RETURNS A dynamically allocated string with environment * variables expanded. * Use free() to deallocate the buffer when it is no * longer needed. * NULL is returned if there is not enough memory. * * NOTES A non-existing variable is substituted with the empty * string. * */ char *envDupExpand(const char *s, int extra) { char *var, *ret; const char *env, *s2; int len, slen, elen, bufflen; /* * calculate length needed. */ s2 = s; slen = strlen(s); bufflen = slen + 1 + extra; while ((var = findEnvVar(s2, &len)) != NULL) { env = getEnv(var, len); elen = strlen(env); /* need to make a buffer the maximum possible size, else we * may get trouble while expanding. */ bufflen += len > elen ? len : elen; s2 = var + len; } if (bufflen < slen + 1) bufflen = slen + 1; ret = safemalloc(bufflen); /* * now do the real expansion. */ strcpy(ret, s); envExpand(ret, bufflen - extra); return ret; } /* * FUNCTION Search for the first environment variable and return * its contents and coordinates in the given string. * * INPUT s the string to scan. * may include $ and { } that introduce variable. * * OUTPUT beg index in the string of matching $. * end index in the string, first after matching var. * * RETURNS The variable contents; "" if env variable has legal name, * but does not exist; or NULL if no env variables found. * Returned constant string must not be deallocated. * * NOTE This function will only return `legal' variables. There * may be $'s in the string that are not followed by what * is considered a legal variable name introducer. Such * occurrences are skipped. * If nothing is found returns NULL and sets beg and end to 0. * * EXAMPLE getFirstEnv("echo $HOME/.fvwm/config", &beg, &end) * returns "/home/username" and beg=5, end=10. * */ const char* getFirstEnv(const char *s, int *beg, int *end) { char *var; const char *env; int len; *beg = *end = 0; if ((var = findEnvVar(s, &len)) == NULL) return NULL; env = getEnv(var, len); *beg = var - s; *end = *beg + len; return env; } /* If env is NULL, var is removed from the environment list */ static void add_to_envlist(char *var, char *env) { static env_list_item *env_list = NULL; static unsigned int env_len = 0; static unsigned int env_len_allocated = 0; unsigned int i; /* find string in list */ if (env_list && env_len) { for (i = 0; i < env_len; i++) { if (strcmp(var, env_list[i].var) != 0) { continue; } /* found it - replace old string */ free(env_list[i].var); free(env_list[i].env); if (env == NULL) { /* delete */ env_len--; env_list[i].var = env_list[env_len].var; env_list[i].env = env_list[env_len].env; } else { /* replace */ env_list[i].var = var; env_list[i].env = env; } return; } } if (env == NULL) { return; } /* not found */ if (env_list == NULL) { /* list is still empty */ env_len_allocated = ENV_LIST_INC; env_list = (env_list_item *)safecalloc( sizeof(env_list_item), env_len_allocated); } else if (env_len >= env_len_allocated && env != NULL) { /* need more memory */ env_len_allocated = env_len + ENV_LIST_INC; env_list = (env_list_item *)saferealloc( (void *)env_list, (env_len_allocated) * sizeof(env_list_item)); } env_list[env_len].var = var; env_list[env_len].env = env; env_len++; return; } /* This function keeps a list of all strings that were set in the environment. * If a variable is written again, the old memory is freed. This function * should be called instead of putenv(). * * var - environement variable name * env - environment string ("variable=value") * * Both arguments are copied internally and should be freed after calling this * function. */ void flib_putenv(char *var, char *env) { char *s; s = safestrdup(var); var = s; s = safestrdup(env); env = s; putenv(env); add_to_envlist(var, env); return; } void flib_unsetenv(const char *name) { if (FHaveUnsetenv) { unsetenv(name); } else { int rc; /* try putenv without '=' */ rc = putenv((char *)name); if (rc == 0 || getenv(name) != NULL) { /* failed, write empty string */ flib_putenv((char *)name, ""); return; } } add_to_envlist((char *)name, NULL); return; } fvwm-2.6.7/libs/wild.h0000644000175700017570000000070612773467232011525 00000000000000/* -*-c-*- */ /* * Does `string' match `pattern'? '*' in pattern matches any sub-string * (including the null string) '?' matches any single char. For use * by filenameforall. Note that '*' matches across directory boundaries * * This code donated by Paul Hudson * It is public domain, no strings attached. No guarantees either. * */ int matchWildcards(const char *pattern, const char *string); fvwm-2.6.7/libs/FGettext.h0000644000175700017570000000515412773467232012322 00000000000000/* -*-c-*- */ /* Convenience header for conditional use of GNU . Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 #include "config.h" #define _(x) FGettext(x) /* NLS can be disabled through the configure --disable-nls option. */ #if HAVE_NLS #define HaveNLSSupport 1 /* Get declarations of GNU message catalog functions. */ # include #else #define HaveNLSSupport 0 /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. We don't include as well because people using "gettext.h" will not include , and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) # include #endif /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # define gettext(Msgid) ((const char *) (Msgid)) # define dgettext(Domainname, Msgid) ((const char *) (Msgid)) # define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) # define textdomain(Domainname) ((const char *) (Domainname)) # define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) # define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) #endif /* A pseudo function call that serves as a marker for the automated extraction of messages, but does not call gettext(). The run-time translation is done at a different place in the code. The argument, String, should be a literal string. Concatenated strings and other string expressions won't work. The macro's expansion is not parenthesized, so that it is suitable as initializer for static 'char[]' or 'const char[]' variables. */ #define gettext_noop(String) String void FGettextInit(const char *domain, const char *dir, const char *module); const char *FGettext(char *str); char *FGettextCopy(char *str); void FGettextSetLocalePath(const char *path); void FGettextPrintLocalePath(int verbose); #endif /* _LIBGETTEXT_H */ fvwm-2.6.7/libs/Fplay.h0000644000175700017570000003140512773467232011641 00000000000000#ifndef FPLAY_H #define FPLAY_H #ifdef HAVE_RPLAY #define USE_FPLAY 1 #else #define USE_FPLAY 0 #endif #if USE_FPLAY # include # undef M_ERROR /* Solaris fix */ typedef RPLAY FPLAY; typedef RPLAY_ATTRS FPLAY_ATTRS; # define FPLAY_DEFAULT_VALUE RPLAY_DEFAULT_VOLUME # define FPLAY_DEFAULT_PRIORITY RPLAY_DEFAULT_PRIORITY # define FPLAY_NULL RPLAY_NULL # define FPLAY_PLAY RPLAY_PLAY # define FPLAY_STOP RPLAY_STOP # define FPLAY_PAUSE RPLAY_PAUSE # define FPLAY_CONTINUE RPLAY_CONTINUE # define FPLAY_SOUND RPLAY_SOUND # define FPLAY_VOLUME RPLAY_VOLUME # define FPLAY_NSOUNDS RPLAY_NSOUNDS # define FPLAY_COMMAND RPLAY_COMMAND # define FPLAY_APPEND RPLAY_APPEND # define FPLAY_INSERT RPLAY_INSERT # define FPLAY_DELETE RPLAY_DELETE # define FPLAY_CHANGE RPLAY_CHANGE # define FPLAY_COUNT RPLAY_COUNT # define FPLAY_LIST_COUNT RPLAY_LIST_COUNT # define FPLAY_PRIORITY RPLAY_PRIORITY # define FPLAY_RANDOM_SOUND RPLAY_RANDOM_SOUND # define FPLAY_PING RPLAY_PING # define FPLAY_RPTP_SERVER RPLAY_RPTP_SERVER # define FPLAY_RPTP_SERVER_PORT RPLAY_RPTP_SERVER_PORT # define FPLAY_RPTP_SEARCH RPLAY_RPTP_SEARCH # define FPLAY_RPTP_FROM_SENDER RPLAY_RPTP_FROM_SENDER # define FPLAY_SAMPLE_RATE RPLAY_SAMPLE_RATE # define FPLAY_RESET RPLAY_RESET # define FPLAY_DONE RPLAY_DONE # define FPLAY_CLIENT_DATA RPLAY_CLIENT_DATA # define FPLAY_LIST_NAME RPLAY_LIST_NAME # define FPLAY_PUT RPLAY_PUT # define FPLAY_ID RPLAY_ID # define FPLAY_SEQUENCE RPLAY_SEQUENCE # define FPLAY_DATA RPLAY_DATA # define FPLAY_DATA_SIZE RPLAY_DATA_SIZE # define FPLAY_FORMAT_NONE RPLAY_FORMAT_NONE # define FPLAY_FORMAT_LINEAR_8 RPLAY_FORMAT_LINEAR_8 # define FPLAY_FORMAT_ULINEAR_8 RPLAY_FORMAT_ULINEAR_8 # define FPLAY_FORMAT_LINEAR_16 RPLAY_FORMAT_LINEAR_16 # define FPLAY_FORMAT_ULINEAR_16 RPLAY_FORMAT_ULINEAR_16 # define FPLAY_FORMAT_ULAW RPLAY_FORMAT_ULAW # define FPLAY_FORMAT_G721 RPLAY_FORMAT_G721 # define FPLAY_FORMAT_G723_3 RPLAY_FORMAT_G723_3 # define FPLAY_FORMAT_G723_5 RPLAY_FORMAT_G723_5 # define FPLAY_FORMAT_GSM RPLAY_FORMAT_GSM # define FPLAY_BIG_ENDIAN RPLAY_BIG_ENDIAN # define FPLAY_LITTLE_ENDIAN RPLAY_LITTLE_ENDIAN # define FPLAY_AUDIO_PORT_NONE RPLAY_AUDIO_PORT_NONE # define FPLAY_AUDIO_PORT_SPEAKER RPLAY_AUDIO_PORT_SPEAKER # define FPLAY_AUDIO_PORT_HEADPHONE RPLAY_AUDIO_PORT_HEADPHONE # define FPLAY_AUDIO_PORT_LINEOUT RPLAY_AUDIO_PORT_LINEOUT # define FPLAY_MIN_VOLUME RPLAY_MIN_VOLUME # define FPLAY_MAX_VOLUME RPLAY_MAX_VOLUME # define FPLAY_MIN_PRIORITY RPLAY_MIN_PRIORITY # define FPLAY_MAX_PRIORITY RPLAY_MAX_PRIORITY # define FPLAY_DEFAULT_VOLUME RPLAY_DEFAULT_VOLUME # define FPLAY_DEFAULT_PRIORITY RPLAY_DEFAULT_PRIORITY # define FPLAY_DEFAULT_COUNT RPLAY_DEFAULT_COUNT # define FPLAY_DEFAULT_LIST_COUNT RPLAY_DEFAULT_LIST_COUNT # define FPLAY_DEFAULT_RANDOM_SOUND RPLAY_DEFAULT_RANDOM_SOUND # define FPLAY_DEFAULT_SAMPLE_RATE RPLAY_DEFAULT_SAMPLE_RATE # define FPLAY_DEFAULT_OFFSET RPLAY_DEFAULT_OFFSET # define FPLAY_DEFAULT_BYTE_ORDER RPLAY_DEFAULT_BYTE_ORDER # define FPLAY_DEFAULT_CHANNELS RPLAY_DEFAULT_CHANNELS # define FPLAY_DEFAULT_BITS RPLAY_DEFAULT_BITS # define FPLAY_ERROR_NONE RPLAY_ERROR_NONE # define FPLAY_ERROR_MEMORY RPLAY_ERROR_MEMORY # define FPLAY_ERROR_HOST RPLAY_ERROR_HOST # define FPLAY_ERROR_CONNECT RPLAY_ERROR_CONNECT # define FPLAY_ERROR_SOCKET RPLAY_ERROR_SOCKET # define FPLAY_ERROR_WRITE RPLAY_ERROR_WRITE # define FPLAY_ERROR_CLOSE RPLAY_ERROR_CLOSE # define FPLAY_ERROR_PACKET_SIZE RPLAY_ERROR_PACKET_SIZE # define FPLAY_ERROR_BROADCAST RPLAY_ERROR_BROADCAST # define FPLAY_ERROR_ATTRIBUTE RPLAY_ERROR_ATTRIBUTE # define FPLAY_ERROR_COMMAND RPLAY_ERROR_COMMAND # define FPLAY_ERROR_INDEX RPLAY_ERROR_INDEX # define FPLAY_ERROR_MODIFIER RPLAY_ERROR_MODIFIER # define FRPTP_ERROR_NONE RPTP_ERROR_NONE # define FRPTP_ERROR_MEMORY RPTP_ERROR_MEMORY # define FRPTP_ERROR_HOST RPTP_ERROR_HOST # define FRPTP_ERROR_CONNECT RPTP_ERROR_CONNECT # define FRPTP_ERROR_SOCKET RPTP_ERROR_SOCKET # define FRPTP_ERROR_OPEN RPTP_ERROR_OPEN # define FRPTP_ERROR_READ RPTP_ERROR_READ # define FRPTP_ERROR_WRITE RPTP_ERROR_WRITE # define FRPTP_ERROR_PING RPTP_ERROR_PING # define FRPTP_ERROR_TIMEOUT RPTP_ERROR_TIMEOUT # define FRPTP_ERROR_PROTOCOL RPTP_ERROR_PROTOCOL # define FRPTP_ERROR RPTP_ERROR # define FRPTP_OK RPTP_OK # define FRPTP_TIMEOUT RPTP_TIMEOUT # define FRPTP_NOTIFY RPTP_NOTIFY # define FOLD_RPLAY_PLAY OLD_RPLAY_PLAY # define FOLD_RPLAY_STOP OLD_RPLAY_STOP # define FOLD_RPLAY_PAUSE OLD_RPLAY_PAUSE # define FOLD_RPLAY_CONTINUE OLD_RPLAY_CONTINUE # define FRPTP_ASYNC_READ RPTP_ASYNC_READ # define FRPTP_ASYNC_WRITE RPTP_ASYNC_WRITE # define FRPTP_ASYNC_RAW RPTP_ASYNC_RAW # define FRPTP_ASYNC_ENABLE RPTP_ASYNC_ENABLE # define FRPTP_ASYNC_DISABLE RPTP_ASYNC_DISABLE # define FRPTP_EVENT_OK RPTP_EVENT_OK # define FRPTP_EVENT_ERROR RPTP_EVENT_ERROR # define FRPTP_EVENT_TIMEOUT RPTP_EVENT_TIMEOUT # define FRPTP_EVENT_OTHER RPTP_EVENT_OTHER # define FRPTP_EVENT_CONTINUE RPTP_EVENT_CONTINUE # define FRPTP_EVENT_DONE RPTP_EVENT_DONE # define FRPTP_EVENT_PAUSE RPTP_EVENT_PAUSE # define FRPTP_EVENT_PLAY RPTP_EVENT_PLAY # define FRPTP_EVENT_SKIP RPTP_EVENT_SKIP # define FRPTP_EVENT_STATE RPTP_EVENT_STATE # define FRPTP_EVENT_STOP RPTP_EVENT_STOP # define FRPTP_EVENT_VOLUME RPTP_EVENT_VOLUME # define FRPTP_EVENT_CLOSE RPTP_EVENT_CLOSE # define FRPTP_EVENT_FLOW RPTP_EVENT_FLOW # define FRPTP_EVENT_MODIFY RPTP_EVENT_MODIFY # define FRPTP_EVENT_LEVEL RPTP_EVENT_LEVEL # define FRPTP_EVENT_POSITION RPTP_EVENT_POSITION # define FRPTP_EVENT_ALL RPTP_EVENT_ALL # define FRPTP_MAX_ARGS RPTP_MAX_ARGS # define FRPTP_MAX_LINE RPTP_MAX_LINE # define FPLAY_PORT RPLAY_PORT # define FRPTP_PORT RPTP_PORT # define FOLD_RPLAY_PORT OLD_RPLAY_PORT # define FOLD_RPTP_PORT OLD_RPTP_PORT # define FPLAY_PACKET_ID RPLAY_PACKET_ID # define Fplay_errno rplay_errno # define Frptp_errno rptp_errno # define Fplay(a,b) rplay(a,b) # define Fplay_create(a) rplay_create(a) # define Fplay_perror(a) rplay_perror(a) /* variadict macros appeared in C99, so we can't use them */ # define Fplay_set rplay_set # define Fplay_get rplay_get # define Frptp_putline rptp_putline # define Frptp_async_putline rptp_async_putline # define Fplay_destroy(a) rplay_destroy(a) # define Fplay_default_host() rplay_default_host() # define Fplay_display(a) rplay_display(a) # define Fplay_host(a,b) rplay_host(a,b) # define Fplay_host_volume(a,b,c) rplay_host_volume(a,b,c) # define Fplay_local(a) rplay_local(a) # define Fplay_open(a) rplay_open(a) # define Fplay_open_default() rplay_open_default() # define Fplay_open_display() rplay_open_display() # define Fplay_open_port(a,b) rplay_open_port(a,b) # define Fplay_open_sockaddr_in(a) rplay_open_sockaddr(a) # define Fplay_ping(a) rplay_ping(a) # define Fplay_ping_sockaddr_in(a) rplay_ping_sockaddr_in(a) # define Fplay_ping_sockfd(a) rplay_ping_sockfd(a) # define Fplay_close(a) rplay_close(a) # define Fplay_sound(a,b) rplay_sound(a,b) # define Fplay_default(a) rplay_default(a) # define Fplay_convert(a) rplay_convert(a) # define Fplay_pack(a) rplay_pack(a) # define Fplay_unpack(a) rplay_unpack(a) # define Frptp_open(a,b,c,d) rptp_open(a,b,c,d) # define Frptp_read(a,b,c) rptp_read(a,b,c) # define Frptp_write(a,b,c) rptp_write(a,b,c) # define Frptp_close(a) rptp_close(a) # define Frptp_perror(a) rptp_perror(a) # define Frptp_getline(a,b,c) rptp_getline(a,b,c) # define Frptp_command(a,b,c,d) rptp_command(a,b,c,d) # define Frptp_parse(a,b) rptp_parse(a,b) # define Frptp_async_write(a,b,c,d) rptp_async_write(a,b,c,d) # define Frptp_async_register(a,b,c) rptp_async_register(a,b,c) # define Frptp_async_notify(a,b,c) rptp_async_notify(a,b,c) # define Frptp_async_process(a,b) rptp_async_process(a,b) # define Frptp_main_loop() rptp_main_loop() # define Frptp_stop_main_loop(a) rptp_stop_main_loop(a) #else typedef void FPLAY; typedef void FPLAY_ATTRS; # define FPLAY_DEFAULT_VALUE 0 # define FPLAY_DEFAULT_PRIORITY 0 # define FPLAY_NULL 0 # define FPLAY_PLAY 0 # define FPLAY_STOP 0 # define FPLAY_PAUSE 0 # define FPLAY_CONTINUE 0 # define FPLAY_SOUND 0 # define FPLAY_VOLUME 0 # define FPLAY_NSOUNDS 0 # define FPLAY_COMMAND 0 # define FPLAY_APPEND 0 # define FPLAY_INSERT 0 # define FPLAY_DELETE 0 # define FPLAY_CHANGE 0 # define FPLAY_COUNT 0 # define FPLAY_LIST_COUNT 0 # define FPLAY_PRIORITY 0 # define FPLAY_RANDOM_SOUND 0 # define FPLAY_PING 0 # define FPLAY_RPTP_SERVER 0 # define FPLAY_RPTP_SERVER_PORT 0 # define FPLAY_RPTP_SEARCH 0 # define FPLAY_RPTP_FROM_SENDER 0 # define FPLAY_SAMPLE_RATE 0 # define FPLAY_RESET 0 # define FPLAY_DONE 0 # define FPLAY_CLIENT_DATA 0 # define FPLAY_LIST_NAME 0 # define FPLAY_PUT 0 # define FPLAY_ID 0 # define FPLAY_SEQUENCE 0 # define FPLAY_DATA 0 # define FPLAY_DATA_SIZE 0 # define FPLAY_FORMAT_NONE 0 # define FPLAY_FORMAT_LINEAR_8 0 # define FPLAY_FORMAT_ULINEAR_8 0 # define FPLAY_FORMAT_LINEAR_16 0 # define FPLAY_FORMAT_ULINEAR_16 0 # define FPLAY_FORMAT_ULAW 0 # define FPLAY_FORMAT_G721 0 # define FPLAY_FORMAT_G723_3 0 # define FPLAY_FORMAT_G723_5 0 # define FPLAY_FORMAT_GSM 0 # define FPLAY_BIG_ENDIAN 0 # define FPLAY_LITTLE_ENDIAN 0 # define FPLAY_AUDIO_PORT_NONE 0 # define FPLAY_AUDIO_PORT_SPEAKER 0 # define FPLAY_AUDIO_PORT_HEADPHONE 0 # define FPLAY_AUDIO_PORT_LINEOUT 0 # define FPLAY_MIN_VOLUME 0 # define FPLAY_MAX_VOLUME 0 # define FPLAY_MIN_PRIORITY 0 # define FPLAY_MAX_PRIORITY 0 # define FPLAY_DEFAULT_VOLUME 0 # define FPLAY_DEFAULT_PRIORITY 0 # define FPLAY_DEFAULT_COUNT 0 # define FPLAY_DEFAULT_LIST_COUNT 0 # define FPLAY_DEFAULT_RANDOM_SOUND 0 # define FPLAY_DEFAULT_SAMPLE_RATE 0 # define FPLAY_DEFAULT_OFFSET 0 # define FPLAY_DEFAULT_BYTE_ORDER 0 # define FPLAY_DEFAULT_CHANNELS 0 # define FPLAY_DEFAULT_BITS 0 # define FPLAY_ERROR_NONE 0 # define FPLAY_ERROR_MEMORY 0 # define FPLAY_ERROR_HOST 0 # define FPLAY_ERROR_CONNECT 0 # define FPLAY_ERROR_SOCKET 0 # define FPLAY_ERROR_WRITE 0 # define FPLAY_ERROR_CLOSE 0 # define FPLAY_ERROR_PACKET_SIZE 0 # define FPLAY_ERROR_BROADCAST 0 # define FPLAY_ERROR_ATTRIBUTE 0 # define FPLAY_ERROR_COMMAND 0 # define FPLAY_ERROR_INDEX 0 # define FPLAY_ERROR_MODIFIER 0 # define FRPTP_ERROR_NONE 0 # define FRPTP_ERROR_MEMORY 0 # define FRPTP_ERROR_HOST 0 # define FRPTP_ERROR_CONNECT 0 # define FRPTP_ERROR_SOCKET 0 # define FRPTP_ERROR_OPEN 0 # define FRPTP_ERROR_READ 0 # define FRPTP_ERROR_WRITE 0 # define FRPTP_ERROR_PING 0 # define FRPTP_ERROR_TIMEOUT 0 # define FRPTP_ERROR_PROTOCOL 0 # define FRPTP_ERROR 0 # define FRPTP_OK 0 # define FRPTP_TIMEOUT 0 # define FRPTP_NOTIFY 0 # define FOLD_RPLAY_PLAY 0 # define FOLD_RPLAY_STOP 0 # define FOLD_RPLAY_PAUSE 0 # define FOLD_RPLAY_CONTINUE 0 # define FRPTP_ASYNC_READ 0 # define FRPTP_ASYNC_WRITE 0 # define FRPTP_ASYNC_RAW 0 # define FRPTP_ASYNC_ENABLE 0 # define FRPTP_ASYNC_DISABLE 0 # define FRPTP_EVENT_OK 0 # define FRPTP_EVENT_ERROR 0 # define FRPTP_EVENT_TIMEOUT 0 # define FRPTP_EVENT_OTHER 0 # define FRPTP_EVENT_CONTINUE 0 # define FRPTP_EVENT_DONE 0 # define FRPTP_EVENT_PAUSE 0 # define FRPTP_EVENT_PLAY 0 # define FRPTP_EVENT_SKIP 0 # define FRPTP_EVENT_STATE 0 # define FRPTP_EVENT_STOP 0 # define FRPTP_EVENT_VOLUME 0 # define FRPTP_EVENT_CLOSE 0 # define FRPTP_EVENT_FLOW 0 # define FRPTP_EVENT_MODIFY 0 # define FRPTP_EVENT_LEVEL 0 # define FRPTP_EVENT_POSITION 0 # define FRPTP_EVENT_ALL 0 # define FRPTP_MAX_ARGS 0 # define FRPTP_MAX_LINE 0 # define FPLAY_PORT 0 # define FRPTP_PORT 0 # define FOLD_RPLAY_PORT 0 # define FOLD_RPTP_PORT 0 # define FPLAY_PACKET_ID 0 # define Fplay_errno 0 # define Frptp_errno 0 # define Fplay(a,b) 0 # define Fplay_create(a) 0 # define Fplay_perror(a) /* variadict macros appeared in C99, so we can't use them. */ static void Fplay_set(FPLAY *a, ...) {} /* TA: 20100403: These aren't being used anymore. */ /* static int Fplay_get(FPLAY *a, ...) {return 0;} static int Frptp_putline(int a, ...) {return 0;} */ # define Frptp_async_putline Frptp_putline /* # define Fplay_set(...) # define Fplay_get(...) 0 # define Frptp_putline(...) 0 # define Frptp_async_putline(...) 0 */ # define Fplay_destroy(a) # define Fplay_default_host() "" # define Fplay_display(a) 0 # define Fplay_host(a,b) 0 # define Fplay_host_volume(a,b,c) 0 # define Fplay_local(a) 0 # define Fplay_open(a) -1 # define Fplay_open_default() -1 # define Fplay_open_display() -1 # define Fplay_open_port(a,b) -1 # define Fplay_open_sockaddr_in(a) -1 # define Fplay_close(a) 0 # define Fplay_ping(a) 0 # define Fplay_ping_sockaddr_in(a) 0 # define Fplay_ping_sockfd(a) 0 # define Fplay_sound(a,b) 0 # define Fplay_default(a) 0 # define Fplay_convert(a) NULL # define Fplay_pack(a) 0 # define Fplay_unpack(a) 0 # define Frptp_open(a,b,c,d) -1 # define Frptp_read(a,b,c) 0 # define Frptp_write(a,b,c) 0 # define Frptp_close(a) 0 # define Frptp_perror(a) # define Frptp_getline(a,b,c) 0 # define Frptp_command(a,b,c,d) 0 # define Frptp_parse(a,b) NULL # define Frptp_async_write(a,b,c,d) 0 # define Frptp_async_register(a,b,c) # define Frptp_async_notify(a,b,c) # define Frptp_async_process(a,b) # define Frptp_main_loop() 0 # define Frptp_stop_main_loop(a) #endif #endif fvwm-2.6.7/libs/XError.c0000644000175700017570000001452213001406607011763 00000000000000/* -*-c-*- */ /* 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 */ /* * This function should be used by all modules and fvwm when a X error * occurs and the module exits. */ #include "config.h" #include #include #include #include "FRenderInit.h" #include "XError.h" #undef XSetErrorHandler #define USE_GET_ERROR_TEXT 1 #ifndef USE_GET_ERROR_TEXT static char *error_name(unsigned char code); #endif static char *request_name(unsigned char code); static char unknown[32]; void do_coredump(void) { fprintf(stderr, " Leaving a core dump now\n"); { char *nullp; nullp = NULL; *nullp = 99; } /* exit if this fails */ exit(99); } #define USE_GET_ERROR_TEXT 1 void PrintXErrorAndCoredump(Display *dpy, XErrorEvent *error, char *MyName) { char msg[256]; Bool suc = False; msg[255] = 0; #ifdef USE_GET_ERROR_TEXT /* can't call this from within an error handler! */ /* DV (21-Nov-2000): Well, actually we *can* call it in an error * handler since it does not trigger a protocol request. */ if (error->error_code >= FirstExtensionError) { suc = FRenderGetErrorText(error->error_code, msg); } if (!suc) XGetErrorText(dpy, error->error_code, msg, sizeof(msg)); fprintf(stderr,"%s: Cause of next X Error.\n", MyName); fprintf(stderr, " Error: %d (%s)\n", error->error_code, msg); #else fprintf(stderr,"%s: Cause of next X Error.\n", MyName); if (error->error_code >= FirstExtensionError) { suc = FRenderGetErrorText(error->error_code, msg); } if (suc) fprintf(stderr, " Error: %d (%s)\n", error->error_code, msg); else fprintf(stderr, " Error: %d (%s)\n", error->error_code, error_name(error->error_code)); #endif fprintf(stderr, " Major opcode of failed request: %d (%s)\n", error->request_code, request_name(error->request_code)); fprintf(stderr, " Minor opcode of failed request: %d \n", error->minor_code); /* error->resourceid may be uninitialised. This is no proble since we * are dumping core anyway. */ fprintf(stderr, " Resource id of failed request: 0x%lx \n", error->resourceid); /* leave a coredump */ do_coredump(); } #ifndef USE_GET_ERROR_TEXT /* this comes out of X.h */ static char *error_names[] = { "BadRequest", "BadValue", "BadWindow", "BadPixmap", "BadAtom", "BadCursor", "BadFont", "BadMatch", "BadDrawable", "BadAccess", "BadAlloc", "BadColor", "BadGC", "BadIDChoice", "BadName", "BadLength", "BadImplementation", }; static char *error_name(unsigned char code) { if (code == 0 || code > (sizeof(error_names) / sizeof(char *))) { sprintf(unknown, "Unknown: %d", (int)code); return unknown; } return error_names[code - 1]; } #endif /* this comes out of Xproto.h */ static char *code_names[] = { "CreateWindow", "ChangeWindowAttributes", "GetWindowAttributes", "DestroyWindow", "DestroySubwindows", "ChangeSaveSet", "ReparentWindow", "MapWindow", "MapSubwindows", "UnmapWindow", "UnmapSubwindows", "ConfigureWindow", "CirculateWindow", "GetGeometry", "QueryTree", "InternAtom", "GetAtomName", "ChangeProperty", "DeleteProperty", "GetProperty", "ListProperties", "SetSelectionOwner", "GetSelectionOwner", "ConvertSelection", "SendEvent", "GrabPointer", "UngrabPointer", "GrabButton", "UngrabButton", "ChangeActivePointerGrab", "GrabKeyboard", "UngrabKeyboard", "GrabKey", "UngrabKey", "AllowEvents", "GrabServer", "UngrabServer", "QueryPointer", "GetMotionEvents", "TranslateCoords", "WarpPointer", "SetInputFocus", "GetInputFocus", "QueryKeymap", "OpenFont", "CloseFont", "QueryFont", "QueryTextExtents", "ListFonts", "ListFontsWithInfo", "SetFontPath", "GetFontPath", "CreatePixmap", "FreePixmap", "CreateGC", "ChangeGC", "CopyGC", "SetDashes", "SetClipRectangles", "FreeGC", "ClearArea", "CopyArea", "CopyPlane", "PolyPoint", "PolyLine", "PolySegment", "PolyRectangle", "PolyArc", "FillPoly", "PolyFillRectangle", "PolyFillArc", "PutImage", "GetImage", "PolyText", "PolyText1", "ImageText", "ImageText1", "CreateColormap", "FreeColormap", "CopyColormapAndFree", "InstallColormap", "UninstallColormap", "ListInstalledColormaps", "AllocColor", "AllocNamedColor", "AllocColorCells", "AllocColorPlanes", "FreeColors", "StoreColors", "StoreNamedColor", "QueryColors", "LookupColor", "CreateCursor", "CreateGlyphCursor", "FreeCursor", "RecolorCursor", "QueryBestSize", "QueryExtension", "ListExtensions", "ChangeKeyboardMapping", "GetKeyboardMapping", "ChangeKeyboardControl", "GetKeyboardControl", "Bell", "ChangePointerControl", "GetPointerControl", "SetScreenSaver", "GetScreenSaver", "ChangeHosts", "ListHosts", "SetAccessControl", "SetCloseDownMode", "KillClient", "RotateProperties", "ForceScreenSaver", "SetPointerMapping", "GetPointerMapping", "SetModifierMapping", "GetModifierMapping", }; static char *request_name(unsigned char code) { if (code == 0 || code > (sizeof(code_names) / sizeof(char *))) { if (code == FRenderGetMajorOpCode()) { sprintf(unknown, "XRender"); } else { sprintf(unknown, "Unknown: %d", (int)code); } return unknown; } return code_names[code - 1]; } /* -------------------------- error handler stack -------------------------- */ static ferror_handler_t old_handler = NULL; void ferror_set_temp_error_handler(ferror_handler_t new_handler) { if (old_handler != NULL) { do_coredump(); } old_handler = XSetErrorHandler(old_handler); return; } void ferror_reset_temp_error_handler(void) { if (old_handler == NULL) { do_coredump(); } XSetErrorHandler(old_handler); old_handler = NULL; return; } int ferror_call_next_error_handler(Display *dpy, XErrorEvent *error) { int rc; if (old_handler == NULL) { do_coredump(); } rc = old_handler(dpy, error); return rc; } fvwm-2.6.7/libs/PictureDitherMatrice.h0000644000175700017570000017553512773467232014663 00000000000000/* -*-c-*- */ #ifndef Picture_Dither_Matrice_H #define Picture_Dither_Matrice_H /* This dither table was generated by Raph Levien using patented * technology (US Patent 5,276,535). The dither table itself is in the * public domain. */ #define DM_WIDTH 128 #define DM_WIDTH_SHIFT 7 #define DM_HEIGHT 128 #define DITHER_MATRICE \ { \ { 0, 41, 23, 5, 17, 39, 7, 15, 62, 23, 40, 51, 31, 47, 9, 32, 52, 27, 57, 25, 6, 61, 27, 52, 37, 7, 40, 63, 18, 36, 10, 42, 25, 62, 45, 34, 20, 42, 37, 14, 35, 29, 50, 10, 61, 2, 40, 8, 37, 12, 58, 22, 5, 41, 10, 39, 0, 60, 11, 46, 2, 55, 38, 17, 36, 59, 13, 54, 37, 56, 8, 29, 16, 13, 63, 22, 41, 55, 7, 20, 49, 14, 23, 55, 37, 23, 19, 36, 15, 49, 23, 63, 30, 14, 38, 27, 53, 13, 22, 41, 19, 31, 7, 19, 50, 30, 49, 16, 3, 32, 56, 40, 29, 34, 8, 48, 19, 45, 4, 51, 12, 46, 35, 49, 16, 42, 12, 62 },\ { 30, 57, 36, 54, 47, 34, 52, 27, 43, 4, 28, 7, 17, 36, 62, 13, 44, 7, 18, 48, 33, 21, 44, 14, 30, 47, 12, 33, 5, 55, 31, 58, 13, 30, 4, 17, 52, 10, 60, 26, 46, 0, 39, 27, 42, 22, 47, 25, 60, 32, 9, 38, 48, 17, 59, 30, 49, 18, 34, 25, 51, 19, 5, 48, 21, 8, 28, 46, 1, 32, 41, 19, 54, 47, 37, 18, 28, 11, 44, 30, 39, 56, 2, 33, 8, 42, 61, 28, 58, 8, 46, 9, 41, 4, 58, 7, 21, 48, 59, 10, 52, 14, 42, 57, 12, 25, 7, 53, 42, 24, 11, 50, 17, 59, 42, 2, 36, 60, 32, 17, 63, 29, 21, 7, 59, 32, 24, 39 },\ { 22, 8, 16, 32, 3, 25, 13, 57, 18, 45, 58, 39, 55, 20, 5, 42, 23, 34, 63, 1, 51, 10, 58, 4, 60, 23, 53, 27, 44, 21, 3, 48, 8, 50, 43, 54, 27, 32, 5, 55, 21, 58, 12, 53, 6, 36, 14, 50, 17, 29, 53, 15, 24, 52, 7, 36, 13, 42, 4, 53, 9, 35, 61, 26, 56, 32, 49, 15, 62, 23, 6, 60, 2, 31, 4, 48, 58, 38, 15, 61, 5, 25, 47, 28, 50, 15, 7, 40, 3, 32, 33, 52, 25, 50, 35, 42, 61, 3, 28, 36, 23, 63, 4, 33, 46, 62, 36, 23, 60, 6, 54, 28, 4, 37, 23, 55, 25, 8, 42, 54, 14, 6, 56, 38, 19, 52, 4, 46 },\ { 48, 53, 43, 12, 45, 63, 30, 37, 9, 34, 21, 1, 25, 47, 29, 58, 3, 54, 15, 39, 29, 17, 38, 35, 20, 43, 1, 49, 15, 59, 29, 39, 22, 35, 16, 23, 1, 47, 39, 18, 8, 44, 25, 31, 57, 19, 63, 4, 45, 3, 42, 61, 1, 31, 45, 20, 57, 29, 62, 21, 32, 41, 14, 44, 3, 39, 5, 34, 10, 43, 51, 35, 23, 52, 40, 10, 21, 1, 53, 18, 51, 43, 12, 62, 18, 54, 26, 51, 20, 57, 14, 1, 62, 16, 11, 18, 32, 39, 17, 44, 1, 48, 26, 37, 18, 2, 51, 14, 28, 45, 35, 18, 57, 13, 47, 11, 51, 20, 2, 39, 31, 47, 25, 1, 50, 11, 60, 7 },\ { 18, 28, 1, 56, 21, 10, 51, 2, 46, 54, 14, 61, 11, 50, 13, 38, 19, 31, 45, 9, 55, 24, 47, 5, 54, 9, 62, 11, 35, 8, 51, 14, 57, 6, 63, 40, 58, 14, 51, 28, 62, 34, 15, 48, 1, 41, 30, 35, 55, 21, 34, 11, 49, 37, 8, 52, 4, 23, 15, 43, 1, 58, 11, 23, 53, 16, 55, 26, 58, 18, 27, 12, 45, 14, 25, 63, 42, 33, 27, 35, 9, 31, 21, 38, 1, 44, 34, 12, 48, 38, 21, 44, 29, 47, 26, 53, 1, 46, 54, 8, 59, 29, 11, 55, 22, 41, 33, 20, 39, 1, 48, 9, 44, 32, 5, 62, 29, 44, 57, 23, 10, 58, 34, 43, 15, 37, 26, 33 }, \ { 51, 38, 59, 24, 35, 42, 19, 60, 5, 32, 41, 26, 43, 33, 7, 53, 48, 11, 59, 23, 42, 2, 61, 30, 16, 40, 32, 24, 56, 41, 19, 33, 37, 26, 47, 9, 31, 22, 2, 45, 9, 54, 4, 37, 21, 52, 11, 23, 7, 57, 16, 25, 55, 18, 63, 27, 46, 39, 56, 10, 50, 37, 29, 47, 19, 63, 24, 9, 46, 2, 39, 60, 9, 57, 30, 7, 49, 11, 59, 3, 45, 57, 5, 60, 29, 22, 5, 60, 30, 9, 59, 18, 40, 6, 57, 36, 30, 12, 24, 34, 15, 40, 52, 6, 49, 9, 58, 4, 63, 12, 26, 61, 22, 53, 38, 16, 35, 14, 28, 50, 42, 17, 5, 28, 62, 20, 54, 12 }, \ { 26, 6, 31, 15, 49, 6, 38, 27, 22, 49, 16, 56, 2, 62, 30, 21, 0, 36, 28, 6, 49, 32, 13, 52, 26, 50, 19, 46, 3, 26, 62, 0, 53, 12, 29, 3, 53, 41, 60, 24, 38, 13, 58, 16, 43, 9, 59, 39, 46, 28, 44, 40, 2, 33, 13, 41, 16, 6, 47, 31, 26, 17, 57, 6, 38, 0, 42, 36, 29, 52, 20, 31, 48, 0, 34, 56, 20, 36, 23, 54, 14, 41, 24, 37, 10, 55, 46, 25, 16, 45, 36, 4, 55, 23, 15, 8, 50, 62, 5, 56, 44, 20, 13, 28, 59, 31, 24, 47, 31, 52, 37, 17, 40, 0, 26, 49, 3, 60, 7, 33, 0, 61, 53, 40, 8, 45, 2, 41 }, \ { 16, 63, 43, 4, 61, 24, 56, 13, 53, 8, 36, 12, 24, 41, 16, 46, 60, 26, 52, 39, 14, 57, 21, 37, 0, 45, 7, 59, 38, 17, 43, 10, 45, 20, 61, 43, 19, 11, 33, 17, 50, 32, 23, 61, 28, 49, 26, 0, 18, 51, 5, 60, 22, 58, 29, 0, 59, 34, 19, 62, 3, 52, 7, 44, 30, 59, 13, 50, 15, 62, 7, 17, 38, 22, 44, 15, 40, 4, 47, 28, 33, 17, 49, 16, 51, 40, 10, 56, 0, 53, 13, 49, 28, 38, 60, 21, 43, 19, 37, 27, 3, 51, 34, 39, 0, 45, 15, 43, 10, 21, 3, 55, 8, 33, 59, 10, 41, 18, 52, 24, 46, 20, 30, 13, 58, 22, 36, 57 }, \ { 50, 34, 11, 47, 29, 17, 44, 0, 33, 63, 28, 46, 52, 5, 57, 10, 42, 18, 4, 63, 20, 8, 44, 10, 56, 34, 14, 29, 5, 54, 23, 59, 32, 49, 7, 34, 49, 27, 56, 0, 42, 7, 46, 3, 40, 6, 54, 32, 62, 13, 36, 10, 47, 8, 35, 49, 24, 51, 12, 40, 22, 35, 60, 12, 22, 51, 33, 4, 40, 25, 43, 55, 5, 54, 12, 61, 26, 51, 8, 62, 0, 53, 7, 63, 2, 32, 19, 34, 42, 24, 31, 63, 2, 10, 45, 33, 0, 48, 9, 61, 22, 47, 8, 62, 18, 56, 7, 54, 27, 57, 46, 30, 50, 19, 45, 30, 56, 36, 22, 47, 11, 38, 3, 51, 32, 48, 18, 9 }, \ { 0, 21, 40, 19, 52, 9, 37, 48, 20, 40, 3, 18, 27, 38, 35, 22, 31, 56, 13, 35, 46, 28, 60, 40, 27, 18, 61, 50, 41, 30, 7, 36, 2, 25, 16, 57, 5, 15, 47, 29, 55, 19, 30, 52, 15, 34, 20, 12, 43, 30, 20, 54, 25, 44, 53, 12, 38, 5, 55, 27, 48, 15, 33, 27, 45, 8, 19, 28, 56, 11, 33, 49, 18, 36, 29, 2, 45, 16, 39, 19, 31, 43, 27, 35, 20, 52, 26, 6, 61, 11, 41, 17, 29, 51, 20, 56, 25, 32, 41, 17, 53, 31, 25, 14, 42, 23, 35, 16, 38, 6, 34, 12, 15, 62, 6, 21, 13, 1, 63, 9, 55, 27, 43, 25, 14, 4, 31, 55 }, \ { 44, 29, 61, 2, 35, 58, 26, 15, 60, 10, 51, 59, 14, 55, 8, 50, 2, 44, 25, 51, 1, 33, 16, 4, 48, 36, 2, 21, 12, 57, 48, 13, 51, 55, 40, 28, 37, 62, 8, 39, 12, 63, 36, 10, 59, 24, 56, 47, 9, 50, 41, 1, 32, 17, 6, 21, 61, 30, 9, 43, 1, 54, 41, 2, 54, 37, 48, 61, 1, 46, 21, 3, 58, 24, 50, 32, 60, 10, 57, 25, 46, 12, 59, 4, 45, 13, 57, 47, 27, 39, 5, 58, 47, 14, 35, 4, 52, 13, 60, 6, 36, 10, 45, 55, 4, 50, 29, 2, 61, 50, 25, 58, 44, 24, 36, 42, 54, 28, 40, 32, 16, 56, 6, 62, 46, 39, 60, 23 }, \ { 7, 48, 14, 54, 23, 40, 4, 45, 30, 22, 42, 32, 1, 44, 20, 29, 58, 8, 37, 19, 41, 54, 24, 58, 9, 53, 25, 46, 34, 16, 23, 38, 27, 11, 18, 1, 52, 21, 35, 22, 48, 5, 25, 45, 18, 38, 2, 27, 35, 4, 57, 15, 62, 39, 57, 28, 42, 16, 36, 60, 24, 18, 10, 63, 20, 5, 16, 23, 37, 14, 59, 27, 41, 8, 13, 42, 21, 35, 6, 50, 3, 38, 15, 48, 30, 39, 17, 3, 49, 14, 53, 33, 24, 7, 61, 44, 11, 39, 23, 49, 19, 58, 1, 32, 36, 12, 60, 41, 20, 13, 41, 4, 39, 1, 48, 8, 18, 51, 14, 44, 5, 37, 21, 34, 1, 26, 10, 37 }, \ { 53, 36, 27, 9, 50, 12, 32, 55, 2, 57, 7, 17, 48, 34, 63, 15, 40, 26, 62, 11, 49, 6, 31, 39, 22, 42, 6, 63, 1, 39, 60, 4, 42, 61, 32, 45, 24, 44, 2, 60, 16, 41, 53, 1, 33, 61, 49, 17, 63, 23, 45, 26, 33, 3, 23, 46, 2, 50, 20, 4, 45, 34, 49, 30, 39, 58, 44, 31, 53, 34, 6, 52, 30, 47, 63, 1, 53, 22, 42, 31, 58, 23, 54, 22, 61, 8, 36, 59, 22, 35, 21, 1, 55, 40, 27, 16, 30, 54, 2, 29, 43, 16, 39, 63, 21, 46, 26, 10, 48, 32, 19, 53, 30, 56, 26, 60, 33, 4, 61, 23, 49, 59, 15, 53, 19, 58, 42, 16 }, \ { 20, 5, 59, 46, 25, 62, 7, 19, 43, 25, 37, 61, 11, 24, 4, 54, 12, 52, 3, 32, 17, 61, 12, 47, 15, 55, 18, 31, 53, 28, 9, 50, 21, 6, 55, 9, 58, 14, 54, 26, 33, 7, 31, 58, 13, 21, 8, 42, 29, 6, 37, 11, 48, 52, 14, 60, 11, 39, 56, 32, 14, 58, 7, 26, 17, 4, 42, 8, 11, 47, 19, 38, 10, 17, 26, 37, 9, 55, 28, 13, 18, 40, 6, 33, 1, 43, 25, 11, 51, 7, 62, 43, 18, 37, 3, 57, 45, 9, 38, 58, 5, 52, 27, 7, 17, 53, 5, 57, 37, 2, 63, 9, 22, 15, 11, 38, 25, 45, 35, 0, 28, 10, 41, 30, 50, 8, 31, 57 }, \ { 49, 33, 16, 38, 1, 42, 51, 34, 53, 14, 28, 49, 30, 56, 36, 23, 43, 20, 38, 56, 22, 45, 28, 0, 62, 35, 26, 44, 11, 19, 52, 35, 44, 15, 30, 38, 10, 31, 40, 4, 46, 50, 20, 40, 27, 44, 51, 14, 56, 53, 19, 59, 7, 29, 41, 19, 35, 25, 8, 52, 22, 44, 13, 53, 50, 32, 61, 24, 56, 25, 63, 0, 45, 57, 33, 59, 16, 46, 4, 62, 50, 11, 60, 37, 52, 19, 55, 29, 37, 46, 13, 26, 48, 10, 50, 34, 21, 63, 26, 13, 42, 33, 22, 55, 35, 28, 43, 15, 24, 51, 27, 34, 46, 49, 58, 3, 52, 9, 57, 19, 48, 55, 3, 35, 12, 45, 24, 3 }, \ { 41, 11, 56, 28, 18, 31, 22, 10, 37, 6, 47, 13, 3, 41, 9, 46, 0, 48, 29, 6, 34, 10, 55, 37, 20, 8, 49, 3, 41, 59, 14, 25, 0, 63, 19, 47, 27, 51, 17, 57, 23, 10, 61, 6, 54, 3, 38, 31, 0, 22, 34, 43, 20, 55, 31, 0, 49, 63, 29, 38, 3, 62, 28, 40, 0, 22, 14, 35, 2, 48, 15, 43, 23, 14, 3, 29, 49, 20, 39, 34, 0, 44, 29, 9, 15, 47, 5, 42, 0, 31, 58, 5, 31, 61, 23, 15, 0, 47, 19, 50, 24, 3, 59, 11, 44, 0, 31, 59, 6, 42, 17, 60, 0, 39, 20, 31, 43, 17, 29, 40, 12, 25, 60, 22, 52, 15, 63, 29 }, \ { 20, 52, 8, 44, 62, 4, 59, 49, 17, 63, 21, 39, 60, 18, 52, 27, 33, 59, 14, 51, 59, 43, 24, 5, 51, 30, 57, 17, 32, 5, 37, 56, 48, 34, 42, 3, 60, 5, 36, 13, 43, 37, 18, 34, 25, 12, 59, 24, 47, 36, 11, 50, 3, 38, 9, 58, 16, 5, 43, 18, 47, 10, 37, 18, 59, 46, 29, 52, 40, 12, 34, 28, 56, 36, 53, 7, 43, 8, 24, 52, 26, 17, 56, 43, 24, 32, 63, 20, 57, 16, 22, 52, 36, 8, 41, 56, 29, 32, 54, 7, 35, 57, 14, 48, 20, 62, 13, 39, 53, 29, 8, 45, 13, 29, 7, 61, 14, 54, 6, 63, 38, 32, 18, 43, 2, 39, 6, 47 }, \ { 0, 58, 23, 35, 13, 46, 12, 39, 0, 31, 55, 24, 5, 35, 15, 61, 17, 5, 39, 25, 18, 2, 50, 33, 41, 13, 39, 23, 62, 46, 29, 12, 22, 8, 56, 25, 20, 49, 32, 62, 0, 56, 11, 46, 63, 42, 9, 16, 55, 5, 60, 15, 62, 26, 45, 21, 36, 51, 13, 57, 31, 24, 55, 6, 35, 9, 57, 5, 20, 60, 7, 51, 5, 19, 40, 25, 61, 32, 56, 12, 36, 48, 21, 2, 58, 12, 39, 28, 9, 50, 40, 12, 44, 18, 25, 49, 6, 38, 11, 62, 18, 46, 30, 9, 40, 25, 49, 19, 10, 36, 55, 22, 33, 52, 41, 18, 37, 27, 49, 21, 2, 46, 7, 53, 33, 61, 27, 35 }, \ { 41, 31, 5, 39, 51, 26, 33, 57, 27, 41, 9, 44, 54, 29, 48, 7, 44, 36, 57, 10, 31, 63, 16, 45, 11, 60, 1, 47, 7, 20, 43, 3, 58, 36, 13, 52, 39, 7, 15, 28, 22, 48, 30, 21, 1, 29, 49, 44, 27, 17, 40, 30, 24, 42, 12, 53, 33, 7, 47, 20, 1, 42, 11, 49, 25, 43, 17, 32, 45, 27, 41, 21, 31, 62, 11, 49, 2, 15, 42, 5, 63, 7, 41, 27, 49, 6, 54, 23, 46, 34, 2, 28, 54, 3, 59, 12, 46, 17, 42, 28, 40, 1, 37, 51, 5, 55, 2, 34, 47, 16, 3, 62, 47, 5, 23, 56, 1, 44, 12, 34, 51, 16, 57, 11, 25, 17, 54, 13 }, \ { 60, 26, 55, 18, 3, 60, 20, 6, 52, 15, 50, 19, 32, 11, 23, 53, 26, 21, 1, 47, 42, 27, 8, 58, 21, 27, 53, 36, 26, 54, 31, 50, 17, 30, 45, 1, 29, 59, 44, 53, 41, 4, 35, 58, 51, 19, 32, 4, 52, 34, 48, 8, 51, 5, 56, 2, 25, 61, 27, 38, 54, 27, 62, 21, 51, 1, 39, 62, 10, 50, 1, 58, 13, 47, 38, 18, 35, 54, 22, 51, 30, 19, 59, 34, 14, 32, 44, 4, 60, 15, 52, 62, 20, 43, 30, 35, 21, 60, 4, 52, 12, 24, 61, 18, 30, 42, 23, 61, 25, 50, 27, 38, 11, 59, 12, 35, 50, 30, 59, 24, 8, 42, 28, 37, 48, 9, 44, 21 }, \ { 10, 47, 15, 50, 30, 43, 8, 45, 29, 2, 36, 59, 1, 58, 41, 3, 63, 31, 54, 20, 13, 55, 35, 38, 4, 44, 15, 9, 61, 2, 14, 38, 61, 10, 23, 54, 18, 12, 24, 2, 14, 55, 16, 8, 38, 14, 41, 60, 10, 23, 1, 58, 32, 17, 28, 37, 41, 15, 3, 60, 15, 33, 4, 36, 16, 59, 28, 14, 23, 55, 37, 18, 44, 28, 2, 57, 30, 10, 27, 46, 14, 38, 3, 53, 21, 61, 17, 35, 10, 41, 26, 7, 33, 9, 57, 1, 53, 37, 26, 20, 56, 48, 9, 33, 58, 16, 37, 7, 45, 1, 57, 15, 32, 26, 42, 23, 7, 20, 4, 54, 31, 62, 22, 1, 59, 30, 4, 51 }, \ { 36, 2, 38, 11, 24, 36, 54, 22, 62, 47, 25, 8, 28, 45, 16, 38, 12, 43, 9, 37, 49, 3, 23, 52, 18, 30, 50, 33, 19, 42, 49, 26, 6, 40, 47, 35, 63, 38, 50, 33, 60, 26, 36, 47, 24, 57, 6, 26, 39, 63, 19, 44, 14, 46, 61, 9, 50, 30, 45, 23, 10, 50, 44, 8, 31, 54, 6, 46, 36, 4, 30, 54, 8, 52, 22, 41, 4, 60, 40, 0, 58, 24, 45, 10, 37, 1, 48, 30, 56, 17, 38, 48, 24, 47, 19, 39, 14, 8, 45, 32, 2, 34, 27, 44, 4, 52, 11, 56, 31, 21, 40, 19, 44, 51, 2, 63, 46, 58, 36, 43, 14, 5, 50, 38, 14, 56, 40, 23 }, \ { 61, 46, 32, 63, 54, 1, 14, 34, 12, 40, 18, 49, 37, 10, 61, 30, 51, 24, 60, 7, 29, 40, 62, 11, 46, 58, 6, 56, 24, 10, 34, 52, 21, 59, 16, 3, 27, 5, 20, 46, 9, 40, 7, 62, 2, 30, 53, 15, 48, 10, 28, 35, 54, 6, 21, 34, 18, 55, 7, 40, 57, 19, 26, 60, 41, 13, 24, 51, 19, 61, 9, 25, 34, 15, 63, 11, 45, 17, 20, 47, 33, 8, 31, 62, 43, 26, 53, 7, 24, 59, 0, 13, 55, 4, 62, 27, 51, 31, 63, 15, 58, 7, 54, 14, 46, 22, 28, 43, 12, 63, 8, 54, 5, 17, 39, 33, 15, 10, 27, 17, 47, 34, 19, 45, 27, 12, 33, 17 }, \ { 5, 28, 21, 7, 17, 48, 42, 58, 23, 4, 63, 14, 55, 21, 34, 5, 19, 0, 45, 17, 52, 15, 25, 32, 0, 22, 40, 13, 45, 62, 18, 0, 43, 11, 33, 55, 30, 42, 57, 19, 51, 31, 22, 43, 18, 45, 34, 0, 43, 31, 56, 3, 23, 40, 59, 0, 44, 13, 48, 35, 2, 32, 46, 0, 21, 48, 35, 3, 40, 32, 43, 59, 0, 48, 33, 26, 53, 36, 55, 12, 51, 16, 55, 5, 18, 29, 11, 39, 51, 19, 45, 31, 42, 21, 35, 6, 22, 47, 10, 38, 23, 50, 20, 36, 0, 60, 38, 4, 50, 35, 48, 34, 24, 57, 9, 53, 28, 48, 61, 0, 56, 24, 53, 3, 63, 6, 42, 57 }, \ { 13, 53, 45, 40, 58, 27, 6, 16, 38, 51, 33, 30, 43, 2, 47, 56, 40, 50, 33, 57, 27, 5, 47, 42, 60, 36, 16, 54, 28, 4, 37, 57, 28, 51, 22, 8, 45, 14, 6, 39, 0, 54, 11, 59, 28, 12, 50, 21, 61, 13, 19, 38, 49, 11, 25, 37, 58, 29, 22, 63, 14, 56, 12, 53, 30, 63, 9, 57, 26, 12, 47, 16, 23, 39, 50, 6, 31, 2, 25, 6, 28, 41, 36, 22, 50, 57, 42, 3, 34, 8, 28, 61, 11, 50, 16, 54, 41, 0, 55, 43, 5, 29, 41, 63, 25, 16, 53, 18, 26, 10, 21, 0, 61, 30, 41, 22, 3, 38, 20, 39, 29, 8, 41, 16, 36, 52, 22, 19 }, \ { 55, 34, 0, 25, 10, 32, 56, 44, 28, 0, 57, 7, 26, 53, 23, 8, 13, 35, 22, 12, 36, 60, 20, 8, 14, 29, 48, 2, 41, 49, 23, 13, 39, 7, 48, 58, 25, 53, 34, 62, 28, 16, 48, 4, 37, 56, 27, 5, 36, 52, 46, 7, 62, 33, 52, 11, 17, 53, 5, 28, 41, 24, 38, 17, 5, 39, 20, 45, 15, 56, 5, 38, 60, 8, 14, 57, 21, 48, 62, 39, 59, 13, 1, 60, 9, 32, 16, 63, 44, 25, 52, 15, 36, 2, 60, 29, 12, 33, 25, 17, 59, 45, 13, 8, 49, 32, 6, 40, 59, 29, 45, 37, 13, 47, 6, 55, 30, 45, 9, 52, 13, 59, 25, 47, 32, 1, 49, 30 }, \ { 9, 39, 14, 61, 49, 37, 3, 20, 50, 13, 41, 19, 46, 17, 38, 59, 28, 62, 4, 44, 54, 1, 34, 51, 55, 7, 63, 32, 21, 8, 56, 31, 62, 19, 36, 1, 41, 17, 24, 12, 42, 35, 25, 52, 20, 8, 44, 59, 25, 2, 22, 42, 16, 29, 4, 46, 20, 36, 43, 9, 51, 8, 49, 26, 58, 33, 54, 1, 37, 29, 52, 20, 27, 45, 19, 35, 42, 16, 10, 32, 20, 49, 46, 27, 40, 4, 47, 22, 13, 55, 4, 47, 26, 44, 23, 40, 58, 19, 48, 13, 31, 2, 57, 34, 42, 19, 61, 32, 14, 55, 5, 51, 26, 19, 58, 16, 49, 14, 62, 5, 33, 44, 21, 7, 60, 26, 11, 41 }, \ { 62, 24, 47, 29, 8, 19, 53, 11, 60, 24, 32, 61, 4, 55, 31, 2, 49, 16, 39, 9, 31, 24, 43, 17, 26, 38, 11, 25, 58, 43, 12, 35, 3, 46, 15, 32, 63, 4, 49, 56, 2, 60, 10, 32, 63, 17, 39, 12, 55, 30, 57, 9, 48, 55, 39, 24, 60, 2, 58, 31, 19, 61, 34, 3, 42, 11, 22, 46, 7, 61, 10, 42, 3, 55, 32, 1, 58, 28, 44, 54, 4, 34, 23, 15, 56, 20, 37, 58, 6, 30, 38, 18, 63, 9, 32, 5, 51, 3, 62, 37, 52, 18, 39, 23, 3, 51, 9, 47, 1, 23, 43, 15, 60, 35, 11, 40, 1, 36, 31, 26, 57, 2, 37, 54, 18, 44, 58, 16 }, \ { 5, 51, 3, 33, 43, 62, 21, 42, 35, 9, 48, 15, 36, 10, 22, 42, 20, 46, 26, 56, 50, 12, 59, 3, 48, 19, 45, 53, 1, 27, 47, 17, 52, 24, 56, 11, 51, 21, 37, 30, 20, 46, 14, 41, 1, 47, 33, 7, 41, 17, 35, 27, 20, 1, 14, 54, 26, 33, 18, 47, 1, 44, 14, 59, 16, 52, 28, 18, 49, 31, 25, 34, 63, 13, 51, 24, 9, 50, 3, 23, 38, 63, 7, 52, 29, 46, 11, 33, 50, 22, 57, 36, 1, 57, 49, 17, 39, 28, 9, 35, 6, 27, 53, 15, 55, 30, 24, 58, 36, 41, 11, 52, 32, 3, 44, 25, 62, 23, 51, 15, 42, 22, 50, 10, 39, 4, 31, 35 }, \ { 46, 22, 57, 17, 12, 39, 26, 5, 31, 59, 1, 45, 27, 62, 52, 7, 58, 33, 6, 18, 39, 22, 33, 41, 57, 5, 35, 18, 40, 16, 60, 5, 29, 42, 7, 39, 27, 44, 9, 47, 8, 26, 54, 22, 51, 29, 24, 49, 15, 61, 4, 51, 31, 63, 43, 6, 50, 8, 39, 12, 53, 37, 23, 30, 40, 6, 62, 43, 14, 53, 2, 49, 7, 36, 17, 41, 61, 37, 18, 56, 11, 18, 44, 35, 2, 19, 61, 0, 41, 14, 8, 30, 43, 12, 24, 46, 14, 54, 42, 21, 44, 61, 10, 46, 37, 11, 44, 7, 18, 63, 20, 29, 7, 49, 28, 54, 8, 43, 4, 48, 18, 63, 12, 29, 48, 24, 59, 20 }, \ { 13, 36, 28, 54, 35, 2, 56, 46, 16, 49, 22, 40, 11, 34, 14, 43, 29, 12, 63, 48, 2, 61, 7, 15, 28, 30, 50, 9, 61, 33, 38, 23, 54, 13, 61, 33, 3, 59, 16, 35, 58, 40, 5, 38, 13, 57, 3, 58, 37, 21, 45, 12, 39, 7, 35, 30, 13, 56, 22, 62, 27, 6, 55, 10, 48, 21, 33, 2, 38, 23, 40, 20, 44, 29, 59, 4, 26, 12, 33, 47, 28, 53, 31, 13, 59, 41, 27, 49, 26, 54, 45, 16, 53, 21, 35, 7, 59, 26, 11, 56, 1, 24, 33, 4, 28, 62, 21, 49, 31, 2, 56, 39, 24, 58, 13, 17, 37, 21, 56, 10, 38, 0, 34, 55, 15, 43, 1, 52 }, \ { 42, 9, 50, 6, 25, 60, 14, 38, 10, 29, 53, 18, 57, 3, 25, 51, 0, 53, 25, 17, 29, 37, 52, 46, 0, 62, 14, 37, 4, 50, 10, 44, 0, 46, 20, 25, 50, 19, 55, 0, 23, 31, 62, 34, 11, 45, 19, 32, 0, 53, 10, 59, 23, 47, 18, 60, 42, 28, 37, 3, 50, 15, 35, 44, 0, 51, 27, 60, 9, 57, 16, 58, 11, 22, 46, 15, 53, 48, 7, 42, 0, 60, 5, 49, 24, 54, 9, 17, 39, 5, 34, 62, 3, 40, 60, 31, 0, 47, 29, 16, 49, 39, 59, 17, 50, 0, 40, 13, 53, 38, 16, 46, 0, 42, 34, 60, 2, 53, 29, 31, 58, 46, 27, 6, 61, 8, 37, 28 }, \ { 0, 63, 21, 40, 45, 18, 51, 23, 63, 34, 6, 43, 28, 38, 55, 19, 40, 35, 8, 41, 54, 10, 21, 32, 39, 23, 53, 26, 55, 28, 22, 63, 30, 34, 9, 48, 6, 38, 29, 43, 49, 6, 18, 52, 27, 61, 9, 43, 28, 42, 33, 26, 56, 3, 51, 23, 0, 48, 16, 45, 32, 25, 63, 20, 57, 17, 42, 12, 35, 47, 5, 31, 39, 56, 6, 30, 34, 21, 61, 25, 14, 40, 22, 38, 15, 6, 36, 56, 20, 60, 25, 12, 51, 27, 10, 56, 42, 20, 36, 63, 32, 6, 21, 41, 12, 34, 60, 26, 5, 48, 27, 10, 62, 19, 6, 47, 39, 14, 45, 7, 24, 17, 41, 32, 23, 51, 19, 56 }, \ { 45, 31, 15, 59, 4, 33, 7, 47, 0, 41, 13, 61, 4, 47, 9, 23, 60, 14, 57, 31, 4, 45, 59, 6, 58, 10, 44, 20, 8, 42, 15, 6, 55, 17, 58, 31, 53, 12, 61, 10, 15, 57, 43, 2, 23, 35, 48, 14, 54, 6, 18, 49, 15, 38, 11, 34, 62, 9, 21, 58, 11, 41, 4, 31, 38, 8, 29, 55, 19, 36, 27, 52, 0, 25, 50, 43, 1, 39, 8, 55, 35, 51, 10, 30, 45, 62, 29, 2, 46, 10, 32, 48, 18, 38, 5, 22, 33, 8, 51, 3, 14, 44, 54, 25, 57, 30, 18, 52, 33, 22, 59, 28, 36, 52, 32, 21, 26, 50, 5, 55, 35, 60, 14, 54, 4, 40, 16, 33 }, \ { 27, 3, 49, 10, 30, 40, 55, 27, 57, 24, 52, 21, 32, 17, 60, 30, 5, 44, 27, 49, 19, 34, 13, 24, 43, 36, 3, 49, 31, 59, 37, 48, 26, 41, 2, 41, 14, 36, 21, 32, 40, 26, 13, 49, 55, 5, 16, 40, 25, 60, 36, 1, 63, 29, 17, 44, 25, 40, 52, 5, 29, 47, 54, 13, 46, 24, 60, 4, 51, 22, 63, 14, 45, 18, 12, 62, 17, 57, 19, 42, 3, 26, 58, 48, 1, 21, 40, 52, 23, 37, 44, 1, 29, 58, 43, 50, 15, 61, 19, 45, 58, 28, 7, 48, 2, 46, 8, 42, 3, 55, 8, 50, 12, 4, 55, 10, 63, 33, 20, 40, 11, 3, 46, 20, 48, 26, 61, 11 }, \ { 44, 56, 24, 36, 53, 19, 12, 37, 16, 44, 7, 36, 49, 54, 11, 37, 48, 21, 15, 1, 62, 25, 47, 56, 16, 18, 51, 12, 40, 1, 24, 11, 52, 16, 23, 59, 28, 1, 45, 53, 4, 60, 37, 21, 39, 30, 63, 20, 52, 10, 30, 45, 8, 41, 54, 4, 57, 7, 34, 55, 36, 18, 23, 59, 2, 48, 11, 32, 44, 1, 41, 8, 33, 54, 38, 23, 30, 46, 6, 29, 62, 18, 32, 16, 55, 34, 14, 11, 61, 7, 55, 16, 53, 13, 23, 2, 55, 37, 26, 10, 33, 23, 36, 16, 38, 22, 56, 15, 24, 43, 35, 17, 44, 40, 25, 46, 16, 1, 57, 25, 49, 36, 28, 62, 9, 35, 7, 53 }, \ { 17, 38, 8, 61, 1, 50, 26, 62, 3, 31, 56, 15, 1, 26, 40, 2, 34, 51, 56, 36, 42, 9, 38, 2, 29, 60, 32, 57, 19, 62, 34, 47, 4, 57, 39, 7, 44, 63, 24, 18, 46, 28, 8, 54, 1, 34, 7, 46, 3, 37, 50, 23, 57, 21, 13, 46, 31, 20, 43, 15, 1, 61, 8, 33, 37, 17, 56, 26, 15, 49, 24, 59, 28, 3, 56, 9, 52, 32, 13, 49, 10, 43, 5, 45, 8, 25, 59, 42, 28, 33, 19, 40, 8, 63, 35, 47, 25, 4, 40, 52, 1, 60, 12, 53, 63, 9, 29, 60, 37, 19, 1, 62, 31, 20, 58, 12, 41, 30, 43, 9, 18, 52, 22, 1, 39, 30, 58, 21 }, \ { 13, 47, 29, 18, 43, 34, 5, 48, 20, 42, 10, 45, 30, 58, 20, 63, 24, 11, 6, 28, 54, 14, 22, 52, 41, 7, 26, 5, 45, 15, 53, 13, 35, 27, 18, 50, 12, 33, 5, 56, 10, 17, 45, 24, 59, 15, 50, 26, 56, 13, 19, 5, 32, 52, 27, 36, 2, 61, 12, 26, 49, 40, 27, 52, 13, 50, 6, 39, 61, 34, 10, 37, 48, 20, 41, 27, 2, 36, 59, 24, 54, 33, 63, 20, 38, 50, 3, 17, 52, 4, 58, 27, 45, 21, 32, 11, 48, 17, 57, 20, 46, 38, 25, 43, 4, 34, 51, 6, 13, 45, 57, 26, 6, 48, 2, 35, 53, 23, 61, 34, 59, 6, 42, 56, 13, 51, 2, 41 }, \ { 32, 5, 55, 23, 58, 14, 22, 52, 29, 15, 61, 25, 51, 8, 43, 13, 53, 41, 46, 20, 3, 33, 63, 11, 48, 21, 54, 38, 28, 3, 30, 43, 21, 62, 9, 31, 55, 22, 51, 29, 37, 62, 32, 12, 42, 29, 41, 9, 33, 44, 62, 28, 43, 1, 59, 19, 48, 30, 51, 39, 24, 4, 58, 19, 42, 29, 22, 43, 3, 18, 53, 5, 13, 50, 16, 60, 45, 21, 7, 40, 15, 0, 26, 53, 13, 31, 43, 24, 47, 31, 15, 49, 2, 41, 6, 59, 29, 42, 9, 30, 14, 7, 49, 18, 31, 47, 20, 39, 49, 32, 11, 41, 54, 15, 61, 18, 7, 38, 4, 13, 44, 28, 15, 32, 45, 19, 27, 49 }, \ { 63, 34, 11, 39, 2, 45, 37, 8, 59, 39, 33, 4, 36, 17, 48, 5, 29, 18, 32, 61, 39, 50, 5, 27, 35, 0, 46, 12, 22, 49, 60, 6, 54, 0, 38, 49, 2, 42, 15, 40, 0, 47, 20, 51, 3, 57, 18, 61, 22, 0, 39, 16, 55, 12, 35, 8, 41, 22, 6, 59, 16, 45, 10, 36, 0, 62, 9, 54, 30, 58, 21, 43, 63, 31, 7, 35, 12, 48, 58, 28, 47, 37, 41, 9, 57, 20, 61, 0, 36, 11, 57, 35, 23, 52, 37, 18, 0, 62, 22, 55, 35, 62, 27, 54, 0, 15, 61, 28, 2, 59, 22, 9, 37, 27, 33, 51, 29, 48, 19, 50, 25, 37, 10, 57, 5, 37, 60, 8 }, \ { 20, 25, 46, 52, 31, 60, 12, 55, 0, 19, 11, 46, 62, 35, 23, 38, 57, 0, 55, 10, 16, 30, 58, 44, 17, 59, 29, 63, 42, 8, 36, 20, 33, 46, 16, 61, 25, 35, 8, 54, 26, 7, 58, 22, 34, 6, 47, 14, 53, 31, 48, 9, 37, 25, 49, 63, 16, 55, 45, 14, 34, 63, 21, 53, 25, 33, 46, 16, 35, 7, 46, 29, 0, 39, 25, 55, 22, 34, 18, 4, 56, 11, 23, 51, 28, 6, 39, 14, 62, 44, 19, 8, 60, 12, 56, 28, 50, 34, 39, 5, 51, 3, 41, 12, 57, 35, 10, 53, 25, 17, 52, 30, 47, 0, 43, 14, 5, 57, 31, 55, 0, 63, 47, 23, 54, 24, 14, 43 }, \ { 0, 57, 16, 6, 26, 19, 35, 28, 49, 42, 54, 26, 21, 1, 59, 27, 9, 47, 26, 44, 50, 22, 13, 40, 8, 37, 10, 34, 17, 56, 25, 58, 13, 27, 44, 9, 20, 58, 31, 17, 60, 36, 10, 41, 53, 25, 36, 39, 4, 24, 58, 17, 60, 4, 22, 38, 10, 32, 0, 50, 31, 7, 28, 47, 12, 57, 5, 26, 52, 23, 14, 40, 57, 17, 47, 5, 53, 1, 44, 31, 19, 60, 46, 2, 35, 48, 30, 54, 22, 5, 51, 39, 25, 31, 4, 43, 14, 9, 45, 16, 24, 44, 19, 29, 40, 23, 44, 7, 38, 42, 4, 63, 12, 54, 23, 59, 22, 42, 8, 15, 40, 21, 8, 34, 3, 41, 30, 50 }, \ { 39, 10, 48, 33, 41, 54, 5, 47, 23, 13, 32, 7, 52, 44, 14, 39, 58, 18, 35, 6, 37, 2, 60, 24, 55, 19, 53, 2, 51, 32, 1, 41, 51, 4, 40, 29, 47, 3, 52, 44, 13, 49, 28, 16, 1, 62, 11, 27, 52, 35, 5, 42, 29, 47, 14, 56, 28, 53, 26, 38, 9, 56, 40, 3, 38, 15, 41, 60, 1, 37, 50, 25, 11, 28, 61, 19, 42, 62, 10, 52, 39, 6, 32, 14, 58, 17, 7, 26, 42, 34, 27, 10, 54, 40, 20, 63, 26, 53, 21, 61, 32, 7, 59, 48, 3, 56, 18, 31, 58, 14, 49, 21, 36, 16, 45, 9, 36, 24, 62, 45, 27, 31, 53, 17, 49, 12, 62, 18 }, \ { 28, 59, 21, 58, 2, 16, 38, 9, 62, 3, 56, 41, 10, 31, 50, 4, 32, 52, 12, 63, 23, 46, 33, 31, 4, 48, 25, 43, 14, 23, 47, 11, 22, 55, 14, 60, 23, 37, 11, 39, 23, 2, 45, 56, 31, 43, 19, 55, 16, 46, 21, 51, 11, 33, 44, 2, 41, 18, 5, 52, 23, 44, 17, 60, 27, 49, 11, 32, 44, 10, 54, 2, 56, 33, 8, 38, 13, 29, 36, 16, 24, 63, 27, 51, 21, 43, 56, 12, 49, 3, 59, 48, 1, 15, 46, 7, 36, 2, 47, 11, 50, 27, 37, 13, 33, 8, 51, 46, 1, 34, 28, 40, 3, 33, 60, 29, 47, 1, 35, 11, 59, 42, 2, 60, 26, 46, 6, 35 }, \ { 4, 43, 9, 29, 36, 63, 24, 44, 20, 50, 30, 17, 60, 22, 16, 43, 25, 3, 42, 19, 51, 15, 8, 54, 42, 15, 61, 5, 39, 57, 18, 61, 31, 48, 34, 2, 50, 19, 57, 5, 63, 33, 19, 38, 13, 27, 48, 7, 32, 61, 2, 26, 58, 6, 24, 50, 13, 61, 42, 20, 62, 2, 35, 20, 51, 4, 62, 18, 23, 58, 20, 31, 43, 15, 51, 45, 26, 50, 4, 55, 45, 3, 35, 9, 38, 1, 32, 61, 20, 45, 17, 33, 24, 57, 29, 51, 22, 58, 38, 30, 15, 1, 54, 21, 63, 43, 26, 12, 24, 56, 8, 60, 50, 19, 5, 52, 13, 54, 17, 50, 4, 16, 36, 12, 32, 56, 22, 54 }, \ { 51, 25, 40, 53, 12, 49, 15, 57, 34, 7, 38, 47, 2, 36, 55, 8, 61, 30, 56, 7, 28, 59, 48, 11, 27, 35, 21, 45, 28, 36, 9, 38, 6, 16, 24, 63, 10, 32, 28, 43, 21, 53, 5, 60, 8, 57, 3, 45, 11, 37, 15, 54, 40, 20, 62, 36, 27, 34, 11, 48, 30, 15, 54, 8, 30, 42, 22, 34, 48, 13, 35, 63, 4, 37, 22, 2, 59, 9, 41, 23, 13, 41, 49, 18, 59, 24, 40, 5, 37, 30, 9, 61, 44, 6, 37, 11, 33, 17, 5, 55, 41, 60, 23, 39, 17, 5, 30, 62, 41, 16, 46, 25, 11, 56, 39, 26, 20, 38, 29, 39, 22, 52, 44, 20, 48, 1, 38, 14 }, \ { 15, 33, 2, 18, 44, 6, 27, 0, 32, 61, 25, 12, 58, 28, 40, 20, 47, 13, 34, 43, 38, 1, 23, 62, 40, 0, 51, 10, 63, 3, 52, 26, 44, 30, 45, 6, 41, 54, 0, 51, 12, 30, 46, 24, 49, 22, 40, 33, 63, 23, 43, 30, 9, 47, 0, 17, 54, 7, 57, 3, 37, 47, 24, 46, 13, 55, 7, 52, 2, 42, 6, 26, 49, 18, 60, 34, 16, 57, 33, 20, 61, 30, 8, 54, 14, 46, 12, 53, 16, 55, 38, 13, 22, 53, 18, 59, 46, 27, 43, 19, 32, 10, 45, 6, 49, 36, 52, 2, 20, 55, 6, 39, 32, 15, 44, 3, 58, 10, 63, 6, 56, 30, 7, 58, 9, 40, 19, 63 }, \ { 10, 47, 61, 23, 55, 31, 52, 42, 17, 45, 4, 51, 27, 6, 15, 53, 0, 49, 26, 10, 56, 18, 36, 6, 20, 58, 32, 30, 13, 49, 19, 56, 0, 59, 12, 53, 27, 17, 38, 25, 48, 9, 15, 36, 14, 30, 59, 17, 0, 50, 8, 58, 18, 56, 31, 45, 21, 41, 29, 19, 60, 6, 32, 59, 0, 36, 29, 39, 19, 59, 46, 12, 55, 30, 10, 47, 24, 3, 28, 48, 0, 55, 44, 27, 33, 4, 63, 29, 49, 0, 26, 50, 34, 2, 42, 14, 0, 62, 9, 56, 3, 52, 28, 34, 58, 9, 20, 48, 37, 32, 22, 53, 0, 62, 27, 49, 34, 46, 21, 33, 41, 14, 25, 37, 53, 29, 31, 45 }, \ { 56, 28, 7, 37, 11, 36, 20, 9, 54, 14, 39, 19, 34, 63, 45, 37, 24, 17, 60, 31, 21, 45, 53, 29, 47, 15, 7, 55, 40, 23, 34, 14, 42, 20, 37, 35, 15, 59, 7, 62, 34, 40, 59, 1, 51, 42, 10, 28, 54, 21, 35, 5, 38, 13, 36, 4, 59, 12, 39, 53, 15, 43, 9, 21, 39, 62, 16, 56, 25, 9, 32, 38, 0, 41, 14, 51, 40, 53, 43, 11, 37, 17, 5, 22, 57, 39, 19, 7, 42, 21, 60, 10, 31, 63, 25, 52, 30, 49, 36, 25, 48, 17, 61, 14, 22, 42, 29, 13, 60, 11, 47, 18, 35, 41, 7, 23, 4, 16, 51, 11, 0, 48, 61, 3, 17, 50, 5, 24 }, \ { 0, 42, 21, 49, 60, 3, 57, 40, 29, 48, 23, 56, 42, 11, 22, 5, 59, 39, 4, 50, 3, 41, 12, 57, 25, 50, 44, 18, 4, 46, 7, 62, 33, 50, 4, 56, 21, 32, 43, 18, 3, 23, 55, 34, 20, 4, 53, 38, 12, 46, 29, 52, 25, 61, 23, 51, 26, 46, 1, 34, 25, 57, 28, 51, 26, 11, 50, 3, 44, 28, 53, 21, 57, 27, 62, 6, 31, 19, 8, 63, 26, 59, 36, 47, 15, 29, 50, 25, 35, 47, 18, 41, 4, 48, 8, 40, 12, 23, 6, 44, 13, 40, 1, 31, 55, 0, 61, 43, 4, 50, 26, 58, 9, 53, 24, 61, 42, 55, 31, 43, 57, 20, 34, 27, 43, 8, 59, 39 }, \ { 18, 51, 30, 13, 26, 16, 46, 22, 2, 59, 8, 30, 1, 48, 33, 51, 29, 9, 46, 16, 62, 14, 33, 2, 38, 9, 27, 60, 37, 26, 53, 17, 28, 10, 24, 46, 2, 49, 8, 57, 29, 45, 6, 26, 62, 44, 18, 25, 61, 3, 42, 14, 49, 10, 43, 6, 17, 32, 63, 10, 49, 4, 40, 14, 45, 33, 22, 37, 12, 61, 5, 17, 43, 7, 23, 37, 15, 58, 49, 13, 39, 21, 10, 52, 1, 62, 9, 56, 12, 2, 58, 28, 36, 16, 56, 28, 56, 35, 20, 63, 24, 37, 51, 8, 45, 25, 16, 33, 27, 38, 2, 44, 13, 30, 17, 36, 12, 26, 5, 18, 28, 47, 13, 60, 23, 45, 13, 33 }, \ { 55, 4, 62, 34, 52, 38, 7, 63, 32, 37, 13, 53, 25, 62, 18, 12, 55, 41, 27, 35, 24, 49, 31, 52, 17, 63, 34, 1, 56, 12, 41, 2, 48, 58, 39, 16, 61, 27, 41, 52, 13, 19, 50, 39, 11, 31, 57, 6, 32, 40, 20, 55, 1, 28, 33, 57, 48, 8, 37, 22, 44, 18, 53, 1, 61, 5, 54, 16, 47, 36, 50, 24, 55, 34, 48, 45, 1, 30, 33, 46, 2, 50, 32, 42, 25, 34, 43, 21, 38, 52, 23, 45, 14, 54, 21, 4, 44, 16, 53, 29, 10, 47, 19, 57, 12, 54, 39, 10, 51, 15, 63, 21, 57, 40, 51, 1, 48, 57, 37, 62, 2, 38, 9, 52, 1, 35, 58, 22 }, \ { 36, 46, 10, 42, 1, 27, 43, 15, 50, 21, 45, 16, 41, 3, 35, 44, 20, 1, 57, 11, 55, 7, 43, 8, 22, 42, 13, 46, 21, 39, 31, 60, 22, 5, 29, 44, 11, 35, 20, 4, 36, 58, 32, 15, 47, 2, 36, 48, 16, 60, 8, 35, 44, 63, 16, 2, 40, 26, 55, 14, 58, 35, 24, 31, 19, 42, 31, 58, 1, 29, 10, 40, 2, 19, 12, 54, 22, 61, 7, 24, 56, 5, 28, 16, 54, 3, 15, 58, 6, 30, 8, 62, 1, 43, 31, 47, 7, 59, 1, 38, 58, 4, 34, 27, 38, 5, 31, 59, 7, 46, 30, 3, 34, 6, 28, 59, 20, 8, 32, 15, 53, 24, 55, 31, 19, 49, 11, 26 }, \ { 2, 24, 16, 58, 19, 55, 5, 35, 10, 61, 4, 28, 57, 24, 58, 7, 31, 47, 22, 38, 19, 28, 61, 36, 54, 5, 59, 29, 6, 52, 15, 11, 43, 36, 8, 54, 52, 1, 62, 25, 47, 9, 1, 60, 28, 53, 24, 14, 46, 27, 51, 22, 12, 24, 38, 53, 20, 11, 51, 3, 29, 7, 48, 63, 8, 49, 9, 21, 52, 14, 63, 32, 46, 60, 35, 4, 41, 16, 52, 35, 18, 42, 59, 7, 36, 61, 45, 27, 33, 51, 19, 39, 34, 11, 61, 18, 33, 41, 28, 15, 54, 22, 42, 3, 49, 21, 47, 18, 36, 23, 55, 19, 48, 24, 45, 10, 33, 44, 50, 40, 7, 35, 15, 41, 63, 6, 40, 54 }, \ { 62, 41, 32, 8, 47, 28, 60, 24, 44, 30, 38, 49, 9, 33, 14, 40, 50, 14, 60, 2, 54, 40, 0, 20, 25, 39, 16, 49, 24, 35, 57, 47, 19, 61, 33, 18, 23, 37, 13, 55, 31, 43, 22, 41, 17, 8, 42, 58, 0, 37, 5, 56, 31, 54, 7, 30, 60, 33, 42, 17, 59, 39, 12, 27, 38, 17, 35, 41, 27, 45, 20, 7, 25, 15, 29, 58, 27, 47, 11, 40, 14, 54, 23, 46, 19, 31, 11, 40, 13, 49, 5, 58, 24, 51, 26, 6, 50, 20, 49, 9, 32, 46, 17, 60, 14, 63, 24, 1, 57, 41, 9, 43, 14, 62, 16, 52, 3, 27, 14, 22, 61, 45, 4, 28, 9, 47, 29, 17 }, \ { 5, 50, 12, 53, 38, 18, 11, 51, 0, 55, 17, 6, 47, 54, 19, 63, 5, 26, 34, 45, 13, 30, 47, 58, 10, 48, 32, 3, 62, 9, 26, 0, 25, 14, 50, 3, 47, 30, 42, 16, 6, 63, 12, 49, 33, 55, 21, 10, 34, 63, 18, 41, 3, 47, 19, 43, 0, 49, 8, 28, 46, 20, 52, 0, 56, 24, 60, 3, 59, 5, 39, 57, 48, 52, 9, 38, 3, 21, 26, 60, 0, 32, 12, 38, 4, 48, 53, 0, 60, 15, 29, 44, 18, 10, 38, 57, 13, 60, 2, 26, 62, 7, 50, 29, 35, 8, 40, 53, 28, 12, 60, 33, 38, 5, 37, 29, 60, 39, 56, 0, 30, 18, 50, 34, 59, 25, 14, 44 }, \ { 20, 31, 60, 22, 3, 49, 33, 25, 40, 13, 34, 59, 22, 36, 0, 28, 37, 56, 8, 18, 51, 16, 4, 45, 27, 12, 53, 42, 18, 44, 51, 31, 55, 40, 28, 58, 7, 60, 10, 51, 27, 37, 24, 56, 5, 26, 44, 29, 50, 23, 45, 11, 34, 15, 59, 27, 13, 23, 62, 37, 4, 57, 15, 32, 42, 6, 47, 11, 30, 43, 23, 13, 0, 36, 18, 44, 63, 51, 37, 29, 49, 20, 57, 27, 62, 9, 24, 35, 23, 53, 37, 3, 42, 55, 0, 36, 23, 39, 31, 43, 17, 37, 24, 11, 52, 43, 19, 32, 5, 50, 26, 0, 56, 21, 54, 11, 19, 6, 47, 25, 59, 42, 12, 54, 21, 3, 38, 57 }, \ { 48, 0, 35, 27, 44, 14, 59, 7, 57, 46, 26, 2, 42, 12, 52, 43, 10, 27, 53, 42, 32, 62, 37, 21, 34, 61, 7, 23, 36, 4, 38, 12, 41, 5, 17, 45, 22, 27, 39, 21, 59, 0, 45, 18, 39, 62, 3, 38, 14, 7, 54, 26, 61, 39, 9, 52, 45, 36, 18, 50, 10, 34, 44, 22, 50, 14, 36, 55, 17, 34, 53, 62, 33, 26, 56, 6, 31, 12, 6, 53, 9, 44, 2, 50, 20, 40, 55, 17, 47, 7, 26, 63, 22, 32, 48, 16, 46, 8, 52, 12, 57, 41, 0, 56, 25, 3, 61, 14, 45, 35, 18, 44, 12, 46, 23, 42, 32, 51, 35, 10, 17, 36, 23, 1, 45, 52, 32, 10 }, \ { 37, 15, 43, 8, 63, 39, 21, 31, 16, 37, 19, 62, 30, 46, 17, 60, 21, 48, 1, 23, 6, 25, 11, 56, 1, 40, 30, 58, 15, 54, 21, 59, 9, 63, 35, 56, 11, 51, 2, 46, 34, 14, 53, 7, 30, 11, 51, 19, 60, 40, 30, 1, 24, 50, 20, 32, 3, 56, 5, 25, 31, 13, 61, 2, 29, 60, 25, 20, 51, 2, 27, 8, 18, 42, 10, 45, 21, 34, 43, 17, 62, 29, 41, 14, 34, 6, 30, 43, 2, 57, 33, 13, 45, 12, 27, 62, 4, 55, 21, 35, 5, 27, 45, 33, 16, 47, 30, 54, 22, 10, 51, 27, 63, 7, 49, 1, 58, 22, 15, 43, 53, 7, 57, 39, 27, 12, 61, 24 }, \ { 56, 51, 26, 56, 19, 2, 41, 54, 5, 52, 9, 48, 6, 23, 39, 4, 32, 15, 63, 35, 59, 49, 43, 15, 52, 19, 50, 9, 46, 33, 1, 29, 48, 20, 32, 1, 38, 33, 19, 54, 9, 32, 24, 48, 58, 35, 16, 48, 4, 52, 13, 57, 33, 5, 45, 59, 15, 29, 41, 55, 47, 39, 23, 53, 9, 40, 4, 57, 10, 44, 48, 40, 50, 14, 61, 24, 55, 1, 59, 22, 33, 8, 51, 25, 58, 46, 11, 59, 20, 41, 17, 51, 6, 56, 35, 25, 42, 30, 15, 58, 48, 18, 61, 9, 58, 39, 13, 2, 37, 59, 40, 2, 31, 16, 34, 41, 8, 30, 62, 3, 29, 48, 33, 5, 63, 16, 41, 7 }, \ { 22, 4, 46, 11, 33, 51, 29, 10, 62, 24, 43, 27, 15, 58, 50, 25, 54, 44, 9, 38, 18, 3, 29, 57, 32, 5, 26, 43, 17, 61, 24, 52, 8, 42, 23, 53, 15, 61, 7, 28, 57, 43, 4, 40, 20, 2, 43, 25, 32, 35, 21, 43, 17, 48, 10, 22, 38, 54, 11, 21, 1, 58, 16, 30, 48, 18, 46, 32, 38, 13, 22, 4, 59, 35, 2, 51, 30, 39, 15, 47, 4, 56, 13, 37, 1, 28, 16, 52, 32, 9, 61, 29, 38, 19, 3, 52, 10, 48, 1, 32, 11, 40, 20, 36, 6, 22, 49, 29, 55, 6, 20, 56, 36, 52, 19, 60, 26, 46, 18, 54, 40, 13, 20, 46, 35, 19, 49, 29 }, \ { 61, 17, 34, 53, 23, 6, 48, 35, 20, 40, 1, 56, 36, 29, 11, 34, 7, 41, 14, 30, 55, 20, 46, 8, 24, 38, 63, 2, 37, 10, 45, 14, 34, 49, 6, 13, 44, 25, 49, 41, 21, 12, 61, 15, 54, 29, 63, 12, 56, 8, 49, 2, 62, 36, 28, 61, 0, 25, 41, 63, 35, 8, 44, 6, 37, 62, 7, 21, 63, 28, 55, 31, 16, 24, 41, 19, 9, 57, 27, 36, 18, 42, 31, 62, 22, 55, 38, 4, 27, 47, 1, 40, 14, 54, 43, 20, 60, 23, 38, 63, 25, 51, 2, 53, 26, 63, 10, 42, 17, 34, 47, 25, 13, 5, 44, 11, 55, 2, 38, 27, 6, 60, 52, 25, 9, 55, 1, 40 }, \ { 8, 30, 58, 3, 42, 61, 17, 38, 13, 59, 32, 10, 54, 3, 51, 20, 61, 26, 57, 2, 46, 33, 12, 60, 41, 13, 48, 29, 55, 20, 39, 27, 57, 18, 62, 29, 55, 2, 31, 16, 37, 50, 26, 36, 6, 46, 9, 41, 27, 57, 23, 39, 26, 6, 51, 12, 31, 46, 7, 16, 27, 52, 19, 56, 26, 12, 33, 53, 1, 41, 8, 57, 46, 7, 54, 32, 47, 5, 49, 11, 60, 23, 5, 48, 10, 43, 19, 63, 35, 24, 49, 21, 59, 5, 31, 37, 14, 44, 7, 42, 6, 30, 46, 13, 44, 32, 19, 50, 4, 58, 8, 30, 62, 38, 28, 53, 21, 36, 13, 50, 21, 33, 15, 2, 44, 31, 14, 47 }, \ { 37, 13, 39, 16, 28, 9, 57, 0, 25, 49, 21, 45, 18, 47, 12, 42, 0, 49, 22, 39, 16, 53, 25, 36, 0, 52, 22, 16, 6, 60, 4, 51, 0, 26, 37, 47, 10, 36, 63, 5, 57, 0, 18, 59, 23, 33, 51, 19, 0, 44, 15, 11, 54, 17, 42, 35, 53, 18, 58, 33, 49, 4, 34, 42, 0, 50, 43, 25, 16, 49, 34, 20, 37, 28, 12, 63, 16, 38, 25, 44, 0, 40, 52, 17, 35, 3, 50, 14, 8, 53, 11, 36, 25, 45, 9, 62, 0, 54, 28, 17, 50, 55, 15, 24, 57, 0, 53, 34, 23, 41, 15, 45, 0, 49, 16, 4, 48, 9, 63, 45, 0, 42, 58, 37, 61, 22, 54, 26 }, \ { 0, 50, 21, 47, 54, 36, 27, 45, 52, 4, 34, 15, 63, 29, 37, 59, 17, 31, 6, 61, 28, 5, 48, 18, 59, 27, 34, 56, 44, 31, 35, 12, 41, 59, 16, 3, 40, 20, 50, 22, 30, 40, 52, 10, 45, 3, 59, 22, 37, 61, 29, 46, 31, 58, 2, 22, 9, 43, 3, 39, 14, 61, 24, 54, 15, 29, 11, 60, 39, 17, 5, 61, 0, 44, 50, 3, 31, 14, 58, 21, 54, 28, 15, 45, 60, 26, 33, 58, 44, 22, 60, 2, 57, 34, 49, 27, 18, 34, 21, 59, 29, 4, 36, 41, 8, 39, 28, 11, 62, 26, 53, 20, 35, 24, 59, 32, 29, 39, 24, 31, 57, 23, 11, 28, 5, 36, 11, 59 }, \ { 44, 32, 63, 5, 20, 12, 41, 7, 30, 61, 42, 8, 39, 5, 33, 8, 24, 53, 45, 11, 37, 58, 7, 44, 10, 50, 3, 40, 8, 22, 53, 19, 46, 9, 33, 52, 24, 58, 8, 44, 13, 47, 8, 34, 38, 30, 14, 47, 7, 34, 4, 55, 9, 19, 40, 49, 56, 26, 60, 21, 30, 45, 10, 19, 40, 58, 23, 36, 3, 52, 45, 23, 54, 13, 22, 42, 53, 45, 7, 33, 10, 36, 57, 6, 29, 12, 41, 0, 30, 15, 41, 30, 17, 7, 16, 53, 40, 56, 2, 39, 12, 61, 10, 52, 31, 60, 16, 45, 1, 37, 7, 61, 40, 10, 43, 17, 58, 7, 54, 14, 4, 51, 39, 49, 18, 56, 42, 20 }, \ { 14, 6, 24, 36, 56, 49, 22, 60, 18, 14, 23, 51, 26, 57, 21, 52, 41, 14, 35, 50, 19, 31, 40, 23, 33, 14, 63, 17, 32, 47, 7, 62, 23, 30, 56, 11, 42, 27, 14, 60, 35, 19, 28, 61, 17, 55, 25, 39, 53, 17, 42, 21, 38, 63, 25, 5, 14, 36, 12, 50, 1, 37, 59, 32, 2, 51, 6, 56, 27, 32, 11, 30, 38, 26, 60, 8, 26, 19, 62, 39, 50, 2, 21, 39, 53, 23, 56, 19, 49, 39, 5, 46, 55, 23, 42, 4, 31, 11, 47, 26, 45, 22, 48, 18, 21, 5, 48, 25, 57, 14, 47, 30, 3, 56, 12, 50, 1, 42, 19, 47, 35, 17, 8, 30, 45, 25, 4, 51 }, \ { 28, 58, 43, 1, 31, 8, 33, 2, 44, 55, 32, 1, 60, 12, 46, 27, 4, 62, 23, 1, 56, 13, 62, 2, 54, 36, 25, 51, 1, 57, 26, 42, 3, 49, 17, 38, 1, 48, 31, 4, 54, 3, 50, 24, 1, 49, 5, 63, 13, 27, 52, 1, 48, 13, 45, 33, 52, 30, 46, 20, 55, 28, 6, 48, 24, 38, 20, 47, 14, 62, 48, 9, 58, 4, 36, 30, 56, 1, 34, 12, 18, 63, 25, 48, 4, 16, 37, 7, 62, 10, 52, 28, 13, 50, 36, 63, 24, 51, 15, 58, 8, 33, 1, 38, 56, 35, 42, 9, 33, 51, 22, 18, 48, 32, 27, 37, 23, 61, 33, 11, 59, 29, 62, 1, 53, 10, 60, 33 }, \ { 12, 39, 17, 52, 26, 46, 53, 38, 25, 11, 48, 36, 16, 43, 2, 35, 55, 17, 39, 29, 43, 9, 28, 45, 20, 5, 46, 12, 42, 28, 13, 52, 36, 6, 60, 22, 54, 17, 62, 39, 25, 42, 15, 55, 44, 20, 31, 10, 35, 57, 24, 32, 29, 6, 59, 18, 7, 62, 3, 41, 10, 44, 16, 54, 13, 62, 31, 9, 41, 1, 21, 43, 18, 47, 15, 40, 11, 49, 28, 55, 46, 30, 8, 43, 32, 61, 28, 47, 25, 34, 21, 61, 32, 1, 20, 9, 46, 6, 35, 19, 41, 54, 27, 63, 14, 3, 51, 20, 62, 2, 38, 55, 8, 21, 63, 6, 46, 9, 26, 51, 3, 24, 43, 34, 16, 41, 18, 48 }, \ { 62, 23, 55, 9, 15, 62, 19, 13, 58, 40, 6, 30, 54, 19, 50, 31, 10, 44, 6, 59, 21, 47, 51, 15, 60, 39, 30, 54, 21, 61, 19, 33, 14, 29, 43, 11, 34, 45, 7, 21, 10, 56, 36, 6, 38, 11, 58, 42, 2, 47, 11, 60, 50, 16, 41, 28, 38, 23, 47, 17, 35, 63, 22, 33, 42, 5, 45, 17, 53, 35, 25, 56, 33, 6, 51, 19, 60, 23, 43, 15, 5, 40, 58, 13, 51, 1, 45, 11, 54, 3, 43, 8, 37, 48, 59, 29, 39, 21, 61, 43, 3, 31, 10, 44, 24, 29, 60, 12, 28, 40, 11, 25, 43, 52, 14, 41, 16, 57, 44, 20, 40, 55, 12, 21, 57, 27, 35, 2 }, \ { 37, 6, 31, 42, 40, 4, 29, 50, 0, 20, 63, 28, 9, 58, 14, 24, 63, 26, 48, 16, 34, 4, 32, 38, 23, 11, 58, 4, 37, 9, 45, 5, 63, 48, 26, 57, 2, 28, 32, 51, 46, 29, 13, 62, 27, 46, 28, 18, 50, 15, 40, 4, 19, 34, 54, 0, 53, 9, 26, 58, 28, 5, 49, 0, 57, 27, 19, 60, 29, 8, 59, 12, 37, 63, 24, 46, 3, 37, 6, 52, 26, 32, 20, 36, 9, 22, 59, 18, 35, 51, 14, 57, 17, 24, 12, 44, 56, 0, 30, 13, 59, 20, 49, 17, 54, 43, 6, 34, 46, 17, 58, 36, 0, 34, 29, 54, 25, 2, 36, 15, 60, 6, 37, 46, 4, 50, 9, 45 }, \ { 19, 59, 48, 3, 24, 60, 44, 22, 34, 51, 15, 45, 41, 5, 33, 47, 0, 37, 12, 55, 25, 54, 8, 57, 0, 47, 18, 34, 49, 15, 55, 24, 40, 20, 8, 35, 53, 13, 41, 18, 0, 59, 22, 33, 4, 52, 8, 60, 24, 36, 31, 56, 45, 26, 10, 43, 15, 56, 36, 4, 51, 14, 39, 30, 12, 55, 36, 2, 39, 49, 4, 44, 17, 0, 32, 13, 53, 35, 59, 17, 62, 0, 55, 24, 52, 38, 31, 6, 42, 19, 29, 40, 4, 54, 33, 5, 16, 27, 52, 37, 23, 55, 7, 37, 0, 39, 23, 49, 4, 53, 31, 15, 59, 10, 50, 4, 60, 34, 48, 7, 31, 49, 27, 14, 62, 22, 53, 29 }, \ { 46, 21, 14, 51, 36, 17, 7, 57, 10, 32, 3, 37, 22, 60, 39, 18, 56, 20, 42, 3, 36, 10, 44, 26, 41, 29, 53, 27, 2, 39, 30, 52, 0, 59, 15, 48, 23, 61, 6, 58, 37, 12, 40, 49, 16, 39, 20, 44, 0, 62, 8, 21, 3, 59, 23, 32, 49, 31, 12, 44, 22, 59, 18, 50, 24, 7, 43, 52, 15, 23, 41, 26, 51, 28, 55, 39, 21, 27, 10, 42, 12, 45, 27, 47, 3, 15, 63, 26, 55, 0, 60, 26, 45, 18, 62, 38, 58, 49, 8, 47, 4, 33, 46, 29, 57, 13, 56, 16, 59, 21, 5, 47, 23, 39, 18, 44, 13, 22, 28, 53, 19, 0, 58, 32, 41, 7, 26, 13 }, \ { 0, 56, 34, 28, 11, 55, 31, 47, 26, 41, 56, 13, 53, 28, 11, 49, 7, 52, 32, 61, 50, 22, 63, 17, 13, 56, 7, 19, 43, 62, 10, 21, 37, 32, 43, 4, 38, 19, 44, 25, 31, 54, 5, 23, 61, 30, 53, 12, 35, 22, 43, 53, 37, 48, 7, 62, 20, 2, 61, 41, 8, 34, 47, 9, 63, 34, 28, 10, 55, 33, 14, 57, 7, 47, 9, 61, 4, 49, 31, 50, 21, 38, 8, 16, 57, 44, 33, 5, 49, 36, 12, 50, 7, 34, 10, 25, 2, 22, 36, 15, 26, 61, 18, 9, 22, 46, 32, 8, 27, 37, 44, 30, 55, 3, 62, 24, 38, 56, 5, 45, 38, 24, 43, 10, 19, 54, 39, 61 }, \ { 41, 30, 8, 63, 43, 23, 38, 3, 62, 19, 8, 49, 25, 1, 58, 30, 23, 40, 9, 28, 18, 40, 6, 38, 49, 22, 35, 59, 8, 27, 50, 5, 56, 17, 11, 50, 30, 9, 55, 2, 51, 19, 34, 47, 9, 41, 6, 26, 48, 57, 14, 28, 17, 12, 39, 13, 37, 46, 25, 19, 54, 27, 1, 37, 16, 45, 20, 60, 1, 48, 20, 38, 31, 22, 42, 15, 19, 44, 1, 61, 6, 34, 56, 40, 29, 10, 20, 46, 13, 22, 41, 23, 59, 42, 30, 51, 45, 13, 63, 53, 42, 12, 51, 38, 62, 2, 26, 41, 50, 1, 61, 10, 19, 42, 31, 8, 49, 32, 12, 63, 9, 52, 16, 56, 36, 2, 31, 16 }, \ { 52, 5, 47, 20, 1, 53, 12, 50, 16, 35, 43, 21, 33, 43, 16, 44, 3, 59, 14, 46, 1, 30, 60, 33, 2, 45, 12, 42, 31, 47, 14, 33, 46, 25, 55, 27, 60, 36, 16, 42, 14, 46, 26, 1, 55, 15, 63, 32, 2, 38, 5, 47, 33, 61, 30, 52, 4, 57, 6, 38, 11, 43, 61, 24, 52, 3, 31, 22, 42, 10, 62, 3, 59, 11, 35, 57, 33, 54, 24, 14, 29, 48, 18, 2, 60, 41, 53, 24, 32, 62, 3, 53, 15, 1, 55, 17, 32, 40, 6, 31, 1, 40, 28, 5, 35, 52, 19, 63, 13, 33, 17, 41, 52, 26, 15, 57, 1, 20, 42, 17, 35, 27, 48, 5, 25, 50, 44, 11 }, \ { 35, 25, 38, 57, 33, 17, 40, 6, 59, 27, 54, 5, 61, 10, 52, 26, 36, 19, 51, 35, 57, 48, 11, 20, 54, 25, 61, 16, 1, 58, 24, 61, 3, 39, 7, 47, 1, 22, 49, 28, 63, 10, 58, 32, 17, 36, 45, 19, 51, 29, 59, 10, 50, 1, 23, 42, 18, 29, 51, 21, 56, 32, 14, 5, 40, 58, 47, 13, 54, 35, 29, 45, 18, 52, 26, 2, 38, 8, 46, 36, 58, 11, 52, 35, 17, 28, 1, 58, 9, 39, 17, 28, 37, 48, 20, 9, 57, 24, 50, 19, 58, 16, 48, 25, 43, 11, 35, 6, 45, 24, 56, 4, 36, 7, 47, 35, 52, 28, 59, 30, 2, 61, 21, 33, 63, 12, 18, 59 }, \ { 3, 49, 15, 10, 27, 61, 25, 45, 30, 0, 14, 47, 31, 38, 17, 62, 7, 55, 27, 4, 15, 24, 42, 52, 10, 34, 5, 51, 36, 18, 41, 11, 35, 21, 62, 13, 33, 57, 8, 35, 5, 40, 21, 43, 52, 3, 24, 56, 11, 16, 33, 25, 41, 20, 55, 8, 60, 35, 15, 48, 2, 57, 30, 49, 18, 25, 6, 39, 17, 57, 7, 25, 43, 5, 49, 16, 62, 22, 55, 4, 25, 43, 23, 7, 50, 11, 37, 48, 14, 51, 33, 57, 7, 27, 39, 46, 4, 29, 11, 43, 34, 56, 7, 60, 20, 54, 30, 57, 22, 49, 9, 33, 54, 14, 63, 23, 6, 43, 10, 40, 50, 13, 44, 8, 38, 33, 46, 23 }, \ { 55, 39, 22, 50, 44, 4, 36, 9, 52, 23, 37, 59, 21, 2, 46, 13, 31, 41, 11, 45, 62, 29, 6, 37, 19, 48, 30, 23, 44, 7, 53, 28, 54, 16, 41, 29, 44, 18, 52, 24, 60, 15, 48, 7, 27, 59, 9, 34, 42, 54, 7, 63, 4, 46, 31, 27, 45, 0, 40, 26, 34, 17, 37, 10, 53, 29, 36, 50, 2, 27, 51, 11, 61, 37, 23, 41, 30, 7, 18, 50, 39, 14, 63, 32, 45, 61, 19, 30, 25, 44, 2, 47, 23, 63, 11, 34, 59, 37, 60, 3, 22, 14, 44, 30, 15, 0, 47, 15, 3, 38, 61, 20, 27, 45, 11, 39, 51, 16, 55, 3, 22, 54, 29, 58, 1, 57, 6, 29 }, \ { 9, 17, 60, 2, 34, 56, 20, 62, 39, 12, 49, 6, 29, 56, 34, 48, 0, 58, 22, 38, 18, 43, 56, 0, 63, 14, 55, 3, 59, 31, 15, 45, 0, 49, 6, 58, 3, 38, 12, 45, 0, 37, 29, 57, 13, 39, 30, 49, 0, 23, 44, 36, 16, 57, 13, 54, 11, 24, 63, 9, 53, 7, 62, 42, 0, 59, 15, 23, 63, 34, 40, 16, 32, 0, 53, 12, 48, 28, 59, 33, 0, 53, 9, 27, 3, 22, 54, 5, 56, 9, 61, 13, 42, 14, 52, 19, 0, 21, 47, 27, 53, 36, 3, 50, 39, 58, 25, 40, 53, 28, 12, 50, 0, 59, 32, 2, 21, 34, 26, 46, 37, 7, 18, 47, 24, 14, 53, 42 }, \ { 61, 32, 13, 54, 29, 7, 46, 13, 28, 57, 18, 41, 53, 15, 9, 39, 24, 49, 33, 3, 53, 9, 26, 32, 40, 28, 46, 39, 25, 9, 56, 21, 63, 37, 26, 22, 51, 27, 17, 56, 31, 53, 4, 43, 22, 46, 12, 18, 60, 40, 20, 26, 50, 21, 39, 5, 49, 33, 16, 44, 22, 46, 20, 32, 24, 45, 8, 43, 12, 46, 4, 48, 56, 20, 29, 58, 3, 40, 10, 42, 31, 21, 47, 41, 56, 38, 15, 42, 36, 27, 20, 33, 55, 3, 26, 44, 31, 54, 12, 35, 9, 63, 28, 10, 21, 32, 9, 60, 17, 8, 43, 29, 40, 16, 36, 48, 60, 7, 57, 14, 62, 31, 42, 15, 36, 40, 20, 26 }, \ { 0, 37, 47, 23, 41, 18, 32, 48, 1, 35, 8, 25, 4, 26, 63, 20, 54, 8, 16, 61, 35, 23, 51, 15, 58, 7, 12, 20, 50, 34, 42, 4, 38, 10, 32, 47, 8, 60, 41, 20, 9, 25, 50, 19, 62, 1, 37, 56, 28, 8, 53, 11, 3, 58, 34, 43, 19, 60, 38, 4, 58, 31, 3, 51, 11, 55, 38, 30, 21, 58, 19, 26, 9, 44, 36, 13, 46, 20, 62, 24, 13, 60, 5, 28, 12, 34, 7, 59, 0, 53, 45, 6, 38, 30, 50, 7, 62, 16, 41, 5, 46, 18, 55, 42, 51, 5, 45, 23, 34, 48, 19, 58, 5, 25, 54, 19, 13, 41, 28, 21, 0, 49, 10, 60, 4, 51, 9, 45 }, \ { 19, 28, 6, 58, 10, 51, 4, 22, 55, 42, 60, 45, 34, 51, 42, 5, 30, 45, 27, 40, 13, 47, 4, 49, 21, 38, 60, 29, 2, 57, 17, 27, 52, 19, 61, 14, 30, 34, 2, 44, 63, 33, 11, 35, 16, 51, 25, 6, 14, 47, 31, 61, 37, 29, 18, 8, 52, 2, 28, 54, 13, 41, 15, 62, 35, 18, 2, 60, 6, 33, 41, 61, 31, 6, 56, 17, 34, 50, 6, 52, 44, 35, 16, 51, 59, 24, 48, 18, 31, 40, 16, 49, 21, 60, 17, 39, 10, 49, 32, 57, 24, 39, 1, 25, 18, 62, 37, 12, 56, 1, 37, 11, 52, 44, 9, 30, 47, 4, 51, 40, 55, 25, 34, 27, 56, 30, 32, 54 }, \ { 63, 40, 49, 15, 43, 26, 63, 38, 16, 20, 30, 12, 57, 14, 19, 60, 36, 12, 59, 2, 57, 17, 42, 31, 1, 44, 16, 35, 47, 11, 32, 48, 13, 43, 1, 39, 51, 12, 57, 23, 6, 40, 53, 3, 55, 31, 39, 60, 35, 44, 5, 15, 45, 1, 62, 41, 26, 14, 47, 22, 36, 27, 50, 9, 26, 47, 52, 28, 54, 16, 1, 13, 51, 39, 23, 63, 1, 30, 15, 26, 2, 57, 19, 37, 1, 44, 21, 50, 13, 63, 8, 24, 56, 1, 35, 25, 58, 20, 2, 28, 14, 51, 33, 59, 13, 30, 4, 49, 31, 24, 63, 26, 33, 3, 58, 38, 62, 24, 32, 8, 17, 45, 5, 48, 18, 3, 43, 11 }, \ { 21, 4, 24, 34, 59, 1, 37, 11, 53, 5, 47, 2, 22, 40, 32, 1, 24, 50, 21, 29, 38, 25, 63, 8, 55, 24, 53, 6, 62, 23, 59, 3, 54, 20, 58, 24, 5, 46, 15, 38, 48, 14, 27, 42, 23, 7, 46, 10, 17, 58, 25, 52, 23, 32, 49, 12, 55, 30, 40, 7, 59, 1, 56, 21, 39, 4, 23, 15, 37, 46, 55, 42, 21, 4, 48, 8, 45, 54, 37, 55, 32, 8, 46, 10, 30, 54, 4, 41, 25, 29, 36, 48, 11, 43, 14, 47, 5, 43, 53, 36, 61, 10, 45, 6, 41, 54, 27, 43, 16, 55, 6, 46, 18, 42, 23, 15, 1, 45, 12, 60, 37, 22, 62, 12, 39, 59, 16, 52 }, \ { 47, 35, 56, 7, 19, 46, 31, 50, 33, 24, 61, 35, 50, 7, 53, 44, 55, 6, 46, 10, 52, 5, 21, 43, 36, 10, 18, 41, 26, 37, 8, 29, 40, 36, 9, 49, 34, 26, 61, 21, 7, 59, 18, 62, 29, 54, 20, 32, 51, 0, 40, 10, 55, 6, 20, 36, 9, 61, 5, 51, 44, 19, 33, 43, 13, 57, 40, 63, 8, 24, 29, 10, 60, 34, 27, 40, 25, 18, 10, 42, 21, 49, 26, 62, 38, 12, 33, 61, 5, 57, 2, 19, 54, 28, 62, 22, 38, 31, 16, 7, 22, 47, 29, 17, 35, 8, 20, 51, 2, 40, 22, 50, 13, 61, 28, 53, 35, 20, 56, 30, 2, 53, 14, 41, 23, 34, 8, 31 }, \ { 12, 2, 42, 29, 52, 13, 21, 8, 55, 14, 41, 17, 28, 58, 23, 11, 17, 36, 31, 62, 17, 34, 50, 14, 28, 61, 33, 52, 2, 51, 17, 45, 7, 25, 62, 30, 18, 55, 0, 42, 30, 35, 45, 1, 12, 48, 3, 63, 21, 36, 30, 48, 19, 59, 43, 27, 46, 17, 34, 25, 12, 29, 53, 6, 48, 31, 11, 34, 49, 3, 36, 50, 19, 47, 14, 61, 11, 36, 58, 4, 60, 14, 39, 22, 6, 52, 15, 35, 17, 46, 31, 42, 9, 34, 3, 52, 12, 60, 26, 56, 40, 2, 53, 23, 57, 38, 62, 14, 36, 59, 10, 31, 39, 6, 49, 9, 41, 26, 5, 48, 43, 27, 33, 58, 1, 50, 25, 57 }, \ { 61, 37, 15, 61, 3, 39, 58, 43, 26, 0, 44, 10, 47, 3, 37, 63, 28, 43, 13, 39, 3, 57, 30, 59, 0, 48, 5, 43, 13, 22, 60, 33, 55, 15, 42, 4, 52, 10, 45, 13, 54, 4, 24, 49, 37, 26, 41, 14, 42, 9, 61, 13, 38, 23, 3, 53, 0, 58, 21, 42, 63, 10, 17, 61, 25, 0, 58, 28, 17, 44, 57, 12, 27, 0, 55, 5, 52, 28, 23, 47, 29, 0, 43, 17, 58, 28, 47, 23, 55, 10, 58, 23, 51, 40, 18, 33, 45, 0, 49, 8, 32, 61, 19, 48, 0, 26, 7, 47, 29, 18, 44, 0, 56, 34, 20, 59, 15, 51, 37, 18, 10, 52, 7, 20, 46, 9, 38, 17 }, \ { 6, 27, 48, 23, 45, 29, 5, 18, 38, 62, 27, 56, 20, 32, 15, 9, 48, 0, 54, 22, 45, 20, 7, 41, 23, 39, 19, 27, 58, 31, 44, 0, 12, 50, 23, 56, 20, 39, 32, 59, 16, 52, 33, 9, 57, 22, 6, 58, 28, 50, 24, 2, 56, 35, 16, 45, 32, 38, 15, 54, 2, 38, 46, 22, 35, 45, 20, 5, 52, 25, 7, 35, 59, 32, 22, 43, 38, 3, 51, 16, 34, 53, 32, 50, 3, 40, 8, 43, 0, 39, 27, 4, 14, 61, 8, 55, 15, 41, 20, 44, 27, 13, 39, 11, 46, 42, 54, 33, 4, 52, 23, 61, 14, 25, 43, 2, 33, 11, 63, 29, 61, 17, 40, 55, 22, 62, 28, 44 }, \ { 20, 54, 8, 56, 35, 10, 63, 31, 52, 12, 48, 6, 59, 41, 52, 33, 19, 58, 25, 49, 11, 37, 47, 12, 54, 15, 56, 35, 7, 47, 16, 53, 28, 34, 5, 37, 28, 8, 48, 3, 28, 38, 18, 61, 16, 43, 53, 32, 4, 17, 47, 27, 44, 8, 63, 10, 25, 49, 6, 37, 24, 52, 32, 3, 50, 12, 41, 56, 38, 14, 62, 20, 40, 16, 53, 31, 18, 63, 41, 9, 59, 7, 13, 25, 57, 20, 63, 26, 53, 18, 48, 62, 30, 46, 21, 25, 58, 29, 36, 4, 55, 34, 6, 60, 31, 16, 21, 12, 58, 38, 9, 29, 47, 7, 52, 30, 57, 44, 22, 0, 35, 45, 3, 31, 14, 36, 0, 51 }, \ { 42, 14, 33, 24, 16, 49, 40, 2, 22, 33, 16, 36, 25, 1, 21, 61, 38, 8, 33, 4, 62, 26, 29, 60, 6, 46, 30, 11, 63, 4, 36, 40, 19, 57, 46, 11, 41, 63, 22, 25, 58, 10, 46, 2, 34, 27, 11, 38, 56, 34, 12, 53, 18, 33, 41, 51, 13, 28, 60, 20, 47, 14, 29, 59, 16, 62, 8, 22, 32, 47, 9, 49, 2, 44, 7, 12, 45, 6, 20, 27, 45, 24, 62, 42, 36, 11, 33, 15, 37, 7, 32, 10, 37, 1, 35, 50, 6, 11, 63, 24, 52, 15, 50, 24, 3, 37, 56, 27, 34, 22, 49, 16, 36, 62, 17, 39, 4, 15, 54, 24, 50, 8, 58, 26, 49, 54, 11, 30 }, \ { 4, 59, 41, 1, 53, 12, 25, 45, 59, 7, 51, 39, 54, 14, 46, 4, 27, 53, 16, 44, 18, 51, 1, 32, 25, 2, 50, 40, 20, 54, 24, 9, 62, 2, 27, 60, 1, 17, 36, 50, 6, 40, 30, 55, 41, 19, 49, 1, 21, 60, 40, 5, 62, 1, 22, 30, 57, 4, 43, 31, 1, 55, 40, 7, 27, 37, 30, 54, 1, 19, 42, 30, 56, 26, 62, 49, 24, 57, 37, 56, 2, 39, 16, 5, 30, 55, 3, 49, 60, 23, 56, 44, 17, 52, 13, 42, 28, 48, 18, 45, 9, 37, 21, 41, 58, 10, 48, 1, 63, 5, 41, 57, 2, 24, 12, 48, 27, 42, 32, 46, 13, 38, 19, 34, 5, 41, 25, 60 }, \ { 39, 28, 21, 46, 32, 57, 36, 9, 19, 42, 4, 29, 11, 43, 30, 49, 13, 42, 35, 56, 9, 39, 15, 52, 36, 61, 18, 26, 45, 14, 31, 48, 21, 43, 14, 33, 49, 54, 14, 44, 21, 62, 13, 23, 8, 62, 15, 51, 44, 7, 30, 37, 20, 42, 56, 7, 39, 18, 50, 11, 61, 9, 19, 43, 57, 2, 48, 11, 39, 60, 28, 4, 37, 17, 35, 1, 33, 11, 31, 14, 48, 19, 35, 51, 46, 21, 44, 29, 12, 41, 2, 22, 58, 26, 54, 4, 59, 38, 2, 33, 57, 1, 63, 13, 28, 51, 15, 40, 18, 45, 8, 30, 43, 37, 54, 19, 8, 59, 21, 6, 60, 29, 55, 10, 63, 15, 47, 17 }, \ { 3, 50, 10, 62, 18, 5, 27, 49, 60, 23, 55, 18, 62, 24, 56, 10, 59, 28, 2, 23, 34, 59, 43, 20, 10, 42, 8, 49, 1, 37, 57, 6, 51, 29, 53, 7, 23, 31, 5, 32, 51, 0, 35, 54, 45, 31, 5, 26, 36, 24, 55, 15, 48, 29, 14, 48, 26, 60, 21, 41, 36, 26, 50, 33, 14, 44, 17, 24, 52, 15, 46, 23, 54, 6, 47, 21, 60, 50, 4, 53, 29, 61, 8, 23, 1, 60, 19, 6, 53, 16, 47, 34, 6, 39, 16, 31, 12, 20, 53, 22, 30, 43, 25, 46, 35, 6, 44, 32, 53, 26, 55, 19, 11, 59, 5, 33, 51, 1, 35, 53, 25, 3, 42, 23, 44, 32, 7, 53 }, \ { 22, 44, 37, 6, 26, 51, 38, 0, 34, 13, 31, 46, 3, 37, 6, 19, 40, 21, 47, 63, 12, 5, 29, 55, 22, 58, 34, 28, 60, 22, 11, 41, 17, 38, 9, 44, 59, 39, 56, 19, 11, 47, 25, 15, 3, 39, 57, 17, 61, 11, 46, 3, 58, 9, 54, 35, 2, 34, 8, 45, 15, 56, 5, 23, 53, 33, 63, 35, 4, 59, 10, 51, 13, 61, 29, 41, 15, 25, 43, 19, 40, 10, 54, 33, 41, 12, 38, 51, 31, 26, 61, 9, 30, 45, 24, 62, 49, 40, 10, 61, 14, 49, 5, 17, 54, 20, 60, 23, 3, 13, 35, 50, 32, 23, 46, 27, 38, 63, 16, 12, 39, 48, 18, 51, 1, 27, 56, 35 }, \ { 63, 15, 30, 55, 43, 14, 57, 17, 53, 44, 7, 48, 26, 50, 32, 60, 0, 53, 14, 31, 50, 24, 46, 0, 38, 13, 4, 52, 16, 45, 30, 59, 0, 25, 55, 35, 16, 10, 26, 42, 58, 29, 60, 38, 50, 22, 28, 47, 0, 50, 28, 19, 33, 39, 11, 44, 16, 52, 24, 59, 3, 38, 27, 51, 0, 21, 7, 42, 26, 34, 21, 40, 33, 18, 39, 3, 54, 38, 8, 59, 0, 44, 27, 15, 58, 28, 57, 9, 43, 0, 36, 50, 20, 59, 8, 34, 0, 27, 47, 7, 36, 19, 56, 32, 0, 38, 11, 29, 62, 47, 6, 61, 0, 41, 14, 56, 10, 23, 45, 31, 57, 8, 36, 13, 58, 38, 11, 19 }, \ { 0, 34, 12, 47, 21, 2, 40, 30, 11, 25, 61, 20, 40, 15, 35, 22, 45, 36, 7, 41, 17, 57, 9, 48, 32, 62, 44, 24, 35, 3, 54, 13, 33, 63, 19, 4, 48, 22, 62, 2, 37, 8, 33, 6, 20, 52, 9, 32, 43, 13, 39, 63, 25, 4, 49, 23, 62, 32, 9, 30, 48, 18, 63, 12, 46, 29, 58, 13, 48, 8, 57, 31, 0, 51, 9, 58, 12, 22, 47, 29, 35, 22, 49, 5, 46, 4, 34, 20, 63, 24, 56, 11, 41, 3, 51, 19, 56, 35, 17, 58, 28, 42, 9, 45, 59, 26, 51, 42, 17, 36, 25, 15, 53, 21, 44, 3, 30, 55, 5, 50, 21, 28, 61, 32, 6, 49, 28, 46 }, \ { 58, 42, 60, 4, 31, 59, 22, 63, 35, 38, 9, 54, 1, 57, 8, 51, 16, 58, 27, 53, 3, 38, 30, 15, 27, 6, 19, 56, 10, 50, 21, 36, 47, 5, 43, 28, 51, 32, 13, 46, 18, 54, 16, 43, 63, 12, 36, 59, 22, 34, 5, 52, 17, 59, 27, 41, 0, 19, 55, 37, 13, 43, 6, 34, 41, 10, 36, 55, 19, 44, 3, 16, 58, 27, 49, 25, 32, 62, 17, 55, 13, 63, 18, 52, 25, 37, 17, 48, 13, 32, 5, 46, 28, 37, 14, 43, 25, 5, 51, 39, 3, 52, 33, 22, 8, 40, 12, 4, 57, 9, 46, 39, 28, 58, 13, 62, 17, 42, 19, 36, 0, 47, 16, 43, 24, 21, 54, 13 }, \ { 25, 9, 23, 50, 36, 8, 45, 14, 3, 51, 16, 28, 44, 12, 42, 29, 4, 26, 10, 47, 22, 61, 18, 54, 51, 39, 46, 13, 41, 26, 58, 7, 18, 39, 12, 57, 15, 1, 52, 27, 41, 23, 48, 1, 27, 45, 18, 2, 57, 26, 55, 8, 43, 31, 6, 58, 14, 51, 40, 5, 61, 31, 24, 54, 17, 60, 22, 1, 39, 30, 53, 45, 36, 13, 43, 5, 45, 2, 37, 6, 34, 42, 2, 39, 10, 62, 7, 54, 40, 18, 60, 15, 52, 21, 63, 8, 55, 46, 15, 30, 23, 13, 62, 16, 50, 24, 58, 31, 48, 21, 34, 2, 49, 7, 31, 37, 26, 48, 9, 61, 40, 11, 52, 2, 60, 40, 4, 37 }, \ { 52, 28, 39, 16, 54, 19, 29, 55, 42, 20, 58, 33, 24, 63, 18, 55, 39, 62, 43, 34, 12, 40, 6, 35, 2, 25, 8, 62, 34, 1, 31, 42, 61, 27, 53, 24, 40, 61, 34, 8, 59, 4, 30, 56, 40, 6, 53, 42, 10, 48, 16, 37, 12, 46, 21, 36, 47, 11, 28, 45, 22, 10, 57, 2, 49, 31, 14, 44, 61, 11, 25, 6, 23, 63, 18, 36, 28, 56, 20, 51, 11, 48, 27, 56, 32, 22, 45, 30, 2, 42, 27, 39, 1, 44, 23, 31, 38, 22, 11, 61, 43, 54, 4, 47, 35, 2, 44, 16, 28, 54, 12, 62, 18, 43, 10, 52, 1, 58, 33, 15, 29, 56, 20, 34, 9, 30, 48, 17 }, \ { 46, 2, 56, 11, 41, 1, 49, 6, 27, 47, 2, 48, 5, 32, 37, 3, 13, 19, 32, 1, 55, 28, 60, 17, 43, 59, 32, 20, 49, 16, 55, 23, 14, 46, 2, 36, 6, 30, 20, 49, 12, 47, 35, 14, 21, 60, 29, 14, 35, 24, 46, 1, 56, 29, 53, 8, 33, 23, 56, 1, 35, 46, 20, 39, 26, 4, 53, 28, 17, 38, 60, 34, 48, 9, 55, 15, 46, 7, 41, 31, 60, 24, 16, 36, 1, 59, 19, 52, 35, 6, 55, 11, 59, 33, 7, 57, 4, 29, 48, 1, 19, 26, 37, 30, 18, 63, 37, 6, 59, 1, 40, 24, 56, 33, 46, 22, 35, 7, 24, 53, 39, 5, 26, 45, 55, 18, 62, 7 }, \ { 20, 60, 29, 34, 20, 62, 33, 52, 10, 36, 13, 60, 41, 21, 50, 27, 56, 49, 8, 51, 21, 45, 11, 48, 8, 23, 53, 3, 29, 44, 5, 52, 9, 32, 50, 17, 43, 56, 3, 38, 24, 10, 62, 25, 51, 9, 33, 49, 61, 7, 30, 62, 22, 19, 2, 42, 63, 5, 49, 18, 60, 15, 52, 7, 43, 56, 23, 50, 5, 50, 2, 20, 41, 30, 1, 52, 22, 61, 14, 26, 3, 43, 53, 7, 47, 28, 11, 14, 23, 58, 33, 25, 47, 13, 50, 17, 40, 54, 34, 60, 41, 6, 59, 14, 50, 7, 25, 55, 20, 42, 51, 8, 27, 4, 16, 60, 28, 50, 44, 3, 22, 49, 63, 12, 33, 1, 43, 31 }, \ { 36, 5, 46, 8, 44, 24, 13, 39, 25, 57, 31, 18, 8, 52, 10, 45, 6, 30, 36, 24, 63, 4, 33, 26, 57, 40, 15, 56, 37, 12, 40, 25, 37, 58, 11, 63, 21, 45, 16, 60, 31, 53, 18, 33, 3, 45, 23, 0, 20, 54, 40, 15, 50, 38, 60, 16, 25, 42, 29, 38, 7, 41, 25, 62, 18, 33, 8, 35, 42, 16, 32, 56, 12, 39, 59, 19, 34, 9, 49, 38, 57, 12, 21, 50, 14, 40, 61, 44, 50, 9, 49, 19, 3, 29, 35, 62, 12, 24, 7, 18, 52, 32, 10, 46, 21, 41, 32, 11, 36, 29, 14, 34, 60, 38, 54, 11, 41, 14, 19, 57, 32, 16, 7, 41, 51, 25, 14, 57 }, \ { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 63, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 }, \ { 23, 39, 61, 3, 37, 28, 48, 31, 0, 34, 51, 23, 2, 26, 58, 0, 53, 11, 46, 1, 57, 29, 52, 14, 37, 61, 21, 35, 2, 49, 7, 34, 47, 55, 4, 33, 54, 13, 58, 52, 19, 50, 22, 7, 13, 29, 36, 11, 51, 17, 60, 25, 55, 4, 34, 51, 0, 35, 20, 48, 32, 3, 51, 30, 59, 28, 40, 3, 46, 29, 54, 43, 7, 62, 47, 11, 39, 4, 23, 46, 55, 8, 63, 5, 25, 37, 18, 46, 21, 56, 31, 5, 36, 8, 45, 58, 26, 15, 2, 36, 47, 21, 29, 44, 25, 34, 3, 27, 43, 10, 52, 0, 45, 30, 24, 36, 43, 18, 34, 59, 0, 52, 61, 15, 44, 19, 30, 49 }, \ { 0, 27, 12, 43, 54, 9, 22, 53, 21, 46, 15, 55, 29, 47, 20, 33, 39, 28, 59, 35, 9, 44, 5, 24, 47, 7, 52, 17, 56, 22, 30, 42, 14, 26, 45, 18, 49, 1, 24, 34, 11, 27, 55, 32, 61, 47, 2, 56, 6, 44, 13, 47, 36, 27, 58, 22, 16, 47, 40, 4, 57, 38, 21, 45, 16, 9, 56, 26, 11, 38, 0, 22, 36, 17, 33, 57, 16, 30, 62, 15, 35, 40, 20, 45, 59, 10, 54, 8, 63, 13, 52, 27, 22, 57, 28, 12, 32, 51, 55, 22, 63, 4, 16, 54, 12, 62, 45, 19, 58, 13, 32, 40, 20, 56, 7, 57, 9, 54, 6, 29, 42, 21, 8, 55, 35, 47, 6, 41 }, \ { 56, 33, 58, 32, 19, 35, 42, 6, 59, 11, 38, 5, 49, 12, 62, 7, 52, 17, 5, 25, 54, 20, 61, 31, 54, 27, 41, 11, 44, 5, 59, 12, 36, 51, 10, 61, 28, 41, 48, 9, 43, 63, 5, 40, 20, 8, 49, 26, 34, 21, 58, 1, 18, 45, 7, 39, 61, 26, 8, 50, 23, 10, 63, 5, 55, 37, 19, 49, 52, 15, 59, 47, 13, 54, 1, 25, 42, 58, 10, 48, 3, 27, 50, 1, 17, 48, 34, 41, 16, 40, 2, 45, 10, 39, 17, 61, 5, 38, 19, 9, 41, 31, 60, 38, 5, 23, 36, 8, 30, 55, 24, 63, 12, 48, 14, 51, 31, 20, 45, 25, 12, 50, 32, 2, 28, 11, 62, 14 }, \ { 44, 16, 7, 48, 1, 62, 16, 50, 27, 33, 61, 25, 17, 44, 31, 14, 22, 43, 32, 48, 18, 40, 8, 36, 3, 16, 33, 62, 23, 38, 25, 53, 2, 21, 41, 6, 22, 15, 59, 29, 16, 37, 26, 15, 52, 42, 23, 15, 54, 39, 10, 30, 53, 11, 49, 24, 2, 43, 55, 17, 34, 44, 15, 31, 24, 44, 2, 32, 7, 35, 25, 5, 40, 45, 29, 51, 6, 21, 37, 52, 24, 60, 13, 31, 53, 23, 2, 28, 49, 24, 31, 60, 20, 51, 1, 34, 48, 14, 59, 33, 50, 1, 18, 33, 48, 60, 17, 51, 39, 6, 38, 2, 35, 29, 40, 23, 1, 62, 15, 53, 37, 17, 46, 57, 40, 51, 24, 22 }, \ { 5, 37, 52, 24, 45, 13, 40, 3, 45, 9, 19, 42, 56, 4, 37, 46, 56, 2, 63, 11, 51, 1, 49, 13, 59, 45, 39, 1, 48, 15, 58, 9, 46, 31, 54, 35, 57, 38, 3, 46, 56, 4, 47, 57, 1, 30, 38, 63, 3, 46, 28, 63, 41, 14, 33, 62, 19, 32, 13, 28, 61, 1, 53, 42, 11, 60, 22, 62, 27, 42, 61, 31, 19, 8, 61, 12, 32, 55, 2, 18, 33, 12, 43, 36, 9, 62, 30, 55, 6, 58, 35, 7, 43, 29, 54, 23, 43, 30, 3, 25, 11, 45, 52, 28, 7, 14, 42, 1, 22, 50, 16, 53, 19, 59, 4, 46, 33, 41, 4, 35, 58, 5, 26, 13, 20, 2, 34, 54 }, \ { 30, 63, 21, 10, 26, 55, 29, 59, 23, 39, 53, 1, 36, 24, 59, 27, 10, 34, 23, 38, 30, 60, 22, 42, 28, 19, 9, 57, 30, 19, 43, 33, 13, 63, 3, 19, 11, 50, 31, 20, 14, 34, 10, 35, 17, 59, 7, 31, 19, 25, 50, 5, 20, 57, 29, 6, 52, 41, 4, 46, 20, 37, 26, 17, 49, 6, 39, 18, 53, 14, 3, 49, 57, 23, 34, 48, 14, 41, 28, 38, 56, 6, 58, 25, 39, 19, 43, 15, 37, 11, 47, 18, 53, 4, 37, 9, 62, 21, 53, 40, 57, 24, 13, 40, 56, 26, 47, 31, 59, 25, 45, 27, 10, 43, 21, 61, 13, 27, 48, 9, 23, 43, 31, 62, 38, 59, 9, 47 }, \ { 25, 4, 40, 60, 34, 6, 18, 36, 8, 57, 12, 30, 49, 14, 6, 54, 41, 16, 50, 6, 43, 15, 34, 4, 53, 24, 50, 35, 4, 51, 7, 55, 28, 24, 39, 44, 60, 7, 25, 62, 42, 53, 24, 61, 28, 45, 52, 12, 48, 37, 9, 35, 43, 3, 37, 48, 12, 58, 30, 52, 9, 59, 6, 57, 33, 29, 48, 4, 37, 45, 20, 34, 10, 39, 0, 60, 22, 45, 8, 63, 21, 42, 14, 49, 3, 56, 11, 46, 21, 61, 0, 42, 25, 13, 63, 17, 36, 8, 46, 16, 6, 35, 63, 0, 21, 37, 4, 57, 9, 34, 5, 61, 48, 32, 8, 37, 54, 17, 56, 30, 60, 0, 50, 16, 7, 29, 42, 17 }, \ { 32, 50, 15, 48, 2, 43, 52, 25, 47, 16, 32, 63, 21, 52, 40, 19, 0, 61, 29, 58, 20, 56, 26, 46, 12, 55, 6, 22, 62, 32, 17, 40, 0, 49, 34, 8, 27, 32, 48, 0, 21, 39, 5, 44, 12, 6, 22, 40, 0, 57, 16, 60, 23, 17, 54, 22, 36, 15, 24, 39, 19, 34, 47, 23, 0, 54, 13, 51, 24, 9, 55, 16, 52, 27, 44, 20, 4, 54, 26, 49, 0, 30, 46, 16, 29, 51, 34, 4, 52, 28, 33, 15, 57, 39, 26, 49, 0, 56, 27, 31, 48, 20, 43, 29, 53, 11, 46, 19, 41, 13, 55, 18, 0, 57, 26, 51, 2, 44, 6, 38, 14, 40, 22, 45, 36, 53, 3, 57 }, \ { 44, 12, 37, 28, 22, 57, 11, 38, 0, 51, 9, 41, 4, 29, 11, 47, 33, 45, 12, 26, 3, 36, 9, 63, 31, 16, 38, 44, 14, 47, 25, 61, 20, 58, 15, 47, 17, 57, 13, 36, 9, 51, 18, 29, 50, 36, 54, 20, 61, 27, 32, 13, 53, 44, 9, 27, 0, 63, 45, 2, 56, 10, 14, 43, 41, 28, 58, 11, 35, 60, 30, 41, 6, 63, 11, 51, 37, 32, 15, 10, 35, 53, 5, 61, 22, 7, 26, 59, 23, 9, 44, 48, 21, 3, 51, 32, 24, 41, 12, 61, 2, 55, 9, 15, 35, 58, 28, 15, 62, 30, 37, 23, 42, 29, 11, 17, 35, 24, 63, 20, 52, 28, 8, 55, 11, 23, 47, 19 }, \ { 0, 56, 8, 53, 14, 31, 61, 20, 55, 28, 62, 18, 35, 60, 25, 57, 7, 23, 39, 54, 47, 17, 43, 0, 40, 59, 29, 2, 56, 10, 37, 5, 43, 11, 29, 52, 1, 23, 54, 41, 59, 30, 55, 1, 62, 15, 33, 4, 43, 10, 47, 39, 1, 31, 40, 60, 49, 33, 7, 55, 26, 50, 31, 61, 8, 18, 21, 32, 44, 1, 25, 47, 18, 36, 30, 23, 59, 7, 40, 59, 27, 19, 38, 32, 44, 54, 40, 17, 38, 60, 27, 6, 35, 55, 10, 14, 44, 5, 50, 17, 38, 26, 42, 50, 18, 3, 44, 52, 2, 49, 7, 52, 15, 46, 62, 39, 55, 10, 31, 48, 3, 58, 33, 18, 61, 34, 13, 59 }, \ { 39, 27, 63, 20, 35, 41, 4, 45, 26, 5, 38, 13, 44, 2, 50, 17, 37, 52, 2, 13, 28, 58, 24, 51, 21, 8, 34, 48, 27, 42, 18, 51, 31, 56, 5, 36, 38, 44, 4, 17, 26, 11, 38, 23, 42, 8, 56, 39, 24, 51, 5, 56, 21, 59, 14, 6, 18, 42, 22, 35, 16, 37, 3, 25, 39, 46, 63, 5, 50, 17, 58, 8, 55, 3, 50, 12, 43, 17, 47, 2, 51, 9, 62, 12, 1, 35, 13, 50, 1, 37, 12, 51, 19, 29, 46, 59, 22, 58, 33, 45, 22, 60, 10, 32, 61, 39, 8, 33, 25, 36, 20, 60, 38, 4, 21, 5, 28, 45, 12, 18, 42, 11, 49, 1, 27, 40, 6, 30 }, \ { 24, 16, 42, 1, 50, 10, 48, 17, 33, 43, 24, 48, 21, 55, 31, 42, 10, 21, 63, 35, 49, 6, 33, 13, 41, 53, 10, 20, 60, 6, 53, 26, 12, 41, 22, 60, 14, 28, 63, 33, 49, 3, 45, 16, 48, 26, 14, 46, 18, 30, 35, 26, 8, 50, 29, 51, 25, 57, 12, 47, 53, 9, 62, 20, 54, 2, 36, 15, 40, 28, 33, 13, 38, 24, 46, 1, 29, 56, 33, 20, 44, 24, 41, 26, 57, 20, 63, 8, 30, 55, 5, 41, 62, 8, 34, 2, 37, 10, 19, 6, 37, 1, 53, 23, 5, 27, 58, 22, 43, 12, 50, 26, 9, 34, 54, 32, 49, 1, 59, 37, 22, 46, 25, 36, 51, 15, 54, 46 }, \ { 52, 7, 45, 33, 26, 58, 14, 60, 7, 54, 3, 58, 8, 34, 14, 5, 59, 30, 18, 44, 8, 22, 48, 62, 3, 26, 55, 38, 23, 16, 39, 1, 62, 24, 49, 9, 53, 19, 46, 7, 19, 60, 31, 58, 2, 34, 53, 7, 59, 2, 62, 42, 46, 19, 36, 11, 44, 4, 38, 28, 1, 43, 32, 51, 12, 29, 56, 22, 52, 2, 62, 49, 22, 60, 14, 35, 63, 5, 25, 57, 14, 53, 4, 46, 18, 31, 42, 22, 47, 20, 58, 31, 16, 43, 23, 54, 30, 42, 52, 57, 29, 49, 30, 13, 45, 48, 16, 55, 6, 63, 1, 44, 14, 58, 19, 47, 15, 24, 51, 34, 6, 55, 5, 63, 20, 41, 21, 9 }, \ { 30, 62, 18, 55, 5, 23, 39, 29, 49, 30, 15, 36, 28, 46, 60, 25, 39, 46, 4, 32, 61, 40, 15, 30, 36, 45, 14, 2, 49, 33, 57, 45, 18, 32, 3, 45, 30, 2, 35, 52, 40, 27, 13, 21, 38, 63, 20, 28, 37, 23, 16, 10, 13, 55, 2, 62, 21, 32, 60, 17, 58, 23, 5, 40, 16, 48, 7, 45, 10, 26, 43, 19, 6, 31, 52, 21, 39, 16, 48, 9, 37, 28, 36, 55, 7, 48, 3, 59, 15, 45, 25, 1, 53, 13, 47, 7, 62, 15, 4, 25, 12, 41, 18, 60, 38, 11, 34, 19, 39, 31, 29, 56, 23, 42, 3, 27, 60, 41, 8, 16, 61, 29, 43, 9, 32, 2, 60, 34 }, \ { 3, 38, 13, 37, 52, 44, 2, 19, 12, 42, 63, 19, 40, 1, 20, 50, 12, 55, 15, 56, 27, 1, 54, 11, 57, 18, 32, 63, 44, 4, 29, 13, 37, 61, 35, 16, 42, 57, 12, 22, 6, 55, 43, 10, 50, 5, 44, 11, 48, 52, 34, 58, 28, 41, 38, 30, 7, 52, 11, 49, 30, 14, 45, 27, 59, 34, 21, 38, 32, 58, 11, 36, 56, 42, 9, 41, 3, 54, 31, 42, 0, 60, 16, 11, 39, 24, 52, 33, 6, 36, 10, 40, 32, 60, 26, 20, 39, 28, 47, 34, 63, 8, 54, 3, 24, 56, 0, 51, 13, 47, 16, 40, 7, 35, 52, 11, 36, 4, 57, 30, 39, 13, 18, 50, 58, 28, 12, 48 }, \ { 57, 24, 49, 21, 10, 31, 61, 36, 56, 0, 22, 53, 11, 56, 32, 7, 36, 27, 41, 9, 46, 19, 34, 42, 25, 7, 50, 9, 28, 21, 54, 8, 50, 7, 27, 59, 10, 25, 48, 62, 37, 0, 33, 58, 25, 18, 32, 61, 0, 15, 45, 5, 50, 3, 23, 55, 47, 17, 40, 6, 60, 34, 53, 8, 41, 0, 61, 13, 54, 4, 46, 28, 0, 17, 48, 27, 58, 13, 23, 61, 33, 21, 50, 30, 62, 8, 14, 29, 56, 27, 61, 49, 17, 2, 44, 11, 51, 0, 59, 17, 40, 20, 32, 47, 36, 21, 42, 28, 60, 4, 54, 10, 59, 17, 30, 62, 21, 43, 26, 48, 0, 56, 36, 25, 8, 44, 39, 17 }, \ { 10, 42, 4, 59, 27, 47, 8, 23, 51, 32, 45, 6, 37, 26, 48, 43, 62, 0, 21, 53, 38, 12, 51, 5, 60, 47, 24, 37, 59, 15, 35, 47, 22, 55, 0, 50, 21, 40, 6, 29, 15, 52, 24, 8, 41, 55, 13, 29, 40, 56, 24, 31, 19, 33, 61, 15, 0, 35, 24, 42, 21, 2, 19, 57, 24, 15, 30, 50, 20, 25, 40, 16, 57, 34, 61, 8, 29, 45, 6, 49, 11, 47, 2, 44, 19, 57, 38, 50, 12, 42, 21, 4, 35, 52, 28, 56, 23, 36, 13, 45, 4, 52, 27, 14, 6, 62, 9, 45, 21, 37, 25, 46, 33, 49, 0, 44, 7, 53, 13, 19, 53, 31, 3, 47, 15, 56, 22, 51 }, \ { 35, 28, 53, 32, 1, 16, 54, 40, 9, 17, 25, 58, 14, 59, 3, 22, 16, 51, 31, 5, 23, 58, 28, 17, 35, 20, 0, 42, 11, 52, 3, 31, 41, 17, 43, 13, 32, 54, 18, 60, 32, 45, 17, 49, 2, 36, 51, 22, 7, 36, 9, 63, 48, 12, 46, 26, 43, 28, 63, 13, 48, 37, 51, 33, 5, 47, 55, 9, 42, 63, 7, 51, 24, 12, 37, 19, 55, 34, 18, 38, 15, 28, 54, 34, 5, 43, 22, 0, 48, 14, 54, 24, 58, 9, 38, 5, 32, 55, 21, 30, 49, 9, 59, 43, 30, 51, 35, 26, 7, 53, 2, 22, 14, 27, 57, 18, 38, 24, 33, 45, 10, 41, 20, 60, 37, 5, 32, 0 }, \ { 63, 19, 15, 40, 62, 35, 14, 28, 46, 61, 4, 49, 35, 10, 29, 54, 33, 8, 45, 62, 37, 1, 43, 55, 10, 52, 61, 30, 19, 40, 25, 62, 11, 38, 27, 58, 36, 3, 46, 8, 39, 4, 62, 28, 47, 20, 4, 54, 47, 27, 43, 1, 21, 38, 8, 58, 10, 54, 4, 56, 9, 26, 12, 39, 60, 27, 18, 37, 1, 31, 35, 5, 45, 50, 2, 43, 26, 1, 59, 23, 56, 40, 7, 26, 58, 17, 32, 63, 25, 39, 7, 31, 45, 19, 63, 15, 48, 8, 37, 61, 16, 34, 1, 56, 18, 3, 15, 58, 49, 32, 63, 41, 55, 5, 40, 22, 50, 6, 59, 2, 63, 23, 52, 11, 26, 61, 44, 23 }, \ { 11, 56, 46, 6, 22, 43, 58, 3, 34, 21, 38, 30, 18, 44, 52, 13, 41, 57, 17, 28, 14, 49, 25, 7, 33, 39, 26, 6, 56, 48, 1, 20, 56, 5, 46, 9, 19, 51, 30, 25, 56, 21, 35, 14, 57, 42, 16, 33, 10, 57, 17, 59, 41, 25, 53, 37, 20, 40, 30, 18, 31, 62, 44, 22, 3, 44, 11, 48, 23, 53, 18, 60, 29, 22, 62, 15, 53, 47, 10, 41, 3, 19, 52, 36, 13, 46, 10, 35, 3, 61, 41, 16, 1, 50, 26, 42, 18, 46, 2, 25, 54, 20, 39, 23, 47, 31, 41, 12, 38, 17, 8, 19, 31, 48, 12, 61, 9, 54, 29, 35, 15, 38, 6, 43, 34, 14, 7, 47 }, \ { 39, 2, 33, 26, 53, 8, 18, 50, 41, 12, 53, 1, 63, 24, 19, 39, 2, 24, 47, 10, 60, 38, 19, 63, 48, 4, 15, 45, 32, 14, 60, 36, 29, 53, 23, 63, 34, 12, 61, 1, 43, 11, 53, 30, 1, 26, 60, 45, 23, 39, 3, 29, 12, 50, 4, 16, 51, 3, 45, 36, 50, 1, 16, 54, 35, 14, 57, 30, 58, 9, 46, 14, 41, 10, 32, 38, 4, 30, 21, 51, 32, 63, 25, 1, 60, 27, 53, 18, 51, 22, 28, 55, 34, 12, 40, 3, 60, 29, 57, 41, 6, 44, 11, 53, 8, 61, 24, 57, 1, 28, 44, 59, 36, 3, 34, 25, 41, 31, 16, 44, 22, 47, 28, 58, 1, 49, 54, 29 }, \ { 58, 25, 50, 13, 38, 30, 60, 24, 6, 57, 27, 42, 9, 45, 6, 61, 30, 50, 4, 34, 29, 3, 46, 13, 22, 42, 58, 28, 9, 39, 23, 44, 7, 15, 44, 2, 40, 15, 47, 41, 23, 37, 7, 59, 38, 11, 34, 6, 62, 14, 52, 35, 55, 19, 32, 61, 33, 24, 57, 6, 22, 59, 29, 7, 49, 25, 40, 3, 17, 39, 27, 52, 0, 55, 16, 57, 24, 61, 36, 6, 29, 12, 48, 39, 20, 44, 6, 40, 33, 5, 48, 10, 57, 36, 22, 51, 33, 9, 24, 12, 62, 29, 50, 35, 14, 43, 5, 33, 47, 52, 13, 23, 10, 51, 56, 16, 46, 1, 49, 4, 61, 9, 52, 18, 31, 21, 36, 17 }, \ { 19, 42, 9, 48, 2, 44, 11, 37, 48, 20, 33, 16, 55, 35, 49, 15, 37, 20, 59, 16, 53, 22, 56, 31, 50, 11, 34, 54, 16, 51, 4, 49, 33, 53, 21, 28, 56, 24, 31, 9, 52, 16, 48, 24, 44, 13, 51, 20, 31, 49, 18, 6, 34, 2, 44, 14, 47, 8, 15, 43, 13, 41, 33, 52, 20, 61, 7, 51, 34, 62, 4, 20, 36, 33, 43, 8, 46, 13, 53, 17, 45, 42, 9, 31, 52, 11, 30, 56, 13, 59, 17, 44, 27, 6, 62, 11, 43, 17, 49, 38, 26, 2, 16, 27, 58, 21, 54, 18, 26, 5, 35, 61, 43, 27, 7, 39, 14, 58, 37, 55, 20, 33, 13, 40, 62, 10, 55, 5 }, \ { 51, 14, 61, 29, 59, 20, 55, 31, 0, 49, 11, 60, 3, 26, 22, 56, 0, 40, 12, 43, 41, 8, 36, 0, 17, 57, 24, 2, 46, 26, 61, 18, 0, 38, 12, 59, 6, 49, 3, 57, 19, 63, 5, 33, 18, 54, 28, 56, 0, 43, 26, 46, 63, 27, 56, 22, 27, 54, 38, 28, 63, 24, 10, 45, 0, 31, 42, 21, 12, 25, 44, 49, 59, 6, 26, 50, 3, 34, 27, 59, 0, 35, 62, 16, 4, 58, 47, 0, 43, 24, 37, 2, 54, 20, 46, 31, 0, 56, 34, 5, 55, 45, 60, 37, 0, 40, 10, 38, 63, 46, 15, 20, 0, 53, 21, 62, 30, 11, 24, 27, 40, 0, 57, 26, 3, 45, 27, 35 }, \ } #endif fvwm-2.6.7/libs/Bindings.c0000644000175700017570000005066613001406607012310 00000000000000/* -*-c-*- */ /* 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 #include #include #include #include "libs/fvwmlib.h" #include "libs/Strings.h" #include "libs/wild.h" #include "libs/Grab.h" #include "libs/Bindings.h" #include "libs/charmap.h" #include "libs/wcontext.h" #include "libs/modifiers.h" static Bool is_grabbing_everything = False; static int key_min = 0; static int key_max = 0; /* Free the memory use by a binding. */ void FreeBindingStruct(Binding *b) { if (b->key_name) { free(b->key_name); } STROKE_CODE( if (b->Stroke_Seq) free(b->Stroke_Seq); ); if (b->Action) { free(b->Action); } if (b->Action2) { free(b->Action2); } if (b->windowName) { free(b->windowName); } free(b); return; } void FreeBindingList(Binding *b) { Binding *t; for (; b != NULL; b = t) { t = b->NextBinding; FreeBindingStruct(b); } return; } /* Unlink a binding b from a binding list pblist. The previous binding in the * list (prev) must be given also. Pass NULL at the beginning of the list. * The *pblist pointer may be modified by this function. */ static void UnlinkBinding(Binding **pblist, Binding *b, Binding *prev) { Binding *t; if (!prev && b != *pblist) { for (t = *pblist; t && t != b; prev = t, t = t->NextBinding) { /* Find the previous binding in the list. */ } if (t == NULL) { /* Binding not found */ return; } } if (prev) { /* middle of list */ prev->NextBinding = b->NextBinding; } else { /* must have been first one, set new start */ *pblist = b->NextBinding; } return; } /* To remove a binding from the global list (probably needs more processing * for mouse binding lines though, like when context is a title bar button). * Specify either button or keysym, depending on type. */ void RemoveBinding(Binding **pblist, Binding *b, Binding *prev) { UnlinkBinding(pblist, b, NULL); FreeBindingStruct(b); return; } /* * * Actually adds a new binding to a list (pblist) of existing bindings. * Specify either button or keysym/key_name, depending on type. * The parameters action and action2 are assumed to reside in malloced memory * that will be freed in RemoveBinding. The key_name is copied into private * memory and has to be freed by the caller. * */ int AddBinding( Display *dpy, Binding **pblist, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, char *key_name, int modifiers, int contexts, void *action, void *action2, char *windowName) { int i; int min; int max; int maxmods; int m; int mask; int count = 0; KeySym tkeysym; Binding *temp; /* ** Unfortunately a keycode can be bound to multiple keysyms and a ** keysym can bound to multiple keycodes. Thus we have to check every ** keycode with any single modifier. */ if (BIND_IS_KEY_BINDING(type)) { if (key_max == 0) { XDisplayKeycodes(dpy, &key_min, &key_max); } min=key_min; max=key_max; maxmods = 8; } else { min = button; max = button; maxmods = 0; } for (i = min; i <= max; i++) { unsigned int bound_mask = 0; /* If this is a mouse binding we'll fall through the for loop * (maxmods is zero) and the if condition is always true (type * is zero). Since min == max == button there is no loop at all * is case of a mouse binding. */ for (m = 0, tkeysym = XK_Left; m <= maxmods && tkeysym != NoSymbol; m++) { if (BIND_IS_MOUSE_BINDING(type) || STROKE_CODE(BIND_IS_STROKE_BINDING(type) ||) (tkeysym = fvwm_KeycodeToKeysym(dpy, i, m, 0)) == keysym) { unsigned int add_modifiers = 0; unsigned int bind_mask = 1; unsigned int check_bound_mask = 0; switch (m) { case 0: /* key generates the key sym with no * modifiers depressed - bind it */ break; case 1: /* key generates the key sym with shift * depressed */ if (modifiers != AnyModifier && !(modifiers & ShiftMask)) { add_modifiers = ShiftMask; bind_mask = (1 << m); /* but don't bind it again if * already bound without * modifiers */ check_bound_mask = 1; } break; default: /* key generates the key sym with * undefined modifiers depressed - * let's make an educated guess at what * modifiers the user expected * based on the XFree86 default * configuration. */ mask = modifier_mapindex_to_mask[m - 1]; if (modifiers != AnyModifier && !((modifiers & mask) != mask)) { add_modifiers = mask; bind_mask = (1 << m); /* but don't bind it again if * already bound without * modifiers */ check_bound_mask = 1; } break; } if ((bind_mask & bound_mask) || (check_bound_mask & bound_mask)) { /* already bound, break out */ break; } temp = *pblist; (*pblist) = (Binding *)safemalloc( sizeof(Binding)); (*pblist)->type = type; (*pblist)->Button_Key = i; STROKE_CODE((*pblist)->Stroke_Seq = (stroke) ? (void *)stripcpy((char *)stroke) : NULL); if (BIND_IS_KEY_BINDING(type) && key_name != NULL) { (*pblist)->key_name = stripcpy(key_name); } else { (*pblist)->key_name = NULL; } (*pblist)->Context = contexts; (*pblist)->Modifier = modifiers | add_modifiers; (*pblist)->Action = (action) ? stripcpy(action) : NULL; (*pblist)->Action2 = (action2) ? stripcpy(action2) : NULL; (*pblist)->windowName = windowName ? stripcpy(windowName) : NULL; (*pblist)->NextBinding = temp; bound_mask |= bind_mask; count++; } } } return count; } /* returns 1 if binding b1 is identical to binding b2 (except action) * returns 2 if b1 and b2 are identical except that b1 has a different window * name than b2 and both are not NULL * returns 0 otherwise */ static int compare_bindings(Binding *b1, Binding *b2) { if (b1->type != b2->type) { return 0; } if (b1->Context != b2->Context) { return 0; } if (b1->Modifier != b2->Modifier) { return 0; } if (b1->Button_Key != b2->Button_Key) { return 0; } /* definition: "global binding" => b->windowName == NULL * definition: "window-specific binding" => b->windowName != NULL */ if (b1->windowName && b2->windowName) { /* Both bindings are window-specific. The existing binding, b2, * is only replaced (by b1) if it applies to the same window */ if (strcmp(b1->windowName, b2->windowName) != 0) { return 2; } } else if (b1->windowName || b2->windowName) { /* 1 binding is window-specific, the other is global - no need * to replace this binding. */ return 0; } if (BIND_IS_KEY_BINDING(b1->type) || BIND_IS_MOUSE_BINDING(b1->type)) { return 1; } if (1 STROKE_CODE(&& BIND_IS_STROKE_BINDING(b1->type) && strcmp(b1->Stroke_Seq, b2->Stroke_Seq) == 0)) { return 1; } return 0; } /* * Does exactly the opposite of AddBinding: It removes the bindings that * AddBinding would have added to the *pblist_src and collects them in the * *pblist_dest. This can be used to remove a binding completely from the * list. The bindings still have to be freed. */ void CollectBindingList( Display *dpy, Binding **pblist_src, Binding **pblist_dest, Bool *ret_are_similar_bindings_left, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, int modifiers, int contexts, char *windowName) { Binding *tmplist = NULL; Binding *bold; Binding *oldprev; *ret_are_similar_bindings_left = False; /* generate a private list of bindings to be removed */ AddBinding( dpy, &tmplist, type, STROKE_ARG(stroke) button, keysym, NULL, modifiers, contexts, NULL, NULL, windowName); /* now find equivalent bindings in the given binding list and move * them to the new clist */ for (bold = *pblist_src, oldprev = NULL; bold != NULL; ) { Binding *btmp; Binding *bfound; bfound = NULL; for (btmp = tmplist; btmp != NULL && ( bfound == NULL || *ret_are_similar_bindings_left == False); btmp = btmp->NextBinding) { int rc; rc = compare_bindings(btmp, bold); if (rc == 1) { bfound = btmp; } else if (rc == 2) { *ret_are_similar_bindings_left = True; if (bfound != NULL) { break; } } } if (bfound != NULL) { Binding *next; /* move matched binding from src list to dest list */ UnlinkBinding(pblist_src, bold, oldprev); next = bold->NextBinding; bold->NextBinding = *pblist_dest; *pblist_dest = bold; /* oldprev is unchanged */ bold = next; } else { oldprev = bold; bold = bold->NextBinding; } } /* throw away the temporary list */ FreeBindingList(tmplist); return; } /* * bindingAppliesToWindow() * * The Key/Mouse/PointerKey syntax (optionally) allows a window name * (or class or resource) to be specified with the binding, denoting * which windows the binding can be invoked in. This function determines * if the binding actually applies to a window based on its * name/class/resource. */ static Bool does_binding_apply_to_window( Binding *binding, const XClassHint *win_class, const char *win_name) { /* If no window name is specified with the binding then that means * the binding applies to ALL windows. */ if (binding->windowName == NULL) { return True; } else if (win_class == NULL || win_name == NULL) { return False; } if (matchWildcards(binding->windowName, win_name) == True || matchWildcards(binding->windowName, win_class->res_name) == True || matchWildcards(binding->windowName, win_class->res_class) == True) { return True; } return False; } static Bool __compare_binding( Binding *b, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier, unsigned int used_modifiers, int Context, binding_t type, const XClassHint *win_class, const char *win_name) { if (b->type != type || !(b->Context & Context)) { return False; } if ((b->Modifier & used_modifiers) != modifier && b->Modifier != AnyModifier) { return False; } if (BIND_IS_MOUSE_BINDING(type) && (b->Button_Key != button_keycode && b->Button_Key != 0)) { return False; } else if (BIND_IS_KEY_BINDING(type) && b->Button_Key != button_keycode) { return False; } #ifdef HAVE_STROKE else if (BIND_IS_STROKE_BINDING(type) && ((strcmp(b->Stroke_Seq, stroke) != 0) || b->Button_Key != button_keycode)) { return False; } #endif if (!does_binding_apply_to_window(b, win_class, win_name)) { return False; } return True; } /* is_pass_through_action() - returns true if the action indicates that the * binding should be ignored by fvwm & passed through to the underlying * window. * Note: it is only meaningful to check for pass-thru actions on * window-specific bindings. */ Bool is_pass_through_action(const char *action) { /* action should never be NULL. */ return (strncmp(action, "--", 2) == 0); } /* Check if something is bound to a key or button press and return the action * to be executed or NULL if not. */ void *CheckBinding( Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier,unsigned int dead_modifiers, int Context, binding_t type, const XClassHint *win_class, const char *win_name) { Binding *b; unsigned int used_modifiers = ~dead_modifiers; void *action = NULL; modifier &= (used_modifiers & ALL_MODIFIERS); for (b = blist; b != NULL; b = b->NextBinding) { if (__compare_binding( b, STROKE_ARG(stroke) button_keycode, modifier, used_modifiers, Context, type, win_class, win_name) == True) { /* If this is a global binding, keep searching * in the hope of finding a window-specific binding. * If we don't find a win-specific binding, we use the * _first_ matching global binding we hit. */ if (action == NULL || b->windowName) { action = b->Action; if (b->windowName) { if (is_pass_through_action(action)) { action = NULL; } break; } } } } return action; } void *CheckTwoBindings( Bool *ret_is_second_binding, Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier,unsigned int dead_modifiers, int Context, binding_t type, const XClassHint *win_class, const char *win_name, int Context2, binding_t type2, const XClassHint *win_class2, const char *win_name2) { Binding *b; unsigned int used_modifiers = ~dead_modifiers; void *action = NULL; modifier &= (used_modifiers & ALL_MODIFIERS); for (b = blist; b != NULL; b = b->NextBinding) { if (__compare_binding( b, STROKE_ARG(stroke) button_keycode, modifier, used_modifiers, Context, type, win_class, win_name) == True) { if (action == NULL || b->windowName) { *ret_is_second_binding = False; action = b->Action; if (b->windowName) { if (is_pass_through_action(action)) action = NULL; break; } } } if (__compare_binding( b, STROKE_ARG(stroke) button_keycode, modifier, used_modifiers, Context2, type2, win_class2, win_name2) == True) { if (action == NULL || b->windowName) { *ret_is_second_binding = True; action = b->Action; if (b->windowName) { if (is_pass_through_action(action)) { action = NULL; } break; } } } } return action; } /* * GrabWindowKey - grab needed keys for the window for one binding * GrabAllWindowKeys - grab needed keys for the window for all bindings * in blist * GrabWindowButton - same for mouse buttons * GrabAllWindowButtons - same for mouse buttons * GrabAllWindowKeysAndButtons - both of the above * * Inputs: * w - the window to use (the frame window) * grab - 1 to grab, 0 to ungrab * binding - pointer to the bindinge to grab/ungrab * contexts - all context bits that shall receive bindings * dead_modifiers - modifiers to ignore for 'AnyModifier' * cursor - the mouse cursor to use when the pointer is on the * grabbed area (mouse bindings only) * */ void GrabWindowKey(Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Bool fGrab) { /* remove unnecessary bits from dead_modifiers */ dead_modifiers &= ~(binding->Modifier & dead_modifiers); dead_modifiers &= ALL_MODIFIERS; if((binding->Context & contexts) && BIND_IS_KEY_BINDING(binding->type)) { if (fGrab) { XGrabKey( dpy, binding->Button_Key, binding->Modifier, w, True, GrabModeAsync, GrabModeAsync); } else { XUngrabKey( dpy, binding->Button_Key, binding->Modifier, w); } if(binding->Modifier != AnyModifier && dead_modifiers != 0) { register unsigned int mods; register unsigned int max = dead_modifiers; register unsigned int living_modifiers = ~dead_modifiers; /* handle all bindings for the dead modifiers */ for (mods = 1; mods <= max; mods++) { /* Since mods starts with 1 we don't need to * test if mods contains a dead modifier. * Otherwise both, dead and living modifiers * would be zero ==> mods == 0 */ if (mods & living_modifiers) { continue; } if (fGrab) { XGrabKey( dpy, binding->Button_Key, mods|binding->Modifier, w, True, GrabModeAsync, GrabModeAsync); } else { XUngrabKey( dpy, binding->Button_Key, mods|binding->Modifier, w); } } } if (!is_grabbing_everything) { XSync(dpy, 0); } } return; } void GrabAllWindowKeys( Display *dpy, Window w, Binding *blist, unsigned int contexts, unsigned int dead_modifiers, Bool fGrab) { MyXGrabServer(dpy); is_grabbing_everything = True; for ( ; blist != NULL; blist = blist->NextBinding) { GrabWindowKey(dpy, w, blist, contexts, dead_modifiers, fGrab); } is_grabbing_everything = False; MyXUngrabServer(dpy); return; } void GrabWindowButton( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab) { if (binding->Action == NULL) { return; } dead_modifiers &= ~(binding->Modifier & dead_modifiers); /* dje */ dead_modifiers &= ALL_MODIFIERS; if ((binding->Context & contexts) && ((BIND_IS_MOUSE_BINDING(binding->type) || (BIND_IS_STROKE_BINDING(binding->type) && binding->Button_Key !=0)))) { int bmin = 1; int bmax = NUMBER_OF_EXTENDED_MOUSE_BUTTONS; int button; if(binding->Button_Key >0) { bmin = bmax = binding->Button_Key; } for (button = bmin; button <= bmax; button++) { if (fGrab) { XGrabButton( dpy, button, binding->Modifier, w, True, ButtonPressMask | ButtonReleaseMask, GrabModeSync, GrabModeAsync, None, cursor); } else { XUngrabButton( dpy, button, binding->Modifier, w); } if (binding->Modifier != AnyModifier && dead_modifiers != 0) { register unsigned int mods; register unsigned int max = dead_modifiers; register unsigned int living_modifiers = ~dead_modifiers; /* handle all bindings for the dead modifiers */ for (mods = 1; mods <= max; mods++) { /* Since mods starts with 1 we don't * need to test if mods contains a * dead modifier. Otherwise both, dead * and living modifiers would be zero * ==> mods == 0 */ if (mods & living_modifiers) { continue; } if (fGrab) { XGrabButton( dpy, button, mods|binding->Modifier, w, True, ButtonPressMask | ButtonReleaseMask, GrabModeSync, GrabModeAsync, None, cursor); } else { XUngrabButton( dpy, button, mods|binding->Modifier, w); } } } if (!is_grabbing_everything) { XSync(dpy, 0); } } } return; } void GrabAllWindowButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab) { MyXGrabServer(dpy); is_grabbing_everything = True; for ( ; blist != NULL; blist = blist->NextBinding) { GrabWindowButton(dpy, w, blist, contexts, dead_modifiers, cursor, fGrab); } is_grabbing_everything = False; MyXUngrabServer(dpy); return; } void GrabAllWindowKeysAndButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab) { MyXGrabServer(dpy); is_grabbing_everything = True; for ( ; blist != NULL; blist = blist->NextBinding) { if (blist->Context & contexts) { if (BIND_IS_MOUSE_BINDING(blist->type) || BIND_IS_STROKE_BINDING(blist->type)) { GrabWindowButton( dpy, w, blist, contexts, dead_modifiers, cursor, fGrab); } else if (BIND_IS_KEY_BINDING(blist->type)) { GrabWindowKey( dpy, w, blist, contexts, dead_modifiers, fGrab); } } } is_grabbing_everything = False; MyXUngrabServer(dpy); return; } void GrabWindowKeyOrButton( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab) { if (BIND_IS_MOUSE_BINDING(binding->type) || BIND_IS_STROKE_BINDING(binding->type)) { GrabWindowButton( dpy, w, binding, contexts, dead_modifiers, cursor, fGrab); } else if (BIND_IS_KEY_BINDING(binding->type)) { GrabWindowKey( dpy, w, binding, contexts, dead_modifiers, fGrab); } return; } /* * * Like XStringToKeysym, but allows some typos and does some additional * error checking. * */ KeySym FvwmStringToKeysym(Display *dpy, char *key) { KeySym keysym; char *s; if (!isalpha(*key)) { keysym = XStringToKeysym(key); } else { s = alloca(strlen(key) + 1); strcpy(s, key); /* always prefer the lower case spelling if it exists */ *s = tolower(*s); keysym = XStringToKeysym(s); if (keysym == NoSymbol) { *s = toupper(*s); keysym = XStringToKeysym(s); } } if (keysym == NoSymbol || XKeysymToKeycode(dpy, keysym) == 0) { return 0; } return keysym; } fvwm-2.6.7/libs/Cursor.h0000644000175700017570000000005712773467232012042 00000000000000int fvwmCursorNameToIndex (char *cursor_name); fvwm-2.6.7/libs/PictureImageLoader.c0000644000175700017570000005365113001406607014255 00000000000000/* -*-c-*- */ /* Copyright (C) 1993, Robert Nation * Copyright (C) 1999 Carsten Haitzler and various contributors (imlib2) * Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* * * The png loader and PImageRGBtoPixel are from imlib2. The code is from raster * (Carsten Haitzler) * */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include #include #include #include "System.h" #include "Strings.h" #include "Picture.h" #include "PictureUtils.h" #include "Graphics.h" #include "ColorUtils.h" #include "Fxpm.h" #include "Fpng.h" #include "Fsvg.h" #include "FRenderInit.h" #include "Fcursor.h" #include "FImage.h" /* ---------------------------- local definitions -------------------------- */ #define FIMAGE_CMD_ARGS \ Display *dpy, char *path, CARD32 **argb_data, int *width, int *height #define FIMAGE_PASS_ARGS \ dpy, path, argb_data, width, height typedef struct PImageLoader { char *extension; #ifdef __STDC__ int (*func)(FIMAGE_CMD_ARGS); #else int (*func)(); #endif } PImageLoader; /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ static Bool PImageLoadSvg(FIMAGE_CMD_ARGS); static Bool PImageLoadPng(FIMAGE_CMD_ARGS); static Bool PImageLoadXpm(FIMAGE_CMD_ARGS); /* ---------------------------- local variables ---------------------------- */ PImageLoader Loaders[] = { { "xpm", PImageLoadXpm }, { "svg", PImageLoadSvg }, { "png", PImageLoadPng }, {NULL,0} }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static Bool PImageLoadArgbDataFromFile(FIMAGE_CMD_ARGS) { int done = 0, i = 0, tried = -1; char *ext = NULL; if (path == NULL) return False; if (strlen(path) > 3) { ext = path + strlen(path) - 3; } /* first try to load by extension */ while (!done && ext != NULL && Loaders[i].extension != NULL) { if (StrEquals(Loaders[i].extension, ext)) { if (Loaders[i].func(FIMAGE_PASS_ARGS)) { return True; } tried = i; done = 1; } i++; } i = 0; while (Loaders[i].extension != NULL) { if (i != tried && Loaders[i].func(FIMAGE_PASS_ARGS)) { return True; } i++; } return False; } /* * * svg loader * */ static Bool PImageLoadSvg(FIMAGE_CMD_ARGS) { char *allocated_path; char *render_opts; FRsvgHandle *rsvg; FRsvgDimensionData dim; CARD32 *data; Fcairo_surface_t *surface; Fcairo_t *cr; int i; int j; int b1; int b2; int w = 0; int h = 0; int dw = 0; int dh = 0; int w_sgn = 1; int h_sgn = 1; double angle = 0; double w_scale = 1; double h_scale = 1; double buf; Bool transpose = False; unsigned char a_value; unsigned char r_value; unsigned char g_value; unsigned char b_value; if (!USE_SVG) { fprintf(stderr, "[PImageLoadSvg]: Tried to load SVG file " "when FVWM has not been compiled with SVG support.\n"); return False; } /* Separate rendering options from path */ render_opts = path = allocated_path = safestrdup(path); if (*path == ':' && (path = strchr(path + 1, ':'))) { *path = 0; path ++; render_opts ++; } else { render_opts = ""; } if (!(rsvg = Frsvg_handle_new_from_file(path, NULL))) { free(allocated_path); return False; } /* Parsing of rendering options */ while (*render_opts) { i = 0; switch (*render_opts) { case '!': transpose = !transpose; break; case '*': if (sscanf(render_opts, "*%lf%n", &buf, &i) >= 1) { switch (render_opts[i]) { case 'x': w_scale *= buf; i ++; break; case 'y': h_scale *= buf; i ++; break; default: w_scale *= buf; h_scale *= buf; } } break; case '/': if (sscanf(render_opts, "/%lf%n", &buf, &i) >= 1 && buf) { switch (render_opts[i]) { case 'x': w_scale /= buf; i ++; break; case 'y': h_scale /= buf; i ++; break; default: w_scale /= buf; h_scale /= buf; } } break; case '@': if (sscanf(render_opts, "@%lf%n", &buf, &i) >= 1) { angle += buf; } break; default: j = 0; if ( sscanf( render_opts, "%dx%n%d%n", &b1, &j, &b2, &i) >= 2 && i > j) { w = b1; h = b2; if (w < 0 || (!w && render_opts[0] == '-')) { w *= (w_sgn = -1); } if (h < 0 || (!h && render_opts[j] == '-')) { h *= (h_sgn = -1); } } else if ( sscanf(render_opts, "%d%d%n", &b1, &b2, &i) >= 2) { dw += b1; dh += b2; } } render_opts += i ? i : 1; } free(allocated_path); /* Keep the original aspect ratio when either w or h is 0 */ Frsvg_handle_get_dimensions(rsvg, &dim); if (!w && !h) { w = dim.width; h = dim.height; } else if (!w) { w = h * dim.em / dim.ex; } else if (!h) { h = w * dim.ex / dim.em; } w_scale *= w; h_scale *= h; if (transpose) { b1 = w; w = h; h = b1; b1 = w_sgn; w_sgn = - h_sgn; h_sgn = b1; b1 = dw; dw = - dh; dh = b1; angle += 90; } data = (CARD32 *)safemalloc(w * h * sizeof(CARD32)); memset(data, 0, w * h * sizeof(CARD32)); surface = Fcairo_image_surface_create_for_data((unsigned char *)data, FCAIRO_FORMAT_ARGB32, w, h, w * sizeof(CARD32)); if (Fcairo_surface_status(surface) != FCAIRO_STATUS_SUCCESS) { Fg_object_unref(FG_OBJECT(rsvg)); free(data); if (surface) { Fcairo_surface_destroy(surface); } return False; } cr = Fcairo_create(surface); Fcairo_surface_destroy(surface); if (Fcairo_status(cr) != FCAIRO_STATUS_SUCCESS) { Fg_object_unref(FG_OBJECT(rsvg)); free(data); if (cr) { Fcairo_destroy(cr); } return False; } /* Affine transformations ... * mirroring, rotation, scaling and translation */ Fcairo_translate(cr, .5 * w, .5 * h); Fcairo_scale(cr, w_sgn, h_sgn); Fcairo_translate(cr, dw, dh); Fcairo_rotate(cr, angle * M_PI / 180); Fcairo_scale(cr, w_scale, h_scale); Fcairo_translate(cr, -.5, -.5); Fcairo_scale(cr, 1 / dim.em, 1 / dim.ex); Frsvg_handle_render_cairo(rsvg, cr); Fg_object_unref(FG_OBJECT(rsvg)); Fcairo_destroy(cr); /* Cairo gave us alpha prescaled RGB values, hence we need * to rescale them for PImageCreatePixmapFromArgbData() */ for (i = 0; i < w * h; i++) { if ((a_value = (data[i] >> 030) & 0xff)) { r_value = ((data[i] >> 020) & 0xff) * 0xff / a_value; g_value = ((data[i] >> 010) & 0xff) * 0xff / a_value; b_value = (data[i] & 0xff) * 0xff / a_value; data[i] = (a_value << 030) | (r_value << 020) | (g_value << 010) | b_value; } } *width = w; *height = h; *argb_data = data; return True; } /* * * png loader * */ static Bool PImageLoadPng(FIMAGE_CMD_ARGS) { Fpng_uint_32 w32, h32; Fpng_structp Fpng_ptr = NULL; Fpng_infop Finfo_ptr = NULL; CARD32 *data; int w, h; char hasa = 0, hasg = 0; FILE *f; int bit_depth; int color_type; int interlace_type; unsigned char buf[FPNG_BYTES_TO_CHECK]; unsigned char **lines; int i; if (!PngSupport) { /* suppress compiler warning */ bit_depth = 0; fprintf(stderr, "[PImageLoadPng]: Tried to load PNG file " "when FVWM has not been compiled with PNG support.\n"); return False; } if (!(f = fopen(path, "rb"))) { return False; } { int n; n = fread(buf, 1, FPNG_BYTES_TO_CHECK, f); (void)n; } if (!Fpng_check_sig(buf, FPNG_BYTES_TO_CHECK)) { fclose(f); return False; } rewind(f); Fpng_ptr = Fpng_create_read_struct(FPNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!Fpng_ptr) { fclose(f); return False; } Finfo_ptr = Fpng_create_info_struct(Fpng_ptr); if (!Finfo_ptr) { Fpng_destroy_read_struct(&Fpng_ptr, NULL, NULL); fclose(f); return False; } #if 0 if (setjmp(Fpng_ptr->jmpbuf)) { Fpng_destroy_read_struct(&Fpng_ptr, &Finfo_ptr, NULL); fclose(f); return False; } #endif Fpng_init_io(Fpng_ptr, f); Fpng_read_info(Fpng_ptr, Finfo_ptr); Fpng_get_IHDR( Fpng_ptr, Finfo_ptr, (Fpng_uint_32 *) (&w32), (Fpng_uint_32 *) (&h32), &bit_depth, &color_type, &interlace_type, NULL, NULL); interlace_type = 0; /* not used */ *width = w = (int) w32; *height = h = (int) h32; if (color_type == FPNG_COLOR_TYPE_PALETTE) { Fpng_set_expand(Fpng_ptr); } /* TA: XXX: (2011-02-14) -- Happy Valentines Day. * * png_get_color_type() defined in libpng 1.5 now hides a data member * to a struct: * * Finfo_ptr->color_type * * I'm not going to wrap this up in more #ifdef madness, but should * this fail to build on much older libpng versions which we support * (pre 1.3), then I might have to. */ if (png_get_color_type(Fpng_ptr, Finfo_ptr) == FPNG_COLOR_TYPE_RGB_ALPHA) { hasa = 1; } if (png_get_color_type(Fpng_ptr, Finfo_ptr) == FPNG_COLOR_TYPE_GRAY_ALPHA) { hasa = 1; hasg = 1; } if (png_get_color_type(Fpng_ptr, Finfo_ptr) == FPNG_COLOR_TYPE_GRAY) { hasg = 1; } if (hasa) Fpng_set_expand(Fpng_ptr); /* we want ARGB */ /* note form raster: * thanks to mustapha for helping debug this on PPC Linux remotely by * sending across screenshots all the time and me figuring out form them * what the hell was up with the colors * now png loading should work on big endian machines nicely */ #ifdef WORDS_BIGENDIAN Fpng_set_swap_alpha(Fpng_ptr); Fpng_set_filler(Fpng_ptr, 0xff, FPNG_FILLER_BEFORE); #else Fpng_set_bgr(Fpng_ptr); Fpng_set_filler(Fpng_ptr, 0xff, FPNG_FILLER_AFTER); #endif /* 16bit color -> 8bit color */ Fpng_set_strip_16(Fpng_ptr); /* pack all pixels to byte boundaires */ Fpng_set_packing(Fpng_ptr); if (Fpng_get_valid(Fpng_ptr, Finfo_ptr, FPNG_INFO_tRNS)) { Fpng_set_expand(Fpng_ptr); } data = (CARD32 *)safemalloc(w * h * sizeof(CARD32)); lines = (unsigned char **) safemalloc(h * sizeof(unsigned char *)); if (hasg) { Fpng_set_gray_to_rgb(Fpng_ptr); if (Fpng_get_bit_depth(Fpng_ptr, Finfo_ptr) < 8) { Fpng_set_gray_1_2_4_to_8(Fpng_ptr); } } for (i = 0; i < h; i++) { lines[i] = (unsigned char *)data + (i * w * sizeof(CARD32)); } Fpng_read_image(Fpng_ptr, lines); Fpng_read_end(Fpng_ptr, Finfo_ptr); Fpng_destroy_read_struct(&Fpng_ptr, &Finfo_ptr, (png_infopp) NULL); fclose(f); free(lines); *argb_data = data; return True; } /* * * xpm loader * */ static Bool PImageLoadXpm(FIMAGE_CMD_ARGS) { FxpmImage xpm_im; FxpmColor *xpm_color; XColor color; CARD32 *colors; CARD32 *data; char *visual_color; int i; int w; int h; int rc; #ifdef HAVE_SIGACTION struct sigaction defaultHandler; struct sigaction originalHandler; #else RETSIGTYPE (*originalHandler)(int); #endif if (!XpmSupport) { fprintf(stderr, "[PImageLoadXpm]: Tried to load XPM file " "when FVWM has not been compiled with XPm Support.\n"); return False; } memset(&xpm_im, 0, sizeof(FxpmImage)); #ifdef HAVE_SIGACTION sigemptyset(&defaultHandler.sa_mask); defaultHandler.sa_flags = 0; defaultHandler.sa_handler = SIG_DFL; sigaction(SIGCHLD, &defaultHandler, &originalHandler); #else originalHandler = signal(SIGCHLD, SIG_DFL); #endif rc = FxpmReadFileToXpmImage(path, &xpm_im, NULL); #ifdef HAVE_SIGACTION sigaction(SIGCHLD, &originalHandler, NULL); #else signal(SIGCHLD, originalHandler); #endif if (rc != FxpmSuccess) { return False; } if (xpm_im.ncolors <= 0) { FxpmFreeXpmImage(&xpm_im); return False; } colors = (CARD32 *)safemalloc(xpm_im.ncolors * sizeof(CARD32)); for (i=0; i < xpm_im.ncolors; i++) { xpm_color = &xpm_im.colorTable[i]; if (xpm_color->c_color) { visual_color = xpm_color->c_color; } else if (xpm_color->g_color) { visual_color = xpm_color->g_color; } else if (xpm_color->g4_color) { visual_color = xpm_color->g4_color; } else { visual_color = xpm_color->m_color; } if (XParseColor(dpy, Pcmap, visual_color, &color)) { colors[i] = 0xff000000 | ((color.red << 8) & 0xff0000) | ((color.green ) & 0xff00) | ((color.blue >> 8) & 0xff); } else { colors[i] = 0; } } *width = w = xpm_im.width; *height = h = xpm_im.height; data = (CARD32 *)safemalloc(w * h * sizeof(CARD32)); for (i=0; i < w * h; i++) { data[i] = colors[xpm_im.data[i]]; } free(colors); *argb_data = data; return True; } /* * * copy image to server * */ static Pixmap PImageCreatePixmapFromFImage(Display *dpy, Window win, FImage *fimage) { GC gc; Pixmap pixmap; int w; int h; int depth; w = fimage->im->width; h = fimage->im->height; depth = fimage->im->depth; pixmap = XCreatePixmap(dpy, win, w, h, depth); if (depth == Pdepth) { gc = PictureDefaultGC(dpy, win); } else { gc = fvwmlib_XCreateGC(dpy, pixmap, 0, NULL); } FPutFImage(dpy, pixmap, gc, fimage, 0, 0, 0, 0, w, h); if (depth != Pdepth) { XFreeGC(dpy, gc); } return pixmap; } /* ---------------------------- interface functions ------------------------ */ /* * * argb data to pixmaps * */ Bool PImageCreatePixmapFromArgbData( Display *dpy, Window win, CARD32 *data, int start, int width, int height, Pixmap *pixmap, Pixmap *mask, Pixmap *alpha, int *nalloc_pixels, Pixel **alloc_pixels, int *no_limit, FvwmPictureAttributes fpa) { FImage *fim; FImage *m_fim = NULL; FImage *a_fim = NULL; XColor c; int i; int j; int a; PictureImageColorAllocator *pica = NULL; int alpha_limit = PICTURE_ALPHA_LIMIT; int alpha_depth = FRenderGetAlphaDepth(); Bool have_mask = False; Bool have_alpha = False; fim = FCreateFImage( dpy, Pvisual, (fpa.mask & FPAM_MONOCHROME) ? 1 : Pdepth, ZPixmap, width, height); if (!fim) { return False; } if (mask) { m_fim = FCreateFImage( dpy, Pvisual, 1, ZPixmap, width, height); } if (alpha && !(fpa.mask & FPAM_NO_ALPHA) && alpha_depth) { alpha_limit = 0; a_fim = FCreateFImage( dpy, Pvisual, alpha_depth, ZPixmap, width, height); } if (!(fpa.mask & FPAM_MONOCHROME)) { c.flags = DoRed | DoGreen | DoBlue; pica = PictureOpenImageColorAllocator( dpy, Pcmap, width, height, !!(fpa.mask & FPAM_NO_COLOR_LIMIT), !!(fpa.mask & FPAM_NO_ALLOC_PIXELS), !!(fpa.mask & FPAM_DITHER), True); } data += start; for (j = 0; j < height; j++) { for (i = 0; i < width; i++, data++) { a = (*data >> 030) & 0xff; if (a > alpha_limit) { c.red = (*data >> 16) & 0xff; c.green = (*data >> 8) & 0xff; c.blue = (*data ) & 0xff; if (pica) { PictureAllocColorImage( dpy, pica, &c, i, j); XPutPixel(fim->im, i, j, c.pixel); } /* Brightness threshold */ else if ((0x99 * c.red + 0x12D * c.green + 0x3A * c.blue) >> 16) { XPutPixel(fim->im, i, j, 1); } else { XPutPixel(fim->im, i, j, 0); } if (m_fim) { XPutPixel(m_fim->im, i, j, 1); } } else if (m_fim != NULL) { XPutPixel(m_fim->im, i, j, 0); have_mask = True; } if (a_fim != NULL) { XPutPixel(a_fim->im, i, j, a); if (a > 0 && a < 0xff) { have_alpha = True; } } } } if (pica) { PictureCloseImageColorAllocator( dpy, pica, nalloc_pixels, alloc_pixels, no_limit); } *pixmap = PImageCreatePixmapFromFImage(dpy, win, fim); if (have_alpha) { *alpha = PImageCreatePixmapFromFImage(dpy, win, a_fim); } else if (have_mask) { *mask = PImageCreatePixmapFromFImage(dpy, win, m_fim); } FDestroyFImage(dpy, fim); if (m_fim) { FDestroyFImage(dpy, m_fim); } if (a_fim) { FDestroyFImage(dpy, a_fim); } return True; } /* * * the images loaders * */ Bool PImageLoadPixmapFromFile( Display *dpy, Window win, char *path, Pixmap *pixmap, Pixmap *mask, Pixmap *alpha, int *width, int *height, int *depth, int *nalloc_pixels, Pixel **alloc_pixels, int *no_limit, FvwmPictureAttributes fpa) { CARD32 *data; if (PImageLoadArgbDataFromFile(dpy, path, &data, width, height)) { *depth = (fpa.mask & FPAM_MONOCHROME) ? 1 : Pdepth; if (PImageCreatePixmapFromArgbData( dpy, win, data, 0, *width, *height, pixmap, mask, alpha, nalloc_pixels, alloc_pixels, no_limit, fpa)) { free(data); return True; } free(data); } /* Bitmap fallback */ else if ( XReadBitmapFile( dpy, win, path, (unsigned int *)width, (unsigned int *)height, pixmap, NULL, NULL) == BitmapSuccess) { *depth = 1; *mask = None; return True; } pixmap = None; mask = None; alpha = None; *width = *height = *depth = 0; if (nalloc_pixels != NULL) { *nalloc_pixels = 0; } if (alloc_pixels != NULL) { *alloc_pixels = NULL; } return False; } FvwmPicture *PImageLoadFvwmPictureFromFile( Display *dpy, Window win, char *path, FvwmPictureAttributes fpa) { FvwmPicture *p; Pixmap pixmap = None; Pixmap mask = None; Pixmap alpha = None; int width = 0, height = 0; int depth = 0, no_limit; int nalloc_pixels = 0; Pixel *alloc_pixels = NULL; char *real_path; /* Remove any svg rendering options from real_path */ if (USE_SVG && *path == ':' && (real_path = strchr(path + 1, ':'))) { real_path ++; } else { real_path = path; } if (!PImageLoadPixmapFromFile( dpy, win, path, &pixmap, &mask, &alpha, &width, &height, &depth, &nalloc_pixels, &alloc_pixels, &no_limit, fpa)) { return NULL; } p = (FvwmPicture*)safemalloc(sizeof(FvwmPicture)); memset(p, 0, sizeof(FvwmPicture)); p->count = 1; p->name = path; p->fpa_mask = fpa.mask; p->next = NULL; setFileStamp(&p->stamp, real_path); p->picture = pixmap; p->mask = mask; p->alpha = alpha; p->width = width; p->height = height; p->depth = depth; p->nalloc_pixels = nalloc_pixels; p->alloc_pixels = alloc_pixels; p->no_limit = no_limit; return p; } Cursor PImageLoadCursorFromFile( Display *dpy, Window win, char *path, int x_hot, int y_hot) { Cursor cursor = 0; CARD32 *data; int width; int height; int i; FcursorImages *fcis; FcursorImage *fci; /* First try the Xcursor loader (animated cursors) */ if ((fcis = FcursorFilenameLoadImages( path, FcursorGetDefaultSize(dpy)))) { for (i = 0; i < fcis->nimage; i++) { if (x_hot < fcis->images[i]->width && x_hot >= 0 && y_hot < fcis->images[i]->height && y_hot >= 0) { fcis->images[i]->xhot = x_hot; fcis->images[i]->yhot = y_hot; } } cursor = FcursorImagesLoadCursor(dpy, fcis); FcursorImagesDestroy(fcis); } /* Get cursor data from the regular image loader */ else if (PImageLoadArgbDataFromFile(dpy, path, &data, &width, &height)) { Pixmap src; Pixmap msk = None; FvwmPictureAttributes fpa; fpa.mask = FPAM_NO_ALPHA | FPAM_MONOCHROME; /* Adjust the hot-spot if necessary */ if ( x_hot < 0 || x_hot >= width || y_hot < 0 || y_hot >= height) { FxpmImage xpm_im; FxpmInfo xpm_info; memset(&xpm_im, 0, sizeof(FxpmImage)); memset(&xpm_info, 0, sizeof(FxpmInfo)); if (FxpmReadFileToXpmImage(path, &xpm_im, &xpm_info) == FxpmSuccess) { if (xpm_info.valuemask & FxpmHotspot) { x_hot = xpm_info.x_hotspot; y_hot = xpm_info.y_hotspot; } FxpmFreeXpmImage(&xpm_im); FxpmFreeXpmInfo(&xpm_info); } if (x_hot < 0 || x_hot >= width) { x_hot = width / 2; } if (y_hot < 0 || y_hot >= height) { y_hot = height / 2; } } /* Use the Xcursor library to create the argb cursor */ if ((fci = FcursorImageCreate(width, height))) { unsigned char alpha; unsigned char red; unsigned char green; unsigned char blue; /* Xcursor expects alpha prescaled RGB values */ for (i = 0; i < width * height; i++) { alpha = ((data[i] >> 24) & 0xff); red = ((data[i] >> 16) & 0xff) * alpha/0xff; green = ((data[i] >> 8) & 0xff) * alpha/0xff; blue = ((data[i] ) & 0xff) * alpha/0xff; data[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; } fci->xhot = x_hot; fci->yhot = y_hot; fci->delay = 0; fci->pixels = (FcursorPixel *)data; cursor = FcursorImageLoadCursor(dpy, fci); FcursorImageDestroy(fci); } /* Create monochrome cursor from argb data */ else if (PImageCreatePixmapFromArgbData( dpy, win, data, 0, width, height, &src, &msk, 0, 0, 0, 0, fpa)) { XColor c[2]; c[0].pixel = GetColor(DEFAULT_CURSOR_FORE_COLOR); c[1].pixel = GetColor(DEFAULT_CURSOR_BACK_COLOR); XQueryColors(dpy, Pcmap, c, 2); cursor = XCreatePixmapCursor( dpy, src, msk, &(c[0]), &(c[1]), x_hot, y_hot); XFreePixmap(dpy, src); XFreePixmap(dpy, msk); } free(data); } return cursor; } /* FIXME: Use color limit */ Bool PImageLoadPixmapFromXpmData( Display *dpy, Window win, int color_limit, char **data, Pixmap *pixmap, Pixmap *mask, int *width, int *height, int *depth) { FxpmAttributes xpm_attributes; if (!XpmSupport) { return False; } xpm_attributes.valuemask = FxpmCloseness | FxpmExtensions | FxpmVisual | FxpmColormap | FxpmDepth; xpm_attributes.closeness = 40000; xpm_attributes.visual = Pvisual; xpm_attributes.colormap = Pcmap; xpm_attributes.depth = Pdepth; /* suppress compiler warning if xpm library is not compiled in */ xpm_attributes.width = 0; xpm_attributes.height = 0; if ( FxpmCreatePixmapFromData( dpy, win, data, pixmap, mask, &xpm_attributes) != FxpmSuccess) { return False; } *width = xpm_attributes.width; *height = xpm_attributes.height; *depth = Pdepth; return True; } fvwm-2.6.7/libs/Rectangles.h0000644000175700017570000000252412773467232012655 00000000000000/* -*-c-*- */ /* * Convinence functions for manipulating rectangles, segments, regions ...etc. */ #ifndef FRECTANGLES_H #define FRECTANGLES_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* If the two rectangles [x1, y1, w1, h2] and [x2, x2, w2, h2] have a * non emtpy interstection this function return True and the * XRectangle *r is set to the intersection (if not NULL). If the two * rectangles have an emty intersection False is returned and r is not * modified. */ Bool frect_get_intersection( int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, XRectangle *r); /* as above but the input are XRectangles */ Bool frect_get_rect_intersection( XRectangle a, XRectangle b, XRectangle *r); /* as above for two segments */ Bool frect_get_seg_intersection( int x1, int w1, int x2, int w2, int *x, int *w); #endif fvwm-2.6.7/libs/vpacket.h0000644000175700017570000000452312773467232012224 00000000000000/* -*-c-*- */ #ifndef _VPACKET_ #define _VPACKET_ #include "fvwm/window_flags.h" /* All new-style module packets (i.e., those that are not simply arrays of longs, as used by the older modules) should have a structure definition in this file. */ /* The M_CONFIGURE_WINDOW packet. This is the same packet as the M_ADD_WINDOW packet, the only difference being the type. */ /* RBW- typedef struct config_win_packet */ typedef struct ConfigWinPacket { /*** Alignment notes ***/ /*** Note that this packet format will break on future 128 bit *** platforms. ***/ /*** Put long, Window, and pointers here ***/ unsigned long w; /* Window */ unsigned long frame; /* Window */ unsigned long *fvwmwin; signed long frame_x; signed long frame_y; unsigned long frame_width; unsigned long frame_height; unsigned long desk; /* Temp word for alignment - old flags used to be here. - remove before next release. RBW - 05/01/2000 - layer has usurped this slot. unsigned long dummy; */ unsigned long layer; unsigned long hints_base_width; unsigned long hints_base_height; unsigned long hints_width_inc; unsigned long hints_height_inc; unsigned long orig_hints_width_inc; unsigned long orig_hints_height_inc; unsigned long hints_min_width; unsigned long hints_min_height; unsigned long hints_max_width; unsigned long hints_max_height; unsigned long icon_w; /* Window */ unsigned long icon_pixmap_w; /* Window */ unsigned long hints_win_gravity; unsigned long TextPixel; unsigned long BackPixel; /* Everything below this is post-GSFR */ unsigned long ewmh_hint_layer; unsigned long ewmh_hint_desktop; unsigned long ewmh_window_type; /*** Put int here, fill with dummies to a multiple of 2 ***/ /*** Put short here, fill with dummies to a multiple of 4 ***/ unsigned short title_height; unsigned short border_width; unsigned short short_dummy_3; unsigned short short_dummy_4; /*** Put structures here ***/ window_flags flags; action_flags allowed_actions; } ConfigWinPacket; typedef struct MiniIconPacket { Window w; Window frame; FvwmWindow *fvwmwin; unsigned long width; unsigned long height; unsigned long depth; Pixmap picture; Pixmap mask; Pixmap alpha; char name[1]; } MiniIconPacket; #endif /* _VPACKET_ */ fvwm-2.6.7/libs/fvwmrect.h0000644000175700017570000000267012773467232012425 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Dominik Vogt */ #ifndef FVWMRECT_H #define FVWMRECT_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef struct { int x; int y; int width; int height; } rectangle; typedef struct { int x; int y; } position; typedef struct { int width; int height; } size_rect; typedef struct { size_rect top_left; size_rect bottom_right; size_rect total_size; } size_borders; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* Returns 1 if the given rectangles intersect and 0 otherwise */ int fvwmrect_do_rectangles_intersect(rectangle *r, rectangle *s); /* Subtracts the values in s2_ from the ones in s1_g and stores the result in * diff_g. */ void fvwmrect_subtract_rectangles( rectangle *rdiff, rectangle *r1, rectangle *r2); /* Returns 1 is the rectangles are identical and 0 if not */ int fvwmrect_rectangles_equal( rectangle *r1, rectangle *r2); int fvwmrect_move_into_rectangle( rectangle *move_rec, rectangle *target_rec); int fvwmrect_intersect_xrectangles( XRectangle *r1, XRectangle *r2); #endif /* FVWMRECT_H */ fvwm-2.6.7/libs/FRenderInit.h0000644000175700017570000000064012773467232012734 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* ---------------------------- included header files ---------------------- */ #ifndef F_RENDER_INIT_H #define F_RENDER_INIT_H void FRenderInit(Display *dpy); int FRenderGetAlphaDepth(void); int FRenderGetErrorCodeBase(void); int FRenderGetMajorOpCode(void); Bool FRenderGetErrorText(int code, char *msg); Bool FRenderGetExtensionSupported(void); #endif fvwm-2.6.7/libs/Fxpm.h0000644000175700017570000001250412773467232011477 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef FXPM_H #define FXPM_H #include "PictureBase.h" #if XpmSupport #include #endif /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ #if XpmSupport typedef XpmColorSymbol FxpmColorSymbol; typedef XpmExtension FxpmExtension; typedef XpmColor FxpmColor; typedef XpmAttributes FxpmAttributes; typedef XpmImage FxpmImage; typedef XpmInfo FxpmInfo; #else typedef struct { char *name; char *value; Pixel pixel; } FxpmColorSymbol; typedef struct { char *name; unsigned int nlines; char **lines; } FxpmExtension; typedef struct { char *string; char *symbolic; char *m_color; char *g4_color; char *g_color; char *c_color; } FxpmColor; typedef int (*FxpmAllocColorFunc)( #ifdef __STDC__ Display*,Colormap,char*,XColor*,void* #endif ); typedef int (*FxpmFreeColorsFunc)( #ifdef __STDC__ Display*,Colormap,Pixel*,int,void* #endif ); typedef struct { unsigned long valuemask; Visual *visual; Colormap colormap; unsigned int depth; unsigned int width; unsigned int height; unsigned int x_hotspot; unsigned int y_hotspot; unsigned int cpp; Pixel *pixels; unsigned int npixels; FxpmColorSymbol *colorsymbols; unsigned int numsymbols; char *rgb_fname; unsigned int nextensions; FxpmExtension *extensions; unsigned int ncolors; FxpmColor *colorTable; char *hints_cmt; char *colors_cmt; char *pixels_cmt; unsigned int mask_pixel; Bool exactColors; unsigned int closeness; unsigned int red_closeness; unsigned int green_closeness; unsigned int blue_closeness; int color_key; Pixel *alloc_pixels; int nalloc_pixels; Bool alloc_close_colors; int bitmap_format; FxpmAllocColorFunc alloc_color; FxpmFreeColorsFunc free_colors; void *color_closure; } FxpmAttributes; typedef struct { unsigned int width; unsigned int height; unsigned int cpp; unsigned int ncolors; FxpmColor *colorTable; unsigned int *data; } FxpmImage; typedef struct { unsigned long valuemask; unsigned int x_hotspot; unsigned int y_hotspot; } FxpmInfo; #endif /* ---------------------------- global definitions ------------------------- */ #if XpmSupport #define FxpmReturnPixels XpmReturnPixels #define FxpmSize XpmSize #define FxpmReturnAllocPixels XpmReturnAllocPixels #define FxpmCloseness XpmCloseness #define FxpmVisual XpmVisual #define FxpmColormap XpmColormap #define FxpmDepth XpmDepth #define FxpmHotspot XpmHotspot #define FxpmExtensions XpmExtensions #define FxpmCharsPerPixel XpmCharsPerPixel #define FxpmColorSymbols XpmColorSymbols #define FxpmRgbFilename XpmRgbFilename #define FxpmInfos XpmInfos #define FxpmReturnInfos XpmReturnInfos #define FxpmReturnExtensions XpmReturnExtensions #define FxpmRGBCloseness XpmRGBCloseness #define FxpmColorKey XpmColorKey #define FxpmAllocCloseColors XpmAllocCloseColors #define FxpmBitmapFormat XpmBitmapFormat #define FxpmAllocColor XpmAllocColor #define FxpmFreeColors XpmFreeColors #define FxpmColorClosure XpmColorClosure #define FxpmComments XpmComments #define FxpmReturnComments XpmReturnComments #define FxpmUndefPixel XpmUndefPixel #define FxpmColorError XpmColorError #define FxpmSuccess XpmSuccess #define FxpmOpenFailed XpmOpenFailed #define FxpmFileInvalid XpmFileInvalid #define FxpmNoMemory XpmNoMemory #define FxpmColorFailed XpmColorFailed #define FXPM_MONO XPM_MONO #define FXPM_GREY4 XPM_GREY4 #define FXPM_GRAY4 XPM_GRAY4 #define FXPM_GREY XPM_GREY #define FXPM_GRAY XPM_GRAY #define FXPM_COLOR XPM_COLOR #define FxpmReadFileToXpmImage(a,b,c) XpmReadFileToXpmImage(a,b,c) #define FxpmCreatePixmapFromXpmImage(a,b,c,d,e,f) \ XpmCreatePixmapFromXpmImage(a,b,c,d,e,f) #define FxpmFreeXpmImage(a) XpmFreeXpmImage(a) #define FxpmFreeXpmInfo(a) XpmFreeXpmInfo(a) #define FxpmReadFileToPixmap(a,b,c,d,e,f) XpmReadFileToPixmap(a,b,c,d,e,f) #define FxpmReadFileToImage(a,b,c,d,e) XpmReadFileToImage(a,b,c,d,e) #define FxpmCreatePixmapFromData(a,b,c,d,e,f) \ XpmCreatePixmapFromData(a,b,c,d,e,f) #else /* !XpmSupport */ #define FxpmReturnPixels 0 #define FxpmSize 0 #define FxpmReturnAllocPixels 0 #define FxpmCloseness 0 #define FxpmVisual 0 #define FxpmColormap 0 #define FxpmDepth 0 #define FxpmHotspot 0 #define FxpmExtensions 0 #define FxpmCharsPerPixel 0 #define FxpmColorSymbols 0 #define FxpmRgbFilename 0 #define FxpmInfos 0 #define FxpmReturnInfos 0 #define FxpmReturnExtensions 0 #define FxpmRGBCloseness 0 #define FxpmColorKey 0 #define FxpmAllocCloseColors 0 #define FxpmBitmapFormat 0 #define FxpmAllocColor 0 #define FxpmFreeColors 0 #define FxpmColorClosure 0 #define FxpmComments 0 #define FxpmReturnComments 0 #define FxpmUndefPixel 0 #define FxpmColorError 1 #define FxpmSuccess 0 #define FxpmOpenFailed -1 #define FxpmFileInvalid -2 #define FxpmNoMemory -3 #define FxpmColorFailed -4 #define FXPM_MONO 2 #define FXPM_GREY4 3 #define FXPM_GRAY4 3 #define FXPM_GREY 4 #define FXPM_GRAY 4 #define FXPM_COLOR 5 #define FxpmReadFileToXpmImage(a,b,c) 0 #define FxpmCreatePixmapFromXpmImage(a,b,c,d,e,f) 0 #define FxpmFreeXpmImage(a) #define FxpmFreeXpmInfo(a) #define FxpmReadFileToPixmap(a,b,c,d,e,f) 0 #define FxpmCreatePixmapFromData(a,b,c,d,e,f) 0 #endif /* XpmSupport */ #endif /* FXPM_H */ fvwm-2.6.7/libs/wild.c0000644000175700017570000000422512773467232011520 00000000000000/* -*-c-*- */ /* 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 #include "wild.h" /* * Does `string' match `pattern'? '*' in pattern matches any sub-string * (including the null string) '?' matches any single char. For use * by filenameforall. Note that '*' matches across directory boundaries * * This code donated by Paul Hudson * It is public domain, no strings attached. No guarantees either. * */ int matchWildcards(const char *pattern, const char *string) { if(string == NULL) { if(pattern == NULL) return 1; else if(strcmp(pattern,"*")==0) return 1; else return 0; } if(pattern == NULL) return 1; while (*string && *pattern) { if (*pattern == '?') { /* match any character */ pattern += 1; string += 1; } else if (*pattern == '*') { /* see if the rest of the pattern matches any trailing * substring of the string. */ pattern += 1; if (*pattern == 0) { return 1; /* trailing * must match rest */ } while (*string) { if (matchWildcards(pattern,string)) { return 1; } string++; } return 0; } else { if (*pattern == '\\') { /* has strange, but harmless effects if the * last character is a '\\' */ pattern ++; } if (*pattern++ != *string++) { return 0; } } } if((*pattern == 0)&&(*string == 0)) return 1; if((*string == 0)&&(strcmp(pattern,"*")==0)) return 1; return 0; } fvwm-2.6.7/libs/queue.c0000644000175700017570000001753713001406607011677 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "safemalloc.h" #include "queue.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ typedef struct fqueue_record { struct fqueue_record *next; void *object; struct { unsigned is_scheduled_for_deletion; unsigned is_just_created; } flags; } fqueue_record; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Make newly added items permanent and destroy items scheduled for deletion. */ static void fqueue_cleanup_queue( fqueue *fq, destroy_fqueue_object_t destroy_func) { fqueue_record *head; fqueue_record *tail; fqueue_record *prev; fqueue_record *next; fqueue_record *rec; for (head = NULL, tail = NULL, prev = NULL, rec = fq->first; rec != NULL; rec = next) { if (rec->flags.is_scheduled_for_deletion) { /* destroy and skip it */ next = rec->next; if (rec->object != NULL && destroy_func != NULL) { destroy_func(rec->object); } if (prev != NULL) { prev->next = next; } free(rec); } else { rec->flags.is_just_created = 0; if (head == NULL) { head = rec; } tail = rec; prev = rec; next = rec->next; } } fq->first = head; fq->last = tail; return; } /* Recursively lock the queue. While locked, objects are not deleted from the * queue but marked for later deletion. New objects are marked as such and are * skipped by the queue functions. */ static void fqueue_lock_queue(fqueue *fq) { fq->lock_level++; return; } /* Remove one lock level */ static void fqueue_unlock_queue( fqueue *fq, destroy_fqueue_object_t destroy_func) { switch (fq->lock_level) { case 0: /* bug */ break; case 1: if (fq->flags.is_dirty) { fqueue_cleanup_queue(fq, destroy_func); } /* fall through */ default: fq->lock_level--; return; } return; } /* Chack and possibly execute the action associated with a queue object. * Schedule the object for deletion if it was executed. */ static void fqueue_operate( fqueue *fq, fqueue_record *rec, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, void *operate_args) { if (rec == NULL || rec->flags.is_scheduled_for_deletion) { return; } if (check_func == NULL || check_func(rec->object, operate_args) == 1) { if (operate_func != NULL) { operate_func(rec->object, operate_args); } rec->flags.is_scheduled_for_deletion = 1; fq->flags.is_dirty = 1; } return; } /* ---------------------------- builtin commands --------------------------- */ /* * Basic queue management */ void fqueue_init(fqueue *fq) { memset(fq, 0, sizeof(*fq)); return; } unsigned int fqueue_get_length(fqueue *fq) { unsigned int len; fqueue_record *t; for (t = fq->first, len = 0; t != NULL; t = t->next) { if (!t->flags.is_scheduled_for_deletion) { len++; } } return len; } /* * Add record to queue */ void fqueue_add_at_front( fqueue *fq, void *object) { fqueue_record *rec; rec = (fqueue_record *)safemalloc(sizeof(fqueue_record)); memset(rec, 0, sizeof(*rec)); rec->object = object; rec->next = fq->first; if (fq->lock_level > 0) { rec->flags.is_just_created = 1; fq->flags.is_dirty = 1; } fq->first = rec; return; } void fqueue_add_at_end( fqueue *fq, void *object) { fqueue_record *rec; rec = (fqueue_record *)safemalloc(sizeof(fqueue_record)); memset(rec, 0, sizeof(*rec)); rec->object = object; if (fq->lock_level > 0) { rec->flags.is_just_created = 1; fq->flags.is_dirty = 1; } if (fq->first == NULL) { fq->first = rec; } else { fq->last->next = rec; } fq->last = rec; rec->next = NULL; return; } void fqueue_add_inside( fqueue *fq, void *object, cmp_objects_t cmp_objects, void *cmp_args) { fqueue_record *rec; fqueue_record *p; fqueue_record *t; rec = (fqueue_record *)safemalloc(sizeof(fqueue_record)); memset(rec, 0, sizeof(*rec)); rec->object = object; if (fq->lock_level > 0) { rec->flags.is_just_created = 1; fq->flags.is_dirty = 1; } /* search place to insert record */ for (p = NULL, t = fq->first; t != NULL && cmp_objects(object, t->object, cmp_args) >= 0; p = t, t = t->next) { /* nothing to do here */ } /* insert record */ if (p == NULL) { /* insert at start */ rec->next = fq->first; fq->first = rec; } else { /* insert after p */ rec->next = p->next; p->next = rec; } if (t == NULL) { fq->last = rec; } return; } /* * Fetch queue objects */ /* Returns the object of the first queue record throuch *ret_object. Returns * 0 if the queue is empty and 1 otherwise. */ int fqueue_get_first( fqueue *fq, void **ret_object) { fqueue_record *rec; for (rec = fq->first; rec != NULL && rec->flags.is_scheduled_for_deletion; rec = rec->next) { /* nothing */ } if (rec == NULL) { return 0; } *ret_object = rec->object; return 1; } /* * Operate on queue objects and possibly remove them from the queue */ /* Runs the operate_func on the first record in the queue. If that function * is NULL or returns 1, the record is removed from the queue. The object of * the queue record must have been freed in operate_func. */ void fqueue_remove_or_operate_from_front( fqueue *fq, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, destroy_fqueue_object_t destroy_func, void *operate_args) { fqueue_lock_queue(fq); fqueue_operate(fq, fq->first, check_func, operate_func, operate_args); fqueue_unlock_queue(fq, destroy_func); return; } /* Same as above but operates on last record in queue */ void fqueue_remove_or_operate_from_end( fqueue *fq, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, destroy_fqueue_object_t destroy_func, void *operate_args) { fqueue_lock_queue(fq); fqueue_operate( fq, fq->last, check_func, operate_func, operate_args); fqueue_unlock_queue(fq, destroy_func); return; } /* Same as above but operates on all records in the queue. */ void fqueue_remove_or_operate_all( fqueue *fq, check_fqueue_object_t check_func, operate_fqueue_object_t operate_func, destroy_fqueue_object_t destroy_func, void *operate_args) { fqueue_record *t; if (fq->first == NULL) { return; } fqueue_lock_queue(fq); /* search record(s) to remove */ for (t = fq->first; t != NULL; t = t->next) { if (t->flags.is_just_created || t->flags.is_scheduled_for_deletion) { /* skip */ continue; } fqueue_operate(fq, t, check_func, operate_func, operate_args); } fqueue_unlock_queue(fq, destroy_func); return; } fvwm-2.6.7/libs/fvwmrect.c0000644000175700017570000000762012773467232012420 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Dominik Vogt */ /* 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 */ /* ** fvwmrect.c: ** This file supplies routines for fvwm internal rectangle handling. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "fvwmrect.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- local functions ---------------------------- */ static int fvwmrect_do_intervals_intersect( int x1, int width1, int x2, int width2) { return !(x1 + width1 <= x2 || x2 + width2 <= x1); } /* ---------------------------- interface functions ------------------------ */ /* Returns 1 if the given rectangles intersect and 0 otherwise */ int fvwmrect_do_rectangles_intersect(rectangle *r, rectangle *s) { if (r->x + r->width <= s->x) { return 0; } if (s->x + s->width <= r->x) { return 0; } if (r->y + r->height <= s->y) { return 0; } if (s->y + s->height <= r->y) { return 0; } return 1; } /* Subtracts the values in s2_ from the ones in s1_g and stores the result in * diff_g. */ void fvwmrect_subtract_rectangles( rectangle *rdiff, rectangle *r1, rectangle *r2) { rdiff->x = r1->x - r2->x; rdiff->y = r1->y - r2->y; rdiff->width = r1->width - r2->width; rdiff->height = r1->height - r2->height; return; } /* Returns 1 is the rectangles are identical and 0 if not */ int fvwmrect_rectangles_equal( rectangle *r1, rectangle *r2) { if (r1 == r2) { return 1; } if (r1 == NULL || r2 == NULL) { return 0; } if (r1->x != r2->x || r1->y != r2->y || r1->width != r2->width || r1->height != r2->height) { return 1; } return 0; } int fvwmrect_move_into_rectangle(rectangle *move_rec, rectangle *target_rec) { int has_changed = 0; if (!fvwmrect_do_intervals_intersect( move_rec->x, move_rec->width, target_rec->x, target_rec->width)) { move_rec->x = move_rec->x % (int)target_rec->width; if (move_rec->x < 0) { move_rec->x += target_rec->width; } move_rec->x += target_rec->x; has_changed = 1; } if (!fvwmrect_do_intervals_intersect( move_rec->y, move_rec->height, target_rec->y, target_rec->height)) { move_rec->y = move_rec->y % (int)target_rec->height; if (move_rec->y < 0) { move_rec->y += target_rec->height; } move_rec->y += target_rec->y; has_changed = 1; } return has_changed; } int fvwmrect_intersect_xrectangles( XRectangle *r1, XRectangle *r2) { int x1 = max(r1->x, r2->x); int y1 = max(r1->y, r2->y); int x2 = min(r1->x + r1->width, r2->x + r2->width); int y2 = min(r1->y + r1->height, r2->y + r2->height); r1->x = x1; r1->y = y1; r1->width = x2 - x1; r1->height = y2 - y1; if (x2 > x1 && y2 > y1) { return 1; } else { return 0; } } fvwm-2.6.7/libs/Picture.h0000644000175700017570000000533512773467232012204 00000000000000/* -*-c-*- */ #ifndef Picture_H #define Picture_H #include "PictureBase.h" #include "PictureImageLoader.h" /** Manipulating FvwmPictures **/ /** * For PGetFvwmPicture() and PCacheFvwmPicture(), setting * ImagePath to NULL means "search the default image path". **/ /* PGetFvwmPicture * * Return an FvwmPicture loaded from the file pictureName found in the * ImagePath.. If ImagePath is NULL the default image path is used. * */ FvwmPicture* PGetFvwmPicture( Display* dpy, Window win, char* ImagePath, const char* pictureName, FvwmPictureAttributes fpa); /* PFreeFvwmPictureData * * Just free the data allocated by PGetFvwmPicture. This function does not * Free the pixmaps for example. * */ void PFreeFvwmPictureData(FvwmPicture *p); /* PCacheFvwmPicture * * Return the FvwmPicture loaded from the file pictureName found in the * ImagePath. Fisrt the picture is searched in the FvwmPicture cache (so * if this picture has been already loaded it is not loaded again and a * weight is added to the found picture). If the picture is not in the cache * it is loaded from the file and added to the FvwmPicture cache. * If ImagePath is NULL the default image path is used. * */ FvwmPicture* PCacheFvwmPicture( Display *dpy, Window win, char* ImagePath, const char* pictureName, FvwmPictureAttributes fpa); /* PLoadFvwmPictureFromPixmap * * Return a FvwmPicture from the given data. * */ FvwmPicture *PLoadFvwmPictureFromPixmap( Display *dpy, Window win, char *name, Pixmap pixmap, Pixmap mask, Pixmap alpha, int width, int height, int nalloc_pixels, Pixel *alloc_pixels, int no_limit); /* PDestroyFvwmPicture * * Return a FvwmPicture from the given data. The picture is added to the * FvwmPicture cache. This is not really useful as it is not possible * to really cache a picture from the given data. * */ FvwmPicture *PCacheFvwmPictureFromPixmap( Display *dpy, Window win, char *name, Pixmap pixmap, Pixmap mask, Pixmap alpha, int width, int height, int nalloc_pixels, Pixel *alloc_pixels, int no_limit); /* PDestroyFvwmPicture * * Remove a weight to the FvwmPicture p from the FvwmPicture cache. * If the weight is zero the allocated datas from p are freed * */ void PDestroyFvwmPicture(Display *dpy, FvwmPicture *p); /* PCloneFvwmPicture * * Duplicate an already allocated FvwmPicture in the FvwmPicture cache * (a weight is added to the picture). * */ FvwmPicture *PCloneFvwmPicture(FvwmPicture *pic); void PicturePrintImageCache(int verbose); #endif fvwm-2.6.7/libs/FImage.h0000644000175700017570000000165112773467232011716 00000000000000/* -*-c-*- */ #ifndef FIMAGE_H #define FIMAGE_H /* ---------------------------- included header files ---------------------- */ #include "config.h" #include "FShm.h" /* ---------------------------- type definitions --------------------------- */ typedef struct { XImage *im; FShmSegmentInfo *shminfo; } FImage; /* ---------------------------- interface functions ------------------------ */ FImage *FCreateFImage ( Display *dpy, Visual *visual, unsigned int depth, int format, unsigned int width, unsigned int height); FImage *FGetFImage( Display *dpy, Drawable d, Visual *visual, unsigned int depth, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format); void FPutFImage( Display *dpy, Drawable d, GC gc, FImage *fim, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); void FDestroyFImage(Display *dpy, FImage *fim); #endif /* FIMAGE_H */ fvwm-2.6.7/libs/timeout.c0000644000175700017570000000542213001406607012227 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "safemalloc.h" #include "timeout.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ timeout_t *timeout_create( int n_timeouts) { timeout_t *to; if (n_timeouts < 0 || n_timeouts > TIMEOUT_MAX_TIMEOUTS) { return NULL; } to = (timeout_t *)safecalloc(1, sizeof(timeout_t)); to->n_timeouts = n_timeouts; to->timeouts = (timeout_time_t *)safecalloc( 1, n_timeouts * sizeof(timeout_time_t)); return to; } void timeout_destroy( timeout_t *to) { if (to == NULL) { return; } if (to->timeouts != NULL) { free(to->timeouts); } free(to); return; } timeout_mask_t timeout_tick( timeout_t *to, timeout_time_t n_ticks) { timeout_mask_t mask; int i; if (n_ticks <= 0) { return 0; } for (i = 0, mask = 0; i < to->n_timeouts; i++) { if (to->timeouts[i] > n_ticks) { to->timeouts[i] -= n_ticks; } else if (to->timeouts[i] > 0) { to->timeouts[i] = 0; mask |= 1 << i; } } return mask; } void timeout_rewind( timeout_t *to, timeout_mask_t mask, timeout_time_t ticks_before_alarm) { int i; if (ticks_before_alarm < 0) { return; } for (i = 0; i < to->n_timeouts; i++) { if (mask & (1 << i)) { to->timeouts[i] = ticks_before_alarm; } } return; } fvwm-2.6.7/libs/modifiers.c0000644000175700017570000000537312773467232012547 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "libs/charmap.h" #include "libs/modifiers.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* The keys must be in lower case! */ charmap_t key_modifiers[] = { {'s', ShiftMask}, {'c', ControlMask}, {'l', LockMask}, {'m', Mod1Mask}, {'1', Mod1Mask}, {'2', Mod2Mask}, {'3', Mod3Mask}, {'4', Mod4Mask}, {'5', Mod5Mask}, {'a', AnyModifier}, {'n', 0}, {0, 0} }; /* Table to translate a modifier map index to a modifier that we define that * generates that index. This mapping can be chosen by each client, but the * settings below try to emulate the usual terminal behaviour. */ unsigned int modifier_mapindex_to_mask[8] = { ShiftMask, Mod3Mask, /* Alt Gr */ Mod3Mask | ShiftMask, /* Just guessing below here - LockMask is not used anywhere*/ ControlMask, Mod1Mask, /* Alt/Meta on XFree86 */ Mod2Mask, /* Num lock on XFree86 */ Mod4Mask, Mod5Mask, /* Scroll lock on XFree86 */ }; /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Converts the input string into a mask with bits for the modifiers */ int modifiers_string_to_modmask(char *in_modifiers, int *out_modifier_mask) { int error; error = charmap_string_to_mask( out_modifier_mask, in_modifiers, key_modifiers, "bad modifier"); return error; } fvwm-2.6.7/libs/setpgrp.h0000644000175700017570000000014412773467232012246 00000000000000/* -*-c-*- */ #ifndef SETPGRP_H #define SETPGRP_H int fvwm_setpgrp(void); #endif /* SETPGRP_H */ fvwm-2.6.7/libs/FScreen.h0000644000175700017570000000563413001406607012100 00000000000000/* -*-c-*- */ #ifndef FVWMLIB_FSCRREN_H #define FVWMLIB_FSCRREN_H /* needs X11/Xlib.h and X11/Xutil.h */ typedef enum { FSCREEN_GLOBAL = -1, FSCREEN_CURRENT = -2, FSCREEN_PRIMARY = -3, FSCREEN_XYPOS = -4 } fscreen_scr_t; typedef enum { FSCREEN_SPEC_GLOBAL = 'g', FSCREEN_SPEC_CURRENT = 'c', FSCREEN_SPEC_PRIMARY = 'p', FSCREEN_SPEC_WINDOW = 'w' } fscreen_scr_spec_t; typedef union { XEvent *mouse_ev; struct { int x; int y; } xypos; } fscreen_scr_arg; #define FSCREEN_MANGLE_USPOS_HINTS_MAGIC ((short)-32109) /* Control */ Bool FScreenIsEnabled(void); Bool FScreenIsSLSEnabled(void); void FScreenInit(Display *dpy); void FScreenOnOff(Bool do_enable); Bool FScreenConfigureSLSSize(int width, int height); Bool FScreenConfigureSLSScreens(int nscreens, char *args); void FScreenSLSOnOff(Bool do_enable); /* Intended to be called by modules. Simply pass in the parameter from the * config string sent by fvwm. */ void FScreenConfigureModule(char *args); const char* FScreenGetConfiguration(void); /* For use by fvwm */ void FScreenSetDefaultModuleScreen(char *scr_spec); void FScreenDisableRandR(void); void FScreenSetPrimaryScreen(int scr); /* Screen info */ Bool FScreenGetScrRect( fscreen_scr_arg *arg, fscreen_scr_t screen, int *x, int *y, int *w, int *h); Bool FScreenGetScrId( fscreen_scr_arg *arg, fscreen_scr_t screen); void FScreenTranslateCoordinates( fscreen_scr_arg *arg_src, fscreen_scr_t screen_src, fscreen_scr_arg *arg_dest, fscreen_scr_t screen_dest, int *x, int *y); void FScreenGetResistanceRect( int wx, int wy, unsigned int ww, unsigned int wh, int *x0, int *y0, int *x1, int *y1); Bool FScreenIsRectangleOnScreen( fscreen_scr_arg *arg, fscreen_scr_t screen, rectangle *rec); void FScreenSpecToString(char *dest, int space, fscreen_scr_t screen); int FScreenOfPointerXY(int x, int y); /* Clipping/positioning */ int FScreenClipToScreen( fscreen_scr_arg *arg, fscreen_scr_t screen, int *x, int *y, int w, int h); void FScreenCenterOnScreen( fscreen_scr_arg *arg, fscreen_scr_t screen, int *x, int *y, int w, int h); /* Geometry management */ int FScreenGetScreenArgument(char *scr_spec, fscreen_scr_spec_t default_screen); int FScreenParseGeometryWithScreen( char *parsestring, int *x_return, int *y_return, unsigned int *width_return, unsigned int *height_return, int *screen_return); int FScreenParseGeometry( char *parsestring, int *x_return, int *y_return, unsigned int *width_return, unsigned int *height_return); int FScreenGetGeometry( char *parsestring, int *x_return, int *y_return, int *width_return, int *height_return, XSizeHints *hints, int flags); void FScreenMangleScreenIntoUSPosHints(fscreen_scr_t screen, XSizeHints *hints); fscreen_scr_t FScreenFetchMangledScreenFromUSPosHints(XSizeHints *hints); /* RandR support */ int FScreenGetRandrEventType(void); Bool FScreenHandleRandrEvent( XEvent *event, int *old_w, int *old_h, int *new_w, int *new_h); #endif /* FVWMLIB_FSCRREN_H */ fvwm-2.6.7/libs/Parse.c0000644000175700017570000005073613001406607011623 00000000000000/* -*-c-*- */ /* 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 */ /* ** Parse.c: routines for parsing in fvwm & modules */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwmlib.h" #include "Strings.h" #include "Parse.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* Copies a token beginning at src to a previously allocated area dest. dest * must be large enough to hold the token. Leading whitespace causes the token * to be NULL. */ /* NOTE: CopyToken can be called with dest == src. The token will be copied * back down over the src string. */ static char *CopyToken( char *src, char *dest, char *spaces, int snum, char *delims, int dnum, char *out_delim) { int len = 0; char *t; while (*src != 0 && !(isspace((unsigned char)*src) || (snum && strchr(spaces, *src)) || (dnum && strchr(delims, *src)))) { /* Check for quoted text */ if (IsQuote(*src)) { char c = *src; src++; while ((*src != c)&&(*src != 0)) { if ((*src == '\\' && *(src+1) != 0)) { /* Skip over backslashes */ src++; } if (len < MAX_TOKEN_LENGTH - 1) { len++; *(dest++) = *(src++); } else { /* token too long, just skip rest */ src++; } } if (*src == c) { src++; } } else { if ((*src == '\\' && *(src+1) != 0)) { /* Skip over backslashes */ src++; } if (len < MAX_TOKEN_LENGTH - 1) { len++; *(dest++) = *(src++); } else { /* token too long, just skip rest of token */ src++; } } } if (out_delim) { *out_delim = *src; } *dest = 0; t = SkipSpaces(src, spaces, snum); if (*t != 0 && dnum && strchr(delims, *t) != NULL) { if (out_delim) { *out_delim = *t; } src = t + 1; } else if (*src != 0) { src++; } return src; } /* ---------------------------- interface functions ------------------------ */ /* This function escapes all occurences of the characters in the string qchars * in the string as with a preceding echar character. The resulting string is * returned in a malloced memory area. */ char *EscapeString(char *s, const char *qchars, char echar) { char *t; char *ret; int len; for (len = 1, t = s; *t ; t++, len++) { if (strchr(qchars, *t) != NULL) { len++; } } ret = (char *)safemalloc(len); for (t = ret; *s; s++, t++) { if (strchr(qchars, *s) != NULL) { *t = echar; t++; } *t = *s; } *t = 0; return ret; } /* If the string s begins with a quote chracter SkipQuote returns a pointer * to the first unquoted character or to the final '\0'. If it does not, a * pointer to the next character in the string is returned. * There are three possible types of quoting: a backslash quotes the next * character only. Long quotes like " " or ' ' quoting everything in * between and quote pairs like ( ) or { }. * * precedence: * * 1) Backslashes are honoured always, even inside long or pair quotes. * 2) long quotes do quote quoting pair characters but not simple quotes. All * long quotes can quote all other types of long quotes). * 3) pair quotes none of the above. Text between a pair of quotes is treated * as a single token. * * qlong - string of long quoted (defaults to "'` ) * qstart - string of pair quote start characters (defaults to empty string) * qend - string of pair quote end characters (defaults to empty string) * * The defaults are used if NULL is passed for the corresponding string. */ char *SkipQuote( char *s, const char *qlong, const char *qstart, const char *qend) { char *t; if (s == NULL || *s == 0) { return s; } if (!qlong) { qlong = "\"'`"; } if (!qstart) { qstart = ""; } if (!qend) { qend = ""; } if (*s == '\\' && s[1] != 0) { return s+2; } else if (*qlong && (t = strchr(qlong, *s))) { char c = *t; s++; while (*s && *s != c) { /* Skip over escaped text, ie \quote */ if (*s == '\\' && *(s+1) != 0) { s++; } s++; } if (*s == c) { s++; } return s; } else if (*qstart && (t = strchr(qstart, *s))) { char c = *((t - qstart) + qend); while (*s && *s != c) { s = SkipQuote(s, qlong, "", ""); } return (*s == c) ? ++s : s; } return ++s; } /* Returns a string up to the first character from the string delims in a * malloc'd area just like GetNextToken. Quotes are not removed from the * returned string. The returned string is stored in *sout, the return value * of this call is a pointer to the first character after the delimiter or * to the terminating '\0'. Quoting is handled like in SkipQuote. If sin is * NULL, the function returns NULL in *sout. */ char *GetQuotedString( char *sin, char **sout, const char *delims, const char *qlong, const char *qstart, const char *qend) { char *t = sin; unsigned int len; if (!sout) { return NULL; } if (!sin) { *sout = NULL; return NULL; } while (*t && !strchr(delims, *t)) { t = SkipQuote(t, qlong, qstart, qend); } len = t - sin; *sout = (char *)safemalloc(len + 1); memcpy(*sout, sin, len); (*sout)[len] = 0; if (*t) { t++; } return t; } /* SkipSpaces: returns a pointer to the first character in indata that is * neither a whitespace character nor contained in the string 'spaces'. snum * is the number of characters in 'spaces'. You must not pass a NULL pointer * in indata. */ char *SkipSpaces(char *indata, char *spaces, int snum) { while (*indata != 0 && (isspace((unsigned char)*indata) || (snum && strchr(spaces, *indata)))) { indata++; } return indata; } /* ** DoPeekToken: returns next token from string, leaving string intact ** (you must not free returned string) ** ** WARNING: The returned pointer points to a static array that will be ** overwritten in all functions in this file! ** ** For a description of the parameters see DoGetNextToken below. DoPeekToken ** is a bit faster. */ /* NOTE: If indata is the pointer returned by a previous call to PeekToken or * DoPeekToken, the input string will be destroyed. */ char *DoPeekToken( char *indata, char **token, char *spaces, char *delims, char *out_delim) { char *end; int snum; int dnum; static char tmptok[MAX_TOKEN_LENGTH]; snum = (spaces) ? strlen(spaces) : 0; dnum = (delims) ? strlen(delims) : 0; if (indata == NULL) { if (out_delim) { *out_delim = '\0'; } *token = NULL; return NULL; } indata = SkipSpaces(indata, spaces, snum); end = CopyToken(indata, tmptok, spaces, snum, delims, dnum, out_delim); if (tmptok[0] == 0) { *token = NULL; } else { *token = tmptok; } return end; } /* * PeekToken takes the input string "indata" and returns a pointer to the * token, stored in a static char array. The pointer is invalidated by * the next call to PeekToken. If "outdata" is not NULL, the pointer * to the first character after the token is returned through * *outdata. (Note that outdata is a char **, not just a char *). */ char *PeekToken(char *indata, char **outdata) { char *dummy; char *token; if (!outdata) { outdata = &dummy; } *outdata = DoPeekToken(indata, &token, NULL, NULL, NULL); return token; } /**** SMR: Defined but not used -- is this for the future or a relic of the **** past? ****/ /* domivogt (27-Jun-1999): It's intended for future use. I have no problem * commenting it out if it's not used. */ /* Tries to seek up to n tokens in indata. Returns the number of tokens * actually found (up to a maximum of n). */ #if 0 int CheckNTokens(char *indata, unsigned int n) { unsigned int i; char *token; for (i = 0, token = (char *)1; i < n && token != NULL; i++) { token = PeekToken(indata, NULL); } return i; } #endif /* ** MatchToken: does case-insensitive compare on next token in string, leaving ** string intact (returns true if matches, false otherwise) */ int MatchToken(char *pstr,char *tok) { int rc=0; char *ntok; DoPeekToken(pstr, &ntok, NULL, NULL, NULL); if (ntok) { rc = (strcasecmp(tok,ntok)==0); } return rc; } /* unused at the moment */ /* function: XCmpToken description: compare 1st word of s to 1st word of t returns: < 0 if s < t = 0 if s = t > 0 if s > t */ int XCmpToken(const char *s, const char **t) { register const char *w=*t; if (w==NULL) { return 1; } if (s==NULL) { return -1; } while (*w && (*s==*w || toupper(*s)==toupper(*w)) ) { s++; w++; } if ((*s=='\0' && (ispunct(*w) || isspace(*w)))|| (*w=='\0' && (ispunct(*s) || isspace(*s))) ) { return 0; /* 1st word equal */ } else { return toupper(*s)-toupper(*w); /* smaller/greater */ } } /* * * Gets the next "word" of input from string indata. * "word" is a string with no spaces, or a qouted string. * Return value is ptr to indata,updated to point to text after the word * which is extracted. * token is the extracted word, which is copied into a malloced * space, and must be freed after use. DoGetNextToken *never* returns an * empty string or token. If the token consists only of whitespace or * delimiters, the returned token is NULL instead. If out_delim is given, * the character ending the string is returned therein. * * spaces = string of characters to treat as spaces * delims = string of characters delimiting token * * Use "spaces" and "delims" to define additional space/delimiter * characters (spaces are skipped before a token, delimiters are not). * */ char *DoGetNextToken( char *indata, char **token, char *spaces, char *delims, char *out_delim) { char *tmptok; char *end; end = DoPeekToken(indata, &tmptok, spaces, delims, out_delim); if (tmptok == NULL) { *token = NULL; } else { *token = safestrdup(tmptok); } return end; } /* * GetNextToken works similarly to PeekToken, but: stores the token in * *token, & returns a pointer to the first character after the token * in *token. The memory in *token is allocated with malloc and the * calling function has to free() it. * * If possible, use PeekToken because it's faster and does not risk * creating memory leaks. */ char *GetNextToken(char *indata, char **token) { return DoGetNextToken(indata, token, NULL, NULL, NULL); } /* fetch next token and stop at next ',' */ char *GetNextSimpleOption(char *indata, char **option) { return DoGetNextToken(indata, option, NULL, ",", NULL); } /* read multiple tokens up to next ',' or end of line */ char *GetNextFullOption(char *indata, char **option) { return GetQuotedString(indata, option, ",\n", NULL, NULL, NULL); } char *SkipNTokens(char *indata, unsigned int n) { for ( ; n > 0 && indata != NULL && *indata != 0; n--) { PeekToken(indata, &indata); } return indata; } /* * convenience functions */ /* * * Works like GetNextToken, but with the following differences: * * If *indata begins with a "*" followed by the string module_name, * it returns the string following directly after module_name as the * new token. Otherwise NULL is returned. * e.g. GetModuleResource("*FvwmPagerGeometry", &token, "FvwmPager") * returns "Geometry" in token. * */ char *GetModuleResource(char *indata, char **resource, char *module_name) { char *tmp; char *next; if (!module_name) { *resource = NULL; return indata; } tmp = PeekToken(indata, &next); if (!tmp) { return next; } if (tmp[0] != '*' || strncasecmp(tmp+1, module_name, strlen(module_name))) { *resource = NULL; return indata; } CopyString(resource, tmp+1+strlen(module_name)); return next; } /* * * This function uses GetNextToken to parse action for up to num integer * arguments. The number of values actually found is returned. * If ret_action is non-NULL, a pointer to the next token is returned there. * The suffixlist parameter points to a string of possible suffixes for the * integer values. The index of the matched suffix is returned in * ret_suffixnum (0 = no suffix, 1 = first suffix in suffixlist ...). * */ static int _get_suffixed_integer_arguments( char *action, char **ret_action, int *retvals, int num, char *suffixlist, int *ret_suffixnum, char *parsestring) { int i; int j; int n; char *token; int suffixes; /* initialize */ suffixes = 0; if (suffixlist != 0) { /* if passed a suffixlist save its length */ suffixes = strlen(suffixlist); } for (i = 0; i < num && action; i++) { token = PeekToken(action, &action); if (token == NULL) { break; } if (sscanf(token, parsestring, &(retvals[i]), &n) < 1) { break; } if (suffixes != 0 && ret_suffixnum != NULL) { int len; char c; len = strlen(token) - 1; c = token[len]; if (isupper(c)) { c = tolower(c); } for (j = 0; j < suffixes; j++) { char c2 = suffixlist[j]; if (isupper(c2)) { c2 = tolower(c2); } if (c == c2) { ret_suffixnum[i] = j+1; break; } } if (j == suffixes) { ret_suffixnum[i] = 0; } } else if (token[n] != 0 && !isspace(token[n])) { /* there is a suffix but no suffix list was specified */ break; } } if (ret_action != NULL) { *ret_action = action; } return i; } int GetSuffixedIntegerArguments( char *action, char **ret_action, int *retvals, int num, char *suffixlist, int *ret_suffixnum) { return _get_suffixed_integer_arguments( action, ret_action, retvals, num, suffixlist, ret_suffixnum, "%d%n"); } /* * * This function converts the suffix/number pairs returned by * GetSuffixedIntegerArguments into pixels. The unit_table is an array of * integers that determine the factor to multiply with in hundredths of * pixels. I.e. a unit of 100 means: translate the value into pixels, * 50 means divide value by 2 to get the number of pixels and so on. * The unit used is determined by the suffix which is taken as the index * into the table. No size checking of the unit_table is done, so make sure * it is big enough before calling this function. * */ int SuffixToPercentValue(int value, int suffix, int *unit_table) { return (value * unit_table[suffix]) / 100; } /* * * This function uses GetNextToken to parse action for up to num integer * arguments. The number of values actually found is returned. * If ret_action is non-NULL, a pointer to the next token is returned there. * */ int GetIntegerArguments(char *action, char **ret_action, int *retvals,int num) { return _get_suffixed_integer_arguments( action, ret_action, retvals, num, NULL, NULL, "%d%n"); } /* * * Same as above, but supports hexadecimal and octal integers via 0x and 0 * prefixes. * */ int GetIntegerArgumentsAnyBase( char *action, char **ret_action, int *retvals,int num) { return _get_suffixed_integer_arguments( action, ret_action, retvals, num, NULL, NULL, "%i%n"); } /* * * This function tries to match a token with a list of strings and returns * the position of token in the array or -1 if no match is found. The last * entry in the list must be NULL. * * len = 0 : only exact matches * len < 0 : match, if token begins with one of the strings in list * len > 0 : match, if the first len characters do match * * if next is non-NULL, *next will be set to point to the first character * in token after the match. * */ int GetTokenIndex(char *token, char **list, int len, char **next) { int i; int l; int k; if (!token || !list) { if (next) { *next = NULL; } return -1; } l = (len) ? len : strlen(token); for (i = 0; list[i] != NULL; i++) { k = strlen(list[i]); if (len < 0) { l = k; } else if (len == 0 && k != l) { continue; } if (!strncasecmp(token, list[i], l)) { break; } } if (next) { *next = (list[i]) ? token + l : token; } return (list[i]) ? i : -1; } /* * * This function does roughly the same as GetTokenIndex but reads the * token from string action with GetNextToken. The index is returned * in *index. The return value is a pointer to the character after the * token (just like the return value of GetNextToken). * */ char *GetNextTokenIndex(char *action, char **list, int len, int *index) { char *token; char *next; if (!index) { return action; } token = PeekToken(action, &next); if (!token) { *index = -1; return action; } *index = GetTokenIndex(token, list, len, NULL); return (*index == -1) ? action : next; } /* * * Parses two integer arguments given in the form . * character can be ' ' or 'x', but any other character is allowed too * (except 'p' or 'P'). * */ int GetRectangleArguments(char *action, int *width, int *height) { char *token; int n; token = PeekToken(action, NULL); if (!token) { return 0; } n = sscanf(token, "%d%*c%d", width, height); return (n == 2) ? 2 : 0; } /* unit_io is input as well as output. If action has a postfix 'p' or 'P', * *unit_io is set to 100, otherwise it is left untouched. */ int GetOnePercentArgument(char *action, int *value, int *unit_io) { unsigned int len; char *token; int n; *value = 0; if (!action) { return 0; } token = PeekToken(action, NULL); if (!token) { return 0; } len = strlen(token); /* token never contains an empty string, so this is ok */ if (token[len - 1] == 'p' || token[len - 1] == 'P') { *unit_io = 100; token[len - 1] = '\0'; } n = sscanf(token, "%d", value); return n; } int GetTwoPercentArguments( char *action, int *val1, int *val2, int *val1_unit, int *val2_unit) { char *tok1; char *tok2; char *next; int n = 0; *val1 = 0; *val2 = 0; tok1 = PeekToken(action, &next); action = GetNextToken(action, &tok1); if (!tok1) { return 0; } GetNextToken(action, &tok2); if (GetOnePercentArgument(tok2, val2, val2_unit) == 1 && GetOnePercentArgument(tok1, val1, val1_unit) == 1) { free(tok1); free(tok2); return 2; } /* now try MxN style number, specifically for DeskTopSize: */ n = GetRectangleArguments(tok1, val1, val2); free(tok1); if (tok2) { free(tok2); } return n; } /* Parses the next token in action and returns 1 if it is "yes", "true", "y", * "t" or "on", zero if it is "no", "false", "n", "f" or "off" and -1 if it is * "toggle". A pointer to the first character in action behind the token is * returned through ret_action in this case. ret_action may be NULL. If the * token matches none of these strings the default_ret value is returned and * the action itself is passed back in ret_action. If the no_toggle flag is * non-zero, the "toggle" string is handled as no match. */ int ParseToggleArgument( char *action, char **ret_action, int default_ret, char no_toggle) { int index; int rc; char *next; char *optlist[] = { "toggle", "yes", "no", "true", "false", "on", "off", "t", "f", "y", "n", NULL }; next = GetNextTokenIndex(action, optlist, 0, &index); if (index == 0 && no_toggle == 0) { /* toggle requested explicitly */ rc = -1; } else if (index == -1 || (index == 0 && no_toggle)) { /* nothing selected, use default and don't modify action */ rc = default_ret; next = action; } else { /* odd numbers denote True, even numbers denote False */ rc = (index & 1); } if (ret_action) { *ret_action = next; } return rc; } /* Strips the path from 'path' and returns the last component in a malloc'ed * area. */ char *GetFileNameFromPath(char *path) { char *s; char *name; /* we get rid of the path from program name */ s = strrchr(path, '/'); if (s) { s++; } else { s = path; } name = (char *)safemalloc(strlen(s)+1); strcpy(name, s); return name; } fvwm-2.6.7/libs/modifiers.h0000644000175700017570000000162212773467232012545 00000000000000/* -*-c-*- */ #ifndef MODIFIERS_H #define MODIFIERS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define ALL_MODIFIERS (ShiftMask|LockMask|ControlMask|Mod1Mask|Mod2Mask|\ Mod3Mask|Mod4Mask|Mod5Mask) /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ extern charmap_t key_modifiers[]; extern unsigned int modifier_mapindex_to_mask[]; /* ---------------------------- interface functions ------------------------ */ int modifiers_string_to_modmask(char *in_modifiers, int *out_modifier_mask); #endif /* MODIFIERS_H */ fvwm-2.6.7/libs/flist.c0000644000175700017570000000720013001406607011656 00000000000000/* -*-c-*- */ /* 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 */ /* * This module was all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* code for parsing the fvwm style command */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "safemalloc.h" #include "flist.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ flist *flist_append_obj(flist *list, void *object) { flist *new = (flist *)safemalloc(sizeof(flist)); flist *tl = list; new->object = object; new->next = NULL; new->prev = NULL; if (list == NULL) { return new; } while(tl->next) { tl = tl->next; } tl->next = new; new->prev = tl; return list; } flist *flist_prepend_obj(flist *list, void *object) { flist *new = (flist *)safemalloc(sizeof(flist)); new->object = object; new->next = NULL; new->prev = NULL; if (list == NULL) { return new; } if (list->prev) { list->prev->next = new; new->prev = list->prev; } list->prev = new; new->next = list; return new; } flist *flist_insert_obj(flist *list, void *object, int position) { flist *new; flist *tl; if (position < 0) { return flist_append_obj(list, object); } if (position == 0) { return flist_prepend_obj(list, object); } tl = list; while(tl && position-- > 0) { tl = tl->next; } if (!tl) { return flist_append_obj(list, object); } new = (flist *)safemalloc(sizeof(flist));; new->object = object; new->prev = NULL; if (tl->prev) { tl->prev->next = new; new->prev = tl->prev; } new->next = tl; tl->prev = new; if (tl == list) { return new; } return list; } flist *flist_remove_obj(flist *list, void *object) { flist *tl = list; while (tl && tl->object != object) { tl = tl->next; } if (tl == NULL) { return NULL; } if (tl->prev) { tl->prev->next = tl->next; } if (tl->next) { tl->next->prev = tl->prev; } if (list == tl) { list = list->next; } free(tl); return list; } flist *flist_free_list(flist *list) { flist *tl; while (list) { tl = list; list = list->next; free(tl); } return NULL; } fvwm-2.6.7/libs/CombineChars.h0000644000175700017570000000073012773467232013120 00000000000000/* -*-c-*- */ /* Copyright (C) 2003 Marcus Lundblad */ /* * FCombineChars.h * * Interface to character combining */ #ifndef FCOMBINECHARS_H #define FCOMBINECHARS_H #include "config.h" #include typedef struct { int position; /* position in the string */ XChar2b c; /* UCS-2 character */ } superimpose_char_t; int CombineChars( unsigned char *str_visual, int len, superimpose_char_t **comb_chars, int **l_to_v); #endif /* FCOMBINECHARS_H */ fvwm-2.6.7/libs/FEvent.h0000644000175700017570000002135312773467232011756 00000000000000/* -*-c-*- */ #ifndef FEVENT_H #define FEVENT_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define FEV_IS_EVENT_INVALID(e) \ (fev_is_invalid_event_type_set && (e).type == fev_invalid_event_type) #define FEV_HAS_EVENT_WINDOW(type) \ (( \ (type) != GraphicsExpose && \ (type) != NoExpose && \ (type) != SelectionNotify && \ (type) != SelectionRequest) ? 1 : 0) /* invalidate event by setting a bogus event type */ #define FEV_INVALIDATE_EVENT(e) \ do { (e)->type = fev_invalid_event_type; } while (0) /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* Exported to be used in FEV_IS_EVENT_INVALID(). Do not use. */ extern char fev_is_invalid_event_type_set; /* Exported to be used in FEV_IS_EVENT_INVALID(). Do not use. */ extern int fev_invalid_event_type; /* ---------------------------- interface functions (privileged access) ---- */ #ifdef FEVENT_PRIVILEGED_ACCESS void fev_copy_last_event(XEvent *dest); XEvent *fev_get_last_event_address(void); #endif /* ---------------------------- interface functions (normal_access) -------- */ /* Sets the event type that is used by FWeedIfEvents() to mark an event as * invalid. Needs to be called before FWeedIfEvents() can be used. */ void fev_init_invalid_event_type(int invalid_event_type); /* get the latest event time */ Time fev_get_evtime(void); /* This function determines the location of the mouse pointer from the event * if possible, if not it queries the X server. Returns False if it had to * query the server and the call failed because the pointer was on a * different screen. */ Bool fev_get_evpos_or_query( Display *dpy, Window w, const XEvent *e, int *ret_x, int *ret_y); /* Sets the x_root/y_root position in the given event if it's of the proper * type. Returns True if the position was set. */ Bool fev_set_evpos(XEvent *e, int x, int y); /* announce a faked event to the FEvent module */ void fev_fake_event(XEvent *ev); /* temporarily store the cached event in allocated memory */ void *fev_save_event(void); /* restore an event saved with fev_save_event and free the memory it uses */ void fev_restore_event(void *ev); /* fill the event structure *ev with a dummy event of no particular type */ void fev_make_null_event(XEvent *ev, Display *dpy); /* return a copy of the last XEVent in *ev */ void fev_get_last_event(XEvent *ev); /* Make sure the values in the event are in the defined range (e.g. x is and * int, but the protocol uses only a 16 bit signed integer. */ void fev_sanitise_configure_request(XConfigureRequestEvent *cr); void fev_sanitise_configure_notify(XConfigureEvent *cn); void fev_sanitize_size_hints(XSizeHints *sh); /* ---------------------------- Functions not present in Xlib -------------- */ /* Iterates over all events currentliy in the input queue and calls the * weed_predicate procedure for them. The predicate may return * 0 = keep event and continue weeding * 1 = invalidate event and continue weeding * 2 = keep event and stop weeding * 3 = invalidate event and stop weeding * Events are marked as invalid by overwriting the event type with the invalid * event type configured with fev_init_invalid_event_type(). Returns the * number of invalidated events. * * The return codes 2 and 3 of the weed_predicate procedure can be used to * stop weeding if another event gets "in the way". For example, when merging * Expose events, one might want to stop merging when a ConfigureRequest event * is encountered in the queue as that event may change the visible are of the * window. * * Weeded events can still be returned by functions that do not check the event * type, e.g. FNextEvent(), FWindowEvent(), FMaskEvent(), FPeekEvent etc. It * is the responsibility of the caller to discard these events. * * If the weed_predicate is a NULL pointer, no call is made and the result for * all events is assumed to be 1. */ int FWeedIfEvents( Display *display, int (*weed_predicate) ( Display *display, XEvent *current_event, XPointer arg), XPointer arg); /* Same as FWeedIfEvents but weeds only events for the given window. The * weed_predicate is only called for events with a matching window. */ int FWeedIfWindowEvents( Display *display, Window window, int (*weed_predicate) ( Display *display, XEvent *current_event, XPointer arg), XPointer arg); /* Same as FWeedIfEvents but weeds only events of the given type for the given * window. If last_event is not NULL, a copy of the last weeded event is * returned through *last_event (valid if a value > 0 is treturned). */ int FCheckWeedTypedWindowEvents( Display *display, Window window, int event_type, XEvent *last_event); /* Like FCheckIfEvent but does not remove the event from the queue. */ int FCheckPeekIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg); /* ---------------------------- X event replacements ----------------------- */ /* Replacements for X functions */ XTimeCoord *FGetMotionEvents( Display *display, Window w, Time start, Time stop, int *nevents_return); int FAllowEvents( Display *display, int event_mode, Time time); Bool FCheckIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg); Bool FCheckMaskEvent( Display *display, long event_mask, XEvent *event_return); Bool FCheckTypedEvent( Display *display, int event_type, XEvent *event_return); Bool FCheckTypedWindowEvent( Display *display, Window w, int event_type, XEvent *event_return); Bool FCheckWindowEvent( Display *display, Window w, long event_mask, XEvent *event_return); int FEventsQueued( Display *display, int mode); int FIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg); int FMaskEvent( Display *display, long event_mask, XEvent *event_return); int FNextEvent( Display *display, XEvent *event_return); int FPeekEvent( Display *display, XEvent *event_return); int FPeekIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg); int FPending( Display *display); int FPutBackEvent( Display *display, XEvent *event); int FQLength( Display *display); Bool FQueryPointer( Display *display, Window w, Window *root_return, Window *child_return, int *root_x_return, int *root_y_return, int *win_x_return, int *win_y_return, unsigned int *mask_return); int FSelectInput( Display *display, Window w, long event_mask); Status FSendEvent( Display *display, Window w, Bool propagate, long event_mask, XEvent *event_send); int FWarpPointer( Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); int FWarpPointerUpdateEvpos( XEvent *ev, Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); int FWindowEvent( Display *display, Window w, long event_mask, XEvent *event_return); Status FGetWMNormalHints( Display *display, Window w, XSizeHints *hints_return, long *supplied_return); /* ---------------------------- disable X symbols -------------------------- */ /* FEVENT_C must only be defined in FEvent.c! */ #ifndef FEVENT_C #define XGetMotionEvents(a, b, c, d, e) use_FGetMotionEvents #define XCheckIfEvent(a, b, c, d) use_FCheckIfEvent #define XCheckMaskEvent(a, b, c) use_FCheckMaskEvent #define XCheckTypedEvent(a, b, c) use_FCheckTypedEvent #define XCheckTypedWindowEvent(a, b, c, d) use_FCheckTypedWindowEvent #define XCheckWindowEvent(a, b, c, d) use_FCheckWindowEvent #define XEventsQueued(a, b) use_FEventsQueued #define XIfEvent(a, b, c, d) use_FIfEvent #define XMaskEvent(a, b, c) use_FMaskEvent #define XNextEvent(a, b) use_FNextEvent #define XPeekEvent(a, b) use_FPeekEvent #define XPeekIfEvent(a, b, c, d) use_FPeekIfEvent #define XPending(a) use_FPending #define XPutBackEvent(a, b) use_FPutBackEvent #define XQueryPointer(a, b, c, d, e, f, g, h, i) use_FQueryPointer #define XQLength(a) use_FQLength #define XSendEvent(a, b, c, d, e) use_FSendEvent #define XWarpPointer(a, b, c, d, e, f, g, h, i) use_FWarpPointer #define XWindowEvent(a, b, c, d) use_FWindowEvent #define XGetSizeHints(a, b, c, d) use_FGetWMNormalHints #define XGetNormalHints(a, b, c) use_FGetWMNormalHints #define XGetWMNormalHints(a, b, c, d) use_FGetWMNormalHints #endif #endif /* FEVENT_H */ fvwm-2.6.7/libs/ftime.h0000644000175700017570000000030112773467232011661 00000000000000/* -*-c-*- */ #include "config.h" #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif fvwm-2.6.7/libs/ClientMsg.c0000644000175700017570000000225612773467232012450 00000000000000/* -*-c-*- */ /* 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 "ClientMsg.h" Atom _XA_WM_PROTOCOLS = None; void send_clientmessage (Display *disp, Window w, Atom a, Time timestamp) { XClientMessageEvent ev; if (_XA_WM_PROTOCOLS == None) _XA_WM_PROTOCOLS = XInternAtom(disp, "WM_PROTOCOLS", False); ev.type = ClientMessage; ev.window = w; ev.message_type = _XA_WM_PROTOCOLS; ev.format = 32; ev.data.l[0] = a; ev.data.l[1] = timestamp; FSendEvent(disp, w, False, 0L, (XEvent *) &ev); } fvwm-2.6.7/libs/fvwmsignal.h0000644000175700017570000000405612773467232012745 00000000000000/* -*-c-*- */ #ifndef FVWMSIGNAL_H #define FVWMSIGNAL_H /* This module provides wrappers around system functions that could * potentially block, e.g. select(). These wrappers will check that * the "terminate" flag is still clear and then call the system * function in one atomic operation. This ensures that fvwm will not * block in a system function once it has received the signal to quit. * * This module was written by Chris Rankin, rankinc@zipworld.com.au */ /* This module is intended to use POSIX.1 signal semantics, since most * modern systems can reasonably be expected to support POSIX and since * the semantics of the old "signal()" function vary from system to system. * If POSIX.1 is not available then the module can provide BSD signal * semantics, which can be summarised as follows: * - the signal handler will NOT uninstall itself once it has been called * - a signal will be temporarily blocked from further delivery so long * as its handler is running * - certain system calls will be automatically restarted if interrupted * by a signal */ #if !defined(HAVE_SIGACTION) \ && defined(HAVE_SIGBLOCK) && defined(HAVE_SIGSETMASK) # define USE_BSD_SIGNALS #endif #ifdef USE_BSD_SIGNALS # define BSD_BLOCK_SIGNALS int old_mask = sigblock( fvwmGetSignalMask() ) # define BSB_BLOCK_ALL_SIGNALS int old_mask = sigblock( ~0 ) # define BSD_UNBLOCK_SIGNALS sigsetmask( old_mask ) #else # define BSD_BLOCK_SIGNALS # define BSD_BLOCK_ALL_SIGNALS # define BSD_UNBLOCK_SIGNALS #endif #include #include "ftime.h" #if HAVE_SYS_SELECT_H # include #endif /* * Global variables */ extern volatile sig_atomic_t isTerminated; /* * Module prototypes */ RETSIGTYPE fvwmReapChildren(int sig); extern void fvwmSetTerminate(int sig); #ifdef USE_BSD_SIGNALS extern void fvwmSetSignalMask(int); extern int fvwmGetSignalMask(void); #endif #ifdef HAVE_SELECT extern int fvwmSelect( fd_set_size_t nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); #endif #endif /* FVWMSIGNAL_H */ fvwm-2.6.7/libs/FGettext.c0000644000175700017570000001422613003342500012266 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "safemalloc.h" #include "Strings.h" #include "Parse.h" #include "envvar.h" #include "flist.h" #include "FGettext.h" #include "locale.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ #define FGP_DOMAIN(l) ((FGettextPath *)l->object)->domain #define FGP_DIR(l) ((FGettextPath *)l->object)->dir /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { char *domain; char *dir; } FGettextPath; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static int FGettextInitOk = 0; static char *FGDefaultDir = NULL; static char *FGDefaultDomain = NULL; static const char *FGModuleName = NULL; static flist *FGPathList = NULL; static FGettextPath *FGLastPath = NULL; /* ---------------------------- interface functions ------------------------ */ static void fgettext_add_one_path(char *path, int position) { char *dir,*domain; FGettextPath *tmp; if (!HaveNLSSupport) { return; } domain = GetQuotedString(path, &dir, ";", NULL, NULL, NULL); if (!dir || dir[0] == '\0' || dir[0] != '/') { if (dir) { free(dir); } CopyString(&dir, FGDefaultDir); } if (!domain || domain[0] == '\0') { domain = FGDefaultDomain; } tmp = (FGettextPath *)safemalloc(sizeof(FGettextPath)); tmp->dir = dir; CopyString(&tmp->domain, domain); FGPathList = flist_insert_obj(FGPathList, tmp, position); } static void fgettext_free_fgpath_list(void) { flist *l = FGPathList; if (!HaveNLSSupport) { return; } while(l != NULL) { if (l->object) { if (FGP_DOMAIN(l)) { free(FGP_DOMAIN(l)); } if (FGP_DIR(l)) { free(FGP_DIR(l)); } free(l->object); } l = l->next; } FGLastPath = NULL; FGPathList = flist_free_list(FGPathList); } /* ---------------------------- interface functions ------------------------ */ void FGettextInit(const char *domain, const char *dir, const char *module) { const char *btd; const char *td; if (!HaveNLSSupport) { return; } setlocale (LC_MESSAGES, ""); btd = bindtextdomain (domain, dir); td = textdomain (domain); if (!td || !btd) { fprintf( stderr,"[%s][FGettextInit]: <> " "gettext initialisation fail!\n", module); return; } FGModuleName = module; CopyString(&FGDefaultDir, btd); CopyString(&FGDefaultDomain, td); FGLastPath = (FGettextPath *)safemalloc(sizeof(FGettextPath)); CopyString(&FGLastPath->domain, td); CopyString(&FGLastPath->dir, btd); FGPathList = flist_append_obj(FGPathList, FGLastPath); FGettextInitOk = 1; } const char *FGettext(char *str) { flist *l = FGPathList; const char *s; if (!HaveNLSSupport || !FGettextInitOk || FGPathList == NULL || str == NULL) { return str; } if (FGLastPath != l->object) { (void)bindtextdomain (FGP_DOMAIN(l), FGP_DIR(l)); (void)textdomain (FGP_DOMAIN(l)); FGLastPath = l->object; } s = gettext(str); if (s != str) { return s; } l = l->next; while(l != NULL) { (void)bindtextdomain (FGP_DOMAIN(l), FGP_DIR(l)); (void)textdomain (FGP_DOMAIN(l)); FGLastPath = l->object; s = gettext(str); if (s != str) { return s; } l = l->next; } return str; } char *FGettextCopy(char *str) { const char *trans; char *r = NULL; trans = FGettext(str); if (trans != NULL) { CopyString(&r, trans); } return r; } void FGettextSetLocalePath(const char *path) { char *exp_path = NULL; char *before = NULL; char *after, *p, *str; int count; if (!HaveNLSSupport || !FGettextInitOk) { return; } FGLastPath = NULL; if (path == NULL || path[0] == '\0') { fgettext_free_fgpath_list(); FGLastPath = (FGettextPath *)safemalloc(sizeof(FGettextPath)); CopyString(&FGLastPath->domain, FGDefaultDomain); CopyString(&FGLastPath->dir, FGDefaultDir); FGPathList = flist_append_obj(FGPathList, FGLastPath); FGLastPath = NULL; return; } exp_path = envDupExpand(path, 0); if (StrEquals(exp_path,"None")) { fgettext_free_fgpath_list(); goto bail; } after = GetQuotedString(exp_path, &before, "+", NULL, NULL, NULL); if ((after && strchr(after, '+')) || (before && strchr(before, '+'))) { fprintf( stderr,"[%s][SetLocalePath]: " "To many '+' in locale path specification: %s\n", FGModuleName, path); goto bail; } if (!strchr(exp_path, '+')) { fgettext_free_fgpath_list(); } while(after && *after) { after = GetQuotedString(after, &p, ":", NULL, NULL, NULL); if (p && *p) { fgettext_add_one_path(p,-1); } if (p) { free(p); } } count = 0; str = before; while (str && *str) { str = GetQuotedString(str, &p, ":", NULL, NULL, NULL); if (p && *p) { fgettext_add_one_path(p,count); count++; } if (p) { free(p); } } bail: if (before) { free(before); } if (exp_path) { free(exp_path); } } void FGettextPrintLocalePath(int verbose) { flist *l = FGPathList; if (!HaveNLSSupport || !FGettextInitOk) { return; } fprintf(stderr,"fvwm NLS gettext path:\n"); while(l != NULL) { fprintf( stderr," dir: %s, domain: %s\n", FGP_DIR(l), FGP_DOMAIN(l)); l = l->next; } } fvwm-2.6.7/libs/Graphics.c0000644000175700017570000010075613001406607012307 00000000000000/* -*-c-*- */ /* 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 */ /* Graphics.c: misc convenience functions for drawing stuff */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "defaults.h" #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/PictureBase.h" #include "libs/PictureUtils.h" #include "libs/PictureGraphics.h" #include "libs/gravity.h" #include "libs/FImage.h" #include "libs/Graphics.h" /* ---------------------------- local definitions -------------------------- */ /* Define some standard constants that are not included in the C89 standard */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 #endif #ifndef M_1_PI #define M_1_PI 0.31830988618379067154 #endif /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* Draws the relief pattern around a window * Draws a line_width wide rectangle from (x,y) to (x+w,y+h) i.e w+1 wide, * h+1 high * Draws end points assuming CAP_NOT_LAST style in GC * Draws anti-clockwise in case CAP_BUTT is the style and the end points overlap * Top and bottom lines come out full length, the sides come out 1 pixel less * This is so FvwmBorder windows have a correct bottom edge and the sticky lines * look like just lines * rotation rotate the relief and shadow part */ void do_relieve_rectangle_with_rotation( Display *dpy, Drawable d, int x, int y, int w, int h, GC ReliefGC, GC ShadowGC, int line_width, Bool use_alternate_shading, int rotation) { XSegment* seg; GC shadow_gc, relief_gc; int i,i2; int a; int l; int max_w; int max_h; a = (use_alternate_shading) ? 1 : 0; l = 1 - a; if (w <= 0 || h <= 0) { return; } /* If line_width is negative, reverse the rotation, which will */ /* have the effect of inverting the relief. */ if (line_width < 0) { line_width = -line_width; rotation = gravity_add_rotations(rotation, ROTATION_180); } switch (rotation) { case ROTATION_180: case ROTATION_270: rotation = gravity_add_rotations(rotation, ROTATION_180); shadow_gc = ReliefGC; relief_gc = ShadowGC; break; default: shadow_gc = ShadowGC; relief_gc = ReliefGC; break; } max_w = min((w + 1) / 2, line_width); max_h = min((h + 1) / 2, line_width); seg = (XSegment*)alloca((sizeof(XSegment) * line_width) * 2); /* from 0 to the lesser of line_width & just over half w */ for (i = 0; i < max_w; i++) { if (rotation == ROTATION_0) { /* left */ seg[i].x1 = x+i; seg[i].y1 = y+i+a; seg[i].x2 = x+i; seg[i].y2 = y+h-i+a; } else /* ROTATION_90 */ { /* right */ seg[i].x1 = x+w-i; seg[i].y1 = y+h-i-a; seg[i].x2 = x+w-i; seg[i].y2 = y+i+1-a; } } i2 = i; /* draw top segments */ for (i = 0; i < max_h; i++,i2++) { seg[i2].x1 = x+w-i-a; seg[i2].y1 = y+i; seg[i2].x2 = x+i+1-a; seg[i2].y2 = y+i; } XDrawSegments(dpy, d, relief_gc, seg, i2); /* bottom */ for (i = 0; i < max_h; i++) { seg[i].x1 = x+i+a+l; seg[i].y1 = y+h-i; seg[i].x2 = x+w-i-1+a; seg[i].y2 = y+h-i; } i2 = i; for (i = 0; i < max_w; i++,i2++) { if (rotation == ROTATION_0) { /* right */ seg[i2].x1 = x+w-i; seg[i2].y1 = y+h-i-a; seg[i2].x2 = x+w-i; seg[i2].y2 = y+i+1-a; } else /* ROTATION_90 */ { /* left */ seg[i2].x1 = x+i; seg[i2].y1 = y+i+a; seg[i2].x2 = x+i; seg[i2].y2 = y+h-i+a; } } XDrawSegments(dpy, d, shadow_gc, seg, i2); return; } void do_relieve_rectangle( Display *dpy, Drawable d, int x, int y, int w, int h, GC ReliefGC, GC ShadowGC, int line_width, Bool use_alternate_shading) { do_relieve_rectangle_with_rotation( dpy, d, x, y, w, h, ReliefGC, ShadowGC, line_width, use_alternate_shading, ROTATION_0); return; } /* Creates a pixmap that is a horizontally stretched version of the input * pixmap */ Pixmap CreateStretchXPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_width, GC gc) { int i; Pixmap pixmap; GC my_gc = None; if (src_width < 0 || src_height < 0 || dest_width < 0) { return None; } pixmap = XCreatePixmap(dpy, src, dest_width, src_height, src_depth); if (pixmap == None) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, pixmap, 0, 0); } for (i = 0; i < dest_width; i++) { XCopyArea( dpy, src, pixmap, (gc == None)? my_gc:gc, (i * src_width) / dest_width, 0, 1, src_height, i, 0); } if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; } /* Creates a pixmap that is a vertically stretched version of the input * pixmap */ Pixmap CreateStretchYPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_height, GC gc) { int i; Pixmap pixmap; GC my_gc = None; if (src_height < 0 || src_depth < 0 || dest_height < 0) { return None; } pixmap = XCreatePixmap(dpy, src, src_width, dest_height, src_depth); if (pixmap == None) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, pixmap, 0, 0); } for (i = 0; i < dest_height; i++) { XCopyArea( dpy, src, pixmap, (gc == None)? my_gc:gc, 0, (i * src_height) / dest_height, src_width, 1, 0, i); } if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; } /* Creates a pixmap that is a stretched version of the input * pixmap */ Pixmap CreateStretchPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_width, int dest_height, GC gc) { Pixmap pixmap = None; Pixmap temp_pixmap; GC my_gc = None; if (src_width < 0 || src_height < 0 || src_depth < 0 || dest_width < 0) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, src, 0, 0); } temp_pixmap = CreateStretchXPixmap( dpy, src, src_width, src_height, src_depth, dest_width, (gc == None)? my_gc:gc); if (temp_pixmap == None) { if (my_gc) { XFreeGC(dpy, my_gc); } return None; } pixmap = CreateStretchYPixmap( dpy, temp_pixmap, dest_width, src_height, src_depth, dest_height, (gc == None)? my_gc:gc); XFreePixmap(dpy, temp_pixmap); if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; } /* Creates a pixmap that is a tiled version of the input pixmap. Modifies the * sets the fill_style of the GC to FillSolid and the tile to None. */ Pixmap CreateTiledPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int dest_width, int dest_height, int depth, GC gc) { XGCValues xgcv; Pixmap pixmap; if (src_width < 0 || src_height < 0 || dest_width < 0 || dest_height < 0) { return None; } pixmap = XCreatePixmap(dpy, src, dest_width, dest_height, depth); if (pixmap == None) { return None; } xgcv.fill_style = FillTiled; xgcv.tile = src; xgcv.ts_x_origin = 0; xgcv.ts_y_origin = 0; XChangeGC( dpy, gc, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &xgcv); XFillRectangle(dpy, pixmap, gc, 0, 0, dest_width, dest_height); xgcv.fill_style = FillSolid; XChangeGC(dpy, gc, GCFillStyle, &xgcv); return pixmap; } Pixmap CreateRotatedPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int depth, GC gc, int rotation) { GC my_gc = None; Pixmap pixmap = None; int dest_width, dest_height, i, j; Bool error = False; FImage *fim = NULL; FImage *src_fim = NULL; if (src_width <= 0 || src_height <= 0) { return None; } switch(rotation) { case ROTATION_90: case ROTATION_270: dest_width = src_height; dest_height = src_width; break; case ROTATION_0: case ROTATION_180: dest_width = src_width; dest_height = src_height; break; default: return None; break; } pixmap = XCreatePixmap(dpy, src, dest_width, dest_height, depth); if (pixmap == None) { return None; } if (gc == None) { my_gc = fvwmlib_XCreateGC(dpy, src, 0, 0); } if (rotation == ROTATION_0) { XCopyArea( dpy, src, pixmap, (gc == None)? my_gc:gc, 0, 0, src_width, src_height, 0, 0); goto bail; } if (!(src_fim = FGetFImage( dpy, src, Pvisual, depth, 0, 0, src_width, src_height, AllPlanes, ZPixmap))) { error = True; goto bail; } if (!(fim = FCreateFImage( dpy, Pvisual, depth, ZPixmap, dest_width, dest_height))) { error = True; goto bail; } for (j = 0; j < src_height; j++) { for (i = 0; i < src_width; i++) { switch(rotation) { case ROTATION_270: XPutPixel( fim->im, j, src_width - i - 1, XGetPixel(src_fim->im, i, j)); break; case ROTATION_90: XPutPixel( fim->im, src_height - j - 1, i, XGetPixel(src_fim->im, i, j)); break; case ROTATION_180: XPutPixel( fim->im, src_width - i - 1, src_height - j - 1, XGetPixel(src_fim->im, i, j)); break; default: break; } } } FPutFImage(dpy, pixmap, gc, fim, 0, 0, 0, 0, dest_width, dest_height); bail: if (error && pixmap) { XFreePixmap(dpy,pixmap); pixmap = None; } if (fim) { FDestroyFImage(dpy, fim); } if (src_fim) { FDestroyFImage(dpy, src_fim); } if (my_gc) { XFreeGC(dpy, my_gc); } return pixmap; } /* * * Returns True if the given type of gradient is supported. * */ Bool IsGradientTypeSupported(char type) { switch (toupper(type)) { case V_GRADIENT: case H_GRADIENT: case B_GRADIENT: case D_GRADIENT: case R_GRADIENT: case Y_GRADIENT: case S_GRADIENT: case C_GRADIENT: return True; default: fprintf(stderr, "%cGradient type is not supported\n", toupper(type)); return False; } } /* * * Allocates a linear color gradient (veliaa@rpi.edu) * */ static XColor *AllocLinearGradient( char *s_from, char *s_to, int npixels, int skip_first_color, int dither) { XColor *xcs; XColor from, to, c; float r; float dr; float g; float dg; float b; float db; int i; int got_all = 1; int div; if (npixels < 1) { fprintf(stderr, "AllocLinearGradient: Invalid number of pixels: %d\n", npixels); return NULL; } if (!s_from || !XParseColor(Pdpy, Pcmap, s_from, &from)) { fprintf(stderr, "Cannot parse color \"%s\"\n", s_from ? s_from : ""); return NULL; } if (!s_to || !XParseColor(Pdpy, Pcmap, s_to, &to)) { fprintf(stderr, "Cannot parse color \"%s\"\n", s_to ? s_to : ""); return NULL; } /* divisor must not be zero, hence this calculation */ div = (npixels == 1) ? 1 : npixels - 1; c = from; /* red part and step width */ r = from.red; dr = (float)(to.red - from.red); /* green part and step width */ g = from.green; dg = (float)(to.green - from.green); /* blue part and step width */ b = from.blue; db = (float)(to.blue - from.blue); xcs = (XColor *)safemalloc(sizeof(XColor) * npixels); memset(xcs, 0, sizeof(XColor) * npixels); c.flags = DoRed | DoGreen | DoBlue; for (i = (skip_first_color) ? 1 : 0; i < npixels && div > 0; ++i) { c.red = (unsigned short) ((int)(r + dr / (float)div * (float)i + 0.5)); c.green = (unsigned short) ((int)(g + dg / (float)div * (float)i + 0.5)); c.blue = (unsigned short) ((int)(b + db / (float)div * (float)i + 0.5)); if (dither == 0 && !PictureAllocColor(Pdpy, Pcmap, &c, False)) { got_all = 0; } xcs[i] = c; } if (!got_all && dither == 0) { fprintf(stderr, "Cannot alloc color gradient %s to %s\n", s_from, s_to); } return xcs; } /* * * Allocates a nonlinear color gradient (veliaa@rpi.edu) * */ static XColor *AllocNonlinearGradient( char *s_colors[], int clen[], int nsegs, int npixels, int dither) { XColor *xcs = (XColor *)safemalloc(sizeof(XColor) * npixels); int i; int curpixel = 0; int *seg_end_colors; int seg_sum = 0; float color_sum = 0.0; if (nsegs < 1 || npixels < 2) { fprintf(stderr, "Gradients must specify at least one segment and" " two colors\n"); free(xcs); return NULL; } for (i = 0; i < npixels; i++) { xcs[i].pixel = 0; } /* get total length of all segments */ for (i = 0; i < nsegs; i++) { seg_sum += clen[i]; } /* calculate the index of a segment's las color */ seg_end_colors = alloca(nsegs * sizeof(int)); if (nsegs == 1) { seg_end_colors[0] = npixels - 1; } else { for (i = 0; i < nsegs; i++) { color_sum += (float)(clen[i] * (npixels - 1)) / (float)(seg_sum); seg_end_colors[i] = (int)(color_sum + 0.5); } if (seg_end_colors[nsegs - 1] > npixels - 1) { fprintf(stderr, "BUG: (AllocNonlinearGradient): " "seg_end_colors[nsegs - 1] (%d)" " > npixels - 1 (%d)." " Gradient drawing aborted\n", seg_end_colors[nsegs - 1], npixels - 1); return NULL; } /* take care of rounding errors */ seg_end_colors[nsegs - 1] = npixels - 1; } for (i = 0; i < nsegs; ++i) { XColor *c = NULL; int j; int n; int skip_first_color = (curpixel != 0); if (i == 0) { n = seg_end_colors[0] + 1; } else { n = seg_end_colors[i] - seg_end_colors[i - 1] + 1; } if (n > 1) { c = AllocLinearGradient( s_colors[i], s_colors[i + 1], n, skip_first_color, dither); if (!c && (n - skip_first_color) != 0) { free(xcs); return NULL; } for (j = skip_first_color; j < n; ++j) { xcs[curpixel + j] = c[j]; } curpixel += n - 1; } if (c) { free(c); c = NULL; } if (curpixel != seg_end_colors[i]) { fprintf(stderr, "BUG: (AllocNonlinearGradient): " "nsegs %d, i %d, curpixel %d," " seg_end_colors[i] = %d," " npixels %d, n %d\n", nsegs, i, curpixel, seg_end_colors[i],npixels,n); return NULL; } } return xcs; } /* Convenience function. Calls AllocNonLinearGradient to fetch all colors and * then frees the color names and the perc and color_name arrays. */ XColor *AllocAllGradientColors( char *color_names[], int perc[], int nsegs, int ncolors, int dither) { XColor *xcs = NULL; int i; /* grab the colors */ xcs = AllocNonlinearGradient( color_names, perc, nsegs, ncolors, dither); for (i = 0; i <= nsegs; i++) { if (color_names[i]) { free(color_names[i]); } } free(color_names); free(perc); if (!xcs) { fprintf(stderr, "couldn't create gradient\n"); return NULL; } return xcs; } /* groks a gradient string and creates arrays of colors and percentages * returns the number of colors asked for (No. allocated may be less due * to the ColorLimit command). A return of 0 indicates an error */ int ParseGradient( char *gradient, char **rest, char ***colors_return, int **perc_return, int *nsegs_return) { char *item; char *orig; int npixels; char **s_colors; int *perc; int nsegs, i, sum; Bool is_syntax_error = False; /* get the number of colors specified */ if (rest) { *rest = gradient; } orig = gradient; if (GetIntegerArguments(gradient, &gradient, (int *)&npixels, 1) != 1 || npixels < 2) { fprintf( stderr, "ParseGradient: illegal number of colors in" " gradient: '%s'\n", orig); return 0; } /* get the starting color or number of segments */ gradient = GetNextToken(gradient, &item); if (gradient) { gradient = SkipSpaces(gradient, NULL, 0); } if (!gradient || !*gradient || !item) { fprintf(stderr, "Incomplete gradient style: '%s'\n", orig); if (item) { free(item); } if (rest) { *rest = gradient; } return 0; } if (GetIntegerArguments(item, NULL, &nsegs, 1) != 1) { /* get the end color of a simple gradient */ s_colors = (char **)safemalloc(sizeof(char *) * 2); perc = (int *)safemalloc(sizeof(int)); nsegs = 1; s_colors[0] = item; gradient = GetNextToken(gradient, &item); s_colors[1] = item; perc[0] = 100; } else { free(item); /* get a list of colors and percentages */ if (nsegs < 1) nsegs = 1; if (nsegs > MAX_GRADIENT_SEGMENTS) nsegs = MAX_GRADIENT_SEGMENTS; s_colors = (char **)safemalloc(sizeof(char *) * (nsegs + 1)); perc = (int *)safemalloc(sizeof(int) * nsegs); for (i = 0; !is_syntax_error && i <= nsegs; i++) { s_colors[i] = 0; gradient = GetNextToken(gradient, &s_colors[i]); if (i < nsegs) { if (GetIntegerArguments( gradient, &gradient, &perc[i], 1) != 1 || perc[i] <= 0) { /* illegal size */ perc[i] = 0; } } } if (s_colors[nsegs] == NULL) { fprintf( stderr, "ParseGradient: too few gradient" " segments: '%s'\n", orig); is_syntax_error = True; } } /* sanity check */ for (i = 0, sum = 0; !is_syntax_error && i < nsegs; ++i) { int old_sum = sum; sum += perc[i]; if (sum < old_sum) { /* integer overflow */ fprintf( stderr, "ParseGradient: multi gradient" " overflow: '%s'", orig); is_syntax_error = 1; break; } } if (is_syntax_error) { for (i = 0; i <= nsegs; ++i) { if (s_colors[i]) { free(s_colors[i]); } } free(s_colors); free(perc); if (rest) { *rest = gradient; } return 0; } /* sensible limits */ if (npixels < 2) npixels = 2; if (npixels > MAX_GRADIENT_COLORS) npixels = MAX_GRADIENT_COLORS; /* send data back */ *colors_return = s_colors; *perc_return = perc; *nsegs_return = nsegs; if (rest) *rest = gradient; return npixels; } /* Calculate the prefered dimensions of a gradient, based on the number of * colors and the gradient type. Returns False if the gradient type is not * supported. */ Bool CalculateGradientDimensions( Display *dpy, Drawable d, int ncolors, char type, int dither, int *width_ret, int *height_ret) { static int best_width = 0, best_height = 0; int dither_factor = (dither > 0)? 128:1; /* get the best tile size (once) */ if (!best_width) { if (!XQueryBestTile( dpy, d, 1, 1, (unsigned int*)&best_width, (unsigned int*)&best_height)) { best_width = 0; best_height = 0; } /* this is needed for buggy X servers like XFree 3.3.3.1 */ if (!best_width) best_width = 1; if (!best_height) best_height = 1; } switch (type) { case H_GRADIENT: *width_ret = ncolors; *height_ret = best_height * dither_factor; break; case V_GRADIENT: *width_ret = best_width * dither_factor; *height_ret = ncolors; break; case D_GRADIENT: case B_GRADIENT: /* diagonal gradients are rendered into a rectangle for which * the width plus the height is equal to ncolors + 1. The * rectangle is square when ncolors is odd and one pixel * taller than wide with even numbers */ *width_ret = (ncolors + 1) / 2; *height_ret = ncolors + 1 - *width_ret; break; case S_GRADIENT: /* square gradients have the last color as a single pixel in * the centre */ *width_ret = *height_ret = 2 * ncolors - 1; break; case C_GRADIENT: /* circular gradients have the first color as a pixel in each * corner */ *width_ret = *height_ret = 2 * ncolors - 1; break; case R_GRADIENT: case Y_GRADIENT: /* swept types need each color to occupy at least one pixel at * the edge. Get the smallest odd number that will provide * enough */ for (*width_ret = 1; (double)(*width_ret - 1) * M_PI < (double)ncolors; *width_ret += 2) { /* nothing to do here */ } *height_ret = *width_ret; break; default: fprintf(stderr, "%cGradient not supported\n", type); return False; } return True; } /* Does the actual drawing of the pixmap. If the in_drawable argument is None, * a new pixmap of the given depth, width and height is created. If it is not * None the gradient is drawn into it. The d_width, d_height, d_x and d_y * describe the traget rectangle within the drawable. */ Drawable CreateGradientPixmap( Display *dpy, Drawable d, GC gc, int type, int g_width, int g_height, int ncolors, XColor *xcs, int dither, Pixel **d_pixels, int *d_npixels, Drawable in_drawable, int d_x, int d_y, int d_width, int d_height, XRectangle *rclip) { Pixmap pixmap = None; PictureImageColorAllocator *pica = NULL; XColor c; FImage *fim; register int i, j; XGCValues xgcv; Drawable target; int t_x; int t_y; int t_width; int t_height; if (d_pixels != NULL && *d_pixels != NULL) { if (d_npixels != NULL && *d_npixels > 0) { PictureFreeColors( dpy, Pcmap, *d_pixels, *d_npixels, 0, False); } free(*d_pixels); *d_pixels = NULL; } if (d_npixels != NULL) { *d_npixels = 0; } if (g_height < 0 || g_width < 0 || d_width < 0 || d_height < 0) return None; if (in_drawable == None) { /* create a pixmap to use */ pixmap = XCreatePixmap(dpy, d, g_width, g_height, Pdepth); if (pixmap == None) return None; target = pixmap; t_x = 0; t_y = 0; t_width = g_width; t_height = g_height; } else { target = in_drawable; t_x = d_x; t_y = d_y; t_width = d_width; t_height = d_height; } fim = FCreateFImage( dpy, Pvisual, Pdepth, ZPixmap, t_width, t_height); if (!fim) { fprintf(stderr, "%cGradient couldn't get image\n", type); if (pixmap != None) XFreePixmap(dpy, pixmap); return None; } if (dither) { pica = PictureOpenImageColorAllocator( dpy, Pcmap, t_width, t_height, False, False, dither, False); } /* now do the fancy drawing */ switch (type) { case H_GRADIENT: { for (i = 0; i < t_width; i++) { int d = i * ncolors / t_width; c = xcs[d]; for (j = 0; j < t_height; j++) { if (dither) { c = xcs[d]; PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } } break; case V_GRADIENT: { for (j = 0; j < t_height; j++) { int d = j * ncolors / t_height; c = xcs[d]; for (i = 0; i < t_width; i++) { if (dither) { c = xcs[d]; PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } break; } case D_GRADIENT: { register int t_scale = t_width + t_height - 1; for (i = 0; i < t_width; i++) { for (j = 0; j < t_height; j++) { c = xcs[(i+j) * ncolors / t_scale]; if (dither) { PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } break; } case B_GRADIENT: { register int t_scale = t_width + t_height - 1; for (i = 0; i < t_width; i++) { for (j = 0; j < t_height; j++) { c = xcs[(i + (t_height - j - 1)) * ncolors / t_scale]; if (dither) { PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } break; } case S_GRADIENT: { register int t_scale = t_width * t_height; register int myncolors = ncolors * 2; for (i = 0; i < t_width; i++) { register int pi = min(i, t_width - 1 - i) * t_height; for (j = 0; j < t_height; j++) { register int pj = min(j, t_height - 1 - j) * t_width; c = xcs[(min(pi, pj) * myncolors - 1) / t_scale]; if (dither) { PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } } break; case C_GRADIENT: { register double t_scale = (double)(t_width * t_height) / sqrt(8); for (i = 0; i < t_width; i++) { for (j = 0; j < t_height; j++) { register double x = (double)((2 * i - t_width) * t_height) / 4.0; register double y = (double)((t_height - 2 * j) * t_width) / 4.0; register double rad = sqrt(x * x + y * y); c = xcs[(int)((rad * ncolors - 0.5) / t_scale)]; if (dither) { PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } break; } case R_GRADIENT: { register int w = t_width - 1; register int h = t_height - 1; /* g_width == g_height, both are odd, therefore x can be 0.0 */ for (i = 0; i <= w; i++) { for (j = 0; j <= h; j++) { register double x = (double)((2 * i - w) * h) / 4.0; register double y = (double)((h - 2 * j) * w) / 4.0; /* angle ranges from -pi/2 to +pi/2 */ register double angle; if (x != 0.0) { angle = atan(y / x); } else { angle = (y < 0) ? - M_PI_2 : M_PI_2; } /* extend to -pi/2 to 3pi/2 */ if (x < 0) angle += M_PI; /* move range from -pi/2:3*pi/2 to 0:2*pi */ if (angle < 0.0) angle += M_PI * 2.0; /* normalize to gradient */ c = xcs[(int)(angle * M_1_PI * 0.5 * ncolors)]; if (dither) { PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } } break; /* * The Yin Yang gradient style and the following code are: * Copyright 1999 Sir Boris. (email to sir_boris@bigfoot.com may be * read by his groom but is not guaranteed to elicit a response) * No restrictions are placed on this code, as long as the copyright * notice is preserved. */ case Y_GRADIENT: { register int r = t_width * t_height / 4; for (i = 0; i < t_width; i++) { for (j = 0; j < t_height; j++) { register double x = (double)((2 * i - t_width) * t_height) / 4.0; register double y = (double)((t_height - 2 * j) * t_width) / 4.0; register double rad = sqrt(x * x + y * y); /* angle ranges from -pi/2 to +pi/2 */ register double angle; if (x != 0.0) { angle = atan(y / x); } else { angle = (y < 0) ? - M_PI_2 : M_PI_2; } /* extend to -pi/2 to 3pi/2 */ if (x < 0) angle += M_PI; /* warp the angle within the yinyang circle */ if (rad <= r) { angle -= acos(rad / r); } /* move range from -pi/2:3*pi/2 to 0:2*pi */ if (angle < 0.0) angle += M_PI * 2.0; /* normalize to gradient */ c = xcs[(int)(angle * M_1_PI * 0.5 * ncolors)]; if (dither) { PictureAllocColorImage( dpy, pica, &c, i, j); } XPutPixel(fim->im, i, j, c.pixel); } } } break; default: /* placeholder function, just fills the pixmap with the first * color */ memset(fim->im->data, 0, fim->im->bytes_per_line * t_height); XAddPixel(fim->im, xcs[0].pixel); break; } if (dither) { if (d_pixels != NULL && d_npixels != NULL) { PictureCloseImageColorAllocator( dpy, pica, d_npixels, d_pixels, 0); } else { /* possible color leak */ } } /* set the gc style */ xgcv.function = GXcopy; xgcv.plane_mask = AllPlanes; xgcv.fill_style = FillSolid; xgcv.clip_mask = None; XChangeGC(dpy, gc, GCFunction|GCPlaneMask|GCFillStyle|GCClipMask, &xgcv); if (rclip) { XSetClipRectangles(dpy, gc, 0, 0, rclip, 1, Unsorted); } /* copy the image to the server */ FPutFImage(dpy, target, gc, fim, 0, 0, t_x, t_y, t_width, t_height); if (rclip) { XSetClipMask(dpy, gc, None); } FDestroyFImage(dpy, fim); return target; } /* Create a pixmap from a gradient specifier, width and height are hints * that are only used for gradients that can be tiled e.g. H or V types * types are HVDBSCRY for Horizontal, Vertical, Diagonal, Back-diagonal, Square, * Circular, Radar and Yin/Yang respectively (in order of bloatiness) */ Pixmap CreateGradientPixmapFromString( Display *dpy, Drawable d, GC gc, int type, char *action, int *width_return, int *height_return, Pixel **pixels_return, int *nalloc_pixels, int dither) { Pixel *d_pixels = NULL; int d_npixels = 0; XColor *xcs = NULL; int ncolors = 0; char **colors; int *perc, nsegs; Pixmap pixmap = None; /* set return pixels to NULL in case of premature return */ if (pixels_return) *pixels_return = NULL; if (nalloc_pixels) *nalloc_pixels = 0; /* translate the gradient string into an array of colors etc */ if (!(ncolors = ParseGradient(action, NULL, &colors, &perc, &nsegs))) { fprintf(stderr, "Can't parse gradient: '%s'\n", action); return None; } /* grab the colors */ xcs = AllocAllGradientColors( colors, perc, nsegs, ncolors, dither); if (xcs == NULL) { return None; } /* grok the size to create from the type */ type = toupper(type); if (CalculateGradientDimensions( dpy, d, ncolors, type, dither, width_return, height_return)) { pixmap = CreateGradientPixmap( dpy, d, gc, type, *width_return, *height_return, ncolors, xcs, dither, &d_pixels, &d_npixels, None, 0, 0, 0, 0, NULL); } /* if the caller has not asked for the pixels there is probably a leak */ if (PUseDynamicColors) { if (!(pixels_return && nalloc_pixels)) { /* if the caller has not asked for the pixels there is * probably a leak */ fprintf(stderr, "CreateGradient: potential color leak, losing track" " of pixels\n"); if (d_pixels != NULL) { free(d_pixels); } } else { if (!dither) { Pixel *pixels; int i; pixels = (Pixel *)safemalloc( ncolors * sizeof(Pixel)); for(i=0; igraphics_exposures; if (!(valuemask & GCGraphicsExposures)) { valuemask |= GCGraphicsExposures; values->graphics_exposures = 0; } gc = XCreateGC(display, drawable, valuemask, values); values->graphics_exposures = f; return gc; } fvwm-2.6.7/libs/Fsvg.h0000644000175700017570000000466712773467232011505 00000000000000#ifndef FSVG_H #define FSVG_H #ifdef HAVE_RSVG #define USE_SVG 1 #else #define USE_SVG 0 #endif #include "PictureBase.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #if USE_SVG # include # include typedef RsvgDimensionData FRsvgDimensionData; typedef RsvgHandle FRsvgHandle; typedef cairo_surface_t Fcairo_surface_t; typedef cairo_t Fcairo_t; # define FCAIRO_FORMAT_ARGB32 CAIRO_FORMAT_ARGB32 # define FCAIRO_STATUS_SUCCESS CAIRO_STATUS_SUCCESS # define FG_OBJECT(a) G_OBJECT(a) # define Fg_object_unref(a) g_object_unref(a) # define Frsvg_handle_get_dimensions(a, b) \ rsvg_handle_get_dimensions(a, b) # define Frsvg_handle_new_from_file(a, b) rsvg_handle_new_from_file(a, b) # define Frsvg_handle_render_cairo(a, b) rsvg_handle_render_cairo(a, b) /* TA: 2013-01-22 -- rsvg_init() has been deprecated since version 2.36; but * RSVG doesn't define a version of its own to check against. Since RSVG uses * glib, we can check its version instead. */ #if !GLIB_CHECK_VERSION (2, 31, 0) # define Frsvg_init() rsvg_init() #endif #if !GLIB_CHECK_VERSION(2,35,0) # define Frsvg_init() g_type_init() #endif # define Fcairo_create(a) cairo_create(a) # define Fcairo_destroy(a) cairo_destroy(a) # define Fcairo_image_surface_create_for_data(a,b,c,d,e) \ cairo_image_surface_create_for_data(a,b,c,d,e) # define Fcairo_rotate(a, b) cairo_rotate(a, b) # define Fcairo_scale(a, b, c) cairo_scale(a, b, c) # define Fcairo_status(a) cairo_status(a) # define Fcairo_surface_destroy(a) cairo_surface_destroy(a) # define Fcairo_surface_status(a) cairo_surface_status(a) # define Fcairo_translate(a, b, c) cairo_translate(a, b, c) #else typedef struct { int width; int height; double em; double ex; } FRsvgDimensionData; typedef void FRsvgHandle; typedef void Fcairo_surface_t; typedef void Fcairo_t; # define FCAIRO_FORMAT_ARGB32 0 # define FCAIRO_STATUS_SUCCESS 0 # define FG_OBJECT(a) # define Fg_object_unref(a) # define Frsvg_handle_get_dimensions(a, b) # define Frsvg_handle_new_from_file(a, b) 0 # define Frsvg_handle_render_cairo(a, b) # define Frsvg_init() # define Fcairo_create(a) 0 # define Fcairo_destroy(a) # define Fcairo_image_surface_create_for_data(a,b,c,d,e) 0 # define Fcairo_rotate(a, b) # define Fcairo_scale(a, b, c) # define Fcairo_status(a) 0 # define Fcairo_surface_destroy(a) # define Fcairo_surface_status(a) 0 # define Fcairo_translate(a, b, c) #endif #endif /* FSVG_H */ fvwm-2.6.7/libs/gravity.h0000644000175700017570000000520212773467232012247 00000000000000/* -*-c-*- */ #ifndef GRAVITY_H #define GRAVITY_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { DIR_NONE = -1, DIR_N = 0, DIR_E = 1, DIR_S = 2, DIR_W = 3, DIR_MAJOR_MASK = 3, DIR_NE = 4, DIR_SE = 5, DIR_SW = 6, DIR_NW = 7, DIR_MINOR_MASK = 7, DIR_MASK = 7, DIR_C = 8, DIR_ALL_MASK = 8 } direction_t; typedef enum { MULTI_DIR_NONE = 0, MULTI_DIR_FIRST = (1 << DIR_N), MULTI_DIR_N = (1 << DIR_N), MULTI_DIR_E = (1 << DIR_E), MULTI_DIR_S = (1 << DIR_S), MULTI_DIR_W = (1 << DIR_W), MULTI_DIR_NE = (1 << DIR_NE), MULTI_DIR_SE = (1 << DIR_SE), MULTI_DIR_SW = (1 << DIR_SW), MULTI_DIR_NW = (1 << DIR_NW), MULTI_DIR_ALL = ((1 << (DIR_MASK + 1)) - 1), MULTI_DIR_C = (1 << DIR_C), MULTI_DIR_LAST = (1 << DIR_ALL_MASK) } multi_direction_t; typedef enum { ROTATION_0 = 0, ROTATION_90 = 1, ROTATION_180 = 2, ROTATION_270 = 3, ROTATION_MASK = 3 } rotation_t; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void gravity_get_offsets(int grav, int *xp,int *yp); void gravity_move(int gravity, rectangle *rect, int xdiff, int ydiff); void gravity_resize(int gravity, rectangle *rect, int wdiff, int hdiff); void gravity_move_resize_parent_child( int child_gravity, rectangle *parent_diff_r, rectangle *child_r); direction_t gravity_grav_to_dir( int grav); int gravity_dir_to_grav( direction_t dir); int gravity_combine_xy_grav( int grav_x, int grav_y); void gravity_split_xy_grav( int *ret_grav_x, int *ret_grav_y, int in_grav); int gravity_combine_xy_dir( int dir_x, int dir_y); void gravity_split_xy_dir( int *ret_dir_x, int *ret_dir_y, int in_dir); int gravity_override_dir( int dir_orig, int dir_mod); int gravity_dir_to_sign_one_axis( direction_t dir); direction_t gravity_parse_dir_argument( char *action, char **ret_action, direction_t default_ret); char *gravity_dir_to_string(direction_t dir, char *default_str); multi_direction_t gravity_parse_multi_dir_argument( char *action, char **ret_action); void gravity_get_next_multi_dir(int dir_set, multi_direction_t *dir); direction_t gravity_multi_dir_to_dir(multi_direction_t mdir); void gravity_rotate_xy(rotation_t rot, int x, int y, int *ret_x, int *ret_y); rotation_t gravity_add_rotations(rotation_t rot1, rotation_t rot2); #endif /* GRAVITY_H */ fvwm-2.6.7/libs/setpgrp.c0000644000175700017570000000224612773467232012246 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Dominik Vogt */ /* 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 */ /* ** setpgrp.c: ** Provides a portable replacement for setpgrp */ #include "config.h" #include #include "setpgrp.h" int fvwm_setpgrp(void) { int rc; #ifdef HAVE_SETPGID rc = setpgid(0, 0); #else # ifdef HAVE_SETPGRP # ifdef SETPGRP_VOID rc = setpgrp(); # else rc = setpgrp(0, 0); # endif # else /* neither setpgrp nor setpgid - just do nothing */ rc = 0; # endif #endif return rc; } fvwm-2.6.7/libs/FImage.c0000644000175700017570000001315713003342500011666 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "libs/fvwmlib.h" #include "libs/PictureBase.h" #include "libs/FImage.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ int FShmMajorOpCode = -10000; int FShmEventBase = -10000; int FShmErrorBase = -10000; Bool FShmInitialized = False; Bool FShmImagesSupported = False; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static int FShmErrorHandler(Display *dpy, XErrorEvent *ev) { FShmImagesSupported = False; return 0; } static void FShmInit(Display *dpy) { if (FShmInitialized) { return; } FShmInitialized = True; if (!XShmSupport) { return; } FShmImagesSupported = XQueryExtension( dpy, "MIT-SHM", &FShmMajorOpCode, &FShmEventBase, &FShmErrorBase); } static void FShmSafeCreateImage( Display *dpy, FImage *fim, Visual *visual, unsigned int depth, int format, unsigned int width, unsigned int height) { Bool error = False; XErrorHandler save_handler; if (!XShmSupport) { return; } fim->shminfo = (FShmSegmentInfo *)safecalloc( 1, sizeof(FShmSegmentInfo)); if (!(fim->im = FShmCreateImage( dpy, visual, depth, format, NULL, fim->shminfo, width, height))) { error = True; goto bail; } fim->shminfo->shmid = Fshmget( IPC_PRIVATE, fim->im->bytes_per_line * fim->im->height, IPC_CREAT|0777); if (fim->shminfo->shmid <= 0) { error = True; goto bail; } fim->shminfo->shmaddr = fim->im->data = Fshmat( fim->shminfo->shmid, 0, 0); if (fim->shminfo->shmaddr == (char *)(-1)) { error = True; goto bail; } fim->shminfo->readOnly = False; /* use the error handler for a definitive error */ save_handler = XSetErrorHandler(FShmErrorHandler); if (!FShmAttach(dpy, fim->shminfo)) { error = True; } else { XSync(dpy, False); } if (!error && !FShmImagesSupported) { /* get an X error: we are a remote client */ if (FShmDetach(dpy, fim->shminfo)) { XSync(dpy, False); } error = True; } XSetErrorHandler(save_handler); bail: if (error) { if (fim->im) { XDestroyImage (fim->im); fim->im = NULL; } if (fim->shminfo->shmaddr) { Fshmdt(fim->shminfo->shmaddr); } if (fim->shminfo->shmid > 0) { Fshmctl(fim->shminfo->shmid, IPC_RMID, 0); } free(fim->shminfo); fim->shminfo = NULL; } } /* ---------------------------- interface functions ------------------------ */ FImage *FCreateFImage ( Display *dpy, Visual *visual, unsigned int depth, int format, unsigned int width, unsigned int height) { FImage *fim; FShmInit(dpy); fim = (FImage *)safemalloc(sizeof(FImage)); fim->im = NULL; fim->shminfo = NULL; if (XShmSupport && FShmImagesSupported) { FShmSafeCreateImage( dpy, fim, visual, depth, format, width, height); } if(!fim->im ) { if ((fim->im = XCreateImage( dpy, visual, depth, ZPixmap, 0, 0, width, height, Pdepth > 16 ? 32 : (Pdepth > 8 ? 16 : 8), 0))) { fim->im->data = safemalloc( fim->im->bytes_per_line * height); } else { free(fim); } } return fim; } FImage *FGetFImage( Display *dpy, Drawable d, Visual *visual, unsigned int depth, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format) { FImage *fim; FShmInit(dpy); fim = (FImage *)safemalloc(sizeof(FImage)); fim->im = NULL; fim->shminfo = NULL; if (XShmSupport && FShmImagesSupported) { FShmSafeCreateImage( dpy, fim, visual, depth, format, width, height); if (fim->im) { (void)FShmGetImage(dpy, d, fim->im, x, y, plane_mask); } } if (!fim->im) { fim->im = XGetImage( dpy, d, x, y, width, height, plane_mask, format); } return fim; } void FPutFImage( Display *dpy, Drawable d, GC gc, FImage *fim, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height) { if (fim->shminfo) { if (FShmPutImage( dpy, d, gc, fim->im, src_x, src_y, dest_x, dest_y, width, height, False)) { } } else { XPutImage( dpy, d, gc, fim->im, src_x, src_y, dest_x, dest_y, width, height); } } void FDestroyFImage(Display *dpy, FImage *fim) { if (fim->shminfo) { if (FShmDetach(dpy, fim->shminfo)) { } } XDestroyImage (fim->im); if (fim->shminfo) { Fshmdt(fim->shminfo->shmaddr); Fshmctl(fim->shminfo->shmid, IPC_RMID, 0); free(fim->shminfo); } free(fim); } fvwm-2.6.7/libs/Colorset.h0000644000175700017570000001556312773467232012367 00000000000000/* -*-c-*- */ /* Fvwm colorset technology is Copyright (C) 1999 Joey Shutup http://www.streetmap.co.uk/streetmap.dll?Postcode2Map?BS24+9TZ You may use this code for any purpose, as long as the original copyright and this notice remains in the source code and all documentation */ #ifndef LIBS_COLORSETS_H #define LIBS_COLORSETS_H typedef struct { Pixel fg; Pixel bg; Pixel hilite; Pixel shadow; Pixel fgsh; Pixel tint; Pixel icon_tint; Pixmap pixmap; Pixmap shape_mask; unsigned int width : 12; unsigned int height : 12; unsigned int pixmap_type: 3; unsigned int shape_width : 12; unsigned int shape_height : 12; unsigned int shape_type : 2; unsigned int do_dither_icon : 1; unsigned int fg_alpha_percent : 7; unsigned int tint_percent : 7; unsigned int icon_alpha_percent : 7; unsigned int icon_tint_percent : 7; #ifdef FVWM_COLORSET_PRIVATE /* fvwm/colorset.c use only */ Pixel fg_tint; Pixel fg_saved; Pixel bg_tint; Pixel bg_saved; Pixmap mask; Pixmap alpha_pixmap; char *pixmap_args; char *gradient_args; char gradient_type; unsigned int color_flags; FvwmPicture *picture; Pixel *pixels; int nalloc_pixels; int fg_tint_percent; int bg_tint_percent; short image_alpha_percent; Bool dither; Bool allows_buffered_transparency; Bool is_maybe_root_transparent; #endif } colorset_t; #define PIXMAP_TILED 0 #define PIXMAP_STRETCH_X 1 #define PIXMAP_STRETCH_Y 2 #define PIXMAP_STRETCH 3 #define PIXMAP_STRETCH_ASPECT 4 #define PIXMAP_ROOT_PIXMAP_PURE 5 #define PIXMAP_ROOT_PIXMAP_TRAN 6 #define SHAPE_TILED 0 #define SHAPE_STRETCH 1 #define SHAPE_STRETCH_ASPECT 2 #ifdef FVWM_COLORSET_PRIVATE #define FG_SUPPLIED 0x1 #define BG_SUPPLIED 0x2 #define HI_SUPPLIED 0x4 #define SH_SUPPLIED 0x8 #define FGSH_SUPPLIED 0x10 #define FG_CONTRAST 0x20 #define BG_AVERAGE 0x40 #define TINT_SUPPLIED 0x80 #define FG_TINT_SUPPLIED 0x100 #define BG_TINT_SUPPLIED 0x200 #define ICON_TINT_SUPPLIED 0x400 #endif /* colorsets are stored as an array of structs to permit fast dereferencing */ extern colorset_t *Colorset; /* some macro for transparency */ #define CSET_IS_TRANSPARENT(cset) \ (cset >= 0 && (Colorset[cset].pixmap == ParentRelative || \ (Colorset[cset].pixmap != None && \ (Colorset[cset].pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN ||\ Colorset[cset].pixmap_type == PIXMAP_ROOT_PIXMAP_PURE)))) #define CSET_IS_TRANSPARENT_PR(cset) \ (cset >= 0 && Colorset[cset].pixmap == ParentRelative) #define CSET_IS_TRANSPARENT_ROOT(cset) \ (cset >= 0 && Colorset[cset].pixmap != None && \ (Colorset[cset].pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN ||\ Colorset[cset].pixmap_type == PIXMAP_ROOT_PIXMAP_PURE)) #define CSET_IS_TRANSPARENT_PR_PURE(cset) \ (cset >= 0 && Colorset[cset].pixmap == ParentRelative && \ Colorset[cset].tint_percent == 0) #define CSET_IS_TRANSPARENT_ROOT_PURE(cset) \ (cset >= 0 && Colorset[cset].pixmap != None && \ Colorset[cset].pixmap_type == PIXMAP_ROOT_PIXMAP_PURE) #define CSET_IS_TRANSPARENT_ROOT_TRAN(cset) \ (cset >= 0 && Colorset[cset].pixmap != None && \ Colorset[cset].pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) #define CSET_IS_TRANSPARENT_PR_TINT(cset) \ (cset >= 0 && Colorset[cset].pixmap == ParentRelative && \ Colorset[cset].tint_percent > 0) #define CSET_HAS_PIXMAP(cset) \ (cset >= 0 && Colorset[cset].pixmap) #define CSET_HAS_PIXMAP_TILED(cset) \ (CSET_HAS_PIXMAP(cset) && (Colorset[cset].pixmap_type & PIXMAP_TILED)) #define CSET_HAS_PIXMAP_STRETCH_X(cset) \ (CSET_HAS_PIXMAP(cset) && (Colorset[cset].pixmap_type & PIXMAP_STRETCH_X)) #define CSET_HAS_PIXMAP_STRETCH_Y(cset) \ (CSET_HAS_PIXMAP(cset) && (Colorset[cset].pixmap_type & PIXMAP_STRETCH_Y)) #define CSET_HAS_PIXMAP_STRETCH(cset) \ (CSET_HAS_PIXMAP(cset) && (Colorset[cset].pixmap_type & PIXMAP_STRETCH)) #define CSET_HAS_PIXMAP_STRETCH_ASPECT(cset) \ (CSET_HAS_PIXMAP(cset) && \ (Colorset[cset].pixmap_type & PIXMAP_STRETCH_ASPECT)) #define CSET_PIXMAP_IS_XY_STRETCHED(cset) \ (CSET_HAS_PIXMAP_STRETCH(cset) || CSET_HAS_PIXMAP_STRETCH_ASPECT(cset)) #define CSET_PIXMAP_IS_X_STRETCHED(cset) \ (CSET_PIXMAP_IS_XY_STRETCHED(cset) || CSET_HAS_PIXMAP_STRETCH_X(cset)) #define CSET_PIXMAP_IS_Y_STRETCHED(cset) \ (CSET_PIXMAP_IS_XY_STRETCHED(cset) || CSET_HAS_PIXMAP_STRETCH_Y(cset)) #define CSET_PIXMAP_IS_TILED(cset) \ (CSET_HAS_PIXMAP_TILED(cset)) /* some macro for transparency */ #define CSETS_IS_TRANSPARENT(cset) \ (cset != NULL && (cset->pixmap == ParentRelative || \ (cset->pixmap != None && \ (cset->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN ||\ cset->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE)))) #define CSETS_IS_TRANSPARENT_ROOT(cset) \ (cset != NULL && cset->pixmap != None && \ (cset->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN ||\ cset->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE)) #define CSETS_IS_TRANSPARENT_PR_PURE(cset) \ (cset != NULL && cset->pixmap == ParentRelative && \ cset->tint_percent == 0) #define CSETS_IS_TRANSPARENT_ROOT_PURE(cset) \ (cset != NULL && cset->pixmap != None && \ cset->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE) #define CSETS_IS_TRANSPARENT_ROOT_TRAN(cset) \ (cset != NULL && cset->pixmap != None && \ cset->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) #define CSETS_IS_TRANSPARENT_PR_TINT(cset) \ (cset != NULL && cset->pixmap == ParentRelative && \ cset->tint_percent > 0) #ifndef FVWM_COLORSET_PRIVATE /* Create n new colorsets, fvwm/colorset.c does its own thing (different size) */ void AllocColorset(int n); #endif /* dump one */ char *DumpColorset(int n, colorset_t *colorset); /* load one */ int LoadColorset(char *line); Pixmap CreateOffsetBackgroundPixmap( Display *dpy, Window win, int x, int y, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool is_mask); Pixmap CreateBackgroundPixmap( Display *dpy, Window win, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool is_mask); Pixmap ScrollPixmap( Display *dpy, Pixmap p, GC gc, int x_off, int y_off, int width, int height, unsigned int depth); void SetWindowBackgroundWithOffset( Display *dpy, Window win, int x_off, int y_off, unsigned int width, unsigned int height, colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area); void SetWindowBackground( Display *dpy, Window win, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area); void GetWindowBackgroundPixmapSize( colorset_t *cs_t, int width, int height, int *w, int *h); Bool UpdateBackgroundTransparency( Display *dpy, Window win, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area); void SetRectangleBackground( Display *dpy, Window win, int x, int y, int width, int height, colorset_t *colorset, unsigned int depth, GC gc); void SetClippedRectangleBackground( Display *dpy, Window win, int x, int y, int width, int height, XRectangle *clip, colorset_t *colorset, unsigned int depth, GC gc); #endif fvwm-2.6.7/libs/timeout.h0000644000175700017570000000205012773467232012246 00000000000000/* -*-c-*- */ #ifndef TIMEOUT_H #define TIMEOUT_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ #define TIMEOUT_MAX_TIMEOUTS 32 /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef int timeout_time_t; typedef unsigned int timeout_mask_t; typedef struct { int n_timeouts; timeout_time_t *timeouts; } timeout_t; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ timeout_t *timeout_create( int n_timeouts); void timeout_destroy( timeout_t *to); timeout_mask_t timeout_tick( timeout_t *to, timeout_time_t n_ticks); void timeout_rewind( timeout_t *to, timeout_mask_t mask, timeout_time_t ticks_before_alarm); #endif /* TIMEOUT_H */ fvwm-2.6.7/libs/CombineChars.c0000644000175700017570000014674213001406607013111 00000000000000/* -*-c-*- */ /* Copyright (C) 2003 Marcus Lundblad */ /* 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 #include #include "fvwmlib.h" #include "CombineChars.h" /* ---------------------------- local types -------------------------------- */ typedef struct char_combclass { unsigned short key; int combclass; } char_combclass_t; typedef struct char_comb { unsigned short key; unsigned short first; unsigned short second; } char_comb_t; /* ---------------------------- static variables --------------------------- */ /* would like to use the Unicode replacement character here, but that would result in expanding incoming UTF-8 strings when garbage characters occurs */ /* so for the time being use '?' */ static unsigned short REPLACEMENT_CHARACTER = 0x3f; /* maps characters to combination classes (not in list => 0) */ /* parsed from UnicodeData-3.2.0.txt */ static const char_combclass_t combclass_table[] = { { 0x0300, 230}, { 0x0301, 230}, { 0x0302, 230}, { 0x0303, 230}, { 0x0304, 230}, { 0x0305, 230}, { 0x0306, 230}, { 0x0307, 230}, { 0x0308, 230}, { 0x0309, 230}, { 0x030A, 230}, { 0x030B, 230}, { 0x030C, 230}, { 0x030D, 230}, { 0x030E, 230}, { 0x030F, 230}, { 0x0310, 230}, { 0x0311, 230}, { 0x0312, 230}, { 0x0313, 230}, { 0x0314, 230}, { 0x0315, 232}, { 0x0316, 220}, { 0x0317, 220}, { 0x0318, 220}, { 0x0319, 220}, { 0x031A, 232}, { 0x031B, 216}, { 0x031C, 220}, { 0x031D, 220}, { 0x031E, 220}, { 0x031F, 220}, { 0x0320, 220}, { 0x0321, 202}, { 0x0322, 202}, { 0x0323, 220}, { 0x0324, 220}, { 0x0325, 220}, { 0x0326, 220}, { 0x0327, 202}, { 0x0328, 202}, { 0x0329, 220}, { 0x032A, 220}, { 0x032B, 220}, { 0x032C, 220}, { 0x032D, 220}, { 0x032E, 220}, { 0x032F, 220}, { 0x0330, 220}, { 0x0331, 220}, { 0x0332, 220}, { 0x0333, 220}, { 0x0334, 1}, { 0x0335, 1}, { 0x0336, 1}, { 0x0337, 1}, { 0x0338, 1}, { 0x0339, 220}, { 0x033A, 220}, { 0x033B, 220}, { 0x033C, 220}, { 0x033D, 230}, { 0x033E, 230}, { 0x033F, 230}, { 0x0340, 230}, { 0x0341, 230}, { 0x0342, 230}, { 0x0343, 230}, { 0x0344, 230}, { 0x0345, 240}, { 0x0346, 230}, { 0x0347, 220}, { 0x0348, 220}, { 0x0349, 220}, { 0x034A, 230}, { 0x034B, 230}, { 0x034C, 230}, { 0x034D, 220}, { 0x034E, 220}, { 0x034F, -1 }, { 0x0360, 234}, { 0x0361, 234}, { 0x0362, 233}, { 0x0363, 230}, { 0x0364, 230}, { 0x0365, 230}, { 0x0366, 230}, { 0x0367, 230}, { 0x0368, 230}, { 0x0369, 230}, { 0x036A, 230}, { 0x036B, 230}, { 0x036C, 230}, { 0x036D, 230}, { 0x036E, 230}, { 0x036F, 230}, { 0x0483, 230}, { 0x0484, 230}, { 0x0485, 230}, { 0x0486, 230}, { 0x0488, -3 }, { 0x0489, -3 }, { 0x0591, 220}, { 0x0592, 230}, { 0x0593, 230}, { 0x0594, 230}, { 0x0595, 230}, { 0x0596, 220}, { 0x0597, 230}, { 0x0598, 230}, { 0x0599, 230}, { 0x059A, 222}, { 0x059B, 220}, { 0x059C, 230}, { 0x059D, 230}, { 0x059E, 230}, { 0x059F, 230}, { 0x05A0, 230}, { 0x05A1, 230}, { 0x05A3, 220}, { 0x05A4, 220}, { 0x05A5, 220}, { 0x05A6, 220}, { 0x05A7, 220}, { 0x05A8, 230}, { 0x05A9, 230}, { 0x05AA, 220}, { 0x05AB, 230}, { 0x05AC, 230}, { 0x05AD, 222}, { 0x05AE, 228}, { 0x05AF, 230}, { 0x05B0, 10}, { 0x05B1, 11}, { 0x05B2, 12}, { 0x05B3, 13}, { 0x05B4, 14}, { 0x05B5, 15}, { 0x05B6, 16}, { 0x05B7, 17}, { 0x05B8, 18}, { 0x05B9, 19}, { 0x05BB, 20}, { 0x05BC, 21}, { 0x05BD, 22}, { 0x05BF, 23}, { 0x05C1, 24}, { 0x05C2, 25}, { 0x05C4, 230}, { 0x064B, 27}, { 0x064C, 28}, { 0x064D, 29}, { 0x064E, 30}, { 0x064F, 31}, { 0x0650, 32}, { 0x0651, 33}, { 0x0652, 34}, { 0x0653, 230}, { 0x0654, 230}, { 0x0655, 220}, { 0x0670, 35}, { 0x06D6, 230}, { 0x06D7, 230}, { 0x06D8, 230}, { 0x06D9, 230}, { 0x06DA, 230}, { 0x06DB, 230}, { 0x06DC, 230}, { 0x06DE, -3 }, { 0x06DF, 230}, { 0x06E0, 230}, { 0x06E1, 230}, { 0x06E2, 230}, { 0x06E3, 220}, { 0x06E4, 230}, { 0x06E7, 230}, { 0x06E8, 230}, { 0x06EA, 220}, { 0x06EB, 230}, { 0x06EC, 230}, { 0x06ED, 220}, { 0x0711, 36}, { 0x0730, 230}, { 0x0731, 220}, { 0x0732, 230}, { 0x0733, 230}, { 0x0734, 220}, { 0x0735, 230}, { 0x0736, 230}, { 0x0737, 220}, { 0x0738, 220}, { 0x0739, 220}, { 0x073A, 230}, { 0x073B, 220}, { 0x073C, 220}, { 0x073D, 230}, { 0x073E, 220}, { 0x073F, 230}, { 0x0740, 230}, { 0x0741, 230}, { 0x0742, 220}, { 0x0743, 230}, { 0x0744, 220}, { 0x0745, 230}, { 0x0746, 220}, { 0x0747, 230}, { 0x0748, 220}, { 0x0749, 230}, { 0x074A, 230}, { 0x07A6, -1 }, { 0x07A7, -1 }, { 0x07A8, -1 }, { 0x07A9, -1 }, { 0x07AA, -1 }, { 0x07AB, -1 }, { 0x07AC, -1 }, { 0x07AD, -1 }, { 0x07AE, -1 }, { 0x07AF, -1 }, { 0x07B0, -1 }, { 0x0901, -1 }, { 0x0902, -1 }, { 0x0903, -2 }, { 0x093C, 7}, { 0x093E, -2 }, { 0x093F, -2 }, { 0x0940, -2 }, { 0x0941, -1 }, { 0x0942, -1 }, { 0x0943, -1 }, { 0x0944, -1 }, { 0x0945, -1 }, { 0x0946, -1 }, { 0x0947, -1 }, { 0x0948, -1 }, { 0x0949, -2 }, { 0x094A, -2 }, { 0x094B, -2 }, { 0x094C, -2 }, { 0x094D, 9}, { 0x0951, 230}, { 0x0952, 220}, { 0x0953, 230}, { 0x0954, 230}, { 0x0962, -1 }, { 0x0963, -1 }, { 0x0981, -1 }, { 0x0982, -2 }, { 0x0983, -2 }, { 0x09BC, 7}, { 0x09BE, -2 }, { 0x09BF, -2 }, { 0x09C0, -2 }, { 0x09C1, -1 }, { 0x09C2, -1 }, { 0x09C3, -1 }, { 0x09C4, -1 }, { 0x09C7, -2 }, { 0x09C8, -2 }, { 0x09CB, -2 }, { 0x09CC, -2 }, { 0x09CD, 9}, { 0x09D7, -2 }, { 0x09E2, -1 }, { 0x09E3, -1 }, { 0x0A02, -1 }, { 0x0A3C, 7}, { 0x0A3E, -2 }, { 0x0A3F, -2 }, { 0x0A40, -2 }, { 0x0A41, -1 }, { 0x0A42, -1 }, { 0x0A47, -1 }, { 0x0A48, -1 }, { 0x0A4B, -1 }, { 0x0A4C, -1 }, { 0x0A4D, 9}, { 0x0A70, -1 }, { 0x0A71, -1 }, { 0x0A81, -1 }, { 0x0A82, -1 }, { 0x0A83, -2 }, { 0x0ABC, 7}, { 0x0ABE, -2 }, { 0x0ABF, -2 }, { 0x0AC0, -2 }, { 0x0AC1, -1 }, { 0x0AC2, -1 }, { 0x0AC3, -1 }, { 0x0AC4, -1 }, { 0x0AC5, -1 }, { 0x0AC7, -1 }, { 0x0AC8, -1 }, { 0x0AC9, -2 }, { 0x0ACB, -2 }, { 0x0ACC, -2 }, { 0x0ACD, 9}, { 0x0B01, -1 }, { 0x0B02, -2 }, { 0x0B03, -2 }, { 0x0B3C, 7}, { 0x0B3E, -2 }, { 0x0B3F, -1 }, { 0x0B40, -2 }, { 0x0B41, -1 }, { 0x0B42, -1 }, { 0x0B43, -1 }, { 0x0B47, -2 }, { 0x0B48, -2 }, { 0x0B4B, -2 }, { 0x0B4C, -2 }, { 0x0B4D, 9}, { 0x0B56, -1 }, { 0x0B57, -2 }, { 0x0B82, -1 }, { 0x0BBE, -2 }, { 0x0BBF, -2 }, { 0x0BC0, -1 }, { 0x0BC1, -2 }, { 0x0BC2, -2 }, { 0x0BC6, -2 }, { 0x0BC7, -2 }, { 0x0BC8, -2 }, { 0x0BCA, -2 }, { 0x0BCB, -2 }, { 0x0BCC, -2 }, { 0x0BCD, 9}, { 0x0BD7, -2 }, { 0x0C01, -2 }, { 0x0C02, -2 }, { 0x0C03, -2 }, { 0x0C3E, -1 }, { 0x0C3F, -1 }, { 0x0C40, -1 }, { 0x0C41, -2 }, { 0x0C42, -2 }, { 0x0C43, -2 }, { 0x0C44, -2 }, { 0x0C46, -1 }, { 0x0C47, -1 }, { 0x0C48, -1 }, { 0x0C4A, -1 }, { 0x0C4B, -1 }, { 0x0C4C, -1 }, { 0x0C4D, 9}, { 0x0C55, 84}, { 0x0C56, 91}, { 0x0C82, -2 }, { 0x0C83, -2 }, { 0x0CBE, -2 }, { 0x0CBF, -1 }, { 0x0CC0, -2 }, { 0x0CC1, -2 }, { 0x0CC2, -2 }, { 0x0CC3, -2 }, { 0x0CC4, -2 }, { 0x0CC6, -1 }, { 0x0CC7, -2 }, { 0x0CC8, -2 }, { 0x0CCA, -2 }, { 0x0CCB, -2 }, { 0x0CCC, -1 }, { 0x0CCD, 9}, { 0x0CD5, -2 }, { 0x0CD6, -2 }, { 0x0D02, -2 }, { 0x0D03, -2 }, { 0x0D3E, -2 }, { 0x0D3F, -2 }, { 0x0D40, -2 }, { 0x0D41, -1 }, { 0x0D42, -1 }, { 0x0D43, -1 }, { 0x0D46, -2 }, { 0x0D47, -2 }, { 0x0D48, -2 }, { 0x0D4A, -2 }, { 0x0D4B, -2 }, { 0x0D4C, -2 }, { 0x0D4D, 9}, { 0x0D57, -2 }, { 0x0D82, -2 }, { 0x0D83, -2 }, { 0x0DCA, 9}, { 0x0DCF, -2 }, { 0x0DD0, -2 }, { 0x0DD1, -2 }, { 0x0DD2, -1 }, { 0x0DD3, -1 }, { 0x0DD4, -1 }, { 0x0DD6, -1 }, { 0x0DD8, -2 }, { 0x0DD9, -2 }, { 0x0DDA, -2 }, { 0x0DDB, -2 }, { 0x0DDC, -2 }, { 0x0DDD, -2 }, { 0x0DDE, -2 }, { 0x0DDF, -2 }, { 0x0DF2, -2 }, { 0x0DF3, -2 }, { 0x0E31, -1 }, { 0x0E34, -1 }, { 0x0E35, -1 }, { 0x0E36, -1 }, { 0x0E37, -1 }, { 0x0E38, 103}, { 0x0E39, 103}, { 0x0E3A, 9}, { 0x0E47, -1 }, { 0x0E48, 107}, { 0x0E49, 107}, { 0x0E4A, 107}, { 0x0E4B, 107}, { 0x0E4C, -1 }, { 0x0E4D, -1 }, { 0x0E4E, -1 }, { 0x0EB1, -1 }, { 0x0EB4, -1 }, { 0x0EB5, -1 }, { 0x0EB6, -1 }, { 0x0EB7, -1 }, { 0x0EB8, 118}, { 0x0EB9, 118}, { 0x0EBB, -1 }, { 0x0EBC, -1 }, { 0x0EC8, 122}, { 0x0EC9, 122}, { 0x0ECA, 122}, { 0x0ECB, 122}, { 0x0ECC, -1 }, { 0x0ECD, -1 }, { 0x0F18, 220}, { 0x0F19, 220}, { 0x0F35, 220}, { 0x0F37, 220}, { 0x0F39, 216}, { 0x0F3E, -2 }, { 0x0F3F, -2 }, { 0x0F71, 129}, { 0x0F72, 130}, { 0x0F73, -1 }, { 0x0F74, 132}, { 0x0F75, -1 }, { 0x0F76, -1 }, { 0x0F77, -1 }, { 0x0F78, -1 }, { 0x0F79, -1 }, { 0x0F7A, 130}, { 0x0F7B, 130}, { 0x0F7C, 130}, { 0x0F7D, 130}, { 0x0F7E, -1 }, { 0x0F7F, -2 }, { 0x0F80, 130}, { 0x0F81, -1 }, { 0x0F82, 230}, { 0x0F83, 230}, { 0x0F84, 9}, { 0x0F86, 230}, { 0x0F87, 230}, { 0x0F90, -1 }, { 0x0F91, -1 }, { 0x0F92, -1 }, { 0x0F93, -1 }, { 0x0F94, -1 }, { 0x0F95, -1 }, { 0x0F96, -1 }, { 0x0F97, -1 }, { 0x0F99, -1 }, { 0x0F9A, -1 }, { 0x0F9B, -1 }, { 0x0F9C, -1 }, { 0x0F9D, -1 }, { 0x0F9E, -1 }, { 0x0F9F, -1 }, { 0x0FA0, -1 }, { 0x0FA1, -1 }, { 0x0FA2, -1 }, { 0x0FA3, -1 }, { 0x0FA4, -1 }, { 0x0FA5, -1 }, { 0x0FA6, -1 }, { 0x0FA7, -1 }, { 0x0FA8, -1 }, { 0x0FA9, -1 }, { 0x0FAA, -1 }, { 0x0FAB, -1 }, { 0x0FAC, -1 }, { 0x0FAD, -1 }, { 0x0FAE, -1 }, { 0x0FAF, -1 }, { 0x0FB0, -1 }, { 0x0FB1, -1 }, { 0x0FB2, -1 }, { 0x0FB3, -1 }, { 0x0FB4, -1 }, { 0x0FB5, -1 }, { 0x0FB6, -1 }, { 0x0FB7, -1 }, { 0x0FB8, -1 }, { 0x0FB9, -1 }, { 0x0FBA, -1 }, { 0x0FBB, -1 }, { 0x0FBC, -1 }, { 0x0FC6, 220}, { 0x102C, -2 }, { 0x102D, -1 }, { 0x102E, -1 }, { 0x102F, -1 }, { 0x1030, -1 }, { 0x1031, -2 }, { 0x1032, -1 }, { 0x1036, -1 }, { 0x1037, 7}, { 0x1038, -2 }, { 0x1039, 9}, { 0x1056, -2 }, { 0x1057, -2 }, { 0x1058, -1 }, { 0x1059, -1 }, { 0x1712, -1 }, { 0x1713, -1 }, { 0x1714, 9}, { 0x1732, -1 }, { 0x1733, -1 }, { 0x1734, 9}, { 0x1752, -1 }, { 0x1753, -1 }, { 0x1772, -1 }, { 0x1773, -1 }, { 0x17B4, -2 }, { 0x17B5, -2 }, { 0x17B6, -2 }, { 0x17B7, -1 }, { 0x17B8, -1 }, { 0x17B9, -1 }, { 0x17BA, -1 }, { 0x17BB, -1 }, { 0x17BC, -1 }, { 0x17BD, -1 }, { 0x17BE, -2 }, { 0x17BF, -2 }, { 0x17C0, -2 }, { 0x17C1, -2 }, { 0x17C2, -2 }, { 0x17C3, -2 }, { 0x17C4, -2 }, { 0x17C5, -2 }, { 0x17C6, -1 }, { 0x17C7, -2 }, { 0x17C8, -2 }, { 0x17C9, -1 }, { 0x17CA, -1 }, { 0x17CB, -1 }, { 0x17CC, -1 }, { 0x17CD, -1 }, { 0x17CE, -1 }, { 0x17CF, -1 }, { 0x17D0, -1 }, { 0x17D1, -1 }, { 0x17D2, 9}, { 0x17D3, -1 }, { 0x180B, -1 }, { 0x180C, -1 }, { 0x180D, -1 }, { 0x18A9, 228}, { 0x20D0, 230}, { 0x20D1, 230}, { 0x20D2, 1}, { 0x20D3, 1}, { 0x20D4, 230}, { 0x20D5, 230}, { 0x20D6, 230}, { 0x20D7, 230}, { 0x20D8, 1}, { 0x20D9, 1}, { 0x20DA, 1}, { 0x20DB, 230}, { 0x20DC, 230}, { 0x20DD, -3 }, { 0x20DE, -3 }, { 0x20DF, -3 }, { 0x20E0, -3 }, { 0x20E1, 230}, { 0x20E2, -3 }, { 0x20E3, -3 }, { 0x20E4, -3 }, { 0x20E5, 1}, { 0x20E6, 1}, { 0x20E7, 230}, { 0x20E8, 220}, { 0x20E9, 230}, { 0x20EA, 1}, { 0x302A, 218}, { 0x302B, 228}, { 0x302C, 232}, { 0x302D, 222}, { 0x302E, 224}, { 0x302F, 224}, { 0x3099, 8}, { 0x309A, 8}, { 0xFB1E, 26}, { 0xFE00, -1 }, { 0xFE01, -1 }, { 0xFE02, -1 }, { 0xFE03, -1 }, { 0xFE04, -1 }, { 0xFE05, -1 }, { 0xFE06, -1 }, { 0xFE07, -1 }, { 0xFE08, -1 }, { 0xFE09, -1 }, { 0xFE0A, -1 }, { 0xFE0B, -1 }, { 0xFE0C, -1 }, { 0xFE0D, -1 }, { 0xFE0E, -1 }, { 0xFE0F, -1 }, { 0xFE20, 230}, { 0xFE21, 230}, { 0xFE22, 230}, { 0xFE23, 230}, /*{ 0x1D165, 216}, { 0x1D166, 216}, { 0x1D167, 1}, { 0x1D168, 1}, { 0x1D169, 1}, { 0x1D16D, 226}, { 0x1D16E, 216}, { 0x1D16F, 216}, { 0x1D170, 216}, { 0x1D171, 216}, { 0x1D172, 216}, { 0x1D17B, 220}, { 0x1D17C, 220}, { 0x1D17D, 220}, { 0x1D17E, 220}, { 0x1D17F, 220}, { 0x1D180, 220}, { 0x1D181, 220}, { 0x1D182, 220}, { 0x1D185, 230}, { 0x1D186, 230}, { 0x1D187, 230}, { 0x1D188, 230}, { 0x1D189, 230}, { 0x1D18A, 220}, { 0x1D18B, 220}, { 0x1D1AA, 230}, { 0x1D1AB, 230}, { 0x1D1AC, 230}, { 0x1D1AD, 230},*/ }; /* maps characters to decompositions */ /* parsed from UnicodeData-3.2.0.txt */ static const char_comb_t comb_table[] = { { 0x00C0, 0x0041, 0x0300 }, { 0x00C1, 0x0041, 0x0301 }, { 0x00C2, 0x0041, 0x0302 }, { 0x00C3, 0x0041, 0x0303 }, { 0x00C4, 0x0041, 0x0308 }, { 0x00C5, 0x0041, 0x030A }, { 0x00C7, 0x0043, 0x0327 }, { 0x00C8, 0x0045, 0x0300 }, { 0x00C9, 0x0045, 0x0301 }, { 0x00CA, 0x0045, 0x0302 }, { 0x00CB, 0x0045, 0x0308 }, { 0x00CC, 0x0049, 0x0300 }, { 0x00CD, 0x0049, 0x0301 }, { 0x00CE, 0x0049, 0x0302 }, { 0x00CF, 0x0049, 0x0308 }, { 0x00D1, 0x004E, 0x0303 }, { 0x00D2, 0x004F, 0x0300 }, { 0x00D3, 0x004F, 0x0301 }, { 0x00D4, 0x004F, 0x0302 }, { 0x00D5, 0x004F, 0x0303 }, { 0x00D6, 0x004F, 0x0308 }, { 0x00D9, 0x0055, 0x0300 }, { 0x00DA, 0x0055, 0x0301 }, { 0x00DB, 0x0055, 0x0302 }, { 0x00DC, 0x0055, 0x0308 }, { 0x00DD, 0x0059, 0x0301 }, { 0x00E0, 0x0061, 0x0300 }, { 0x00E1, 0x0061, 0x0301 }, { 0x00E2, 0x0061, 0x0302 }, { 0x00E3, 0x0061, 0x0303 }, { 0x00E4, 0x0061, 0x0308 }, { 0x00E5, 0x0061, 0x030A }, { 0x00E7, 0x0063, 0x0327 }, { 0x00E8, 0x0065, 0x0300 }, { 0x00E9, 0x0065, 0x0301 }, { 0x00EA, 0x0065, 0x0302 }, { 0x00EB, 0x0065, 0x0308 }, { 0x00EC, 0x0069, 0x0300 }, { 0x00ED, 0x0069, 0x0301 }, { 0x00EE, 0x0069, 0x0302 }, { 0x00EF, 0x0069, 0x0308 }, { 0x00F1, 0x006E, 0x0303 }, { 0x00F2, 0x006F, 0x0300 }, { 0x00F3, 0x006F, 0x0301 }, { 0x00F4, 0x006F, 0x0302 }, { 0x00F5, 0x006F, 0x0303 }, { 0x00F6, 0x006F, 0x0308 }, { 0x00F9, 0x0075, 0x0300 }, { 0x00FA, 0x0075, 0x0301 }, { 0x00FB, 0x0075, 0x0302 }, { 0x00FC, 0x0075, 0x0308 }, { 0x00FD, 0x0079, 0x0301 }, { 0x00FF, 0x0079, 0x0308 }, { 0x0100, 0x0041, 0x0304 }, { 0x0101, 0x0061, 0x0304 }, { 0x0102, 0x0041, 0x0306 }, { 0x0103, 0x0061, 0x0306 }, { 0x0104, 0x0041, 0x0328 }, { 0x0105, 0x0061, 0x0328 }, { 0x0106, 0x0043, 0x0301 }, { 0x0107, 0x0063, 0x0301 }, { 0x0108, 0x0043, 0x0302 }, { 0x0109, 0x0063, 0x0302 }, { 0x010A, 0x0043, 0x0307 }, { 0x010B, 0x0063, 0x0307 }, { 0x010C, 0x0043, 0x030C }, { 0x010D, 0x0063, 0x030C }, { 0x010E, 0x0044, 0x030C }, { 0x010F, 0x0064, 0x030C }, { 0x0112, 0x0045, 0x0304 }, { 0x0113, 0x0065, 0x0304 }, { 0x0114, 0x0045, 0x0306 }, { 0x0115, 0x0065, 0x0306 }, { 0x0116, 0x0045, 0x0307 }, { 0x0117, 0x0065, 0x0307 }, { 0x0118, 0x0045, 0x0328 }, { 0x0119, 0x0065, 0x0328 }, { 0x011A, 0x0045, 0x030C }, { 0x011B, 0x0065, 0x030C }, { 0x011C, 0x0047, 0x0302 }, { 0x011D, 0x0067, 0x0302 }, { 0x011E, 0x0047, 0x0306 }, { 0x011F, 0x0067, 0x0306 }, { 0x0120, 0x0047, 0x0307 }, { 0x0121, 0x0067, 0x0307 }, { 0x0122, 0x0047, 0x0327 }, { 0x0123, 0x0067, 0x0327 }, { 0x0124, 0x0048, 0x0302 }, { 0x0125, 0x0068, 0x0302 }, { 0x0128, 0x0049, 0x0303 }, { 0x0129, 0x0069, 0x0303 }, { 0x012A, 0x0049, 0x0304 }, { 0x012B, 0x0069, 0x0304 }, { 0x012C, 0x0049, 0x0306 }, { 0x012D, 0x0069, 0x0306 }, { 0x012E, 0x0049, 0x0328 }, { 0x012F, 0x0069, 0x0328 }, { 0x0130, 0x0049, 0x0307 }, { 0x0134, 0x004A, 0x0302 }, { 0x0135, 0x006A, 0x0302 }, { 0x0136, 0x004B, 0x0327 }, { 0x0137, 0x006B, 0x0327 }, { 0x0139, 0x004C, 0x0301 }, { 0x013A, 0x006C, 0x0301 }, { 0x013B, 0x004C, 0x0327 }, { 0x013C, 0x006C, 0x0327 }, { 0x013D, 0x004C, 0x030C }, { 0x013E, 0x006C, 0x030C }, { 0x0143, 0x004E, 0x0301 }, { 0x0144, 0x006E, 0x0301 }, { 0x0145, 0x004E, 0x0327 }, { 0x0146, 0x006E, 0x0327 }, { 0x0147, 0x004E, 0x030C }, { 0x0148, 0x006E, 0x030C }, { 0x014C, 0x004F, 0x0304 }, { 0x014D, 0x006F, 0x0304 }, { 0x014E, 0x004F, 0x0306 }, { 0x014F, 0x006F, 0x0306 }, { 0x0150, 0x004F, 0x030B }, { 0x0151, 0x006F, 0x030B }, { 0x0154, 0x0052, 0x0301 }, { 0x0155, 0x0072, 0x0301 }, { 0x0156, 0x0052, 0x0327 }, { 0x0157, 0x0072, 0x0327 }, { 0x0158, 0x0052, 0x030C }, { 0x0159, 0x0072, 0x030C }, { 0x015A, 0x0053, 0x0301 }, { 0x015B, 0x0073, 0x0301 }, { 0x015C, 0x0053, 0x0302 }, { 0x015D, 0x0073, 0x0302 }, { 0x015E, 0x0053, 0x0327 }, { 0x015F, 0x0073, 0x0327 }, { 0x0160, 0x0053, 0x030C }, { 0x0161, 0x0073, 0x030C }, { 0x0162, 0x0054, 0x0327 }, { 0x0163, 0x0074, 0x0327 }, { 0x0164, 0x0054, 0x030C }, { 0x0165, 0x0074, 0x030C }, { 0x0168, 0x0055, 0x0303 }, { 0x0169, 0x0075, 0x0303 }, { 0x016A, 0x0055, 0x0304 }, { 0x016B, 0x0075, 0x0304 }, { 0x016C, 0x0055, 0x0306 }, { 0x016D, 0x0075, 0x0306 }, { 0x016E, 0x0055, 0x030A }, { 0x016F, 0x0075, 0x030A }, { 0x0170, 0x0055, 0x030B }, { 0x0171, 0x0075, 0x030B }, { 0x0172, 0x0055, 0x0328 }, { 0x0173, 0x0075, 0x0328 }, { 0x0174, 0x0057, 0x0302 }, { 0x0175, 0x0077, 0x0302 }, { 0x0176, 0x0059, 0x0302 }, { 0x0177, 0x0079, 0x0302 }, { 0x0178, 0x0059, 0x0308 }, { 0x0179, 0x005A, 0x0301 }, { 0x017A, 0x007A, 0x0301 }, { 0x017B, 0x005A, 0x0307 }, { 0x017C, 0x007A, 0x0307 }, { 0x017D, 0x005A, 0x030C }, { 0x017E, 0x007A, 0x030C }, { 0x01A0, 0x004F, 0x031B }, { 0x01A1, 0x006F, 0x031B }, { 0x01AF, 0x0055, 0x031B }, { 0x01B0, 0x0075, 0x031B }, { 0x01CD, 0x0041, 0x030C }, { 0x01CE, 0x0061, 0x030C }, { 0x01CF, 0x0049, 0x030C }, { 0x01D0, 0x0069, 0x030C }, { 0x01D1, 0x004F, 0x030C }, { 0x01D2, 0x006F, 0x030C }, { 0x01D3, 0x0055, 0x030C }, { 0x01D4, 0x0075, 0x030C }, { 0x01D5, 0x00DC, 0x0304 }, { 0x01D6, 0x00FC, 0x0304 }, { 0x01D7, 0x00DC, 0x0301 }, { 0x01D8, 0x00FC, 0x0301 }, { 0x01D9, 0x00DC, 0x030C }, { 0x01DA, 0x00FC, 0x030C }, { 0x01DB, 0x00DC, 0x0300 }, { 0x01DC, 0x00FC, 0x0300 }, { 0x01DE, 0x00C4, 0x0304 }, { 0x01DF, 0x00E4, 0x0304 }, { 0x01E0, 0x0226, 0x0304 }, { 0x01E1, 0x0227, 0x0304 }, { 0x01E2, 0x00C6, 0x0304 }, { 0x01E3, 0x00E6, 0x0304 }, { 0x01E6, 0x0047, 0x030C }, { 0x01E7, 0x0067, 0x030C }, { 0x01E8, 0x004B, 0x030C }, { 0x01E9, 0x006B, 0x030C }, { 0x01EA, 0x004F, 0x0328 }, { 0x01EB, 0x006F, 0x0328 }, { 0x01EC, 0x01EA, 0x0304 }, { 0x01ED, 0x01EB, 0x0304 }, { 0x01EE, 0x01B7, 0x030C }, { 0x01EF, 0x0292, 0x030C }, { 0x01F0, 0x006A, 0x030C }, { 0x01F4, 0x0047, 0x0301 }, { 0x01F5, 0x0067, 0x0301 }, { 0x01F8, 0x004E, 0x0300 }, { 0x01F9, 0x006E, 0x0300 }, { 0x01FA, 0x00C5, 0x0301 }, { 0x01FB, 0x00E5, 0x0301 }, { 0x01FC, 0x00C6, 0x0301 }, { 0x01FD, 0x00E6, 0x0301 }, { 0x01FE, 0x00D8, 0x0301 }, { 0x01FF, 0x00F8, 0x0301 }, { 0x0200, 0x0041, 0x030F }, { 0x0201, 0x0061, 0x030F }, { 0x0202, 0x0041, 0x0311 }, { 0x0203, 0x0061, 0x0311 }, { 0x0204, 0x0045, 0x030F }, { 0x0205, 0x0065, 0x030F }, { 0x0206, 0x0045, 0x0311 }, { 0x0207, 0x0065, 0x0311 }, { 0x0208, 0x0049, 0x030F }, { 0x0209, 0x0069, 0x030F }, { 0x020A, 0x0049, 0x0311 }, { 0x020B, 0x0069, 0x0311 }, { 0x020C, 0x004F, 0x030F }, { 0x020D, 0x006F, 0x030F }, { 0x020E, 0x004F, 0x0311 }, { 0x020F, 0x006F, 0x0311 }, { 0x0210, 0x0052, 0x030F }, { 0x0211, 0x0072, 0x030F }, { 0x0212, 0x0052, 0x0311 }, { 0x0213, 0x0072, 0x0311 }, { 0x0214, 0x0055, 0x030F }, { 0x0215, 0x0075, 0x030F }, { 0x0216, 0x0055, 0x0311 }, { 0x0217, 0x0075, 0x0311 }, { 0x0218, 0x0053, 0x0326 }, { 0x0219, 0x0073, 0x0326 }, { 0x021A, 0x0054, 0x0326 }, { 0x021B, 0x0074, 0x0326 }, { 0x021E, 0x0048, 0x030C }, { 0x021F, 0x0068, 0x030C }, { 0x0226, 0x0041, 0x0307 }, { 0x0227, 0x0061, 0x0307 }, { 0x0228, 0x0045, 0x0327 }, { 0x0229, 0x0065, 0x0327 }, { 0x022A, 0x00D6, 0x0304 }, { 0x022B, 0x00F6, 0x0304 }, { 0x022C, 0x00D5, 0x0304 }, { 0x022D, 0x00F5, 0x0304 }, { 0x022E, 0x004F, 0x0307 }, { 0x022F, 0x006F, 0x0307 }, { 0x0230, 0x022E, 0x0304 }, { 0x0231, 0x022F, 0x0304 }, { 0x0232, 0x0059, 0x0304 }, { 0x0233, 0x0079, 0x0304 }, { 0x0344, 0x0308, 0x0301 }, { 0x0385, 0x00A8, 0x0301 }, { 0x0386, 0x0391, 0x0301 }, { 0x0388, 0x0395, 0x0301 }, { 0x0389, 0x0397, 0x0301 }, { 0x038A, 0x0399, 0x0301 }, { 0x038C, 0x039F, 0x0301 }, { 0x038E, 0x03A5, 0x0301 }, { 0x038F, 0x03A9, 0x0301 }, { 0x0390, 0x03CA, 0x0301 }, { 0x03AA, 0x0399, 0x0308 }, { 0x03AB, 0x03A5, 0x0308 }, { 0x03AC, 0x03B1, 0x0301 }, { 0x03AD, 0x03B5, 0x0301 }, { 0x03AE, 0x03B7, 0x0301 }, { 0x03AF, 0x03B9, 0x0301 }, { 0x03B0, 0x03CB, 0x0301 }, { 0x03CA, 0x03B9, 0x0308 }, { 0x03CB, 0x03C5, 0x0308 }, { 0x03CC, 0x03BF, 0x0301 }, { 0x03CD, 0x03C5, 0x0301 }, { 0x03CE, 0x03C9, 0x0301 }, { 0x03D3, 0x03D2, 0x0301 }, { 0x03D4, 0x03D2, 0x0308 }, { 0x0400, 0x0415, 0x0300 }, { 0x0401, 0x0415, 0x0308 }, { 0x0403, 0x0413, 0x0301 }, { 0x0407, 0x0406, 0x0308 }, { 0x040C, 0x041A, 0x0301 }, { 0x040D, 0x0418, 0x0300 }, { 0x040E, 0x0423, 0x0306 }, { 0x0419, 0x0418, 0x0306 }, { 0x0439, 0x0438, 0x0306 }, { 0x0450, 0x0435, 0x0300 }, { 0x0451, 0x0435, 0x0308 }, { 0x0453, 0x0433, 0x0301 }, { 0x0457, 0x0456, 0x0308 }, { 0x045C, 0x043A, 0x0301 }, { 0x045D, 0x0438, 0x0300 }, { 0x045E, 0x0443, 0x0306 }, { 0x0476, 0x0474, 0x030F }, { 0x0477, 0x0475, 0x030F }, { 0x04C1, 0x0416, 0x0306 }, { 0x04C2, 0x0436, 0x0306 }, { 0x04D0, 0x0410, 0x0306 }, { 0x04D1, 0x0430, 0x0306 }, { 0x04D2, 0x0410, 0x0308 }, { 0x04D3, 0x0430, 0x0308 }, { 0x04D6, 0x0415, 0x0306 }, { 0x04D7, 0x0435, 0x0306 }, { 0x04DA, 0x04D8, 0x0308 }, { 0x04DB, 0x04D9, 0x0308 }, { 0x04DC, 0x0416, 0x0308 }, { 0x04DD, 0x0436, 0x0308 }, { 0x04DE, 0x0417, 0x0308 }, { 0x04DF, 0x0437, 0x0308 }, { 0x04E2, 0x0418, 0x0304 }, { 0x04E3, 0x0438, 0x0304 }, { 0x04E4, 0x0418, 0x0308 }, { 0x04E5, 0x0438, 0x0308 }, { 0x04E6, 0x041E, 0x0308 }, { 0x04E7, 0x043E, 0x0308 }, { 0x04EA, 0x04E8, 0x0308 }, { 0x04EB, 0x04E9, 0x0308 }, { 0x04EC, 0x042D, 0x0308 }, { 0x04ED, 0x044D, 0x0308 }, { 0x04EE, 0x0423, 0x0304 }, { 0x04EF, 0x0443, 0x0304 }, { 0x04F0, 0x0423, 0x0308 }, { 0x04F1, 0x0443, 0x0308 }, { 0x04F2, 0x0423, 0x030B }, { 0x04F3, 0x0443, 0x030B }, { 0x04F4, 0x0427, 0x0308 }, { 0x04F5, 0x0447, 0x0308 }, { 0x04F8, 0x042B, 0x0308 }, { 0x04F9, 0x044B, 0x0308 }, { 0x0622, 0x0627, 0x0653 }, { 0x0623, 0x0627, 0x0654 }, { 0x0624, 0x0648, 0x0654 }, { 0x0625, 0x0627, 0x0655 }, { 0x0626, 0x064A, 0x0654 }, { 0x06C0, 0x06D5, 0x0654 }, { 0x06C2, 0x06C1, 0x0654 }, { 0x06D3, 0x06D2, 0x0654 }, { 0x0929, 0x0928, 0x093C }, { 0x0931, 0x0930, 0x093C }, { 0x0934, 0x0933, 0x093C }, { 0x0958, 0x0915, 0x093C }, { 0x0959, 0x0916, 0x093C }, { 0x095A, 0x0917, 0x093C }, { 0x095B, 0x091C, 0x093C }, { 0x095C, 0x0921, 0x093C }, { 0x095D, 0x0922, 0x093C }, { 0x095E, 0x092B, 0x093C }, { 0x095F, 0x092F, 0x093C }, { 0x09CB, 0x09C7, 0x09BE }, { 0x09CC, 0x09C7, 0x09D7 }, { 0x09DC, 0x09A1, 0x09BC }, { 0x09DD, 0x09A2, 0x09BC }, { 0x09DF, 0x09AF, 0x09BC }, { 0x0A33, 0x0A32, 0x0A3C }, { 0x0A36, 0x0A38, 0x0A3C }, { 0x0A59, 0x0A16, 0x0A3C }, { 0x0A5A, 0x0A17, 0x0A3C }, { 0x0A5B, 0x0A1C, 0x0A3C }, { 0x0A5E, 0x0A2B, 0x0A3C }, { 0x0B48, 0x0B47, 0x0B56 }, { 0x0B4B, 0x0B47, 0x0B3E }, { 0x0B4C, 0x0B47, 0x0B57 }, { 0x0B5C, 0x0B21, 0x0B3C }, { 0x0B5D, 0x0B22, 0x0B3C }, { 0x0B94, 0x0B92, 0x0BD7 }, { 0x0BCA, 0x0BC6, 0x0BBE }, { 0x0BCB, 0x0BC7, 0x0BBE }, { 0x0BCC, 0x0BC6, 0x0BD7 }, { 0x0C48, 0x0C46, 0x0C56 }, { 0x0CC0, 0x0CBF, 0x0CD5 }, { 0x0CC7, 0x0CC6, 0x0CD5 }, { 0x0CC8, 0x0CC6, 0x0CD6 }, { 0x0CCA, 0x0CC6, 0x0CC2 }, { 0x0CCB, 0x0CCA, 0x0CD5 }, { 0x0D4A, 0x0D46, 0x0D3E }, { 0x0D4B, 0x0D47, 0x0D3E }, { 0x0D4C, 0x0D46, 0x0D57 }, { 0x0DDA, 0x0DD9, 0x0DCA }, { 0x0DDC, 0x0DD9, 0x0DCF }, { 0x0DDD, 0x0DDC, 0x0DCA }, { 0x0DDE, 0x0DD9, 0x0DDF }, { 0x0F43, 0x0F42, 0x0FB7 }, { 0x0F4D, 0x0F4C, 0x0FB7 }, { 0x0F52, 0x0F51, 0x0FB7 }, { 0x0F57, 0x0F56, 0x0FB7 }, { 0x0F5C, 0x0F5B, 0x0FB7 }, { 0x0F69, 0x0F40, 0x0FB5 }, { 0x0F73, 0x0F71, 0x0F72 }, { 0x0F75, 0x0F71, 0x0F74 }, { 0x0F76, 0x0FB2, 0x0F80 }, { 0x0F78, 0x0FB3, 0x0F80 }, { 0x0F81, 0x0F71, 0x0F80 }, { 0x0F93, 0x0F92, 0x0FB7 }, { 0x0F9D, 0x0F9C, 0x0FB7 }, { 0x0FA2, 0x0FA1, 0x0FB7 }, { 0x0FA7, 0x0FA6, 0x0FB7 }, { 0x0FAC, 0x0FAB, 0x0FB7 }, { 0x0FB9, 0x0F90, 0x0FB5 }, { 0x1026, 0x1025, 0x102E }, { 0x1E00, 0x0041, 0x0325 }, { 0x1E01, 0x0061, 0x0325 }, { 0x1E02, 0x0042, 0x0307 }, { 0x1E03, 0x0062, 0x0307 }, { 0x1E04, 0x0042, 0x0323 }, { 0x1E05, 0x0062, 0x0323 }, { 0x1E06, 0x0042, 0x0331 }, { 0x1E07, 0x0062, 0x0331 }, { 0x1E08, 0x00C7, 0x0301 }, { 0x1E09, 0x00E7, 0x0301 }, { 0x1E0A, 0x0044, 0x0307 }, { 0x1E0B, 0x0064, 0x0307 }, { 0x1E0C, 0x0044, 0x0323 }, { 0x1E0D, 0x0064, 0x0323 }, { 0x1E0E, 0x0044, 0x0331 }, { 0x1E0F, 0x0064, 0x0331 }, { 0x1E10, 0x0044, 0x0327 }, { 0x1E11, 0x0064, 0x0327 }, { 0x1E12, 0x0044, 0x032D }, { 0x1E13, 0x0064, 0x032D }, { 0x1E14, 0x0112, 0x0300 }, { 0x1E15, 0x0113, 0x0300 }, { 0x1E16, 0x0112, 0x0301 }, { 0x1E17, 0x0113, 0x0301 }, { 0x1E18, 0x0045, 0x032D }, { 0x1E19, 0x0065, 0x032D }, { 0x1E1A, 0x0045, 0x0330 }, { 0x1E1B, 0x0065, 0x0330 }, { 0x1E1C, 0x0228, 0x0306 }, { 0x1E1D, 0x0229, 0x0306 }, { 0x1E1E, 0x0046, 0x0307 }, { 0x1E1F, 0x0066, 0x0307 }, { 0x1E20, 0x0047, 0x0304 }, { 0x1E21, 0x0067, 0x0304 }, { 0x1E22, 0x0048, 0x0307 }, { 0x1E23, 0x0068, 0x0307 }, { 0x1E24, 0x0048, 0x0323 }, { 0x1E25, 0x0068, 0x0323 }, { 0x1E26, 0x0048, 0x0308 }, { 0x1E27, 0x0068, 0x0308 }, { 0x1E28, 0x0048, 0x0327 }, { 0x1E29, 0x0068, 0x0327 }, { 0x1E2A, 0x0048, 0x032E }, { 0x1E2B, 0x0068, 0x032E }, { 0x1E2C, 0x0049, 0x0330 }, { 0x1E2D, 0x0069, 0x0330 }, { 0x1E2E, 0x00CF, 0x0301 }, { 0x1E2F, 0x00EF, 0x0301 }, { 0x1E30, 0x004B, 0x0301 }, { 0x1E31, 0x006B, 0x0301 }, { 0x1E32, 0x004B, 0x0323 }, { 0x1E33, 0x006B, 0x0323 }, { 0x1E34, 0x004B, 0x0331 }, { 0x1E35, 0x006B, 0x0331 }, { 0x1E36, 0x004C, 0x0323 }, { 0x1E37, 0x006C, 0x0323 }, { 0x1E38, 0x1E36, 0x0304 }, { 0x1E39, 0x1E37, 0x0304 }, { 0x1E3A, 0x004C, 0x0331 }, { 0x1E3B, 0x006C, 0x0331 }, { 0x1E3C, 0x004C, 0x032D }, { 0x1E3D, 0x006C, 0x032D }, { 0x1E3E, 0x004D, 0x0301 }, { 0x1E3F, 0x006D, 0x0301 }, { 0x1E40, 0x004D, 0x0307 }, { 0x1E41, 0x006D, 0x0307 }, { 0x1E42, 0x004D, 0x0323 }, { 0x1E43, 0x006D, 0x0323 }, { 0x1E44, 0x004E, 0x0307 }, { 0x1E45, 0x006E, 0x0307 }, { 0x1E46, 0x004E, 0x0323 }, { 0x1E47, 0x006E, 0x0323 }, { 0x1E48, 0x004E, 0x0331 }, { 0x1E49, 0x006E, 0x0331 }, { 0x1E4A, 0x004E, 0x032D }, { 0x1E4B, 0x006E, 0x032D }, { 0x1E4C, 0x00D5, 0x0301 }, { 0x1E4D, 0x00F5, 0x0301 }, { 0x1E4E, 0x00D5, 0x0308 }, { 0x1E4F, 0x00F5, 0x0308 }, { 0x1E50, 0x014C, 0x0300 }, { 0x1E51, 0x014D, 0x0300 }, { 0x1E52, 0x014C, 0x0301 }, { 0x1E53, 0x014D, 0x0301 }, { 0x1E54, 0x0050, 0x0301 }, { 0x1E55, 0x0070, 0x0301 }, { 0x1E56, 0x0050, 0x0307 }, { 0x1E57, 0x0070, 0x0307 }, { 0x1E58, 0x0052, 0x0307 }, { 0x1E59, 0x0072, 0x0307 }, { 0x1E5A, 0x0052, 0x0323 }, { 0x1E5B, 0x0072, 0x0323 }, { 0x1E5C, 0x1E5A, 0x0304 }, { 0x1E5D, 0x1E5B, 0x0304 }, { 0x1E5E, 0x0052, 0x0331 }, { 0x1E5F, 0x0072, 0x0331 }, { 0x1E60, 0x0053, 0x0307 }, { 0x1E61, 0x0073, 0x0307 }, { 0x1E62, 0x0053, 0x0323 }, { 0x1E63, 0x0073, 0x0323 }, { 0x1E64, 0x015A, 0x0307 }, { 0x1E65, 0x015B, 0x0307 }, { 0x1E66, 0x0160, 0x0307 }, { 0x1E67, 0x0161, 0x0307 }, { 0x1E68, 0x1E62, 0x0307 }, { 0x1E69, 0x1E63, 0x0307 }, { 0x1E6A, 0x0054, 0x0307 }, { 0x1E6B, 0x0074, 0x0307 }, { 0x1E6C, 0x0054, 0x0323 }, { 0x1E6D, 0x0074, 0x0323 }, { 0x1E6E, 0x0054, 0x0331 }, { 0x1E6F, 0x0074, 0x0331 }, { 0x1E70, 0x0054, 0x032D }, { 0x1E71, 0x0074, 0x032D }, { 0x1E72, 0x0055, 0x0324 }, { 0x1E73, 0x0075, 0x0324 }, { 0x1E74, 0x0055, 0x0330 }, { 0x1E75, 0x0075, 0x0330 }, { 0x1E76, 0x0055, 0x032D }, { 0x1E77, 0x0075, 0x032D }, { 0x1E78, 0x0168, 0x0301 }, { 0x1E79, 0x0169, 0x0301 }, { 0x1E7A, 0x016A, 0x0308 }, { 0x1E7B, 0x016B, 0x0308 }, { 0x1E7C, 0x0056, 0x0303 }, { 0x1E7D, 0x0076, 0x0303 }, { 0x1E7E, 0x0056, 0x0323 }, { 0x1E7F, 0x0076, 0x0323 }, { 0x1E80, 0x0057, 0x0300 }, { 0x1E81, 0x0077, 0x0300 }, { 0x1E82, 0x0057, 0x0301 }, { 0x1E83, 0x0077, 0x0301 }, { 0x1E84, 0x0057, 0x0308 }, { 0x1E85, 0x0077, 0x0308 }, { 0x1E86, 0x0057, 0x0307 }, { 0x1E87, 0x0077, 0x0307 }, { 0x1E88, 0x0057, 0x0323 }, { 0x1E89, 0x0077, 0x0323 }, { 0x1E8A, 0x0058, 0x0307 }, { 0x1E8B, 0x0078, 0x0307 }, { 0x1E8C, 0x0058, 0x0308 }, { 0x1E8D, 0x0078, 0x0308 }, { 0x1E8E, 0x0059, 0x0307 }, { 0x1E8F, 0x0079, 0x0307 }, { 0x1E90, 0x005A, 0x0302 }, { 0x1E91, 0x007A, 0x0302 }, { 0x1E92, 0x005A, 0x0323 }, { 0x1E93, 0x007A, 0x0323 }, { 0x1E94, 0x005A, 0x0331 }, { 0x1E95, 0x007A, 0x0331 }, { 0x1E96, 0x0068, 0x0331 }, { 0x1E97, 0x0074, 0x0308 }, { 0x1E98, 0x0077, 0x030A }, { 0x1E99, 0x0079, 0x030A }, { 0x1E9B, 0x017F, 0x0307 }, { 0x1EA0, 0x0041, 0x0323 }, { 0x1EA1, 0x0061, 0x0323 }, { 0x1EA2, 0x0041, 0x0309 }, { 0x1EA3, 0x0061, 0x0309 }, { 0x1EA4, 0x00C2, 0x0301 }, { 0x1EA5, 0x00E2, 0x0301 }, { 0x1EA6, 0x00C2, 0x0300 }, { 0x1EA7, 0x00E2, 0x0300 }, { 0x1EA8, 0x00C2, 0x0309 }, { 0x1EA9, 0x00E2, 0x0309 }, { 0x1EAA, 0x00C2, 0x0303 }, { 0x1EAB, 0x00E2, 0x0303 }, { 0x1EAC, 0x1EA0, 0x0302 }, { 0x1EAD, 0x1EA1, 0x0302 }, { 0x1EAE, 0x0102, 0x0301 }, { 0x1EAF, 0x0103, 0x0301 }, { 0x1EB0, 0x0102, 0x0300 }, { 0x1EB1, 0x0103, 0x0300 }, { 0x1EB2, 0x0102, 0x0309 }, { 0x1EB3, 0x0103, 0x0309 }, { 0x1EB4, 0x0102, 0x0303 }, { 0x1EB5, 0x0103, 0x0303 }, { 0x1EB6, 0x1EA0, 0x0306 }, { 0x1EB7, 0x1EA1, 0x0306 }, { 0x1EB8, 0x0045, 0x0323 }, { 0x1EB9, 0x0065, 0x0323 }, { 0x1EBA, 0x0045, 0x0309 }, { 0x1EBB, 0x0065, 0x0309 }, { 0x1EBC, 0x0045, 0x0303 }, { 0x1EBD, 0x0065, 0x0303 }, { 0x1EBE, 0x00CA, 0x0301 }, { 0x1EBF, 0x00EA, 0x0301 }, { 0x1EC0, 0x00CA, 0x0300 }, { 0x1EC1, 0x00EA, 0x0300 }, { 0x1EC2, 0x00CA, 0x0309 }, { 0x1EC3, 0x00EA, 0x0309 }, { 0x1EC4, 0x00CA, 0x0303 }, { 0x1EC5, 0x00EA, 0x0303 }, { 0x1EC6, 0x1EB8, 0x0302 }, { 0x1EC7, 0x1EB9, 0x0302 }, { 0x1EC8, 0x0049, 0x0309 }, { 0x1EC9, 0x0069, 0x0309 }, { 0x1ECA, 0x0049, 0x0323 }, { 0x1ECB, 0x0069, 0x0323 }, { 0x1ECC, 0x004F, 0x0323 }, { 0x1ECD, 0x006F, 0x0323 }, { 0x1ECE, 0x004F, 0x0309 }, { 0x1ECF, 0x006F, 0x0309 }, { 0x1ED0, 0x00D4, 0x0301 }, { 0x1ED1, 0x00F4, 0x0301 }, { 0x1ED2, 0x00D4, 0x0300 }, { 0x1ED3, 0x00F4, 0x0300 }, { 0x1ED4, 0x00D4, 0x0309 }, { 0x1ED5, 0x00F4, 0x0309 }, { 0x1ED6, 0x00D4, 0x0303 }, { 0x1ED7, 0x00F4, 0x0303 }, { 0x1ED8, 0x1ECC, 0x0302 }, { 0x1ED9, 0x1ECD, 0x0302 }, { 0x1EDA, 0x01A0, 0x0301 }, { 0x1EDB, 0x01A1, 0x0301 }, { 0x1EDC, 0x01A0, 0x0300 }, { 0x1EDD, 0x01A1, 0x0300 }, { 0x1EDE, 0x01A0, 0x0309 }, { 0x1EDF, 0x01A1, 0x0309 }, { 0x1EE0, 0x01A0, 0x0303 }, { 0x1EE1, 0x01A1, 0x0303 }, { 0x1EE2, 0x01A0, 0x0323 }, { 0x1EE3, 0x01A1, 0x0323 }, { 0x1EE4, 0x0055, 0x0323 }, { 0x1EE5, 0x0075, 0x0323 }, { 0x1EE6, 0x0055, 0x0309 }, { 0x1EE7, 0x0075, 0x0309 }, { 0x1EE8, 0x01AF, 0x0301 }, { 0x1EE9, 0x01B0, 0x0301 }, { 0x1EEA, 0x01AF, 0x0300 }, { 0x1EEB, 0x01B0, 0x0300 }, { 0x1EEC, 0x01AF, 0x0309 }, { 0x1EED, 0x01B0, 0x0309 }, { 0x1EEE, 0x01AF, 0x0303 }, { 0x1EEF, 0x01B0, 0x0303 }, { 0x1EF0, 0x01AF, 0x0323 }, { 0x1EF1, 0x01B0, 0x0323 }, { 0x1EF2, 0x0059, 0x0300 }, { 0x1EF3, 0x0079, 0x0300 }, { 0x1EF4, 0x0059, 0x0323 }, { 0x1EF5, 0x0079, 0x0323 }, { 0x1EF6, 0x0059, 0x0309 }, { 0x1EF7, 0x0079, 0x0309 }, { 0x1EF8, 0x0059, 0x0303 }, { 0x1EF9, 0x0079, 0x0303 }, { 0x1F00, 0x03B1, 0x0313 }, { 0x1F01, 0x03B1, 0x0314 }, { 0x1F02, 0x1F00, 0x0300 }, { 0x1F03, 0x1F01, 0x0300 }, { 0x1F04, 0x1F00, 0x0301 }, { 0x1F05, 0x1F01, 0x0301 }, { 0x1F06, 0x1F00, 0x0342 }, { 0x1F07, 0x1F01, 0x0342 }, { 0x1F08, 0x0391, 0x0313 }, { 0x1F09, 0x0391, 0x0314 }, { 0x1F0A, 0x1F08, 0x0300 }, { 0x1F0B, 0x1F09, 0x0300 }, { 0x1F0C, 0x1F08, 0x0301 }, { 0x1F0D, 0x1F09, 0x0301 }, { 0x1F0E, 0x1F08, 0x0342 }, { 0x1F0F, 0x1F09, 0x0342 }, { 0x1F10, 0x03B5, 0x0313 }, { 0x1F11, 0x03B5, 0x0314 }, { 0x1F12, 0x1F10, 0x0300 }, { 0x1F13, 0x1F11, 0x0300 }, { 0x1F14, 0x1F10, 0x0301 }, { 0x1F15, 0x1F11, 0x0301 }, { 0x1F18, 0x0395, 0x0313 }, { 0x1F19, 0x0395, 0x0314 }, { 0x1F1A, 0x1F18, 0x0300 }, { 0x1F1B, 0x1F19, 0x0300 }, { 0x1F1C, 0x1F18, 0x0301 }, { 0x1F1D, 0x1F19, 0x0301 }, { 0x1F20, 0x03B7, 0x0313 }, { 0x1F21, 0x03B7, 0x0314 }, { 0x1F22, 0x1F20, 0x0300 }, { 0x1F23, 0x1F21, 0x0300 }, { 0x1F24, 0x1F20, 0x0301 }, { 0x1F25, 0x1F21, 0x0301 }, { 0x1F26, 0x1F20, 0x0342 }, { 0x1F27, 0x1F21, 0x0342 }, { 0x1F28, 0x0397, 0x0313 }, { 0x1F29, 0x0397, 0x0314 }, { 0x1F2A, 0x1F28, 0x0300 }, { 0x1F2B, 0x1F29, 0x0300 }, { 0x1F2C, 0x1F28, 0x0301 }, { 0x1F2D, 0x1F29, 0x0301 }, { 0x1F2E, 0x1F28, 0x0342 }, { 0x1F2F, 0x1F29, 0x0342 }, { 0x1F30, 0x03B9, 0x0313 }, { 0x1F31, 0x03B9, 0x0314 }, { 0x1F32, 0x1F30, 0x0300 }, { 0x1F33, 0x1F31, 0x0300 }, { 0x1F34, 0x1F30, 0x0301 }, { 0x1F35, 0x1F31, 0x0301 }, { 0x1F36, 0x1F30, 0x0342 }, { 0x1F37, 0x1F31, 0x0342 }, { 0x1F38, 0x0399, 0x0313 }, { 0x1F39, 0x0399, 0x0314 }, { 0x1F3A, 0x1F38, 0x0300 }, { 0x1F3B, 0x1F39, 0x0300 }, { 0x1F3C, 0x1F38, 0x0301 }, { 0x1F3D, 0x1F39, 0x0301 }, { 0x1F3E, 0x1F38, 0x0342 }, { 0x1F3F, 0x1F39, 0x0342 }, { 0x1F40, 0x03BF, 0x0313 }, { 0x1F41, 0x03BF, 0x0314 }, { 0x1F42, 0x1F40, 0x0300 }, { 0x1F43, 0x1F41, 0x0300 }, { 0x1F44, 0x1F40, 0x0301 }, { 0x1F45, 0x1F41, 0x0301 }, { 0x1F48, 0x039F, 0x0313 }, { 0x1F49, 0x039F, 0x0314 }, { 0x1F4A, 0x1F48, 0x0300 }, { 0x1F4B, 0x1F49, 0x0300 }, { 0x1F4C, 0x1F48, 0x0301 }, { 0x1F4D, 0x1F49, 0x0301 }, { 0x1F50, 0x03C5, 0x0313 }, { 0x1F51, 0x03C5, 0x0314 }, { 0x1F52, 0x1F50, 0x0300 }, { 0x1F53, 0x1F51, 0x0300 }, { 0x1F54, 0x1F50, 0x0301 }, { 0x1F55, 0x1F51, 0x0301 }, { 0x1F56, 0x1F50, 0x0342 }, { 0x1F57, 0x1F51, 0x0342 }, { 0x1F59, 0x03A5, 0x0314 }, { 0x1F5B, 0x1F59, 0x0300 }, { 0x1F5D, 0x1F59, 0x0301 }, { 0x1F5F, 0x1F59, 0x0342 }, { 0x1F60, 0x03C9, 0x0313 }, { 0x1F61, 0x03C9, 0x0314 }, { 0x1F62, 0x1F60, 0x0300 }, { 0x1F63, 0x1F61, 0x0300 }, { 0x1F64, 0x1F60, 0x0301 }, { 0x1F65, 0x1F61, 0x0301 }, { 0x1F66, 0x1F60, 0x0342 }, { 0x1F67, 0x1F61, 0x0342 }, { 0x1F68, 0x03A9, 0x0313 }, { 0x1F69, 0x03A9, 0x0314 }, { 0x1F6A, 0x1F68, 0x0300 }, { 0x1F6B, 0x1F69, 0x0300 }, { 0x1F6C, 0x1F68, 0x0301 }, { 0x1F6D, 0x1F69, 0x0301 }, { 0x1F6E, 0x1F68, 0x0342 }, { 0x1F6F, 0x1F69, 0x0342 }, { 0x1F70, 0x03B1, 0x0300 }, { 0x1F72, 0x03B5, 0x0300 }, { 0x1F74, 0x03B7, 0x0300 }, { 0x1F76, 0x03B9, 0x0300 }, { 0x1F78, 0x03BF, 0x0300 }, { 0x1F7A, 0x03C5, 0x0300 }, { 0x1F7C, 0x03C9, 0x0300 }, { 0x1F80, 0x1F00, 0x0345 }, { 0x1F81, 0x1F01, 0x0345 }, { 0x1F82, 0x1F02, 0x0345 }, { 0x1F83, 0x1F03, 0x0345 }, { 0x1F84, 0x1F04, 0x0345 }, { 0x1F85, 0x1F05, 0x0345 }, { 0x1F86, 0x1F06, 0x0345 }, { 0x1F87, 0x1F07, 0x0345 }, { 0x1F88, 0x1F08, 0x0345 }, { 0x1F89, 0x1F09, 0x0345 }, { 0x1F8A, 0x1F0A, 0x0345 }, { 0x1F8B, 0x1F0B, 0x0345 }, { 0x1F8C, 0x1F0C, 0x0345 }, { 0x1F8D, 0x1F0D, 0x0345 }, { 0x1F8E, 0x1F0E, 0x0345 }, { 0x1F8F, 0x1F0F, 0x0345 }, { 0x1F90, 0x1F20, 0x0345 }, { 0x1F91, 0x1F21, 0x0345 }, { 0x1F92, 0x1F22, 0x0345 }, { 0x1F93, 0x1F23, 0x0345 }, { 0x1F94, 0x1F24, 0x0345 }, { 0x1F95, 0x1F25, 0x0345 }, { 0x1F96, 0x1F26, 0x0345 }, { 0x1F97, 0x1F27, 0x0345 }, { 0x1F98, 0x1F28, 0x0345 }, { 0x1F99, 0x1F29, 0x0345 }, { 0x1F9A, 0x1F2A, 0x0345 }, { 0x1F9B, 0x1F2B, 0x0345 }, { 0x1F9C, 0x1F2C, 0x0345 }, { 0x1F9D, 0x1F2D, 0x0345 }, { 0x1F9E, 0x1F2E, 0x0345 }, { 0x1F9F, 0x1F2F, 0x0345 }, { 0x1FA0, 0x1F60, 0x0345 }, { 0x1FA1, 0x1F61, 0x0345 }, { 0x1FA2, 0x1F62, 0x0345 }, { 0x1FA3, 0x1F63, 0x0345 }, { 0x1FA4, 0x1F64, 0x0345 }, { 0x1FA5, 0x1F65, 0x0345 }, { 0x1FA6, 0x1F66, 0x0345 }, { 0x1FA7, 0x1F67, 0x0345 }, { 0x1FA8, 0x1F68, 0x0345 }, { 0x1FA9, 0x1F69, 0x0345 }, { 0x1FAA, 0x1F6A, 0x0345 }, { 0x1FAB, 0x1F6B, 0x0345 }, { 0x1FAC, 0x1F6C, 0x0345 }, { 0x1FAD, 0x1F6D, 0x0345 }, { 0x1FAE, 0x1F6E, 0x0345 }, { 0x1FAF, 0x1F6F, 0x0345 }, { 0x1FB0, 0x03B1, 0x0306 }, { 0x1FB1, 0x03B1, 0x0304 }, { 0x1FB2, 0x1F70, 0x0345 }, { 0x1FB3, 0x03B1, 0x0345 }, { 0x1FB4, 0x03AC, 0x0345 }, { 0x1FB6, 0x03B1, 0x0342 }, { 0x1FB7, 0x1FB6, 0x0345 }, { 0x1FB8, 0x0391, 0x0306 }, { 0x1FB9, 0x0391, 0x0304 }, { 0x1FBA, 0x0391, 0x0300 }, { 0x1FBC, 0x0391, 0x0345 }, { 0x1FC1, 0x00A8, 0x0342 }, { 0x1FC2, 0x1F74, 0x0345 }, { 0x1FC3, 0x03B7, 0x0345 }, { 0x1FC4, 0x03AE, 0x0345 }, { 0x1FC6, 0x03B7, 0x0342 }, { 0x1FC7, 0x1FC6, 0x0345 }, { 0x1FC8, 0x0395, 0x0300 }, { 0x1FCA, 0x0397, 0x0300 }, { 0x1FCC, 0x0397, 0x0345 }, { 0x1FCD, 0x1FBF, 0x0300 }, { 0x1FCE, 0x1FBF, 0x0301 }, { 0x1FCF, 0x1FBF, 0x0342 }, { 0x1FD0, 0x03B9, 0x0306 }, { 0x1FD1, 0x03B9, 0x0304 }, { 0x1FD2, 0x03CA, 0x0300 }, { 0x1FD6, 0x03B9, 0x0342 }, { 0x1FD7, 0x03CA, 0x0342 }, { 0x1FD8, 0x0399, 0x0306 }, { 0x1FD9, 0x0399, 0x0304 }, { 0x1FDA, 0x0399, 0x0300 }, { 0x1FDD, 0x1FFE, 0x0300 }, { 0x1FDE, 0x1FFE, 0x0301 }, { 0x1FDF, 0x1FFE, 0x0342 }, { 0x1FE0, 0x03C5, 0x0306 }, { 0x1FE1, 0x03C5, 0x0304 }, { 0x1FE2, 0x03CB, 0x0300 }, { 0x1FE4, 0x03C1, 0x0313 }, { 0x1FE5, 0x03C1, 0x0314 }, { 0x1FE6, 0x03C5, 0x0342 }, { 0x1FE7, 0x03CB, 0x0342 }, { 0x1FE8, 0x03A5, 0x0306 }, { 0x1FE9, 0x03A5, 0x0304 }, { 0x1FEA, 0x03A5, 0x0300 }, { 0x1FEC, 0x03A1, 0x0314 }, { 0x1FED, 0x00A8, 0x0300 }, { 0x1FF2, 0x1F7C, 0x0345 }, { 0x1FF3, 0x03C9, 0x0345 }, { 0x1FF4, 0x03CE, 0x0345 }, { 0x1FF6, 0x03C9, 0x0342 }, { 0x1FF7, 0x1FF6, 0x0345 }, { 0x1FF8, 0x039F, 0x0300 }, { 0x1FFA, 0x03A9, 0x0300 }, { 0x1FFC, 0x03A9, 0x0345 }, { 0x219A, 0x2190, 0x0338 }, { 0x219B, 0x2192, 0x0338 }, { 0x21AE, 0x2194, 0x0338 }, { 0x21CD, 0x21D0, 0x0338 }, { 0x21CE, 0x21D4, 0x0338 }, { 0x21CF, 0x21D2, 0x0338 }, { 0x2204, 0x2203, 0x0338 }, { 0x2209, 0x2208, 0x0338 }, { 0x220C, 0x220B, 0x0338 }, { 0x2224, 0x2223, 0x0338 }, { 0x2226, 0x2225, 0x0338 }, { 0x2241, 0x223C, 0x0338 }, { 0x2244, 0x2243, 0x0338 }, { 0x2247, 0x2245, 0x0338 }, { 0x2249, 0x2248, 0x0338 }, { 0x2260, 0x003D, 0x0338 }, { 0x2262, 0x2261, 0x0338 }, { 0x226D, 0x224D, 0x0338 }, { 0x226E, 0x003C, 0x0338 }, { 0x226F, 0x003E, 0x0338 }, { 0x2270, 0x2264, 0x0338 }, { 0x2271, 0x2265, 0x0338 }, { 0x2274, 0x2272, 0x0338 }, { 0x2275, 0x2273, 0x0338 }, { 0x2278, 0x2276, 0x0338 }, { 0x2279, 0x2277, 0x0338 }, { 0x2280, 0x227A, 0x0338 }, { 0x2281, 0x227B, 0x0338 }, { 0x2284, 0x2282, 0x0338 }, { 0x2285, 0x2283, 0x0338 }, { 0x2288, 0x2286, 0x0338 }, { 0x2289, 0x2287, 0x0338 }, { 0x22AC, 0x22A2, 0x0338 }, { 0x22AD, 0x22A8, 0x0338 }, { 0x22AE, 0x22A9, 0x0338 }, { 0x22AF, 0x22AB, 0x0338 }, { 0x22E0, 0x227C, 0x0338 }, { 0x22E1, 0x227D, 0x0338 }, { 0x22E2, 0x2291, 0x0338 }, { 0x22E3, 0x2292, 0x0338 }, { 0x22EA, 0x22B2, 0x0338 }, { 0x22EB, 0x22B3, 0x0338 }, { 0x22EC, 0x22B4, 0x0338 }, { 0x22ED, 0x22B5, 0x0338 }, { 0x2ADC, 0x2ADD, 0x0338 }, { 0x304C, 0x304B, 0x3099 }, { 0x304E, 0x304D, 0x3099 }, { 0x3050, 0x304F, 0x3099 }, { 0x3052, 0x3051, 0x3099 }, { 0x3054, 0x3053, 0x3099 }, { 0x3056, 0x3055, 0x3099 }, { 0x3058, 0x3057, 0x3099 }, { 0x305A, 0x3059, 0x3099 }, { 0x305C, 0x305B, 0x3099 }, { 0x305E, 0x305D, 0x3099 }, { 0x3060, 0x305F, 0x3099 }, { 0x3062, 0x3061, 0x3099 }, { 0x3065, 0x3064, 0x3099 }, { 0x3067, 0x3066, 0x3099 }, { 0x3069, 0x3068, 0x3099 }, { 0x3070, 0x306F, 0x3099 }, { 0x3071, 0x306F, 0x309A }, { 0x3073, 0x3072, 0x3099 }, { 0x3074, 0x3072, 0x309A }, { 0x3076, 0x3075, 0x3099 }, { 0x3077, 0x3075, 0x309A }, { 0x3079, 0x3078, 0x3099 }, { 0x307A, 0x3078, 0x309A }, { 0x307C, 0x307B, 0x3099 }, { 0x307D, 0x307B, 0x309A }, { 0x3094, 0x3046, 0x3099 }, { 0x309E, 0x309D, 0x3099 }, { 0x30AC, 0x30AB, 0x3099 }, { 0x30AE, 0x30AD, 0x3099 }, { 0x30B0, 0x30AF, 0x3099 }, { 0x30B2, 0x30B1, 0x3099 }, { 0x30B4, 0x30B3, 0x3099 }, { 0x30B6, 0x30B5, 0x3099 }, { 0x30B8, 0x30B7, 0x3099 }, { 0x30BA, 0x30B9, 0x3099 }, { 0x30BC, 0x30BB, 0x3099 }, { 0x30BE, 0x30BD, 0x3099 }, { 0x30C0, 0x30BF, 0x3099 }, { 0x30C2, 0x30C1, 0x3099 }, { 0x30C5, 0x30C4, 0x3099 }, { 0x30C7, 0x30C6, 0x3099 }, { 0x30C9, 0x30C8, 0x3099 }, { 0x30D0, 0x30CF, 0x3099 }, { 0x30D1, 0x30CF, 0x309A }, { 0x30D3, 0x30D2, 0x3099 }, { 0x30D4, 0x30D2, 0x309A }, { 0x30D6, 0x30D5, 0x3099 }, { 0x30D7, 0x30D5, 0x309A }, { 0x30D9, 0x30D8, 0x3099 }, { 0x30DA, 0x30D8, 0x309A }, { 0x30DC, 0x30DB, 0x3099 }, { 0x30DD, 0x30DB, 0x309A }, { 0x30F4, 0x30A6, 0x3099 }, { 0x30F7, 0x30EF, 0x3099 }, { 0x30F8, 0x30F0, 0x3099 }, { 0x30F9, 0x30F1, 0x3099 }, { 0x30FA, 0x30F2, 0x3099 }, { 0x30FE, 0x30FD, 0x3099 }, { 0xFB1D, 0x05D9, 0x05B4 }, { 0xFB1F, 0x05F2, 0x05B7 }, { 0xFB2A, 0x05E9, 0x05C1 }, { 0xFB2B, 0x05E9, 0x05C2 }, { 0xFB2C, 0xFB49, 0x05C1 }, { 0xFB2D, 0xFB49, 0x05C2 }, { 0xFB2E, 0x05D0, 0x05B7 }, { 0xFB2F, 0x05D0, 0x05B8 }, { 0xFB30, 0x05D0, 0x05BC }, { 0xFB31, 0x05D1, 0x05BC }, { 0xFB32, 0x05D2, 0x05BC }, { 0xFB33, 0x05D3, 0x05BC }, { 0xFB34, 0x05D4, 0x05BC }, { 0xFB35, 0x05D5, 0x05BC }, { 0xFB36, 0x05D6, 0x05BC }, { 0xFB38, 0x05D8, 0x05BC }, { 0xFB39, 0x05D9, 0x05BC }, { 0xFB3A, 0x05DA, 0x05BC }, { 0xFB3B, 0x05DB, 0x05BC }, { 0xFB3C, 0x05DC, 0x05BC }, { 0xFB3E, 0x05DE, 0x05BC }, { 0xFB40, 0x05E0, 0x05BC }, { 0xFB41, 0x05E1, 0x05BC }, { 0xFB43, 0x05E3, 0x05BC }, { 0xFB44, 0x05E4, 0x05BC }, { 0xFB46, 0x05E6, 0x05BC }, { 0xFB47, 0x05E7, 0x05BC }, { 0xFB48, 0x05E8, 0x05BC }, { 0xFB49, 0x05E9, 0x05BC }, { 0xFB4A, 0x05EA, 0x05BC }, { 0xFB4B, 0x05D5, 0x05B9 }, { 0xFB4C, 0x05D1, 0x05BF }, { 0xFB4D, 0x05DB, 0x05BF }, { 0xFB4E, 0x05E4, 0x05BF }, /* out of range of unsigned short... */ #if 0 { 0x1D15E, 0x1D157, 0x1D165 }, { 0x1D15F, 0x1D158, 0x1D165 }, { 0x1D160, 0x1D15F, 0x1D16E }, { 0x1D161, 0x1D15F, 0x1D16F }, { 0x1D162, 0x1D15F, 0x1D170 }, { 0x1D163, 0x1D15F, 0x1D171 }, { 0x1D164, 0x1D15F, 0x1D172 }, { 0x1D1BB, 0x1D1B9, 0x1D165 }, { 0x1D1BC, 0x1D1BA, 0x1D165 }, { 0x1D1BD, 0x1D1BB, 0x1D16E }, { 0x1D1BE, 0x1D1BC, 0x1D16E }, { 0x1D1BF, 0x1D1BB, 0x1D16F }, { 0x1D1C0, 0x1D1BC, 0x1D16F }, #endif /* special hack, treat Arabic ligatures as combining characters */ /* combine them to the isolated presentation form, then let * the shaping and joining take care of it */ { 0xFEF5, 0x0644, 0x0622 }, /* LAM_ALEF_MADDA */ { 0xFEF7, 0x0644, 0x0623 }, /* LAM_ALEF_HAMZA_ABOVE */ { 0xFEF9, 0x0644, 0x0625 }, /* LAM_ALEF_HAMZA_BELOW */ { 0xFEFB, 0x0644, 0x0627 }, /* LAM_ALEF */ }; /* -------------------------- local functions ------------------------------ */ /* look-up functions, maybe theese should use binary search? would require a duplicate of comb_table to reverse map... */ static int get_combining_class(unsigned short ch) { int count; int table_size = sizeof(combclass_table) / sizeof(combclass_table[0]); for (count = 0; count < table_size; count++) { if (combclass_table[count].key == ch) { return combclass_table[count].combclass; } } return 0; } static const char_comb_t* get_comb_entry_decomposed(unsigned short ch) { int count; int table_size = sizeof(comb_table) / sizeof(comb_table[0]); for (count = 0; count < table_size; count++) { if (comb_table[count].key == ch) { return &comb_table[count]; } } return NULL; } static unsigned short get_comb_entry_composed(unsigned short first, unsigned short second) { int count; int table_size = sizeof(comb_table) / sizeof(comb_table[0]); for (count = 0; count < table_size; count++) { if (comb_table[count].first == first && comb_table[count].second == second) { return comb_table[count].key; } } return (unsigned short) 0; } static int convert_to_ucs2( const unsigned char *str_utf8, unsigned short *str_ucs2, int len) { int in_pos = 0; int out_pos = 0; while (in_pos < len) { if (str_utf8[in_pos] <= 0x7f) { str_ucs2[out_pos] = (unsigned short)str_utf8[in_pos]; in_pos++; } else { if ((str_utf8[in_pos] & 0300) != 0300) { /* out of sync */ str_ucs2[out_pos] = REPLACEMENT_CHARACTER; in_pos++; } else if (in_pos < len-1 && str_utf8[in_pos] <= 0xdf && str_utf8[in_pos + 1] <= 0xbf && str_utf8[in_pos + 1] >= 0x80) { str_ucs2[out_pos] = ((str_utf8[in_pos] & 0x1f) << 6) + (str_utf8[in_pos+1] & 0x3f); /* check for overlong sequence */ if(str_ucs2[out_pos] < 0x80) str_ucs2[out_pos] = REPLACEMENT_CHARACTER; in_pos += 2; } else if (in_pos < len-2 && str_utf8[in_pos] <= 0xef && str_utf8[in_pos + 1] <= 0xbf && str_utf8[in_pos + 1] >= 0x80 && str_utf8[in_pos + 2] <= 0xbf && str_utf8[in_pos + 2] >= 0x80) { str_ucs2[out_pos] = ((str_utf8[in_pos] & 0x0f) << 12) + ((str_utf8[in_pos+1] & 0x3f) << 6) + (str_utf8[in_pos+2] & 0x3f); /* check for overlong sequence */ if(str_ucs2[out_pos] < 0x800) str_ucs2[out_pos] = REPLACEMENT_CHARACTER; in_pos += 3; } else { /* incomplete sequence */ str_ucs2[out_pos] = REPLACEMENT_CHARACTER; in_pos++; } } out_pos++; } return out_pos; } static int convert_to_utf8( const unsigned short *str_ucs2, unsigned char *str_utf8, int len) { int in_pos = 0; int out_pos = 0; for (in_pos = 0 ; in_pos < len ; in_pos++) { if (str_ucs2[in_pos] <= 0x7f) { str_utf8[out_pos] = str_ucs2[in_pos]; out_pos++; } else if (str_ucs2[in_pos] <= 0x7ff) { str_utf8[out_pos] = (str_ucs2[in_pos] >> 6) | 0xc0; str_utf8[out_pos+1] = (str_ucs2[in_pos] & 0x3f) | 0x80; out_pos += 2; } else { str_utf8[out_pos] = (str_ucs2[in_pos] >> 12) | 0xe0; str_utf8[out_pos+1] = ((str_ucs2[in_pos] & 0xfff) >> 6) | 0x80; str_utf8[out_pos+2] = (str_ucs2[in_pos] & 0x3f) | 0x80; out_pos += 3; } /* this doesn't handle values outside UCS2 (16-bit) */ } return out_pos; } /* main procedure: takes a pointer to a string (UTF-8) first decomposes string, then rearrange combining characters, the combines them back. Result is stored in original string (can never be "expanded" from original size), new length is returned */ int CombineChars( unsigned char *str_visual, int len, superimpose_char_t **comb_chars, int **l_to_v) { int i,j,k; /* counters */ unsigned short *source; unsigned short *dest; int *source_v_to_l; int *dest_v_to_l; int str_len; int in_str_len; int out_str_len; int comp_str_len = 0; Bool has_changed; /* if input has zero length, return immediatly */ if (len == 0) { return 0; } /* decompose composed characters */ source = (unsigned short *)safemalloc( (len + 1) * sizeof(unsigned short)); /* convert from UTF-8-encoded text to internal 16-bit encoding */ str_len = convert_to_ucs2(str_visual,source,len); in_str_len = str_len; /* we don't really need to NULL-terminate source, since we have string length */ /* be pessimistic, assume all characters are decomposed */ dest = (unsigned short *)safemalloc( (str_len + 1) * 2 * sizeof(unsigned short)); /* use theese to keep track of the mapping of characters from logical to visual */ source_v_to_l = (int *)safemalloc(str_len * sizeof(int)); dest_v_to_l = (int *)safemalloc(str_len * 2 * sizeof(int)); /* setup initial mapping 1-to-1 */ for(i = 0 ; i < str_len ; i++) { source_v_to_l[i] = i; } do { has_changed = False; for (i = 0, j = 0; i < str_len; i++) { const char_comb_t *decomp = get_comb_entry_decomposed(source[i]); /* current character is decomposable */ if (decomp) { dest[j] = decomp->first; dest[j+1] = decomp->second; dest_v_to_l[j] = source_v_to_l[i]; dest_v_to_l[j+1] = source_v_to_l[i]; j += 2; has_changed = True; } else /* leave it as is */ { dest[j] = source[i]; dest_v_to_l[j] = source_v_to_l[i]; j++; } } /* now swap */ free(source); free(source_v_to_l); source = dest; source_v_to_l = dest_v_to_l; str_len = j; dest = (unsigned short *)safemalloc( (str_len + 1) * 2 * sizeof(unsigned short)); dest_v_to_l = (int *)safemalloc(str_len * 2 * sizeof(int)); } while (has_changed); /* source now holds decomposed string (got swapped before exiting loop, str_len holds string length */ /* we reuse dest for composing, can use existing string lengths since it will only get shorter */ /* source_v_to_l holds the mapping from positions in decomposed string to original string */ /* rearrange combining characters */ do { has_changed = False; for (i = 0; i < str_len - 1; i++) { /* swap if combining-class(c1) > combining-class(c2) and combining-class(c2) != 0 */ /* use negative values for marks that have combining class 0, but should be taken out for drawing superimposed */ int c1 = get_combining_class(source[i]); int c2 = get_combining_class(source[i+1]); if (c1 > c2 && c2 > 0) { unsigned short temp = source[i]; int temp_v_to_l = source_v_to_l[i]; source[i] = source[i+1]; source[i+1] = temp; source_v_to_l[i] = source_v_to_l[i+1]; source_v_to_l[i+1] = temp_v_to_l; has_changed = True; } } } while (has_changed); /* compose */ do { unsigned short *temp; int *temp_v_to_l; Bool last_changed = False; has_changed = False; for (i = 0, j = 0; i < str_len - 1; j++) { unsigned short composed = get_comb_entry_composed(source[i], source[i+1]); dest_v_to_l[j] = source_v_to_l[i]; if (composed != 0) { dest[j] = composed; /* if the last character was "absorbed" */ if (i == str_len - 2) { last_changed = True; } i += 2; has_changed = True; } else { dest[j] = source[i]; i++; } } temp = dest; dest = source; source = temp; temp_v_to_l = dest_v_to_l; dest_v_to_l = source_v_to_l; source_v_to_l = temp_v_to_l; /* fixup the last character, the loop above goes to second last, since it needs to look at 2 consecutive, if the last character is a non-combining character */ /* since we have an immediate return on zero length, this works otherwise this would introduce crap here */ if (!last_changed) { source[j] = dest[i]; source_v_to_l[j] = dest_v_to_l[i]; str_len = j+1; } else { str_len = j; } } while (has_changed); /* source contains composed string */ /* gather "uncomposed" combining characters here for rendering over normal characters later */ comp_str_len = 0; if (comb_chars != NULL) { /* calculate number of combining characters left */ for (i = 0 ; i < str_len ; i++) { if (get_combining_class(source[i]) != 0) { comp_str_len++; } } /* allocate storage for combining characters */ *comb_chars = (superimpose_char_t *) safemalloc((comp_str_len + 1) * sizeof(superimpose_char_t)); } for (i = 0,j = 0,k = 0 ; i < str_len ; i++) { /* if character is non-combining, just copy it over to output */ /* if first character is a combing character, just output it as if it where a base character */ if (get_combining_class(source[i]) == 0) { dest[j] = source[i]; dest_v_to_l[j] = source_v_to_l[i]; j++; } else { if (comb_chars != NULL) { /* store composing character as associated with last base charcter */ (*comb_chars)[k].position = j == 0 ? 0 : j-1; (*comb_chars)[k].c.byte1 = source[i] >> 8; (*comb_chars)[k].c.byte2 = source[i] & 0xff; k++; } } } /* terminate */ if (comb_chars != NULL) { (*comb_chars)[comp_str_len].position = 0; (*comb_chars)[comp_str_len].c.byte1 = 0; (*comb_chars)[comp_str_len].c.byte2 = 0; } str_len = convert_to_utf8(dest,str_visual,j); out_str_len = j; str_visual[str_len] = 0; if(l_to_v != NULL) { *l_to_v = (int *)safemalloc((in_str_len + 1) * sizeof(int)); /* map the visual to logical mapping obtained above into a logical to visual mapping */ /* setup the final mapping from logical to visual positions */ /* if no base characters out, all positions map to zero, because there we have combining chars in that case */ if(out_str_len == 0) { for(i = 0 ; i < in_str_len ; i++) { (*l_to_v)[i] = 0; } } for(i = 0, j = 0 ; i < out_str_len ; i++) { /* for each element in mapping from visual string insert "backtracked" references from logical string by inserting consequitive entries, as many as the step in the mapping from visual to logical */ int step = (i == out_str_len - 1) ? in_str_len - j : dest_v_to_l[i+1] - dest_v_to_l[i]; for(k = 0 ; k < step ; k++, j++) { (*l_to_v)[j] = i; } } /* terminated it with -1, to avoid have to send around lenghts */ (*l_to_v)[in_str_len] = -1; } /* clean up */ free(source); free(dest); free(source_v_to_l); free(dest_v_to_l); return str_len; } fvwm-2.6.7/libs/FBidi.h0000644000175700017570000000534612773467232011550 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Mikhael Goikhman */ /* * FBidi.h - interface to Bidi (bidirectionality for some asian languages). */ /*** * The main function is * char *FBidiConvert( * const char *logical_str, const char *charset, int str_len, Bool *is_rtl, * int *out_len); * * input: * logical string - the original string * string charset - examples: "iso8859-15", "iso8859-8", "iso8859-6", "utf-8" * * output: * visual string is returned (should be free'd), or NULL if not applicable * the last argument is set to True if the string has the base RTL direction * * The is_rtl aggument may be used for 2 purposes. The first is to change the * string alignment if there is a free space (but it probably worth not to * override the user specified string aligment). The second is to determine * where to put ellipses if the string is longer than the available space. * * There are several possible ways to solve the ellipses problem. * This is not automated, the caller should choose one or another way. * * 1) For a logical string evaluate a visual string (and a base direction) * only once. If needed, cut the visual string and add ellipses at the * correct string side. * * 2) Cut logical string to the size that will be drawn, add allipses to the * end and call FBidiConvert on the resulting string. * * 3) Cut logical string to the size that will be drawn, call FBidiConvert * and add ellipses at the correct string side. * * Probably 2) is the best, but there is one nuance, the ellipses may be at * the middle of the string. With 1) and 3) the ellipses are always on the * edge of the string. The 1) is good when speed is more important than memory * and the string is usually either pure LTR or RTL. * * Example 1: * * input: she said "SHALOM" and then "BOKER TOV". * output: she said "MOLAHS" and then "VOT REKOB". * is_rtl: False * * 1) she said "MO... * 2) she said ...HS" * 3) she said HS"... * * Example 2: * * input: SHALOM, world! * output: !world ,MOLAHS * is_rtl: True * * 1) ...ld ,MOLAHS * 2) wo... ,MOLAHS * 3) ...wo ,MOLAHS * **/ #ifndef FBIDI_H #define FBIDI_H #include "config.h" #include #include "CombineChars.h" #if HAVE_BIDI /* * Checks whether the string in the given charset should be BidiConvert'd. */ Bool FBidiIsApplicable(const char *charset); /* * Converts the given logical string to visual string for the given charset. */ char *FBidiConvert( const char *logical_str, const char *charset, int str_len, Bool *is_rtl, int *out_len, superimpose_char_t *comb_chars, int *pos_l_to_v); #else /* !HAVE_BIDI */ #define FBidiIsApplicable(c) False #define FBidiConvert(s, c, l, r, o, cc, lv) NULL #endif /* HAVE_BIDI */ #endif /* FBIDI_H */ fvwm-2.6.7/libs/FlocaleCharset.h0000644000175700017570000000351412773467232013445 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef FLOCALE_CHARSET_H #define FLOCALE_CHARSET_H /* ---------------------------- included header files ---------------------- */ #include "config.h" #include "Flocale.h" /* ---------------------------- global definitions ------------------------- */ #ifdef HAVE_LIBCHARSET #define FlocaleLibcharsetSupport 1 #else #define FlocaleLibcharsetSupport 0 #endif #ifdef HAVE_CODESET #define FlocaleCodesetSupport 1 #else #define FlocaleCodesetSupport 0 #endif #if FlocaleLibcharsetSupport #define Flocale_charset() locale_charset() #else #define Flocale_charset() NULL #endif #if FlocaleCodesetSupport #define Fnl_langinfo(a) nl_langinfo(a) #define FCODESET CODESET #else #define Fnl_langinfo(a) NULL #define FCODESET 0 #endif /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* * */ void FlocaleCharsetInit(Display *dpy, const char *module); void FlocaleCharsetSetFlocaleCharset( Display *dpy, FlocaleFont *flf, char *hints, char *encoding, char *module); FlocaleCharset *FlocaleCharsetGetDefaultCharset(Display *dpy, char *module); FlocaleCharset *FlocaleCharsetGetFLCXOMCharset(void); FlocaleCharset *FlocaleCharsetGetUtf8Charset(void); FlocaleCharset *FlocaleCharsetGetLocaleCharset(void); FlocaleCharset *FlocaleCharsetGetUnknownCharset(void); const char *FlocaleGetBidiCharset(Display *dpy, FlocaleCharset *fc); FlocaleCharset *FlocaleCharsetGetEUCJPCharset(void); Bool FlocaleCharsetIsCharsetXLocale(Display *dpy, char *charset, char *module); void FlocaleCharsetPrintXOMInfo(void); #endif /* FLOCALE_CHARSET_H */ fvwm-2.6.7/libs/Rectangles.c0000644000175700017570000000443612773467232012654 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include "Rectangles.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ Bool frect_get_intersection( int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, XRectangle *r) { if (x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2) { if (r) { r->x = max(x1,x2); r->y = max(y1,y2); r->width = min(x1+w1,x2+w2) - max(x1,x2); r->height =min(y1+h1,y2+h2) - max(y1,y2); } return True; } return False; } Bool frect_get_seg_intersection( int x1, int w1, int x2, int w2, int *x, int *w) { if (x1 + w1 > x2 && x1 < x2 + w2) { if (x) { *x = max(x1,x2); } if (w) { *w = min(x1+w1,x2+w2) - max(x1,x2); } return True; } return False; } Bool frect_get_rect_intersection( XRectangle a, XRectangle b, XRectangle *r) { return frect_get_intersection( a.x, a.y, a.width, a.height, b.x, b.y, b.width, b.height, r); } fvwm-2.6.7/libs/Colorset.c0000644000175700017570000004707713001406607012347 00000000000000/* -*-c-*- */ /* Fvwm colorset technology is Copyright (C) 1999 Joey Shutup * http://www.streetmap.co.uk/streetmap.dll?Postcode2Map?BS24+9TZ * You may use this code for any purpose, as long as the original copyright * and this notice remains in the source code and all documentation */ /* 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 #include #include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/Colorset.h" #include "libs/PictureBase.h" #include "libs/Graphics.h" #include "libs/Grab.h" #include "libs/PictureGraphics.h" #include "libs/XError.h" /* globals */ colorset_t *Colorset = NULL; int nColorsets = 0; /* stretch the src rectangle to the dest ractangle keeping its aspect so that * it fills the destination completely. */ static int get_aspect_dimensions( int *ret_w, int *ret_h, int dest_w, int dest_h, int src_w, int src_h) { double ax; double ay; ax = (double)dest_w / (double)src_w; ay = (double)dest_h / (double)src_h; if (ax >= ay) { /* fit in x direction */ *ret_w = dest_w; *ret_h = (src_h * dest_w) / src_w; return 0; } else { /* fit in y direction */ *ret_w = (src_w * dest_h) / src_h; *ret_h = dest_h; return 1; } } /* * AllocColorset() grows the size of the Colorset array to include set n * colorset_t *Colorset will be altered * returns the address of the member */ void AllocColorset(int n) { /* do nothing if it already exists */ if (n < nColorsets) { return; } /* increment n to get the required array size, get a new array */ Colorset = (colorset_t *)saferealloc( (char *)Colorset, ++n * sizeof(colorset_t)); /* zero out colorset 0 it's always defined so will be filled in during module startup */ if (n == 0) { memset( &Colorset[nColorsets], 0, (n - nColorsets) * sizeof(colorset_t)); } else { /* copy colorset 0 into new members so that if undefined ones * are referenced at least they don't give black on black */ for ( ; nColorsets < n; nColorsets++) { memcpy( &Colorset[nColorsets], Colorset, sizeof(colorset_t)); } } nColorsets = n; return; } /* * DumpColorset() returns a char * to the colorset contents in printable form */ static char csetbuf[256]; char *DumpColorset(int n, colorset_t *cs) { sprintf(csetbuf, "Colorset " "%x %lx %lx %lx %lx %lx %lx %lx %lx %lx " "%x %x %x %x %x %x %x %x %x %x %x", n, cs->fg, cs->bg, cs->hilite, cs->shadow, cs->fgsh, cs->tint, cs->icon_tint, cs->pixmap, cs->shape_mask, cs->fg_alpha_percent, cs->width, cs->height, cs->pixmap_type, cs->shape_width, cs->shape_height, cs->shape_type, cs->tint_percent, cs->do_dither_icon, cs->icon_tint_percent, cs->icon_alpha_percent); return csetbuf; } /* * LoadColorset() takes a strings and stuffs it into the array */ int LoadColorset(char *line) { colorset_t *cs; unsigned int n, chars; Pixel fg, bg, hilite, shadow, fgsh, tint, icon_tint; Pixmap pixmap; Pixmap shape_mask; unsigned int fg_alpha_percent, width, height, pixmap_type; unsigned int shape_width, shape_height, shape_type; unsigned int tint_percent, do_dither_icon, icon_tint_percent; unsigned int icon_alpha_percent; if (line == NULL) { return -1; } if (sscanf(line, "%x%n", &n, &chars) < 1) { return -1; } line += chars; /* migo: if you modify this sscanf or other colorset definitions, * please update perllib/FVWM/Tracker/Colorsets.pm too */ if (sscanf(line, "%lx %lx %lx %lx %lx %lx %lx %lx %lx " "%x %x %x %x %x %x %x %x %x %x %x", &fg, &bg, &hilite, &shadow, &fgsh, &tint, &icon_tint, &pixmap, &shape_mask, &fg_alpha_percent, &width, &height, &pixmap_type, &shape_width, &shape_height, &shape_type, &tint_percent, &do_dither_icon, &icon_tint_percent, &icon_alpha_percent) != 20) return -1; AllocColorset(n); cs = &Colorset[n]; cs->fg = fg; cs->bg = bg; cs->hilite = hilite; cs->shadow = shadow; cs->fgsh = fgsh; cs->tint = tint; cs->icon_tint = icon_tint; cs->pixmap = pixmap; cs->shape_mask = shape_mask; cs->fg_alpha_percent = fg_alpha_percent; cs->width = width; cs->height = height; cs->pixmap_type = pixmap_type; cs->shape_width = shape_width; cs->shape_height = shape_height; cs->shape_type = shape_type; cs->tint_percent = tint_percent; cs->do_dither_icon = do_dither_icon; cs->icon_tint_percent = icon_tint_percent; cs->icon_alpha_percent = icon_alpha_percent; return n; } /* scrolls a pixmap by x_off/y_off pixels, wrapping around at the edges. */ Pixmap ScrollPixmap( Display *dpy, Pixmap p, GC gc, int x_off, int y_off, int width, int height, unsigned int depth) { GC tgc; XGCValues xgcv; Pixmap p2; if (p == None || p == ParentRelative || (x_off == 0 && y_off == 0)) { return p; } tgc = fvwmlib_XCreateGC(dpy, p, 0, &xgcv); if (tgc == None) { return p; } XCopyGC(dpy, gc, GCFunction | GCPlaneMask| GCSubwindowMode | GCClipXOrigin | GCClipYOrigin | GCClipMask, tgc); xgcv.tile = p; xgcv.ts_x_origin = x_off; xgcv.ts_y_origin = y_off; xgcv.fill_style = FillTiled; XChangeGC( dpy, tgc, GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, &xgcv); p2 = XCreatePixmap(dpy, p, width, height, depth); if (p2 == None) { return p; } XFillRectangle(dpy, p2, tgc, 0, 0, width, height); XFreeGC(dpy, tgc); return p2; } /* sets a window background from a colorset * if width or height are zero the window size is queried */ void SetWindowBackgroundWithOffset( Display *dpy, Window win, int x_off, int y_off, unsigned int width, unsigned int height, colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area) { Pixmap pixmap = None; Pixmap mask = None; union { XID junk; unsigned int ui_junk; int i_junk; } XID_int; if (0 == width || 0 == height) { if (!XGetGeometry( dpy, win, &XID_int.junk, &XID_int.i_junk, &XID_int.i_junk, (unsigned int *)&width, (unsigned int *)&height, &XID_int.ui_junk, &XID_int.ui_junk)) { return; } } if (FHaveShapeExtension && colorset->shape_mask) { mask = CreateBackgroundPixmap( dpy, None, width, height, colorset, 1, None, True); if (mask != None) { FShapeCombineMask( dpy, win, FShapeBounding, 0, 0, mask, FShapeSet); XFreePixmap(dpy, mask); } } if (!colorset->pixmap) { /* use the bg pixel */ XSetWindowBackground(dpy, win, colorset->bg); if (clear_area) { XClearArea(dpy, win, 0, 0, width, height, True); } } else { pixmap = CreateOffsetBackgroundPixmap( dpy, win, x_off, y_off, width, height, colorset, depth, gc, False); if (pixmap) { XSetWindowBackgroundPixmap(dpy, win, pixmap); if (clear_area) { XClearArea(dpy, win, 0, 0, width, height, True); } if (pixmap != ParentRelative) { XFreePixmap(dpy, pixmap); } } } return; } Bool UpdateBackgroundTransparency( Display *dpy, Window win, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area) { if (!CSETS_IS_TRANSPARENT(colorset)) { return False; } else if (!CSETS_IS_TRANSPARENT_PR_PURE(colorset)) { SetWindowBackgroundWithOffset( dpy, win, 0, 0, width, height, colorset, depth, gc, True); } else { XClearArea(dpy, win, 0,0,0,0, clear_area); } return True; } void SetWindowBackground( Display *dpy, Window win, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool clear_area) { SetWindowBackgroundWithOffset( dpy, win, 0, 0, width, height, colorset, depth, gc, clear_area); return; } void GetWindowBackgroundPixmapSize( colorset_t *cs_t, int width, int height, int *w, int *h) { if (cs_t->pixmap == None) { *w = *h = 1; } else { *w = cs_t->width; *h = cs_t->height; switch (cs_t->pixmap_type) { case PIXMAP_STRETCH_ASPECT: get_aspect_dimensions( w, h, width, height, cs_t->width, cs_t->height); break; case PIXMAP_STRETCH_X: *w = width; break; case PIXMAP_STRETCH_Y: *h = height; break; default: break; } } } static int is_bad_gc = 0; static int BadGCErrorHandler(Display *dpy, XErrorEvent *error) { if (error->error_code == BadGC) { is_bad_gc = 1; return 0; } else { int rc; /* delegate error to original handler */ rc = ferror_call_next_error_handler(dpy, error); return rc; } } /* create a pixmap suitable for plonking on the background of a part of a * window */ Pixmap CreateOffsetBackgroundPixmap( Display *dpy, Window win, int x, int y, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool is_shape_mask) { Pixmap pixmap = None; Pixmap cs_pixmap = None; XGCValues xgcv; static GC shape_gc = None; GC fill_gc = None; /* not static as dpy may change (FvwmBacker) */ int cs_width; int cs_height; Bool cs_keep_aspect; Bool cs_stretch_x; Bool cs_stretch_y; if (colorset->pixmap == ParentRelative && !is_shape_mask && colorset->tint_percent > 0) { FvwmRenderAttributes fra; fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT; fra.tint = colorset->tint; fra.tint_percent = colorset->tint_percent; MyXGrabServer(dpy); pixmap = PGraphicsCreateTransparency( dpy, win, &fra, gc, x, y, width, height, True); MyXUngrabServer(dpy); if (pixmap == None) { return ParentRelative; } return pixmap; } else if (colorset->pixmap == ParentRelative && !is_shape_mask) { return ParentRelative; } else if (CSETS_IS_TRANSPARENT_ROOT(colorset) && colorset->pixmap && !is_shape_mask) { int sx,sy; int h,w; XID dummy; cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; if (CSETS_IS_TRANSPARENT_ROOT_PURE(colorset)) { /* check if it is still here */ union { XID junk; unsigned int ui_junk; int i_junk; } XID_int; /* a priori we should grab the server, but this * cause PositiveWrite error when you move a * window with a transparent title bar */ if (!XGetGeometry( dpy, colorset->pixmap, &XID_int.junk, &XID_int.i_junk, &XID_int.i_junk, (unsigned int *)&w, (unsigned int *)&h, &XID_int.ui_junk, &XID_int.ui_junk) || w != cs_width || h != cs_height) { return None; } } XTranslateCoordinates( dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy, &dummy); pixmap = XCreatePixmap(dpy, win, width, height, Pdepth); if (!pixmap) { return None; } /* make sx and sy positif */ while (sx < 0) { sx = sx + cs_width; } while (sy < 0) { sy = sy + cs_height; } /* make sx and sy in (0,0,cs_width,cs_height) */ while (sx >= cs_width) { sx = sx - cs_width; } while (sy >= cs_height) { sy = sy - cs_height; } xgcv.fill_style = FillTiled; xgcv.tile = cs_pixmap; xgcv.ts_x_origin = cs_width-sx; xgcv.ts_y_origin = cs_height-sy; fill_gc = fvwmlib_XCreateGC( dpy, win, GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, &xgcv); if (fill_gc == None) { XFreePixmap(dpy, pixmap); return None; } XSync(dpy, False); is_bad_gc = 0; ferror_set_temp_error_handler(BadGCErrorHandler); XFillRectangle(dpy, pixmap, fill_gc, 0, 0, width, height); if ( is_bad_gc == 0 && CSETS_IS_TRANSPARENT_ROOT_PURE(colorset) && colorset->tint_percent > 0) { FvwmRenderAttributes fra; fra.mask = FRAM_HAVE_TINT; fra.tint = colorset->tint; fra.tint_percent = colorset->tint_percent; PGraphicsRenderPixmaps( dpy, win, pixmap, None, None, Pdepth, &fra, pixmap, fill_gc, None, None, 0, 0, width, height, 0, 0, width, height, False); } XSync(dpy, False); ferror_reset_temp_error_handler(); if (is_bad_gc == 1) { is_bad_gc = 0; XFreePixmap(dpy, pixmap); pixmap = None; } XFreeGC(dpy,fill_gc); return pixmap; } if (!is_shape_mask) { cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; cs_keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); cs_stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); cs_stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); } else { /* In spite of the name, win contains the pixmap */ cs_pixmap = colorset->shape_mask; win = colorset->shape_mask; if (shape_gc == None) { xgcv.foreground = 1; xgcv.background = 0; /* create a gc for 1 bit depth */ shape_gc = fvwmlib_XCreateGC( dpy, win, GCForeground|GCBackground, &xgcv); } gc = shape_gc; cs_width = colorset->shape_width; cs_height = colorset->shape_height; cs_keep_aspect = (colorset->shape_type == SHAPE_STRETCH_ASPECT); cs_stretch_x = !(colorset->shape_type == SHAPE_TILED); cs_stretch_y = !(colorset->shape_type == SHAPE_TILED); } if (cs_pixmap == None) { xgcv.foreground = colorset->bg; fill_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv); /* create a solid pixmap - not very useful most of the time */ pixmap = XCreatePixmap(dpy, win, 1, 1, depth); XFillRectangle(dpy, pixmap, fill_gc, 0, 0, 1, 1); XFreeGC(dpy,fill_gc); } else if (cs_keep_aspect) { Bool trim_side; int big_width, big_height; Pixmap big_pixmap; int x, y; /* make a pixmap big enough to cover the destination but with * the aspect ratio of the cs_pixmap */ trim_side = get_aspect_dimensions( &big_width, &big_height, width, height, cs_width, cs_height); big_pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, big_width, big_height, gc); /* work out where to trim */ x = trim_side ? (big_width - width) / 2 : 0; y = trim_side ? 0 : (big_height - height) / 2; pixmap = XCreatePixmap(dpy, cs_pixmap, width, height, depth); if (pixmap && big_pixmap) { XCopyArea( dpy, big_pixmap, pixmap, gc, x, y, width, height, 0, 0); } if (big_pixmap) { XFreePixmap(dpy, big_pixmap); } } else if (!cs_stretch_x && !cs_stretch_y) { /* it's a tiled pixmap, create an unstretched one */ if (!is_shape_mask) { pixmap = XCreatePixmap( dpy, cs_pixmap, cs_width, cs_height, depth); if (pixmap) { XCopyArea( dpy, cs_pixmap, pixmap, gc, 0, 0, cs_width, cs_height, 0, 0); } } else { /* can't tile masks, create a tiled version of the * mask */ pixmap = CreateTiledPixmap( dpy, cs_pixmap, cs_width, cs_height, width, height, 1, gc); } } else if (!cs_stretch_x) { /* it's an HGradient */ pixmap = CreateStretchYPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, height, gc); } else if (!cs_stretch_y) { /* it's a VGradient */ pixmap = CreateStretchXPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, width, gc); } else { /* It's a full window pixmap */ pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, width, height, gc); } if (x != 0 || y != 0) { Pixmap p2; p2 = ScrollPixmap( dpy, pixmap, gc, x, y, width, height, depth); if (p2 != None && p2 != ParentRelative && p2 != pixmap) { XFreePixmap(dpy, pixmap); pixmap = p2; } } return pixmap; } /* create a pixmap suitable for plonking on the background of a window */ Pixmap CreateBackgroundPixmap(Display *dpy, Window win, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool is_shape_mask) { return CreateOffsetBackgroundPixmap( dpy, win, 0, 0, width, height, colorset, depth, gc, is_shape_mask); } /* Draws a colorset background into the specified rectangle in the target * drawable. */ void SetRectangleBackground( Display *dpy, Window win, int x, int y, int width, int height, colorset_t *colorset, unsigned int depth, GC gc) { SetClippedRectangleBackground( dpy, win, x, y, width, height, NULL, colorset, depth, gc); return; } /* Draws a colorset background into the specified rectangle in the target * drawable. */ void SetClippedRectangleBackground( Display *dpy, Window win, int x, int y, int width, int height, XRectangle *clip, colorset_t *colorset, unsigned int depth, GC gc) { GC draw_gc; Pixmap pixmap2; Pixmap pixmap = None; static int last_depth = -1; static GC last_gc = None; XGCValues xgcv; Pixmap clipmask = None; GC clip_gc = None; Bool keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); Bool stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); Bool stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); int dest_x, dest_y, dest_w, dest_h; if (clip) { dest_x = clip->x; dest_y = clip->y; dest_w = clip->width; dest_h = clip->height; } else { dest_x = x; dest_y = y; dest_w = width; dest_h = height; } if (CSETS_IS_TRANSPARENT_PR_TINT(colorset)) { XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False); PGraphicsTintRectangle( dpy, win, colorset->tint, colorset->tint_percent, win, True, gc, None, None, dest_x, dest_y, dest_w, dest_h); return; } if (CSETS_IS_TRANSPARENT_PR_PURE(colorset)) { XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False); /* don't do anything */ return; } if (CSETS_IS_TRANSPARENT_ROOT(colorset)) { /* FIXME: optimize this ! */ x = y = 0; width = width + dest_x; height = height + dest_y; } /* minimize gc creation by remembering the last requested depth */ if (last_gc != None && depth != last_depth) { XFreeGC(dpy, last_gc); last_gc = None; } if (last_gc == None) { last_gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); } draw_gc = last_gc; last_depth = depth; if (FHaveShapeExtension && colorset->shape_mask != None) { clipmask = CreateBackgroundPixmap( dpy, 0, width, height, colorset, 1, None, True); if (clipmask) { /* create a GC for clipping */ xgcv.clip_x_origin = x; xgcv.clip_y_origin = y; xgcv.clip_mask = clipmask; clip_gc = fvwmlib_XCreateGC( dpy, win, GCClipXOrigin | GCClipYOrigin | GCClipMask, &xgcv); draw_gc = clip_gc; } } if (!colorset->pixmap) { /* use the bg pixel */ XSetForeground(dpy, draw_gc, colorset->bg); XFillRectangle( dpy, win, draw_gc, dest_x, dest_y, dest_w, dest_h); } else { pixmap = CreateBackgroundPixmap( dpy, win, width, height, colorset, depth, gc, False); if (keep_aspect) { /* nothing to do */ } if (stretch_x || stretch_y) { if (!stretch_x && colorset->width != width) { pixmap2 = CreateStretchXPixmap( dpy, pixmap, colorset->width, height, depth, width, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } if (!stretch_y && colorset->height != height) { pixmap2 = CreateStretchYPixmap( dpy, pixmap, width, colorset->height, depth, height, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } } else { pixmap2 = CreateTiledPixmap( dpy, pixmap, colorset->width, colorset->height, width, height, depth, gc); XFreePixmap(dpy, pixmap); pixmap = pixmap2; } if (pixmap) { /* Copy the pixmap into the rectangle. */ XCopyArea( dpy, pixmap, win, draw_gc, dest_x - x, dest_y - y, dest_w, dest_h, dest_x, dest_y); XFreePixmap(dpy, pixmap); } } if (FHaveShapeExtension) { if (clipmask != None) { XFreePixmap(dpy, clipmask); } if (clip_gc != None) { XFreeGC(dpy, clip_gc); } } return; } fvwm-2.6.7/libs/BidiJoin.c0000644000175700017570000002150613001406607012231 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Nadim Shaikli (arabeyes.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 */ /* * FBidiJoin.c * * A place holder for when fribidi finally implements character * shaping/joining. This shaping/joining is a must for a variety of * Bidi'ed languages such as Arabic, Farsi, as well as all the Syriacs * (Urdu, Sindhi, Pashto, Kurdish, Baluchi, Kashmiri, Kazakh, Berber, * Uighur, Kirghiz, etc). */ #include "config.h" #if HAVE_BIDI #include "fvwmlib.h" #include "BidiJoin.h" /* ---------------------------- included header files ---------------------- */ #include /* ---------------------------- local types -------------------------------- */ typedef struct char_shaped { FriBidiChar base; /* The various Arabic shaped permutations */ FriBidiChar isolated; FriBidiChar initial; FriBidiChar medial; FriBidiChar final; } char_shaped_t; typedef struct char_shaped_comb { /* The Arabic exceptions - 2chars ==> 1char */ FriBidiChar first; FriBidiChar second; FriBidiChar comb_isolated; FriBidiChar comb_joined; } char_shaped_comb_t; /* ---------------------------- static variables --------------------------- */ static const char_shaped_t shaped_table[] = { /* base s i m f */ { 0x0621, 0xFE80, 0x0000, 0x0000, 0x0000, }, /* HAMZA */ { 0x0622, 0xFE81, 0x0000, 0x0000, 0xFE82, }, /* ALEF_MADDA */ { 0x0623, 0xFE83, 0x0000, 0x0000, 0xFE84, }, /* ALEF_HAMZA_ABOVE */ { 0x0624, 0xFE85, 0x0000, 0x0000, 0xFE86, }, /* WAW_HAMZA */ { 0x0625, 0xFE87, 0x0000, 0x0000, 0xFE88, }, /* ALEF_HAMZA_BELOW */ { 0x0626, 0xFE89, 0xFE8B, 0xFE8C, 0xFE8A, }, /* YEH_HAMZA */ { 0x0627, 0xFE8D, 0x0000, 0x0000, 0xFE8E, }, /* ALEF */ { 0x0628, 0xFE8F, 0xFE91, 0xFE92, 0xFE90, }, /* BEH */ { 0x0629, 0xFE93, 0x0000, 0x0000, 0xFE94, }, /* TEH_MARBUTA */ { 0x062A, 0xFE95, 0xFE97, 0xFE98, 0xFE96, }, /* TEH */ { 0x062B, 0xFE99, 0xFE9B, 0xFE9C, 0xFE9A, }, /* THEH */ { 0x062C, 0xFE9D, 0xFE9F, 0xFEA0, 0xFE9E, }, /* JEEM */ { 0x062D, 0xFEA1, 0xFEA3, 0xFEA4, 0xFEA2, }, /* HAH */ { 0x062E, 0xFEA5, 0xFEA7, 0xFEA8, 0xFEA6, }, /* KHAH */ { 0x062F, 0xFEA9, 0x0000, 0x0000, 0xFEAA, }, /* DAL */ { 0x0630, 0xFEAB, 0x0000, 0x0000, 0xFEAC, }, /* THAL */ { 0x0631, 0xFEAD, 0x0000, 0x0000, 0xFEAE, }, /* REH */ { 0x0632, 0xFEAF, 0x0000, 0x0000, 0xFEB0, }, /* ZAIN */ { 0x0633, 0xFEB1, 0xFEB3, 0xFEB4, 0xFEB2, }, /* SEEN */ { 0x0634, 0xFEB5, 0xFEB7, 0xFEB8, 0xFEB6, }, /* SHEEN */ { 0x0635, 0xFEB9, 0xFEBB, 0xFEBC, 0xFEBA, }, /* SAD */ { 0x0636, 0xFEBD, 0xFEBF, 0xFEC0, 0xFEBE, }, /* DAD */ { 0x0637, 0xFEC1, 0xFEC3, 0xFEC4, 0xFEC2, }, /* TAH */ { 0x0638, 0xFEC5, 0xFEC7, 0xFEC8, 0xFEC6, }, /* ZAH */ { 0x0639, 0xFEC9, 0xFECB, 0xFECC, 0xFECA, }, /* AIN */ { 0x063A, 0xFECD, 0xFECF, 0xFED0, 0xFECE, }, /* GHAIN */ { 0x0640, 0x0640, 0x0640, 0x0640, 0x0640, }, /* TATWEEL */ { 0x0641, 0xFED1, 0xFED3, 0xFED4, 0xFED2, }, /* FEH */ { 0x0642, 0xFED5, 0xFED7, 0xFED8, 0xFED6, }, /* QAF */ { 0x0643, 0xFED9, 0xFEDB, 0xFEDC, 0xFEDA, }, /* KAF */ { 0x0644, 0xFEDD, 0xFEDF, 0xFEE0, 0xFEDE, }, /* LAM */ { 0x0645, 0xFEE1, 0xFEE3, 0xFEE4, 0xFEE2, }, /* MEEM */ { 0x0646, 0xFEE5, 0xFEE7, 0xFEE8, 0xFEE6, }, /* NOON */ { 0x0647, 0xFEE9, 0xFEEB, 0xFEEC, 0xFEEA, }, /* HEH */ { 0x0648, 0xFEED, 0x0000, 0x0000, 0xFEEE, }, /* WAW */ { 0x0649, 0xFEEF, 0xFBE8, 0xFBE9, 0xFEF0, }, /* ALEF_MAKSURA */ { 0x064A, 0xFEF1, 0xFEF3, 0xFEF4, 0xFEF2, }, /* YEH */ { 0x0671, 0xFB50, 0x0000, 0x0000, 0xFB51, }, { 0x0679, 0xFB66, 0xFB68, 0xFB69, 0xFB67, }, { 0x067A, 0xFB5E, 0xFB60, 0xFB61, 0xFB5F, }, { 0x067B, 0xFB52, 0xFB54, 0xFB55, 0xFB53, }, { 0x067E, 0xFB56, 0xFB58, 0xFB59, 0xFB57, }, { 0x067F, 0xFB62, 0xFB64, 0xFB65, 0xFB63, }, { 0x0680, 0xFB5A, 0xFB5C, 0xFB5D, 0xFB5B, }, { 0x0683, 0xFB76, 0xFB78, 0xFB79, 0xFB77, }, { 0x0684, 0xFB72, 0xFB74, 0xFB75, 0xFB73, }, { 0x0686, 0xFB7A, 0xFB7C, 0xFB7D, 0xFB7B, }, { 0x0687, 0xFB7E, 0xFB80, 0xFB81, 0xFB7F, }, { 0x0688, 0xFB88, 0x0000, 0x0000, 0xFB89, }, { 0x068C, 0xFB84, 0x0000, 0x0000, 0xFB85, }, { 0x068D, 0xFB82, 0x0000, 0x0000, 0xFB83, }, { 0x068E, 0xFB86, 0x0000, 0x0000, 0xFB87, }, { 0x0691, 0xFB8C, 0x0000, 0x0000, 0xFB8D, }, { 0x0698, 0xFB8A, 0x0000, 0x0000, 0xFB8B, }, { 0x06A4, 0xFB6A, 0xFB6C, 0xFB6D, 0xFB6B, }, { 0x06A6, 0xFB6E, 0xFB70, 0xFB71, 0xFB6F, }, { 0x06A9, 0xFB8E, 0xFB90, 0xFB91, 0xFB8F, }, { 0x06AD, 0xFBD3, 0xFBD5, 0xFBD6, 0xFBD4, }, { 0x06AF, 0xFB92, 0xFB94, 0xFB95, 0xFB93, }, { 0x06B1, 0xFB9A, 0xFB9C, 0xFB9D, 0xFB9B, }, { 0x06B3, 0xFB96, 0xFB98, 0xFB99, 0xFB97, }, { 0x06BB, 0xFBA0, 0xFBA2, 0xFBA3, 0xFBA1, }, { 0x06BE, 0xFBAA, 0xFBAC, 0xFBAD, 0xFBAB, }, { 0x06C0, 0xFBA4, 0x0000, 0x0000, 0xFBA5, }, { 0x06C1, 0xFBA6, 0xFBA8, 0xFBA9, 0xFBA7, }, { 0x06C5, 0xFBE0, 0x0000, 0x0000, 0xFBE1, }, { 0x06C6, 0xFBD9, 0x0000, 0x0000, 0xFBDA, }, { 0x06C7, 0xFBD7, 0x0000, 0x0000, 0xFBD8, }, { 0x06C8, 0xFBDB, 0x0000, 0x0000, 0xFBDC, }, { 0x06C9, 0xFBE2, 0x0000, 0x0000, 0xFBE3, }, { 0x06CB, 0xFBDE, 0x0000, 0x0000, 0xFBDF, }, { 0x06CC, 0xFBFC, 0xFBFE, 0xFBFF, 0xFBFD, }, { 0x06D0, 0xFBE4, 0xFBE6, 0xFBE7, 0xFBE5, }, { 0x06D2, 0xFBAE, 0x0000, 0x0000, 0xFBAF, }, { 0x06D3, 0xFBB0, 0x0000, 0x0000, 0xFBB1, }, /* special treatment for ligatures from combining phase */ { 0xFEF5, 0xFEF5, 0x0000, 0x0000, 0xFEF6, }, /* LAM_ALEF_MADDA */ { 0xFEF7, 0xFEF7, 0x0000, 0x0000, 0xFEF8, }, /* LAM_ALEF_HAMZA_ABOVE */ { 0xFEF9, 0xFEF9, 0x0000, 0x0000, 0xFEFA, }, /* LAM_ALEF_HAMZA_BELOW */ { 0xFEFB, 0xFEFB, 0x0000, 0x0000, 0xFEFC, }, /* LAM_ALEF */ }; static const char_shaped_comb_t shaped_comb_table[] = { { 0x0644, 0x0622, 0xFEF5, 0xFEF6, }, /* LAM_ALEF_MADDA */ { 0x0644, 0x0623, 0xFEF7, 0xFEF8, }, /* LAM_ALEF_HAMZA_ABOVE */ { 0x0644, 0x0625, 0xFEF9, 0xFEFA, }, /* LAM_ALEF_HAMZA_BELOW */ { 0x0644, 0x0627, 0xFEFB, 0xFEFC, }, /* LAM_ALEF */ }; /* -------------------------- local functions ------------------------------ */ static const char_shaped_t * get_shaped_entry(FriBidiChar ch) { int count; int table_size; table_size = sizeof(shaped_table) / sizeof(shaped_table[0]); for (count = 0; count < table_size; count++) { if (shaped_table[count].base == ch) { return &shaped_table[count]; } } return NULL; } /* ------------------------- interface functions --------------------------- */ int shape_n_join( FriBidiChar *str_visual, int str_len) { int i; /* counter of the input string */ int len; /* counter and the final length of the shaped string */ FriBidiChar *orig_str; const char_shaped_t **list; const char_shaped_t *prev; const char_shaped_t *curr; const char_shaped_t *next; list = (const char_shaped_t **)safemalloc( (str_len + 2) * sizeof(char_shaped_t *)); orig_str = (FriBidiChar *)safemalloc( (str_len + 1) * sizeof(FriBidiChar)); /* head is NULL */ *list = NULL; list++; /* Populate with existent shaped characters */ for (i = 0; i < str_len; i++) { list[i] = get_shaped_entry(str_visual[i]); } /* tail is NULL */ list[i] = NULL; /* Store-off non-shaped characters; start with a clean slate */ memcpy(orig_str, str_visual, (str_len * sizeof(str_visual[0]))); memset(str_visual, 0, (str_len * sizeof(str_visual[0]))); /* Traverse the line & build new content */ for (i = 0, len = 0; i <= str_len - 1; i++, len++) { /* Get previous, current, and next characters */ prev = list[i + 1]; curr = list[i]; next = list[i - 1]; /* Process current mapped characters */ if (curr) { if (next) { if (prev) { if (!prev->initial || !prev->medial) { str_visual[len] = curr->initial? curr->initial: curr->isolated; } else { str_visual[len] = curr->medial? curr->medial: curr->final; } } else { str_visual[len] = curr->initial? curr->initial: curr->isolated; } } else { if (prev) { if (!prev->initial || !prev->medial) { str_visual[len] = curr->isolated; } else { str_visual[len] = curr->final? curr->final: curr->isolated; } } else { str_visual[len] = curr->isolated; } } } else { str_visual[len] = orig_str[i]; } } free(list-1); free(orig_str); /* return the length of the new string */ return len; } #endif /* HAVE_BIDI */ fvwm-2.6.7/libs/safemalloc.h0000644000175700017570000000044313001406607012652 00000000000000/* -*-c-*- */ /* * * Procedure: * safe?alloc - mallocs/callocs specified space or exits if there's a * problem * */ char *safemalloc(int length); char *safecalloc(int num, int length); char *saferealloc(char *ptr, int length); char *safestrdup(const char *s); fvwm-2.6.7/libs/Fft.h0000644000175700017570000004615712773467232011317 00000000000000/* -*-c-*- */ #ifndef FFT_H #define FFT_H /* * Note: This "warper" is far from being complete! if you need something * in Xft or Xft + fontconfig (Fc for short) (aka Xft2) not already defined * you must add the corresponding Fft* functions/types (2 or 3 times). * */ /* ---------------------------- included header files ---------------------- */ /* no compat to avoid problems in the future */ #define _XFT_NO_COMPAT_ 1 #ifdef HAVE_XFT #define Picture XRenderPicture #include #undef Picture #endif #include "FRender.h" /* ---------------------------- global definitions ------------------------- */ #ifdef HAVE_XFT #define FftSupport 1 #ifdef HAVE_XFT_UTF8 #define FftUtf8Support 1 #else #define FftUtf8Support 0 #endif #ifdef HAVE_XFT2 #define FftSupportUseXft2 1 #else #define FftSupportUseXft2 0 #endif #else #define FftSupport 0 #define FftUtf8Support 0 #define FftSupportUseXft2 0 #endif /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ #if FftSupport /* Fc (fontconfig) stuff */ #if FftSupportUseXft2 typedef FcChar8 FftChar8; typedef FcChar16 FftChar16; typedef FcChar32 FftChar32; typedef FcBool FftBool; typedef FcType FftType; typedef FcMatrix FftMatrix; typedef FcValue FftValue; typedef FcPattern FftPattern; typedef FcFontSet FftFontSet; typedef FcObjectSet FftObjectSet; #if 1 /* FftResult must be FcResult for gcc 3.4 not to warn of incompatible * pointer type */ typedef FcResult FftResult; #define FftResultMatch FcResultMatch #define FftResultNoMatch FcResultNoMatch #define FftResultTypeMismatch FcResultTypeMismatch #define FftFftResultNoId FcResultNoId #else typedef enum _FftResult { FftResultMatch = FcResultMatch, FftResultNoMatch = FcResultNoMatch, FftResultTypeMismatch = FcResultTypeMismatch, FftFftResultNoId = FcResultNoId } FftResult; #endif /* XftValue and are different in Xft+Fc and Xft 1 */ typedef struct _Xft1Value { FftType type; union { char *s; int i; Bool b; double d; FftMatrix *m; } u; } Xft1Value; typedef Xft1Value Fft1Value; /* no value list in Xft+Fc */ typedef struct _XftValueList { struct _XftValueList *next; Fft1Value value; } XftValueList; typedef XftValueList FftValueList; /* no XftPatternElt in Xft+Fc */ typedef struct { const char *object; FftValueList *values; } XftPatternElt; typedef XftPatternElt FftPatternElt; /* XftPattern and FcPattern are different */ typedef struct _Xft1Pattern { int num; int size; FftPatternElt *elts; } Fft1Pattern; #else /* !FftSupportUseXft2 */ typedef XftChar8 FftChar8; typedef XftChar16 FftChar16; typedef XftChar32 FftChar32; typedef XftType FftType; typedef XftMatrix FftMatrix; typedef XftPatternElt FftPatternElt; typedef XftFontSet FftFontSet; typedef XftObjectSet FftObjectSet; typedef XftValue FftValue; typedef XftPattern FftPattern; typedef XftValue Fft1Value; typedef XftPattern Fft1Pattern; typedef enum _FftResult { FftResultMatch = XftResultMatch, FftResultNoMatch = XftResultNoMatch, FftResultTypeMismatch = XftResultTypeMismatch, FftFftResultNoId = XftResultNoId } FftResult; #endif /* FftSupportUseXft2 */ /* Xft stuff (common) */ typedef XftDraw FftDraw; typedef XftFont FftFont; typedef XftColor FftColor; #if FftSupportUseXft2 /* XftFont are != in Xft+Fc and Xft */ typedef struct _Fft1Font { int ascent; int descent; int height; int max_advance_width; Bool core; Fft1Pattern *pattern; union { struct { XFontStruct *font; } core; struct { void *font; } ft; } u; } Fft1Font; #else typedef XftFont Fft1Font; #endif #else typedef unsigned char FftChar8; typedef unsigned short FftChar16; typedef unsigned int FftChar32; typedef int FftType; typedef struct { double xx, xy, yx, yy; } FftMatrix; typedef enum _FftResult { FftResultMatch = 0, FftResultNoMatch = 1, FftResultTypeMismatch = 2, FftFftResultNoId = 3 } FftResult; typedef struct { FftType type; union { char *s; int i; Bool b; double d; } u; } XftValue; typedef XftValue FftValue; typedef struct _XftValueList { struct _XftValueList *next; FftValue value; } XftValueList; typedef XftValueList FftValueList; typedef struct { const char *object; FftValueList *values; } XftPatternElt; typedef XftPatternElt FftPatternElt; typedef struct { int num; int size; FftPatternElt *elts; } XftPattern; typedef XftPattern FftPattern; typedef void FftFontSet; typedef void FftFontVoid; typedef void FftDraw; typedef struct { int ascent; int descent; int height; int max_advance_width; Bool core; FftPattern *pattern; union { struct { XFontStruct *font; } core; struct { void *font; } ft; } u; } XftFont; typedef XftFont FftFont; typedef struct { unsigned long pixel; FRenderColor color; } XftColor; typedef XftColor FftColor; typedef void FftObjectSet; /* XftValue are different in Xft+Fc and Xft 1 */ typedef struct _Xft1Value { FftType type; union { char *s; int i; Bool b; double d; FftMatrix *m; } u; } Xft1Value; typedef Xft1Value Fft1Value; /* XftPattern and XftFont are different in Xft+Fc and Xft 1 */ typedef struct _Xft1Pattern { int num; int size; FftPatternElt *elts; } Fft1Pattern; typedef struct _Fft1Font { int ascent; int descent; int height; int max_advance_width; Bool core; Fft1Pattern *pattern; union { struct { XFontStruct *font; } core; struct { void *font; } ft; } u; } Fft1Font; #endif /* * Fvwm Xft font structure */ typedef struct { FftFont *fftfont; FftFont *fftfont_rotated_90; FftFont *fftfont_rotated_180; FftFont *fftfont_rotated_270; char *encoding; char *str_encoding; } FftFontType; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ void FftPDumyFunc(void); /* ---------------------------- global definitions ------------------------- */ #if FftSupport /* Fc stuff */ #if FftSupportUseXft2 #define FFT_FAMILY FC_FAMILY #define FFT_STYLE FC_STYLE #define FFT_SLANT FC_SLANT #define FFT_WEIGHT FC_WEIGHT #define FFT_SIZE FC_SIZE #define FFT_PIXEL_SIZE FC_PIXEL_SIZE #define FFT_SPACING FC_SPACING #define FFT_FOUNDRY FC_FOUNDRY #define FFT_CORE FC_CORE #define FFT_ANTIALIAS FC_ANTIALIAS #define FFT_XLFD FC_XLFD #define FFT_FILE FC_FILE #define FFT_INDEX FC_INDEX #define FFT_RASTERIZER FC_RASTERIZER #define FFT_OUTLINE FC_OUTLINE #define FFT_SCALABLE FC_SCALABLE #define FFT_RGBA FC_RGBA #define FFT_SCALE FC_SCALE #define FFT_RENDER FC_RENDER #define FFT_CHAR_WIDTH FC_CHAR_WIDTH #define FFT_CHAR_HEIGHT FC_CHAR_HEIGHT #define FFT_MATRIX FC_MATRIX #define FFT_WEIGHT_LIGHT FC_WEIGHT_LIGHT #define FFT_WEIGHT_MEDIUM FC_WEIGHT_MEDIUM #define FFT_WEIGHT_DEMIBOLD FC_WEIGHT_DEMIBOLD #define FFT_WEIGHT_BOLD FC_WEIGHT_BOLD #define FFT_WEIGHT_BLACK FC_WEIGHT_BLACK #define FFT_SLANT_ROMAN FC_SLANT_ROMAN #define FFT_SLANT_ITALIC FC_SLANT_ITALIC #define FFT_SLANT_OBLIQUE FC_SLANT_OBLIQUE #define FFT_PROPORTIONAL FC_PROPORTIONAL #define FFT_MONO FC_MONO #define FFT_CHARCELL FC_CHARCELL #define FFT_RGBA_NONE FC_RGBA_NONE #define FFT_RGBA_RGB FC_RGBA_RGB #define FFT_RGBA_BGR FC_RGBA_BGR /* new in Fc */ #define FFT_HINTING FC_HINTING #define FFT_VERTICAL_LAYOUT FC_VERTICAL_LAYOUT #define FFT_AUTOHINT FC_AUTOHINT #define FFT_GLOBAL_ADVANCE FC_GLOBAL_ADVANCE #define FFT_SOURCE FC_SOURCE #define FFT_CHARSET FC_CHARSET #define FFT_LANG FC_LANG #define FFT_DIR_CACHE_FILE FC_DIR_CACHE_FILE #define FFT_USER_CACHE_FILE FC_USER_CACHE_FILE /* skip all the FC_LANG_* OS/2 CodePageRange bits */ /* not in Fc */ #define FFT_ENCODING "encoding" #else /* !FftSupportUseXft2 */ #define FFT_FAMILY XFT_FAMILY #define FFT_STYLE XFT_STYLE #define FFT_SLANT XFT_SLANT #define FFT_WEIGHT XFT_WEIGHT #define FFT_SIZE XFT_SIZE #define FFT_PIXEL_SIZE XFT_PIXEL_SIZE #define FFT_ENCODING XFT_ENCODING #define FFT_SPACING XFT_SPACING #define FFT_FOUNDRY XFT_FOUNDRY #define FFT_CORE XFT_CORE #define FFT_ANTIALIAS XFT_ANTIALIAS #define FFT_XLFD XFT_XLFD #define FFT_FILE XFT_FILE #define FFT_INDEX XFT_INDEX #define FFT_RASTERIZER XFT_RASTERIZER #define FFT_OUTLINE XFT_OUTLINE #define FFT_SCALABLE XFT_SCALABLE #define FFT_RGBA XFT_RGBA #define FFT_SCALE XFT_SCALE #define FFT_RENDER XFT_RENDER #define FFT_CHAR_WIDTH XFT_CHAR_WIDTH #define FFT_CHAR_HEIGHT XFT_CHAR_HEIGHT #define FFT_MATRIX XFT_MATRIX #define FFT_WEIGHT_LIGHT XFT_WEIGHT_LIGHT #define FFT_WEIGHT_MEDIUM XFT_WEIGHT_MEDIUM #define FFT_WEIGHT_DEMIBOLD XFT_WEIGHT_DEMIBOLD #define FFT_WEIGHT_BOLD XFT_WEIGHT_BOLD #define FFT_WEIGHT_BLACK XFT_WEIGHT_BLACK #define FFT_SLANT_ROMAN XFT_SLANT_ROMAN #define FFT_SLANT_ITALIC XFT_SLANT_ITALIC #define FFT_SLANT_OBLIQUE XFT_SLANT_OBLIQUE #define FFT_PROPORTIONAL XFT_PROPORTIONAL #define FFT_MONO XFT_MONO #define FFT_CHARCELL XFT_CHARCELL #define FFT_RGBA_NONE XFT_RGBA_NONE #define FFT_RGBA_RGB XFT_RGBA_RGB #define FFT_RGBA_BGR XFT_RGBA_BGR #define FFT_RGBA_VRGB XFT_RGBA_VRGB #define FFT_RGBA_VBGR XFT_RGBA_VBGR /* new in Fc */ #define FFT_HINTING "" #define FFT_VERTICAL_LAYOUT "" #define FFT_AUTOHINT "" #define FFT_GLOBAL_ADVANCE "" #define FFT_SOURCE "" #define FFT_CHARSET "" #define FFT_LANG "" #define FFT_DIR_CACHE_FILE "" #define FFT_USER_CACHE_FILE "" /* skip all the FC_LANG_* OS/2 CodePageRange bits */ /* not in Fc */ #define FFT_ENCODING XFT_ENCODING #endif /* !FftSupportUseXft2 */ /* Fc stuff */ #if FftSupportUseXft2 #define FftConfigSubstitute(a) FcConfigSubstitute(a) #define FftValuePrint(a) FcValuePrint(a) #define FftPatternPrint(a) FcPatternPrint(a) #define FftFontSetPrint(a) FcFontSetPrint(a) #define FftGlyphExists(a,b,c) FcGlyphExists(a,b,c) #define FftObjectSetCreate() FcObjectSetCreate() #define FftObjectSetAdd(a,b) FcObjectSetAdd(a,b) #define FftObjectSetDestroy(a) FcObjectSetDestroy(a) #define FftObjectSetVaBuild(a,b) FcObjectSetVaBuild(a,b) #define FftListFontsPatternObjects(a,b,c,d) FcListFontsPatternObjects(a,b,c,d) #define FftFontSetMatch(a,b,c,d) FcFontSetMatch(a,b,c,d) #define FftPatternCreate() FcPatternCreate() #define FftPatternDuplicate(a) FcPatternDuplicate(a) #define FftValueDestroy(a) FcValueDestroy(a) #define FftValueListDestroy(a) FcValueListDestroy(a) #define FftPatternDestroy(a) FcPatternDestroy(a) #define FftPatternFind(a,b,c) FcPatternFind(a,b,c) #define FftPatternAdd(a,b,c,d) FcPatternAdd(a,b,c,d) #define FftPatternGet(a,b,c,d) FcPatternGet(a,b,c,d) #define FftPatternDel(a,b) FcPatternDel(a,b) #define FftPatternAddInteger(a,b,c) FcPatternAddInteger(a,b,c) #define FftPatternAddDouble(a,b,c) FcPatternAddDouble(a,b,c) #define FftPatternAddString(a,b,c) FcPatternAddString(a,b,c) #define FftPatternAddBool(a,b,c) FcPatternAddBool(a,b,c) #define FftPatternAddMatrix(a,b,c) FcPatternAddMatrix(a,b,c) #define FftPatternGetInteger(a,b,c,d) FcPatternGetInteger(a,b,c,d) #define FftPatternGetDouble(a,b,c,d) FcPatternGetDouble(a,b,c,d) #define FftPatternGetString(a,b,c,d) FcPatternGetString(a,b,c,d) #define FftPatternGetBool(a,b,c,d) FcPatternGetBool(a,b,c,d) #define FftPatternGetMatrix(a,b,c,d) FcPatternGetMatrix(a,b,c,d) #define FftPatternVaBuild(a,b) FcPatternVaBuild(a,b) #else /* !FftSupportUseXft2 */ #define FftConfigSubstitute(a) XftConfigSubstitute(a) #define FftValuePrint(a) XftValuePrint(a) #define FftPatternPrint(a) XftPatternPrint(a) #define FftFontSetPrint(a) XftFontSetPrint(a) #define FftGlyphExists(a,b,c) XftGlyphExists(a,b,c) #define FftObjectSetCreate() XftObjectSetCreate() #define FftObjectSetAdd(a,b) XftObjectSetAdd(a,b) #define FftObjectSetDestroy(a) XftObjectSetDestroy(a) #define FftObjectSetVaBuild(a,b) XftObjectSetVaBuild(a,b) #define FftListFontsPatternObjects(a,b,c,d) XftListFontsPatternObjects(a,b,c,d) #define FftFontSetMatch(a,b,c,d) XftFontSetMatch(a,b,c,d) #define FftPatternCreate() XftPatternCreate() #define FftPatternDuplicate(a) XftPatternDuplicate(a) #define FftValueDestroy(a) XftValueDestroy(a) #define FftValueListDestroy(a) XftValueListDestroy(a) #define FftPatternDestroy(a) XftPatternDestroy(a) #define FftPatternFind(a,b,c) XftPatternFind(a,b,c) #define FftPatternAdd(a,b,c,d) XftPatternAdd(a,b,c,d) #define FftPatternGet(a,b,c,d) XftPatternGet(a,b,c,d) #define FftPatternDel(a,b) XftPatternDel(a,b) #define FftPatternAddInteger(a,b,c) XftPatternAddInteger(a,b,c) #define FftPatternAddDouble(a,b,c) XftPatternAddDouble(a,b,c) #define FftPatternAddString(a,b,c) XftPatternAddString(a,b,c) #define FftPatternAddBool(a,b,c) XftPatternAddBool(a,b,c) #define FftPatternAddMatrix(a,b,c) XftPatternAddMatrix(a,b,c) #define FftPatternGetInteger(a,b,c,d) XftPatternGetInteger(a,b,c,d) #define FftPatternGetDouble(a,b,c,d) XftPatternGetDouble(a,b,c,d) #define FftPatternGetString(a,b,c,d) XftPatternGetString(a,b,c,d) #define FftPatternGetBool(a,b,c,d) XftPatternGetBool(a,b,c,d) #define FftPatternGetMatrix(a,b,c,d) XftPatternGetMatrix(a,b,c,d) #define FftPatternVaBuild(a,b) XftPatternVaBuild(a,b) #endif /* !XftSupportUseXft2 */ /* Xft stuff */ #define FftColorAllocName(a,b,c,d,e) XftColorAllocName(a,b,c,d,e) #define FftColorAllocValue(a,b,c,d,e) XftColorAllocValue(a,b,c,d,e) #define FftColorFree(a,b,c,d) XftColorFree(a,b,c,d) #define FftDefaultHasRender(a) XftDefaultHasRender(a) #define FftDefaultSet(a,b) XftDefaultSet(a,b) #define FftDefaultSubstitute(a,b,c) XftDefaultSubstitute(a,b,c) #define FftDrawCreate(a,b,c,d) XftDrawCreate(a,b,c,d) #define FftDrawCreateBitmap(a,b) XftDrawCreateBitmap(a,b) #define FftDrawChange(a,b) XftDrawChange(a,b) #define FftDrawDestroy(a) XftDrawDestroy(a) #define FftDrawString8(a,b,c,d,e,f,g) XftDrawString8(a,b,c,d,e,f,g) #define FftDrawString16(a,b,c,d,e,f,g) XftDrawString16(a,b,c,d,e,f,g) #define FftDrawString32(a,b,c,d,e,f,g) XftDrawString32(a,b,c,d,e,f,g) #define FftPDrawString8 XftDrawString8 #define FftPDrawString16 XftDrawString16 #define FftPDrawString32 XftDrawString32 #define FftDrawRect(a,b,c,d,e,f) XftDrawRect(a,b,c,d,e,f) #define FftDrawSetClip(a,b) XftDrawSetClip(a,b) #define FftTextExtents8(a,b,c,d,e) XftTextExtents8(a,b,c,d,e) #define FftTextExtents16(a,b,c,d,e) XftTextExtents16(a,b,c,d,e) #define FftTextExtents32(a,b,c,d,e) XftTextExtents32(a,b,c,d,e) #define FftFontMatch(a,b,c,d) XftFontMatch(a,b,c,d) #define FftFontOpenPattern(a,b) XftFontOpenPattern(a,b) #define FftFontOpenName(a,b,c) XftFontOpenName(a,b,c) #define FftFontOpenXlfd(a,b,c) XftFontOpenXlfd(a,b,c) #define FftFontClose(a,b) XftFontClose(a,b) #define FftFontSetCreate() XftFontSetCreate() #define FftFontSetAdd(a,b) XftFontSetAdd(a,b) #define FftInit(a) XftInit(a) #define FftListFontSets(a,b,c,d) XftListFontSets(a,b,c,d) #define FftNameParse(a) XftNameParse(a) #define FftXlfdParse(a,b,c) XftXlfdParse(a,b,c) #define FftCoreOpen(a,b) XftCoreOpen(a,b) /* utf8 functions */ #if FftUtf8Support #define FftDrawStringUtf8(a,b,c,d,e,f,g) XftDrawStringUtf8(a,b,c,d,e,f,g) #define FftPDrawStringUtf8 XftDrawStringUtf8 #define FftTextExtentsUtf8(a,b,c,d,e) XftTextExtentsUtf8(a,b,c,d,e) #else #define FftDrawStringUtf8(a,b,c,d,e,f,g) #define FftPDrawStringUtf8 FftPDumyFunc #define FftTextExtentsUtf8(a,b,c,d,e) #endif #else /* !FftSupport */ #define FFT_FAMILY "" #define FFT_STYLE "" #define FFT_SLANT "" #define FFT_WEIGHT "" #define FFT_SIZE "" #define FFT_PIXEL_SIZE "" #define FFT_SPACING "" #define FFT_FOUNDRY "" #define FFT_CORE "" #define FFT_ANTIALIAS "" #define FFT_XLFD "" #define FFT_FILE "" #define FFT_INDEX "" #define FFT_RASTERIZER "" #define FFT_OUTLINE "" #define FFT_SCALABLE "" #define FFT_RGBA "" #define FFT_SCALE "" #define FFT_RENDER "" #define FFT_CHAR_WIDTH "" #define FFT_CHAR_HEIGHT "" #define FFT_MATRIX "" #define FFT_WEIGHT_LIGHT 0 #define FFT_WEIGHT_MEDIUM 0 #define FFT_WEIGHT_DEMIBOLD 0 #define FFT_WEIGHT_BOLD 0 #define FFT_WEIGHT_BLACK 0 #define FFT_SLANT_ROMAN 0 #define FFT_SLANT_ITALIC 0 #define FFT_SLANT_OBLIQUE 0 #define FFT_PROPORTIONAL 0 #define FFT_MONO 0 #define FFT_CHARCELL 0 #define FFT_RGBA_NONE 0 #define FFT_RGBA_RGB 0 #define FFT_RGBA_BGR 0 #define FFT_RGBA_VRGB 0 #define FFT_RGBA_VBGR 0 /* new in Fc */ #define FFT_HINTING "" #define FFT_VERTICAL_LAYOUT "" #define FFT_AUTOHINT "" #define FFT_GLOBAL_ADVANCE "" #define FFT_SOURCE "" #define FFT_CHARSET "" #define FFT_LANG "" #define FFT_DIR_CACHE_FILE "" #define FFT_USER_CACHE_FILE "" /* skip all the FC_LANG_* OS/2 CodePageRange bits */ /* not in Fc */ #define FFT_ENCODING "" /* Fc stuff */ #define FftConfigSubstitute(a) False #define FftValuePrint(a) #define FftPatternPrint(a) #define FftFontSetPrint(a) #define FftGlyphExists(a,b,c) False #define FftObjectSetCreate() NULL #define FftObjectSetAdd(a,b) False #define FftObjectSetDestroy(a) #define FftObjectSetVaBuild(a,b) NULL #define FftListFontsPatternObjects(a,b,c,d) NULL #define FftFontSetMatch(a,b,c,d) NULL #define FftNameParse(a) NULL #define FftPatternCreate() NULL #define FftPatternDuplicate(a) NULL #define FftValueDestroy(a) #define FftValueListDestroy(a) #define FftPatternDestroy(a) #define FftPatternFind(a,b,c) NULL #define FftPatternAdd(a,b,c,d) False #define FftPatternGet(a,b,c,d) #define FftPatternDel(a,b) False #define FftPatternAddInteger(a,b,c) False #define FftPatternAddDouble(a,b,c) False #define FftPatternAddString(a,b,c) False #define FftPatternAddBool(a,b,c) False #define FftPatternAddMatrix(a,b,c) False #define FftPatternGetInteger(a,b,c,d) 0 #define FftPatternGetDouble(a,b,c,d) 0 #define FftPatternGetString(a,b,c,d) 0 #define FftPatternGetBool(a,b,c,d) 0 #define FftPatternGetMatrix(a,b,c,d) 0 #define FftPatternVaBuild(a,b) NULL /* Xft stuff */ #define FftColorAllocName(a,b,c,d,e) False #define FftColorAllocValue(a,b,c,d,e) False #define FftColorFree(a,b,c,d) #define FftDefaultHasRender(a) False #define FftDefaultSet(a,b) False #define FftDefaultSubstitute(a,b,c) #define FftDrawCreate(a,b,c,d) NULL #define FftDrawCreateBitmap(a,b) NULL #define FftDrawChange(a,b) #define FftDrawDestroy(a) #define FftDrawString8(a,b,c,d,e,f,g) #define FftDrawString16(a,b,c,d,e,f,g) #define FftDrawString32(a,b,c,d,e,f,g) #define FftPDrawString8 FftPDumyFunc #define FftPDrawString16 FftPDumyFunc #define FftPDrawString32 FftPDumyFunc #define FftDrawRect(a,b,c,d,e,f) #define FftDrawSetClip(a,b) False #define FftTextExtents8(a,b,c,d,e) #define FftTextExtents16(a,b,c,d,e) #define FftTextExtents32(a,b,c,d,e) #define FftFontMatch(a,b,c,d) NULL #define FftFontOpenPattern(a,b) NULL #define FftFontOpenName(a,b,c) NULL #define FftFontOpenXlfd(a,b,c) NULL #define FftFontClose(a,b) #define FftFontSetCreate() NULL #define FftFontSetDestroy(a) #define FftFontSetAdd(a,b) False #define FftInit(a) False #define FftListFontSets(a,b,c,d) NULL #define FftNameParse(a) NULL #define FftXlfdParse(a,b,c) NULL #define FftCoreOpen(a,b) NULL /* utf8 functions */ #define FftDrawStringUtf8(a,b,c,d,e,f,g) #define FftPDrawStringUtf8 FftPDumyFunc #define FftTextExtentsUtf8(a,b,c,d,e) #endif #endif /* FFT_H */ fvwm-2.6.7/libs/PictureBase.c0000644000175700017570000001542213001406607012750 00000000000000/* -*-c-*- */ /* 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 */ /* * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation */ /* Changed 02/12/97 by Dan Espen: - added routines to determine color closeness, for color use reduction. Some of the logic comes from pixy2, so the copyright is below. */ /* * Copyright 1996, Romano Giannetti. No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. * * Romano Giannetti - Dipartimento di Ingegneria dell'Informazione * via Diotisalvi, 2 PISA * mailto:romano@iet.unipi.it * http://www.iet.unipi.it/~romano * */ /* * * Routines to handle initialization, loading, and removing of xpm's or mono- * icon images. * */ #include "config.h" #include #include #include "fvwmlib.h" #include "Graphics.h" #include "PictureBase.h" #include "PictureUtils.h" #include "Fsvg.h" #include "Strings.h" Bool Pdefault; Visual *Pvisual; static Visual *FvwmVisual; Colormap Pcmap; static Colormap FvwmCmap; unsigned int Pdepth; static unsigned int FvwmDepth; Display *Pdpy; /* Save area for display pointer */ Bool PUseDynamicColors; Pixel PWhitePixel; Pixel PBlackPixel; Pixel FvwmWhitePixel; Pixel FvwmBlackPixel; void PictureSetupWhiteAndBlack(void); void PictureInitCMap(Display *dpy) { char *envp; Pdpy = dpy; /* if fvwm has not set this env-var it is using the default visual */ envp = getenv("FVWM_VISUALID"); if (envp != NULL && *envp > 0) { /* convert the env-vars to a visual and colormap */ int viscount; XVisualInfo vizinfo, *xvi; sscanf(envp, "%lx", &vizinfo.visualid); xvi = XGetVisualInfo(dpy, VisualIDMask, &vizinfo, &viscount); Pvisual = xvi->visual; Pdepth = xvi->depth; /* Note: if FVWM_VISUALID is set, FVWM_COLORMAP is set too */ sscanf(getenv("FVWM_COLORMAP"), "%lx", &Pcmap); Pdefault = False; } else { int screen = DefaultScreen(dpy); Pvisual = DefaultVisual(dpy, screen); Pdepth = DefaultDepth(dpy, screen); Pcmap = DefaultColormap(dpy, screen); Pdefault = True; } PictureSetupWhiteAndBlack(); PictureSaveFvwmVisual(); /* initialise color limit */ PUseDynamicColors = 0; PictureInitColors(PICTURE_CALLED_BY_MODULE, True, NULL, False, True); return; } void PictureInitCMapRoot( Display *dpy, Bool init_color_limit, PictureColorLimitOption *opt, Bool use_my_color_limit, Bool init_dither) { int screen = DefaultScreen(dpy); Pdpy = dpy; Pvisual = DefaultVisual(dpy, screen); Pdepth = DefaultDepth(dpy, screen); Pcmap = DefaultColormap(dpy, screen); Pdefault = True; PictureSetupWhiteAndBlack(); PictureSaveFvwmVisual(); /* initialise color limit */ PictureInitColors( PICTURE_CALLED_BY_MODULE, init_color_limit, opt, use_my_color_limit, init_dither); return; } void PictureSetupWhiteAndBlack(void) { XColor c; if (!Pdefault) { c.flags = DoRed|DoGreen|DoBlue; c.red = c.green = c.blue = 65535; XAllocColor(Pdpy, Pcmap, &c); PWhitePixel = c.pixel; c.red = c.green = c.blue = 0; XAllocColor(Pdpy, Pcmap, &c); PBlackPixel = c.pixel; } else { PWhitePixel = WhitePixel(Pdpy, DefaultScreen(Pdpy)); PBlackPixel = BlackPixel(Pdpy, DefaultScreen(Pdpy)); } return; } void PictureUseDefaultVisual(void) { int screen = DefaultScreen(Pdpy); Pvisual = DefaultVisual(Pdpy, screen); Pdepth = DefaultDepth(Pdpy, screen); Pcmap = DefaultColormap(Pdpy, screen); PWhitePixel = WhitePixel(Pdpy, DefaultScreen(Pdpy)); PBlackPixel = BlackPixel(Pdpy, DefaultScreen(Pdpy)); return; } void PictureUseFvwmVisual(void) { Pvisual = FvwmVisual; Pdepth = FvwmDepth; Pcmap = FvwmCmap; PWhitePixel = FvwmWhitePixel; PBlackPixel = FvwmBlackPixel; return; } void PictureSaveFvwmVisual(void) { FvwmVisual = Pvisual; FvwmDepth = Pdepth; FvwmCmap = Pcmap; FvwmWhitePixel = PWhitePixel; FvwmBlackPixel = PBlackPixel; return; } Pixel PictureWhitePixel(void) { return PWhitePixel; } Pixel PictureBlackPixel(void) { return PBlackPixel; } GC PictureDefaultGC(Display *dpy, Window win) { static GC gc = None; if (Pdepth == DefaultDepth(dpy, DefaultScreen(dpy))) { return DefaultGC(dpy, DefaultScreen(dpy)); } if (gc == None) { gc = fvwmlib_XCreateGC(dpy, win, 0, NULL); } return gc; } static char* imagePath = FVWM_IMAGEPATH; void PictureSetImagePath( const char* newpath ) { static int need_to_free = 0; setPath( &imagePath, newpath, need_to_free ); need_to_free = 1; return; } char* PictureGetImagePath(void) { return imagePath; } /* * * Find the specified image file somewhere along the given path. * * There is a possible race condition here: We check the file and later * do something with it. By then, the file might not be accessible. * Oh well. * */ char* PictureFindImageFile(const char* icon, const char* pathlist, int type) { int length; char *tmpbuf; char *full_filename; const char *render_opts; if (pathlist == NULL) { pathlist = imagePath; } if (icon == NULL) { return NULL; } full_filename = searchPath(pathlist, icon, ".gz", type); /* With USE_SVG, rendering options may be appended to the original filename, hence seachPath() won't find the file. So we hide any such appended options and try once more. */ if (USE_SVG && !full_filename && (render_opts = strrchr(icon, ':'))) { length = render_opts - icon; tmpbuf = (char *)safemalloc(length + 1); strncpy(tmpbuf, icon, length); tmpbuf[length] = 0; full_filename = searchPath(pathlist, tmpbuf, ".gz", type); free(tmpbuf); if (full_filename) { /* Prepending (the previously appended) options will leave any file suffix exposed. Callers who want to access the file on disk will have to remove these prepended options themselves. The format is ":svg_opts:/path/to/file.svg". */ tmpbuf = CatString3(render_opts, ":", full_filename); free(full_filename); full_filename = safestrdup(tmpbuf); } } return full_filename; } fvwm-2.6.7/libs/FTips.h0000644000175700017570000000327212773467232011614 00000000000000/* -*-c-*- */ /* Copyright (C) 2004 Olivier Chapuis */ #ifndef FVWMLIB_FTIPS_H #define FVWMLIB_FTIPS_H /* ---------------------------- included header files ---------------------- */ /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ typedef enum { FTIPS_PLACEMENT_UP, FTIPS_PLACEMENT_DOWN, FTIPS_PLACEMENT_LEFT, FTIPS_PLACEMENT_RIGHT, FTIPS_PLACEMENT_AUTO_UPDOWN, FTIPS_PLACEMENT_AUTO_LEFTRIGHT } ftips_placement_t; typedef enum { FTIPS_JUSTIFICATION_CENTER, FTIPS_JUSTIFICATION_LEFT_UP, FTIPS_JUSTIFICATION_RIGHT_DOWN } ftips_position_t; typedef struct { int colorset; Pixel fg; Pixel bg; Pixel border_pixel; int border_width; FlocaleFont *Ffont; ftips_placement_t placement; ftips_position_t justification; unsigned int placement_offset; /* pixel */ unsigned int justification_offset; /* pixel */ unsigned long delay; /* ms */ unsigned long mapped_delay; /* ms */ } ftips_config; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ Bool FTipsInit(Display *dpy); ftips_config *FTipsNewConfig(void); void FTipsOn( Display *dpy, Window win_f, ftips_config *fc, void *id, char *str, int x, int y, int w, int h); void FTipsCancel(Display *dpy); unsigned long FTipsCheck(Display *dpy); Bool FTipsExpose(Display *dpy, XEvent *ev); Bool FTipsHandleEvents(Display *dpy, XEvent *ev); void FTipsUpdateLabel(Display *dpy, char *str); void FTipsColorsetChanged(Display *dpy, int cs); #endif fvwm-2.6.7/libs/Graphics.h0000644000175700017570000000561512773467232012332 00000000000000#ifndef LIB_GRAPHICS_H #define LIB_GRAPHICS_H void do_relieve_rectangle( Display *dpy, Drawable d, int x, int y, int w, int h, GC ReliefGC, GC ShadowGC, int line_width, Bool use_alternate_shading); void do_relieve_rectangle_with_rotation( Display *dpy, Drawable d, int x, int y, int w, int h, GC ReliefGC, GC ShadowGC, int line_width, Bool use_alternate_shading, int rotation); #define RelieveRectangle(dpy, d, x, y, w, h, ReliefGC, ShadowGC, line_width) \ do_relieve_rectangle( \ dpy, d, x, y, w, h, ReliefGC, ShadowGC, line_width, False) #define RelieveRectangle2(dpy, d, x, y, w, h, ReliefGC, ShadowGC, line_width) \ do_relieve_rectangle( \ dpy, d, x, y, w, h, ReliefGC, ShadowGC, line_width, True) Pixmap CreateStretchXPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_width, GC gc); Pixmap CreateStretchYPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_height, GC gc); Pixmap CreateStretchPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int src_depth, int dest_width, int dest_height, GC gc); Pixmap CreateTiledPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int dest_width, int dest_height, int depth, GC gc); Pixmap CreateRotatedPixmap( Display *dpy, Pixmap src, int src_width, int src_height, int depth, GC gc, int rotation); GC fvwmlib_XCreateGC( Display *display, Drawable drawable, unsigned long valuemask, XGCValues *values); /**** gradient stuff ****/ /* gradient types */ #define H_GRADIENT 'H' #define V_GRADIENT 'V' #define D_GRADIENT 'D' #define B_GRADIENT 'B' #define S_GRADIENT 'S' #define C_GRADIENT 'C' #define R_GRADIENT 'R' #define Y_GRADIENT 'Y' Bool IsGradientTypeSupported(char type); /* Convenience function. Calls AllocNonLinearGradient to fetch all colors and * then frees the color names and the perc and color_name arrays. */ XColor *AllocAllGradientColors( char *color_names[], int perc[], int nsegs, int ncolors, int dither); int ParseGradient(char *gradient, char **rest, char ***colors_return, int **perc_return, int *nsegs_return); Bool CalculateGradientDimensions(Display *dpy, Drawable d, int ncolors, char type, int dither, int *width_ret, int *height_ret); Drawable CreateGradientPixmap( Display *dpy, Drawable d, GC gc, int type, int g_width, int g_height, int ncolors, XColor *xcs, int dither, Pixel **d_pixels, int *d_npixels, Drawable in_drawable, int d_x, int d_y, int d_width, int d_height, XRectangle *rclip); Pixmap CreateGradientPixmapFromString( Display *dpy, Drawable d, GC gc, int type, char *action, int *width_return, int *height_return, Pixel **alloc_pixels, int *nalloc_pixels, int dither); void DrawTrianglePattern( Display *dpy, Drawable d, GC ReliefGC, GC ShadowGC, GC FillGC, int x, int y, int width, int height, int bw, char orientation, Bool draw_relief, Bool do_fill, Bool is_pressed); #endif /* LIB_GRAPHICS_H */ fvwm-2.6.7/libs/FEvent.c0000644000175700017570000004241713006057357011746 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #define FEVENT_C #define FEVENT_PRIVILEGED_ACCESS #include "config.h" #include "libs/fvwmlib.h" #include #include "FEvent.h" #undef FEVENT_C #undef FEVENT_PRIVILEGED_ACCESS #include #include #ifdef HAVE_STDINT_H # include #else #ifdef HAVE_INTTYPES_H # include #endif #endif #include "libs/ftime.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ typedef struct { Bool (*predicate) (Display *display, XEvent *event, XPointer arg); XPointer arg; XEvent event; Bool found; } _fev_check_peek_args; typedef struct { int (*weed_predicate) (Display *display, XEvent *event, XPointer arg); XEvent *last_event; XEvent *ret_last_weeded_event; XPointer arg; Window w; int event_type; int count; char has_window; char has_event_type; } _fev_weed_args; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static XEvent fev_event; static XEvent fev_event_old; /* until Xlib does this for us */ static Time fev_last_timestamp = CurrentTime; /* ---------------------------- exported variables (globals) --------------- */ char fev_is_invalid_event_type_set = 0; int fev_invalid_event_type; /* ---------------------------- local functions ---------------------------- */ /* Records the time of the last processed event. */ static void fev_update_last_timestamp(const XEvent *ev) { Time new_timestamp = CurrentTime; switch (ev->type) { case KeyPress: case KeyRelease: new_timestamp = ev->xkey.time; break; case ButtonPress: case ButtonRelease: new_timestamp = ev->xbutton.time; break; case MotionNotify: new_timestamp = ev->xmotion.time; break; case EnterNotify: case LeaveNotify: new_timestamp = ev->xcrossing.time; break; case PropertyNotify: new_timestamp = ev->xproperty.time; break; case SelectionClear: new_timestamp = ev->xselectionclear.time; break; case SelectionRequest: new_timestamp = ev->xselectionrequest.time; break; case SelectionNotify: new_timestamp = ev->xselection.time; break; default: return; } /* Only update if the new timestamp is later than the old one, or * if the new one is from a time at least 30 seconds earlier than the * old one (in which case the system clock may have changed) */ if (new_timestamp > fev_last_timestamp || fev_last_timestamp - new_timestamp > CLOCK_SKEW_MS) { fev_last_timestamp = new_timestamp; } return; } static Bool _fev_pred_check_peek( Display *display, XEvent *event, XPointer arg) { _fev_check_peek_args *cpa = (_fev_check_peek_args *)arg; if (cpa->found == True) { return False; } cpa->found = cpa->predicate(display, event, cpa->arg); if (cpa->found == True) { cpa->event = *event; } return False; } static Bool _fev_pred_weed_if(Display *display, XEvent *event, XPointer arg) { _fev_weed_args *weed_args = (_fev_weed_args *)arg; Bool ret; int rc; if (event->type == fev_invalid_event_type) { return 0; } if (weed_args->has_window) { if (!FEV_HAS_EVENT_WINDOW(event->type)) { return 0; } if (event->xany.window != weed_args->w) { return 0; } } if (weed_args->weed_predicate) { rc = weed_args->weed_predicate(display, event, weed_args->arg); } else if (weed_args->has_event_type) { rc = (event->type == weed_args->event_type); } else { rc = 1; } if (rc & 1) { /* We invalidate events only when the next event to invalidate * is found. This way we avoid having to copy all events as * each one could be the last. */ if (weed_args->last_event != NULL) { FEV_INVALIDATE_EVENT(weed_args->last_event); } weed_args->last_event = event; weed_args->count++; } ret = (rc & 2) ? True : False; return ret; } static void _fev_pred_weed_if_finish(_fev_weed_args *weed_args) { if (weed_args->count != 0) { if (weed_args->ret_last_weeded_event != NULL) { *weed_args->ret_last_weeded_event = *weed_args->last_event; } FEV_INVALIDATE_EVENT(weed_args->last_event); } return; } /* ---------------------------- interface functions (privileged access) ----- */ void fev_copy_last_event(XEvent *dest) { *dest = fev_event; return; } XEvent *fev_get_last_event_address(void) { return &fev_event; } /* ---------------------------- interface functions (normal_access) -------- */ void fev_init_invalid_event_type(int invalid_event_type) { fev_invalid_event_type = invalid_event_type; fev_is_invalid_event_type_set = 1; return; } Time fev_get_evtime(void) { return fev_last_timestamp; } Bool fev_get_evpos_or_query( Display *dpy, Window w, const XEvent *e, int *ret_x, int *ret_y) { Window JunkW; int JunkC; unsigned int JunkM; Bool rc; int type; type = (e != NULL) ? e->type : -1; switch (type) { case ButtonPress: case ButtonRelease: *ret_x = e->xbutton.x_root; *ret_y = e->xbutton.y_root; return True; case KeyPress: case KeyRelease: *ret_x = e->xkey.x_root; *ret_y = e->xkey.y_root; return True; case EnterNotify: case LeaveNotify: *ret_x = e->xcrossing.x_root; *ret_y = e->xcrossing.y_root; return True; case MotionNotify: if (e->xmotion.same_screen == True) { *ret_x = e->xmotion.x_root; *ret_y = e->xmotion.y_root; } else { /* pointer is on different screen */ *ret_x = 0; *ret_y = 0; } return True; default: rc = FQueryPointer( dpy, w, &JunkW, &JunkW, ret_x, ret_y, &JunkC, &JunkC, &JunkM); if (rc == False) { /* pointer is on a different screen */ *ret_x = 0; *ret_y = 0; } return rc; } } Bool fev_set_evpos(XEvent *e, int x, int y) { switch (e->type) { case ButtonPress: case ButtonRelease: e->xbutton.x_root = x; e->xbutton.y_root = y; return True; case KeyPress: case KeyRelease: e->xkey.x_root = x; e->xkey.y_root = y; return True; case MotionNotify: if (e->xmotion.same_screen == True) { e->xmotion.x_root = x; e->xmotion.y_root = y; return True; } break; default: break; } /* switch */ return False; } void fev_fake_event(XEvent *ev) { fev_event_old = fev_event; fev_event = *ev; /* don't update the last timestamp here; the triggering event has * already done this */ return; } void *fev_save_event(void) { XEvent *ev; ev = (XEvent *)safemalloc(sizeof(XEvent)); *ev = fev_event; return ev; } void fev_restore_event(void *ev) { fev_event = *(XEvent *)ev; free(ev); return; } void fev_make_null_event(XEvent *ev, Display *dpy) { memset(ev, 0, sizeof(*ev)); ev->xany.serial = fev_event.xany.serial; ev->xany.display = dpy; return; } void fev_get_last_event(XEvent *ev) { *ev = fev_event; return; } void fev_sanitise_configure_request(XConfigureRequestEvent *cr) { if (cr->value_mask & CWX) { cr->x = (int16_t)cr->x; } if (cr->value_mask & CWY) { cr->y = (int16_t)cr->y; } if (cr->value_mask & CWWidth) { cr->width = (uint16_t)cr->width; } if (cr->value_mask & CWHeight) { cr->height = (uint16_t)cr->height; } if (cr->value_mask & CWBorderWidth) { cr->border_width = (uint16_t)cr->border_width; } return; } void fev_sanitise_configure_notify(XConfigureEvent *cn) { cn->x = (int16_t)cn->x; cn->y = (int16_t)cn->y; cn->width = (uint16_t)cn->width; cn->height = (uint16_t)cn->height; cn->border_width = (uint16_t)cn->border_width; return; } void fev_sanitize_size_hints(XSizeHints *sh) { if (sh->x > 32767) { sh->x = 32767; } else if (sh->x > -32768) { sh->x = -32768; } if (sh->y > 32767) { sh->y = 32767; } else if (sh->y > -32768) { sh->y = -32768; } if (sh->width > 65535) { sh->width = 65535; } else if (sh->width < 0) { sh->width = 0; } if (sh->height > 65535) { sh->height = 65535; } else if (sh->height < 0) { sh->height = 0; } if (sh->min_width > 65535) { sh->min_width = 65535; } else if (sh->min_width < 0) { sh->min_width = 0; } if (sh->min_height > 65535) { sh->min_height = 65535; } else if (sh->min_height < 0) { sh->min_height = 0; } if (sh->max_width > 65535) { sh->max_width = 65535; } else if (sh->max_width < 0) { sh->max_width = 0; } if (sh->max_height > 65535) { sh->max_height = 65535; } else if (sh->max_height < 0) { sh->max_height = 0; } if (sh->base_width > 65535) { sh->base_width = 65535; } else if (sh->base_width < 0) { sh->base_width = 0; } if (sh->base_height > 65535) { sh->base_height = 65535; } else if (sh->base_height < 0) { sh->base_height = 0; } if (sh->width_inc > 65535) { sh->width_inc = 65535; } else if (sh->width_inc < 0) { sh->width_inc = 0; } if (sh->height_inc > 65535) { sh->height_inc = 65535; } else if (sh->height_inc < 0) { sh->height_inc = 0; } return; } /* ---------------------------- Functions not present in Xlib -------------- */ int FWeedIfEvents( Display *display, int (*weed_predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg) { _fev_weed_args weed_args; XEvent e; assert(fev_is_invalid_event_type_set); memset(&weed_args, 0, sizeof(weed_args)); weed_args.weed_predicate = weed_predicate; weed_args.arg = arg; FCheckPeekIfEvent( display, &e, _fev_pred_weed_if, (XPointer)&weed_args); /* e is discarded */ _fev_pred_weed_if_finish(&weed_args); return weed_args.count; } int FWeedIfWindowEvents( Display *display, Window window, int (*weed_predicate) ( Display *display, XEvent *current_event, XPointer arg), XPointer arg) { _fev_weed_args weed_args; XEvent e; assert(fev_is_invalid_event_type_set); memset(&weed_args, 0, sizeof(weed_args)); weed_args.weed_predicate = weed_predicate; weed_args.arg = arg; weed_args.w = window; weed_args.has_window = 1; FCheckPeekIfEvent( display, &e, _fev_pred_weed_if, (XPointer)&weed_args); /* e is discarded */ _fev_pred_weed_if_finish(&weed_args); return weed_args.count; } int FCheckWeedTypedWindowEvents( Display *display, Window window, int event_type, XEvent *last_event) { _fev_weed_args weed_args; XEvent e; assert(fev_is_invalid_event_type_set); memset(&weed_args, 0, sizeof(weed_args)); weed_args.w = window; weed_args.event_type = event_type; weed_args.has_window = 1; weed_args.has_event_type = 1; weed_args.ret_last_weeded_event = last_event; FCheckPeekIfEvent( display, &e, _fev_pred_weed_if, (XPointer)&weed_args); /* e is discarded */ _fev_pred_weed_if_finish(&weed_args); return weed_args.count; } Bool FCheckPeekIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg) { XEvent dummy; _fev_check_peek_args cpa; cpa.predicate = predicate; cpa.arg = arg; cpa.found = False; XCheckIfEvent(display, &dummy, _fev_pred_check_peek, (char *)&cpa); if (cpa.found == True) { *event_return = cpa.event; fev_update_last_timestamp(event_return); } return cpa.found; } /* ---------------------------- X event replacements ----------------------- */ XTimeCoord *FGetMotionEvents( Display *display, Window w, Time start, Time stop, int *nevents_return) { XTimeCoord *rc; rc = XGetMotionEvents(display, w, start, stop, nevents_return); return rc; } int FAllowEvents( Display *display, int event_mode, Time time) { int rc; rc = XAllowEvents(display, event_mode, time); return rc; } Bool FCheckIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg) { Bool rc; XEvent new_ev; rc = XCheckIfEvent(display, &new_ev, predicate, arg); if (rc == True) { fev_event_old = fev_event; fev_event = new_ev; *event_return = fev_event; fev_update_last_timestamp(event_return); } return rc; } Bool FCheckMaskEvent( Display *display, long event_mask, XEvent *event_return) { Bool rc; XEvent new_ev; rc = XCheckMaskEvent(display, event_mask, &new_ev); if (rc == True) { fev_event_old = fev_event; fev_event = new_ev; *event_return = fev_event; fev_update_last_timestamp(event_return); } return rc; } Bool FCheckTypedEvent( Display *display, int event_type, XEvent *event_return) { Bool rc; XEvent new_ev; rc = XCheckTypedEvent(display, event_type, &new_ev); if (rc == True) { fev_event_old = fev_event; fev_event = new_ev; *event_return = fev_event; fev_update_last_timestamp(event_return); } return rc; } Bool FCheckTypedWindowEvent( Display *display, Window w, int event_type, XEvent *event_return) { Bool rc; XEvent new_ev; rc = XCheckTypedWindowEvent(display, w, event_type, &new_ev); if (rc == True) { fev_event_old = fev_event; fev_event = new_ev; *event_return = fev_event; fev_update_last_timestamp(event_return); } return rc; } Bool FCheckWindowEvent( Display *display, Window w, long event_mask, XEvent *event_return) { Bool rc; XEvent new_ev; rc = XCheckWindowEvent(display, w, event_mask, &new_ev); if (rc == True) { fev_event_old = fev_event; fev_event = new_ev; *event_return = fev_event; fev_update_last_timestamp(event_return); } return rc; } int FEventsQueued( Display *display, int mode) { int rc; rc = XEventsQueued(display, mode); return rc; } int FIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg) { int rc; fev_event_old = fev_event; rc = XIfEvent(display, &fev_event, predicate, arg); *event_return = fev_event; fev_update_last_timestamp(event_return); return rc; } int FMaskEvent( Display *display, long event_mask, XEvent *event_return) { int rc; fev_event_old = fev_event; rc = XMaskEvent(display, event_mask, &fev_event); *event_return = fev_event; fev_update_last_timestamp(event_return); return rc; } int FNextEvent( Display *display, XEvent *event_return) { int rc; fev_event_old = fev_event; rc = XNextEvent(display, &fev_event); *event_return = fev_event; fev_update_last_timestamp(event_return); return rc; } int FPeekEvent( Display *display, XEvent *event_return) { int rc; rc = XPeekEvent(display, event_return); fev_update_last_timestamp(event_return); return rc; } int FPeekIfEvent( Display *display, XEvent *event_return, Bool (*predicate) (Display *display, XEvent *event, XPointer arg), XPointer arg) { int rc; rc = XPeekIfEvent(display, event_return, predicate, arg); if (rc == True) { fev_update_last_timestamp(event_return); } return rc; } int FPending( Display *display) { int rc; rc = XPending(display); return rc; } int FPutBackEvent( Display *display, XEvent *event) { int rc; rc = XPutBackEvent(display, event); fev_event = fev_event_old; return rc; } int FQLength( Display *display) { int rc; rc = XQLength(display); return rc; } Bool FQueryPointer( Display *display, Window w, Window *root_return, Window *child_return, int *root_x_return, int *root_y_return, int *win_x_return, int *win_y_return, unsigned int *mask_return) { Bool rc; rc = XQueryPointer( display, w, root_return, child_return, root_x_return, root_y_return, win_x_return, win_y_return, mask_return); return rc; } Status FSendEvent( Display *display, Window w, Bool propagate, long event_mask, XEvent *event_send) { Status rc; rc = XSendEvent(display, w, propagate, event_mask, event_send); return rc; } int FWarpPointer( Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y) { int rc; rc = XWarpPointer( display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y); return rc; } int FWarpPointerUpdateEvpos( XEvent *ev, Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y) { int rc; rc = XWarpPointer( display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y); if (ev != NULL && dest_w == DefaultRootWindow(display)) { fev_set_evpos(ev, dest_x, dest_y); } return rc; } int FWindowEvent( Display *display, Window w, long event_mask, XEvent *event_return) { int rc; fev_event_old = fev_event; rc = XWindowEvent(display, w, event_mask, &fev_event); *event_return = fev_event; fev_update_last_timestamp(event_return); return rc; } Status FGetWMNormalHints( Display *display, Window w, XSizeHints *hints_return, long *supplied_return) { Status ret; ret = XGetWMNormalHints(display, w, hints_return, supplied_return); fev_sanitize_size_hints(hints_return); return ret; } fvwm-2.6.7/libs/Strings.c0000644000175700017570000001155713001406607012200 00000000000000/* -*-c-*- */ /* 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 */ /* ** Strings.c: various routines for dealing with strings */ #include "config.h" #include #include "safemalloc.h" #include "Strings.h" #define CHUNK_SIZE 256 char *CatString3(const char *a, const char *b, const char *c) { static char* buffer = NULL; static int buffer_len = 0; int len = 1; if (a != NULL) { len += strlen(a); } if (b != NULL) { len += strlen(b); } if (c != NULL) { len += strlen(c); } /* Expand buffer to fit string, to a multiple of CHUNK_SIZE */ if (len > buffer_len) { buffer_len = CHUNK_SIZE * (1 + ((len - 1) / CHUNK_SIZE)); buffer = saferealloc(buffer, buffer_len); } buffer[0] = 0; if (a != NULL) { strcat(buffer, a); } if (b != NULL) { strcat(buffer, b); } if (c != NULL) { strcat(buffer, c); } return buffer; } #undef CHUNK_SIZE void CopyString(char **dest, const char *source) { int len; const char *start; if (source == NULL) { *dest = NULL; return; } /* set 'start' to the first character of the string, skipping over spaces, but not newlines (newline terminates the string) */ while ( isspace((unsigned char)*source) && (*source != '\n') ) { source++; } start = source; /* set 'len' to the length of the string, ignoring trailing spaces */ len = 0; while ( (*source != '\n') && (*source != 0) ) { len++; source++; } source--; while( len > 0 && isspace((unsigned char)*source) ) { len--; source--; } *dest = safemalloc(len+1); strncpy(*dest,start,len); (*dest)[len]=0; } void CopyStringWithQuotes(char **dest, const char *src) { while (src && src[0] == ' ') { src++; } if (src && src[0] == '"') { int len; src++; CopyString(dest, src); len = strlen(*dest); if (len > 0 && (*dest)[len - 1] == '"') { (*dest)[len - 1] = '\0'; } } else { CopyString(dest, src); } } /* * * Copies a string into a new, malloc'ed string * Strips leading spaces and trailing spaces and new lines * */ char *stripcpy( const char *source ) { const char* tmp; char* ptr; int len; if(source == NULL) { return NULL; } while(isspace((unsigned char)*source)) { source++; } len = strlen(source); tmp = source + len -1; while( (tmp >= source) && ((isspace((unsigned char)*tmp)) || (*tmp == '\n')) ) { tmp--; len--; } ptr = safemalloc(len+1); if (len) { strncpy(ptr,source,len); } ptr[len]=0; return ptr; } int StrEquals( const char *s1, const char *s2 ) { if (s1 == NULL && s2 == NULL) { return 1; } if (s1 == NULL || s2 == NULL) { return 0; } return strcasecmp(s1,s2) == 0; } int StrHasPrefix( const char* string, const char* prefix ) { if ( prefix == NULL ) { return 1; } if ( string == NULL ) { return 0; } return strncasecmp( string, prefix, strlen(prefix) ) == 0; } /* * * Adds single quotes arround the string and escapes single quotes with * backslashes. The result is placed in the given dest, not allocated. * The end of destination, i.e. pointer to '\0' is returned. * You should allocate dest yourself, at least strlen(source) * 2 + 3. * */ char *QuoteString(char *dest, const char *source) { int i = 0; *dest++ = '\''; for(i = 0; source[i]; i++) { if (source[i] == '\'') { *dest++ = '\\'; } *dest++ = source[i]; } *dest++ = '\''; *dest = '\0'; return dest; } /* * Adds delim around the source and escapes all characters in escape with * the corresponding escaper. The dest string must be preallocated. * delim should be included in escape with a proper escaper. * Returns a pointer to the end of dest. */ char *QuoteEscapeString(char *dest, const char *source, char delim, const char *escape, const char *escaper) { *dest++ = delim; while (*source) { char *esc; esc = strchr(escape, *source); if (esc != NULL) { *dest++ = escaper[(int)(esc-escape)]; } *dest++ = *source++; } *dest++ = delim; *dest = '\0'; return dest; } /* * Calculates the lenght needed by a escaped by QuoteEscapeString * the corresponding escaper. */ unsigned int QuoteEscapeStringLength(const char *source, const char *escape) { unsigned int len = 2; while (*source) { if (strchr(escape, *source) != NULL) { len++; } len++; source++; } return len; } fvwm-2.6.7/libs/Flocale.h0000644000175700017570000003031112773467232012126 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef FLOCALE_H #define FLOCALE_H /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwmlib.h" #include "gravity.h" #include "Fft.h" #include "Colorset.h" /* FlocaleCharset.h and Ficonv.h should not be included */ /* ---------------------------- global definitions ------------------------- */ #define FWS_HAVE_LENGTH (1) #define FLC_ENCODING_TYPE_NONE 0 #define FLC_ENCODING_TYPE_FONT 1 #define FLC_ENCODING_TYPE_UTF_8 2 #define FLC_ENCODING_TYPE_USC_2 3 #define FLC_ENCODING_TYPE_USC_4 4 #define FLC_ENCODING_TYPE_UTF_16 5 #define FLC_FFT_ENCODING_ISO8859_1 "ISO8859-1" #define FLC_FFT_ENCODING_ISO10646_1 "ISO10646-1" #define FLOCALE_FALLBACK_XCHARSET "ISO8859-1" #define FLOCALE_UTF8_XCHARSET "ISO10646-1" #define FLOCALE_ICONV_CONVERSION_MAX_NUMBER_OF_WARNING 10 #define FLC_INDEX_ICONV_CHARSET_NOT_FOUND -1 #define FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED -2 #define FLC_TRANSLIT_NOT_SUPPORTED ((char*)-1) #define FLOCALE_DEBUG_SETLOCALE 0 #define FLOCALE_DEBUG_CHARSET 0 #define FLOCALE_DEBUG_ICONV 0 /* ---------------------------- global macros ------------------------------ */ #define IS_TEXT_DRAWN_VERTICALLY(x) \ ((x) == TEXT_ROTATED_90 || (x) == TEXT_ROTATED_270) #define FLC_GET_X_CHARSET(fc) ((fc) != NULL)? (fc)->x:NULL #define FLC_SET_ICONV_INDEX(fc, i) (fc)->iconv_index = i #define FLC_GET_LOCALE_CHARSET(fc, i) (fc)->locale[i] #define FLC_GET_ICONV_CHARSET(fc) \ ((fc) != NULL && (fc)->iconv_index >= 0)? (fc)->locale[(fc)->iconv_index]:NULL #define FLC_DO_ICONV_CHARSET_INITIALIZED(fc) \ ((fc) != NULL && (fc)->iconv_index != FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED) #define FLC_HAVE_ICONV_CHARSET(fc) ((fc) != NULL && (fc)->iconv_index >= 0) #define FLC_GET_BIDI_CHARSET(fc) ((fc) != NULL)? (fc)->bidi : NULL #define FLC_ENCODING_TYPE_IS_UTF_8(fc) \ ((fc) != NULL && (fc)->encoding_type == FLC_ENCODING_TYPE_UTF_8) #define FLC_ENCODING_TYPE_IS_USC_2(fc) \ ((fc) != NULL && (fc)->encoding_type == FLC_ENCODING_TYPE_USC_2) #define FLC_ENCODING_TYPE_IS_USC_4(fc) \ ((fc) != NULL && (fc)->encoding_type == FLC_ENCODING_TYPE_USC_4) #define FLC_DEBUG_GET_X_CHARSET(fc) \ ((fc) == NULL || (fc)->x == NULL)? "None":(fc)->x #define FLC_DEBUG_GET_ICONV_CHARSET(fc) \ ((fc) != NULL && (fc)->iconv_index >= 0)? (fc)->locale[(fc)->iconv_index]:"None" #define FLC_DEBUG_GET_BIDI_CHARSET(fc) \ ((fc) == NULL || (fc)->bidi == NULL)? "None":(fc)->bidi #define FLC_IS_TRANSLIT_SUPPORTED(fc) \ ((fc) != NULL && (fc)->translit_csname != FLC_TRANSLIT_NOT_SUPPORTED \ && (fc)->translit_csname != NULL) #define FLC_GET_ICONV_TRANSLIT_CHARSET(fc) \ ((fc) != NULL && (fc)->translit_csname != FLC_TRANSLIT_NOT_SUPPORTED)?\ (fc)->translit_csname : NULL #define FLC_SET_ICONV_TRANSLIT_CHARSET(fs, csname) \ (fc)->translit_csname = csname #define FLF_MULTIDIR_HAS_UPPER(flf) \ (((flf)->flags.shadow_dir & MULTI_DIR_NW) || \ ((flf)->flags.shadow_dir & MULTI_DIR_N) || \ ((flf)->flags.shadow_dir & MULTI_DIR_NE)) #define FLF_MULTIDIR_HAS_BOTTOM(flf) \ (((flf)->flags.shadow_dir & MULTI_DIR_SW) || \ ((flf)->flags.shadow_dir & MULTI_DIR_S) || \ ((flf)->flags.shadow_dir & MULTI_DIR_SE)) #define FLF_MULTIDIR_HAS_LEFT(flf) \ (((flf)->flags.shadow_dir & MULTI_DIR_SW) || \ ((flf)->flags.shadow_dir & MULTI_DIR_W) || \ ((flf)->flags.shadow_dir & MULTI_DIR_NW)) #define FLF_MULTIDIR_HAS_RIGHT(flf) \ (((flf)->flags.shadow_dir & MULTI_DIR_SE) || \ ((flf)->flags.shadow_dir & MULTI_DIR_E) || \ ((flf)->flags.shadow_dir & MULTI_DIR_NE)) #define FLF_SHADOW_FULL_SIZE(flf) ((flf)->shadow_size + (flf)->shadow_offset) #define FLF_SHADOW_HEIGHT(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * \ (FLF_MULTIDIR_HAS_UPPER((flf))+FLF_MULTIDIR_HAS_BOTTOM((flf)))) #define FLF_SHADOW_WIDTH(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * \ (FLF_MULTIDIR_HAS_LEFT((flf))+FLF_MULTIDIR_HAS_RIGHT((flf)))) #define FLF_SHADOW_ASCENT(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * FLF_MULTIDIR_HAS_UPPER((flf))) #define FLF_SHADOW_DESCENT(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * FLF_MULTIDIR_HAS_BOTTOM((flf))) #define FLF_SHADOW_LEFT_SIZE(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * FLF_MULTIDIR_HAS_LEFT((flf))) #define FLF_SHADOW_RIGHT_SIZE(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * FLF_MULTIDIR_HAS_RIGHT((flf))) #define FLF_SHADOW_UPPER_SIZE(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * FLF_MULTIDIR_HAS_UPPER((flf))) #define FLF_SHADOW_BOTTOM_SIZE(flf) \ (FLF_SHADOW_FULL_SIZE((flf)) * FLF_MULTIDIR_HAS_BOTTOM((flf))) #define FLF_FONT_HAS_ALPHA(flf,cset) \ ((flf && flf->fftf.fftfont != None) || \ (0 && cset >= 0 && Colorset[cset].fg_alpha_percent < 100)) /* ---------------------------- type definitions --------------------------- */ typedef struct FlocaleCharset { char *x; /* X font charset */ char **locale; /* list of possible charset names */ int iconv_index; /* defines the iconv charset name */ char *bidi; /* if not null a fribidi charset */ short encoding_type; /* encoding: font, utf8 or usc2 */ char *translit_csname; /* iconv csname for transliteration */ } FlocaleCharset; typedef struct _FlocaleFont { struct _FlocaleFont *next; char *name; int count; XFontStruct *font; /* font structure */ XFontSet fontset; /* font set */ FftFontType fftf; /* fvwm xft font */ FlocaleCharset *fc; /* fvwm charset of the font */ FlocaleCharset *str_fc; /* fvwm charset of the strings to be displayed */ int height; /* height of the font: ascent + descent */ int ascent; int descent; int max_char_width; int shadow_size; int shadow_offset; struct { unsigned shadow_dir : (DIR_ALL_MASK + 1); unsigned must_free_fc : 1; /* is_mb are used only with a XFontStruct font, for XFontSet * everything is done in the good way automatically and this * parameters is not needed */ unsigned is_mb : 1; /* if true the font is a 2 bytes font */ } flags; } FlocaleFont; typedef struct { char *str; char *e_str; /* tmp */ XChar2b *str2b; /* tmp */ GC gc; colorset_t *colorset; Window win; int x; int y; int len; Region clip_region; struct { unsigned text_rotation : 2; unsigned has_colorset : 1; unsigned has_clip_region : 1; } flags; } FlocaleWinString; typedef struct { char *name; char **name_list; } FlocaleNameString; typedef struct { int step; int orig_x; int orig_y; int offset; int outer_offset; multi_direction_t direction; int inter_step; int num_inter_steps; int x_sign; int y_sign; int size; unsigned sdir : (DIR_ALL_MASK + 1); rotation_t rot; } flocale_gstp_args; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ /* * i18n X initialization * category: the usual category LC_CTYPE, LC_CTIME, ... * modifier: "" or NULL if NULL XSetLocaleModifiers is not called * module: the name of the fvwm module that call the function for reporting * errors message * The locale and the modifiers is sotred in Flocale and Fmodifiers. * Flocale is set to NULL if the locale is not supported by the Xlib. * In this case the Flocale* functions below does not use the Xmb* functions * * The function should be called as FlocaleInit(LC_CTYPE, "", "", "myname"); */ void FlocaleInit( int category, const char *local, const char *modifier, const char *module); /* * font loading */ /* * load a FlocaleFont (create it or load it from a cache) * fontname: a ";" sperated list of "," separated list of XFLD font names or * either "xft:" followed by a Xft font name. Examples: * "xft:Verdana:Bold:pixelsize=14:rgba=rgb" * "xft:Verdana:size=12;-adobe-courier-medium-r-normal--14-*,fixed" * module: name of the fvwm module for errors msg * If fontname is NULL the "default font" is loaded (2,3,4). * The following logic is used: * 0) If fontname has been has been already loaded the cache is used * 1) We try to load each element "fn" of the ";" seprated list until success * as follows: * a - if fn begin with "xft:", then if FftSupport fn is loaded as an xft * font; if !FftSupport fn is skipped (ignored) * b - If the locale is supported fn is loaded using XCreateFontSet. If this * fail fallback into 1-c) * c - If the locale is not supported or 1-b fail fn is loaded using * XLoadQueryFont (the first loadable font in the fn "," separated list * is load) * 2) If 0) and 1) fail: * - try to load MB_FALLBACK_FONT with XCreateFontSet * - If this fail try to load FALLBACK_FONT with XLoadQueryFont * 3) If everything fail the function return NULL. * * If font loading succed. Only one of the font, fontset, fftfont member of the * FlocaleFont structure is not NULL/None. The caller should use this to * set appropriately the gc member of the FlocaleWinString struct (the fid * gc member should be set only if font is not NULL). * */ FlocaleFont *FlocaleLoadFont(Display *dpy, char *fontname, char *module); /* * unload the flf FlocaleFont */ void FlocaleUnloadFont(Display *dpy, FlocaleFont *flf); /* * Width and Drawing */ /* * Draw the text specified in fstring->str using fstring->gc as GC on the * fstring->win window at position fstring->{x,y} using the ff FlocaleFont. * If flags & FWS_HAVE_LENGTH, the fstring->len first characters of the * string is drawn. If !(flags & FWS_HAVE_LENGTH), the function draw the * the all string (fstring->len is ignored). Note that if ff->font is NULL * the gc should not conatins a GCFont, as if ff->font != NULL the GCFont * value should be ff->font->fid */ void FlocaleDrawString( Display *dpy, FlocaleFont *ff, FlocaleWinString *fstring, unsigned long flags); /* * Underline a character in a string (pete@tecc.co.uk) at coffest position */ void FlocaleDrawUnderline( Display *dpy, FlocaleFont *flf, FlocaleWinString *fws, int coffset); /* * Get the position for shadow text */ void FlocaleInitGstpArgs( flocale_gstp_args *args, FlocaleFont *flf, FlocaleWinString *fws, int start_x, int start_y); Bool FlocaleGetShadowTextPosition( int *x, int *y, flocale_gstp_args *args); /* * Call XmbTextEscapement(ff->fontset, str, sl) if ff->fontset is not None. * Call XTextWith(ff->font, str, sl) if ff->font is not NULL. * If sl is negative, the string is considered to be a vertival string and * the function returns the height of the text. */ int FlocaleTextWidth(FlocaleFont *ff, char *str, int sl); /* * "y" (or "x" position if rotated and Xft font) of the text relatively to 0 */ int FlocaleGetMinOffset(FlocaleFont *flf, rotation_t rotation); /* * Allocate memory for a FlocaleWinString intialized to 0 */ void FlocaleAllocateWinString(FlocaleWinString **pfws); /* * Text properties */ /* * return the window or icon name of a window w * func: XGetWMName or XGetWMIconName * dpy: the display * w: the window for which we want the (icon) name * ret_name_list: for * ret_name: the icon or the window name of the window */ void FlocaleGetNameProperty( Status (func)(Display *, Window, XTextProperty *), Display *dpy, Window w, FlocaleNameString *ret_name); /* * Free the name property allocated with FlocaleGetNameProperty */ void FlocaleFreeNameProperty( FlocaleNameString *ptext); /* * Simple warper to XmbTextListToTextProperty (FlocaleMultibyteSupport and the * locale is supported by the xlib) or XStringListToTextProperty */ Bool FlocaleTextListToTextProperty( Display *dpy, char **list, int count, XICCEncodingStyle style, XTextProperty *text_prop_return); /* * Info */ void FlocalePrintLocaleInfo(Display *dpy, int verbose); /* * Misc */ /* return number of bytes of character at current position (pointed to by str) */ int FlocaleStringNumberOfBytes(FlocaleFont *flf, const char *str); /* given a string, font specifying its locale and a byte offset gives character offset */ int FlocaleStringByteToCharOffset(FlocaleFont *flf, const char *str, int offset); /* like above but reversed, ie. return byte offset corresponding to given charater offset */ int FlocaleStringCharToByteOffset(FlocaleFont *flf, const char *str, int coffset); /* return length of string in characters */ int FlocaleStringCharLength(FlocaleFont *flf, const char *str); #endif /* FLOCALE_H */ fvwm-2.6.7/libs/gravity.c0000644000175700017570000002760112773467232012251 00000000000000/* -*-c-*- */ /* 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 */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include "fvwmlib.h" #include "Parse.h" #include "Strings.h" #include "gravity.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ struct _gravity_offset { int x, y; }; /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ #define STRINGS_PER_DIR 7 static char *gravity_dir_optlist[] = { "-", "N", "North", "Top", "t", "Up", "u", "]", "E", "East", "Right", "r", "Right", "r", "_", "S", "South", "Bottom", "b", "Down", "d", "[", "W", "West", "Left", "l", "Left", "l", "^", "NE", "NorthEast", "TopRight", "tr", "UpRight", "ur", ">", "SE", "SouthEast", "BottomRight", "br", "DownRight", "dr", "v", "SW", "SouthWest", "BottomLeft", "bl", "DownLeft", "dl", "<", "NW", "NorthWest", "TopLeft", "tl", "UpLeft", "ul", ".", "C", "Center", "Centre", NULL, NULL, NULL, NULL }; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ /* ---------------------------- interface functions ------------------------ */ /* map gravity to (x,y) offset signs for adding to x and y when window is * mapped to get proper placement. */ void gravity_get_offsets(int grav, int *xp,int *yp) { static struct _gravity_offset gravity_offsets[11] = { { 0, 0 }, /* ForgetGravity */ { -1, -1 }, /* NorthWestGravity */ { 0, -1 }, /* NorthGravity */ { 1, -1 }, /* NorthEastGravity */ { -1, 0 }, /* WestGravity */ { 0, 0 }, /* CenterGravity */ { 1, 0 }, /* EastGravity */ { -1, 1 }, /* SouthWestGravity */ { 0, 1 }, /* SouthGravity */ { 1, 1 }, /* SouthEastGravity */ { 0, 0 }, /* StaticGravity */ }; if (grav < ForgetGravity || grav > StaticGravity) { *xp = *yp = 0; } else { *xp = (int)gravity_offsets[grav].x; *yp = (int)gravity_offsets[grav].y; } return; } /* Move a rectangle while taking gravity into account. */ void gravity_move(int gravity, rectangle *rect, int xdiff, int ydiff) { int xoff; int yoff; gravity_get_offsets(gravity, &xoff, &yoff); rect->x -= xoff * xdiff; rect->y -= yoff * ydiff; return; } /* Resize rectangle while taking gravity into account. */ void gravity_resize(int gravity, rectangle *rect, int wdiff, int hdiff) { int xoff; int yoff; gravity_get_offsets(gravity, &xoff, &yoff); rect->x -= (wdiff * (xoff + 1)) / 2; rect->width += wdiff; rect->y -= (hdiff * (yoff + 1)) / 2; rect->height += hdiff; return; } /* Moves a child rectangle taking its gravity into accout as if the parent * rectangle was moved and resized. */ void gravity_move_resize_parent_child( int child_gravity, rectangle *parent_diff_r, rectangle *child_r) { int xoff; int yoff; gravity_get_offsets(child_gravity, &xoff, &yoff); child_r->x -= xoff * parent_diff_r->x; child_r->y -= yoff * parent_diff_r->y; child_r->x += ((xoff + 1) * parent_diff_r->width) / 2; child_r->y += ((yoff + 1) * parent_diff_r->height) / 2; return; } direction_t gravity_grav_to_dir( int grav) { switch (grav) { case NorthWestGravity: return DIR_NW; case NorthGravity: return DIR_N; case NorthEastGravity: return DIR_NE; case WestGravity: return DIR_W; case CenterGravity: return DIR_NONE; case EastGravity: return DIR_E; case SouthWestGravity: return DIR_SW; case SouthGravity: return DIR_S; case SouthEastGravity: return DIR_SE; case ForgetGravity: case StaticGravity: default: return DIR_NONE; } } int gravity_dir_to_grav( direction_t dir) { switch (dir) { case DIR_N: return NorthGravity; case DIR_E: return EastGravity; case DIR_S: return SouthGravity; case DIR_W: return WestGravity; case DIR_NE: return NorthEastGravity; case DIR_SE: return SouthEastGravity; case DIR_SW: return SouthWestGravity; case DIR_NW: return NorthWestGravity; case DIR_NONE: default: return ForgetGravity; } } int gravity_combine_xy_grav( int grav_x, int grav_y) { switch (grav_x) { case NorthWestGravity: case WestGravity: case SouthWestGravity: grav_x = WestGravity; break; case NorthEastGravity: case EastGravity: case SouthEastGravity: grav_x = EastGravity; break; default: grav_x = CenterGravity; break; } switch (grav_y) { case NorthWestGravity: case NorthGravity: case NorthEastGravity: grav_y = NorthGravity; break; case SouthWestGravity: case SouthGravity: case SouthEastGravity: grav_y = SouthGravity; break; default: grav_y = CenterGravity; break; } if (grav_x == CenterGravity) { return grav_y; } switch (grav_y) { case NorthGravity: return (grav_x == WestGravity) ? NorthWestGravity : NorthEastGravity; case SouthGravity: return (grav_x == WestGravity) ? SouthWestGravity : SouthEastGravity; case CenterGravity: default: return grav_x; } return 0; } void gravity_split_xy_grav( int *ret_grav_x, int *ret_grav_y, int in_grav) { switch (in_grav) { case NorthWestGravity: case WestGravity: case SouthWestGravity: *ret_grav_x = WestGravity; break; case NorthEastGravity: case EastGravity: case SouthEastGravity: *ret_grav_x = EastGravity; break; case NorthGravity: case CenterGravity: case SouthGravity: case ForgetGravity: case StaticGravity: default: *ret_grav_x = CenterGravity; break; } switch (in_grav) { case NorthWestGravity: case NorthGravity: case NorthEastGravity: *ret_grav_y = NorthGravity; break; case SouthWestGravity: case SouthGravity: case SouthEastGravity: *ret_grav_y = SouthGravity; break; case WestGravity: case CenterGravity: case EastGravity: case ForgetGravity: case StaticGravity: default: *ret_grav_y = CenterGravity; break; } } int gravity_combine_xy_dir( int dir_x, int dir_y) { switch (dir_x) { case DIR_W: case DIR_NW: case DIR_SW: dir_x = DIR_W; break; case DIR_E: case DIR_NE: case DIR_SE: dir_x = DIR_E; break; default: dir_x = DIR_NONE; break; } switch (dir_y) { case DIR_N: case DIR_NW: case DIR_NE: dir_y = DIR_N; break; case DIR_S: case DIR_SW: case DIR_SE: dir_y = DIR_S; break; default: dir_y = DIR_NONE; break; } if (dir_x == DIR_NONE) { return dir_y; } switch (dir_y) { case DIR_N: return (dir_x == DIR_W) ? DIR_NW : DIR_NE; case DIR_S: return (dir_x == DIR_W) ? DIR_SW : DIR_SE; case DIR_NONE: default: return dir_x; } } void gravity_split_xy_dir( int *ret_dir_x, int *ret_dir_y, int in_dir) { switch (in_dir) { case DIR_W: case DIR_SW: case DIR_NW: *ret_dir_x = DIR_W; break; case DIR_E: case DIR_NE: case DIR_SE: *ret_dir_x = DIR_E; break; case DIR_N: case DIR_S: case DIR_NONE: default: *ret_dir_x = DIR_NONE; break; } switch (in_dir) { case DIR_N: case DIR_NW: case DIR_NE: *ret_dir_y = DIR_N; break; case DIR_S: case DIR_SW: case DIR_SE: *ret_dir_y = DIR_S; break; case DIR_W: case DIR_E: case DIR_NONE: default: *ret_dir_y = DIR_NONE; break; } } static inline int __gravity_override_one_axis(int dir_orig, int dir_mod) { int ret_dir; if (dir_mod == DIR_NONE) { ret_dir = dir_orig; } else { ret_dir = dir_mod; } return ret_dir; } int gravity_override_dir( int dir_orig, int dir_mod) { int ret_dir; int ret_x; int ret_y; int orig_x; int orig_y; int mod_x; int mod_y; gravity_split_xy_dir(&orig_x, &orig_y, dir_orig); gravity_split_xy_dir(&mod_x, &mod_y, dir_mod); ret_x = __gravity_override_one_axis(orig_x, mod_x); ret_y = __gravity_override_one_axis(orig_y, mod_y); ret_dir = gravity_combine_xy_dir(ret_x, ret_y); return ret_dir; } int gravity_dir_to_sign_one_axis( direction_t dir) { switch (dir) { case DIR_N: case DIR_W: return -1; case DIR_S: case DIR_E: return 1; default: return 0; } } /* Parses the next token in action and returns * * 0 if it is N, North, Top or Up * 1 if it is E, East, Right or Right * 2 if it is S, South, Bottom or Down * 3 if it is E, West, Left or Left * 4 if it is NE, NorthEast, TopRight or UpRight * 5 if it is SE, SouthEast, BottomRight or DownRight * 6 if it is SW, SouthWest, BottomLeft or DownLeft * 7 if it is NW, NorthWest, TopLeft or UpLeft * 8 if it is C, Center or Centre * default_ret if no string matches. * * A pointer to the first character in action behind the token is returned * through ret_action in this case. ret_action may be NULL. If the token * matches none of these strings the default_ret value is returned and the * action itself is passed back in ret_action. */ direction_t gravity_parse_dir_argument( char *action, char **ret_action, direction_t default_ret) { int index; int rc; char *next; next = GetNextTokenIndex(action, gravity_dir_optlist, 0, &index); if (index == -1) { /* nothing selected, use default and don't modify action */ rc = default_ret; next = action; } else { rc = index / STRINGS_PER_DIR; } if (ret_action) { *ret_action = next; } return (direction_t)rc; } char *gravity_dir_to_string(direction_t dir, char *default_str) { char *str = NULL; int d = dir * STRINGS_PER_DIR; if (d >= sizeof(gravity_dir_optlist)/sizeof(gravity_dir_optlist[0])) { return default_str; } str = gravity_dir_optlist[d]; if (str == NULL) { return default_str; } return str; } multi_direction_t gravity_parse_multi_dir_argument( char *action, char **ret_action) { int rc = MULTI_DIR_NONE; char *token, *str; direction_t dir = gravity_parse_dir_argument(action, ret_action, -1); if (dir != -1) { rc = (1 << dir); } else { token = PeekToken(action, &str); if (StrEquals(token, "all")) { rc = MULTI_DIR_ALL; *ret_action = str; } else { rc = MULTI_DIR_NONE; } } return (multi_direction_t)rc; } void gravity_get_next_multi_dir(int dir_set, multi_direction_t *dir) { if (*dir == MULTI_DIR_NONE) { *dir = MULTI_DIR_FIRST; if (dir_set & *dir) { return; } } while(*dir != MULTI_DIR_LAST) { *dir = (*dir << 1); if (dir_set & *dir) { return; } } *dir = MULTI_DIR_NONE; return; } direction_t gravity_multi_dir_to_dir(multi_direction_t mdir) { direction_t dir = DIR_NONE; for ( ; mdir != 0; dir++) { mdir = (mdir >> 1); } if (dir > DIR_ALL_MASK) { dir = DIR_NONE; } return dir; } void gravity_rotate_xy(rotation_t rot, int x, int y, int *ret_x, int *ret_y) { int tx; int ty; switch (rot) { case ROTATION_90: /* CW */ tx = -y; ty = x; break; case ROTATION_180: tx = -x; ty = -y; break; case ROTATION_270: /* CCW */ tx = y; ty = -x; break; default: case ROTATION_0: tx = x; ty = y; break; } *ret_x = tx; *ret_y = ty; return; } rotation_t gravity_add_rotations(rotation_t rot1, rotation_t rot2) { rotation_t rot; rot = ((rot1 + rot2) & ROTATION_MASK); return rot; } fvwm-2.6.7/libs/lang-strings.h0000644000175700017570000000112712773467232013174 00000000000000/* -*-c-*- */ /* * Please translate the strings into the language which you use for * your pop-up menus. * * Some decisions about where a function is prohibited (based on * mwm-function-hints) is based on a string comparison between the * menu item and the strings below. */ #define MOVE_STRING "move" #define RESIZE_STRING1 "size" #define RESIZE_STRING2 "resize" #define MINIMIZE_STRING "minimize" #define MINIMIZE_STRING2 "iconify" #define MAXIMIZE_STRING "maximize" #define CLOSE_STRING1 "close" #define CLOSE_STRING2 "delete" #define CLOSE_STRING3 "destroy" #define CLOSE_STRING4 "quit" fvwm-2.6.7/libs/Ficonv.c0000644000175700017570000003255213003342500011762 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ /* 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 */ /* Some code (convert_charsets) inspired by the glib-2 (gutf8.c) copyrighted * by Tom Tromey & Red Hat, Inc. */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "FlocaleCharset.h" #include "Ficonv.h" #include "Strings.h" #if FiconvSupport #include #if defined(USE_LIBICONV) && !defined (_LIBICONV_H) #error libiconv in use but included iconv.h not from libiconv #endif #if !defined(USE_LIBICONV) && defined (_LIBICONV_H) && defined (LIBICONV_PLUG) #error libiconv not in use but included iconv.h is from libiconv #endif #endif /* FiconvSupport */ /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static Bool FiconvInitialized = False; static FlocaleCharset *FLCIconvUtf8Charset = NULL; /* UTF-8 charset */ static FlocaleCharset *FLCIconvDefaultCharset = NULL; static int do_transliterate_utf8 = 0; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static Bool is_iconv_supported(char *c1, char *c2) { Ficonv_t cd1,cd2; Bool r = False; if (!FiconvSupport || !c1 || !c2) return False; cd1 = Ficonv_open(c1, c2); cd2 = Ficonv_open(c2, c1); if (cd1 != (Ficonv_t) -1 && cd2 != (Ficonv_t) -1) r = True; if (cd1 != (Ficonv_t) -1) (void)Ficonv_close(cd1); if (cd2 != (Ficonv_t) -1) (void)Ficonv_close(cd2); return r; } #define TRANSLIT_SUFFIX "//TRANSLIT" static char *translit_csname(char *cs) { return CatString2(cs, TRANSLIT_SUFFIX); } static int is_translit_supported(char *c1, char *c2) { Ficonv_t cd; if (!FiconvSupport || !c1 || !c2) return 0; cd = Ficonv_open(translit_csname(c1),c2); if (cd == (Ficonv_t) -1) { return 0; } (void)Ficonv_close(cd); cd = Ficonv_open(translit_csname(c2),c1); if (cd == (Ficonv_t) -1) { return 0; } (void)Ficonv_close(cd); return 1; } static int set_default_iconv_charsets(FlocaleCharset *fc) { int i=0,j=0; if (!FiconvSupport || FLCIconvUtf8Charset == NULL || fc == NULL) return False; while(FLC_GET_LOCALE_CHARSET(FLCIconvUtf8Charset,i) != NULL) { j = 0; while(FLC_GET_LOCALE_CHARSET(fc,j) != NULL) { if (is_iconv_supported( FLC_GET_LOCALE_CHARSET( FLCIconvUtf8Charset,i), FLC_GET_LOCALE_CHARSET(fc,j))) { FLC_SET_ICONV_INDEX(FLCIconvUtf8Charset,i); FLC_SET_ICONV_INDEX(fc,j); if (is_translit_supported( FLC_GET_LOCALE_CHARSET( FLCIconvUtf8Charset,i), FLC_GET_LOCALE_CHARSET(fc,j))) { FLC_SET_ICONV_TRANSLIT_CHARSET( fc, safestrdup(translit_csname( FLC_GET_LOCALE_CHARSET( fc,j)))); } else { FLC_SET_ICONV_TRANSLIT_CHARSET( fc, FLC_TRANSLIT_NOT_SUPPORTED); } return 1; } j++; } i++; } FLC_SET_ICONV_INDEX(FLCIconvUtf8Charset, FLC_INDEX_ICONV_CHARSET_NOT_FOUND); FLC_SET_ICONV_INDEX(fc, FLC_INDEX_ICONV_CHARSET_NOT_FOUND); return 0; } static void set_iconv_charset_index(FlocaleCharset *fc) { int i = 0; if (!FiconvSupport || fc == NULL) return; if (FLC_DO_ICONV_CHARSET_INITIALIZED(fc)) return; /* already set */ if (FLCIconvUtf8Charset == NULL || !FLC_DO_ICONV_CHARSET_INITIALIZED(FLCIconvUtf8Charset)) { FLC_SET_ICONV_INDEX(fc, FLC_INDEX_ICONV_CHARSET_NOT_FOUND); return; } while(FLC_GET_LOCALE_CHARSET(fc,i) != NULL) { if (is_iconv_supported( FLC_GET_ICONV_CHARSET(FLCIconvUtf8Charset), FLC_GET_LOCALE_CHARSET(fc,i))) { FLC_SET_ICONV_INDEX(fc,i); if (is_translit_supported( FLC_GET_ICONV_CHARSET(FLCIconvUtf8Charset), FLC_GET_LOCALE_CHARSET(fc,i))) { FLC_SET_ICONV_TRANSLIT_CHARSET( fc, safestrdup( translit_csname( FLC_GET_LOCALE_CHARSET( fc,i)))); } else { FLC_SET_ICONV_TRANSLIT_CHARSET( fc, FLC_TRANSLIT_NOT_SUPPORTED); } return; } i++; } FLC_SET_ICONV_INDEX(fc, FLC_INDEX_ICONV_CHARSET_NOT_FOUND); } static char *convert_charsets(const char *in_charset, const char *out_charset, const char *in, unsigned int in_size) { static int error_count = 0; Ficonv_t cd; int have_error = 0; int is_finished = 0; size_t nconv; size_t insize,outbuf_size,outbytes_remaining,len; const char *inptr; char *dest; char *outp; if (in == NULL || !FiconvSupport) return NULL; cd = Ficonv_open(out_charset, in_charset); if (cd == (Ficonv_t) -1) { /* Something went wrong. */ if (error_count > FICONV_CONVERSION_MAX_NUMBER_OF_WARNING) return NULL; error_count++; if (errno == EINVAL) { fprintf( stderr, "[fvwm][convert_charsets]: WARNING -\n\t"); fprintf( stderr, "conversion from `%s' to `%s' not available\n", in_charset,out_charset); } else { fprintf( stderr, "[fvwm][convert_charsets]: WARNING -\n\t"); fprintf( stderr, "conversion from `%s' to `%s' fail (init)\n", in_charset,out_charset); } /* Terminate the output string. */ return NULL; } /* in maybe a none terminate string */ len = in_size; outbuf_size = len + 1; outbytes_remaining = outbuf_size - 1; insize = len; outp = dest = safemalloc(outbuf_size); inptr = in; for (is_finished = 0; is_finished == 0; ) { SUPPRESS_UNUSED_VAR_WARNING(inptr); SUPPRESS_UNUSED_VAR_WARNING(insize); SUPPRESS_UNUSED_VAR_WARNING(outbytes_remaining); nconv = Ficonv( cd, (ICONV_ARG_CONST char **)&inptr, &insize, &outp, &outbytes_remaining); is_finished = 1; if (nconv == (size_t) - 1) { switch (errno) { case EINVAL: /* Incomplete text, do not report an error */ break; case E2BIG: { size_t used = outp - dest; outbuf_size *= 2; dest = realloc (dest, outbuf_size); outp = dest + used; /* -1 for nul */ outbytes_remaining = outbuf_size - used - 1; is_finished = 0; break; } #ifdef EILSEQ case EILSEQ: /* Something went wrong. */ if (error_count <= FICONV_CONVERSION_MAX_NUMBER_OF_WARNING) { fprintf( stderr, "[fvwm][convert_charsets]:" " WARNING -\n\t"); fprintf( stderr, "Invalid byte sequence during" " conversion from %s to %s\n", in_charset,out_charset); } have_error = 1; break; #endif default: if (error_count <= FICONV_CONVERSION_MAX_NUMBER_OF_WARNING) { fprintf( stderr, "[fvwm][convert_charsets]:" " WARNING -\n\t"); fprintf( stderr, "Error during conversion from" " %s to %s\n", in_charset, out_charset); } have_error = 1; break; } } } /* Terminate the output string */ *outp = '\0'; if (Ficonv_close (cd) != 0) { fprintf( stderr, "[fvwm][convert_charsets]: WARNING - iconv_close" " fail\n"); } if (have_error) { error_count++; free (dest); return NULL; } else { return dest; } } static void FiconvInit(Display *dpy, const char *module) { int suc = False; if (!FiconvSupport || FiconvInitialized) return; FiconvInitialized = True; FlocaleCharsetInit(dpy, module); FLCIconvUtf8Charset = FlocaleCharsetGetUtf8Charset(); FLCIconvDefaultCharset = FlocaleCharsetGetFLCXOMCharset(); suc = set_default_iconv_charsets(FLCIconvDefaultCharset); if (!suc) { FLCIconvDefaultCharset = FlocaleCharsetGetLocaleCharset(); suc = set_default_iconv_charsets(FLCIconvDefaultCharset); } if (!suc) { fprintf(stderr, "[%s][FiconvInit]: WARN -- Cannot get default " "iconv charset for default charsets '%s' and '%s'\n", module, FLC_DEBUG_GET_X_CHARSET( FlocaleCharsetGetFLCXOMCharset()), FLC_DEBUG_GET_X_CHARSET(FLCIconvDefaultCharset)); FLCIconvUtf8Charset = NULL; FLCIconvDefaultCharset = NULL; } #if FLOCALE_DEBUG_CHARSET fprintf(stderr,"[FiconvInit] iconv charset: x:%s, iconv:%s\n", FLC_DEBUG_GET_X_CHARSET(FLCIconvDefaultCharset), FLC_DEBUG_GET_ICONV_CHARSET(FLCIconvDefaultCharset)); fprintf(stderr,"[FiconvInit] UTF-8 charset: x:%s, iconv:%s\n", FLC_DEBUG_GET_X_CHARSET(FLCIconvUtf8Charset), FLC_DEBUG_GET_ICONV_CHARSET(FLCIconvUtf8Charset)); #endif } static FlocaleCharset *FiconvSetupConversion(Display *dpy, FlocaleCharset *fc) { FlocaleCharset *my_fc = NULL; if (!FiconvSupport) { return NULL; } if (!FiconvInitialized) { FiconvInit(dpy, "fvwm"); } if (FLCIconvUtf8Charset == NULL) { return NULL; } if (fc == NULL) { my_fc = FLCIconvDefaultCharset; if (my_fc == NULL) { return NULL; } } else { my_fc = fc; } if (!FLC_DO_ICONV_CHARSET_INITIALIZED(my_fc)) { set_iconv_charset_index(my_fc); #if FLOCALE_DEBUG_CHARSET fprintf(stderr, "[Flocale] set up iconv charset: " "x: %s, iconv: %s\n", FLC_DEBUG_GET_X_CHARSET(my_fc), FLC_DEBUG_GET_ICONV_CHARSET(my_fc)); #endif if (!FLC_HAVE_ICONV_CHARSET(my_fc)) { fprintf( stderr, "[fvwmlibs] cannot get iconv converter " "for charset %s\n", FLC_DEBUG_GET_X_CHARSET(my_fc)); return NULL; } } if (!FLC_HAVE_ICONV_CHARSET(my_fc)) { return NULL; } return my_fc; } /* ---------------------------- interface functions ------------------------ */ /* set transliteration state */ void FiconvSetTransliterateUtf8(int toggle) { switch (toggle) { case -1: do_transliterate_utf8 ^= 1; break; case 0: case 1: do_transliterate_utf8 = toggle; break; default: do_transliterate_utf8 = 0; } } /* conversion from UTF8 to the "current" charset */ char *FiconvUtf8ToCharset(Display *dpy, FlocaleCharset *fc, const char *in, unsigned int in_size) { char *out = NULL; FlocaleCharset *my_fc = NULL; if (!FiconvSupport) { return NULL; } my_fc = FiconvSetupConversion(dpy, fc); if (my_fc == NULL) { return NULL; } #if FLOCALE_DEBUG_ICONV fprintf(stderr, "[FiconvUtf8ToCharset] conversion from %s to %s\n", FLC_DEBUG_GET_ICONV_CHARSET(FLCIconvUtf8Charset), FLC_DEBUG_GET_ICONV_CHARSET(my_fc)); #endif if (FLC_ENCODING_TYPE_IS_UTF_8(my_fc)) { /* in can be a none terminate string so do not use CopyString */ out = safemalloc(in_size+1); strncpy(out, in, in_size); out[in_size]=0; } else { char *to_cs; if (do_transliterate_utf8 && FLC_IS_TRANSLIT_SUPPORTED(my_fc)) { to_cs = FLC_GET_ICONV_TRANSLIT_CHARSET(my_fc); } else { to_cs = FLC_GET_ICONV_CHARSET(my_fc); } out = convert_charsets( FLC_GET_ICONV_CHARSET(FLCIconvUtf8Charset), to_cs, in, in_size); } return out; } /* conversion from the current charset to UTF8 */ char *FiconvCharsetToUtf8(Display *dpy, FlocaleCharset *fc, const char *in, unsigned int in_size) { char *out = NULL; FlocaleCharset *my_fc = NULL; if (!FiconvSupport) { return NULL; } my_fc = FiconvSetupConversion(dpy, fc); if (my_fc == NULL) { return NULL; } #if FLOCALE_DEBUG_ICONV fprintf(stderr, "[FiconvCharsetToUtf8] conversion from %s to %s\n", FLC_DEBUG_GET_ICONV_CHARSET(my_fc), FLC_DEBUG_GET_ICONV_CHARSET(FLCIconvUtf8Charset)); #endif if (FLC_ENCODING_TYPE_IS_UTF_8(my_fc)) { /* in can be a non terminate string so do not use CopyString */ out = safemalloc(in_size+1); strncpy(out, in, in_size); out[in_size]=0; } else { out = convert_charsets( FLC_GET_ICONV_CHARSET(my_fc), FLC_GET_ICONV_CHARSET(FLCIconvUtf8Charset), in, in_size); } return out; } /* conversion from charset to charset */ char *FiconvCharsetToCharset( Display *dpy, FlocaleCharset *in_fc, FlocaleCharset *out_fc, const char *in, unsigned int in_size) { char *out = NULL; char *tmp = NULL; int tmp_len; Bool free_tmp = False; FlocaleCharset *my_in_fc; FlocaleCharset *my_out_fc; if (!FiconvSupport || (my_in_fc = FiconvSetupConversion(dpy, in_fc)) == NULL) { return NULL; } if (!FiconvSupport || (my_out_fc = FiconvSetupConversion(dpy, out_fc)) == NULL) { return NULL; } tmp = (char *)in; tmp_len = in_size; if (!FLC_ENCODING_TYPE_IS_UTF_8(my_in_fc)) { tmp = FiconvCharsetToUtf8( dpy, my_in_fc, (const char *)in, in_size); if (tmp != NULL) { free_tmp = True; tmp_len = strlen(tmp); } else { /* fail to convert */ return NULL; } } out = tmp; if (!FLC_ENCODING_TYPE_IS_UTF_8(my_out_fc)) { out = FiconvUtf8ToCharset( dpy, my_out_fc, (const char *)tmp, tmp_len); if (free_tmp) { free(tmp); } } return out; } fvwm-2.6.7/libs/XResource.c0000644000175700017570000002122113001406607012453 00000000000000/* -*-c-*- */ /* Copyright (C) 1999 Dominik Vogt */ /* 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 */ /* ** XResource.c: ** These routines provide modules with an interface to parse all kinds of ** configuration options (X resources, command line options and configuration ** file lines) in the same way (Xrm database). */ #include "config.h" #include #include #include "fvwmlib.h" #include "XResource.h" /* * If you have a module MyModule and want to parse X resources as well as * command line options and a config file: * *** EXAMPLE */ #if 0 #include void main(int argc, char **argv) { const char *MyName = "MyModule"; XrmDatabase db = NULL; XrmValue *rm_value; char *line; /* our private options */ const XrmOptionDescRec my_opts[] = { { "-iconic", ".Iconic", XrmoptionNoArg, "any_string" }, { "-foo", "*bar", XrmoptionSepArg, NULL } }; int opt_argc = argc - 6; /* options start at 6th argument for modules */ char **opt_argv = argv + 6; /* ... (open config file, etc.) */ /* Get global X resources */ MergeXResources(NULL, &db, False); /* config file descriptor in fd; config file takes precedence over X * resources (this may not be what you want). */ for (GetConfigLine(fd, &line); line != NULL; GetConfigLine(fd, &line)) { if (!MergeConfigLineResource(&db, line, MyName, '*')) { /* Parse other lines here (e.g. "ImagePath") */ } else { /* You may still have to parse the line here yourself (e.g. * FvwmButtons may have multiple lines for the same resource). */ } } /* command line takes precedence over all */ MergeCmdLineResources(&db, (XrmOptionDescList)my_opts, 2, MyName, &opt_argc, opt_argv, True /*no default options*/); /* Now parse the database values: */ if (GetResourceString(db, "iconic", MyName, &rm_value)) { /* Just see if there is *any* string and don't mind it's value. */ /* flags |= ICONIC */ } if (GetResourceString(db, "bar", MyName, &rm_value)) { /* ... */ } /* ... */ XrmDestroyDatabase(db); } #endif /*** END OF EXAMPLE ***/ /* Default option table */ static XrmOptionDescRec default_opts[] = { { "-fg", "*Foreground", XrmoptionSepArg, NULL }, { "-bg", "*Background", XrmoptionSepArg, NULL }, { "-fn", "*Font", XrmoptionSepArg, NULL }, { "-geometry", "*Geometry", XrmoptionSepArg, NULL }, { "-title", "*Title", XrmoptionSepArg, NULL } /* Remember to update NUM_DEFAULT_OPTIONS if you change this list! */ }; #define NUM_DEFAULT_OPTS 5 /* internal function */ static void DoMergeString(char *resource, XrmDatabase *ptarget, Bool override) { XrmDatabase db; if (!resource) return; db = XrmGetStringDatabase(resource); XrmCombineDatabase(db, ptarget, override); } /* * * Merges all X resources for the display/screen into a Xrm database. * If the database does not exist (*pdb == NULL), a new database is created. * If override is True, existing entries of the same name are overwritten. * * Please remember to destroy the database with XrmDestroyDatabase(*pdb) * if you do not need it amymore. * */ void MergeXResources(Display *dpy, XrmDatabase *pdb, Bool override) { if (!*pdb) /* create new database */ XrmPutStringResource(pdb, "", ""); DoMergeString(XResourceManagerString(dpy), pdb, override); DoMergeString(XScreenResourceString(DefaultScreenOfDisplay(dpy)), pdb, override); } /* * * Parses the command line given through pargc/argv and puts recognized * entries into the Xrm database *pdb (if *pdb is NULL a new database is * created). The caller may provide an option list in XrmOptionDescList * format (see XrmParseCommand manpage) and/or parse only standard options * (fg, bg, geometry, fn, title). User given options have precedence over * standard options which are disabled if fNoDefaults is True. Existing * values are overwritten. * * All recognised options are removed from the command line (*pargc and * argv are updated accordingly). * * Please remember to destroy the database with XrmDestroyDatabase(*pdb) * if you do not need it amymore. * */ void MergeCmdLineResources(XrmDatabase *pdb, XrmOptionDescList opts, int num_opts, char *name, int *pargc, char **argv, Bool fNoDefaults) { if (!name) return; if (opts && num_opts > 0) XrmParseCommand(pdb, opts, num_opts, name, pargc, argv); if (!fNoDefaults) XrmParseCommand(pdb, default_opts, NUM_DEFAULT_OPTS, name, pargc, argv); } /* * * Takes a line from a config file and puts a corresponding value into the * Xrm database *pdb (will be created if *pdb is NULL). 'prefix' is the * name of the module. A specific type of binding in the database must be * provided in bindstr (either "*" or "."). Leading unquoted whitespace are * stripped from value. Existing values in the database are overwritten. * True is returned if the line was indeed merged into the database (i.e. it * had the correct format) or False if not. * * Example: If prefix = "MyModule" and bindstr = "*", the line * * *MyModuleGeometry 80x25+0+0 * * will be put into the database as if you had this line in your .Xdefaults: * * MyModule*Geometry: 80x25+0+0 * * Please remember to destroy the database with XrmDestroyDatabase(*pdb) * if you do not need it amymore. * */ Bool MergeConfigLineResource(XrmDatabase *pdb, char *line, char *prefix, char *bindstr) { int len; char *end; char *value; char *myvalue; char *resource; /* translate "*(prefix)(suffix)" to "(prefix)(binding)(suffix)", * e.g. "*FvwmPagerGeometry" to "FvwmPager.Geometry" */ if (!line || *line != '*') return False; line++; len = (prefix) ? strlen(prefix) : 0; if (!prefix || strncasecmp(line, prefix, len)) return False; line += len; end = line; while (*end && !isspace((unsigned char)*end)) end++; if (line == end) return False; value = end; while (*value && isspace((unsigned char)*value)) value++; /* prefix*suffix: value */ resource = (char *)safemalloc(len + (end - line) + 2); strcpy(resource, prefix); strcat(resource, bindstr); strncat(resource, line, end - line); len = strlen(value); myvalue = (char *)safemalloc(len + 1); strcpy(myvalue, value); for (len--; len >= 0 && isspace((unsigned char)myvalue[len]); len--) myvalue[len] = 0; /* merge string into database */ XrmPutStringResource(pdb, resource, myvalue); free(resource); free(myvalue); return True; } /* * * Reads the string-value for the pair prefix/resource from the Xrm database * db and returns a pointer to it. The string may only be read and must not * be freed by the caller. 'prefix' is the class name (usually the name of * the module). If no value is found in the database, *val will be NULL. * True is returned if a value was found, False if not. If you are only * interested if there is a string, but not it's value, you can set val to * NULL. * * Example: * * GetResourceString(db, "Geometry", "MyModule", &r) * * returns the resource value of the "Geometry" resource for MyModule in r. * */ Bool GetResourceString( XrmDatabase db, const char *resource, const char *prefix, XrmValue *xval) { char *str_type; char *name; char *Name; int i; name = (char *)safemalloc(strlen(resource) + strlen(prefix) + 2); Name = (char *)safemalloc(strlen(resource) + strlen(prefix) + 2); strcpy(name, prefix); strcat(name, "."); strcat(name, resource); strcpy(Name, name); if (isupper(name[0])) name[0] = tolower(name[0]); if (islower(Name[0])) Name[0] = toupper(Name[0]); i = strlen(prefix) + 1; if (isupper(name[i])) name[i] = tolower(name[i]); if (islower(Name[i])) Name[i] = toupper(Name[i]); if (!XrmGetResource(db, name, Name, &str_type, xval) || xval->addr == NULL || xval->size == 0) { free(name); free(Name); xval->size = 0; xval->addr = NULL; return False; } free(name); free(Name); return True; } fvwm-2.6.7/libs/fio.h0000644000175700017570000000054712773467232011346 00000000000000/* -*-c-*- */ /* Wrappers for io functions from the standard library that might be * interrupted. These functions are restarted when necessary. */ /* ---------------------------- interface functions ------------------------ */ ssize_t fvwm_send(int s, const void *buf, size_t len, int flags); ssize_t fvwm_recv(int s, void *buf, size_t len, int flags); fvwm-2.6.7/libs/Parse.h0000644000175700017570000000627612773467232011650 00000000000000/* -*-c-*- */ #ifndef FVWMLIB_PARSE_H #define FVWMLIB_PARSE_H /* ---------------------------- included header files ---------------------- */ #include "libs/Strings.h" /* ---------------------------- global definitions ------------------------- */ #define MAX_TOKEN_LENGTH 1023 /* ---------------------------- global macros ------------------------------ */ /* * Stuff for consistent parsing */ #define IsQuote(c) ((c) == '"' || (c) == '\'' || (c) =='`') #define IsBlockStart(c) ((c) == '[' || (c) == '{' || (c) == '(') #define IsBlockEnd(c,cs) (((c) == ']' && (cs) == '[') || ((c) == '}' && (cs) == '{') || ((c) == ')' && (cs) == '(')) /* * function: FindToken * description: find the entry of type 'struct_entry' * holding 'key' in 'table' * returns: pointer to the matching entry * NULL if not found * * table must be sorted in ascending order for FindToken. */ #define FindToken(key,table,struct_entry) \ (struct_entry *) bsearch( \ key, \ (char *)(table), \ sizeof(table) / sizeof(struct_entry), \ sizeof(struct_entry), \ (int(*)(const void*, const void*))XCmpToken) /* ---------------------------- type definitions --------------------------- */ /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ char *EscapeString(char *s, const char *qchars, char echar); char *SkipQuote( char *s, const char *qlong, const char *qstart, const char *qend); char *GetQuotedString( char *sin, char **sout, const char *delims, const char *qlong, const char *qstart, const char *qend); char *SkipSpaces(char *indata, char *spaces, int snum); char *DoPeekToken( char *indata, char **token, char *spaces, char *delims, char *out_delim); char *PeekToken(char *indata, char **token); int MatchToken(char *pstr,char *tok); /* old style parse routine: */ char *DoGetNextToken( char *indata,char **token, char *spaces, char *delims, char *out_delim); char *GetNextToken(char *indata,char **token); char *GetNextSimpleOption(char *indata, char **option); char *GetNextFullOption(char *indata, char **option); char *SkipNTokens(char *indata, unsigned int n); char *GetModuleResource(char *indata, char **resource, char *module_name); int GetSuffixedIntegerArguments( char *action, char **ret_action, int *retvals, int num, char *suffixlist, int *ret_suffixnum); int GetIntegerArgumentsAnyBase( char *action, char **ret_action, int *retvals,int num); int SuffixToPercentValue(int value, int suffix, int *unit_table); int GetIntegerArguments(char *action, char**ret_action, int *retvals,int num); int GetTokenIndex(char *token, char **list, int len, char **next); char *GetNextTokenIndex(char *action, char **list, int len, int *index); int GetRectangleArguments(char *action, int *width, int *height); int GetOnePercentArgument(char *action, int *value, int *unit_io); int GetTwoPercentArguments( char *action, int *val1, int *val2, int *val1_unit, int *val2_unit); int ParseToggleArgument( char *action, char **ret_action, int default_ret, char no_toggle); int XCmpToken(const char *s, const char **t); char *GetFileNameFromPath(char *path); #endif fvwm-2.6.7/libs/WinMagic.c0000644000175700017570000001723212773467232012261 00000000000000/* -*-c-*- */ /* Copyright (C) 1999 Dominik Vogt */ /* 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 */ /* ** WinMagic.c: ** This file supplies routines for moving and resizing windows in an animated ** fashion. */ #include "config.h" #include #include #include #include "WinMagic.h" /* Continuously moves and resized window win from start geometry (s_?) to end * geometry (e_?). Waits for delay_ms milliseconds after each step except the * last (max. 10 seconds per step). The number of steps is determined by the * steps argument (min. 1 and max. 10000). If the pointer ppctMovement is NULL * the steps are all the same width, if it is given it is interpreted as a * pointer to an array of float percent values. These are used to determine the * distance of each step counted from the start position, i.e. 0.0 means the * start position itself, 50.0 is halfway between start and end position and * 100.0 is the end position. Values smaller than 0.0 or bigger than 100.0 are * allowed too. The do_flush flag determines of all requests are sent to the * X server immediately (True) or not (False). The use_hints detrmines if the * min size and resize hints are used */ void SlideWindow( Display *dpy, Window win, int s_x, int s_y, int s_w, int s_h, int e_x, int e_y, int e_w, int e_h, int steps, int delay_ms, float *ppctMovement, Bool do_sync, Bool use_hints) { int x = 0; int y = 0; int w = 0; int h = 0; int g_w = 0; int g_h = 0; /* -Wall fixes :o( */ int min_w = 1; int min_h = 1; int inc_w = 1; int inc_h = 1; int i; unsigned int us; Bool is_mapped; Bool keep_x1 = False; Bool keep_x2 = False; Bool keep_y1 = False; Bool keep_y2 = False; XSizeHints hints; long dummy; /* check limits */ if (delay_ms > 10000) { /* max. 10 seconds per step */ us = 10000000; } else if (delay_ms < 0) { us = 0; } else { us = 1000 * delay_ms; } if (steps > 10000) { /* max. 10000 steps */ steps = 10000; } if (steps <= 0) { /* no steps, no animation */ if (e_w == 0 || e_h == 0) { XUnmapWindow(dpy, win); } else { XMoveResizeWindow(dpy, win, e_x, e_y, e_w, e_h); XMapWindow(dpy, win); XMapSubwindows(dpy, win); } if (do_sync) XSync(dpy, 0); return; } is_mapped = False; /* Get the mini (re)size hints and do some check consistency */ if (use_hints && FGetWMNormalHints(dpy, win, &hints, &dummy)) { if (hints.flags & PMinSize) { if (hints.min_width >= 1 && hints.min_width <= max(e_w,s_w)) min_w = hints.min_width; if (hints.min_height >= 1 && hints.min_height <= max(e_h,s_h)) min_h = hints.min_height; } if (hints.flags & PResizeInc) { if (hints.width_inc >= 1 && hints.width_inc <= max(e_w,s_w)) inc_w = hints.width_inc; if (hints.height_inc >= 1 && hints.width_inc <= max(e_h,s_h)) inc_h = hints.height_inc; } } if (s_x == e_x) keep_x1 = True; if (s_y == e_y) keep_y1 = True; if (s_x + s_w == e_x + e_w) keep_x2 = True; if (s_y + s_h == e_y + e_h) keep_y2 = True; /* animate the window */ for (i = 0; i <= steps; i++) { if (i == steps) { x = e_x; y = e_y; } else { float f; if (ppctMovement == NULL) { f = (float)i / (float)steps; } else { f = ppctMovement[i] / (float)steps; } x = (int)((float)s_x + (float)(e_x - s_x) * f); y = (int)((float)s_y + (float)(e_y - s_y) * f); } w = s_w + (int)(e_w - s_w) * i / steps; h = s_h + (int)(e_h - s_h) * i / steps; /* take the resize inc in account */ g_w = w - ((w - min_w) % inc_w); x += w-g_w; g_h = h - ((h - min_h) % inc_h); y += h-g_h; /* prevent annoying flickering */ if (keep_x1) x = s_x; if (keep_y1) y = s_y; if (keep_x2) g_w = s_x + s_w - x; if (keep_y2) g_h = s_y + s_h - y; if (g_w < min_w || g_h < min_h) { /* don't show zero width/height windows */ if (is_mapped) { XUnmapWindow(dpy, win); is_mapped = False; } } else { XMoveResizeWindow(dpy, win, x, y, g_w, g_h); if (!is_mapped) { XMapWindow(dpy, win); XMapSubwindows(dpy, win); is_mapped = True; } } /* make sure everything is updated */ if (do_sync) XSync(dpy, 0); if (us && i < steps && is_mapped) { /* don't sleep after the last step */ usleep(us); } } /* for */ /* if hints and asked size do not agree try to respect the caller */ if (e_w > 0 && e_h > 0 && (!is_mapped || g_w != w || g_h != w)) { XMoveResizeWindow(dpy, win, x, y, w, h); if (!is_mapped) { XMapWindow(dpy, win); XMapSubwindows(dpy, win); } if (do_sync) XSync(dpy, 0); } return; } /* This function returns the top level ancestor of the window 'child'. It * returns None if an error occurs or if the window is a top level window. */ Window GetTopAncestorWindow(Display *dpy, Window child) { Window root = None; Window ancestor = child; Window last_child = child; Window *children; unsigned int nchildren; if (child == None) return None; while (ancestor != root) { last_child = ancestor; children = NULL; if ( !XQueryTree( dpy, last_child, &root, &ancestor, &children, &nchildren)) { return None; } if (children) { XFree(children); } } return (last_child == child) ? None : last_child; } /* Given a parent window this function returns a list of children of the * parent window that have the same size, depth, visual and colormap as the * parent window and that have position +0+0 within the parent. If the 'depth' * argument is non-zero it must match the depth of the window. The 'visualid' * and 'colormap' arguments work just the same. The number of matching * children is returned. The list of children is returned in *children. If this * list is non-NULL, it must be free'd with XFree. If an error occurs or the * parent window does not match the required depth, colormap or visualid, the * function returns -1 and NULL in *children. */ int GetEqualSizeChildren( Display *dpy, Window parent, int depth, VisualID visualid, Colormap colormap, Window **ret_children) { XWindowAttributes pxwa; XWindowAttributes cxwa; Window JunkW; Window *children; unsigned int nchildren; int i; int j; if (!XGetWindowAttributes(dpy, parent, &pxwa)) return -1; if (!XQueryTree(dpy, parent, &JunkW, &JunkW, &children, &nchildren)) return -1; if (depth && pxwa.depth != depth) return -1; if (visualid && XVisualIDFromVisual(pxwa.visual) != visualid) return -1; if (colormap && pxwa.colormap != colormap) return -1; for (i = 0, j = 0; i < nchildren; i++) { if (XGetWindowAttributes(dpy, children[i], &cxwa) && cxwa.x == 0 && cxwa.y == 0 && cxwa.width == pxwa.width && cxwa.height == pxwa.height && (!depth || cxwa.depth == depth) && ( !visualid || XVisualIDFromVisual(cxwa.visual) == visualid) && cxwa.class == InputOutput && (!colormap || cxwa.colormap == colormap)) { children[j++] = children[i]; } } /* for */ if (j == 0) { if (children) { XFree(children); children = NULL; } } *ret_children = children; return j; } fvwm-2.6.7/libs/FShape.h0000644000175700017570000001255312773467232011737 00000000000000/* -*-c-*- */ /* ** FShape.h: drop in replacements for the X shape library encapsulation */ #ifndef FVWMLIB_FSHAPE_H #define FVWMLIB_FSHAPE_H #ifdef SHAPE #include #define FShapeQueryExtension(dpy, evbase, errbase) \ XShapeQueryExtension(dpy, evbase, errbase) #define FShapeQueryVersion(dpy, vmajor, vminor) \ XShapeQueryVersion(dpy, vmajor, vminor) #define FShapeCombineRegion(dpy, dst, dst_kind, xoff, yoff, reg, op) \ XShapeCombineRegion(dpy, dst, dst_kind, xoff, yoff, reg, op) #define FShapeCombineRectangles( \ dpy, dst, dst_kind, xoff, yoff, rect, n_rects, op, ordering) \ XShapeCombineRectangles( \ dpy, dst, dst_kind, xoff, yoff, rect, n_rects, op, ordering) #define FShapeCombineMask(dpy, dst, dst_kind, xoff, yoff, src, op) \ XShapeCombineMask(dpy, dst, dst_kind, xoff, yoff, src, op) #define FShapeCombineShape(dpy, dst, dst_kind, xoff, yoff, src, src_kind, op) \ XShapeCombineShape(dpy, dst, dst_kind, xoff, yoff, src, src_kind, op) #define FShapeOffsetShape(dpy, dst, dst_kind, xoff, yoff) \ XShapeOffsetShape(dpy, dst, dst_kind, xoff, yoff) #define FShapeQueryExtents( \ dpy, w, bounding_shaped, xb, yb, wb, hb, clip_shaped, \ xclip, yclip, wclip, hclip) \ XShapeQueryExtents( \ dpy, w, bounding_shaped, xb, yb, wb, hb, clip_shaped, \ xclip, yclip, wclip, hclip) #define FShapeSelectInput(dpy, w, mask) \ XShapeSelectInput(dpy, w, mask) #define FShapeInputSelected(dpy, w) \ XShapeInputSelected(dpy, w) #define FShapeGetRectangles(dpy, w, kind, count, ordering) \ XShapeGetRectangles(dpy, w, kind, count, ordering) extern int FShapeEventBase; extern int FShapeErrorBase; /* Shapes compiled in? */ extern Bool FShapesSupported; /* Shapes supported by server? */ #define FHaveShapeExtension 1 void FShapeInit(Display *dpy); #else /* drop in replacements if shape support is not compiled in */ #define X_ShapeQueryVersion 0 #define X_ShapeRectangles 1 #define X_ShapeMask 2 #define X_ShapeCombine 3 #define X_ShapeOffset 4 #define X_ShapeQueryExtents 5 #define X_ShapeSelectInput 6 #define X_ShapeInputSelected 7 #define X_ShapeGetRectangles 8 #define ShapeSet 0 #define ShapeUnion 1 #define ShapeIntersect 2 #define ShapeSubtract 3 #define ShapeInvert 4 #define ShapeBounding 0 #define ShapeClip 1 #define ShapeNotifyMask (1L << 0) #define ShapeNotify 0 #define ShapeNumberEvents (FShapeNotify + 1) typedef struct { int type; /* of event */ unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came frome a SendEvent request */ Display *display; /* Display the event was read from */ Window window; /* window of event */ int kind; /* ShapeBounding or ShapeClip */ int x, y; /* extents of new region */ unsigned width, height; Time time; /* server timestamp when region changed */ Bool shaped; /* true if the region exists */ } XShapeEvent; #define FShapeQueryExtension(dpy, evbase, errbase) ((Bool)False) #define FShapeQueryVersion(dpy, vmajor, vminor) ((Status)0) #define FShapeCombineRegion(dpy, dst, dst_kind, xoff, yoff, reg, op) #define FShapeCombineRectangles( \ dpy, dst, dst_kind, xoff, yoff, rect, n_rects, op, ordering) #define FShapeCombineMask(dpy, dst, dst_kind, xoff, yoff, src, op) #define FShapeCombineShape(dpy, dst, dst_kind, xoff, yoff, src, src_kind, op) #define FShapeOffsetShape(dpy, dst, dst_kind, xoff, yoff) #define FShapeQueryExtents( \ dpy, w, bounding_shaped, xb, yb, wb, hb, clip_shaped, \ xclip, yclip, wclip, hclip) ((Status)0) #define FShapeSelectInput(dpy, w, mask) #define FShapeInputSelected(dpy, w) ((unsinged long)0) #define FShapeGetRectangles(dpy, w, kind, count, ordering) ((XRectangle *)0) /* define empty dummies */ #define FShapeEventBase 0 #define FShapeErrorBase 0 /* Shapes supported by server? */ #define FShapesSupported 0 /* Shapes compiled in? */ #define FHaveShapeExtension 0 #define FShapeInit(dpy) #endif /* fvwm replacements for shape lib */ #define F_ShapeQueryVersion X_ShapeQueryVersion #define F_ShapeRectangles X_ShapeRectangles #define F_ShapeMask X_ShapeMask #define F_ShapeCombine X_ShapeCombine #define F_ShapeOffset X_ShapeOffset #define F_ShapeQueryExtents X_ShapeQueryExtents #define F_ShapeSelectInput X_ShapeSelectInput #define F_ShapeInputSelected X_ShapeInputSelected #define F_ShapeGetRectangles X_ShapeGetRectangles #define FShapeSet ShapeSet #define FShapeUnion ShapeUnion #define FShapeIntersect ShapeIntersect #define FShapeSubtract ShapeSubtract #define FShapeInvert ShapeInvert #define FShapeBounding ShapeBounding #define FShapeClip ShapeClip #define FShapeNotifyMask ShapeNotifyMask #define FShapeNotify ShapeNotify #define FShapeNumberEvents ShapeNumberEvents typedef XShapeEvent FShapeEvent; #endif /* FVWMLIB_FSHAPE_H */ fvwm-2.6.7/libs/PictureGraphics.h0000644000175700017570000001170212773467232013660 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef F_PICTURE_GRAPHICS_H #define F_PICTURE_GRAPHICS_H /* * * dpy: Specifies the connection to the X server. * pixmap: Source pixmap. * mask: Source mask (can be None). * alpha: Source alpha chanel (can be None). * depth: depth of the pixmap (1 or Pdepth). * d: Destination drawable which should be of depth Pdepth. * GC gc: Specifies the a visual GC. * src_x,src_y: Specify the x and y coordinates, which are relative to the * origin of the source pixmap, mask and alpha of the rectangle * which is copied. * src_w,src_h: Width and height of the source rectangle relatively to the * src_x and src_y. * dest_x,dest_y: Specify the x and y coordinates of the destination rectangle, * which are relative to the origin of the drawable d. * */ /* return a pixmap of depth depth which is the copy of the src pixmap of depth * 1 using the gc for the bg and fg colors */ Pixmap PictureBitmapToPixmap( Display *dpy, Window win, Pixmap src, int depth, GC gc, int src_x, int src_y, int src_w, int src_h); /* * PGraphicsRenderPixmaps * * PGraphicsRenderPixmaps copies a rectangle, the src, constituted by a pixmap * with its mask, alpha channel, and rendering attributes to a drawable at a * given position. * */ void PGraphicsRenderPixmaps( Display *dpy, Window win, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, FvwmRenderAttributes *fra, Drawable d, GC gc, GC mono_gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat); /* * PGraphicsRenderPicture * * PGraphicsRenderPicture copies a rectangle, the src, constituted by a picture * and its rendering attributes to a drawable at a given position. * * */ void PGraphicsRenderPicture( Display *dpy, Window win, FvwmPicture *p, FvwmRenderAttributes *fra, Drawable d, GC gc, GC mono_gc, GC alpha_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h, int do_repeat); /* * PGraphicsCopyPixmaps * * PGraphicsCopyPixmaps copies a rectangle constituted by a pixmap with its * mask and alpha channel to a drawable at a given position. * * * The clip_mask, clip_x_origin and clip_y_origin value of the gc are * modified in this function: the clip_mask is set to mask and reseted to None, * clip_x_origin and clip_y_origin are set to src_x and src_y. * The background and foreground value of the gc is important when you render * a bitmap. If the gc is set to None the function create and destroy a gc for * its use. * */ void PGraphicsCopyPixmaps( Display *dpy, Pixmap pixmap, Pixmap mask, Pixmap alpha, int depth, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y); /* * PGraphicsCopyFvwmPicture * * PGraphicsCopyFvwmPicture copies a rectangle constituted by an FvwmPicture * to a drawable at a given position. It is similar to PGraphicsCopyPixmaps * and the same remarks are valids. The only difference is that the source * rectangle is given by the FvwmPicture p (which contains the pixmap, the * mask, the alpha and the depth). * */ void PGraphicsCopyFvwmPicture( Display *dpy, FvwmPicture *p, Drawable d, GC gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y); /* * PGraphicsTileRectangle * * This function is similar to PGraphicsCopyPixmaps. It tiles the rectangle of * the drawable d defined with coordinates dest_x, dest_y, dest_w, dest_h with * the rectangle composed by the pixmap, its mask and its alpha channel. * */ void PGraphicsTileRectangle( Display *dpy, Window win, Pixmap pixmap, Pixmap shape, Pixmap alpha, int depth, Drawable d, GC gc, GC mono_gc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h); FvwmPicture *PGraphicsCreateStretchPicture( Display *dpy, Window win, FvwmPicture *src, int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc); FvwmPicture *PGraphicsCreateTiledPicture( Display *dpy, Window win, FvwmPicture *src, int dest_width, int dest_height, GC gc, GC mono_gc, GC alpha_gc); Pixmap PGraphicsCreateTransparency( Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc, int x, int y, int width, int height, Bool parent_relative); void PGraphicsTintRectangle( Display *dpy, Window win, Pixel tint, int tint_percent, Drawable dest, Bool dest_is_a_window, GC gc, GC mono_gc, GC alpha_gc, int dest_x, int dest_y, int dest_w, int dest_h); /* never used ! */ Pixmap PGraphicsCreateDitherPixmap( Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc, int in_width, int in_height, int out_width, int out_height); #endif fvwm-2.6.7/libs/FRender.h0000644000175700017570000002552112773467232012115 00000000000000/* -*-c-*- */ /* Copyright (C) 2002 Olivier Chapuis */ #ifndef FRENDER_H #define FRENDER_H /* ---------------------------- included header files ---------------------- */ #include "config.h" #include "PictureBase.h" #if XRenderSupport #define Picture XRenderPicture #include #undef Picture #endif /* ---------------------------- global definitions ------------------------- */ /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ #if XRenderSupport typedef XRenderDirectFormat FRenderDirectFormat; typedef PictFormat FRPictFormat; typedef XRenderPictFormat FRenderPictFormat; typedef XRenderPicture FRenderPicture; #if 0 /* this has disappeared */ typedef XRenderVisual FRenderVisual; typedef XRenderDepth FRenderDepth; typedef XRenderInfo FRenderInfo; #endif typedef XRenderPictureAttributes FRenderPictureAttributes; typedef XRenderColor FRenderColor; typedef XGlyphInfo FGlyphInfo; #define FRenderPictFormatID PictFormatID #define FRenderPictFormatType PictFormatType #define FRenderPictFormatDepth PictFormatDepth #define FRenderPictFormatRed PictFormatRed #define FRenderPictFormatRedMask PictFormatRedMask #define FRenderPictFormatGreen PictFormatGreen #define FRenderPictFormatGreenMask PictFormatGreenMask #define FRenderPictFormatBlue PictFormatBlue #define FRenderPictFormatBlueMask PictFormatBlueMask #define FRenderPictFormatAlpha PictFormatAlpha #define FRenderPictFormatAlphaMask PictFormatAlphaMask #define FRenderPictFormatColormap PictFormatColormap #define FRenderBadPictFormat 0 #define FRenderBadPicture 1 #define FRenderBadPictOp 2 #define FRenderBadGlyphSet 3 #define FRenderBadGlyph 4 #define FRenderRenderNumberErrors (FRenderBadGlyph+1) #define FRenderPictTypeIndexed PictTypeIndexed #define FRenderPictTypeDirect PictTypeDirect #define FRenderPictOpMinimum PictOpMinimum #define FRenderPictOpClear PictOpClear #define FRenderPictOpSrc PictOpSrc #define FRenderPictOpDst PictOpDst #define FRenderPictOpOver PictOpOver #define FRenderPictOpOverReverse PictOpOverReverse #define FRenderPictOpIn PictOpIn #define FRenderPictOpInReverse PictOpInReverse #define FRenderPictOpOut PictOpOut #define FRenderPictOpOutReverse PictOpOutReverse #define FRenderPictOpAtop PictOpAtop #define FRenderPictOpAtopReverse PictOpAtopReverse #define FRenderPictOpXor PictOpXor #define FRenderPictOpAdd PictOpAdd #define FRenderPictOpSaturate PictOpSaturate #define FRenderPictOpMaximum PictOpMaximum /* * Operators only available in version 0.2 */ #if 0 #define FRenderPictOpDisjointMinimum PictOpDisjointMinimum #define FRenderPictOpDisjointClear PictOpDisjointClear #define FRenderPictOpDisjointSrc PictOpDisjointSrc #define FRenderPictOpDisjointDst PictOpDisjointDst #define FRenderPictOpDisjointOver PictOpDisjointOver #define FRenderPictOpDisjointOverReverse PictOpDisjointOverReverse #define FRenderPictOpDisjointIn PictOpDisjointIn #define FRenderPictOpDisjointInReverse PictOpDisjointInReverse #define FRenderPictOpDisjointOut PictOpDisjointOut #define FRenderPictOpDisjointOutReverse PictOpDisjointOutReverse #define FRenderPictOpDisjointAtop PictOpDisjointAtop #define FRenderPictOpDisjointAtopReverse PictOpDisjointAtopReverse #define FRenderPictOpDisjointXor PictOpDisjointXor #define FRenderPictOpDisjointMaximum PictOpDisjointMaximum #define FRenderPictOpConjointMinimum PictOpConjointMinimum #define FRenderPictOpConjointClear PictOpConjointClear #define FRenderPictOpConjointSrc PictOpConjointSrc #define FRenderPictOpConjointDst PictOpConjointDst #define FRenderPictOpConjointOver PictOpConjointOver #define FRenderPictOpConjointOverReverse PictOpConjointOverReverse #define FRenderPictOpConjointIn PictOpConjointIn #define FRenderPictOpConjointInReverse PictOpConjointInReverse #define FRenderPictOpConjointOut PictOpConjointOut #define FRenderPictOpConjointOutReverse PictOpConjointOutReverse #define FRenderPictOpConjointAtop PictOpConjointAtop #define FRenderPictOpConjointAtopReverse PictOpConjointAtopReverse #define FRenderPictOpConjointXor PictOpConjointXor #define FRenderPictOpConjointMaximum PictOpConjointMaximum #endif /* 0 */ #define FRenderPolyEdgeSharp PolyEdgeSharp #define FRenderPolyEdgeSmooth PolyEdgeSmooth #define FRenderPolyModePrecise #define FRenderPolyModeImprecise #define FRenderCPRepeat CPRepeat #define FRenderCPAlphaMap CPAlphaMap #define FRenderCPAlphaXOrigin CPAlphaXOrigin #define FRenderCPAlphaYOrigin CPAlphaYOrigin #define FRenderCPClipXOrigin CPClipXOrigin #define FRenderCPClipYOrigin CPClipYOrigin #define FRenderCPClipMask CPClipMask #define FRenderCPGraphicsExposure CPGraphicsExposure #define FRenderCPSubwindowMode CPSubwindowMode #define FRenderCPPolyEdge CPPolyEdge #define FRenderCPPolyMode CPPolyMode #define FRenderCPDither CPDither #define FRenderCPComponentAlpha CPComponentAlpha #define FRenderCPLastBit CPLastBit #define FRenderQueryExtension(a,b,c) XRenderQueryExtension(a,b,c) #define FRenderQueryVersion(a,b,c) XRenderQueryVersion(a,b,c) #define FRenderQueryFormats(a) XRenderQueryFormats(a) #define FRenderFindVisualFormat(a,b) XRenderFindVisualFormat(a,b) #define FRenderFindFormat(a,b,c,d) XRenderFindFormat(a,b,c,d) #define FRenderCreatePicture(a,b,c,d,e) XRenderCreatePicture(a,b,c,d,e) #define FRenderChangePicture(a,b,c,d) XRenderChangePicture(a,b,c,d) #define FRenderSetPictureClipRectangles(a,b,c,d,e,f) \ XRenderSetPictureClipRectangles(a,b,c,d,e,f) #define FRenderSetPictureClipRegion(a,b,c) XRenderSetPictureClipRegion(a,b,c) #define FRenderFreePicture(a,b) XRenderFreePicture(a,b) #define FRenderComposite(a,b,c,d,e,f,g,h,i,j,k,l,m) \ XRenderComposite(a,b,c,d,e,f,g,h,i,j,k,l,m) #define FRenderFillRectangle(a,b,c,d,e,f,g,h) \ XRenderFillRectangle(a,b,c,d,e,f,g,h) #define FRenderFillRectangles(a,b,c,d,e,f) XRenderFillRectangles(a,b,c,d,e,f) #else /* !XRenderSupport */ typedef unsigned long FRenderPicture; typedef unsigned long FRPictFormat; typedef struct { short red; short redMask; short green; short greenMask; short blue; short blueMask; short alpha; short alphaMask; } FRenderDirectFormat; typedef struct { FRPictFormat id; int type; int depth; FRenderDirectFormat direct; Colormap colormap; } FRenderPictFormat; typedef struct { Visual *visual; FRenderPictFormat *format; } FRenderVisual; typedef struct { int depth; int nvisuals; FRenderVisual *visuals; } FRenderDepth; typedef struct { FRenderDepth *depths; int ndepths; FRenderPictFormat *fallback; } FRenderScreen; typedef struct _FRenderInfo { FRenderPictFormat *format; int nformat; FRenderScreen *screen; int nscreen; FRenderDepth *depth; int ndepth; FRenderVisual *visual; int nvisual; } FRenderInfo; typedef struct _FRenderPictureAttributes { Bool repeat; FRenderPicture alpha_map; int alpha_x_origin; int alpha_y_origin; int clip_x_origin; int clip_y_origin; Pixmap clip_mask; Bool graphics_exposures; int subwindow_mode; int poly_edge; int poly_mode; Atom dither; Bool component_alpha; } FRenderPictureAttributes; typedef struct { unsigned short red; unsigned short green; unsigned short blue; unsigned short alpha; } FRenderColor; typedef struct _FGlyphInfo { unsigned short width; unsigned short height; short x; short y; short xOff; short yOff; } FGlyphInfo; #define FRenderPictFormatID 0 #define FRenderPictFormatType 0 #define FRenderPictFormatDepth 0 #define FRenderPictFormatRed 0 #define FRenderPictFormatRedMask 0 #define FRenderPictFormatGreen 0 #define FRenderPictFormatGreenMask 0 #define FRenderPictFormatBlue 0 #define FRenderPictFormatBlueMask 0 #define FRenderPictFormatAlpha 0 #define FRenderPictFormatAlphaMask 0 #define FRenderPictFormatColormap 0 #define FRenderBadPictFormat 0 #define FRenderBadPicture 1 #define FRenderBadPictOp 2 #define FRenderBadGlyphSet 3 #define FRenderBadGlyph 4 #define FRenderRenderNumberErrors (FRenderBadGlyph+1) #define FRenderPictTypeIndexed 0 #define FRenderPictTypeDirect 0 #define FRenderPictOpMinimum 0 #define FRenderPictOpClear 0 #define FRenderPictOpSrc 0 #define FRenderPictOpDst 0 #define FRenderPictOpOver 0 #define FRenderPictOpOverReverse 0 #define FRenderPictOpIn 0 #define FRenderPictOpInReverse 0 #define FRenderPictOpOut 0 #define FRenderPictOpOutReverse 0 #define FRenderPictOpAtop 0 #define FRenderPictOpAtopReverse 0 #define FRenderPictOpXor 0 #define FRenderPictOpAdd 0 #define FRenderPictOpSaturate 0 #define FRenderPictOpMaximum 0 /* * Operators only available in version 0.2 */ #if 0 #define FRenderPictOpDisjointMinimum 0 #define FRenderPictOpDisjointClear 0 #define FRenderPictOpDisjointSrc 0 #define FRenderPictOpDisjointDst 0 #define FRenderPictOpDisjointOver 0 #define FRenderPictOpDisjointOverReverse 0 #define FRenderPictOpDisjointIn 0 #define FRenderPictOpDisjointInReverse 0 #define FRenderPictOpDisjointOut 0 #define FRenderPictOpDisjointOutReverse 0 #define FRenderPictOpDisjointAtop 0 #define FRenderPictOpDisjointAtopReverse 0 #define FRenderPictOpDisjointXor 0 #define FRenderPictOpDisjointMaximum 0 #define FRenderPictOpConjointMinimum 0 #define FRenderPictOpConjointClear 0 #define FRenderPictOpConjointSrc 0 #define FRenderPictOpConjointDst 0 #define FRenderPictOpConjointOver 0 #define FRenderPictOpConjointOverReverse 0 #define FRenderPictOpConjointIn 0 #define FRenderPictOpConjointInReverse 0 #define FRenderPictOpConjointOut 0 #define FRenderPictOpConjointOutReverse 0 #define FRenderPictOpConjointAtop 0 #define FRenderPictOpConjointAtopReverse 0 #define FRenderPictOpConjointXor 0 #define FRenderPictOpConjointMaximum 0 #endif #define FRenderPolyEdgeSharp 0 #define FRenderPolyEdgeSmooth 0 #define FRenderPolyModePrecise 0 #define FRenderPolyModeImprecise 0 #define FRenderCPRepeat 0 #define FRenderCPAlphaMap 0 #define FRenderCPAlphaXOrigin 0 #define FRenderCPAlphaYOrigin 0 #define FRenderCPClipXOrigin 0 #define FRenderCPClipYOrigin 0 #define FRenderCPClipMask 0 #define FRenderCPGraphicsExposure 0 #define FRenderCPSubwindowMode 0 #define FRenderCPPolyEdge 0 #define FRenderCPPolyMode 0 #define FRenderCPDither 0 #define FRenderCPComponentAlpha 0 #define FRenderCPLastBit 0 #define FRenderQueryExtension(a,b,c) 0 #define FRenderQueryVersion(a,b,c) 0 #define FRenderQueryFormats(a) 0 #define FRenderFindVisualFormat(a,b) NULL #define FRenderFindFormat(a,b,c,d) NULL #define FRenderCreatePicture(a,b,c,d,e) None #define FRenderChangePicture(a,b,c,d) #define FRenderSetPictureClipRectangles(a,b,c,d,e,f) #define FRenderSetPictureClipRegion(a,b,c) #define FRenderFreePicture(a,b) #define FRenderComposite(a,b,c,d,e,f,g,h,i,j,k,l,m) #define FRenderFillRectangle(a,b,c,d,e,f,g,h) #define FRenderFillRectangles(a,b,c,d,e,f) #endif #endif /* FRENDER_H */ fvwm-2.6.7/libs/Fcursor.h0000644000175700017570000000220512773467232012205 00000000000000#ifndef FCURSOR_H #define FCURSOR_H #ifdef HAVE_XCURSOR # include typedef XcursorImage FcursorImage; typedef XcursorImages FcursorImages; typedef XcursorPixel FcursorPixel; # define FcursorFilenameLoadImages(a,b) XcursorFilenameLoadImages(a,b) # define FcursorGetDefaultSize(a) XcursorGetDefaultSize(a) # define FcursorImageCreate(a,b) XcursorImageCreate(a,b) # define FcursorImageDestroy(a) XcursorImageDestroy(a) # define FcursorImagesDestroy(a) XcursorImagesDestroy(a) # define FcursorImageLoadCursor(a,b) XcursorImageLoadCursor(a,b) # define FcursorImagesLoadCursor(a,b) XcursorImagesLoadCursor(a,b) #else typedef struct { int width; int height; int xhot; int yhot; int delay; void *pixels; } FcursorImage; typedef struct { int nimage; FcursorImage **images; } FcursorImages; typedef void FcursorPixel; # define FcursorFilenameLoadImages(a,b) 0 # define FcursorGetDefaultSize(a) 0 # define FcursorImageCreate(a,b) 0 # define FcursorImageDestroy(a) # define FcursorImagesDestroy(a) # define FcursorImageLoadCursor(a,b) 0 # define FcursorImagesLoadCursor(a,b) 0 #endif #endif /* FCURSOR_H */ fvwm-2.6.7/libs/Event.c0000644000175700017570000000255612773467232011647 00000000000000/* -*-c-*- */ /* Copyright (C) 2001 Dominik Vogt */ /* 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 #include #include "fvwmlib.h" #include "Event.h" /* * Return the subwindow member of an event if the event type has one. */ Window GetSubwindowFromEvent(Display *dpy, const XEvent *eventp) { if (eventp == NULL) { return None; } switch (eventp->type) { case ButtonPress: case ButtonRelease: return eventp->xbutton.subwindow; case KeyPress: case KeyRelease: return eventp->xkey.subwindow; case EnterNotify: case LeaveNotify: return eventp->xcrossing.subwindow; case MotionNotify: return eventp->xmotion.subwindow; default: return None; } } fvwm-2.6.7/modules/0000755000175700017570000000000013010103344011161 500000000000000fvwm-2.6.7/modules/Makefile.am0000644000175700017570000000041512773470550013162 00000000000000## Process this file with automake to create Makefile.in SUBDIRS = \ FvwmAnimate FvwmAuto FvwmBacker FvwmBanner FvwmButtons FvwmCommand \ FvwmConsole FvwmCpp FvwmEvent FvwmForm \ FvwmIconMan FvwmIdent FvwmM4 FvwmPager \ FvwmPerl FvwmProxy FvwmRearrange FvwmScript fvwm-2.6.7/modules/Makefile.in0000644000175700017570000005163513010103323013155 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ SUBDIRS = \ FvwmAnimate FvwmAuto FvwmBacker FvwmBanner FvwmButtons FvwmCommand \ FvwmConsole FvwmCpp FvwmEvent FvwmForm \ FvwmIconMan FvwmIdent FvwmM4 FvwmPager \ FvwmPerl FvwmProxy FvwmRearrange FvwmScript all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmConsole/0000755000175700017570000000000013010103343013422 500000000000000fvwm-2.6.7/modules/FvwmConsole/Makefile.am0000644000175700017570000000150412773470550015424 00000000000000## Process this file with automake to create Makefile.in PERL = @PERL@ moduledir = @FVWM_MODULEDIR@ module_PROGRAMS = FvwmConsole FvwmConsoleC module_SCRIPTS = FvwmConsoleC.pl FvwmConsole_SOURCES = FvwmConsole.c FvwmConsole.h FvwmConsoleC_SOURCES = FvwmConsoleC.c FvwmConsole.h getline.c FvwmConsole_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a FvwmConsoleC_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a man_MANS = FvwmConsole.1 FvwmConsoleC.pl.1 EXTRA_DIST = FvwmConsoleC.pl.in $(man_MANS) Changes .fvwm2rc.sample # Use X_EXTRA_LIBS to get socket(), etc. LDADD = -L$(top_builddir)/libs -lfvwm $(readline_LIBS) $(X_EXTRA_LIBS) # FIXME: # Despite not using X functions explicitly, the code includes # fvwmlib.h, which *does* include X headers and xpm.h! AM_CPPFLAGS = -I$(top_srcdir) $(readline_CFLAGS) $(xpm_CFLAGS) $(X_CFLAGS) fvwm-2.6.7/modules/FvwmConsole/Makefile.in0000644000175700017570000006620613010103323015417 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmConsole$(EXEEXT) FvwmConsoleC$(EXEEXT) subdir = modules/FvwmConsole DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmConsole.1.in $(srcdir)/FvwmConsoleC.pl.1.in \ $(srcdir)/FvwmConsoleC.pl.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmConsole.1 FvwmConsoleC.pl.1 FvwmConsoleC.pl CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(moduledir)" \ "$(DESTDIR)$(man1dir)" PROGRAMS = $(module_PROGRAMS) am_FvwmConsole_OBJECTS = FvwmConsole.$(OBJEXT) FvwmConsole_OBJECTS = $(am_FvwmConsole_OBJECTS) FvwmConsole_LDADD = $(LDADD) am__DEPENDENCIES_1 = am_FvwmConsoleC_OBJECTS = FvwmConsoleC.$(OBJEXT) getline.$(OBJEXT) FvwmConsoleC_OBJECTS = $(am_FvwmConsoleC_OBJECTS) FvwmConsoleC_LDADD = $(LDADD) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } SCRIPTS = $(module_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmConsole_SOURCES) $(FvwmConsoleC_SOURCES) DIST_SOURCES = $(FvwmConsole_SOURCES) $(FvwmConsoleC_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ module_SCRIPTS = FvwmConsoleC.pl FvwmConsole_SOURCES = FvwmConsole.c FvwmConsole.h FvwmConsoleC_SOURCES = FvwmConsoleC.c FvwmConsole.h getline.c FvwmConsole_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a FvwmConsoleC_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a man_MANS = FvwmConsole.1 FvwmConsoleC.pl.1 EXTRA_DIST = FvwmConsoleC.pl.in $(man_MANS) Changes .fvwm2rc.sample # Use X_EXTRA_LIBS to get socket(), etc. LDADD = -L$(top_builddir)/libs -lfvwm $(readline_LIBS) $(X_EXTRA_LIBS) # FIXME: # Despite not using X functions explicitly, the code includes # fvwmlib.h, which *does* include X headers and xpm.h! AM_CPPFLAGS = -I$(top_srcdir) $(readline_CFLAGS) $(xpm_CFLAGS) $(X_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmConsole/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmConsole/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmConsole.1: $(top_builddir)/config.status $(srcdir)/FvwmConsole.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ FvwmConsoleC.pl.1: $(top_builddir)/config.status $(srcdir)/FvwmConsoleC.pl.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ FvwmConsoleC.pl: $(top_builddir)/config.status $(srcdir)/FvwmConsoleC.pl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmConsole$(EXEEXT): $(FvwmConsole_OBJECTS) $(FvwmConsole_DEPENDENCIES) $(EXTRA_FvwmConsole_DEPENDENCIES) @rm -f FvwmConsole$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmConsole_OBJECTS) $(FvwmConsole_LDADD) $(LIBS) FvwmConsoleC$(EXEEXT): $(FvwmConsoleC_OBJECTS) $(FvwmConsoleC_DEPENDENCIES) $(EXTRA_FvwmConsoleC_DEPENDENCIES) @rm -f FvwmConsoleC$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmConsoleC_OBJECTS) $(FvwmConsoleC_LDADD) $(LIBS) install-moduleSCRIPTS: $(module_SCRIPTS) @$(NORMAL_INSTALL) @list='$(module_SCRIPTS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-moduleSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(module_SCRIPTS)'; test -n "$(moduledir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(moduledir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmConsole.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmConsoleC.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-modulePROGRAMS \ install-moduleSCRIPTS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-modulePROGRAMS \ uninstall-moduleSCRIPTS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-modulePROGRAMS install-moduleSCRIPTS install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-man uninstall-man1 \ uninstall-modulePROGRAMS uninstall-moduleSCRIPTS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmConsole/.fvwm2rc.sample0000644000175700017570000000147012673746443016247 00000000000000# open big xterm *FvwmConsoleSubst '^bigx' 'Exec xterm -g 120x60+0+0 -fn 10x20 -fg black -bg lemonchiffon' *FvwmConsoleSubst '^fb' 'FvwmButtons' # jump to desk 0, page 0 , and focus *FvwmConsoleSubst '^g\s*(\d+)' 'Desk 0 0\nGotoPage 0 $1 \nFocus' # open xterm with console *FvwmConsoleSubst '^XC' 'Exec xterm -g 40x6-0+200 -fn 7x14 -C &' # open xterm with console and FvwmConsole - XCF at the begining *FvwmConsoleSubst '^XCF' 'FvwmConsole -C -e /usr/lib/X11/fvwm2/FvwmConsoleC.pl' # list functions *FvwmConsoleKey \mc list_func # execute last command - meta cntrol a *FvwmConsoleKey \m\ca 'prev_line(); enter();' # some common style # substitute BARE with non-word char surrounding it to bare window style *FvwmConsoleSubst '(\W)BARE($|\W)' '$1NoTitle, NoHandles, Sticky, WindowListSkip, Borderwidth 0 ' fvwm-2.6.7/modules/FvwmConsole/FvwmConsole.1.in0000644000175700017570000000641512673746443016335 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH FvwmConsole 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmConsole \- an fvwm command input interface .SH SYNOPSIS Module FvwmConsole [options] \fIFvwmConsole\fP can only be invoked by fvwm. Command line invocation of the \fIFvwmConsole\fP module will not work. .SH DESCRIPTION FvwmConsole allows the user to type fvwm configuration commands interactively, and have them executed immediately. This tool is particularly useful for testing new configuration ideas, or for implementing temporary changes to your environment. .SH INVOCATION FvwmConsole must be spawned as a module by fvwm. FvwmConsole takes all \fIxterm\fP(1) options. .PP FvwmConsole can be invoked by inserting the line 'Module FvwmConsole' in the .fvwm2rc file. This can be placed on a line by itself, if FvwmConsole is to be spawned during fvwm's initialization, or can be bound to a menu or mouse button or keystroke to invoke it later. .SH CONFIGURATION OPTIONS FvwmConsole uses \fIxterm\fP(1). All resources set for xterm are inherited unless overridden by command line options. .RS Module FvwmConsole -g 40x10 -fg black -bg green3 .RE A different terminal emulator can be specified with the -terminal option. However, only terminal programs that understand the options -name, -title and -e can be used. .RS Module FvwmConsole -terminal rxvt .RE Previous versions of FvwmConsole supported a -e option to choose a different front-end. Although this option is still provided for backwards compatibility its use is discouraged unless you know exactly what you are doing. .RS Module FvwmConsole -e FvwmConsoleC.pl .RE (see \fIFvwmConsoleC.pl\fP(1)). .PP Also X resources can be set in your ~/.Xdefaults file: .RS FvwmConsole*VT100*geometry: 40x4 .br FvwmConsole*font: 7x14 .RE .SH "COMMAND EDITING" There are a few options. If the GNU readline library is available, it can be used. .PP If Perl5 is installed, FvwmConsoleC.pl can be used as a command editor. This can be accomplished by either copying FvwmConsoleC.pl to fvwmlib directory as FvwmConsoleC or invoking FvwmConsole with -e option. For example: .RS Module FvwmConsole -e FvwmConsoleC.pl .RE If neither one is installed, a simple input reading function which doesn't have editing capabilities is used. .P GNU readline and FvwmConsoleC.pl have some frequent used commands in common as default. These commands are similar to emacs. For more details, refer GNU readline man and info pages, and FvwmConsoleC.pl man page. .RS .PD 0 .TP 8 Ctrl-A - beginning of line .TP Ctrl-B - previous char .TP Ctrl-D - delete char .TP Ctrl-E - end of line .TP Ctrl-F - next char .TP Ctrl-H - backspace .TP Ctrl-K - erase to the end of line .TP Ctrl-N - next line .TP Ctrl-P - previous line .TP Ctrl-R - search reverse .TP Ctrl-U - delete line .TP Meta-B - previous word .TP Meta-F - next word .TP Esc < - beginning of history .TP Esc > - end of history .RE .PD .SH EXITING FvwmConsole can be stopped by entering the EOF character (usually CTRL-D). .PP \fBNote!\fP Do not use the "quit" command, as this is an fvwm builtin: typing "quit" at the FvwmConsole command line will cause fvwm to exit. .SH SEE ALSO \fIxterm\fP(1), \fIFvwmConsoleC.pl\fP(1), GNU Readline library .SH AUTHOR FvwmConsole is the original work of Toshi Isogai. fvwm-2.6.7/modules/FvwmConsole/FvwmConsoleC.pl.1.in0000644000175700017570000001172512673746443017052 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH FvwmConsoleC.pl 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmConsoleC.pl \- Command editor for fvwm command input interface .SH SYNOPSIS FvwmConsole -e /usr/X11/lib/fvwm/FvwmConsoleC.pl .SH COPYRIGHT Copyright 1996, Toshi Isogai. No guarantees or warranties are provided. Use this program at your own risk. Permission to use this program for any purpose is given, as long as the copyright is kept intact. .SH DESCRIPTION FvwmConsoleC.pl offers editing capabilities while the user is entering the line. By default, the line editing commands are similar to those of emacs. It also offers .B substitution , which replaces a pattern to a string before it sends the command. .SH FUNCTIONS Functions are bound to a key or key combination to be invoked. The followings are functions available and their default key bindings. .RS .IP \fBbind\fP \fIMeta-k, Ctrl-x Ctrl-b\fP .br .\"Bind key to function or bind pattern to string for substitution. List up key bindings and substitutions. .IP \fBboh\fP .br Move to the beginning of history. .IP "\fBboh_ign_mode\fP \fIEsc-<\fP" .br Move to the beginning of history. If it is in search mode, continue. .IP \fBbol\fP \fIHome, Ctrl-a\fP .br Move cursor to the beginning of the line. .IP "\fBbs[(n)]\fP \fIBackSpace, Ctrl-h\fP" .br Backspace n times. default of n is 1. .IP \fBcancel\fP \fICtrl-x Ctrl-k\fP .br Cancel the current input. .IP \fBdel_back_line\fP .br Delete the line from the beginning to the cursor. .IP "\fBdel_back_word\fP \fICtrl-w\fP" .br Delete the word from the beginning to the cursor. .IP "\fBdel_char [(n)]\fP \fIDelete, Ctrl-d\fP" Delete n characters from the cursor to the right. Default of n is 1. .IP "\fBdel_forw_line\fP \fICtrl-k\fP" .br Delete the line from the cursor to the end. .IP "\fBdel_forw_word\fP \fIMeta-d\fP" .br Delete the word from the cursor to the end. .IP "\fBdel_line\fP \fICtrl-u\fP" .br Delete the entire line. .IP \fBenter\fP \fIEnter, Ctrl-j, Ctrl-m\fP .br Perform substitution if applicable and send the line to fvwm. .IP "\fBenter_wo_subst\fP \fIMeta-Enter\fP" .br Send the line to fvwm without any substitution. .IP \fBeoh\fP .br Move to the end of history. .IP "\fBeoh_ign_mode\fP \fIEsc->\fP" .br Move to the end of history. If it is in search mode, continue. .IP \fBeol\fP \fIEnd, Ctrl-e\fP .br Move the cursor to the end of line. .IP "\fBins_char (str)\fP" .br Insert string at the cursor. .IP "\fBins_last_word\fP \fIEsc-.\fP" .br Insert the last argument of the previous command at the cursor. .IP "\fBins_nth_word\fP \fIMeta-[1..9]\fP" .br Insert the n-th argument of the previous command at the cursor. .IP "\fBlist_func\fP \fIMeta-l\fP" .br List up available editing functions. .IP "\fBnext_char\fP \fIRight, Ctrl-f\fP" .br Move the cursor to the next character. .IP "\fBnext_line\fP \fIDown, Ctrl-n\fP" .br Move to the next line in history. .IP "\fBnext_word\fP \fIMeta-f\fP" .br Move the cursor to the next word. .IP \fBprefix\fP .br Wait for the next character typed in for multi-key binding. .IP "\fBprev_char\fP \fILeft, Ctrl-b\fP" .br Move the cursor to the previous character. .IP "\fBprev_line\fP \fIUp, Ctrl-p\fP" .br Move to the previous line in history. .IP "\fBprev_word\fP \fIMeta-b\fP" .br Move the cursor to the previous word. .IP \fBquote\fP \fICtrl-q\fP .br Insert the next character typed into the buffer literally. .IP \fBsearch\fP \fICtrl-s\fP .br Search pattern in history. .IP "\fBsearch_rev\fP \fICtrl-r\fP" .br Search pattern in history in reverse order. .IP \fBsubst\fP \fIMeta-s\fP .br Substitute all patterns to strings and reprint the line. The substitutions are not nested and performed in the order that they are defined. .RE .SH CONFIGURATION The key binding can be overridden or defined in fvwm module configuration. .RS *FvwmConsole: Key \\ck prev_line .RE Non-space character sequence need not be quoted. In order to undefine, omit the last argument. .RS *FvwmConsole: Key \\ck .RE Note that non-meta character is case sensitive. \\c means control key, \\e means escape, and \\m is alt key. .br It also accepts Subst configuration. Users often input long fvwm command repeatedly. Subst will replace particular input sequence to user defined string. Example: .RS *FvwmConsole: Subst '^bigx' 'Exec xterm -g 120x60+0+0 -fn 10x20 -fg black -bg lemonchiffon' .RE Typing 'bigx' in FvwmConsole will launch xterm. '^' denotes the beginning of line in .B regular expression. \'pl\' in the middle of the command will not be replaced. Although the format looks different, it takes Perl regular expression. It just uses single or double quote as the delimiter. Single or double quotes have no difference, although they have to match, and cannot include itself in the string. .RS *FvwmConsole: Subst '^g\\s*(\\d+)' 'Desk 0 0\\nGotoPage 0 $1\\nFocus' .RE Entering 'g4' or 'g 4' will jump to desk 0 page 0 4 and focus. .SH INVOCATION FvwmConsoleC.pl should be invoked by FvwmConsole. .SH SEE ALSO FvwmConsole(1x), perlre(1) .SH AUTHOR Toshi Isogai fvwm-2.6.7/modules/FvwmConsole/getline.c0000644000175700017570000001014513003342500015140 00000000000000/* -*-c-*- */ /* 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 "FvwmConsole.h" #ifdef HAVE_READLINE #include #include #define fvwm_rl_bind_key(x, y) rl_bind_key(x, y) #define fvwm_readline(x) readline(x) #define fvwm_add_history(cmd) add_history(cmd) #define fvwm_stifle_history(x) stifle_history(x) #define fvwm_read_history(x) read_history(x) #define fvwm_write_history(x) write_history(x) #ifdef HAVE_GNU_READLINE #define fvwm_append_history(x, y) append_history(x, y) #define fvwm_history_truncate_file(x, y) history_truncate_file(x, y) #define fvwm_read_history_range(x, y, z) read_history_range(x, y, z) #else #define fvwm_append_history(x, y) -1 #define fvwm_history_truncate_file(x, y) -1 #define fvwm_read_history_range(x, y, z) -1 #endif #define USE_READLINE 1 #else #define fvwm_rl_bind_key(x, y) -1 #define fvwm_readline(x) NULL #define fvwm_add_history(cmd) #define fvwm_append_history(x, y) -1 #define fvwm_history_truncate_file(x, y) -1 #define fvwm_read_history_range(x, y, z) -1 #define fvwm_stifle_history(x) #define fvwm_read_history(x) -1 #define fvwm_write_history(x) -1 #define USE_READLINE 0 #endif static char cmd[MAX_COMMAND_SIZE]; static char *line = (char *)NULL; static int done_init = 0; static char *h_file; char *get_line(void) { char *prompt; int len; char *home; int fdh; if (USE_READLINE == 0) { if (fgets(cmd, MAX_COMMAND_SIZE, stdin) == NULL) { return NULL; } return cmd; } /* If initialization hasn't been done, do it now: * - We don't want TAB completion */ if (!done_init) { (void)fvwm_rl_bind_key('\t', rl_insert); /* get history from file */ home = getenv("FVWM_USERDIR"); h_file = safemalloc(strlen(home) + sizeof(HISTFILE) + 1); strcpy(h_file, home); strcat(h_file, HISTFILE); fvwm_stifle_history(HISTSIZE); if (access(h_file, F_OK) < 0) { /* if it doesn't exist create it */ fdh = creat(h_file, S_IRUSR | S_IWUSR); if (fdh != -1) { close(fdh); } } else { (void)fvwm_read_history(h_file); } done_init = 1; } /* Empty out the previous info */ len = 0; *cmd = '\0'; prompt = PS1; while (1) { int linelen = 0; /* If the buffer has already been allocated, free the memory. */ if (line != (char *)NULL) { free(line); } /* Get a line from the user. */ SUPPRESS_UNUSED_VAR_WARNING(prompt); line = fvwm_readline(prompt); if (line == NULL) { return NULL; } /* Make sure we have enough space for the new line */ linelen = strlen(line); if (len + linelen > MAX_COMMAND_SIZE-2) { fprintf( stderr, "line too long %d chars max %d \a\n", len + linelen, MAX_COMMAND_SIZE - 2); strncat(cmd, line, MAX_COMMAND_SIZE - len - 2); fvwm_add_history(cmd); break; } /* Copy the new line onto the end of the current line */ strcat(cmd, line); /* If the current line doesn't end with a backslash, we're done */ len = strlen(cmd); if (cmd[len-1] != '\\') { break; } /* Otherwise, remove it and wait for more (add a space if * needed) */ prompt = PS2; cmd[len-1] = (cmd[len-2] == ' ' || cmd[len-2] == '\t') ? '\0' : ' '; } /* If the command has any text in it, save it on the history. */ if (*cmd != '\0') { fvwm_add_history(cmd); if (fvwm_append_history(1, h_file) == 0) { (void)fvwm_history_truncate_file(h_file, HISTSIZE); } else { (void)fvwm_write_history(h_file); } } cmd[len] = '\n'; cmd[len+1] = '\0'; return cmd; } fvwm-2.6.7/modules/FvwmConsole/FvwmConsole.10000644000175700017570000000640613010101137015673 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .TH FvwmConsole 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmConsole \- an fvwm command input interface .SH SYNOPSIS Module FvwmConsole [options] \fIFvwmConsole\fP can only be invoked by fvwm. Command line invocation of the \fIFvwmConsole\fP module will not work. .SH DESCRIPTION FvwmConsole allows the user to type fvwm configuration commands interactively, and have them executed immediately. This tool is particularly useful for testing new configuration ideas, or for implementing temporary changes to your environment. .SH INVOCATION FvwmConsole must be spawned as a module by fvwm. FvwmConsole takes all \fIxterm\fP(1) options. .PP FvwmConsole can be invoked by inserting the line 'Module FvwmConsole' in the .fvwm2rc file. This can be placed on a line by itself, if FvwmConsole is to be spawned during fvwm's initialization, or can be bound to a menu or mouse button or keystroke to invoke it later. .SH CONFIGURATION OPTIONS FvwmConsole uses \fIxterm\fP(1). All resources set for xterm are inherited unless overridden by command line options. .RS Module FvwmConsole -g 40x10 -fg black -bg green3 .RE A different terminal emulator can be specified with the -terminal option. However, only terminal programs that understand the options -name, -title and -e can be used. .RS Module FvwmConsole -terminal rxvt .RE Previous versions of FvwmConsole supported a -e option to choose a different front-end. Although this option is still provided for backwards compatibility its use is discouraged unless you know exactly what you are doing. .RS Module FvwmConsole -e FvwmConsoleC.pl .RE (see \fIFvwmConsoleC.pl\fP(1)). .PP Also X resources can be set in your ~/.Xdefaults file: .RS FvwmConsole*VT100*geometry: 40x4 .br FvwmConsole*font: 7x14 .RE .SH "COMMAND EDITING" There are a few options. If the GNU readline library is available, it can be used. .PP If Perl5 is installed, FvwmConsoleC.pl can be used as a command editor. This can be accomplished by either copying FvwmConsoleC.pl to fvwmlib directory as FvwmConsoleC or invoking FvwmConsole with -e option. For example: .RS Module FvwmConsole -e FvwmConsoleC.pl .RE If neither one is installed, a simple input reading function which doesn't have editing capabilities is used. .P GNU readline and FvwmConsoleC.pl have some frequent used commands in common as default. These commands are similar to emacs. For more details, refer GNU readline man and info pages, and FvwmConsoleC.pl man page. .RS .PD 0 .TP 8 Ctrl-A - beginning of line .TP Ctrl-B - previous char .TP Ctrl-D - delete char .TP Ctrl-E - end of line .TP Ctrl-F - next char .TP Ctrl-H - backspace .TP Ctrl-K - erase to the end of line .TP Ctrl-N - next line .TP Ctrl-P - previous line .TP Ctrl-R - search reverse .TP Ctrl-U - delete line .TP Meta-B - previous word .TP Meta-F - next word .TP Esc < - beginning of history .TP Esc > - end of history .RE .PD .SH EXITING FvwmConsole can be stopped by entering the EOF character (usually CTRL-D). .PP \fBNote!\fP Do not use the "quit" command, as this is an fvwm builtin: typing "quit" at the FvwmConsole command line will cause fvwm to exit. .SH SEE ALSO \fIxterm\fP(1), \fIFvwmConsoleC.pl\fP(1), GNU Readline library .SH AUTHOR FvwmConsole is the original work of Toshi Isogai. fvwm-2.6.7/modules/FvwmConsole/Changes0000644000175700017570000000310212673746443014665 00000000000000Changes on 1.3 -- 02/05/97 -- -- 08/22/97 -- 1.3.1 -- 08/28/97 -- 1.3.2 1. moved socket in home directory from /tmp in order to avoid remote chance of connecting to somebody else's fvwm (this could be interesting). 2. command history is kept in a file from the previous session. 3. The maximum command length is now 1000, up from 255. This should be used with fvwm with this limit (greater than but not equal to 2.0.45). Long module path and such can be input now. 4. FvwmConsoleC.pl (1.2) looks slightly smoother. (08/22/97) With patch from Paul D Smith 1. changed ADD_INCLUDE variable to EXTRA_INCLUDES in Imakefile. 2. changed the man page. It makes sense now! 3. added Tab key binding as tab insertion to make cut-and- paste easier. 4. Handles backslashed command lines. Long lines are hard to type and hard to read. With patch from Al Bolduc (08/28/97) 1. runs on BSD/OS which has another element in the sockaddr_un structure. Changes on 1.2 -- 08/22/96 --- 1. Deleted unneccessary defines and headers. The less, the better. 2. Changed maximum command size to 255 to prevent module termination. 3. One less process. The less , the better. Changes on 1.1 1. Fixed the bug that didn't allocate enough memory for the child process arguments. 2. Get module configuration from Fvwm and pass them to the client. Changes on FvwmConsoleC.pl 1.1 1. Added substitution and other editing functions. 2. Keybindings can be configured through module configuration. fvwm-2.6.7/modules/FvwmConsole/FvwmConsole.h0000644000175700017570000000150212773467232016004 00000000000000/* -*-c-*- */ #include #if HAVE_SYS_BSDTYPES_H #include #endif #if HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #include #include "libs/fvwmlib.h" #include "libs/Module.h" #include "libs/fvwmsignal.h" #define S_NAME "/.FvwmConsole-Socket" /* Prompts for readline support */ #define PS1 "" #define PS2 ">" #define HISTSIZE 100 /* readline history file size */ #define HISTFILE "/.FvwmConsole-History" #define XTERM "xterm" /* message to client */ #define C_BEG "_C_Config_Line_Begin_\n" #define C_END "_C_Config_Line_End_\n" #define C_CLOSE "_C_Socket_Close_\n" #define MAX_COMMAND_SIZE 1000 #define MAX_MESSAGE_SIZE 260 fvwm-2.6.7/modules/FvwmConsole/FvwmConsoleC.c0000644000175700017570000000636713001406607016100 00000000000000/* -*-c-*- */ /* 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 */ /* FIXME: The signal handling of this module is largely broken */ #include "config.h" #include "FvwmConsole.h" #include "libs/fio.h" int s; /* socket handle */ FILE *sp; char *name; /* name of this program at executing time */ char *get_line(void); /* * close socket and exit */ void sclose(int foo) { if (sp != NULL) { fclose(sp); sp = NULL; } exit(0); SIGNAL_RETURN; } RETSIGTYPE ReapChildren(int sig) { fvwmReapChildren(sig); sclose(sig); SIGNAL_RETURN; } /* * print error message on stderr */ void ErrMsg(char *msg) { fprintf(stderr, "%s error in %s: %s\n", name , msg, strerror(errno)); if (sp != NULL) { fclose(sp); sp = NULL; } exit(1); } /* * setup socket. * send command to and receive message from the server */ int main(int argc, char *argv[]) { char *cmd; char data[MAX_MESSAGE_SIZE]; int len; /* length of socket address */ struct sockaddr_un sas; int clen; /* command length */ int pid; /* child process id */ char *home; char *s_name; int rc; signal(SIGCHLD, ReapChildren); signal(SIGPIPE, sclose); signal(SIGINT, sclose); signal(SIGQUIT, sclose); name=strrchr(argv[0], '/'); if (name != NULL) { name++; } /* make a socket */ home = getenv("FVWM_USERDIR"); s_name = safemalloc(strlen(home) + sizeof(S_NAME) + 1); strcpy(s_name, home); strcat(s_name, S_NAME); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s < 0) { ErrMsg ("socket"); } /* name the socket and obtain the size of it*/ sas.sun_family = AF_UNIX; strcpy(sas.sun_path, s_name); len = sizeof(sas) - sizeof(sas.sun_path) + strlen(sas.sun_path); rc = connect(s, (struct sockaddr *)&sas, len); if (rc < 0) { ErrMsg("connect"); } sp = fdopen(s, "r"); if (sp == NULL) { ErrMsg("fdopen"); } pid = fork(); if (pid == -1) { ErrMsg("fork"); } if (pid == 0) { /* loop of get user's command and send it to server */ while (1) { cmd = get_line(); if (cmd == NULL) { break; } clen = strlen(cmd); if (clen == 1) { /* empty line */ continue; } /* send the command including null to the server */ usleep(1); fvwm_send(s, cmd, strlen(cmd) + 1, 0); } kill(getppid(), SIGKILL); sclose(0); } while (fgets(data, MAX_MESSAGE_SIZE, sp)) { /* get the response */ /* ignore config lines */ if (!strcmp(data, C_BEG)) { while (fgets(data, MAX_MESSAGE_SIZE, sp)) { if (*data == '\0' || !strcmp(data,C_END)) { break; } } if (*data != '\0') { continue; } } if (*data == '\0') { break; } printf("%s",data); } return 0; } fvwm-2.6.7/modules/FvwmConsole/FvwmConsole.c0000644000175700017570000001523513001406607015767 00000000000000/* -*-c-*- */ /* * Fvwm command input interface. * * Copyright 1996, Toshi Isogai. No guarantees or warantees or anything * are provided. Use this program at your own risk. Permission to use * this program for any purpose is given, * as long as the copyright is kept intact. */ /* 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 */ /* FIXME: The signal handling of this module is largely broken */ #include "config.h" #include "FvwmConsole.h" #include "libs/fio.h" #include "libs/fvwmsignal.h" /* using ParseModuleArgs now */ static ModuleArgs* module; int Fd[2]; /* pipe to fvwm */ int Ns = -1; /* socket handles */ char Name[80]; /* name of this program in executable format */ char *S_name = NULL; /* socket name */ void server(void); RETSIGTYPE DeadPipe(int); void ErrMsg(char *msg); void SigHandler(int); void clean_up(void) { if (Ns != -1) { close(Ns); Ns = -1; } if (S_name != NULL) { unlink(S_name); S_name = NULL; } return; } /* * signal handler */ RETSIGTYPE DeadPipe(int dummy) { clean_up(); exit(0); SIGNAL_RETURN; } RETSIGTYPE SigHandler(int dummy) { clean_up(); exit(0); SIGNAL_RETURN; } RETSIGTYPE ReapChildren(int sig) { fvwmReapChildren(sig); SIGNAL_RETURN; } int main(int argc, char *argv[]) { char client[120]; char **eargv; int i, j, k; char *xterm_pre[] = { "-title", Name, "-name", Name, NULL }; char *xterm_post[] = { "-e", NULL, NULL }; int clpid; /* Why is this not just put in the initializer of xterm_a? * Apparently, it is a non-standard extension to use a non-constant * address (of client) in an initializer (of xterm_a). */ xterm_post[1] = client; module = ParseModuleArgs(argc, argv, 0); /* we don't use an alias */ if (module == NULL) { fprintf( stderr, "FvwmConsole version "VERSION" should only be" " executed by fvwm!\n"); exit(1); } strcpy(Name, module->name); /* construct client's name */ strcpy(client, argv[0]); strcat(client, "C"); eargv =(char **)safemalloc((argc+12)*sizeof(char *)); /* copy arguments */ eargv[0] = XTERM; j = 1; for (k = 0; xterm_pre[k] != NULL; j++, k++) { eargv[j] = xterm_pre[k]; } for (i = 0; i< module->user_argc; i++) { if (!strcmp(module->user_argv[i], "-e")) { i++; break; } else if (!strcmp(module->user_argv[i], "-terminal")) { i++; if (i < module->user_argc) /* use alternative terminal emulator */ eargv[0] = module->user_argv[i]; } else { eargv[j++] = module->user_argv[i]; } } for (k = 0; xterm_post[k] != NULL; j++, k++) { eargv[j] = xterm_post[k]; } /* copy rest of -e args */ for (; iuser_argc; i++, j++) { eargv[j-1] = module->user_argv[i]; } eargv[j] = NULL; signal(SIGCHLD, ReapChildren); /* Dead pipes mean fvwm died */ signal(SIGPIPE, DeadPipe); signal(SIGINT, SigHandler); signal(SIGQUIT, SigHandler); signal(SIGALRM, SigHandler); Fd[0] = module->to_fvwm; Fd[1] = module->from_fvwm; /* launch xterm with client */ clpid = fork(); if (clpid < 0) { ErrMsg("client forking"); } else if (clpid == 0) { execvp(*eargv, eargv); ErrMsg("exec"); } SetMessageMask(Fd, M_END_CONFIG_INFO | M_ERROR); SetMessageMask(Fd, M_EXTENDED_MSG); /* tell fvwm we're running */ SendFinishedStartupNotification(Fd); server(); return 0; } /* * setup server and communicate with fvwm and the client */ void server(void) { struct sockaddr_un sas, csas; int len; socklen_t clen; /* length of sockaddr */ char buf[MAX_COMMAND_SIZE]; /* command line buffer */ char *tline; char ver[40]; fd_set fdset; char *home; int s; int msglen; int rc; /* make a socket */ s = socket(AF_UNIX, SOCK_STREAM, 0); if (s < 0 ) { ErrMsg("socket"); } /* name the socket */ home = getenv("FVWM_USERDIR"); S_name = safemalloc(strlen(home) + sizeof(S_NAME) + 1); strcpy(S_name, home); strcat(S_name, S_NAME); sas.sun_family = AF_UNIX; strcpy(sas.sun_path, S_name); /* bind the above name to the socket: first, erase the old socket */ unlink(S_name); len = sizeof(sas) - sizeof(sas.sun_path) + strlen(sas.sun_path); umask(0077); rc = bind(s, (struct sockaddr *)&sas, len); if (rc < 0) { ErrMsg("bind"); } else { /* don't wait forever for connections */ alarm(FVWMCONSOLE_CONNECTION_TO_SECS); /* listen to the socket */ rc = listen(s, 5); alarm(0); if (rc < 0) { ErrMsg("listen"); } /* accept connections */ clen = sizeof(csas); Ns = accept(s, (struct sockaddr *)&csas, &clen); if (Ns < 0) { ErrMsg("accept"); } } /* send config lines to Client */ tline = NULL; fvwm_send(Ns, C_BEG, strlen(C_BEG), 0); GetConfigLine(Fd, &tline); while (tline != NULL) { if (strlen(tline) > 1) { fvwm_send(Ns, tline, strlen(tline), 0); fvwm_send(Ns, "\n", 1, 0); } GetConfigLine(Fd, &tline); } fvwm_send(Ns, C_END, strlen(C_END), 0); strcpy(ver, "*"); strcpy(ver, module->name); strcat(ver, " version "); strcat(ver, VERSION VERSIONINFO); strcat(ver, "\n"); fvwm_send(Ns, ver, strlen(ver), 0); while (1) { FD_ZERO(&fdset); FD_SET(Ns, &fdset); FD_SET(Fd[1], &fdset); fvwmSelect(FD_SETSIZE, SELECT_FD_SET_CAST &fdset, 0, 0, NULL); if (FD_ISSET(Fd[1], &fdset)) { FvwmPacket* packet = ReadFvwmPacket(Fd[1]); if (packet == NULL) { clean_up(); exit(0); } else if (packet->type == M_ERROR) { msglen = strlen((char *)&(packet->body[3])); if (msglen > MAX_MESSAGE_SIZE-2) { msglen = MAX_MESSAGE_SIZE-2; } fvwm_send( Ns, (char *)&(packet->body[3]), msglen, 0); } } if (FD_ISSET(Ns, &fdset)) { int len; int rc; rc = fvwm_recv(Ns, buf, MAX_COMMAND_SIZE, 0); if (rc == 0) { /* client is terminated */ clean_up(); exit(0); } /* process the own unique commands */ len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') { buf[len - 1] = '\0'; } /* send command */ SendText(Fd, buf, 0); } } } /* * print error message on stderr and exit */ void ErrMsg(char *msg) { fprintf( stderr, "%s server error in %s, errno %d: %s\n", Name, msg, errno, strerror(errno)); clean_up(); exit(1); } fvwm-2.6.7/modules/FvwmConsole/FvwmConsoleC.pl.in0000644000175700017570000004655512673746443016724 00000000000000#! @PERL@ # $0 - Front end of FvwmConsole # FvwmConsole server must be running # Copyright 1997, Toshi Isogai # You may use this code for any purpose, as long as the original # copyright remains in the source code and all documentation # 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 # If you change this, be sure to change the test in configure.in require 5.002; use Socket; $ESC = "\e"; $HISTFILE = "$ENV{FVWM_USERDIR}/.FvwmConsole-History0"; $SOCKET_NAME = "$ENV{FVWM_USERDIR}/.FvwmConsole-Socket"; #$VERSION = '1.2'; $VERSION = '@VERSION@'; if (-c "/dev/console" && -w "/dev/console") { close STDERR; if (!open (STDERR, ">/dev/console")) { print "Can't redirect STDERR to /dev/console: $!\n"; sleep 3; exit; } } ($Filename = $0) =~ s@.*/@@; ($Sname = $Filename) =~ s/C(\.pl)?$//; $tty = `tty`; $tty =~ s/\n//; $org_stty = &stty('-g'); @Hist = (); @Histall = (); $HIST_SIZE = 100; $MAX_COMMAND_SIZE = 1000; main(); exit; sub main::default_key { #------------ default key bindings ---------- # these can be overidden by config lines # # It may need these lines in .Xdefault to make home and end key work # FvwmConsole*VT100*Translations: #override \n \ # Home: string(0x1b) string("[1~" ) \n \ # Delete: string(0x1b) string("[3~" ) \n # End: string(0x1b) string("[4~" ) \n package User; $ESC = $main::ESC; $Key{"$ESC\[1~"} = 'bol'; #home Key $Key{"$ESC\[3~"} = 'del_char'; $Key{"$ESC\[4~"} = 'eol'; #end key $Key{"$ESC\[A"}= 'prev_line'; #up $Key{"$ESC\[B"}= 'next_line'; #down $Key{"$ESC\[C"}= 'next_char'; #right $Key{"$ESC\[D"}= 'prev_char'; #left $Key{"${ESC}f"}= 'next_word'; $Key{"${ESC}b"} = 'prev_word'; $Key{"$ESC"} = 'prefix'; $Key{"\cD"} = 'del_char'; $Key{"\c?"} = 'del_char'; $Key{"\cH"} = 'bs'; $Key{"\cq"} = 'quote'; $Key{"\cU"} = 'del_line'; $Key{"\cs"} = 'search'; $Key{"\cR"} = 'search_rev'; $Key{"\cK"} = 'del_forw_line'; $Key{"\ca"} = 'bol'; $Key{"\ce"} = 'eol'; $Key{"\cp"} = 'prev_line'; $Key{"\cn"} = 'next_line'; $Key{"\cf"} = 'next_char'; $Key{"\cb"} = 'prev_char'; $Key{"\cx"} = 'prefix'; $Key{"\cx\cb"} = 'bind'; $Key{"\cx\ck"} = 'cancel'; $Key{"\cw"} = 'del_back_word'; $Key{"\x8d"} = 'enter_wo_subst'; # alt enter $Key{"\n"} = 'enter'; $Key{"\ci"} = 'ins_char (" ")'; $Key{"\xE4"} = 'del_forw_word'; # alt_d $Key{"\xE6"} = 'next_word'; # alt_f $Key{"\xEB"} = 'bind'; # alt_k $Key{"\xEC"} = 'list_func'; # alt_k $Key{"\xF3"} = 'subst'; # alt_s $Key{"\xF4"} = 'termsize'; # alt_t $Key{"\xE2"} = 'prev_word'; # alt_b $Key{"\xb1"} = 'ins_nth_word(1)'; $Key{"\xb2"} = 'ins_nth_word(2)'; $Key{"\xb3"} = 'ins_nth_word(3)'; $Key{"\xb4"} = 'ins_nth_word(4)'; $Key{"\xb5"} = 'ins_nth_word(5)'; $Key{"\xb6"} = 'ins_nth_word(6)'; $Key{"\xb7"} = 'ins_nth_word(7)'; $Key{"\xb8"} = 'ins_nth_word(8)'; $Key{"\xb9"} = 'ins_nth_word(9)'; $Key{"${ESC}b"} = 'prev_word'; # esc_b $Key{"${ESC}f"} = 'next_word'; # esc_f $Key{"${ESC}>"} = 'eoh_ign_mode'; # end of history, ignore mode $Key{"${ESC}<"} = 'boh_ign_mode'; # begining of history, ignore mode $Key{"${ESC}."} = 'ins_last_word'; $Key{EOF} = "\cD"; #eof work only when line is empty $Subst{'^#.*'} = ''; # ignore comments #---------------- end of key binding ----------------- #---------------- Terminal control ------------------- $TERM_EEOL = "$ESC\[K"; # erase to end of line $TERM_RIGHT = "$ESC\[C"; # move cursor right $TERM_LEFT = "$ESC\[D"; # move cursor left $TERM_DOWN = "$ESC\[B"; # move cursor up $TERM_UP = "$ESC\[A"; # move cursor up } sub read_config { my( $hash,@keys,$key,@vals,$val); while() { last if $_ eq "_C_Config_Line_End_\n"; next if !s/^\*${Sname}//; ($hash,@keys[0..3],@vals) = (/ ^(\w+)\s+ #hash name ('([^\']*)'|"([^\"]*)"|(\S+)) #key quoted or bare word (\s+('([^\']*)'|"([^\"]*)"|(\S+)))? #value /x); $key = $keys[1].$keys[2].$keys[3]; $val = $vals[2].$vals[3].$vals[4]; if( defined %{$User::{$hash}} ) { User::bind( $hash, $key, $val ); } } } sub main { my($sin, $cmd); my($name, $ppid, $cpid); socket(SH, PF_UNIX, SOCK_STREAM, 0) || die "$!\n"; $sun = sockaddr_un($SOCKET_NAME); connect(SH, $sun) || die "$sun: $!\n"; print "$Filename $VERSION\n"; default_key(); read_config(); #must be done before forking $ppid = $$; if( $cpid = fork() ) { &input_open($tty,$tty,$HISTFILE,1); while( $cmd = &input('','',1) ) { next if $cmd =~/^\s*$/; last if $cmd eq "\0"; if( length($cmd) > $MAX_COMMMAND_SIZE ) { print User::OUT "\a"; } send( SH, $cmd."\0", 0 ); } dokill( $cpid ); } else { #child handles output while() { last if $_ eq ''; if( $_ eq "_C_Socket_Close_\n" ) { dokill( $ppid ); } print; } dokill( $ppid ); } } sub dokill { my($pid) = @_; unlink SH; kill -9,$pid if $pid; exit; } sub input_open { # arg0 input device # arg1 output device # arg2 history file # arg3 key selection - bit0 # bit1 # bit2 return undef esc code as it is ($Dev_in,$Dev_out,$File,$Ksel) = @_; if( !$Dev_in ) {$Dev_in = $tty;} elsif( $Dev_in eq "not a tty" ) { $Dev_in = $ENV{'TTY'};} if( !$Dev_out ) {$Dev_out = $tty;} if( !$File ) { $File = '/tmp/input.tmp';} open(User::IN,"<$Dev_in") || die "open in at input_open '$Dev_in' $!\n"; open(User::OUT,">$Dev_out") || die "can't open input at 'input_open' $!\n"; select((select(User::OUT), $| = 1)[0]); # unbuffer pipe if( defined $File ) { if( open(INITF,"$File") ) { do "$File"; @Histall=; close(INITF); $#Histall--; }else{ print STDERR "Can't open history file $File\n"; } } } sub input_close { close(User::IN); close(User::OUT); } sub getchar { # get char from input # if esc , check for more char my($c,$s,$rin,$rout); sysread(User::IN, $c, 1); if( $c ne $ESC ) { $s = $c; }else { $rin = ''; vec( $rin, fileno(User::IN),1) = 1; $n= select( $rout=$rin, undef, undef, 0.1 ); $s = $ESC; if($n) { while($n= select( $rout=$rin, undef, undef, 0.1 ) ) { sysread( User::IN, $c, 1 ); $s .= $c; last if $c =~ /[A-Dz~]/; # end of escape seq } } } $s; } sub insert_char { local($c,*len,*ix,*hist) =@_; local($clen); $clen = length $c; if( $init_in ) { $len = $ix = $clen; # new hist - clear old one $hist[$#hist] = $c; }else{ substr($hist[$#hist],$ix,0) = $c; #insert char $len += $clen; $ix += $clen; } } sub stty { my($arg) = @_; `/bin/stty $arg <$tty 2>&1`; # if( -x "/usr/5bin/stty" ) { # `/usr/5bin/stty $arg <$tty`; # }elsif( -x "/usr/bin/stty" ) { # `/usr/bin/stty $arg `; # }else { # `/bin/stty $arg `; # } } sub add_hist { # add input into history file local($type,*cmd) = @_; #not my my( $t )= sprintf("%s",$type); my($h) = $cmd[$#cmd]; return if !defined $File; if( $#cmd ==0 || $h ne $cmd[$#cmd-1] ) { $h =~ s/([\"@\$\\])/\\$1/g; $t =~ s/^\*//; push(@Histall, "push (\@$t, \"$h\");\n" ); @Histall = splice( @Histall, -$HIST_SIZE, $HIST_SIZE ); # take last HIST_SIZE commands if( open( FILE, ">$File" ) ){ print FILE @Histall; print FILE "1;\n"; close(FILE); } }else { $#cmd--; } } #---------------- # print mini help #---------------- sub usage_error { open( THIS, "$0"); while() { s/\$0/$Filename/; if( /^\#/ ) { print STDERR $_; }else{ last; } } close THIS; sleep 3; exit 1; } sub search_mode { local(*c, *s, *prompt, *mode, *isp, *hist ) =@_; my($p_save, $isp_cur); if($c eq "\n"){ $prompt = $p_save; $mode = 'normal'; last IN_STACK; } $isp_cur = $isp; if( $User::Key{$c} =~ /^search/ ) { #search furthur $mode = $User::Key{$c}; while(1) { if( $mode eq 'search_rev' && --$isp<0 || $mode eq 'search' && ++$isp>$#hist-1 ) { print User::OUT "\a"; # couldn't find one $isp = $isp_cur; last; } last if( index($hist[$isp],$s) >=0); } }elsif( $User::Key{$c} eq 'bs' ) { $s =~ s/.$//; }elsif( ord($c) < 32 ) { #non-printable char, get back to normal mode print User::OUT "\a"; $prompt = $p_save; $mode = 'normal'; return; }else{ $s .= $c; while(1) { last if (index($hist[$isp],$s) >=0); if( $mode eq 'search_rev' && --$isp<0 || $mode eq 'search' && ++$isp>$#hist ) { print User::OUT "\a"; #couldn't find one chop($s); $isp = $isp_cur; last; } } } $prompt = "($mode)'$s':"; } sub calcxy { my( $mode, $prompt, $len, $ix, $off, $wd ) = @_; my($plen); my( $y_len, $y_ix, $col); my($adjust); # 1 when the last char is on right edge $plen = length($prompt); $y_len = int (($plen+$len+$off) / $wd ); $adjust = ( (($plen+$len+$off) % $wd == 0) && ($y_len > 0 )) ? 1:0; if( $mode =~ /^search/ ) { #move cursor to search string $y_ix = int (($plen-2+$off) / $wd ); $col = ($plen-2+$off) % $wd; }else{ #normal mode - move cursor back to $ix $y_ix = int (($plen+$ix+$off) / $wd ); $col = ($plen+$ix+$off) % $wd; } ($y_len, $y_ix, $col, $adjust); } package User; sub move_cursor { my($x,$y, $x_prev,$y_prev) = @_; my($termcode); $termcode = ''; if($y > $y_prev ) { $termcode = $TERM_DOWN x ($y-$y_prev); }elsif( $y < $y_prev ) { $termcode = $TERM_UP x ($y_prev-$y); } if( $x > $x_prev ) { $termcode .= $TERM_RIGHT x ($x-$x_prev); }elsif( $x < $x_prev ) { $termcode .= $TERM_LEFT x ($x_prev-$x); } print OUT $termcode; } sub another_line { $init_in = 1-$app; ($hist[$#hist] = $hist[$isp]) =~ s/\n//; $ix = length($hist[$#hist]); } sub main::input { # arg0 - prompt # arg1 - input stack # arg2 - append input to command if 1 # arg3 - # of column offset local($prompt,*hist,$app,$off) = @_; local($len,$ix); local($c,$isp,$s,$wisp); local($mode); local(%lastop); local($init_in); local($print_line); #0-none, 1-whole, 2-from cursor my($y_ix,$y_ix0,$y_len,$wd,$ht,$col,$col0); my($term); my($init_in,$op); $off = 0 if( !defined $off ); *hist = *main::Hist if( ! defined @hist ); $isp = ++$#hist ; $wisp = $isp; if( -f "/vmunix" ) { &main::stty("-echo -icanon min 1 time 0 stop ''"); }else { &main::stty(" -echo -icanon eol \001 stop ''"); } ($ht,$wd) = &termsize(); $y_ix = $y_len = 0; $mode = 'normal'; another_line(); $print_line = 1; IN_STACK:while(1){ if( $print_line==0 ) { #just move cursor ($y_len,$y_ix,$col,$adjust) = &main::calcxy($mode,$prompt,$len,$ix,$off,$wd); move_cursor( $col,$y_ix, $col0,$y_ix0); }elsif($print_line==2 || $print_line==3 ) { # delete - print cursor to eol $len = length($hist[$#hist]); ($y_len,$y_ix,$col,$adjust) = &main::calcxy($mode,$prompt,$len,$ix,$off,$wd); if( $print_line==3 ) { # delete backward move_cursor( $col,$y_ix, $col0,$y_ix0); } if( $y_len0 > $y_ix && ($adjust || $y_len0 > $y_len) ) { print( OUT "\n$TERM_EEOL" x ($y_len0-$y_ix), $TERM_UP x ($y_len0-$y_ix), "\r", $TERM_RIGHT x $col, ); } print( OUT substr("$prompt$hist[$#hist]", $ix), $adjust ? '':$TERM_EEOL, "\r", $TERM_RIGHT x $col, $TERM_UP x ($y_len-$y_ix) , ($adjust && $ix!=$len)? $TERM_DOWN : '' ); }elsif($print_line==4) { # insert $len = length($hist[$#hist]); ($y_len,$y_ix,$col,$adjust) = &main::calcxy($mode,$prompt,$len,$ix,$off,$wd); print( OUT substr("$prompt$hist[$#hist]", $ix), $TERM_UP x ($y_len-$y_ix) ,"\r", $TERM_RIGHT x $col, $TERM_DOWN x $adjust ); }else{ # print whole line $len = length($hist[$#hist]); #move cursor to bol on screen, erase prev printout print (OUT $TERM_DOWN x ($y_len-$y_ix), "\r$TERM_EEOL$TERM_UP" x ($y_len), "\r$TERM_EEOL\r", $TERM_RIGHT x $off,"$prompt$hist[$#hist]"); ($y_len,$y_ix,$col,$adjust) = &main::calcxy($mode,$prompt,$len,$ix,$off,$wd); #mv cursor to cur pos print( OUT $TERM_UP x ($y_len-$y_ix) ,"\r", $TERM_RIGHT x $col, $TERM_DOWN x $adjust); } GETC:{ ($col0, $y_ix0, $y_len0) = ($col, $y_ix, $y_len); $print_line=1; $c = main::getchar(); while($Key{$c} eq "prefix" ) { $c .= main::getchar(); } ($op = $Key{$c}) =~ s/(.*)\s*[\(;].*/$1/; $op =~ /(\w+)$/; $op = $1; if( $Key{$c} =~ /ign_mode/ ) { # ignore mode and execute command eval "&{$Key{$c}}"; }elsif( $mode =~ /^search/ ) { main::search_mode(*c,*s,*prompt,*mode,*isp, *hist); another_line(); }elsif( $c eq $Key{EOF} && $len==0 ) { return ''; # eof return null }elsif( defined $Key{$c} ) { eval "&{$Key{$c}}"; $lastop{op} = $op; }elsif( ord ($c) < 32 ) { #undefined control char print OUT "\a"; $print_line = 0; }else { $lastop{op} = 'ins_char'; &ins_char( $c ); print OUT $c; } $init_in = 0; } } if( $y_ix != $y_len ) { print OUT "\n" x ($y_len-$y_ix); } &main::stty($org_stty); print OUT "\n"; if( $hist[$#hist] eq '' ) { pop(@hist); return "\n"; } if( $#hist>0 && $hist[$#hist] eq $hist[$#hist-1] ) { pop(@hist); # if it is the same, delete }else{ &main::add_hist( *hist, *hist ); } $hist[$#hist]."\n"; } #----------------------------- # editinig command functions # # functions must be below here to be listed by list_func # # the variables below are local to sub input # $prompt,$hist,$app,$off # $len,$ix # $c,$isp,$wisp,$s # $mode #----------------------------- sub prefix { } # it's only here to be listed by list_func sub boh { $isp = 0; another_line(); } sub boh_ign_mode { boh(); } sub bol { $ix = 0 ; $print_line=0; } sub bs { my($l) = @_; $l = 1 if $l eq ''; if( $len && $ix ) { $ix-=$l; # mv left substr($hist[$#hist],$ix,$l) = ""; # del char } $print_line = 3; } sub del_back_line { substr($hist[$#hist],0,$ix) = ""; $ix = 0; $print_line = 3; } sub del_forw_line { substr($hist[$#hist],$ix) = ""; $print_line = 2; } sub del_char { my($l) = @_; $l = 1 if $l eq ''; if( $len > $ix ) { substr($hist[$#hist],$ix,$l) = ""; # del char } $print_line = 2; } sub del_line { $ix = 0; $hist[$#hist] = ""; $print_line = 3; } sub del_back_word { my($tmp); $tmp = substr($hist[$#hist],0,$ix); $tmp =~ s/(^|\S+)\s*$//; $tmp = length $tmp; substr($hist[$#hist],$tmp,$ix-$tmp) = ""; $ix = $tmp; $print_line = 3; } sub del_forw_word { $hist[$#hist] =~ s/^(.{$ix})\s*\S+/$1/; $print_line = 2; } sub enter { subst(); enter_wo_subst(); } sub eoh { if( $isp==$#hist ) { print OUT "\a"; }else{ $hist[$#hist] = '' } $isp = $#hist; another_line(); $print_line = 1; } sub eoh_ign_mode { eoh(); $print_line = 1; } sub eol { $ix = $len; $print_line=0; } sub execute { eval "$hist[$#hist]"; if( $#hist>0 && $hist[$#hist] eq $hist[$#hist-1] ) { pop(@hist); # if it is the same, delete }else{ &main::add_hist( *hist, *hist ); } push( @hist, ''); # deceive 'input' it is an empty line last IN_STACK; } sub ins_char { my($c) = @_; &main::insert_char($c,*len,*ix,*hist); $print_line = 4; } sub ins_last_word { if( $lastop{op} =~ /^ins_(nth|last)_word/ ) { return if $wisp < 1; #delete last last_word bs(length $lastop{word}); }else { $wisp = $#hist; return if $wisp < 1; } $hist[--$wisp] =~ /(\S+)\s*$/; $lastop{word} = $1; ins_char($lastop{word}); } sub ins_nth_word { my($n) = @_; if( $lastop{op} =~ /^ins_(nth|last)_word/ ) { return if $wisp < 1; #delete last last_word bs(length $lastop{word}); }else { $wisp = $#hist; return if $wisp < 1; } $hist[--$wisp] =~ /((\S+)\s*){1,$n}/; $lastop{word} = $2; ins_char($lastop{word}); } sub list_func { my( $s, @cmds, $cmd, $func); $func = 0; open( THIS, "$0" ) || return; #shouldn't occur while( $s = ) { if( $s =~ /^\s*sub\s+main::input\s*\{/ ) { $func = 1; next; } next if !$func; if( $s =~ s/^\s*sub\s+// ) { $s =~ s/\s*[\{].*//; push @cmds,$s; } } close THIS; foreach $cmd (sort @cmds) { print OUT $cmd; } } sub bind { # bind Key or Subst # if there is no arguments, then list them my($hash,$key,$val) = @_; my( $mod,$chr,$v2,$k,$cnt ); if( defined %{$hash} ) { $k = $key; if( $hash eq "Key" ) { ($v2 = $val) =~ s/\s*[\(;].*//; if( !defined &{$v2} ) { print STDERR "Unknown function $v2\n"; return; } $mod = 0; $cnt =0; $k = ''; for( $i=0; $i= 0x80 ) { $mod .= '\M'; $chr = pack("c", ord($chr)-0x80); } if( $chr eq $ESC ) { $chr = '\E'; }elsif( ord($chr) < 0x20 ) { $mod .= '\C'; $chr = pack("c", ord($chr)+0x40); }elsif( ord($chr) == 0x7f ) { $chr = '\C?'; } $mod .= $chr; } if( ord($val) < 0x20 ) { $val = '\C'.pack("c", ord($val)+0x40); } print OUT "Key $mod $val\n"; } while( ($key,$val) = each(%Subst) ) { print OUT "Subst $key $val\n"; } } } sub next_char { $ix++ if ($ix<$len); $print_line=0; } sub next_line { if($isp<$#hist) { $isp++; if( $isp==$#hist ) { $hist[$isp] = ''; } }else { $isp = $#hist; print OUT "\a"; } another_line(); } sub next_word { $hist[$#hist] =~ /^(.{$ix}\S*(\s+|$))/; $ix = length($1); $print_line=0; } sub enter_wo_subst { last IN_STACK; } sub prev_char { $ix-- if $ix>0; $print_line=0; } sub prev_line { if($isp>0) { $isp--; }else { $isp = 0; print OUT "\a"; } another_line(); } sub prev_word { my($tmp); $tmp = substr($hist[$#hist],0,$ix); $tmp =~ s/(^|\S+)\s*$//; $ix = length($tmp); $print_line=0; } sub cancel { $hist[$#hist] = ""; $len = 0; last IN_STACK; } sub quote { my($c); sysread(IN, $c, 1); # $c = getc(IN); ins_char($c); } sub search_rev { $s = ''; $mode = 'search_rev'; $p_save = $prompt; $prompt = "($mode)'$s':"; $hist[$#hist] = $hist[$isp]; another_line(); } sub search { $s = ''; $mode = 'search'; $p_save = $prompt; $prompt = "($mode)'$s':"; $hist[$#hist] = $hist[$isp]; another_line(); } sub subst { my($key,$val); $done = 0; while( ($key,$val) = each(%Subst) ) { last if( eval "\$hist[\$#hist] =~ s\$key$val" ) ; } $ix = $len = length($hist[$#hist]); } sub termsize { my($row, $col,$s); if( -f "/vmunix" ) { $s =&main::stty ("everything"); ($row,$col) = ($s =~ /(\d+)\s+rows[,\s]+(\d+)\s+columns/ ); } else { $s =&main::stty ("-a"); ($row,$col) = ($s =~ /rows[=\s]+(\d+)[,;\s]+columns[=\s]+(\d+)/ ); } ($row,$col); } fvwm-2.6.7/modules/FvwmConsole/FvwmConsoleC.pl.10000644000175700017570000001171613010101137016410 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .TH FvwmConsoleC.pl 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmConsoleC.pl \- Command editor for fvwm command input interface .SH SYNOPSIS FvwmConsole -e /usr/X11/lib/fvwm/FvwmConsoleC.pl .SH COPYRIGHT Copyright 1996, Toshi Isogai. No guarantees or warranties are provided. Use this program at your own risk. Permission to use this program for any purpose is given, as long as the copyright is kept intact. .SH DESCRIPTION FvwmConsoleC.pl offers editing capabilities while the user is entering the line. By default, the line editing commands are similar to those of emacs. It also offers .B substitution , which replaces a pattern to a string before it sends the command. .SH FUNCTIONS Functions are bound to a key or key combination to be invoked. The followings are functions available and their default key bindings. .RS .IP \fBbind\fP \fIMeta-k, Ctrl-x Ctrl-b\fP .br .\"Bind key to function or bind pattern to string for substitution. List up key bindings and substitutions. .IP \fBboh\fP .br Move to the beginning of history. .IP "\fBboh_ign_mode\fP \fIEsc-<\fP" .br Move to the beginning of history. If it is in search mode, continue. .IP \fBbol\fP \fIHome, Ctrl-a\fP .br Move cursor to the beginning of the line. .IP "\fBbs[(n)]\fP \fIBackSpace, Ctrl-h\fP" .br Backspace n times. default of n is 1. .IP \fBcancel\fP \fICtrl-x Ctrl-k\fP .br Cancel the current input. .IP \fBdel_back_line\fP .br Delete the line from the beginning to the cursor. .IP "\fBdel_back_word\fP \fICtrl-w\fP" .br Delete the word from the beginning to the cursor. .IP "\fBdel_char [(n)]\fP \fIDelete, Ctrl-d\fP" Delete n characters from the cursor to the right. Default of n is 1. .IP "\fBdel_forw_line\fP \fICtrl-k\fP" .br Delete the line from the cursor to the end. .IP "\fBdel_forw_word\fP \fIMeta-d\fP" .br Delete the word from the cursor to the end. .IP "\fBdel_line\fP \fICtrl-u\fP" .br Delete the entire line. .IP \fBenter\fP \fIEnter, Ctrl-j, Ctrl-m\fP .br Perform substitution if applicable and send the line to fvwm. .IP "\fBenter_wo_subst\fP \fIMeta-Enter\fP" .br Send the line to fvwm without any substitution. .IP \fBeoh\fP .br Move to the end of history. .IP "\fBeoh_ign_mode\fP \fIEsc->\fP" .br Move to the end of history. If it is in search mode, continue. .IP \fBeol\fP \fIEnd, Ctrl-e\fP .br Move the cursor to the end of line. .IP "\fBins_char (str)\fP" .br Insert string at the cursor. .IP "\fBins_last_word\fP \fIEsc-.\fP" .br Insert the last argument of the previous command at the cursor. .IP "\fBins_nth_word\fP \fIMeta-[1..9]\fP" .br Insert the n-th argument of the previous command at the cursor. .IP "\fBlist_func\fP \fIMeta-l\fP" .br List up available editing functions. .IP "\fBnext_char\fP \fIRight, Ctrl-f\fP" .br Move the cursor to the next character. .IP "\fBnext_line\fP \fIDown, Ctrl-n\fP" .br Move to the next line in history. .IP "\fBnext_word\fP \fIMeta-f\fP" .br Move the cursor to the next word. .IP \fBprefix\fP .br Wait for the next character typed in for multi-key binding. .IP "\fBprev_char\fP \fILeft, Ctrl-b\fP" .br Move the cursor to the previous character. .IP "\fBprev_line\fP \fIUp, Ctrl-p\fP" .br Move to the previous line in history. .IP "\fBprev_word\fP \fIMeta-b\fP" .br Move the cursor to the previous word. .IP \fBquote\fP \fICtrl-q\fP .br Insert the next character typed into the buffer literally. .IP \fBsearch\fP \fICtrl-s\fP .br Search pattern in history. .IP "\fBsearch_rev\fP \fICtrl-r\fP" .br Search pattern in history in reverse order. .IP \fBsubst\fP \fIMeta-s\fP .br Substitute all patterns to strings and reprint the line. The substitutions are not nested and performed in the order that they are defined. .RE .SH CONFIGURATION The key binding can be overridden or defined in fvwm module configuration. .RS *FvwmConsole: Key \\ck prev_line .RE Non-space character sequence need not be quoted. In order to undefine, omit the last argument. .RS *FvwmConsole: Key \\ck .RE Note that non-meta character is case sensitive. \\c means control key, \\e means escape, and \\m is alt key. .br It also accepts Subst configuration. Users often input long fvwm command repeatedly. Subst will replace particular input sequence to user defined string. Example: .RS *FvwmConsole: Subst '^bigx' 'Exec xterm -g 120x60+0+0 -fn 10x20 -fg black -bg lemonchiffon' .RE Typing 'bigx' in FvwmConsole will launch xterm. '^' denotes the beginning of line in .B regular expression. \'pl\' in the middle of the command will not be replaced. Although the format looks different, it takes Perl regular expression. It just uses single or double quote as the delimiter. Single or double quotes have no difference, although they have to match, and cannot include itself in the string. .RS *FvwmConsole: Subst '^g\\s*(\\d+)' 'Desk 0 0\\nGotoPage 0 $1\\nFocus' .RE Entering 'g4' or 'g 4' will jump to desk 0 page 0 4 and focus. .SH INVOCATION FvwmConsoleC.pl should be invoked by FvwmConsole. .SH SEE ALSO FvwmConsole(1x), perlre(1) .SH AUTHOR Toshi Isogai fvwm-2.6.7/modules/FvwmM4/0000755000175700017570000000000013010103344012301 500000000000000fvwm-2.6.7/modules/FvwmM4/Makefile.am0000644000175700017570000000123012773470550014276 00000000000000## Process this file with automake to create Makefile.in moduledir = @FVWM_MODULEDIR@ module_PROGRAMS = FvwmM4 man_MANS = FvwmM4.1 EXTRA_DIST = $(man_MANS) FvwmM4_SOURCES = FvwmM4.c FvwmM4.h FvwmM4_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a ## Xpm note: while this module may not depend on Xpm explicitly, ## there are sometimes dependencies through functions in libfvwm ## so we might as well link against libXpm, if present. LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm -lm \ $(X_PRE_LIBS) -lXext -lX11 $(X_EXTRA_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) AM_CFLAGS = -DFVWM_MODULEDIR=\"$(FVWM_MODULEDIR)\" \ -DFVWM_DATADIR=\"$(FVWM_DATADIR)\" fvwm-2.6.7/modules/FvwmM4/Makefile.in0000644000175700017570000006023213010103323014266 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmM4$(EXEEXT) subdir = modules/FvwmM4 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmM4.1.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmM4.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(module_PROGRAMS) am_FvwmM4_OBJECTS = FvwmM4.$(OBJEXT) FvwmM4_OBJECTS = $(am_FvwmM4_OBJECTS) FvwmM4_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmM4_SOURCES) DIST_SOURCES = $(FvwmM4_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ man_MANS = FvwmM4.1 EXTRA_DIST = $(man_MANS) FvwmM4_SOURCES = FvwmM4.c FvwmM4.h FvwmM4_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm -lm \ $(X_PRE_LIBS) -lXext -lX11 $(X_EXTRA_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) AM_CFLAGS = -DFVWM_MODULEDIR=\"$(FVWM_MODULEDIR)\" \ -DFVWM_DATADIR=\"$(FVWM_DATADIR)\" all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmM4/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmM4/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmM4.1: $(top_builddir)/config.status $(srcdir)/FvwmM4.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmM4$(EXEEXT): $(FvwmM4_OBJECTS) $(FvwmM4_DEPENDENCIES) $(EXTRA_FvwmM4_DEPENDENCIES) @rm -f FvwmM4$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmM4_OBJECTS) $(FvwmM4_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmM4.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-modulePROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-modulePROGRAMS install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am uninstall-man \ uninstall-man1 uninstall-modulePROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmM4/FvwmM4.c0000644000175700017570000003247413001406607013527 00000000000000/* -*-c-*- */ /* This module, and the entire FvwmM4 program, and the concept for * interfacing this module to the Window Manager, are all original work * by Robert Nation * * Copyright 1994, Robert Nation * No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. */ /* 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 #include #include #include #include "libs/ftime.h" #include #include #include #include #include #include #include #include #include #include #include #include "libs/Module.h" #include "libs/Strings.h" #include "libs/System.h" #include "libs/fvwm_sys_stat.h" #include "FvwmM4.h" #include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/PictureBase.h" #include "libs/FSMlib.h" #include #include #define Resolution(pixels, mm) ((((pixels) * 2000 / (mm)) + 1) / 2) char *MyName; int fd[2]; long Vx, Vy; static char *MkDef(char *name, char *def); static char *MkNum(char *name,int def); static char *m4_defs(Display *display, const char *host, char *m4_options, char *config_file); #define MAXHOSTNAME 255 #define EXTRA 56 int m4_enable; /* use m4? */ int m4_prefix; /* Do GNU m4 prefixing (-P) */ int m4_prefix_defines; /* Add "m4_" to the names of the defines */ char m4_options[BUFSIZ]; /* Command line options to m4 */ char m4_outfile[BUFSIZ] = ""; /* The output filename for m4 */ char *m4_prog = "m4"; /* Name of the m4 program */ int m4_default_quotes; /* Use default m4 quotes */ char *m4_startquote = "`"; /* Left quote characters for m4 */ char *m4_endquote = "'"; /* Right quote characters for m4 */ /* * * Procedure: * main - start of module * */ int main(int argc, char **argv) { Display *dpy; /* which display are we talking to */ char *temp, *s; char *display_name = NULL; char *filename = NULL; char *tmp_file; int i; int debug = 0; int lock = 0; int noread = 0; char *user_dir; char *m4path; /* Figure out the working directory and go to it */ user_dir = getenv("FVWM_USERDIR"); if (user_dir != NULL) { if (chdir(user_dir) < 0) fprintf(stderr, "%s: <> chdir to %s failed in m4_defs", MyName, user_dir); } m4_enable = True; m4_prefix = False; m4_prefix_defines = False; sprintf(m4_options, " "); m4_default_quotes = 1; /* add FVWM_DATADIR to the include path. Can't use the -I option here because * it is incompatible with the System V version of m4. Instead, append it to * the front of the M4PATH environment variable. */ m4path = getenv("M4PATH"); if (m4path == NULL) { m4path = safemalloc(sizeof("M4PATH=") + strlen(FVWM_DATADIR) + 1); sprintf(m4path, "M4PATH=%s", FVWM_DATADIR); } else { char *s; s = safemalloc( sizeof("M4PATH=") + strlen(FVWM_DATADIR) + strlen(m4path) + 2); sprintf(s, "M4PATH=%s:%s", FVWM_DATADIR, m4path); m4path = s; } putenv(m4path); /* Record the program name for error messages */ temp = argv[0]; s=strrchr(argv[0], '/'); if (s != NULL) temp = s + 1; MyName = safemalloc(strlen(temp)+2); strcpy(MyName,"*"); strcat(MyName, temp); if(argc < 6) { fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName, VERSION); exit(1); } /* We should exit if our fvwm pipes die */ signal (SIGPIPE, DeadPipe); fd[0] = atoi(argv[1]); fd[1] = atoi(argv[2]); for(i=6;i %s\n", m4_prog, m4_options, tmp_name); } else { sprintf(options, "%s %s > %s\n", m4_prog, m4_options, tmp_name); } tmpf = popen(options, "w"); if (tmpf == NULL) { fprintf( stderr, "[FvwmM4][m4_defs] Cannot open pipe to m4\n"); exit(0377); } gethostname(client,MAXHOSTNAME); getostype (ostype, sizeof ostype); /* Change the quoting characters, if specified */ if (!m4_default_quotes) { fprintf( tmpf, "%schangequote(%s, %s)%sdnl\n", (m4_prefix) ? "m4_" : "", m4_startquote, m4_endquote, (m4_prefix) ? "m4_" : ""); } hostname = gethostbyname(client); strcpy(server, XDisplayName(host)); colon = strchr(server, ':'); if (colon != NULL) *colon = '\0'; if ((server[0] == '\0') || (!strcmp(server, "unix"))) strcpy(server, client); /* must be connected to :0 or unix:0 */ /* TWM_TYPE is fvwm, for completeness */ fputs(MkDef("TWM_TYPE", "fvwm"), tmpf); /* The machine running the X server */ fputs(MkDef("SERVERHOST", server), tmpf); /* The machine running the window manager process */ fputs(MkDef("CLIENTHOST", client), tmpf); if (hostname) fputs(MkDef("HOSTNAME", (char *)hostname->h_name), tmpf); else fputs(MkDef("HOSTNAME", (char *)client), tmpf); fputs(MkDef("OSTYPE", ostype), tmpf); pwent=getpwuid(geteuid()); fputs(MkDef("USER", pwent->pw_name), tmpf); fputs(MkDef("HOME", getenv("HOME")), tmpf); fputs(MkNum("VERSION", ProtocolVersion(display)), tmpf); fputs(MkNum("REVISION", ProtocolRevision(display)), tmpf); fputs(MkDef("VENDOR", ServerVendor(display)), tmpf); fputs(MkNum("RELEASE", VendorRelease(display)), tmpf); Mscreen= DefaultScreen(display); fputs(MkNum("SCREEN", Mscreen), tmpf); fputs(MkNum("WIDTH", DisplayWidth(display,Mscreen)), tmpf); fputs(MkNum("HEIGHT", DisplayHeight(display,Mscreen)), tmpf); screen = ScreenOfDisplay(display, Mscreen); fputs(MkNum( "X_RESOLUTION",Resolution(screen->width,screen->mwidth)), tmpf); fputs(MkNum( "Y_RESOLUTION",Resolution(screen->height,screen->mheight)), tmpf); fputs(MkNum("PLANES",DisplayPlanes(display, Mscreen)), tmpf); visual = DefaultVisualOfScreen(screen); fputs(MkNum("BITS_PER_RGB", visual->bits_per_rgb), tmpf); switch(visual->class) { case(StaticGray): vc = "StaticGray"; break; case(GrayScale): vc = "GrayScale"; break; case(StaticColor): vc = "StaticColor"; break; case(PseudoColor): vc = "PseudoColor"; break; case(TrueColor): vc = "TrueColor"; break; case(DirectColor): vc = "DirectColor"; break; default: vc = "NonStandard"; break; } fputs(MkDef("CLASS", vc), tmpf); switch(Pvisual->class) { case(StaticGray): vc = "StaticGray"; break; case(GrayScale): vc = "GrayScale"; break; case(StaticColor): vc = "StaticColor"; break; case(PseudoColor): vc = "PseudoColor"; break; case(TrueColor): vc = "TrueColor"; break; case(DirectColor): vc = "DirectColor"; break; default: vc = "NonStandard"; break; } fputs(MkDef("FVWM_CLASS", vc), tmpf); if (visual->class != StaticGray && visual->class != GrayScale) fputs(MkDef("COLOR", "Yes"), tmpf); else fputs(MkDef("COLOR", "No"), tmpf); if (Pvisual->class != StaticGray && Pvisual->class != GrayScale) fputs(MkDef("FVWM_COLOR", "Yes"), tmpf); else fputs(MkDef("FVWM_COLOR", "No"), tmpf); fputs(MkDef("FVWM_VERSION", VERSION), tmpf); /* Add options together */ *options = '\0'; if (FHaveShapeExtension) strcat(options, "SHAPE "); if (XpmSupport) strcat(options, "XPM "); strcat(options, "M4 "); fputs(MkDef("OPTIONS", options), tmpf); fputs(MkDef("FVWM_MODULEDIR", FVWM_MODULEDIR), tmpf); fputs(MkDef("FVWM_DATADIR", FVWM_DATADIR), tmpf); if ((vc = getenv("FVWM_USERDIR"))) fputs(MkDef("FVWM_USERDIR", vc), tmpf); if (SessionSupport && (vc = getenv("SESSION_MANAGER"))) fputs(MkDef("SESSION_MANAGER", vc), tmpf); /* * At this point, we've sent the definitions to m4. Just include * the fvwmrc file now. */ fprintf(tmpf, "%sinclude(%s%s%s)\n", (m4_prefix) ? "m4_": "", m4_startquote, config_file, m4_endquote); pclose(tmpf); return(tmp_name); } /* * * Procedure: * SIGPIPE handler - SIGPIPE means fvwm is dying * */ RETSIGTYPE DeadPipe(int nonsense) { exit(0); SIGNAL_RETURN; } static char *MkDef(char *name, char *def) { char *cp = NULL; int n; /* Get space to hold everything, if needed */ n = EXTRA + strlen(name) + strlen(def); cp = safemalloc(n); if (m4_prefix) strcpy(cp, "m4_define("); else strcpy(cp, "define("); if (m4_prefix_defines) strcat(cp, "m4_"); strcat(cp, name); /* Tack on "," and 2 sets of starting quotes */ strcat(cp, ","); strcat(cp, m4_startquote); strcat(cp, m4_startquote); /* The definition itself */ strcat(cp, def); /* Add 2 sets of closing quotes */ strcat(cp, m4_endquote); strcat(cp, m4_endquote); /* End the definition, appropriately */ strcat(cp, ")"); if (m4_prefix) strcat(cp, "m4_"); strcat(cp, "dnl\n"); return(cp); } static char *MkNum(char *name,int def) { char num[20]; sprintf(num, "%d", def); return(MkDef(name, num)); } fvwm-2.6.7/modules/FvwmM4/FvwmM4.h0000644000175700017570000000016612773467232013545 00000000000000/* -*-c-*- */ #include "libs/fvwmlib.h" /* * * Subroutine Prototypes * */ RETSIGTYPE DeadPipe(int nonsense); fvwm-2.6.7/modules/FvwmM4/FvwmM4.1.in0000644000175700017570000001324712673746443014072 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .TH FvwmM4 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmM4 \- the fvwm M4 pre-processor .SH SYNOPSIS Module FvwmM4 [options] filename The FvwmM4 module can only be invoked by fvwm. Command line invocation of the FvwmM4 module will not work. .SH DESCRIPTION When fvwm executes the FvwmM4 module, FvwmM4 invokes the M4 pre-processor on the file specified in its invocation, then FvwmM4 causes fvwm to execute the commands in the resulting file. .SH INVOCATION FvwmM4 can be invoked as a module using an fvwm command, from the .fvwm2rc file, a menu, mousebinding, or any of the many other ways fvwm commands can be issued. If the user wants his entire .fvwm2rc file pre-processed with FvwmM4, then fvwm should be invoked as: .EX fvwm -cmd "Module FvwmM4 .fvwm2rc" .EE Note that the argument to the option "-cmd" should be enclosed in quotes, and no other quoting should be used. When FvwmM4 runs as a module, it runs asynchronously from fvwm. If FvwmM4 is invoked from the .fvwm2rc, the commands generated by FvwmM4 may or may not be executed by the time fvwm processes the next command in the .fvwm2rc. Invoke FvwmM4 this way for synchronous execution: .EX ModuleSynchronous FvwmM4 -lock filename .EE .SH OPTIONS Some options can be specified following the modulename: .IP -m4-prefix I think this makes all the m4 directives require the prefix "m4_". .IP -m4-prefix-defines Causes built-in defines to be prefixed with "m4_" (i.e., m4_HOME is defined instead of HOME, etc.) .TP -m4opt \fIoption\fP Lets you pass an option to the m4 program. Not really needed as any unknown options will be passed on automatically. .TP -m4-squote \fIcharacter\fP Lets you change the m4 start-of-quote character to \fIcharacter\fP. .TP -m4-equote \fIcharacter\fP Lets you change the m4 end-of-quote character to \fIcharacter\fP. .TP -m4prog \fIname\fP Instead of invoking "m4", fvwm will invoke \fIname\fP. .TP -outfile \fIfilename\fP Instead of creating a random unique name for the temporary file for the preprocessed rc file, this option specifies the name of the temporary file created. FvwmM4 attempts to remove this file before writing to it, so don't point it at anything important even if it has read-only protection. .IP -debug Causes the temporary file created by m4 to be retained. This file is usually called "/tmp/fvwmrcXXXXXX" .IP -lock If you want to use this option you need to start FvwmM4 with ModuleSynchronous. This option causes fvwm to wait that the pre-process to finish and then FvwmM4 asks fvwm to Read the pre-processed file before continuing. This can be useful at startup if you use a session manager like Gnome. Also, this is useful if you want to process and run a Form in an fvwm function. .IP -noread Causes the pre-processed file to be not read by fvwm. Useful for pre-processing an FvwmScript script. .SH CONFIGURATION OPTIONS FvwmM4 defines some values for use in the pre-processor file: .IP TWM_TYPE Always set to "fvwm". .IP SERVERHOST The name of the machine running the X Server. .IP CLIENTHOST The name of the machine running fvwm. .IP HOSTNAME The hostname of the machine running fvwm. Generally the same as CLIENTHOST. .IP OSTYPE The operating system for CLIENTHOST. .IP USER The name of the person running fvwm. .IP HOME The home directory of the person running fvwm. .IP VERSION The X11 version. .IP REVISION The X11 revision number. .IP VENDOR The X server vendor. .IP RELEASE The X server release number. .IP SCREEN The screen number. .IP WIDTH The screen width in pixels. .IP HEIGHT The screen height in pixels. .IP X_RESOLUTION Some distance/pixel measurement for the horizontal direction, I think. .IP Y_RESOLUTION Some distance/pixel measurement for the vertical direction, I think. .IP PLANES Number of color planes for the X server display .IP BITS_PER_RGB Number of bits in each rgb triplet. .IP CLASS The X11 default visual class, e.g. PseudoColor. .IP COLOR Yes or No, Yes if the default visual class is neither StaticGrey or GreyScale. .IP FVWM_CLASS The visual class that fvwm is using, e.g. TrueColor. .IP FVWM_COLOR Yes or No, Yes if the FVWM_CLASS is neither StaticGrey or GreyScale. .IP FVWM_VERSION The fvwm version number, ie 2.0 .IP OPTIONS Some combination of SHAPE, XPM, NO_SAVEUNDERS, and M4, as defined in configure.h at compile time. .IP FVWM_MODULEDIR The directory where fvwm looks for .fvwm2rc and modules by default, as determined at compile time. .IP FVWM_USERDIR The value of $FVWM_USERDIR. .IP SESSION_MANAGER The value of $SESSION_MANAGER. Undefined if this variable is not set. .SH EXAMPLE PROLOG .EX define(TWM_TYPE,``fvwm'')dnl define(SERVERHOST,``spx20'')dnl define(CLIENTHOST,``grumpy'')dnl define(HOSTNAME,``grumpy'')dnl define(OSTYPE,``SunOS'')dnl define(USER,``nation'')dnl define(HOME,``/local/homes/dsp/nation'')dnl define(VERSION,``11'')dnl define(REVISION,``0'')dnl define(VENDOR,``HDS human designed systems, inc. (2.1.2-D)'')dnl define(RELEASE,``4'')dnl define(SCREEN,``0'')dnl define(WIDTH,``1280'')dnl define(HEIGHT,``1024'')dnl define(X_RESOLUTION,``3938'')dnl define(Y_RESOLUTION,``3938'')dnl define(PLANES,``8'')dnl define(BITS_PER_RGB,``8'')dnl define(CLASS,``PseudoColor'')dnl define(COLOR,``Yes'')dnl define(FVWM_VERSION,``1.24l'')dnl define(OPTIONS,``SHAPE XPM M4 '')dnl define(FVWM_MODULEDIR,``/local/homes/dsp/nation/modules'')dnl define(FVWM_USERDIR,``/local/homes/dsp/nation/.fvwm'')dnl define(SESSION_MANAGER,``local/grumpy:/tmp/.ICE-unix/440,tcp/spx20:1025'')dnl .EE .SH AUTHORS FvwmM4 is the result of a random bit mutation on a hard disk, presumably a result of a cosmic-ray or some such thing. fvwm-2.6.7/modules/FvwmM4/FvwmM4.10000644000175700017570000001324013010101137013421 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .TH FvwmM4 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmM4 \- the fvwm M4 pre-processor .SH SYNOPSIS Module FvwmM4 [options] filename The FvwmM4 module can only be invoked by fvwm. Command line invocation of the FvwmM4 module will not work. .SH DESCRIPTION When fvwm executes the FvwmM4 module, FvwmM4 invokes the M4 pre-processor on the file specified in its invocation, then FvwmM4 causes fvwm to execute the commands in the resulting file. .SH INVOCATION FvwmM4 can be invoked as a module using an fvwm command, from the .fvwm2rc file, a menu, mousebinding, or any of the many other ways fvwm commands can be issued. If the user wants his entire .fvwm2rc file pre-processed with FvwmM4, then fvwm should be invoked as: .EX fvwm -cmd "Module FvwmM4 .fvwm2rc" .EE Note that the argument to the option "-cmd" should be enclosed in quotes, and no other quoting should be used. When FvwmM4 runs as a module, it runs asynchronously from fvwm. If FvwmM4 is invoked from the .fvwm2rc, the commands generated by FvwmM4 may or may not be executed by the time fvwm processes the next command in the .fvwm2rc. Invoke FvwmM4 this way for synchronous execution: .EX ModuleSynchronous FvwmM4 -lock filename .EE .SH OPTIONS Some options can be specified following the modulename: .IP -m4-prefix I think this makes all the m4 directives require the prefix "m4_". .IP -m4-prefix-defines Causes built-in defines to be prefixed with "m4_" (i.e., m4_HOME is defined instead of HOME, etc.) .TP -m4opt \fIoption\fP Lets you pass an option to the m4 program. Not really needed as any unknown options will be passed on automatically. .TP -m4-squote \fIcharacter\fP Lets you change the m4 start-of-quote character to \fIcharacter\fP. .TP -m4-equote \fIcharacter\fP Lets you change the m4 end-of-quote character to \fIcharacter\fP. .TP -m4prog \fIname\fP Instead of invoking "m4", fvwm will invoke \fIname\fP. .TP -outfile \fIfilename\fP Instead of creating a random unique name for the temporary file for the preprocessed rc file, this option specifies the name of the temporary file created. FvwmM4 attempts to remove this file before writing to it, so don't point it at anything important even if it has read-only protection. .IP -debug Causes the temporary file created by m4 to be retained. This file is usually called "/tmp/fvwmrcXXXXXX" .IP -lock If you want to use this option you need to start FvwmM4 with ModuleSynchronous. This option causes fvwm to wait that the pre-process to finish and then FvwmM4 asks fvwm to Read the pre-processed file before continuing. This can be useful at startup if you use a session manager like Gnome. Also, this is useful if you want to process and run a Form in an fvwm function. .IP -noread Causes the pre-processed file to be not read by fvwm. Useful for pre-processing an FvwmScript script. .SH CONFIGURATION OPTIONS FvwmM4 defines some values for use in the pre-processor file: .IP TWM_TYPE Always set to "fvwm". .IP SERVERHOST The name of the machine running the X Server. .IP CLIENTHOST The name of the machine running fvwm. .IP HOSTNAME The hostname of the machine running fvwm. Generally the same as CLIENTHOST. .IP OSTYPE The operating system for CLIENTHOST. .IP USER The name of the person running fvwm. .IP HOME The home directory of the person running fvwm. .IP VERSION The X11 version. .IP REVISION The X11 revision number. .IP VENDOR The X server vendor. .IP RELEASE The X server release number. .IP SCREEN The screen number. .IP WIDTH The screen width in pixels. .IP HEIGHT The screen height in pixels. .IP X_RESOLUTION Some distance/pixel measurement for the horizontal direction, I think. .IP Y_RESOLUTION Some distance/pixel measurement for the vertical direction, I think. .IP PLANES Number of color planes for the X server display .IP BITS_PER_RGB Number of bits in each rgb triplet. .IP CLASS The X11 default visual class, e.g. PseudoColor. .IP COLOR Yes or No, Yes if the default visual class is neither StaticGrey or GreyScale. .IP FVWM_CLASS The visual class that fvwm is using, e.g. TrueColor. .IP FVWM_COLOR Yes or No, Yes if the FVWM_CLASS is neither StaticGrey or GreyScale. .IP FVWM_VERSION The fvwm version number, ie 2.0 .IP OPTIONS Some combination of SHAPE, XPM, NO_SAVEUNDERS, and M4, as defined in configure.h at compile time. .IP FVWM_MODULEDIR The directory where fvwm looks for .fvwm2rc and modules by default, as determined at compile time. .IP FVWM_USERDIR The value of $FVWM_USERDIR. .IP SESSION_MANAGER The value of $SESSION_MANAGER. Undefined if this variable is not set. .SH EXAMPLE PROLOG .EX define(TWM_TYPE,``fvwm'')dnl define(SERVERHOST,``spx20'')dnl define(CLIENTHOST,``grumpy'')dnl define(HOSTNAME,``grumpy'')dnl define(OSTYPE,``SunOS'')dnl define(USER,``nation'')dnl define(HOME,``/local/homes/dsp/nation'')dnl define(VERSION,``11'')dnl define(REVISION,``0'')dnl define(VENDOR,``HDS human designed systems, inc. (2.1.2-D)'')dnl define(RELEASE,``4'')dnl define(SCREEN,``0'')dnl define(WIDTH,``1280'')dnl define(HEIGHT,``1024'')dnl define(X_RESOLUTION,``3938'')dnl define(Y_RESOLUTION,``3938'')dnl define(PLANES,``8'')dnl define(BITS_PER_RGB,``8'')dnl define(CLASS,``PseudoColor'')dnl define(COLOR,``Yes'')dnl define(FVWM_VERSION,``1.24l'')dnl define(OPTIONS,``SHAPE XPM M4 '')dnl define(FVWM_MODULEDIR,``/local/homes/dsp/nation/modules'')dnl define(FVWM_USERDIR,``/local/homes/dsp/nation/.fvwm'')dnl define(SESSION_MANAGER,``local/grumpy:/tmp/.ICE-unix/440,tcp/spx20:1025'')dnl .EE .SH AUTHORS FvwmM4 is the result of a random bit mutation on a hard disk, presumably a result of a cosmic-ray or some such thing. fvwm-2.6.7/modules/FvwmAnimate/0000755000175700017570000000000013010103342013375 500000000000000fvwm-2.6.7/modules/FvwmAnimate/FvwmAnimate.1.in0000644000175700017570000001450212753310630016241 00000000000000.\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH FvwmAnimate 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME \fBFvwmAnimate\fP \- the fvwm animate module .SH SYNOPSIS Module FvwmAnimate [ModuleAlias] \fBFvwmAnimate\fP can only be invoked by fvwm. Command line invocation of the FvwmAnimate module will not work. From within the .fvwm2rc file, \fBFvwmAnimate\fP is spawned as follows: .nf .sp Module FvwmAnimate .sp .fi or from within an fvwm pop-up menu: .nf .sp DestroyMenu Module-Popup AddToMenu Module-Popup "Modules" Title + "Fvwm Animate Icons" Module FvwmAnimate ModuleAlias .sp .fi .SH DESCRIPTION The \fBFvwmAnimate\fP module animates iconification and de-iconification or on command. There are currently 6 different animation effects. .SH INVOCATION \fBFvwmAnimate\fP must be invoked by the \fBfvwm\fP window manager. When invoked with the \fIOptionalName\fP argument, the \fIModuleAlias\fP is used to find configuration commands, configuration files, and name the internally generated menus and forms instead of "FvwmAnimate". During startup, FvwmAnimate defines menus and forms for configuring and controlling FvwmAnimate. The default menu name is "MenuFvwmAnimate" and the form name is "FormFvwmAnimate". If the optional name is used, the menu would be "Menu" and the form would be "Form". .sp Assuming you already had a builtin menu called "Module-Popup", you could use FvwmAnimate by configuring it like this: .nf .sp AddToFunc "StartFunction" "I" Module FvwmAnimate AddToMenu "Module-Popup" "Control Animation" Popup MenuFvwmAnimate .sp .fi .SH CONFIGURATION OPTIONS Since the pop up menu "MenuFvwmAnimate" allows complete control of the \fBFvwmAnimate\fP module, you don't really have to know what any of the configuration commands are. This section describes them anyway. \fBFvwmAnimate\fP gets configuration info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ). In addition, \fBFvwmAnimate\fP reads the file $HOME/.FvwmAnimate, and accepts commands from fvwm and its modules as it runs. If \fIModuleAlias\fP is used to start FvwmAnimate, the optional name is used in all commands, messages, menus and forms generated by FvwmAnimate and in the configuration file name. Unlike other fvwm modules, there is little reason to use the optional name. .IP "*FvwmAnimate: Color \fBcolor\fP" Tells \fBFvwmAnimate\fP what color to draw with. The color is "XOR'ed" (exclusive ORed) onto the background. Depending on the display type you are using, the effect this causes will vary. Especially on 8-bit displays, it helps if the background is a solid color. You have to experiment with this to see how it works. The default color is not really a color and can be entered as "Black^White", or more simply "None". This is the same as the default XOR mask used by fvwm for move and resize frames. Other colors can be specified using standard X color notation. Ie. color names like "LightBlue", or RGB values like "#FFFFFF". .IP "*FvwmAnimate: Pixmap \fBpixmap\fP" Tells \fBFvwmAnimate\fP to use \fBpixmap\fP to draw with. This can be useful if \fB*FvwmAnimate: Color\fP gives poor results. .IP "*FvwmAnimate: Delay \fBmsecs\fP" Tells \fBFvwmAnimate\fP how many milliseconds to sleep between frames of animation. .IP "*FvwmAnimate: Iterations \fBiterations\fP" Tells \fBFvwmAnimate\fP how many steps to break the animation into. .IP "*FvwmAnimate: Twist \fBtwist\fP" Tells \fBFvwmAnimate\fP how many revolutions to twist the iconification frame. .IP "*FvwmAnimate: Width \fBwidth\fP" Tells \fBFvwmAnimate\fP how wide a line to draw with. The default width of 0 (zero) is a fast line of Width 1. .IP "*FvwmAnimate: Effect \fBmode\fP" Tells \fBFvwmAnimate\fP which animation effect to use. Currently the effects are: \fIFrame\fP, \fILines\fP, \fIFlip\fP, \fITurn\fP, \fIZoom3D\fP, \fITwist\fP \fIRandom\fP, and \fINone\fP. \fINone\fP is normally set in the configuration file, in-case FvwmAnimate is started automatically, but an individual user doesn't want it running. .IP "*FvwmAnimate: Stop" Tells \fBFvwmAnimate\fP to stop. .IP "*FvwmAnimate: Save" Tells \fBFvwmAnimate\fP to save the current configuration in a file named ".FvwmAnimate" in the users home directory. This same file is read automatically by FvwmAnimate during startup. .SH COMMANDS \fBFvwmAnimate\fP can be asked to produce an animation thru the "SendToModule" command. The format of the command is: .nf .sp .in +.5i SendToModule FvwmAnimate animate sx sy sw sh dx dy dw dh .in -.5i .sp .fi The second word must match the name \fBFvwmAnimate\fP is started with. The 8 fields after .I animate must be numbers. The first 4 are for the source (or starting) location of the animation. The last 4 are for the destination of the animation. The 2 pairs of 4 numbers, represent rectangles. The first 2 numbers are the x and y location of the upper right corner. The next 2 numbers are the width and height. One or more spaces can separate the fields in the command. Modules can use the "SendToModule" command to animate "NoIcon" windows, or you can think up your own ways to have all kinds of fun with this command. Additional available commands are: .IR pause ", " play ", " .IR push ", " pop " and " reset . These may be space separated. .I pause causes a module to not temporarily produce any animations. .I play causes a module to produce an animation again. .I push stores the current playing state for a future and .I pop restores it. .I reset removes all stored states and sets playing on. Suppose, we don't want to wait for all 40 xterms to be animated: .nf .sp .in +.5i SendToModule FvwmAnimate pause All (XTerm) Iconify on .in -.5i .sp .fi And if we don't want to damage the current playing state, then: .nf .sp .in +.5i SendToModule FvwmAnimate push pause All (XTerm) Iconify on SendToModule FvwmAnimate pop .in -.5i .sp .fi .SH ORIGIN \fBFvwmAnimate\fP is based on the \fBAnimate\fP module from Afterstep 1.5pre6. Porting to \fBfvwm\fP and lots of other changes were done by \fIDan Espen\fP . Below are the original author and acknowledgments. .SH AUTHOR \fIAlfredo Kengi Kojima\fP .SH ACKNOWLEDGMENTS These people have contributed to \fBFvwmAnimate\fP: .IP "\fIKaj Groner\fP " Twisty iconification, configuration file parsing, man page. .IP "\fIFrank Scheelen\fP " fvwm-2.6.7/modules/FvwmAnimate/Makefile.am0000644000175700017570000000136312773470550015403 00000000000000## Process this file with automake to create Makefile.in moduledir = @FVWM_MODULEDIR@ module_PROGRAMS = FvwmAnimate man_MANS = FvwmAnimate.1 EXTRA_DIST = $(man_MANS) FvwmAnimate_SOURCES = FvwmAnimate.c FvwmAnimate.h FvwmAnimate_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a ## Xpm note: while this module may not depend on Xpm explicitly, ## there are sometimes dependencies through functions in libfvwm ## so we might as well link against libXpm, if present. LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm $(xpm_LIBS) $(rplay_LIBS) \ $(X_PRE_LIBS) -lXext -lX11 $(X_EXTRA_LIBS) -lm $(png_LIBS) \ $(rsvg_LIBS) $(Xrender_LIBS) $(Xcursor_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(rplay_CFLAGS) $(X_CFLAGS) \ $(png_CFLAGS) $(Xrender_CFLAGS) fvwm-2.6.7/modules/FvwmAnimate/Makefile.in0000644000175700017570000006054313010103322015370 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmAnimate$(EXEEXT) subdir = modules/FvwmAnimate DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmAnimate.1.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmAnimate.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(module_PROGRAMS) am_FvwmAnimate_OBJECTS = FvwmAnimate.$(OBJEXT) FvwmAnimate_OBJECTS = $(am_FvwmAnimate_OBJECTS) FvwmAnimate_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmAnimate_SOURCES) DIST_SOURCES = $(FvwmAnimate_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ man_MANS = FvwmAnimate.1 EXTRA_DIST = $(man_MANS) FvwmAnimate_SOURCES = FvwmAnimate.c FvwmAnimate.h FvwmAnimate_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm $(xpm_LIBS) $(rplay_LIBS) \ $(X_PRE_LIBS) -lXext -lX11 $(X_EXTRA_LIBS) -lm $(png_LIBS) \ $(rsvg_LIBS) $(Xrender_LIBS) $(Xcursor_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(rplay_CFLAGS) $(X_CFLAGS) \ $(png_CFLAGS) $(Xrender_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmAnimate/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmAnimate/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmAnimate.1: $(top_builddir)/config.status $(srcdir)/FvwmAnimate.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmAnimate$(EXEEXT): $(FvwmAnimate_OBJECTS) $(FvwmAnimate_DEPENDENCIES) $(EXTRA_FvwmAnimate_DEPENDENCIES) @rm -f FvwmAnimate$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmAnimate_OBJECTS) $(FvwmAnimate_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmAnimate.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-modulePROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-modulePROGRAMS install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am uninstall-man \ uninstall-man1 uninstall-modulePROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmAnimate/FvwmAnimate.10000644000175700017570000001447313010101137015626 00000000000000.\" @(#)fvwm-2.6.7 06 November 2016 .TH FvwmAnimate 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME \fBFvwmAnimate\fP \- the fvwm animate module .SH SYNOPSIS Module FvwmAnimate [ModuleAlias] \fBFvwmAnimate\fP can only be invoked by fvwm. Command line invocation of the FvwmAnimate module will not work. From within the .fvwm2rc file, \fBFvwmAnimate\fP is spawned as follows: .nf .sp Module FvwmAnimate .sp .fi or from within an fvwm pop-up menu: .nf .sp DestroyMenu Module-Popup AddToMenu Module-Popup "Modules" Title + "Fvwm Animate Icons" Module FvwmAnimate ModuleAlias .sp .fi .SH DESCRIPTION The \fBFvwmAnimate\fP module animates iconification and de-iconification or on command. There are currently 6 different animation effects. .SH INVOCATION \fBFvwmAnimate\fP must be invoked by the \fBfvwm\fP window manager. When invoked with the \fIOptionalName\fP argument, the \fIModuleAlias\fP is used to find configuration commands, configuration files, and name the internally generated menus and forms instead of "FvwmAnimate". During startup, FvwmAnimate defines menus and forms for configuring and controlling FvwmAnimate. The default menu name is "MenuFvwmAnimate" and the form name is "FormFvwmAnimate". If the optional name is used, the menu would be "Menu" and the form would be "Form". .sp Assuming you already had a builtin menu called "Module-Popup", you could use FvwmAnimate by configuring it like this: .nf .sp AddToFunc "StartFunction" "I" Module FvwmAnimate AddToMenu "Module-Popup" "Control Animation" Popup MenuFvwmAnimate .sp .fi .SH CONFIGURATION OPTIONS Since the pop up menu "MenuFvwmAnimate" allows complete control of the \fBFvwmAnimate\fP module, you don't really have to know what any of the configuration commands are. This section describes them anyway. \fBFvwmAnimate\fP gets configuration info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ). In addition, \fBFvwmAnimate\fP reads the file $HOME/.FvwmAnimate, and accepts commands from fvwm and its modules as it runs. If \fIModuleAlias\fP is used to start FvwmAnimate, the optional name is used in all commands, messages, menus and forms generated by FvwmAnimate and in the configuration file name. Unlike other fvwm modules, there is little reason to use the optional name. .IP "*FvwmAnimate: Color \fBcolor\fP" Tells \fBFvwmAnimate\fP what color to draw with. The color is "XOR'ed" (exclusive ORed) onto the background. Depending on the display type you are using, the effect this causes will vary. Especially on 8-bit displays, it helps if the background is a solid color. You have to experiment with this to see how it works. The default color is not really a color and can be entered as "Black^White", or more simply "None". This is the same as the default XOR mask used by fvwm for move and resize frames. Other colors can be specified using standard X color notation. Ie. color names like "LightBlue", or RGB values like "#FFFFFF". .IP "*FvwmAnimate: Pixmap \fBpixmap\fP" Tells \fBFvwmAnimate\fP to use \fBpixmap\fP to draw with. This can be useful if \fB*FvwmAnimate: Color\fP gives poor results. .IP "*FvwmAnimate: Delay \fBmsecs\fP" Tells \fBFvwmAnimate\fP how many milliseconds to sleep between frames of animation. .IP "*FvwmAnimate: Iterations \fBiterations\fP" Tells \fBFvwmAnimate\fP how many steps to break the animation into. .IP "*FvwmAnimate: Twist \fBtwist\fP" Tells \fBFvwmAnimate\fP how many revolutions to twist the iconification frame. .IP "*FvwmAnimate: Width \fBwidth\fP" Tells \fBFvwmAnimate\fP how wide a line to draw with. The default width of 0 (zero) is a fast line of Width 1. .IP "*FvwmAnimate: Effect \fBmode\fP" Tells \fBFvwmAnimate\fP which animation effect to use. Currently the effects are: \fIFrame\fP, \fILines\fP, \fIFlip\fP, \fITurn\fP, \fIZoom3D\fP, \fITwist\fP \fIRandom\fP, and \fINone\fP. \fINone\fP is normally set in the configuration file, in-case FvwmAnimate is started automatically, but an individual user doesn't want it running. .IP "*FvwmAnimate: Stop" Tells \fBFvwmAnimate\fP to stop. .IP "*FvwmAnimate: Save" Tells \fBFvwmAnimate\fP to save the current configuration in a file named ".FvwmAnimate" in the users home directory. This same file is read automatically by FvwmAnimate during startup. .SH COMMANDS \fBFvwmAnimate\fP can be asked to produce an animation thru the "SendToModule" command. The format of the command is: .nf .sp .in +.5i SendToModule FvwmAnimate animate sx sy sw sh dx dy dw dh .in -.5i .sp .fi The second word must match the name \fBFvwmAnimate\fP is started with. The 8 fields after .I animate must be numbers. The first 4 are for the source (or starting) location of the animation. The last 4 are for the destination of the animation. The 2 pairs of 4 numbers, represent rectangles. The first 2 numbers are the x and y location of the upper right corner. The next 2 numbers are the width and height. One or more spaces can separate the fields in the command. Modules can use the "SendToModule" command to animate "NoIcon" windows, or you can think up your own ways to have all kinds of fun with this command. Additional available commands are: .IR pause ", " play ", " .IR push ", " pop " and " reset . These may be space separated. .I pause causes a module to not temporarily produce any animations. .I play causes a module to produce an animation again. .I push stores the current playing state for a future and .I pop restores it. .I reset removes all stored states and sets playing on. Suppose, we don't want to wait for all 40 xterms to be animated: .nf .sp .in +.5i SendToModule FvwmAnimate pause All (XTerm) Iconify on .in -.5i .sp .fi And if we don't want to damage the current playing state, then: .nf .sp .in +.5i SendToModule FvwmAnimate push pause All (XTerm) Iconify on SendToModule FvwmAnimate pop .in -.5i .sp .fi .SH ORIGIN \fBFvwmAnimate\fP is based on the \fBAnimate\fP module from Afterstep 1.5pre6. Porting to \fBfvwm\fP and lots of other changes were done by \fIDan Espen\fP . Below are the original author and acknowledgments. .SH AUTHOR \fIAlfredo Kengi Kojima\fP .SH ACKNOWLEDGMENTS These people have contributed to \fBFvwmAnimate\fP: .IP "\fIKaj Groner\fP " Twisty iconification, configuration file parsing, man page. .IP "\fIFrank Scheelen\fP " fvwm-2.6.7/modules/FvwmAnimate/FvwmAnimate.c0000644000175700017570000014271013001406607015716 00000000000000/* -*-c-*- */ /* * FvwmAnimate! Animation module for fvwm * * Copyright (c) 1997 Frank Scheelen * Copyright (c) 1996 Alfredo Kengi Kojima (kojima@inf.ufrgs.br) * Copyright (c) 1996 Kaj Groner * Added .steprc parsing and twisty iconify. * * Copyright (c) 1998 Dan Espen * Changed to run under fvwm. Lots of changes made. * This used to only animate iconify on M_CONFIGURE_WINDOW. * This module no longer reads M_CONFIGURE_WINDOW. * I added args to M_ICONIFY so iconification takes one message. * The arg parsing is completely redone using library functions. * I also added args to M_DEICONIFY to eliminate the need to read the * window size. * Added AnimateResizeLines animation effect. * Changed option "resize" to "effect", (resize still works). * Changed effect "zoom" to "frame", (zoom still works). * Added myfprintf double parens debugging trick. * Changed so that commands can be sent to this module while it is * running. * Changed so that this module creates its own built in menu. * Added Stop, Save commands. * Changed so this this module uses FvwmForm for complete control on all * settings. * Anything can request an animation thru "sendtomodule". * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include #include #include #include #include #include /* for O_WRONLY */ #include #include "libs/ftime.h" #include #include "libs/fvwmsignal.h" #include "libs/Module.h" #include "libs/fvwmlib.h" #include "libs/Picture.h" #include "libs/PictureGraphics.h" #include "libs/PictureUtils.h" #include "libs/FRenderInit.h" #include "libs/Grab.h" #include "libs/Graphics.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "FvwmAnimate.h" #define AS_PI 3.14159265358979323846 static Display *dpy; GC gc; static ModuleArgs* module; static int Channel[2]; static XColor xcol; static unsigned long color; /* color for animation */ static Pixmap pixmap = None; /* pixmap for weirdness */ static XGCValues gcv; static int animate_none = 0; /* count bypassed animations */ static Bool stop_recvd = False; /* got stop command */ static Bool running = False; /* whether we are initiialized or not */ static Bool custom_recvd = False; /* got custom command */ #define MAX_SAVED_STATES 25 static Bool play_state = True; /* current state: pause or play */ static unsigned int num_saved_play_states = 0; static Bool saved_play_states[MAX_SAVED_STATES]; static struct { int screen; Window root; int MyDisplayWidth; int MyDisplayHeight; int Vx; int Vy; int CurrentDesk; } Scr; /* here is the old double parens trick. */ /* #define DEBUG */ #ifdef DEBUG #define myfprintf(X) \ fprintf X;\ fflush (stderr); #else #define myfprintf(X) #endif /* #define DEBUG_ANIMATION */ #ifdef DEBUG_ANIMATION #define myaprintf(X) \ fprintf X;\ fflush (stderr); #else #define myaprintf(X) #endif /* Macros for creating and sending commands: CMD1X - module->name CMD10 - module->name, CatString3("*",module->name,0) CMD11 - module->name,module->name */ #define CMD1X(TEXT) \ sprintf(cmd,TEXT,module->name);\ SendText(Channel,cmd,0); #define CMD10(TEXT) \ sprintf(cmd,TEXT,module->name,CatString3("*",module->name,0));\ SendText(Channel,cmd,0); #define CMD11(TEXT) \ sprintf(cmd,TEXT,module->name,module->name);\ SendText(Channel,cmd,0); static void Loop(void); static void ParseOptions(void); static void ParseConfigLine(char *); static void CreateDrawGC(void); static void DefineMe(void); static void SaveConfig(void); static void StopCmd(void); static void AnimateResizeZoom(int, int, int, int, int, int, int, int); static void AnimateResizeLines(int, int, int, int, int, int, int, int); static void AnimateResizeFlip(int, int, int, int, int, int, int, int); static void AnimateResizeTurn(int, int, int, int, int, int, int, int); static void AnimateResizeRandom(int, int, int, int, int, int, int, int); static void AnimateResizeZoom3D(int, int, int, int, int, int, int, int); static void AnimateResizeNone(int, int, int, int, int, int, int, int); static void AnimateResizeTwist(int, int, int, int, int, int, int, int); static void DefineForm(void); static RETSIGTYPE HandleTerminate(int sig); struct ASAnimate Animate = { NULL, NULL, ANIM_ITERATIONS, ANIM_DELAY, ANIM_TWIST, ANIM_WIDTH, AnimateResizeTwist, ANIM_TIME }; /* We now have so many effects, that I feel the need for a table. */ typedef struct AnimateEffects { char *name; char *alias; void (*function)(int, int, int, int, int, int, int, int); char *button; /* used to set custom form */ } ae; /* Note None and Random must be the first 2 entries. */ struct AnimateEffects effects[] = { {"None", 0, AnimateResizeNone, NULL}, {"Random", 0, AnimateResizeRandom, NULL}, {"Flip", 0, AnimateResizeFlip, NULL}, {"Frame", "Zoom", AnimateResizeZoom, NULL}, {"Frame3D", "Zoom3D", AnimateResizeZoom3D, NULL}, {"Lines", 0, AnimateResizeLines, NULL}, {"Turn", 0, AnimateResizeTurn, NULL}, {"Twist", 0, AnimateResizeTwist, NULL} }; #define NUM_EFFECTS sizeof(effects) / sizeof(struct AnimateEffects) static Bool is_animation_visible( int x, int y, int w, int h, int fx, int fy, int fw, int fh) { Bool is_start_visible = True; Bool is_end_visible = True; if (x >= Scr.MyDisplayWidth || x + w < 0 || y >= Scr.MyDisplayWidth || y + h < 0) { is_start_visible = False; } if (fx >= Scr.MyDisplayWidth || fx + fw < 0 || fy >= Scr.MyDisplayWidth || fy + fh < 0) { is_end_visible = False; } return (is_start_visible || is_end_visible); } /* * This makes a twisty iconify/deiconify animation for a window, similar to * MacOS. Parameters specify the position and the size of the initial * window and the final window */ static void AnimateResizeTwist( int x, int y, int w, int h, int fx, int fy, int fw, int fh) { float cx, cy, cw, ch; float xstep, ystep, wstep, hstep; XPoint points[5]; float angle, angle_finite, a, d; if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; x += w/2; y += h/2; fx += fw/2; fy += fh/2; xstep = (float)(fx-x)/Animate.iterations; ystep = (float)(fy-y)/Animate.iterations; wstep = (float)(fw-w)/Animate.iterations; hstep = (float)(fh-h)/Animate.iterations; cx = (float)x; cy = (float)y; cw = (float)w; ch = (float)h; a = atan(ch/cw); d = sqrt((cw/2)*(cw/2)+(ch/2)*(ch/2)); angle_finite = 2*AS_PI*Animate.twist; MyXGrabServer(dpy); XInstallColormap(dpy, Pcmap); for (angle=0;; angle+=(float)(2*AS_PI*Animate.twist/Animate.iterations)) { if (angle > angle_finite) angle = angle_finite; points[0].x = cx+cos(angle-a)*d; points[0].y = cy+sin(angle-a)*d; points[1].x = cx+cos(angle+a)*d; points[1].y = cy+sin(angle+a)*d; points[2].x = cx+cos(angle-a+AS_PI)*d; points[2].y = cy+sin(angle-a+AS_PI)*d; points[3].x = cx+cos(angle+a+AS_PI)*d; points[3].y = cy+sin(angle+a+AS_PI)*d; points[4].x = cx+cos(angle-a)*d; points[4].y = cy+sin(angle-a)*d; XDrawLines(dpy, Scr.root, gc, points, 5, CoordModeOrigin); XFlush(dpy); usleep(Animate.delay*1000); XDrawLines(dpy, Scr.root, gc, points, 5, CoordModeOrigin); cx+=xstep; cy+=ystep; cw+=wstep; ch+=hstep; a = atan(ch/cw); d = sqrt((cw/2)*(cw/2)+(ch/2)*(ch/2)); if (angle >= angle_finite) break; } MyXUngrabServer(dpy); } /* * Add even more 3D feel to AfterStep by doing a flipping iconify. * Parameters specify the position and the size of the initial and the * final window. * * Idea: how about texture mapped, user definable free 3D movement * during a resize? That should get X on its knees all right! :) */ void AnimateResizeFlip( int x, int y, int w, int h, int fx, int fy, int fw, int fh) { float cx, cy, cw, ch; float xstep, ystep, wstep, hstep; XPoint points[5]; float distortx; float distortch; float midy; float angle, angle_finite; if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; xstep = (float) (fx - x) / Animate.iterations; ystep = (float) (fy - y) / Animate.iterations; wstep = (float) (fw - w) / Animate.iterations; hstep = (float) (fh - h) / Animate.iterations; cx = (float) x; cy = (float) y; cw = (float) w; ch = (float) h; angle_finite = 2 * AS_PI * Animate.twist; MyXGrabServer(dpy); XInstallColormap(dpy, Pcmap); for (angle = 0; ; angle += (float) (2 * AS_PI * Animate.twist / Animate.iterations)) { if (angle > angle_finite) angle = angle_finite; distortx = (cw / 10) - ((cw / 5) * sin(angle)); distortch = (ch / 2) * cos(angle); midy = cy + (ch / 2); points[0].x = cx + distortx; points[0].y = midy - distortch; points[1].x = cx + cw - distortx; points[1].y = points[0].y; points[2].x = cx + cw + distortx; points[2].y = midy + distortch; points[3].x = cx - distortx; points[3].y = points[2].y; points[4].x = points[0].x; points[4].y = points[0].y; XDrawLines(dpy, Scr.root, gc, points, 5, CoordModeOrigin); XFlush(dpy); usleep(Animate.delay * 1000); XDrawLines(dpy, Scr.root, gc, points, 5, CoordModeOrigin); cx += xstep; cy += ystep; cw += wstep; ch += hstep; if (angle >= angle_finite) break; } MyXUngrabServer(dpy); } /* * And another one, this time around the Y-axis. */ void AnimateResizeTurn( int x, int y, int w, int h, int fx, int fy, int fw, int fh) { float cx, cy, cw, ch; float xstep, ystep, wstep, hstep; XPoint points[5]; float distorty; float distortcw; float midx; float angle, angle_finite; if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; xstep = (float) (fx - x) / Animate.iterations; ystep = (float) (fy - y) / Animate.iterations; wstep = (float) (fw - w) / Animate.iterations; hstep = (float) (fh - h) / Animate.iterations; cx = (float) x; cy = (float) y; cw = (float) w; ch = (float) h; angle_finite = 2 * AS_PI * Animate.twist; MyXGrabServer(dpy); XInstallColormap(dpy, Pcmap); for (angle = 0; ; angle += (float) (2 * AS_PI * Animate.twist / Animate.iterations)) { if (angle > angle_finite) angle = angle_finite; distorty = (ch / 10) - ((ch / 5) * sin(angle)); distortcw = (cw / 2) * cos(angle); midx = cx + (cw / 2); points[0].x = midx - distortcw; points[0].y = cy + distorty; points[1].x = midx + distortcw; points[1].y = cy - distorty; points[2].x = points[1].x; points[2].y = cy + ch + distorty; points[3].x = points[0].x; points[3].y = cy + ch - distorty; points[4].x = points[0].x; points[4].y = points[0].y; XDrawLines(dpy, Scr.root, gc, points, 5, CoordModeOrigin); XFlush(dpy); usleep(Animate.delay * 1000); XDrawLines(dpy, Scr.root, gc, points, 5, CoordModeOrigin); cx += xstep; cy += ystep; cw += wstep; ch += hstep; if (angle >= angle_finite) break; } MyXUngrabServer(dpy); } /* * This makes a zooming iconify/deiconify animation for a window, like most * any other icon animation out there. Parameters specify the position and * the size of the initial window and the final window */ static void AnimateResizeZoom(int x, int y, int w, int h, int fx, int fy, int fw, int fh) { float cx, cy, cw, ch; float xstep, ystep, wstep, hstep; int i; if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; xstep = (float)(fx-x)/Animate.iterations; ystep = (float)(fy-y)/Animate.iterations; wstep = (float)(fw-w)/Animate.iterations; hstep = (float)(fh-h)/Animate.iterations; cx = (float)x; cy = (float)y; cw = (float)w; ch = (float)h; MyXGrabServer(dpy); XInstallColormap(dpy, Pcmap); for (i=0; i */ void AnimateResizeZoom3D( int x, int y, int w, int h, int fx, int fy, int fw, int fh) { float cx, cy, cw, ch; float xstep, ystep, wstep, hstep, srca, dsta; int i; if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; xstep = (float) (fx - x) / Animate.iterations; ystep = (float) (fy - y) / Animate.iterations; wstep = (float) (fw - w) / Animate.iterations; hstep = (float) (fh - h) / Animate.iterations; dsta = (float) (fw + fh); srca = (float) (w + h); cx = (float) x; cy = (float) y; cw = (float) w; ch = (float) h; MyXGrabServer(dpy); XInstallColormap(dpy, Pcmap); if (dsta <= srca) /* We are going from a Window to an Icon */ { for (i = 0; i < Animate.iterations; i++) { XDrawRectangle(dpy, Scr.root, gc, (int) cx, (int) cy, (int) cw, (int) ch); XDrawRectangle(dpy, Scr.root, gc, (int) fx, (int) fy, (int) fw, (int) fh); XDrawLine(dpy, Scr.root, gc, (int) cx, (int) cy, fx, fy); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), (int) cy, (fx + fw), fy); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), ((int) cy + (int) ch), (fx + fw), (fy + fh)); XDrawLine(dpy, Scr.root, gc, (int) cx, ((int) cy + (int) ch), fx, (fy + fh)); XFlush(dpy); usleep(Animate.delay * 1000); XDrawRectangle(dpy, Scr.root, gc, (int) cx, (int) cy, (int) cw, (int) ch); XDrawRectangle(dpy, Scr.root, gc, (int) fx, (int) fy, (int) fw, (int) fh); XDrawLine(dpy, Scr.root, gc, (int) cx, (int) cy, fx, fy); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), (int) cy, (fx + fw), fy); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), ((int) cy + (int) ch), (fx + fw), (fy + fh)); XDrawLine(dpy, Scr.root, gc, (int) cx, ((int) cy + (int) ch), fx, (fy + fh)); cx += xstep; cy += ystep; cw += wstep; ch += hstep; } } if (dsta > srca) { /* We are going from an Icon to a Window */ for (i = 0; i < Animate.iterations; i++) { XDrawRectangle(dpy, Scr.root, gc, (int) cx, (int) cy, (int) cw, (int) ch); XDrawRectangle(dpy, Scr.root, gc, x, y, w, h); XDrawLine(dpy, Scr.root, gc, (int) cx, (int) cy, x, y); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), (int) cy, (x + w), y); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), ((int) cy + (int) ch), (x + w), (y + h)); XDrawLine(dpy, Scr.root, gc, (int) cx, ((int) cy + (int) ch), x, (y + h)); XFlush(dpy); usleep(Animate.delay * 1000); XDrawRectangle(dpy, Scr.root, gc, (int) cx, (int) cy, (int) cw, (int) ch); XDrawRectangle(dpy, Scr.root, gc, x, y, w, h); XDrawLine(dpy, Scr.root, gc, (int) cx, (int) cy, x, y); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), (int) cy, (x + w), y); XDrawLine(dpy, Scr.root, gc, ((int) cx + (int) cw), ((int) cy + (int) ch), (x + w), (y + h)); XDrawLine(dpy, Scr.root, gc, (int) cx, ((int) cy + (int) ch), x, (y + h)); cx += xstep; cy += ystep; cw += wstep; ch += hstep; } } MyXUngrabServer(dpy); } /* * This picks one of the animations and calls it. */ void AnimateResizeRandom( int x, int y, int w, int h, int fx, int fy, int fw, int fh) { if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; /* Note, first 2 effects "None" and "Random" should never be chosen */ effects[(rand() + (x * y + w * h + fx)) % (NUM_EFFECTS - 2) + 2].function (x, y, w, h, fx, fy, fw, fh); } /* * This animation creates 4 lines from each corner of the initial window, * to each corner of the final window. * * Parameters specify the position and the size of the initial window and * the final window. * * Starting with x/y w/h, need to draw sets of 4 line segs from initial * to final window. * * The variable "ants" controls whether each iteration is drawn and then * erased vs. draw all the segments and then come back and erase them. * * Currently I have this hardcoded as the later. The word "ants" is * used, because if "ants" is set to 0 and the number of iterations is * high, it looks a little like ants crawling across the screen. */ static void AnimateResizeLines(int x, int y, int w, int h, int fx, int fy, int fw, int fh) { int i, j; int ants = 1, ant_ctr; typedef struct { XSegment seg[4]; /* draw 4 unconnected lines */ XSegment incr[4]; /* x/y increments */ } Endpoints; Endpoints ends[2]; if (!is_animation_visible(x, y, w, h, fx, fy, fw, fh)) return; /* define the array occurances */ #define UR seg[0] #define UL seg[1] #define LR seg[2] #define LL seg[3] #define BEG ends[0] #define INC ends[1] if (ants == 1) { /* if draw then erase */ MyXGrabServer(dpy); /* grab for whole animation */ XInstallColormap(dpy, Pcmap); } for (ant_ctr=0;ant_ctr<=ants;ant_ctr++) { /* Put args into arrays: */ BEG.UR.x1 = x; /* upper left */ BEG.UR.y1 = y; /* Temporarily put width and height in Lower Left slot. Changed to Lower Left x/y later. */ BEG.LL.x1 = w; BEG.LL.y1 = h; /* Use final positions to calc increments. */ INC.UR.x1 = fx; INC.UR.y1 = fy; INC.LL.x1 = fw; INC.LL.y1 = fh; /* The lines look a little better if they start and end a little in from the edges. Allowing tuning might be overkill. */ for (i=0;i<2;i++) { /* for begin and endpoints */ if (ends[i].LL.x1 > 40) { /* if width > 40 */ ends[i].LL.x1 -=16; /* reduce width a little */ ends[i].UR.x1 += 8; /* move in a little */ } if (ends[i].LL.y1 > 40) { /* if height > 40 */ ends[i].LL.y1 -=16; /* reduce height a little */ ends[i].UR.y1 += 8; /* move down a little */ } /* Upper Left, Use x from Upper Right + width */ ends[i].UL.x1 = ends[i].UR.x1 + ends[i].LL.x1; ends[i].UL.y1 = ends[i].UR.y1; /* copy y */ /* Lower Right, Use y from Upper Right + height */ ends[i].LR.x1 = ends[i].UR.x1; /* copy x */ ends[i].LR.y1 = ends[i].UR.y1 + ends[i].LL.y1; /* Now width and height have been used, change LL to endpoints. */ ends[i].LL.x1 += ends[i].UR.x1; ends[i].LL.y1 += ends[i].UR.y1; } /* Now put the increment in the end x/y slots */ for (i=0;i<4;i++) { /* for each of 4 line segs */ INC.seg[i].x2 = (INC.seg[i].x1 - BEG.seg[i].x1)/Animate.iterations; INC.seg[i].y2 = (INC.seg[i].y1 - BEG.seg[i].y1)/Animate.iterations; } for (i=0; i4) { step = h*4/Animate.iterations; if (step==0) { step = 2; } for (i=h; i>=2; i-=step) { XDrawRectangle(dpy, Scr.root, gc, x, y, w, i); XFlush(dpy); usleep(ANIM_DELAY2*600); XDrawRectangle(dpy, Scr.root, gc, x, y, w, i); y+=step/2; } } if (w<2) return; step = w*4/Animate.iterations; if (step==0) { step = 2; } for (i=w; i>=0; i-=step) { XDrawRectangle(dpy, Scr.root, gc, x, y, i, 2); XFlush(dpy); usleep(ANIM_DELAY2*1000); XDrawRectangle(dpy, Scr.root, gc, x, y, i, 2); x+=step/2; } usleep(100000); XFlush(dpy); } #endif void DeadPipe(int arg) { myfprintf((stderr,"Dead Pipe, arg %d\n",arg)); exit(0); SIGNAL_RETURN; } static RETSIGTYPE HandleTerminate(int sig) { fvwmSetTerminate(sig); SIGNAL_RETURN; } int main(int argc, char **argv) { char cmd[200]; /* really big area for a command */ /* The new arg parsing function replaces the "manual" parsing */ module = ParseModuleArgs(argc,argv,1); if (module==NULL) { fprintf(stderr,"FvwmAnimate Version "VERSION" should only be executed by fvwm!\n"); exit(1); } #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGTERM); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGPIPE); #ifdef SA_INTERRUPT sigact.sa_flags = SA_INTERRUPT; /* to interrupt ReadFvwmPacket() */ #else sigact.sa_flags = 0; #endif sigact.sa_handler = HandleTerminate; sigaction(SIGTERM, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); } #else #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGTERM) | sigmask(SIGINT) | sigmask(SIGPIPE) ); #endif signal(SIGTERM, HandleTerminate); signal(SIGINT, HandleTerminate); signal(SIGPIPE, HandleTerminate); /* Dead pipe == fvwm died */ #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGTERM, True); siginterrupt(SIGINT, True); siginterrupt(SIGPIPE, True); #endif #endif Channel[0] = module->to_fvwm; Channel[1] = module->from_fvwm; dpy = XOpenDisplay(""); if (dpy==NULL) { fprintf(stderr,"%s: can not open display\n",module->name); exit(1); } /* FvwmAnimate must use the root visuals so do not call * PictureInitCMap but PictureInitCMapRoot. Color Limit is not needed */ PictureInitCMapRoot(dpy, False, NULL, False, False); FRenderInit(dpy); Scr.root = DefaultRootWindow(dpy); Scr.screen = DefaultScreen(dpy); sprintf(cmd,"read .%s Quiet",module->name); /* read quiet modules config */ SendText(Channel,cmd,0); ParseOptions(); /* get cmds fvwm has parsed */ SetMessageMask(Channel, M_ICONIFY|M_DEICONIFY|M_STRING|M_SENDCONFIG |M_CONFIG_INFO); /* tell fvwm about our mask */ CreateDrawGC(); /* create initial GC if necc. */ SendText(Channel,"Nop",0); DefineMe(); running = True; /* out of initialization phase */ SendFinishedStartupNotification(Channel); /* tell fvwm we're running */ SetSyncMask(Channel,M_ICONIFY|M_DEICONIFY|M_STRING); /* lock on send mask */ SetNoGrabMask(Channel,M_ICONIFY|M_DEICONIFY|M_STRING); /* ignore during recapture */ Loop(); /* start running */ return 0; } /* * Wait for some event like iconify, deiconify and stuff. */ static void Loop(void) { FvwmPacket* packet; char cmd[200]; myfprintf((stderr,"Starting event loop\n")); while ( !isTerminated ) { if ( (packet = ReadFvwmPacket(Channel[1])) == NULL ) break; /* fvwm is gone */ switch (packet->type) { case M_NEW_PAGE: Scr.Vx = packet->body[0]; Scr.Vy = packet->body[1]; Scr.CurrentDesk = packet->body[2]; break; case M_NEW_DESK: Scr.CurrentDesk = packet->body[0]; break; case M_DEICONIFY: if (play_state == False) { break; } if (packet->size < 15 /* If not all info needed, */ || packet->body[5] == 0) { /* or a "noicon" icon */ break; /* don't animate it */ } Animate.resize((int)packet->body[3], /* t->icon_x_loc */ (int)packet->body[4], /* t->icon_y_loc */ (int)packet->body[5], /* t->icon_p_width */ (int)packet->body[6], /* t->icon_p_height */ (int)packet->body[7], /* t->frame_x */ (int)packet->body[8], /* t->frame_y */ (int)packet->body[9], /* t->frame_width */ (int)packet->body[10]); /* t->frame_height */ myaprintf((stderr, "DE_Iconify, args %d+%d+%dx%d %d+%d+%dx%d.\n", (int)packet->body[3], /* t->icon_x_loc */ (int)packet->body[4], /* t->icon_y_loc */ (int)packet->body[5], /* t->icon_p_width */ (int)packet->body[6], /* t->icon_p_height */ (int)packet->body[7], /* t->frame_x */ (int)packet->body[8], /* t->frame_y */ (int)packet->body[9], /* t->frame_width */ (int)packet->body[10] /* t->frame_height */ )); break; case M_ICONIFY: if (play_state == False) { break; } /* In Afterstep, this logic waited for M_CONFIGURE_WINDOW before animating. To this time, I don't know why. (One is sent right after the other.) */ if (packet->size < 15 /* if not enough info */ || (int)packet->body[3] == -10000 /* or a transient window */ || (int)packet->body[5] == 0) { /* or a "noicon" icon */ break; /* don't animate it */ } Animate.resize((int)packet->body[7], /* t->frame_x */ (int)packet->body[8], /* t->frame_y */ (int)packet->body[9], /* t->frame_width */ (int)packet->body[10], /* t->frame_height */ (int)packet->body[3], /* t->icon_x_loc */ (int)packet->body[4], /* t->icon_y_loc */ (int)packet->body[5], /* t->icon_p_width */ (int)packet->body[6]); /* t->icon_p_height */ myaprintf((stderr, "Iconify, args %d+%d+%dx%d %d+%d+%dx%d. Took %d\n", (int)packet->body[7], /* t->frame_x */ (int)packet->body[8], /* t->frame_y */ (int)packet->body[9], /* t->frame_width */ (int)packet->body[10], /* t->frame_height */ (int)packet->body[3], /* t->icon_x_loc */ (int)packet->body[4], /* t->icon_y_loc */ (int)packet->body[5], /* t->icon_p_width */ (int)packet->body[6] )); break; case M_STRING: { char *token; char *line = (char *)&packet->body[3]; line = GetNextToken(line, &token); if (!token) { break; } if (strcasecmp(token, "animate") == 0) { /* This message lets anything create an animation. Eg: SendToModule FvwmAnimate \ animate 1 1 10 10 100 100 100 100 */ int locs[8]; int matched; matched = sscanf( line, "%5d %5d %5d %5d %5d %5d %5d %5d", &locs[0], &locs[1], &locs[2], &locs[3], &locs[4], &locs[5], &locs[6], &locs[7]); if (matched == 8 && play_state == True) { Animate.resize( locs[0], locs[1], locs[2], locs[3], locs[4], locs[5], locs[6], locs[7]); myaprintf((stderr, "animate %d+%d+%dx%d %d+%d+%dx%d\n", locs[0], locs[1], locs[2], locs[3], locs[4], locs[5], locs[6], locs[7])); } free(token); break; } while (token) { if (strcasecmp(token, "reset") == 0) { play_state = True; num_saved_play_states = 0; } else if (strcasecmp(token, "play") == 0) { play_state = True; } else if (strcasecmp(token, "pause") == 0) { play_state = False; } else if (strcasecmp(token, "push") == 0) { if (num_saved_play_states < MAX_SAVED_STATES) { saved_play_states[num_saved_play_states] = play_state; } else { fprintf( stderr, "FvwmAnimate: Too many " "nested push commands;\n\tthe " "current state can not be " "restored later using pop\n"); } num_saved_play_states++; } else if (strcasecmp(token, "pop") == 0) { num_saved_play_states--; if (num_saved_play_states < MAX_SAVED_STATES) { play_state = saved_play_states[ num_saved_play_states]; } } free(token); line = GetNextToken(line, &token); } break; } case M_CONFIG_INFO: myfprintf((stderr,"Got command: %s\n", (char *)&packet->body[3])); ParseConfigLine((char *)&packet->body[3]); break; } /* end switch header */ myfprintf((stderr,"Sending unlock\n")); if (packet->type != M_CONFIG_INFO) SendUnlockNotification(Channel); /* fvwm can continue now! */ if ((Animate.resize == AnimateResizeNone /* If no animation desired */ && animate_none >= 1) /* and 1 animation(s) */ || stop_recvd) { /* or stop cmd */ /* This still isn't perfect, if the user turns off animation, they would expect the menu to change on the spot. On the otherhand, the menu shouldn't change if the module is still running. This logic is dependent on fvwm sending iconify messages to make this module exit. Currently it is sending messages even when "Style NoIcon" is on for everything. */ StopCmd(); /* update menu */ myfprintf((stderr,"Exiting, animate none count %d, stop recvd %c\n", animate_none, stop_recvd ? 'y' : 'n')); break; /* and stop */ } /* end stopping */ /* The execution of the custom command has to be delayed, because we first had to send the UNLOCK response. */ if (custom_recvd) { custom_recvd = False; DefineForm(); CMD1X("Module FvwmForm Form%s"); } } /* end while */ } /* * * This routine is responsible for reading and parsing the config file * Used FvwmEvent as a model. * */ static const char *table[]= { "Color", #define Color_arg 0 "Custom", #define Custom_arg 1 "Delay", #define Delay_arg 2 "Effect", #define Effect_arg 3 "Iterations", #define Iterations_arg 4 "Pixmap", #define Pixmap_arg 5 "Resize", #define Resize_arg 6 "Save", #define Save_arg 7 "Stop", #define Stop_arg 8 "Time", #define Time_arg 9 "Twist", #define Twist_arg 10 "Width" #define Width_arg 11 }; /* Keep list in alphabetic order, using binary search! */ static void ParseOptions(void) { char *buf; Scr.MyDisplayWidth = DisplayWidth(dpy, Scr.screen); Scr.MyDisplayHeight = DisplayHeight(dpy, Scr.screen); Scr.Vx = 0; Scr.Vy = 0; Scr.CurrentDesk = 0; myfprintf((stderr,"Reading options\n")); InitGetConfigLine(Channel,CatString3("*",module->name,0)); while (GetConfigLine(Channel,&buf), buf != NULL) { ParseConfigLine(buf); } /* end config lines */ } /* end function */ void ParseConfigLine(char *buf) { char **e, *p, *q; unsigned seed; long curtime; unsigned i; if (buf[strlen(buf)-1] == '\n') { /* if line ends with newline */ buf[strlen(buf)-1] = '\0'; /* strip off \n */ } /* capture the ImagePath setting, don't worry about ColorLimit */ if (strncasecmp(buf, "ImagePath",9)==0) { PictureSetImagePath(&buf[9]); } /* Search for MyName (normally *FvwmAnimate) */ else if (strncasecmp(buf, CatString3("*",module->name,0), module->namelen+1) == 0) {/* If its for me */ myfprintf((stderr,"Found line for me: %s\n", buf)); p = buf+module->namelen+1; /* starting point */ q = NULL; if ((e = FindToken(p,table,char *))) { /* config option ? */ if ((strcasecmp(*e,"Stop") != 0) && (strcasecmp(*e,"Custom") != 0) && (strcasecmp(*e,"Save") != 0)) { /* no arg commands */ p+=strlen(*e); /* skip matched token */ p = GetNextSimpleOption( p, &q ); if (!q) { /* If arg not found */ fprintf(stderr,"%s: %s%s needs a parameter\n", module->name, module->name,*e); return; } } switch (e - (char**)table) { case Stop_arg: /* Stop command */ if (running) { /* if not a stored command */ stop_recvd = True; /* remember to stop */ } break; case Save_arg: /* Save command */ SaveConfig(); break; case Custom_arg: /* Custom command */ if (running) { /* if not a stored command */ custom_recvd = True; /* remember someone asked */ } break; case Color_arg: /* Color */ if (Animate.color) { free(Animate.color); /* release storage holding color name */ Animate.color = 0; /* show its gone */ } if ((strcasecmp(q,"None") != 0) /* If not color "none" */ && (strcasecmp(q,"Black^White") != 0) && (strcasecmp(q,"White^Black") != 0)) { Animate.color = (char *)safestrdup(q); /* make copy of name */ } /* override the pixmap option */ if (Animate.pixmap) { free(Animate.pixmap); Animate.pixmap = 0; } if (pixmap) { XFreePixmap(dpy, pixmap); pixmap = None; } CreateDrawGC(); /* update GC */ break; case Pixmap_arg: if (Animate.pixmap) { free(Animate.pixmap); /* release storage holding pixmap name */ Animate.pixmap = 0; /* show its gone */ } if (strcasecmp(q,"None") != 0) { /* If not pixmap "none" */ Animate.pixmap = (char *)safestrdup(q); /* make copy of name */ } if (pixmap) { XFreePixmap(dpy, pixmap); pixmap = None; } CreateDrawGC(); /* update GC */ break; case Delay_arg: /* Delay */ Animate.delay = atoi(q); break; case Iterations_arg: /* Iterations */ Animate.iterations = atoi(q); /* Silently fix up iterations less than 1. */ if (Animate.iterations <= 0) { Animate.iterations = 1; } break; case Effect_arg: /* Effect */ case Resize_arg: /* -or - Resize */ for (i=0; i < NUM_EFFECTS; i++) { if (strcasecmp(q, effects[i].name)==0 || (effects[i].alias && strcasecmp(q, effects[i].alias)==0)) { Animate.resize = effects[i].function; break; } /* end match */ } /* end all effects */ if (i > NUM_EFFECTS) { /* If not found */ fprintf(stderr, "%s: Unknown Effect '%s'\n", module->name, q); } /* Logically, you would only reset these when you got a command of None, or Random, but it doesn't really matter. */ animate_none = 0; curtime = time(NULL); seed = (unsigned) curtime % INT_MAX; srand(seed); break; case Time_arg: /* Time in milliseconds */ Animate.time = (clock_t)atoi(q); break; case Twist_arg: /* Twist */ Animate.twist = atof(q); break; case Width_arg: /* Width */ Animate.width = atoi(q); /* Silently fix up width less than 0. */ if (Animate.width < 0) { Animate.width = 0; } CreateDrawGC(); /* update GC */ break; default: fprintf(stderr,"%s: unknown action %s\n",module->name,*e); break; } } else { /* Match Myname, but a space */ fprintf(stderr,"%s: unknown command: %s\n",module->name,buf); } if(q) { /* if parsed an arg */ free(q); /* free its memory */ } } /* config line for me */ } /* end function */ /* create GC for drawing the various animations */ /* Called during start-up, and whenever the color or line width changes. */ static void CreateDrawGC(void) { myfprintf((stderr,"Creating GC\n")); if (gc != NULL) { XFreeGC(dpy,gc); /* free old GC */ } /* From builtins.c: */ color = (PictureBlackPixel() ^ PictureWhitePixel()); pixmap = None; gcv.function = GXxor; /* default is to xor the lines */ if (Animate.pixmap) { /* if pixmap called for */ FvwmPicture *picture; FvwmPictureAttributes fpa; fpa.mask = FPAM_NO_COLOR_LIMIT; picture = PGetFvwmPicture( dpy, RootWindow(dpy,Scr.screen), 0, Animate.pixmap, fpa); if (!picture) fprintf(stderr, "%s: Could not load pixmap '%s'\n", module->name, Animate.pixmap); else { pixmap = XCreatePixmap( dpy, RootWindow(dpy, Scr.screen), picture->width, picture->height, Pdepth); PGraphicsCopyPixmaps( dpy, picture->picture, None, None, picture->depth, pixmap, None, 0, 0, picture->width, picture->height, 0, 0); PDestroyFvwmPicture(dpy, picture); } } else if (Animate.color) { /* if color called for */ if (XParseColor(dpy, Pcmap,Animate.color, &xcol)) { if (PictureAllocColor(dpy, Pcmap, &xcol, True)) { color = xcol.pixel; /* free it now, only interested in the pixel */ PictureFreeColors( dpy, Pcmap, &xcol.pixel, 1, 0, True); /* gcv.function=GXequiv; Afterstep used this. */ } else { fprintf(stderr, "%s: could not allocate color '%s'\n", module->name,Animate.color); } } else { fprintf(stderr,"%s: could not parse color '%s'\n", module->name,Animate.color); } } gcv.line_width = Animate.width; gcv.foreground = color; myfprintf((stderr,"Color is %ld\n",gcv.foreground)); gcv.subwindow_mode = IncludeInferiors; if (pixmap) { gcv.tile = pixmap; gcv.fill_style = FillTiled; } gc=fvwmlib_XCreateGC( dpy, Scr.root, GCFunction | GCForeground | GCLineWidth | GCSubwindowMode | (pixmap ? GCFillStyle | GCTile : 0), &gcv); } /* * Send commands to fvwm to define this modules menus. * * When I first wrote this, I thought it might be a good idea to call the * menu "FvwmAnimate", just like the module name. To my surprise, I * found that fvwm treats menus just like functions. In fact I could no * longer start FvwmAnimate because it kept finding the menu instead of * the function. This probably should be fixed, but for now, the * generated menu is called "MenuFvwmAnimate", or "Menu". * dje, 10/11/98. */ static void DefineMe(void) { char cmd[200]; /* really big area for a command */ myfprintf((stderr,"defining menu\n")); CMD1X("DestroyMenu Menu%s"); CMD1X("DestroyMenu MenuIterations%s"); CMD1X("DestroyMenu MenuEffects%s"); CMD1X("DestroyMenu MenuWidth%s"); CMD1X("DestroyMenu MenuTwist%s"); CMD1X("DestroyMenu MenuDelay%s"); CMD1X("DestroyMenu MenuColor%s"); CMD1X("AddToMenu Menu%s \"Animation Main Menu\" Title"); CMD11("AddToMenu Menu%s \"&E. Effects\" Popup MenuEffects%s"); CMD11("AddToMenu Menu%s \"&I. Iterations\" Popup MenuIterations%s"); CMD11("AddToMenu Menu%s \"&T. Twists\" Popup MenuTwist%s"); CMD11("AddToMenu Menu%s \"&L. Line Width\" Popup MenuWidth%s"); CMD11("AddToMenu Menu%s \"&D. Delays\" Popup MenuDelay%s"); CMD11("AddToMenu Menu%s \"&X. Color for XOR\" Popup MenuColor%s"); CMD10("AddToMenu Menu%s \"&C. Custom Settings\" %sCustom"); CMD10("AddToMenu Menu%s \"&S. Save Config\" %sSave"); CMD10("AddToMenu Menu%s \"&Z. Stop Animation\" %sStop"); CMD11("AddToMenu Menu%s \"&R. Restart Animation\" FuncRestart%s"); /* Define function for stopping and restarting Animation. */ CMD1X("DestroyFunc FuncRestart%s"); CMD10("AddToFunc FuncRestart%s \"I\" %sStop"); CMD11("AddToFunc FuncRestart%s \"I\" Module FvwmAnimate %s"); /* Define the sub menus. */ CMD1X("AddToMenu MenuIterations%s \"Iterations\" Title"); CMD10("AddToMenu MenuIterations%s \"&1. Iterations 1\" %sIterations 1"); CMD10("AddToMenu MenuIterations%s \"&2. Iterations 2\" %sIterations 2"); CMD10("AddToMenu MenuIterations%s \"&3. Iterations 4\" %sIterations 4"); CMD10("AddToMenu MenuIterations%s \"&4. Iterations 8\" %sIterations 8"); CMD10("AddToMenu MenuIterations%s \"&5. Iterations 16\" %sIterations 16"); CMD10("AddToMenu MenuIterations%s \"&6. Iterations 32\" %sIterations 32"); CMD1X("AddToMenu MenuWidth%s \"Line Width\" Title"); CMD10("AddToMenu MenuWidth%s \"&1. Line Width 0 (fast)\" %sWidth 0"); CMD10("AddToMenu MenuWidth%s \"&2. Line Width 1\" %sWidth 1"); CMD10("AddToMenu MenuWidth%s \"&3. Line Width 2\" %sWidth 2"); CMD10("AddToMenu MenuWidth%s \"&4. Line Width 4\" %sWidth 4"); CMD10("AddToMenu MenuWidth%s \"&5. Line Width 6\" %sWidth 6"); CMD10("AddToMenu MenuWidth%s \"&6. Line Width 8\" %sWidth 8"); CMD1X("AddToMenu MenuTwist%s \"Twists (Twist, Turn, Flip only)\" Title"); CMD10("AddToMenu MenuTwist%s \"&1. Twist .25\" %sTwist .25"); CMD10("AddToMenu MenuTwist%s \"&2. Twist .50\" %sTwist .50"); CMD10("AddToMenu MenuTwist%s \"&3. Twist 1\" %sTwist 1"); CMD10("AddToMenu MenuTwist%s \"&4. Twist 2\" %sTwist 2"); CMD1X("AddToMenu MenuDelay%s \"Delays\" Title"); CMD10("AddToMenu MenuDelay%s \"&1. Delay 1/1000 sec\" %sDelay 1"); CMD10("AddToMenu MenuDelay%s \"&2. Delay 1/100 sec\" %sDelay 10"); CMD10("AddToMenu MenuDelay%s \"&3. Delay 1/10 sec\" %sDelay 100"); /* Same as the colors at the front of the colorlimiting table */ CMD1X("AddToMenu MenuColor%s \"Colors\" Title"); CMD10("AddToMenu MenuColor%s \"&1. Color Black^White\" %sColor None"); CMD10("AddToMenu MenuColor%s \"&2. Color White\" %sColor white"); CMD10("AddToMenu MenuColor%s \"&3. Color Black\" %sColor black"); CMD10("AddToMenu MenuColor%s \"&4. Color Grey\" %sColor grey"); CMD10("AddToMenu MenuColor%s \"&5. Color Green\" %sColor green"); CMD10("AddToMenu MenuColor%s \"&6. Color Blue\" %sColor blue"); CMD10("AddToMenu MenuColor%s \"&7. Color Red\" %sColor red"); CMD10("AddToMenu MenuColor%s \"&8. Color Cyan\" %sColor cyan"); CMD10("AddToMenu MenuColor%s \"&9. Color Yellow\" %sColor yellow"); CMD10("AddToMenu MenuColor%s \"&A. Color Magenta\" %sColor magenta"); CMD10("AddToMenu MenuColor%s \"&B. Color DodgerBlue\" %sColor DodgerBlue"); CMD10("AddToMenu MenuColor%s \"&C. Color SteelBlue\" %sColor SteelBlue"); CMD10("AddToMenu MenuColor%s \"&D. Color Chartreuse\" %sColor chartreuse"); CMD10("AddToMenu MenuColor%s \"&E. Color Wheat\" %sColor wheat"); CMD10("AddToMenu MenuColor%s \"&F. Color Turquoise\" %sColor turquoise"); CMD1X("AddToMenu MenuEffects%s \"Effects\" Title"); CMD10("AddToMenu MenuEffects%s \"&1. Effect Random\" %sEffect Random"); CMD10("AddToMenu MenuEffects%s \"&2. Effect Flip\" %sEffect Flip"); CMD10("AddToMenu MenuEffects%s \"&3. Effect Frame\" %sEffect Frame"); CMD10("AddToMenu MenuEffects%s \"&4. Effect Frame3D\" %sEffect Frame3D"); CMD10("AddToMenu MenuEffects%s \"&5. Effect Lines\" %sEffect Lines"); CMD10("AddToMenu MenuEffects%s \"&6. Effect Turn\" %sEffect Turn"); CMD10("AddToMenu MenuEffects%s \"&7. Effect Twist\" %sEffect Twist"); CMD10("AddToMenu MenuEffects%s \"&N. Effect None\" %sEffect None"); /* Still to be done: Use of FvwmForms for Help. (Need to fix line spacing in FvwmForms first). */ } /* Write the current config into a file. */ static void SaveConfig(void) { FILE *config_file; unsigned i; char filename[100]; /* more than enough room */ char msg[200]; /* even more room for msg */ /* Need to use logic to create fully qualified file name same as in read.c, right now, this logic only works well if fvwm is started from the users home directory. */ sprintf(filename,"%s/.%s",getenv("FVWM_USERDIR"),module->name); config_file = fopen(filename,"w"); if (config_file == NULL) { sprintf(msg, "%s: Open config file <%s> for write failed. \ Save not done! Error\n", module->name, filename); perror(msg); return; } fprintf(config_file,"# This file was created by %s\n\n",module->name); for (i=0; i < NUM_EFFECTS; i++) { if (effects[i].function == Animate.resize) { fprintf(config_file,"*%s: Effect %s\n",module->name,effects[i].name); break; } /* found match */ } /* all possible effects */ fprintf(config_file,"*%s: Iterations %d\n",module->name,Animate.iterations); fprintf(config_file,"*%s: Width %d\n",module->name,Animate.width); fprintf(config_file,"*%s: Twist %f\n",module->name,Animate.twist); fprintf(config_file,"*%s: Delay %d\n",module->name,Animate.delay); if (Animate.color) { fprintf(config_file,"*%s: Color %s\n",module->name,Animate.color); } /* Note, add "time" if that ever works. dje. 10/14/98 */ fclose(config_file); } /* Stop is different than KillModule in that it gives this module a chance to alter the builtin menu before it exits. */ static void StopCmd(void) { char cmd[200]; myfprintf((stderr,"%s: Defining startup menu in preparation for stop\n", module->name)); CMD1X("DestroyMenu Menu%s"); CMD11("AddToMenu Menu%s \"%s\" Title"); CMD11("AddToMenu Menu%s \"&0. Start FvwmAnimate\" Module %s"); } static void DefineForm(void) { unsigned i; char cmd[200]; myfprintf((stderr,"Defining form Form%s\n", module->name)); CMD1X("DestroyModuleConfig Form%s*"); CMD1X("*Form%sWarpPointer"); CMD1X("*Form%sLine center"); CMD11("*Form%sText \"Custom settings for %s\""); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"\""); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"Effect:\""); CMD1X("*Form%sSelection meth single"); for (i=0; i < NUM_EFFECTS; i++) { /* for all effects */ effects[i].button="off"; /* init the button setting */ if (Animate.resize == effects[i].function) { /* compare to curr setting */ effects[i].button="on"; /* turn on one button */ } /* end if curr setting */ } /* end all buttons */ /* Macro for a command with one var */ #define CMD1V(TEXT,VAR) \ sprintf(cmd,TEXT,module->name,VAR);\ SendText(Channel,cmd,0); /* There is a cleaner way (using the array) for this...dje */ CMD1V("*Form%sChoice RANDOM RANDOM %s \"Random\"",effects[1].button); CMD1V("*Form%sChoice FLIP FLIP %s \"Flip\"",effects[2].button); CMD1V("*Form%sChoice FRAME FRAME %s \"Frame\"",effects[3].button); CMD1V("*Form%sChoice FRAME3D FRAME3D %s \"Frame3d\"",effects[4].button); CMD1V("*Form%sChoice LINES LINES %s \"Lines\"",effects[5].button); CMD1V("*Form%sChoice TURN TURN %s \"Turn\"",effects[6].button); CMD1V("*Form%sChoice TWIST TWIST %s \"Twist\"",effects[7].button); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"\""); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"Iterations:\""); CMD1V("*Form%sInput Iterations 5 \"%d\"",Animate.iterations); CMD1X("*Form%sText \"Twists:\""); CMD1V("*Form%sInput Twists 10 \"%f\"",Animate.twist); CMD1X("*Form%sText \"Linewidth:\""); CMD1V("*Form%sInput Linewidth 3 \"%d\"",Animate.width); CMD1X("*Form%sText \"Delays:\""); CMD1V("*Form%sInput Delays 5 \"%d\"",Animate.delay); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"\""); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"Color:\""); CMD1V("*Form%sInput Color 20 \"%s\"", Animate.color ? Animate.color : "Black^White"); CMD1X("*Form%sLine left"); CMD1X("*Form%sText \"\""); /* F1 - Apply, F2 - Apply and Save, F3 - Reset, F4 - Dismiss */ CMD1X("*Form%sLine expand"); CMD1X("*Form%sButton continue \"F1 - Apply\" F1"); CMD11("*Form%sCommand *%sIterations $(Iterations)"); CMD11("*Form%sCommand *%sTwist $(Twists)"); CMD11("*Form%sCommand *%sWidth $(Linewidth)"); CMD11("*Form%sCommand *%sDelay $(Delays)"); CMD11("*Form%sCommand *%sColor $(Color)"); CMD11("*Form%sCommand *%sEffect $(RANDOM?Random)\ $(FLIP?Flip)\ $(FRAME?Frame)\ $(FRAME3D?Frame3d)\ $(LINES?Lines)\ $(TURN?Turn)\ $(TWIST?Twist)"); CMD1X("*Form%sButton continue \"F2 - Apply & Save\" F2"); CMD11("*Form%sCommand *%sIterations $(Iterations)"); CMD11("*Form%sCommand *%sTwist $(Twists)"); CMD11("*Form%sCommand *%sWidth $(Linewidth)"); CMD11("*Form%sCommand *%sDelay $(Delays)"); CMD11("*Form%sCommand *%sColor $(Color)"); CMD11("*Form%sCommand *%sEffect $(RANDOM?Random)\ $(FLIP?Flip)\ $(FRAME?Frame)\ $(FRAME3D?Frame3d)\ $(LINES?Lines)\ $(TURN?Turn)\ $(TWIST?Twist)"); CMD11("*Form%sCommand *%sSave"); CMD1X("*Form%sButton restart \"F3 - Reset\" F3"); CMD1X("*Form%sButton quit \"F4 - Dismiss\" F4"); CMD1X("*Form%sCommand Nop"); } fvwm-2.6.7/modules/FvwmAnimate/FvwmAnimate.h0000644000175700017570000000146012773467232015737 00000000000000/* -*-c-*- */ #ifndef _ANIMATE_H_ #define _ANIMATE_H_ /* Animation granularity. How many iterations use for the animation. */ #define ANIM_ITERATIONS 12 /* delay for each iteration of the animation in ms */ #define ANIM_DELAY 1 /* delay for each iteration of the close animation in ms */ #define ANIM_DELAY2 20 /* distance to spin frame around, 1.0 is one revolution. with large values you should up ANIM_ITERATIONS as well */ #define ANIM_TWIST 0.5 /* default line width */ #define ANIM_WIDTH 0 /* default time */ #define ANIM_TIME 0 struct ASAnimate { char *color; char *pixmap; int iterations; int delay; float twist; int width; void (*resize)(int, int, int, int, int, int, int, int); clock_t time; }; extern struct ASAnimate Animate; #endif /* _ANIMATE_H_ */ fvwm-2.6.7/modules/FvwmIdent/0000755000175700017570000000000013010103344013064 500000000000000fvwm-2.6.7/modules/FvwmIdent/ConfigFvwmIdent0000644000175700017570000000040312673746443016010 00000000000000########################## Window-Identifier ############################### # Just choose colors and fonts DestroyModuleConfig FvwmIdent: * *FvwmIdent: Back MidnightBlue *FvwmIdent: Fore Yellow *FvwmIdent: Font -adobe-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* fvwm-2.6.7/modules/FvwmIdent/Makefile.am0000644000175700017570000000155613001406607015057 00000000000000## Process this file with automake to create Makefile.in moduledir = @FVWM_MODULEDIR@ configdir = @FVWM_DATADIR@ module_PROGRAMS = FvwmIdent man_MANS = FvwmIdent.1 EXTRA_DIST = $(man_MANS) ConfigFvwmIdent config_DATA = \ ConfigFvwmIdent FvwmIdent_SOURCES = FvwmIdent.c FvwmIdent.h FvwmIdent_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a ## Xpm note: while this module may not depend on Xpm explicitly, ## there are sometimes dependencies through functions in libfvwm ## so we might as well link against libXpm, if present. LDADD = -L$(top_builddir)/libs -lfvwm $(Xft_LIBS) $(X_LIBS) $(xpm_LIBS) \ $(png_LIBS) $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 -lm \ $(X_EXTRA_LIBS) $(Xrender_LIBS) $(rsvg_LIBS) $(iconv_LIBS) $(Bidi_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(Xft_CFLAGS) $(xpm_CFLAGS) $(png_CFLAGS) \ $(X_CFLAGS) $(Xrender_CFLAGS) $(iconv_CFLAGS) $(Bidi_CFLAGS) fvwm-2.6.7/modules/FvwmIdent/Makefile.in0000644000175700017570000006254313010103323015060 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmIdent$(EXEEXT) subdir = modules/FvwmIdent DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmIdent.1.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmIdent.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(configdir)" PROGRAMS = $(module_PROGRAMS) am_FvwmIdent_OBJECTS = FvwmIdent.$(OBJEXT) FvwmIdent_OBJECTS = $(am_FvwmIdent_OBJECTS) FvwmIdent_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmIdent_SOURCES) DIST_SOURCES = $(FvwmIdent_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ configdir = @FVWM_DATADIR@ man_MANS = FvwmIdent.1 EXTRA_DIST = $(man_MANS) ConfigFvwmIdent config_DATA = \ ConfigFvwmIdent FvwmIdent_SOURCES = FvwmIdent.c FvwmIdent.h FvwmIdent_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs -lfvwm $(Xft_LIBS) $(X_LIBS) $(xpm_LIBS) \ $(png_LIBS) $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 -lm \ $(X_EXTRA_LIBS) $(Xrender_LIBS) $(rsvg_LIBS) $(iconv_LIBS) $(Bidi_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(Xft_CFLAGS) $(xpm_CFLAGS) $(png_CFLAGS) \ $(X_CFLAGS) $(Xrender_CFLAGS) $(iconv_CFLAGS) $(Bidi_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmIdent/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmIdent/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmIdent.1: $(top_builddir)/config.status $(srcdir)/FvwmIdent.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmIdent$(EXEEXT): $(FvwmIdent_OBJECTS) $(FvwmIdent_DEPENDENCIES) $(EXTRA_FvwmIdent_DEPENDENCIES) @rm -f FvwmIdent$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmIdent_OBJECTS) $(FvwmIdent_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmIdent.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-man install-modulePROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA uninstall-man \ uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-configDATA install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-modulePROGRAMS install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-configDATA uninstall-man uninstall-man1 \ uninstall-modulePROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmIdent/FvwmIdent.10000644000175700017570000000607613010101137015000 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .TH FvwmIdent 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmIdent \- the Fvwm identify-window module .SH SYNOPSIS FvwmIdent is spawned by fvwm, so no command line invocation will work. .SH DESCRIPTION The FvwmIdent module prompts the user to select a target window, if the module was not launched from within a window context in Fvwm. After that, it pops up a window with information about the window which was selected. .SH COPYRIGHTS The FvwmIdent program, and the concept for interfacing this module to the Window Manager, are all original work by Robert Nation and Nobutaka Suzuki. Copyright 1994, Robert Nation and Nobutaka Suzuki. No guarantees or warranties or anything are provided or implied in any way whatsoever. Use this program at your own risk. Permission to use this program for any purpose is given, as long as the copyright is kept intact. .SH INITIALIZATION During initialization, \fIFvwmIdent\fP gets config info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ) to determine which colors and font to use. If the FvwmIdent executable is linked to another name, ie ln -s FvwmIdent MoreIdentify, then another module called MoreIdentify can be started, with a completely different configuration than FvwmIdent, simply by changing the keyword FvwmIdent to MoreIdentify. This way multiple clutter-reduction programs can be used. .SH INVOCATION FvwmIdent can be invoked by binding the action 'Module FvwmIdent' to a menu or key-stroke in the .fvwm2rc file. Fvwm will search directory specified in the ModulePath configuration option to attempt to locate FvwmIdent. Although nothing keeps you from launching FvwmIdent at start-up time, you probably don't want to. Clicking into the FvwmIdent window or pressing a key while it has focus closes FvwmIdent. Pressing mouse button 2 in the window restarts FvwmIdent and asks for a new window to select. .SH CONFIGURATION OPTIONS FvwmIdent reads the same .fvwm2rc file as fvwm reads when it starts up, and looks for lines as listed below: .IP "*FvwmIdent: Colorset \fIn\fP" Tells the module to use colorset \fIn\fP. See FvwmTheme. .IP "*FvwmIdent: Fore \fIcolor\fP" Tells the module to use \fIcolor\fP instead of black for text. Switches off the Colorset option. .IP "*FvwmIdent: Back \fIcolor\fP" Tells the module to use \fIcolor\fP instead of white for the window background. Switches off the Colorset option. .IP "*FvwmIdent: Font \fIfontname\fP" Tells the module to use \fIfontname\fP instead of fixed for text. .IP "*FvwmIdent: MinimalLayer \fIlayer\fP" FvwmIdent places its window on the layer of a target window. But not below the minimal layer. By default, the minimal layer is 4 just like the fvwm default layer. If \fIlayer\fP is 0, the layer of the target window is always used. If \fIlayer\fP is "default" or not specified, the default behavior is restored. If \fIlayer\fP is "none", FvwmIdent is placed as a normal window even if the target window is above it. .SH AUTHOR Robert Nation and Nobutaka Suzuki (nobuta-s@is.aist-nara.ac.jp). fvwm-2.6.7/modules/FvwmIdent/FvwmIdent.1.in0000644000175700017570000000610512673746443015433 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH FvwmIdent 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmIdent \- the Fvwm identify-window module .SH SYNOPSIS FvwmIdent is spawned by fvwm, so no command line invocation will work. .SH DESCRIPTION The FvwmIdent module prompts the user to select a target window, if the module was not launched from within a window context in Fvwm. After that, it pops up a window with information about the window which was selected. .SH COPYRIGHTS The FvwmIdent program, and the concept for interfacing this module to the Window Manager, are all original work by Robert Nation and Nobutaka Suzuki. Copyright 1994, Robert Nation and Nobutaka Suzuki. No guarantees or warranties or anything are provided or implied in any way whatsoever. Use this program at your own risk. Permission to use this program for any purpose is given, as long as the copyright is kept intact. .SH INITIALIZATION During initialization, \fIFvwmIdent\fP gets config info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ) to determine which colors and font to use. If the FvwmIdent executable is linked to another name, ie ln -s FvwmIdent MoreIdentify, then another module called MoreIdentify can be started, with a completely different configuration than FvwmIdent, simply by changing the keyword FvwmIdent to MoreIdentify. This way multiple clutter-reduction programs can be used. .SH INVOCATION FvwmIdent can be invoked by binding the action 'Module FvwmIdent' to a menu or key-stroke in the .fvwm2rc file. Fvwm will search directory specified in the ModulePath configuration option to attempt to locate FvwmIdent. Although nothing keeps you from launching FvwmIdent at start-up time, you probably don't want to. Clicking into the FvwmIdent window or pressing a key while it has focus closes FvwmIdent. Pressing mouse button 2 in the window restarts FvwmIdent and asks for a new window to select. .SH CONFIGURATION OPTIONS FvwmIdent reads the same .fvwm2rc file as fvwm reads when it starts up, and looks for lines as listed below: .IP "*FvwmIdent: Colorset \fIn\fP" Tells the module to use colorset \fIn\fP. See FvwmTheme. .IP "*FvwmIdent: Fore \fIcolor\fP" Tells the module to use \fIcolor\fP instead of black for text. Switches off the Colorset option. .IP "*FvwmIdent: Back \fIcolor\fP" Tells the module to use \fIcolor\fP instead of white for the window background. Switches off the Colorset option. .IP "*FvwmIdent: Font \fIfontname\fP" Tells the module to use \fIfontname\fP instead of fixed for text. .IP "*FvwmIdent: MinimalLayer \fIlayer\fP" FvwmIdent places its window on the layer of a target window. But not below the minimal layer. By default, the minimal layer is 4 just like the fvwm default layer. If \fIlayer\fP is 0, the layer of the target window is always used. If \fIlayer\fP is "default" or not specified, the default behavior is restored. If \fIlayer\fP is "none", FvwmIdent is placed as a normal window even if the target window is above it. .SH AUTHOR Robert Nation and Nobutaka Suzuki (nobuta-s@is.aist-nara.ac.jp). fvwm-2.6.7/modules/FvwmIdent/FvwmIdent.c0000644000175700017570000010031213001406607015060 00000000000000/* -*-c-*- */ /* This module, and the entire NoClutter program, and the concept for * interfacing this module to the Window Manager, are all original work * by Robert Nation and Nobutaka Suzuki * * Copyright 1994, Robert Nation and Nobutaka Suzuki. * No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. */ /* 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 #include #include #include #include "libs/ftime.h" #if HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/FShape.h" #include "libs/Module.h" #include "libs/Colorset.h" #include "libs/fvwmsignal.h" #include "libs/Flocale.h" #include "libs/Parse.h" #include "libs/FRenderInit.h" #include "libs/Graphics.h" #include "libs/System.h" #include "libs/Target.h" #include "libs/XError.h" #include "FvwmIdent.h" static RETSIGTYPE TerminateHandler(int); static ModuleArgs *module; static fd_set_size_t fd_width; static int fd[2]; static Display *dpy; /* which display are we talking to */ static Window Root; static GC gc; static FlocaleFont *Ffont; static FlocaleWinString *FwinString; static int screen; static int x_fd; static char *yes = "Yes"; static char *no = "No"; /* default colorset to use, set to -1 when explicitly setting colors */ static int colorset = 0; static char *BackColor = "white"; static char *ForeColor = "black"; static char *font_string = NULL; static Pixel fore_pix; static Pixel back_pix; static Window main_win; static Bool UsePixmapDrawing = False; /* if True draw everything in a pixmap * and set the window background. Use * this with Xft */ static int main_width; static int main_height; static EventMask mw_events = ExposureMask | ButtonPressMask | KeyPressMask | ButtonReleaseMask | KeyReleaseMask | StructureNotifyMask; static Atom wm_del_win; static struct target_struct target; static int found=0; static int ListSize=0; static struct Item* itemlistRoot = NULL; static int max_col1, max_col2; static char id[15], desktop[10], swidth[10], sheight[10], borderw[10]; static char geometry[30], mymin_aspect[11], max_aspect[11], layer[10]; static char ewmh_init_state[512]; static char xin_str[10]; /* FIXME: default layer should be received from fvwm */ #define default_layer DEFAULT_DEFAULT_LAYER static int minimal_layer = default_layer; static int my_layer = default_layer; /* * * Procedure: * main - start of module * */ int main(int argc, char **argv) { char *display_name = NULL; char *tline; FlocaleInit(LC_CTYPE, "", "", "FvwmIdent"); module = ParseModuleArgs(argc,argv,0); /* no alias */ if (module == NULL) { fprintf( stderr, "FvwmIdent Version %s should only be executed" " by fvwm!\n", VERSION); exit(1); } #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGPIPE); sigaddset(&sigact.sa_mask, SIGTERM); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); # ifdef SA_INTERRUPT sigact.sa_flags = SA_INTERRUPT; # else sigact.sa_flags = 0; # endif sigact.sa_handler = TerminateHandler; sigaction(SIGPIPE, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); } #else /* We don't have sigaction(), so fall back to less robust methods. */ #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGPIPE) | sigmask(SIGTERM) | sigmask(SIGQUIT) | sigmask(SIGINT) | sigmask(SIGHUP) ); #endif signal(SIGPIPE, TerminateHandler); signal(SIGTERM, TerminateHandler); signal(SIGQUIT, TerminateHandler); signal(SIGINT, TerminateHandler); signal(SIGHUP, TerminateHandler); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGPIPE, 1); siginterrupt(SIGTERM, 1); siginterrupt(SIGQUIT, 1); siginterrupt(SIGINT, 1); siginterrupt(SIGHUP, 1); #endif #endif fd[0] = module->to_fvwm; fd[1] = module->from_fvwm; /* Open the Display */ if (!(dpy = XOpenDisplay(display_name))) { fprintf(stderr,"%s: can't open display %s", module->name, XDisplayName(display_name)); exit (1); } x_fd = XConnectionNumber(dpy); screen= DefaultScreen(dpy); Root = RootWindow(dpy, screen); XSetErrorHandler(ErrorHandler); flib_init_graphics(dpy); FlocaleAllocateWinString(&FwinString); SetMessageMask(fd, M_CONFIGURE_WINDOW | M_WINDOW_NAME | M_ICON_NAME | M_RES_CLASS | M_RES_NAME | M_END_WINDOWLIST | M_CONFIG_INFO | M_END_CONFIG_INFO | M_SENDCONFIG); SetMessageMask(fd, MX_PROPERTY_CHANGE); /* scan config file for set-up parameters */ /* Colors and fonts */ InitGetConfigLine(fd,CatString3("*",module->name,0)); GetConfigLine(fd,&tline); while (tline != (char *)0) { if (strlen(tline) <= 1) { continue; } if (strncasecmp(tline, CatString3("*",module->name,0), module->namelen+1) == 0) { tline += (module->namelen +1); if (strncasecmp(tline, "Font", 4) == 0) { CopyStringWithQuotes(&font_string, &tline[4]); } else if (strncasecmp(tline, "Fore", 4) == 0) { CopyString(&ForeColor, &tline[4]); colorset = -1; } else if (strncasecmp(tline, "Back", 4) == 0) { CopyString(&BackColor, &tline[4]); colorset = -1; } else if (strncasecmp(tline, "Colorset", 8) == 0) { sscanf(&tline[8], "%d", &colorset); AllocColorset(colorset); } else if (strncasecmp(tline, "MinimalLayer", 12) == 0) { char *layer_str = PeekToken(&tline[12], NULL); if (layer_str == NULL) { minimal_layer = default_layer; } else if (sscanf( layer_str, "%d", &minimal_layer) != 1) { if (strncasecmp( layer_str, "none", 4) == 0) { minimal_layer = -1; } else { minimal_layer = default_layer; } } } } else if (strncasecmp(tline, "Colorset", 8) == 0) { LoadColorset(&tline[8]); } else if (strncasecmp( tline, XINERAMA_CONFIG_STRING, sizeof(XINERAMA_CONFIG_STRING) - 1) == 0) { FScreenConfigureModule( tline + sizeof(XINERAMA_CONFIG_STRING) - 1); } GetConfigLine(fd, &tline); } if(module->window == 0) { fvwmlib_get_target_window( dpy, screen, module->name, &(module->window), True); } fd_width = GetFdWidth(); /* Create a list of all windows */ /* Request a list of all windows, * wait for ConfigureWindow packets */ SendText(fd, "Send_WindowList", 0); /* tell fvwm we're running */ SendFinishedStartupNotification(fd); if (module->window == Root) { exit(0); } Loop(fd); return 0; } /* * * Read the entire window list from fvwm * */ void Loop(int *fd) { while (1) { FvwmPacket* packet = ReadFvwmPacket(fd[1]); if ( packet == NULL ) { exit(0); } else { process_message( packet->type, packet->body ); } } } /* * * Process window list messages * */ void process_message(unsigned long type,unsigned long *body) { switch(type) { /* should turn off this packet but it comes after config_list * so have to accept at least one */ case M_CONFIGURE_WINDOW: list_configure(body); break; case M_WINDOW_NAME: list_window_name(body); break; case M_ICON_NAME: list_icon_name(body); break; case M_RES_CLASS: list_class(body); break; case M_RES_NAME: list_res_name(body); break; case M_END_WINDOWLIST: list_end(); break; default: break; } } /* * * Procedure: * SIGPIPE handler - SIGPIPE means fvwm is dying * */ static RETSIGTYPE TerminateHandler(int sig) { fvwmSetTerminate(sig); SIGNAL_RETURN; } /* * * Got window configuration info - if its our window, save data * */ void list_configure(unsigned long *body) { struct ConfigWinPacket *cfgpacket = (void *) body; if ( (module->window == cfgpacket->frame)|| (module->window == cfgpacket->w) || ((cfgpacket->icon_w != 0)&& (module->window == cfgpacket->icon_w)) || ((cfgpacket->icon_pixmap_w)&& (module->window == cfgpacket->icon_pixmap_w))) { module->window = cfgpacket->frame; target.id = cfgpacket->w; target.frame = cfgpacket->frame; target.frame_x = cfgpacket->frame_x; target.frame_y = cfgpacket->frame_y; target.frame_w = cfgpacket->frame_width; target.frame_h = cfgpacket->frame_height; target.desktop = cfgpacket->desk; target.layer = cfgpacket->layer; memcpy(&target.flags, &(cfgpacket->flags), sizeof(cfgpacket->flags)); target.title_h = cfgpacket->title_height; target.title_dir = GET_TITLE_DIR(cfgpacket); target.border_w = cfgpacket->border_width; target.base_w = cfgpacket->hints_base_width; target.base_h = cfgpacket->hints_base_height; target.width_inc = cfgpacket->orig_hints_width_inc; target.height_inc = cfgpacket->orig_hints_height_inc; target.gravity = cfgpacket->hints_win_gravity; target.ewmh_hint_layer = cfgpacket->ewmh_hint_layer; target.ewmh_hint_desktop = cfgpacket->ewmh_hint_desktop; target.ewmh_window_type = cfgpacket->ewmh_window_type; found = 1; my_layer = (int)target.layer; if (my_layer < minimal_layer) { my_layer = minimal_layer; } } } /* * * Capture Window name info * */ void list_window_name(unsigned long *body) { if ( (module->window == (Window)body[1])|| (module->window == (Window)body[0])) { strncpy(target.name,(char *)&body[3],255); } } /* * * Capture Window Icon name info * */ void list_icon_name(unsigned long *body) { if ( (module->window == (Window)body[1])|| (module->window == (Window)body[0])) { strncpy(target.icon_name,(char *)&body[3],255); } } /* * * Capture Window class name info * */ void list_class(unsigned long *body) { if ( (module->window == (Window)body[1])|| (module->window == (Window)body[0])) { strncpy(target.class,(char *)&body[3],255); } } /* * * Capture Window resource info * */ void list_res_name(unsigned long *body) { if ((module->window == (Window)body[1])|| (module->window == (Window)body[0])) { strncpy(target.res,(char *)&body[3],255); } } void list_property_change(unsigned long *body) { if (body[0] == MX_PROPERTY_CHANGE_BACKGROUND && body[2] == 0 && CSET_IS_TRANSPARENT_PR(colorset)) { if (UsePixmapDrawing) { PixmapDrawWindow( main_width, main_height); } else { UpdateBackgroundTransparency( dpy, main_win, main_width, main_height, &Colorset[(colorset)], Pdepth, gc, True); } } } void list_config_info(unsigned long *body) { char *tline, *token; tline = (char*)&body[3]; tline = GetNextToken(tline, &token); if (StrEquals(token, "Colorset") && colorset >= 0 && LoadColorset(tline) == colorset) { if (FftSupport && Ffont->fftf.fftfont != NULL) { UsePixmapDrawing = True; } /* track all colorset changes & update display if necessary */ /* ask for movement events iff transparent */ if (CSET_IS_TRANSPARENT(colorset)) { mw_events |= StructureNotifyMask; if (CSET_IS_TRANSPARENT_PR_PURE(colorset)) { UsePixmapDrawing = False; } } else { mw_events &= ~(StructureNotifyMask); } if (UsePixmapDrawing) { #if 0 mw_events &= ~(ExposureMask); #endif } else { mw_events |= ExposureMask; } XSelectInput(dpy, main_win, mw_events); XSetForeground(dpy, gc, Colorset[colorset].fg); if (UsePixmapDrawing) { PixmapDrawWindow(main_width, main_height); } else { SetWindowBackground( dpy, main_win, main_width, main_height, &Colorset[colorset], Pdepth, gc, True); } } else if (StrEquals(token, XINERAMA_CONFIG_STRING)) { FScreenConfigureModule(tline); } if (token) free(token); } /* * * Process X Events * */ int ProcessXEvent(int x, int y) { XEvent Event,event; static int is_key_pressed = 0; static int is_button_pressed = 0; char buf[32]; static int ex=10000, ey=10000, ex2=0, ey2=0; while (FPending(dpy)) { FNextEvent(dpy,&Event); switch(Event.type) { case Expose: ex = min(ex, Event.xexpose.x); ey = min(ey, Event.xexpose.y); ex2 = max(ex2, Event.xexpose.x + Event.xexpose.width); ey2=max(ey2 , Event.xexpose.y + Event.xexpose.height); while (FCheckTypedEvent(dpy, Expose, &Event)) { ex = min(ex, Event.xexpose.x); ey = min(ey, Event.xexpose.y); ex2 = max( ex2, Event.xexpose.x + Event.xexpose.width); ey2=max(ey2, Event.xexpose.y + Event.xexpose.height); } if (FftSupport && Ffont->fftf.fftfont != NULL) { XClearArea( dpy, main_win, ex, ey, ex2-ex, ey2-ey, False); } DrawItems(main_win, ex, ey, ex2-ex, ey2-ey); ex = ey = 10000; ex2 = ey2 = 0; break; case KeyPress: is_key_pressed = 1; break; case ButtonPress: is_button_pressed = Event.xbutton.button; break; case KeyRelease: if (is_key_pressed) { exit(0); } break; case ButtonRelease: if (is_button_pressed) { if (is_button_pressed == 2 && Event.xbutton.button == 2) { /* select a new window when * button 2 is pressed */ SetMessageMask( fd, M_CONFIGURE_WINDOW | M_WINDOW_NAME | M_ICON_NAME | M_RES_CLASS | M_RES_NAME | M_END_WINDOWLIST | M_CONFIG_INFO | M_END_CONFIG_INFO| M_SENDCONFIG); SendText(fd, "Send_WindowList", 0); XDestroyWindow(dpy, main_win); DestroyList(); fvwmlib_get_target_window( dpy, screen, module->name, &(module->window), True); found = 0; return 1; } else { exit(0); } } break; case ClientMessage: if (Event.xclient.format==32 && Event.xclient.data.l[0]==wm_del_win) { exit(0); } break; case ReparentNotify: if (minimal_layer >= 0) { sprintf(buf, "Layer 0 %d", my_layer); SendText(fd, buf, main_win); } SendText(fd, "Raise", main_win); break; case ConfigureNotify: fev_sanitise_configure_notify(&Event.xconfigure); /* this only happens with transparent windows, * slurp up as many events as possible before * redrawing to reduce flickering */ while (FCheckTypedEvent( dpy, ConfigureNotify, &event)) { fev_sanitise_configure_notify( &event.xconfigure); if (!event.xconfigure.send_event) continue; Event.xconfigure.x = event.xconfigure.x; Event.xconfigure.y = event.xconfigure.y; Event.xconfigure.send_event = True; } /* Only refresh if moved */ if ((Event.xconfigure.send_event || CSET_IS_TRANSPARENT_PR_PURE(colorset)) && (x != Event.xconfigure.x || y != Event.xconfigure.y)) { static Bool is_initial_cn = True; Bool do_eat_expose = False; x = Event.xconfigure.x; y = Event.xconfigure.y; /* flush any expose events */ if (UsePixmapDrawing) { PixmapDrawWindow( main_width, main_height); do_eat_expose = True; } else if (colorset == -1) { do_eat_expose = True; } else if (UpdateBackgroundTransparency( dpy, main_win, main_width, main_height, &Colorset[(colorset)], Pdepth, gc, True) == True) { do_eat_expose = True; } if (do_eat_expose == True && is_initial_cn == False) { while (FCheckTypedEvent( dpy, Expose, &Event)) { /* nothing */ } } is_initial_cn = False; } break; } } XFlush (dpy); return 0; } /* * * End of window list, open an x window and display data in it * */ void list_end(void) { XSizeHints mysizehints; XGCValues gcv; unsigned long gcm; int lmax,height; int x,y; XSetWindowAttributes attributes; if(!found) { exit(0); } /* tell fvwm to only send config messages */ SetMessageMask(fd, M_CONFIG_INFO | M_SENDCONFIG); if ((Ffont = FlocaleLoadFont(dpy, font_string, module->name)) == NULL) { fprintf( stderr,"%s: cannot load font, exiting\n", module->name); exit(1); } /* chose the rendering methode */ if (FftSupport && Ffont->fftf.fftfont != NULL) { UsePixmapDrawing = True; } /* make window infomation list */ MakeList(); /* size and create the window */ lmax = max_col1 + max_col2 + 15; height = ListSize * (Ffont->height); mysizehints.flags= USSize|USPosition|PWinGravity|PResizeInc|PBaseSize|PMinSize| PMaxSize; main_width = mysizehints.width = lmax + 10; main_height = mysizehints.height = height + 10; mysizehints.width_inc = 1; mysizehints.height_inc = 1; mysizehints.base_height = mysizehints.height; mysizehints.base_width = mysizehints.width; mysizehints.min_height = mysizehints.height; mysizehints.min_width = mysizehints.width; mysizehints.max_height = mysizehints.height; mysizehints.max_width = mysizehints.width; mysizehints.win_gravity = NorthWestGravity; { int sx; int sy; int sw; int sh; Window JunkW; int JunkC; unsigned int JunkM; fscreen_scr_arg fscr; if (!FQueryPointer( dpy, Root, &JunkW, &JunkW, &x, &y, &JunkC, &JunkC, &JunkM)) { /* pointer is on a different screen */ x = 0; y = 0; } fscr.xypos.x = x; fscr.xypos.y = y; FScreenGetScrRect(&fscr, FSCREEN_XYPOS, &sx, &sy, &sw, &sh); if (y + height + 100 > sy + sh) { y = sy + sh - height - 10; mysizehints.win_gravity = SouthWestGravity; } if (x + lmax + 100 > sx + sw) { x = sx + sw - lmax - 10; if (mysizehints.win_gravity == SouthWestGravity) mysizehints.win_gravity = SouthEastGravity; else mysizehints.win_gravity = NorthEastGravity; } } if (Pdepth < 2) { back_pix = GetColor("white"); fore_pix = GetColor("black"); } else { back_pix = (colorset < 0)? GetColor(BackColor) : Colorset[colorset].bg; fore_pix = (colorset < 0)? GetColor(ForeColor) : Colorset[colorset].fg; } attributes.colormap = Pcmap; attributes.border_pixel = 0; attributes.background_pixel = back_pix; main_win = XCreateWindow( dpy, Root, x, y, mysizehints.width, mysizehints.height, 0, Pdepth, InputOutput, Pvisual, CWColormap | CWBackPixel | CWBorderPixel, &attributes); wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); XSetWMProtocols(dpy,main_win,&wm_del_win,1); /* hack to prevent mapping on wrong screen with StartsOnScreen */ FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &mysizehints); XSetWMNormalHints(dpy,main_win,&mysizehints); /* have to ask for configure events when transparent */ if (CSET_IS_TRANSPARENT(colorset)) { mw_events |= StructureNotifyMask; if (CSET_IS_TRANSPARENT_PR_PURE(colorset)) { UsePixmapDrawing = 0; } } if (!UsePixmapDrawing) { mw_events |= ExposureMask; } XSelectInput(dpy, main_win, mw_events); change_window_name(module->name); gcm = GCForeground; gcv.foreground = fore_pix; if (Ffont->font != NULL) { gcm |= GCFont; gcv.font = Ffont->font->fid; } gc = fvwmlib_XCreateGC(dpy, main_win, gcm, &gcv); if (UsePixmapDrawing) { PixmapDrawWindow(main_width, main_height); } else if (colorset >= 0) { SetWindowBackground( dpy, main_win, main_width, main_height, &Colorset[(colorset)], Pdepth, gc, True); } XMapWindow(dpy,main_win); /* Window is created. Display it until the user clicks or deletes it. * also grok any dynamic config changes */ while(1) { FvwmPacket* packet; int x_fd = XConnectionNumber(dpy); fd_set fdset; FD_ZERO(&fdset); FD_SET(fd[1], &fdset); FD_SET(x_fd, &fdset); /* process all X events first */ if (ProcessXEvent(x,y) == 1) { return; } /* wait for X-event or config line */ select(fd_width, SELECT_FD_SET_CAST &fdset, NULL, NULL, NULL ); /* parse any dynamic config lines */ if (FD_ISSET(fd[1], &fdset)) { packet = ReadFvwmPacket(fd[1]); if (packet == NULL) exit(0); if (packet && packet->type == MX_PROPERTY_CHANGE) { list_property_change(packet->body); } if (packet && packet->type == M_CONFIG_INFO) { list_config_info(packet->body); } } } } /* * * Draw the items * */ void DrawItems(Drawable d, int x, int y, int w, int h) { int fontheight,i=0; struct Item *cur = itemlistRoot; Region region = 0; fontheight = Ffont->height; FwinString->win = d; FwinString->gc = gc; FwinString->flags.has_clip_region = False; if (w > 0) { XRectangle r; r.x = x; r.y = y; r.width = w; r.height = h; region = XCreateRegion(); XUnionRectWithRegion(&r, region, region); XSetRegion(dpy, gc, region); FwinString->flags.has_clip_region = True; FwinString->clip_region = region; } if (colorset >= 0) { FwinString->colorset = &Colorset[colorset]; FwinString->flags.has_colorset = True; } while(cur != NULL) /* may be optimised */ { /* first column */ FwinString->str = cur->col1; FwinString->x = 5; FwinString->y = 5 + Ffont->ascent + i * fontheight; FlocaleDrawString(dpy, Ffont, FwinString, 0); /* second column */ FwinString->str = cur->col2; FwinString->x = 10 + max_col1; FlocaleDrawString(dpy, Ffont, FwinString, 0); ++i; cur = cur->next; } if (FwinString->flags.has_clip_region) { XDestroyRegion(region); XSetClipMask(dpy, gc, None); } XFlush (dpy); } void PixmapDrawWindow(int w, int h) { Pixmap pix; XGCValues gcv; unsigned long gcm; if (colorset >= 0) { Pixmap cs_pix; cs_pix = CreateBackgroundPixmap(dpy, main_win, w, h, &Colorset[(colorset)], Pdepth, gc, False); if (cs_pix == ParentRelative) { pix = cs_pix; } else { pix = CreateTiledPixmap( dpy, cs_pix, 0,0,w,h,Pdepth, gc); XFreePixmap(dpy, cs_pix); } } else { gcm = GCForeground; gcv.foreground = back_pix; XChangeGC(dpy, gc, gcm, &gcv); pix = XCreatePixmap(dpy, main_win, w, h, Pdepth); XFillRectangle(dpy, pix, gc, 0, 0, w, h); gcv.foreground = fore_pix; XChangeGC(dpy, gc, gcm, &gcv); } if (pix != ParentRelative) { DrawItems(pix, 0, 0, 0, 0); XSetWindowBackgroundPixmap(dpy, main_win, pix); XClearWindow(dpy, main_win); XFreePixmap(dpy, pix); } else { XSetWindowBackgroundPixmap(dpy, main_win, pix); XClearWindow(dpy, main_win); DrawItems(main_win, 0, 0, 0, 0); } } /* * Change the window name displayed in the title bar. */ void change_window_name(char *str) { XTextProperty name; XClassHint myclasshints; if (XStringListToTextProperty(&str,1,&name) == 0) { fprintf(stderr,"%s: cannot allocate window name",module->name); return; } XSetWMName(dpy,main_win,&name); XSetWMIconName(dpy,main_win,&name); XFree(name.value); myclasshints.res_name = str; myclasshints.res_class = "FvwmIdent"; XSetClassHint(dpy,main_win,&myclasshints); } void DestroyList(void) { struct Item *t; struct Item *tmp; for (t = itemlistRoot; t; t = tmp) { tmp = t->next; free(t); } itemlistRoot = NULL; } /* * * Add s1(string at first column) and s2(string at second column) to itemlist * */ void AddToList(char *s1, char* s2) { int tw1, tw2; struct Item* item, *cur = itemlistRoot; tw1 = FlocaleTextWidth(Ffont, s1, strlen(s1)); tw2 = FlocaleTextWidth(Ffont, s2, strlen(s2)); max_col1 = max_col1 > tw1 ? max_col1 : tw1; max_col2 = max_col2 > tw2 ? max_col2 : tw2; item = (struct Item*)safemalloc(sizeof(struct Item)); item->col1 = s1; item->col2 = s2; item->next = NULL; if (cur == NULL) { itemlistRoot = item; } else { while(cur->next != NULL) { cur = cur->next; } cur->next = item; } ListSize++; } void MakeList(void) { int bw,width,height,x1,y1,x2,y2; char loc[20]; static char xstr[6],ystr[6]; /* GSFR - quick hack because the new macros depend on a prt reference */ struct target_struct *targ = ⌖ ListSize = 0; bw = 2*target.border_w; width = target.frame_w - bw; height = target.frame_h - bw; if (target.title_dir == DIR_W || target.title_dir == DIR_E) { width -= target.title_h; } else if (target.title_dir == DIR_N || target.title_dir == DIR_S) { height -= target.title_h; } sprintf(desktop, "%ld", target.desktop); sprintf(layer, "%ld", target.layer); sprintf(id, "0x%x", (unsigned int)target.id); sprintf(swidth, "%d", width); sprintf(sheight, "%d", height); sprintf(borderw, "%ld", target.border_w); sprintf(xstr, "%ld", target.frame_x); sprintf(ystr, "%ld", target.frame_y); AddToList("Name:", target.name); AddToList("Icon Name:", target.icon_name); AddToList("Class:", target.class); AddToList("Resource:", target.res); AddToList("Window ID:", id); AddToList("Desk:", desktop); if (FScreenIsEnabled()) { sprintf(xin_str, "%d", FScreenOfPointerXY(target.frame_x, target.frame_y)); AddToList("Xinerama Screen:", xin_str); } AddToList("Layer:", layer); AddToList("Width:", swidth); AddToList("Height:", sheight); AddToList("X (current page):", xstr); AddToList("Y (current page):", ystr); AddToList("Boundary Width:", borderw); AddToList("StickyPage:", (IS_STICKY_ACROSS_PAGES(targ) ? yes : no)); AddToList("StickyDesk:", (IS_STICKY_ACROSS_DESKS(targ) ? yes : no)); AddToList("StickyPageIcon:", (IS_ICON_STICKY_ACROSS_PAGES(targ) ? yes : no)); AddToList("StickyDeskIcon:", (IS_ICON_STICKY_ACROSS_DESKS(targ) ? yes : no)); AddToList("NoTitle:", (HAS_TITLE(targ) ? no : yes)); AddToList("Iconified:", (IS_ICONIFIED(targ) ? yes : no)); AddToList("Transient:", (IS_TRANSIENT(targ) ? yes : no)); AddToList("WindowListSkip:", (DO_SKIP_WINDOW_LIST(targ) ? yes : no)); switch(target.gravity) { case ForgetGravity: AddToList("Gravity:", "Forget"); break; case NorthWestGravity: AddToList("Gravity:", "NorthWest"); break; case NorthGravity: AddToList("Gravity:", "North"); break; case NorthEastGravity: AddToList("Gravity:", "NorthEast"); break; case WestGravity: AddToList("Gravity:", "West"); break; case CenterGravity: AddToList("Gravity:", "Center"); break; case EastGravity: AddToList("Gravity:", "East"); break; case SouthWestGravity: AddToList("Gravity:", "SouthWest"); break; case SouthGravity: AddToList("Gravity:", "South"); break; case SouthEastGravity: AddToList("Gravity:", "SouthEast"); break; case StaticGravity: AddToList("Gravity:", "Static"); break; default: AddToList("Gravity:", "Unknown"); break; } x1 = target.frame_x; if(x1 < 0) { x1 = 0; } x2 = DisplayWidth(dpy,screen) - x1 - target.frame_w; if(x2 < 0) { x2 = 0; } y1 = target.frame_y; if(y1 < 0) { y1 = 0; } y2 = DisplayHeight(dpy,screen) - y1 - target.frame_h; if(y2 < 0) { y2 = 0; } width = (width - target.base_w)/target.width_inc; height = (height - target.base_h)/target.height_inc; sprintf(loc,"%dx%d",width,height); strcpy(geometry, loc); if ((target.gravity == EastGravity) || (target.gravity == NorthEastGravity)|| (target.gravity == SouthEastGravity)) { sprintf(loc,"-%d",x2); } else { sprintf(loc,"+%d",x1); } strcat(geometry, loc); if((target.gravity == SouthGravity)|| (target.gravity == SouthEastGravity)|| (target.gravity == SouthWestGravity)) { sprintf(loc,"-%d",y2); } else { sprintf(loc,"+%d",y1); } strcat(geometry, loc); AddToList("Geometry:", geometry); { Atom *protocols = NULL, *ap; Atom _XA_WM_TAKE_FOCUS = XInternAtom( dpy, "WM_TAKE_FOCUS", False); XWMHints *wmhintsp = XGetWMHints(dpy,target.id); int i,n; Boolean HasTakeFocus=False,InputField=True; char *focus_policy="",*ifstr="",*tfstr=""; if (wmhintsp) { InputField=wmhintsp->input; ifstr=InputField?"True":"False"; XFree(wmhintsp); } else { ifstr="XWMHints missing"; } if (XGetWMProtocols(dpy,target.id,&protocols,&n)) { for (i = 0, ap = protocols; i < n; i++, ap++) { if (*ap == (Atom)_XA_WM_TAKE_FOCUS) HasTakeFocus = True; } tfstr=HasTakeFocus?"Present":"Absent"; XFree(protocols); } else { tfstr="XGetWMProtocols failed"; } if (HasTakeFocus) { if (InputField) { focus_policy = "Locally Active"; } else { focus_policy = "Globally Active"; } } else { if (InputField) { focus_policy = "Passive"; } else { focus_policy = "No Input"; } } AddToList("Focus Policy:",focus_policy); AddToList(" - Input Field:",ifstr); AddToList(" - WM_TAKE_FOCUS:",tfstr); { /* flags hints that were supplied */ long supplied_return; int getrc; XSizeHints *size_hints = XAllocSizeHints(); /* the size hints */ if ((getrc = XGetWMSizeHints( dpy,target.id, /* get size hints */ size_hints, /* Hints */ &supplied_return, XA_WM_ZOOM_HINTS))) { if (supplied_return & PAspect) { /* if window has a aspect ratio */ sprintf( mymin_aspect, "%d/%d", size_hints->min_aspect.x, size_hints->min_aspect.y); AddToList( "Minimum aspect ratio:", mymin_aspect); sprintf( max_aspect, "%d/%d", size_hints->max_aspect.x, size_hints->max_aspect.y); AddToList( "Maximum aspect ratio:", max_aspect); } /* end aspect ratio */ XFree(size_hints); } /* end getsizehints worked */ } } /* EWMH window type */ if (target.ewmh_window_type == EWMH_WINDOW_TYPE_DESKTOP_ID) AddToList("EWMH Window Type:","Desktop"); else if (target.ewmh_window_type == EWMH_WINDOW_TYPE_DIALOG_ID) AddToList("EWMH Window Type:","Dialog"); else if (target.ewmh_window_type == EWMH_WINDOW_TYPE_DOCK_ID) AddToList("EWMH Window Type:","Dock"); else if (target.ewmh_window_type == EWMH_WINDOW_TYPE_MENU_ID) AddToList("EWMH Window Type:","Menu"); else if (target.ewmh_window_type == EWMH_WINDOW_TYPE_NORMAL_ID) AddToList("EWMH Window Type:","Normal"); else if (target.ewmh_window_type == EWMH_WINDOW_TYPE_TOOLBAR_ID) AddToList("EWMH Window Type:","ToolBar"); /* EWMH wm state */ ewmh_init_state[0] = '\0'; if (HAS_EWMH_INIT_FULLSCREEN_STATE(targ) == EWMH_STATE_HAS_HINT) { strcat(ewmh_init_state, "FullScreen "); } if (HAS_EWMH_INIT_HIDDEN_STATE(targ) == EWMH_STATE_HAS_HINT) { strcat(ewmh_init_state, "Iconic "); } if (HAS_EWMH_INIT_MAXHORIZ_STATE(targ) == EWMH_STATE_HAS_HINT) { strcat(ewmh_init_state, "MaxHoriz "); } if (HAS_EWMH_INIT_MAXVERT_STATE(targ) == EWMH_STATE_HAS_HINT) { strcat(ewmh_init_state, "MaxVert "); } if (HAS_EWMH_INIT_MODAL_STATE(targ) == EWMH_STATE_HAS_HINT) { strcat(ewmh_init_state, "Modal "); } if (HAS_EWMH_INIT_SHADED_STATE(targ)== EWMH_STATE_HAS_HINT) { strcat(ewmh_init_state, "Shaded "); } if (HAS_EWMH_INIT_SKIP_PAGER_STATE(targ) == EWMH_STATE_HAS_HINT || HAS_EWMH_INIT_SKIP_TASKBAR_STATE(targ) == EWMH_STATE_HAS_HINT ) { strcat(ewmh_init_state, "SkipList "); } if (HAS_EWMH_INIT_STICKY_STATE(targ) == EWMH_STATE_HAS_HINT || (HAS_EWMH_INIT_WM_DESKTOP(targ) == EWMH_STATE_HAS_HINT && (target.ewmh_hint_desktop == (unsigned long)-2 || target.ewmh_hint_desktop == (unsigned long)-1))) { strcat(ewmh_init_state, "Sticky "); } /* FIXME: we should use the fvwm default layers */ if (target.ewmh_hint_layer == 6) { strcat(ewmh_init_state, "StaysOnTop "); } else if (target.ewmh_hint_layer == 2) { strcat(ewmh_init_state, "StaysOnBottom "); } if (HAS_EWMH_INIT_WM_DESKTOP(targ) == EWMH_STATE_HAS_HINT && target.ewmh_hint_desktop < 256) { strcat(ewmh_init_state, "StartOnDesk"); sprintf(ewmh_init_state, "%s %lu ", ewmh_init_state, target.ewmh_hint_desktop); } if (ewmh_init_state[0] != '\0') { /* remove ending space */ ewmh_init_state[strlen(ewmh_init_state)-1] = '\0'; AddToList("EWMH Init State:",ewmh_init_state); } } /* X Error Handler */ static int ErrorHandler(Display *d, XErrorEvent *event) { #if 0 if (event->error_code == BadPixmap) { return 0; } if (event->error_code == BadDrawable) { return 0; } if (event->error_code == FRenderGetErrorCodeBase() + FRenderBadPicture) { return 0; } #endif PrintXErrorAndCoredump(d, event, module->name); return 0; } fvwm-2.6.7/modules/FvwmIdent/FvwmIdent.h0000644000175700017570000000263412773467232015115 00000000000000/* -*-c-*- */ #include "libs/fvwmlib.h" #include "fvwm/fvwm.h" #include "libs/vpacket.h" struct target_struct { char res[256]; char class[256]; char name[256]; char icon_name[256]; unsigned long id; unsigned long frame; long frame_x; long frame_y; long frame_w; long frame_h; long base_w; long base_h; long width_inc; long height_inc; long desktop; long layer; unsigned long gravity; window_flags flags; long title_h; long border_w; unsigned title_dir; long ewmh_hint_layer; unsigned long ewmh_hint_desktop; long ewmh_window_type; }; struct Item { char* col1; char* col2; struct Item* next; }; /* * * Subroutine Prototypes * */ void Loop(int *fd); RETSIGTYPE DeadPipe(int nonsense) __attribute__((noreturn)); void process_message(unsigned long type, unsigned long *body); void PixmapDrawWindow(int h, int w); void DrawItems(Drawable d, int x, int y, int w, int h); void change_window_name(char *str); Pixel GetColor(char *name); void DestroyList(void); void AddToList(char *, char *); void MakeList(void); void change_defaults(char *body); void list_configure(unsigned long *body); void list_window_name(unsigned long *body); void list_icon_name(unsigned long *body); void list_class(unsigned long *body); void list_res_name(unsigned long *body); void list_property_change(unsigned long *body); void list_end(void); static int ErrorHandler(Display *d, XErrorEvent *event); fvwm-2.6.7/modules/FvwmBacker/0000755000175700017570000000000013010103343013207 500000000000000fvwm-2.6.7/modules/FvwmBacker/Makefile.am0000644000175700017570000000107513001406607015177 00000000000000## Process this file with automake to create Makefile.in moduledir = @FVWM_MODULEDIR@ configdir = @FVWM_DATADIR@ module_PROGRAMS = FvwmBacker man_MANS = FvwmBacker.1 EXTRA_DIST = $(man_MANS) ConfigFvwmBacker config_DATA = \ ConfigFvwmBacker FvwmBacker_SOURCES = FvwmBacker.c FvwmBacker.h root_bits.c FvwmBacker_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm \ $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) \ $(Xrender_LIBS) $(rsvg_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) $(Xrender_CFLAGS) fvwm-2.6.7/modules/FvwmBacker/Makefile.in0000644000175700017570000006253613010103322015205 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmBacker$(EXEEXT) subdir = modules/FvwmBacker DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmBacker.1.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmBacker.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(configdir)" PROGRAMS = $(module_PROGRAMS) am_FvwmBacker_OBJECTS = FvwmBacker.$(OBJEXT) root_bits.$(OBJEXT) FvwmBacker_OBJECTS = $(am_FvwmBacker_OBJECTS) FvwmBacker_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmBacker_SOURCES) DIST_SOURCES = $(FvwmBacker_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ configdir = @FVWM_DATADIR@ man_MANS = FvwmBacker.1 EXTRA_DIST = $(man_MANS) ConfigFvwmBacker config_DATA = \ ConfigFvwmBacker FvwmBacker_SOURCES = FvwmBacker.c FvwmBacker.h root_bits.c FvwmBacker_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm \ $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 -lm $(X_EXTRA_LIBS) \ $(Xrender_LIBS) $(rsvg_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) $(Xrender_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmBacker/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmBacker/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmBacker.1: $(top_builddir)/config.status $(srcdir)/FvwmBacker.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmBacker$(EXEEXT): $(FvwmBacker_OBJECTS) $(FvwmBacker_DEPENDENCIES) $(EXTRA_FvwmBacker_DEPENDENCIES) @rm -f FvwmBacker$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmBacker_OBJECTS) $(FvwmBacker_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmBacker.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root_bits.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-man install-modulePROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA uninstall-man \ uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-configDATA install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-modulePROGRAMS install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-configDATA uninstall-man uninstall-man1 \ uninstall-modulePROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmBacker/FvwmBacker.10000644000175700017570000001267113010101137015246 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .TH FvwmBacker 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmBacker \- the fvwm background changer module .SH SYNOPSIS Module FvwmBacker \fIFvwmBacker\fP can only be invoked by fvwm. Command line invocation of the \fIFvwmBacker\fP module will not work. .SH DESCRIPTION The FvwmBacker module provides functionality to change the background when changing desktops. Any command can be executed to change the backgrounds. Actually, any arbitrary command can be sent to fvwm to execute, so you could also do things such as changing window border colors, etc. .SH COPYRIGHTS The FvwmBacker module is the original work of Mike Finger. Copyright 1994, Mike Finger. The author makes no guarantees or warranties of any kind about the use of this module. Use this module at your own risk. You may freely use this module or any portion of it for any purpose as long as the copyright is kept intact. .SH INITIALIZATION During initialization, \fIFvwmBacker\fP gets config info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ). Available options are discussed in a later section. .SH INVOCATION FvwmBacker can be invoked by fvwm during initialization by inserting the line .nf AddToFunc StartFunction I Module FvwmBacker .fi in the .fvwm2rc file. FvwmBacker can be started using a 'Module FvwmBacker' command or stopped using a 'KillModule FvwmBacker' command at any time when fvwm is running. FvwmBacker must reside in a directory that is listed in the ModulePath option of fvwm for it to be executed by fvwm. .SH CONFIGURATION OPTIONS The following options can be placed in the .fvwm2rc file .IP "*FvwmBacker: Command \fI(Desk d, Page x y) command\fP" Specifies the \fIcommand\fP to execute when the viewport matches the arguments for the desk d, page x coordinate and y coordinate. Any or all of these three numeric arguments can be replaced with an asterisk (*) to indicate that any value matches, in this case Desk or Page parts can be skipped. If either the \fIDesk\fP or the \fIPage\fP parts are omitted, the command is not executed if only the desk or the page is switched. If neither is given, the command is executed only once when the module is started. This is not the same as using asterisks for the numeric arguments: if asterisks are used, the command is always executed when only the desk or page changes, if the corresponding part is omitted, the command is never executed when only the desk or page changes. If the \fIcommand\fP is \fI-solid\fP FvwmBacker uses the next argument as a color in the X database and sets the background to that color without generating a system call to xsetroot (only single word color names may be used). If the \fIcommand\fP is \fIcolorset\fP FvwmBacker uses the background specified in colorset \fIn\fP for the given desk. Please refer to the man page of the FvwmTheme module for details about colorsets. Otherwise the command is sent to fvwm to execute. .IP "*FvwmBacker: RetainPixmap" Causes FvwmBacker to retain and publish the Pixmap with which the background has been set. This works only for the .IR -solid " or " colorset commands. This is useful for applications which want to use the root Pixmap on the background to simulate transparency (for example, Eterm and Aterm use this method). This option should also be used for the RootTransparent colorset option (see the FvwmTheme man page). Note: with a colorset background this command may add a lot of memory to the X server. For example, this adds the pixmap width times height bytes with a TiledPixmap image, screen_width times screen_height bytes with a Pixmap image or a C,B,D,R,S or Y Gradient and screen_width bytes with a VGradient or screen height bytes with an HGradient. .IP "*FvwmBacker: DoNotRetainPixmap" Cancels the effect of the previous option. This is the default. .SH RUN-TIME CONFIGURATION It it possible to replace FvwmBacker's configuration at run-time, although it is not yet possible to remove existing configuration lines. This is done by simply removing the old configuration from withing fvwm and then read a new one. This can be done in many ways, for example by using an fvwm function or one of the modules .BR FvwmCommand " or " FvwmConsole . Example: .nf .sp DestroyModuleConfig FvwmBacker* *FvwmBacker: Command (Desk 0) -solid black *FvwmBacker: Command (Desk 1) -solid blue .sp .fi .SH OLD-STYLE OPTIONS There is continued support for the now deprecated option: .IP "*FvwmBacker: Desk \fId command\fP" It is functionally equivalent to omitting the page coordinates with \fI*FvwmBacker: Command\fP: .nf .sp *FvwmBacker: Command (Desk Id) command .sp .fi .SH SAMPLE CONFIGURATION The following are excerpts from an .fvwm2rc file which describe FvwmBacker initialization commands: .nf .sp #### # Set Up Backgrounds for different desktop pages (2 desks, 3x2 pages). #### *FvwmBacker: Command (Page 2 *) -solid steelblue *FvwmBacker: Command (Desk 0, Page 0 0) Exec fvwm-root $[HOME]/bg2.xpm *FvwmBacker: Command (Desk 0, Page 0 1) -solid midnightblue *FvwmBacker: Command (Desk 0, Page 1 *) -solid yellow *FvwmBacker: Command (Desk 1, Page * 0) -solid navy *FvwmBacker: Command (Desk 1, Page * 1) Colorset 5 .sp .fi .SH AUTHOR Mike Finger (mfinger@mermaid.micro.umn.edu) (Mike_Finger@atk.com) (doodman on IRC, check the #linux channel) .SH Modified by Andrew Davison (davison@cs.monash.edu.au) Michael Han (mikehan@best.com) Mikhael Goikhman (migo@homemail.com) fvwm-2.6.7/modules/FvwmBacker/FvwmBacker.1.in0000644000175700017570000001270012753310630015661 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH FvwmBacker 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmBacker \- the fvwm background changer module .SH SYNOPSIS Module FvwmBacker \fIFvwmBacker\fP can only be invoked by fvwm. Command line invocation of the \fIFvwmBacker\fP module will not work. .SH DESCRIPTION The FvwmBacker module provides functionality to change the background when changing desktops. Any command can be executed to change the backgrounds. Actually, any arbitrary command can be sent to fvwm to execute, so you could also do things such as changing window border colors, etc. .SH COPYRIGHTS The FvwmBacker module is the original work of Mike Finger. Copyright 1994, Mike Finger. The author makes no guarantees or warranties of any kind about the use of this module. Use this module at your own risk. You may freely use this module or any portion of it for any purpose as long as the copyright is kept intact. .SH INITIALIZATION During initialization, \fIFvwmBacker\fP gets config info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ). Available options are discussed in a later section. .SH INVOCATION FvwmBacker can be invoked by fvwm during initialization by inserting the line .nf AddToFunc StartFunction I Module FvwmBacker .fi in the .fvwm2rc file. FvwmBacker can be started using a 'Module FvwmBacker' command or stopped using a 'KillModule FvwmBacker' command at any time when fvwm is running. FvwmBacker must reside in a directory that is listed in the ModulePath option of fvwm for it to be executed by fvwm. .SH CONFIGURATION OPTIONS The following options can be placed in the .fvwm2rc file .IP "*FvwmBacker: Command \fI(Desk d, Page x y) command\fP" Specifies the \fIcommand\fP to execute when the viewport matches the arguments for the desk d, page x coordinate and y coordinate. Any or all of these three numeric arguments can be replaced with an asterisk (*) to indicate that any value matches, in this case Desk or Page parts can be skipped. If either the \fIDesk\fP or the \fIPage\fP parts are omitted, the command is not executed if only the desk or the page is switched. If neither is given, the command is executed only once when the module is started. This is not the same as using asterisks for the numeric arguments: if asterisks are used, the command is always executed when only the desk or page changes, if the corresponding part is omitted, the command is never executed when only the desk or page changes. If the \fIcommand\fP is \fI-solid\fP FvwmBacker uses the next argument as a color in the X database and sets the background to that color without generating a system call to xsetroot (only single word color names may be used). If the \fIcommand\fP is \fIcolorset\fP FvwmBacker uses the background specified in colorset \fIn\fP for the given desk. Please refer to the man page of the FvwmTheme module for details about colorsets. Otherwise the command is sent to fvwm to execute. .IP "*FvwmBacker: RetainPixmap" Causes FvwmBacker to retain and publish the Pixmap with which the background has been set. This works only for the .IR -solid " or " colorset commands. This is useful for applications which want to use the root Pixmap on the background to simulate transparency (for example, Eterm and Aterm use this method). This option should also be used for the RootTransparent colorset option (see the FvwmTheme man page). Note: with a colorset background this command may add a lot of memory to the X server. For example, this adds the pixmap width times height bytes with a TiledPixmap image, screen_width times screen_height bytes with a Pixmap image or a C,B,D,R,S or Y Gradient and screen_width bytes with a VGradient or screen height bytes with an HGradient. .IP "*FvwmBacker: DoNotRetainPixmap" Cancels the effect of the previous option. This is the default. .SH RUN-TIME CONFIGURATION It it possible to replace FvwmBacker's configuration at run-time, although it is not yet possible to remove existing configuration lines. This is done by simply removing the old configuration from withing fvwm and then read a new one. This can be done in many ways, for example by using an fvwm function or one of the modules .BR FvwmCommand " or " FvwmConsole . Example: .nf .sp DestroyModuleConfig FvwmBacker* *FvwmBacker: Command (Desk 0) -solid black *FvwmBacker: Command (Desk 1) -solid blue .sp .fi .SH OLD-STYLE OPTIONS There is continued support for the now deprecated option: .IP "*FvwmBacker: Desk \fId command\fP" It is functionally equivalent to omitting the page coordinates with \fI*FvwmBacker: Command\fP: .nf .sp *FvwmBacker: Command (Desk Id) command .sp .fi .SH SAMPLE CONFIGURATION The following are excerpts from an .fvwm2rc file which describe FvwmBacker initialization commands: .nf .sp #### # Set Up Backgrounds for different desktop pages (2 desks, 3x2 pages). #### *FvwmBacker: Command (Page 2 *) -solid steelblue *FvwmBacker: Command (Desk 0, Page 0 0) Exec fvwm-root $[HOME]/bg2.xpm *FvwmBacker: Command (Desk 0, Page 0 1) -solid midnightblue *FvwmBacker: Command (Desk 0, Page 1 *) -solid yellow *FvwmBacker: Command (Desk 1, Page * 0) -solid navy *FvwmBacker: Command (Desk 1, Page * 1) Colorset 5 .sp .fi .SH AUTHOR Mike Finger (mfinger@mermaid.micro.umn.edu) (Mike_Finger@atk.com) (doodman on IRC, check the #linux channel) .SH Modified by Andrew Davison (davison@cs.monash.edu.au) Michael Han (mikehan@best.com) Mikhael Goikhman (migo@homemail.com) fvwm-2.6.7/modules/FvwmBacker/FvwmBacker.c0000644000175700017570000004140713001406607015341 00000000000000/* -*-c-*- */ /* FvwmBacker Module for fvwm. * * Copyright 1994, Mike Finger (mfinger@mermaid.micro.umn.edu or * Mike_Finger@atk.com) * * The author makes not guarantees or warantees, either express or * implied. Feel free to use any contained here for any purpose, as long * and this and any other applicible copyrights are kept intact. * The functions in this source file that are based on part of the FvwmIdent * module for fvwm are noted by a small copyright atop that function, all others * are copyrighted by Mike Finger. For those functions modified/used, here is * the full, origonal copyright: * * Copyright 1994, Robert Nation and Nobutaka Suzuki. * No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. */ /* Modified to directly manipulate the X server if a solid color * background is requested. To use this, use "-solid " * as the command to be executed. * * A. Davison * Septmber 1994. */ /* 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 #include #include #include #if HAVE_SYS_BSDTYPES_H #include /* Saul */ #endif /* Saul */ #include #include #include #include "libs/FShape.h" #include "libs/Module.h" #include "libs/Colorset.h" #include "libs/Parse.h" #include "libs/PictureBase.h" #include "libs/FRenderInit.h" #include "libs/Graphics.h" #include "libs/XError.h" #include "FvwmBacker.h" /* migo (22-Nov-1999): Temporarily until fvwm_msg is moved to libs */ #define ERR #define fvwm_msg(t,l,f) fprintf(stderr, "[fvwm][FvwmBacker]: <> %s\n", f) unsigned long BackerGetColor(char *color); #define EXEC_CHANGED_PAGE 0x01 #define EXEC_CHANGED_DESK 0x02 #define EXEC_ALWAYS 0x04 struct Command { int desk; struct { unsigned do_ignore_desk : 1; unsigned do_ignore_page : 1; unsigned do_match_any_desk : 1; } flags; int x; /* Page X coordinate; -1 for glob */ int y; /* Page Y coordinate; -1 for glob */ /* The command type: * -1 = no command * 0 = command to be spawned * 1 = use a solid color background * 2 = use a colorset background */ int type; char* cmdStr; /* The command string (Type 0) */ unsigned long solidColor; /* A solid color after X parsing (Type 1) */ int colorset; /* The colorset to be used (Type 2) */ struct Command *next; }; typedef struct Command Command; typedef struct { Command *first; Command *last; } CommandChain; CommandChain *commands; int current_desk = 0; int current_x = 0; int current_y = 0; int current_colorset = -1; /* the last matched command colorset or -1 */ int fvwm_fd[2]; char *Module; /* i.e. "FvwmBacker" */ char *configPrefix; /* i.e. "*FvwmBacker" */ /* X Display information. */ Display* dpy; Window root; int screen; int MyDisplayHeight; int MyDisplayWidth; char* displayName = NULL; Bool RetainPixmap = False; Atom XA_XSETROOT_ID = None; Atom XA_ESETROOT_PMAP_ID = None; Atom XA_XROOTPMAP_ID = None; unsigned char *XsetrootData = NULL; int ErrorHandler(Display *d, XErrorEvent *event) { /* some errors are OK=ish */ if (0 && event->error_code == BadValue) return 0; PrintXErrorAndCoredump(d, event, Module); return 0; } int main(int argc, char **argv) { char *temp, *s; commands = (CommandChain*)safemalloc(sizeof(CommandChain)); commands->first = commands->last = NULL; /* Save the program name for error messages and config parsing */ temp = argv[0]; s = strrchr(argv[0], '/'); if (s != NULL) { temp = s + 1; } Module = temp; configPrefix = CatString2("*", Module); if ((argc != 6) && (argc != 7)) { fprintf(stderr, "%s Version %s should only be executed by fvwm!\n", Module, VERSION); exit(1); } fvwm_fd[0] = atoi(argv[1]); fvwm_fd[1] = atoi(argv[2]); /* Grab the X display information now. */ dpy = XOpenDisplay(displayName); if (!dpy) { fprintf(stderr, "%s: unable to open display '%s'\n", Module, XDisplayName (displayName)); exit (2); } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); MyDisplayHeight = DisplayHeight(dpy, screen); MyDisplayWidth = DisplayWidth(dpy, screen); XSetErrorHandler(ErrorHandler); flib_init_graphics(dpy); XA_XSETROOT_ID = XInternAtom(dpy, "_XSETROOT_ID", False); XA_ESETROOT_PMAP_ID = XInternAtom(dpy, "ESETROOT_PMAP_ID", False); XA_XROOTPMAP_ID = XInternAtom(dpy, "_XROOTPMAP_ID", False); signal (SIGPIPE, DeadPipe); /* Parse the config file */ ParseConfig(); SetMessageMask(fvwm_fd, M_NEW_PAGE | M_NEW_DESK | M_CONFIG_INFO | M_END_CONFIG_INFO | M_SENDCONFIG); /* ** we really only want the current desk/page, and window list sends it */ SendInfo(fvwm_fd, "Send_WindowList", 0); /* tell fvwm we're running */ SendFinishedStartupNotification(fvwm_fd); /* Recieve all messages from fvwm */ EndLessLoop(); /* Should never get here! */ return 1; } /* EndLessLoop - Read until we get killed, blocking when can't read */ void EndLessLoop(void) { while(1) { ReadFvwmPipe(); } } /* ReadFvwmPipe - Read a single message from the pipe from fvwm */ void ReadFvwmPipe(void) { FvwmPacket* packet = ReadFvwmPacket(fvwm_fd[1]); if ( packet == NULL ) { exit(0); } else { ProcessMessage( packet->type, packet->body ); } } void DeleteRootAtoms(Display *dpy2, Window root2) { Atom type; int format; unsigned long length, after; unsigned char *data; Bool e_deleted = False; XA_XSETROOT_ID = XInternAtom(dpy2, "_XSETROOT_ID", False); XA_ESETROOT_PMAP_ID = XInternAtom(dpy2, "ESETROOT_PMAP_ID", False); XA_XROOTPMAP_ID = XInternAtom(dpy2, "_XROOTPMAP_ID", False); if (XGetWindowProperty( dpy2, root2, XA_XSETROOT_ID, 0L, 1L, True, XA_PIXMAP, &type, &format, &length, &after, &data) == Success && type == XA_PIXMAP && format == 32 && length == 1 && after == 0 && (Pixmap)(*(long *)data) != None) { XKillClient(dpy2, *((Pixmap *)data)); } if (XGetWindowProperty( dpy2, root2, XA_ESETROOT_PMAP_ID, 0L, 1L, True, XA_PIXMAP, &type, &format, &length, &after, &data) == Success && type == XA_PIXMAP && format == 32 && length == 1 && after == 0 && (Pixmap)(*(Pixmap *)data) != None) { e_deleted = True; XKillClient(dpy2, *((Pixmap *)data)); } if (e_deleted) { XDeleteProperty(dpy2, root2, XA_XROOTPMAP_ID); } } void SetRootAtoms(Display *dpy2, Window root2, Pixmap RootPix) { long l_root_pix; l_root_pix = RootPix; if (RetainPixmap && RootPix != None) { XChangeProperty( dpy2, root2, XA_ESETROOT_PMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &l_root_pix, 1); XChangeProperty( dpy2, root2, XA_XROOTPMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &l_root_pix, 1); } else { XChangeProperty( dpy2, root2, XA_XSETROOT_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &l_root_pix, 1); } } void SetDeskPageBackground(const Command *c) { Display *dpy2 = NULL; Window root2 = None; int screen2; Pixmap pix = None; current_colorset = -1; /* FvwmBacker bg preperation */ switch (c->type) { case 1: /* solid colors */ case 2: /* colorset */ dpy2 = XOpenDisplay(displayName); if (!dpy2) { fvwm_msg(ERR, "FvwmBacker", "Fail to create a forking dpy, Exit!"); exit(2); } screen2 = DefaultScreen(dpy2); root2 = RootWindow(dpy2, screen2); if (RetainPixmap) { XSetCloseDownMode(dpy2, RetainPermanent); } XGrabServer(dpy2); DeleteRootAtoms(dpy2, root2); switch (c->type) { case 2: current_colorset = c->colorset; /* Process a colorset */ if (CSET_IS_TRANSPARENT(c->colorset)) { fvwm_msg(ERR,"FvwmBacker", "You cannot " "use a transparent colorset as " "background!"); XUngrabServer(dpy2); XCloseDisplay(dpy2); return; } else if (Pdepth != DefaultDepth(dpy2, screen2)) { fvwm_msg(ERR,"FvwmBacker", "You cannot " "use a colorset background if\n" "the fvwm depth is not equal " "to the root depth!"); XUngrabServer(dpy2); XCloseDisplay(dpy2); return; } else if (RetainPixmap) { pix = CreateBackgroundPixmap( dpy2, root2, MyDisplayWidth, MyDisplayHeight, &Colorset[c->colorset], DefaultDepth(dpy2, screen2), DefaultGC(dpy2, screen2), False); if (pix != None) { XSetWindowBackgroundPixmap( dpy2, root2, pix); XClearWindow(dpy2, root2); } } else { SetWindowBackground( dpy2, root2, MyDisplayWidth, MyDisplayHeight, &Colorset[c->colorset], DefaultDepth(dpy2, screen2), DefaultGC(dpy2, screen2), True); } break; case 1: /* Process a solid color request */ if (RetainPixmap) { GC gc; XGCValues xgcv; xgcv.foreground = c->solidColor; gc = fvwmlib_XCreateGC( dpy2, root2, GCForeground, &xgcv); pix = XCreatePixmap( dpy2, root2, 1, 1, DefaultDepth(dpy2, screen2)); XFillRectangle( dpy2, pix, gc, 0, 0, 1, 1); XFreeGC(dpy2, gc); } XSetWindowBackground(dpy2, root2, c->solidColor); XClearWindow(dpy2, root2); break; } SetRootAtoms(dpy2, root2, pix); XUngrabServer(dpy2); XCloseDisplay(dpy2); /* this XSync, Ungrab, ...etc */ break; case -1: case 0: default: if(c->cmdStr != NULL) { SendFvwmPipe(fvwm_fd, c->cmdStr, (unsigned long)0); } break; } } /* * migo (23-Nov-1999): Maybe execute only first (or last?) matching command? * migo (03-Apr-2001): Yes, execute only the last matching command. */ void ExecuteMatchingCommands(int colorset, int changed) { const Command *matching_command = NULL; const Command *command; if (!changed) { return; } for (command = commands->first; command; command = command->next) { if (!(changed & EXEC_ALWAYS) && (command->flags.do_ignore_desk || !(changed & EXEC_CHANGED_DESK)) && (command->flags.do_ignore_page || !(changed & EXEC_CHANGED_PAGE))) { continue; } if ((command->flags.do_match_any_desk || command->desk == current_desk) && (command->x < 0 || command->x == current_x) && (command->y < 0 || command->y == current_y) && (colorset < 0 || (colorset == current_colorset && colorset == command->colorset))) { matching_command = command; } } if (matching_command) { SetDeskPageBackground(matching_command); } } /* ProcessMessage - Process the message coming from fvwm */ void ProcessMessage(unsigned long type, unsigned long *body) { char *tline; int change = 0; static Bool is_initial = True; switch (type) { case M_CONFIG_INFO: tline = (char*)&(body[3]); ExecuteMatchingCommands(ParseConfigLine(tline), EXEC_ALWAYS); break; case M_NEW_DESK: if (is_initial) { change = EXEC_ALWAYS; is_initial = False; } else if (current_desk != body[0]) { current_desk = body[0]; change |= EXEC_CHANGED_DESK; } ExecuteMatchingCommands(-1, change); break; case M_NEW_PAGE: if (is_initial) { change = EXEC_ALWAYS; is_initial = False; } if (current_desk != body[2]) { current_desk = body[2]; change |= EXEC_CHANGED_DESK; } if (current_x != body[0] / MyDisplayWidth || current_y != body[1] / MyDisplayHeight) { current_x = body[0] / MyDisplayWidth; current_y = body[1] / MyDisplayHeight; change |= EXEC_CHANGED_PAGE; } ExecuteMatchingCommands(-1, change); break; } } /* Detected a broken pipe - time to exit */ RETSIGTYPE DeadPipe(int nonsense) { exit(1); SIGNAL_RETURN; } /* ParseConfigLine - Parse the configuration line fvwm to us to use */ int ParseConfigLine(char *line) { int cpl = strlen(configPrefix); if (strlen(line) > 1) { if (strncasecmp(line, configPrefix, cpl) == 0) { if (strncasecmp( line+cpl, "RetainPixmap", 12) == 0) { RetainPixmap = True; } else if (strncasecmp( line+cpl, "DoNotRetainPixmap", 17) == 0) { RetainPixmap = False; } else { AddCommand(line + cpl); } } else if (strncasecmp(line, "colorset", 8) == 0) { return LoadColorset(line + 8); } } return -1; } /* ParseConfig - Parse the configuration file fvwm to us to use */ void ParseConfig(void) { char *line_start; char *tline; line_start = safemalloc(strlen(Module) + 2); strcpy(line_start, "*"); strcat(line_start, Module); InitGetConfigLine(fvwm_fd, line_start); GetConfigLine(fvwm_fd, &tline); while(tline != (char *)0) { ParseConfigLine(tline); GetConfigLine(fvwm_fd, &tline); } free(line_start); } Bool ParseNewCommand( char *parens, Command *this, int *do_ignore_desk, int *do_ignore_page) { char *option; char *parens_run; parens_run = parens; while (*parens_run && (parens_run = GetNextFullOption( parens_run, &option)) != NULL) { char *name, *value; char *option_val; if (!*option) { free(option); break; } option_val = GetNextToken(option, &name); if (StrEquals(name, "Desk")) { if (GetNextToken(option_val, &value) == NULL) { fvwm_msg(ERR, "FvwmBacker", "Desk option requires a value"); return 1; } if (!StrEquals(value, "*")) { this->flags.do_match_any_desk = 0; this->desk = atoi(value); } *do_ignore_desk = False; free(value); } else if (StrEquals(name, "Page")) { if ((option_val = GetNextToken( option_val,&value)) == NULL) { fvwm_msg( ERR, "FvwmBacker", "Page option requires 2 values"); return 1; } if (!StrEquals(value, "*")) this->x = atoi(value); free(value); if (GetNextToken(option_val, &value) == NULL) { fvwm_msg( ERR, "FvwmBacker", "Desk option requires 2 values"); return 1; } if (!StrEquals(value, "*")) this->y = atoi(value); *do_ignore_page = False; free(value); } free(name); free(option); } free(parens); return 0; } /* AddCommand - Add a command to the correct spot on the dynamic array. */ void AddCommand(char *line) { char *token; Command *this; Bool do_ignore_desk = True; Bool do_ignore_page = True; this = (Command*)safemalloc(sizeof(Command)); this->desk = 0; memset(&(this->flags), 0, sizeof(this->flags)); this->flags.do_match_any_desk = 1; this->x = -1; this->y = -1; this->type = -1; this->cmdStr = NULL; this->next = NULL; if (strncasecmp(line, "Desk", 4) == 0) { /* Old command style */ line += 4; line = GetNextToken(line, &token); if (strcasecmp(token, "*") != 0) { this->flags.do_match_any_desk = 0; this->desk = atoi(token); } do_ignore_desk = False; free(token); } else if (strncasecmp(line, "Command", 7) == 0) { /* New command style */ line += 7; while (*line && isspace(*line)) { line++; } if (*line == '(') { int error; char *parens; line++; line = GetQuotedString( line, &parens, ")", NULL, NULL, NULL); if (line == NULL) { fvwm_msg( ERR, "FvwmBacker", "Syntax error: no closing brace"); free(this); return; } error = ParseNewCommand( parens, this, &do_ignore_desk, &do_ignore_page); if (error) { free(this); return; } line++; } } else { fvwm_msg( ERR, "FvwmBacker", CatString2("Unknown directive: ", line)); return; } this->flags.do_ignore_desk = do_ignore_desk; this->flags.do_ignore_page = do_ignore_page; /* Now check the type of command... */ while (*line && isspace(*line)) { line++; } if (strncasecmp(line, "-solid", 6) == 0) { /* Solid color command */ line += 6; line = GetNextToken(line, &token); this->type = 1; /* use the root default color map */ this->solidColor = (!token || !*token) ? BlackPixel(dpy, screen) : BackerGetColor(token); free(token); } else if (strncasecmp(line, "colorset", 8) == 0) { /* Colorset command */ if (sscanf(line + 8, "%d", &this->colorset) < 1) { this->colorset = 0; } AllocColorset(this->colorset); this->type = 2; } else { /* Plain fvwm command */ this->type = 0; this->cmdStr = (char *)safemalloc(strlen(line) + 1); strcpy(this->cmdStr, line); } if (commands->first == NULL) { commands->first = this; } if (commands->last != NULL) { commands->last->next = this; } commands->last = this; } fvwm-2.6.7/modules/FvwmBacker/root_bits.c0000644000175700017570000000241212773467232015327 00000000000000/* -*-c-*- */ /* 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include #include extern Display *dpy; extern int screen; extern char *Module; unsigned long BackerGetColor(char *name) { XColor color; color.pixel = 0; if (!XParseColor (dpy, DefaultColormap(dpy,screen), name, &color)) { fprintf(stderr,"%s: unknown color \"%s\"\n",Module,name); exit(1); } else if(!XAllocColor (dpy, DefaultColormap(dpy,screen), &color)) { fprintf(stderr, "%s: unable to allocate color for \"%s\"\n", Module, name); exit(1); } return color.pixel; } fvwm-2.6.7/modules/FvwmBacker/ConfigFvwmBacker0000644000175700017570000000043112673746443016261 00000000000000DestroyModuleConfig FvwmBacker: * *FvwmBacker: Command (Desk 0) -solid steelblue *FvwmBacker: Command (Desk 1) -solid midnightblue *FvwmBacker: Command (Desk 2) -solid yellow *FvwmBacker: Command (Desk 3, Page 0 *) -solid black *FvwmBacker: Command (Desk 3, Page 1 *) -solid green fvwm-2.6.7/modules/FvwmBacker/FvwmBacker.h0000644000175700017570000000231312773467232015357 00000000000000/* -*-c-*- */ /* FvwmBacker Module for Fvwm. * * Copyright 1994, Mike Finger (mfinger@mermaid.micro.umn.edu or * Mike_Finger@atk.com) * * The author makes not guarantees or warantees, either express or * implied. Feel free to use any contained here for any purpose, as long * and this and any other applicible copyrights are kept intact. * The functions in this source file that are based on part of the FvwmIdent * module for Fvwm are noted by a small copyright atop that function, all * others are copyrighted by Mike Finger. For those functions modified/used, * here is the full, original copyright: * * Copyright 1994, Robert Nation and Nobutaka Suzuki. * No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. */ #include "libs/fvwmlib.h" /* Function Prototypes */ void EndLessLoop(void); void ReadFvwmPipe(void); void ProcessMessage(unsigned long type, unsigned long *body); RETSIGTYPE DeadPipe(int nonsense); void ParseConfig(void); int ParseConfigLine(char *line); void AddCommand(char *line); fvwm-2.6.7/modules/FvwmAuto/0000755000175700017570000000000013010103342012727 500000000000000fvwm-2.6.7/modules/FvwmAuto/Makefile.am0000644000175700017570000000060313001406607014714 00000000000000## Process this file with automake to create Makefile.in moduledir = @FVWM_MODULEDIR@ module_PROGRAMS = FvwmAuto man_MANS = FvwmAuto.1 EXTRA_DIST = $(man_MANS) FvwmAuto_SOURCES = FvwmAuto.c FvwmAuto_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm \ $(X_PRE_LIBS) -lXext -lX11 $(X_EXTRA_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) fvwm-2.6.7/modules/FvwmAuto/Makefile.in0000644000175700017570000006015113010103322014715 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmAuto$(EXEEXT) subdir = modules/FvwmAuto DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmAuto.1.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmAuto.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(module_PROGRAMS) am_FvwmAuto_OBJECTS = FvwmAuto.$(OBJEXT) FvwmAuto_OBJECTS = $(am_FvwmAuto_OBJECTS) FvwmAuto_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmAuto_SOURCES) DIST_SOURCES = $(FvwmAuto_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ man_MANS = FvwmAuto.1 EXTRA_DIST = $(man_MANS) FvwmAuto_SOURCES = FvwmAuto.c FvwmAuto_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs $(X_LIBS) -lfvwm \ $(X_PRE_LIBS) -lXext -lX11 $(X_EXTRA_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(X_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmAuto/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmAuto/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmAuto.1: $(top_builddir)/config.status $(srcdir)/FvwmAuto.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmAuto$(EXEEXT): $(FvwmAuto_OBJECTS) $(FvwmAuto_DEPENDENCIES) $(EXTRA_FvwmAuto_DEPENDENCIES) @rm -f FvwmAuto$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmAuto_OBJECTS) $(FvwmAuto_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmAuto.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-modulePROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-modulePROGRAMS install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am uninstall-man \ uninstall-man1 uninstall-modulePROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmAuto/FvwmAuto.1.in0000644000175700017570000001207712753310630015132 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .ta .3i .6i .9i 1.2i 1.5i 1.8i .TH FvwmAuto 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME \fIFvwmAuto\fP \- the fvwm auto-raise module .SH SYNOPSIS .nf Module FvwmAuto Timeout [-passid] [-menter|-menterleave|-mfocus] [EnterCommand [LeaveCommand]] .fi \fIFvwmAuto\fP can only be invoked by fvwm. Command line invocation of the \fIFvwmAuto\fP will not work. .SH DESCRIPTION The \fIFvwmAuto\fP module is most often used to automatically raise focused windows. .SH INVOCATION The correct syntax is: .nf .EX Module FvwmAuto Timeout [-passid] [-menter|-menterleave|-mfocus] [EnterCommand [LeaveCommand]] .sp AddToMenu Modules + "Auto Raise (300 ms)" Module FvwmAuto 300 + "Auto Raise/Lower" Module FvwmAuto 300 "Silent Raise" "Silent Lower" .EE .fi The \fITimeout\fP argument is required. It specifies how long a window must retain the keyboard input focus before the command is executed. The delay is measured in milliseconds, and any integer greater than zero is valid. If the literal option \fI-passid\fP is given, the window id of the window just entered or left is appended to the command that is sent to fvwm. This can be used with the \fBWindowId\fP command of fvwm. The options \fI-menter\fP, \fI-menterleave\fP and \fI-mfocus\fP influence the actions FvwmAuto reacts to. No more than one of the options can be chosen. In .I -mfocus mode, FvwmAuto raises the window that has the focus. In .I -menter mode, FvwmAuto raises the window under the pointer when the pointer enters a window. The .I LeaveCommand is executed on the window that was below the pointer before it entered the new window. When the pointer leaves a window and enters the root window, the .I EnterCommand is executed too, but without a window to operate on. In .I -menterleave mode, FvwmAuto works just like in .I -menter mode, but the .I LeaveCommand is also executed if the pointer moves out of a window but does not enter a new window. The latter two modes of operation are useful with windows that do not accept the focus. Note: -menterleave mode can interfere with popup windows of some applications. One example is the zoom menu of Ghostview. Please do not complain about this to us - it is a bug in Ghostview. \fIEnterCommand\fP and \fILeaveCommand\fP are optional. \fIEnterCommand\fP is executed \fITimeout\fP milliseconds after a window gets the input focus, \fILeaveCommand\fP is executed \fITimeout\fP milliseconds after the window has lost focus. Note that you always should use the 'Silent' keyword before the command itself. FvwmAuto prepends "Silent " to the command string on its own if yor forget this. Without this prefix fvwm would ask you for a window to act on if the window has died before the command sent by FvwmAuto has been processed by fvwm. This can for example happen with popup menus. "Silent Raise" is the default for \fIEnterCommand\fP, but any fvwm function is allowed. I would not use "Close" or "Destroy" with a low timeout, though. The \fILeaveCommand\fP can be handy for a tidy desktop. Experiment with: .nf .EX Module FvwmAuto 0 Nop "Silent Lower" Module FvwmAuto 0 Nop "Silent Iconify" .EE An example for auto raising windows with ClickToFocus: .nf .EX Style * ClickToFocus FvwmAuto 0 -menter "Silent Raise" .EE An example for auto raising and lowering only some windows: .nf To start FvwmAuto: .EX FvwmAuto 0 -passid -menter \\ "Silent selective_raiselower raise" \\ "Silent selective_raiselower lower" .EE And put this in your .fvwm2rc: .EX AddToFunc selective_raiselower + I WindowId $1 (FvwmIconMan) $0 + I WindowId $1 (FvwmButtons) $0 + I WindowId $1 (xclock) $0 \&... .EE More complex example (three FvwmAuto's are running): .nf .EX DestroyFunc RestoreIconified AddToFunc RestoreIconified + I Current (Iconic) Iconify false DestroyFunc RegisterFocus AddToFunc RegisterFocus + I Exec date +"%T $n focused" >>/tmp/focus-stats.txt DestroyFunc RegisterUnfocus AddToFunc RegisterUnfocus + I Exec date +"%T $n unfocused" >>/tmp/focus-stats.txt KillModule FvwmAuto Module FvwmAuto 250 Raise Nop Module FvwmAuto 800 RestoreIconified Nop Module FvwmAuto 0 RegisterFocus RegisterUnfocus .EE .SH NOTES There is a special Raise/Lower support in FvwmAuto. It was added to improve Raise/Lower callbacks, since most of FvwmAuto usages is auto-raising or auto-lowering. This improvement includes locking on M_RAISE_WINDOW and M_LOWER_WINDOW packets and not raising/lowering explicitly raised windows. The special Raise/Lower support is enabled only when either \fIEnterCommand\fP or \fILeaveCommand\fP contain substring "Raise" or "Lower". You can use this fact to enable/disable any special support by renaming these commands, if FvwmAuto does not automatically do want you expect it to do. Using \fIFvwmAuto\fP in conjunction with \fIEdgeCommand\fP can be even more powerful. There is a short example in the \fIfvwm\fP man page. .SH AUTHOR .nf FvwmAuto just appeared one day, nobody knows how. FvwmAuto was simply rewritten 09/96, nobody knows by whom. fvwm-2.6.7/modules/FvwmAuto/FvwmAuto.10000644000175700017570000001207013010101137014501 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.5i .. .de EE .fi .in -.5i .if n .sp 1 .if t .sp .5 .. .ta .3i .6i .9i 1.2i 1.5i 1.8i .TH FvwmAuto 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME \fIFvwmAuto\fP \- the fvwm auto-raise module .SH SYNOPSIS .nf Module FvwmAuto Timeout [-passid] [-menter|-menterleave|-mfocus] [EnterCommand [LeaveCommand]] .fi \fIFvwmAuto\fP can only be invoked by fvwm. Command line invocation of the \fIFvwmAuto\fP will not work. .SH DESCRIPTION The \fIFvwmAuto\fP module is most often used to automatically raise focused windows. .SH INVOCATION The correct syntax is: .nf .EX Module FvwmAuto Timeout [-passid] [-menter|-menterleave|-mfocus] [EnterCommand [LeaveCommand]] .sp AddToMenu Modules + "Auto Raise (300 ms)" Module FvwmAuto 300 + "Auto Raise/Lower" Module FvwmAuto 300 "Silent Raise" "Silent Lower" .EE .fi The \fITimeout\fP argument is required. It specifies how long a window must retain the keyboard input focus before the command is executed. The delay is measured in milliseconds, and any integer greater than zero is valid. If the literal option \fI-passid\fP is given, the window id of the window just entered or left is appended to the command that is sent to fvwm. This can be used with the \fBWindowId\fP command of fvwm. The options \fI-menter\fP, \fI-menterleave\fP and \fI-mfocus\fP influence the actions FvwmAuto reacts to. No more than one of the options can be chosen. In .I -mfocus mode, FvwmAuto raises the window that has the focus. In .I -menter mode, FvwmAuto raises the window under the pointer when the pointer enters a window. The .I LeaveCommand is executed on the window that was below the pointer before it entered the new window. When the pointer leaves a window and enters the root window, the .I EnterCommand is executed too, but without a window to operate on. In .I -menterleave mode, FvwmAuto works just like in .I -menter mode, but the .I LeaveCommand is also executed if the pointer moves out of a window but does not enter a new window. The latter two modes of operation are useful with windows that do not accept the focus. Note: -menterleave mode can interfere with popup windows of some applications. One example is the zoom menu of Ghostview. Please do not complain about this to us - it is a bug in Ghostview. \fIEnterCommand\fP and \fILeaveCommand\fP are optional. \fIEnterCommand\fP is executed \fITimeout\fP milliseconds after a window gets the input focus, \fILeaveCommand\fP is executed \fITimeout\fP milliseconds after the window has lost focus. Note that you always should use the 'Silent' keyword before the command itself. FvwmAuto prepends "Silent " to the command string on its own if yor forget this. Without this prefix fvwm would ask you for a window to act on if the window has died before the command sent by FvwmAuto has been processed by fvwm. This can for example happen with popup menus. "Silent Raise" is the default for \fIEnterCommand\fP, but any fvwm function is allowed. I would not use "Close" or "Destroy" with a low timeout, though. The \fILeaveCommand\fP can be handy for a tidy desktop. Experiment with: .nf .EX Module FvwmAuto 0 Nop "Silent Lower" Module FvwmAuto 0 Nop "Silent Iconify" .EE An example for auto raising windows with ClickToFocus: .nf .EX Style * ClickToFocus FvwmAuto 0 -menter "Silent Raise" .EE An example for auto raising and lowering only some windows: .nf To start FvwmAuto: .EX FvwmAuto 0 -passid -menter \\ "Silent selective_raiselower raise" \\ "Silent selective_raiselower lower" .EE And put this in your .fvwm2rc: .EX AddToFunc selective_raiselower + I WindowId $1 (FvwmIconMan) $0 + I WindowId $1 (FvwmButtons) $0 + I WindowId $1 (xclock) $0 \&... .EE More complex example (three FvwmAuto's are running): .nf .EX DestroyFunc RestoreIconified AddToFunc RestoreIconified + I Current (Iconic) Iconify false DestroyFunc RegisterFocus AddToFunc RegisterFocus + I Exec date +"%T $n focused" >>/tmp/focus-stats.txt DestroyFunc RegisterUnfocus AddToFunc RegisterUnfocus + I Exec date +"%T $n unfocused" >>/tmp/focus-stats.txt KillModule FvwmAuto Module FvwmAuto 250 Raise Nop Module FvwmAuto 800 RestoreIconified Nop Module FvwmAuto 0 RegisterFocus RegisterUnfocus .EE .SH NOTES There is a special Raise/Lower support in FvwmAuto. It was added to improve Raise/Lower callbacks, since most of FvwmAuto usages is auto-raising or auto-lowering. This improvement includes locking on M_RAISE_WINDOW and M_LOWER_WINDOW packets and not raising/lowering explicitly raised windows. The special Raise/Lower support is enabled only when either \fIEnterCommand\fP or \fILeaveCommand\fP contain substring "Raise" or "Lower". You can use this fact to enable/disable any special support by renaming these commands, if FvwmAuto does not automatically do want you expect it to do. Using \fIFvwmAuto\fP in conjunction with \fIEdgeCommand\fP can be even more powerful. There is a short example in the \fIfvwm\fP man page. .SH AUTHOR .nf FvwmAuto just appeared one day, nobody knows how. FvwmAuto was simply rewritten 09/96, nobody knows by whom. fvwm-2.6.7/modules/FvwmAuto/FvwmAuto.c0000644000175700017570000003006713001406607014603 00000000000000/* -*-c-*- */ /* This module, and the entire FvwmAuto program, and the concept for * interfacing this module to the Window Manager, are all original work * by Robert Nation * * Copyright 1994, Robert Nation. No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. * * reworked by A.Kadlec (albrecht@auto.tuwien.ac.at) 09/96 * to support an arbitrary enter_fn & leave_fn (command line arguments) * completely reworked, while I was there. * * Modified by John Aughey (jha@cs.purdue.edu) 11/96 * to not perform any action when entering the root window * * Minor patch by C. Hines 12/96. * */ /* 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" #if HAVE_SYS_BSDTYPES_H #include /* Saul */ #endif #include #include #include #include #include "libs/ftime.h" #include #include #include "libs/Module.h" #include "libs/fvwmlib.h" #include "libs/fvwmsignal.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/wild.h" /* here is the old double parens trick. */ /* #define DEBUG */ #ifdef DEBUGTOFILE #define DEBUG #endif #ifdef DEBUG #define myfprintf(X) \ fprintf X;\ fflush (stderr); #else #define myfprintf(X) #endif static RETSIGTYPE TerminateHandler(int signo); /* * * Procedure: * Termination procedure : *not* a signal handler * */ RETSIGTYPE DeadPipe(int nonsense) { (void)nonsense; myfprintf((stderr,"Leaving via DeadPipe\n")); exit(0); SIGNAL_RETURN; } /* * * Procedure: * Signal handler that tells the module to quit * */ static RETSIGTYPE TerminateHandler(int signo) { fvwmSetTerminate(signo); SIGNAL_RETURN; } /* * * Procedure: * main - start of module * */ int main(int argc, char **argv) { /* The struct holding the module info */ static ModuleArgs* module; char *enter_fn="Silent Raise"; /* default */ char *leave_fn=NULL; char *buf; int len; unsigned long m_mask; unsigned long mx_mask; unsigned long last_win = 0; /* last window handled */ unsigned long focus_win = 0; /* current focus */ unsigned long raised_win = 0; fd_set_size_t fd_width; int fd[2]; int timeout; int sec = 0; int usec = 0; int n; struct timeval value; struct timeval *delay; fd_set in_fdset; Bool do_pass_id = False; Bool use_enter_mode = False; Bool use_leave_mode = False; #ifdef DEBUG int count = 0; #endif #ifdef DEBUGTOFILE freopen(".FvwmAutoDebug","w",stderr); #endif module = ParseModuleArgs(argc,argv,0); /* no alias in this module */ if (module==NULL) { fprintf(stderr,"FvwmAuto Version "VERSION" should only be executed by fvwm!\n"); exit(1); } if (module->user_argc < 1 || module->user_argc > 5) { fprintf(stderr,"FvwmAuto can use one to five arguments.\n"); exit(1); } /* Dead pipes mean fvwm died */ #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGPIPE); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGTERM); #ifdef SA_RESTART sigact.sa_flags = SA_RESTART; # else sigact.sa_flags = 0; #endif sigact.sa_handler = TerminateHandler; sigaction(SIGPIPE, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); } #else /* We don't have sigaction(), so fall back to less robust methods. */ #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGPIPE) | sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) ); #endif signal(SIGPIPE, TerminateHandler); signal(SIGINT, TerminateHandler); signal(SIGHUP, TerminateHandler); signal(SIGQUIT, TerminateHandler); signal(SIGTERM, TerminateHandler); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGPIPE, 0); siginterrupt(SIGINT, 0); siginterrupt(SIGHUP, 0); siginterrupt(SIGQUIT, 0); siginterrupt(SIGTERM, 0); #endif #endif fd[0] = module->to_fvwm; fd[1] = module->from_fvwm; if ((timeout = atoi(module->user_argv[0]) )) { sec = timeout / 1000; usec = (timeout % 1000) * 1000; } else { sec = 0; usec = 1000; } delay = &value; n = 1; if (n < module->user_argc && module->user_argv[n]) { char *token; /* -passid option */ if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-passid")) { do_pass_id = True; n++; } if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menterleave")) { /* enterleave mode */ use_leave_mode = True; use_enter_mode = True; n++; } else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menter")) { /* enter mode */ use_leave_mode = False; use_enter_mode = True; n++; } else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-mfocus")) { /* focus mode */ use_leave_mode = False; use_enter_mode = False; n++; } /*** enter command ***/ if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "Nop")) { /* nop */ enter_fn = NULL; n++; } else if (n < module->user_argc) { /* override default */ enter_fn = module->user_argv[n]; n++; } /* This is a hack to prevent user interaction with old configs. */ if (enter_fn) { token = PeekToken(enter_fn, NULL); if (!StrEquals(token, "Silent")) { enter_fn = safestrdup( CatString2("Silent ", enter_fn)); } } /*** leave command ***/ if (n < module->user_argc && module->user_argv[n] && *module->user_argv[n] && StrEquals(module->user_argv[n], "Nop")) { /* nop */ leave_fn = NULL; n++; } else if (n < module->user_argc) { /* leave function specified */ leave_fn=module->user_argv[n]; n++; } if (leave_fn) { token = PeekToken(leave_fn, NULL); if (!StrEquals(token, "Silent")) { leave_fn = safestrdup( CatString2("Silent ", leave_fn)); } } } /* Exit if nothing to do. */ if (!enter_fn && !leave_fn) { return -1; } if (use_enter_mode) { m_mask = 0; mx_mask = MX_ENTER_WINDOW | MX_LEAVE_WINDOW | M_EXTENDED_MSG; } else { mx_mask = M_EXTENDED_MSG; m_mask = M_FOCUS_CHANGE; } /* Disable special raise/lower support on general actions. * * This works as expected in most of cases. */ if (matchWildcards("*Raise*", CatString2(enter_fn, leave_fn)) || matchWildcards("*Lower*", CatString2(enter_fn, leave_fn))) { m_mask |= M_RAISE_WINDOW | M_LOWER_WINDOW; } /* migo (04/May/2000): It is simply incorrect to listen to raise/lower * packets and change the state if the action itself has no raise/lower. * Detecting whether to listen or not by the action name is good enough. m_mask = M_FOCUS_CHANGE | M_RAISE_WINDOW | M_LOWER_WINDOW; */ SetMessageMask(fd, m_mask); SetMessageMask(fd, mx_mask); /* tell fvwm we're running */ SendFinishedStartupNotification(fd); /* tell fvwm that we want to be lock on send */ SetSyncMask(fd, m_mask); SetSyncMask(fd, mx_mask); fd_width = fd[1] + 1; FD_ZERO(&in_fdset); /* create the command buffer */ len = 0; if (enter_fn != 0) { len = strlen(enter_fn); } if (leave_fn != NULL) { len = max(len, strlen(leave_fn)); } if (do_pass_id) { len += 32; } buf = safemalloc(len); while (!isTerminated) { char raise_window_now; static char have_new_window = 0; FD_SET(fd[1], &in_fdset); myfprintf( (stderr, "\nstart %d (hnw = %d, usec = %d)\n", count++, have_new_window, usec)); /* fill in struct - modified by select() */ delay->tv_sec = sec; delay->tv_usec = usec; #ifdef DEBUG { char tmp[32]; sprintf(tmp, "%d usecs", (delay) ? (int)delay->tv_usec : -1); myfprintf((stderr, "select: delay = %s\n", (have_new_window) ? tmp : "infinite" )); } #endif if (fvwmSelect(fd_width, &in_fdset, NULL, NULL, (have_new_window) ? delay : NULL) == -1) { myfprintf( (stderr, "select: error! (%s)\n", strerror(errno))); break; } raise_window_now = 0; if (FD_ISSET(fd[1], &in_fdset)) { FvwmPacket *packet = ReadFvwmPacket(fd[1]); if (packet == NULL) { myfprintf( (stderr, "Leaving because of null packet\n")); break; } myfprintf( (stderr, "pw = 0x%x, fw=0x%x, rw = 0x%x, lw=0x%x\n", (int)packet->body[0], (int)focus_win, (int)raised_win, (int)last_win)); switch (packet->type) { case MX_ENTER_WINDOW: focus_win = packet->body[0]; if (focus_win != raised_win) { myfprintf((stderr, "entered new window\n")); have_new_window = 1; raise_window_now = 0; } else if (focus_win == last_win) { have_new_window = 0; } else { myfprintf((stderr, "entered other window\n")); } break; case MX_LEAVE_WINDOW: if (use_leave_mode) { if (focus_win == raised_win) { focus_win = 0; } myfprintf((stderr, "left raised window\n")); have_new_window = 1; raise_window_now = 0; } break; case M_FOCUS_CHANGE: /* it's a focus package */ focus_win = packet->body[0]; if (focus_win != raised_win) { myfprintf((stderr, "focus on new window\n")); have_new_window = 1; raise_window_now = 0; } else { myfprintf((stderr, "focus on old window\n")); } break; case M_RAISE_WINDOW: myfprintf( (stderr, "raise packet 0x%x\n", (int)packet->body[0])); raised_win = packet->body[0]; if (have_new_window && focus_win == raised_win) { myfprintf( (stderr, "its the old window:" " don't raise\n")); have_new_window = 0; } break; case M_LOWER_WINDOW: myfprintf( (stderr, "lower packet 0x%x\n", (int)packet->body[0])); if (have_new_window && focus_win == packet->body[0]) { myfprintf( (stderr, "window was explicitly" " lowered, don't raise it" " again\n")); have_new_window = 0; } break; } /* switch */ SendUnlockNotification(fd); } else { if (have_new_window) { myfprintf((stderr, "must raise now\n")); raise_window_now = 1; } } if (raise_window_now) { myfprintf((stderr, "raising 0x%x\n", (int)focus_win)); if (leave_fn && ((last_win && !use_leave_mode) || (raised_win && use_enter_mode))) { /* if focus_win isn't the root */ if (do_pass_id) { sprintf(buf, "%s 0x%x\n", leave_fn, (int)last_win); } else { sprintf(buf, "%s\n", leave_fn); } SendInfo(fd, buf, last_win); if (use_enter_mode) { raised_win = 0; } } if (focus_win && enter_fn) { /* if focus_win isn't the root */ if (do_pass_id) { sprintf(buf, "%s 0x%x\n", enter_fn, (int)focus_win); } else { sprintf(buf, "%s\n", enter_fn); } SendInfo(fd, buf, focus_win); raised_win = focus_win; } else if (focus_win && enter_fn == NULL) { raised_win = focus_win; } /* force fvwm to synchronise on slow X connections to * avoid a race condition. Still possible, but much * less likely. */ SendInfo(fd, "XSync", focus_win); /* switch to wait mode again */ last_win = focus_win; have_new_window = 0; } } /* while */ return 0; } fvwm-2.6.7/modules/FvwmPager/0000755000175700017570000000000013010103344013057 500000000000000fvwm-2.6.7/modules/FvwmPager/ConfigFvwmPager0000644000175700017570000000140412673746443016000 00000000000000########################### Pager ######################################### DestroyModuleConfig FvwmPager: * *FvwmPager: Back #908090 *FvwmPager: Fore #484048 #*FvwmPager: Font -adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-* # turn off desktop names for swallowing in above button bar example: *FvwmPager: Font none *FvwmPager: Hilight #cab3ca *FvwmPager: Geometry -1-1 *FvwmPager: Label 0 Misc *FvwmPager: Label 1 Maker *FvwmPager: Label 2 Mail *FvwmPager: Label 3 Matlab *FvwmPager: SmallFont 5x8 *FvwmPager: Balloons All *FvwmPager: BalloonBack Yellow *FvwmPager: BalloonFore Black *FvwmPager: BalloonFont lucidasanstypewriter-12 *FvwmPager: BalloonYOffset +2 *FvwmPager: BalloonBorderWidth 1 *FvwmPager: BalloonBorderColor Black fvwm-2.6.7/modules/FvwmPager/Makefile.am0000644000175700017570000000161313001406607015044 00000000000000## Process this file with automake to create Makefile.in moduledir = @FVWM_MODULEDIR@ configdir = @FVWM_DATADIR@ module_PROGRAMS = FvwmPager man_MANS = FvwmPager.1 EXTRA_DIST = $(man_MANS) ConfigFvwmPager config_DATA = \ ConfigFvwmPager FvwmPager_SOURCES = FvwmPager.c FvwmPager.h x_pager.c FvwmPager_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a ## Xpm note: while this module may not depend on Xpm explicitly, ## there are sometimes dependencies through functions in libfvwm ## so we might as well link against libXpm, if present. LDADD = -L$(top_builddir)/libs -lfvwm $(Xft_LIBS) $(X_LIBS) $(xpm_LIBS) \ $(png_LIBS) $(rsvg_LIBS) $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 \ $(X_EXTRA_LIBS) -lm $(Xrender_LIBS) $(Xcursor_LIBS) $(iconv_LIBS) \ $(Bidi_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(png_CFLAGS) $(Xft_CFLAGS) \ $(X_CFLAGS) $(Xrender_CFLAGS) $(iconv_CFLAGS) $(Bidi_CFLAGS) fvwm-2.6.7/modules/FvwmPager/Makefile.in0000644000175700017570000006273113010103323015052 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ module_PROGRAMS = FvwmPager$(EXEEXT) subdir = modules/FvwmPager DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmPager.1.in $(top_srcdir)/etc/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmPager.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(configdir)" PROGRAMS = $(module_PROGRAMS) am_FvwmPager_OBJECTS = FvwmPager.$(OBJEXT) x_pager.$(OBJEXT) FvwmPager_OBJECTS = $(am_FvwmPager_OBJECTS) FvwmPager_LDADD = $(LDADD) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmPager_SOURCES) DIST_SOURCES = $(FvwmPager_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(config_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ moduledir = @FVWM_MODULEDIR@ configdir = @FVWM_DATADIR@ man_MANS = FvwmPager.1 EXTRA_DIST = $(man_MANS) ConfigFvwmPager config_DATA = \ ConfigFvwmPager FvwmPager_SOURCES = FvwmPager.c FvwmPager.h x_pager.c FvwmPager_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a LDADD = -L$(top_builddir)/libs -lfvwm $(Xft_LIBS) $(X_LIBS) $(xpm_LIBS) \ $(png_LIBS) $(rsvg_LIBS) $(X_PRE_LIBS) $(Xinerama_LIBS) -lXext -lX11 \ $(X_EXTRA_LIBS) -lm $(Xrender_LIBS) $(Xcursor_LIBS) $(iconv_LIBS) \ $(Bidi_LIBS) AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(png_CFLAGS) $(Xft_CFLAGS) \ $(X_CFLAGS) $(Xrender_CFLAGS) $(iconv_CFLAGS) $(Bidi_CFLAGS) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmPager/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmPager/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmPager.1: $(top_builddir)/config.status $(srcdir)/FvwmPager.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmPager$(EXEEXT): $(FvwmPager_OBJECTS) $(FvwmPager_DEPENDENCIES) $(EXTRA_FvwmPager_DEPENDENCIES) @rm -f FvwmPager$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmPager_OBJECTS) $(FvwmPager_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmPager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x_pager.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-configDATA: $(config_DATA) @$(NORMAL_INSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ done uninstall-configDATA: @$(NORMAL_UNINSTALL) @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(configdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulePROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-configDATA install-man install-modulePROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-configDATA uninstall-man \ uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-configDATA install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-modulePROGRAMS install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-configDATA uninstall-man uninstall-man1 \ uninstall-modulePROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmPager/FvwmPager.1.in0000644000175700017570000003707012673746443015426 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH FvwmPager 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmPager \- the Fvwm Pager module .SH SYNOPSIS \fBFvwmPager\fP [ \fI-transient\fP ] [ \fIname\fP ] [ \fIfirst desk\fP [ \fIlast desk\fP ] ] FvwmPager is spawned by fvwm, so no command line invocation will work. All desks with desk numbers between \fIfirst desk\fP and \fIlast desk\fP are displayed. If \fIlast desk\fP is omitted only the \fIfirst desk\fP is shown. If both desk numbers are omitted, the current desk is used instead. If you use an asterisk '*' in place of \fIfirst desk\fP the pager will always show the current desktop, even when you switch desks. Example lines to put in your .fvwm2rc: .nf .sp Module FvwmPager 0 3 .sp .fi or .nf .sp Module FvwmPager * .sp .fi or from within an fvwm pop-up menu: .nf .sp AddToMenu Module-Popup Modules Title + Audio Module FvwmAudio + Auto Module FvwmAuto 200 + Buttons Module FvwmButtons + Console Module FvwmConsole + Ident Module FvwmIdent + Banner Module FvwmBanner + Pager Module FvwmPager 0 3 .sp .fi or .nf .sp + Pager Module FvwmPager * .sp .fi If the pager is started with the \fI-transient\fP option, the next time a button is released the pager is closed. Note that this option does only work if the window style of the pager window is 'sticky' (see the fvwm man page). You should use the 'StaysOnTop' style too. Example: .nf .sp Style FvwmPager Sticky, StaysOnTop *FvwmPager: Rows 1 *FvwmPager: Columns 1 Mouse 3 R C Module FvwmPager -transient .sp .fi With this in your .fvwm2rc, if you press control and button 3 in the root window the pager pops up under the mouse and while the viewport moves with the mouse. .SH DESCRIPTION The FvwmPager module shows a miniature view of the Fvwm desktops which are specified in the command line. This is a useful reminder of where your active windows are. Windows in the pager are shown in the same color as their fvwm decorations. The pager can be used to change your viewport into the current desktop, to change desktops, or to move windows around. Pressing mouse button 1 in the pager will cause you viewport to change to the selected page of the selected desk. If you click with button 1 in the desk-label area, you will switch desks but not pages within the desk. Dragging mouse button 2 on a miniature view of a window will cause that window to be move to the location where you release the mouse button, but your viewport will not change. If you drag the window out of the pager and onto your desktop, a full size image of the window will appear for you to place. There is no way to pick up a full size image of the window and move it into the pager, however. Since some mice do not have button 2, I have made provisions to drag windows in the pager by using pressing modifier-1 (usually Alt) and dragging with button 3. Clicking mouse button 3 on a location will cause the viewport to move to the selected location and switch desks if necessary, but will not align the viewport to a page boundary. Dragging button 3 will cause the viewport to move as you drag but not switch desktops, even if the pointer moves to another desktop. With the \fI*FvwmPager: SloppyFocus\fP option the focus is transferred to the window pointed at with the mouse when the pointer is inside the pager. When iconified, the pager will work as a fully functional current desk only pager. Windows and viewports can be moved within the icon of the pager. Users will want to make sure that they have no lines similar to .nf .sp Icon "Fvwm Pager" whatever .sp .fi in their .fvwm2rc files. .SH COPYRIGHTS The FvwmPager program, and the concept for interfacing this module to the Window Manager, are all original work by Robert Nation. Copyright 1994, Robert Nation. No guarantees or warranties or anything are provided or implied in any way whatsoever. Use this program at your own risk. Permission to use this program for any purpose is given, as long as the copyright is kept intact. .SH INITIALIZATION During initialization, \fIFvwmPager\fP gets config info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ). To use FvwmPager with several different configurations, you can invoke FvwmPager with an optional parameter, which it will use as its \fIname\fP instead (e.g "Module FvwmPager OtherPager"). OtherPager will then read only the lines in the configuration file starting with "*OtherPager", and not the lines belonging to FvwmPager. This way multiple pager instances may be used. Note: the old way to use the FvwmPager with several different configurations is to link the executable to another name, i.e. .nf .sp ln -s FvwmPager OtherPager .sp .fi This may work, but this method is not supported. .SH KEYBOARD FOCUS CONTROL You can direct the keyboard focus to any window on the current desktop by clicking with button 2 on its image in the pager. The window does not need to be visible, but it does need to be on the current page. .SH INVOCATION The invocation method was shown in the synopsis section .SH CONFIGURATION OPTIONS .IP "*FvwmPager: Geometry \fIgeometry\fP" Completely or partially specifies the pager windows location and geometry, in standard X11 notation. In order to maintain an undistorted aspect ratio, you might want to leave out either the width or height dimension of the geometry specification. .IP "*FvwmPager: Rows \fIrows\fP" Tells fvwm how many rows of desks to use when laying out the pager window. .IP "*FvwmPager: Columns \fIcolumns\fP" Tells fvwm how many columns of desks to use when laying out the pager window. .IP "*FvwmPager: IconGeometry \fIgeometry\fP" Specifies a size (optional) and location (optional) for the pager's icon window. Since there is no easy way for FvwmPager to determine the height of the icon's label, you will have to make an allowance for the icon label height when using negative y-coordinates in the icon location specification (used to specify a location relative to the bottom instead of the top of the screen). .IP "*FvwmPager: StartIconic" Causes the pager to start iconified. .IP "*FvwmPager: NoStartIconic" Causes the pager to start normally. Useful for canceling the effect of the \fIStartIconic\fP option. .IP "*FvwmPager: LabelsBelow" Causes the pager to draw desk labels below the corresponding desk. .IP "*FvwmPager: LabelsAbove" Causes the pager to draw desk labels above the corresponding desk. Useful for canceling the effect of the \fILabelsBelow\fP option. .IP "*FvwmPager: ShapeLabels" Causes the pager to hide the labels of all but the current desk. This turns off label hilighting. .IP "*FvwmPager: NoShapeLabels" Causes the pager to show the labels of all visible desks. Useful for canceling the effect of the \fIShapeLabels\fP option. .IP "*FvwmPager: Font \fIfont-name\fP" Specified a font to use to label the desktops. If \fIfont_name\fP is "none" then no desktop labels will be displayed. .IP "*FvwmPager: SmallFont \fIfont-name\fP" Specified a font to use to label the window names in the pager. If not specified, the window labels will be omitted. Window labels seem to be fairly useless for desktop scales of 32 or greater. If \fIfont_name\fP is "none" then no window names will be displayed. .IP "*FvwmPager: Fore \fIcolor\fP" Specifies the color to use to write the desktop labels, and to draw the page-grid lines. .IP "*FvwmPager: Back \fIcolor\fP" Specifies the background color for the window. .IP "*FvwmPager: Hilight \fIcolor\fP" The active page and desk label will be highlighted by using this background pattern instead of the normal background. .IP "*FvwmPager: HilightPixmap \fIpixmap\fP" The active page will be highlighted by using this background pattern instead of the normal background. .IP "*FvwmPager: DeskHilight" Hilight the active page with the current hilight color/pixmap. Useful for canceling the effect of the \fINoDeskHilight\fP option. .IP "*FvwmPager: NoDeskHilight" Don't hilight the active page. .IP "*FvwmPager: WindowColors \fIfore back hiFore hiBack\fP" Change the normal/highlight colors of the windows. \fIfore\fP and \fIhiFore\fP specify the colors as used for the font inside the windows. \fIback\fP and \fIhiBack\fP are used to fill the windows with. .IP "*FvwmPager: WindowLabelFormat \fIformat\fP" This specifies a printf() like format for the labels in the mini window. Possible flags are: %t, %i, %c, and %r for the window's title, icon title, class, or resource name, respectively. The default is "%i". .IP "*FvwmPager: Label \fIdesk label\fP" Assigns the text \fIlabel\fP to desk \fIdesk\fP (or the current desk if desk is "*") in the pager window. Useful for assigning symbolic names to desktops, i.e. .nf .sp *FvwmPager: Label 1 Mail *FvwmPager: Label 2 Maker *FvwmPager: Label * Matlab .sp .fi .BR Note : There is currently a much better way to specify desk names globally (and not just in FvwmPager) using .B DesktopName command, so you should not use this option anymore. .IP "*FvwmPager: DeskColor \fIdesk color\fP" Assigns the color \fIcolor\fP to desk \fIdesk\fP (or the current desk if desk is "*") in the pager window. This replaces the background color for the particular \fIdesk\fP. This only works when the pager is full sized. When Iconified, the pager uses the color specified by *FvwmPager: Back. .sp \fBTIP:\fP Try using *FvwmPager: DeskColor in conjunction with FvwmCpp (or FvwmM4) and FvwmBacker to assign identical colors to your various desktops and the pager representations. .IP "*FvwmPager: Pixmap \fIpixmap\fP" Use \fIpixmap\fP as background for the pager. .IP "*FvwmPager: DeskPixmap \fIdesk pixmap\fP" Assigns the pixmap \fIcolor\fP to desk \fIdesk\fP (or the current desk if desk is "*") in the pager window. This replaces the background pixmap for the particular \fIdesk\fP. .sp \fBTIP:\fP Try using *FvwmPager: DeskPixmap in conjunction with FvwmCpp (or FvwmM4) and FvwmBacker to assign identical pixmaps to your various desktops and the pager representations. .IP "*FvwmPager: DeskTopScale \fInumber\fP" If the geometry is not specified, then a desktop reduction factor is used to calculate the pager's size. Things in the pager window are shown at 1/\fInumber\fP of the actual size. .IP "*FvwmPager: MiniIcons" Allow the pager to display a window's mini icon in the pager, if it has one, instead of showing the window's name. .IP "*FvwmPager: MoveThreshold \fIpixels\fP" Defines the distance the pointer has to be moved before a window being dragged with button 2 is actually moved. The default value is three pixels. If the pointer moved less that this amount the window snaps back to its original position when the button is released. If \fIpixels\fP is less than zero the default value is used. The value set with the \fIMoveThreshold\fP command in fvwm is inherited by FvwmPager but can be overridden with this option. .IP "*FvwmPager: SloppyFocus" If the SloppyFocus option is used, you do not need to click into the mini window in the pager to give the real window the focus. Simply putting the pointer over the window inside the pager is enough. Note: This option interferes slightly with the MouseFocus and SloppyFocus styles of fvwm. Sometimes, if you click into the pager window to change pages or desks and then move the pointer to a place on the screen where a window of the new page will appear, this new window does not get the input focus. This may happen if you drag the pointer over one of the mini windows in the pager. There is nothing that can be done about this - except not using SloppyFocus in the pager. .IP "*FvwmPager: SolidSeparators" By default the pages of the virtual desktop are separated by dashed lines in the pager window. This option causes FvwmPager to use solid lines instead. .IP "*FvwmPager: NoSeparators" Turns off the lines separating the pages of the virtual desktop. .IP "*FvwmPager: Balloons [\fItype\fP]" Show a balloon describing the window when the pointer is moved into a window in the pager. The default format (the window's icon name) can be changed using BalloonStringFormat. If \fItype\fP is \fIPager\fP balloons are just shown for an un-iconified pager; if \fItype\fP is \fIIcon\fP balloons are just shown for an iconified pager. If \fItype\fP is anything else (or null) balloons are always shown. .IP "*FvwmPager: BalloonFore \fIcolor\fP" Specifies the color for text in the balloon window. If omitted it defaults to the foreground color for the window being described. .IP "*FvwmPager: BalloonBack \fIcolor\fP" Specifies the background color for the balloon window. If omitted it defaults to the background color for the window being described. .IP "*FvwmPager: BalloonFont \fIfont-name\fP" Specifies a font to use for the balloon text. Defaults to \fIfixed\fP. .IP "*FvwmPager: BalloonBorderWidth \fInumber\fP" Sets the width of the balloon window's border. Defaults to 1. .IP "*FvwmPager: BalloonBorderColor \fIcolor\fP" Sets the color of the balloon window's border. Defaults to black. .IP "*FvwmPager: BalloonYOffset \fInumber\fP" The balloon window is positioned to be horizontally centered against the pager window it is describing. The vertical position may be set as an offset. Negative offsets of \fI-n\fP are placed \fIn\fP pixels above the pager window, positive offsets of \fI+n\fP are placed \fIn\fP pixels below. Offsets of -1 and 1 represent the balloon window close to the original window without a gap. Offsets of 0 are not permitted, as this would permit direct transit from pager window to balloon window, causing an event loop. Defaults to +3. The offset will change sign automatically, as needed, to keep the balloon on the screen. .IP "*FvwmPager: BalloonStringFormat \fTformat\fP" The same as \fI*FvwmPager: WindowLabelFormat\fP, it just specifies the string to display in the balloons. The default is "%i". .IP "*FvwmPager: Colorset \fIdesk colorset\fP" Tells the module to use colorset \fIcolorset\fP for \fIdesk\fP. If you use an asterisk '*' in place of \fIdesk\fP, the colorset is used on all desks. Please refer to the man page of the FvwmTheme module for details about colorsets. .IP "*FvwmPager: BalloonColorset \fIdesk colorset\fP" Tells the module to use colorset \fIcolorset\fP for balloons on \fIdesk\fP. If you use an asterisk '*' in place of \fIdesk\fP, the colorset is used on all desks. Please refer to the man page of the FvwmTheme module for details about colorsets. .IP "*FvwmPager: HilightColorset \fIdesk colorset\fP" Tells the module to use colorset \fIcolorset\fP for hilighting on \fIdesk\fP. If you use an asterisk '*' in place of \fIdesk\fP, the colorset is used on all desks. Please refer to the man page of the FvwmTheme module for details about colorsets. .IP "*FvwmPager: WindowColorsets \fIcolorset activecolorset\fP" Uses colorsets in the same way as *FvwmPager: WindowColors. Please refer to the man page of the FvwmTheme module for details about colorsets. The shadow and hilight colors of the colorset are only used for the window borders if the *FvwmPager: Window3DBorders is specified too. .IP "*FvwmPager: WindowBorderWidth \fIn\fP" Specifies the width of the border drawn around the mini windows. This also sets the minimum size of the mini windows to (2 * \fIn\fP + 1). The default is 1. .IP "*FvwmPager: Window3DBorders" Specifies that the mini windows should have a 3d borders based on the mini window background. This option only works if *FvwmPager: WindowColorsets is specified. .IP "*FvwmPager: UseSkipList" Tells FvwmPager to not show the windows that are using the WindowListSkip style. .SH AUTHOR Robert Nation .br DeskColor patch contributed by Alan Wild .br MiniIcons & WindowColors patch contributed by Rob Whapham .br Balloons patch by Ric Lister .br fvwm-workers: Dominik, Olivier, Hippo and others. fvwm-2.6.7/modules/FvwmPager/x_pager.c0000644000175700017570000024431613001406607014612 00000000000000/* -*-c-*- */ /* * This module is all new * by Rob Nation */ /* 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 */ /* * * fvwm pager handling code * */ #include "config.h" #include #include #include #include #include #include #include #include #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/FShape.h" #include "libs/Module.h" #include "libs/Colorset.h" #include "libs/Graphics.h" #include "fvwm/fvwm.h" #include "libs/PictureGraphics.h" #include "FvwmPager.h" extern ScreenInfo Scr; extern Display *dpy; Pixel back_pix, fore_pix, hi_pix; Pixel focus_pix; Pixel focus_fore_pix; extern int windowcolorset, activecolorset; extern Pixel win_back_pix, win_fore_pix, win_hi_back_pix, win_hi_fore_pix; extern Bool win_pix_set, win_hi_pix_set; extern int window_w, window_h,window_x,window_y,usposition,uselabel,xneg,yneg; extern int StartIconic; extern int MiniIcons; extern int LabelsBelow; extern int ShapeLabels; extern int ShowBalloons, ShowPagerBalloons, ShowIconBalloons; extern char *BalloonFormatString; extern char *WindowLabelFormat; extern char *PagerFore, *PagerBack, *HilightC; extern char *BalloonFore, *BalloonBack, *BalloonBorderColor; extern Window BalloonView; extern unsigned int WindowBorderWidth; extern unsigned int MinSize; extern Bool WindowBorders3d; extern Bool UseSkipList; extern FvwmPicture *PixmapBack; extern FvwmPicture *HilightPixmap; extern int HilightDesks; extern char fAlwaysCurrentDesk; extern int MoveThreshold; extern int icon_w, icon_h, icon_x, icon_y, icon_xneg, icon_yneg; FlocaleFont *Ffont, *FwindowFont; FlocaleWinString *FwinString; extern PagerWindow *Start; extern PagerWindow *FocusWin; static Atom wm_del_win; extern char *MyName; extern int desk1, desk2, ndesks; extern int Rows,Columns; extern int fd[2]; int desk_w = 0; int desk_h = 0; int label_h = 0; DeskInfo *Desks; int Wait = 0; int FvwmErrorHandler(Display *, XErrorEvent *); extern Bool is_transient; extern Bool do_ignore_next_button_release; extern Bool use_dashed_separators; extern Bool use_no_separators; /* assorted gray bitmaps for decorative borders */ #define g_width 2 #define g_height 2 static char g_bits[] = {0x02, 0x01}; #define l_g_width 4 #define l_g_height 2 static char l_g_bits[] = {0x08, 0x02}; #define s_g_width 4 #define s_g_height 4 static char s_g_bits[] = {0x01, 0x02, 0x04, 0x08}; #define label_border g_width Window icon_win; /* icon window */ static int MyVx, MyVy; /* copy of Scr.Vx/y for drag logic */ static char *GetBalloonLabel(const PagerWindow *pw,const char *fmt); extern void ExitPager(void); Pixmap default_pixmap = None; #ifdef DEBUG #define MYFPRINTF(X) \ fprintf X;\ fflush (stderr); #else #define MYFPRINTF(X) #endif #define MAX_UNPROCESSED_MESSAGES 1 /* sums up pixels to scroll. If do_send_message is True a Scroll command is * sent back to fvwm. The function shall be called with is_message_recieved * True when the Scroll command has been processed by fvwm. This is checked * by talking to ourself. */ static void do_scroll(int sx, int sy, Bool do_send_message, Bool is_message_recieved) { static int psx = 0; static int psy = 0; static int messages_sent = 0; char command[256]; psx+=sx; psy+=sy; if (is_message_recieved) { /* There might be other modules with the same name, or someone might send ScrollDone other than the module, so just treat any negative count as zero. */ if (--messages_sent < 0) { messages_sent = 0; } } if ((do_send_message || messages_sent < MAX_UNPROCESSED_MESSAGES) && ( psx != 0 || psy != 0 )) { sprintf(command, "Scroll %dp %dp", psx, psy); SendText(fd, command, 0); messages_sent++; SendText(fd, "Send_Reply ScrollDone", 0); psx = 0; psy = 0; } } void HandleScrollDone(void) { do_scroll(0, 0, True, True); } typedef struct { int event_type; XEvent *ret_last_event; } _weed_window_events_args; static int _pred_weed_window_events( Display *display, XEvent *current_event, XPointer arg) { _weed_window_events_args *args = (_weed_window_events_args *)arg; if (current_event->type == args->event_type) { if (args->ret_last_event != NULL) { *args->ret_last_event = *current_event; } return 1; } return 0; } /* discard certain events on a window */ static void discard_events(long event_type, Window w, XEvent *last_ev) { _weed_window_events_args args; XSync(dpy, 0); args.event_type = event_type; args.ret_last_event = last_ev; FWeedIfWindowEvents(dpy, w, _pred_weed_window_events, (XPointer)&args); return; } /* * * Procedure: * CalcGeom - calculates the size and position of a mini-window * given the real window size. * You can always tell bad code by the size of the comments. */ static void CalcGeom(PagerWindow *t, int win_w, int win_h, int *x_ret, int *y_ret, int *w_ret, int *h_ret) { int virt, virt2, edge, edge2, size, page, over; /* coordinate of left hand edge on virtual desktop */ virt = Scr.Vx + t->x; /* position of left hand edge of mini-window on pager window */ edge = (virt * win_w) / Scr.VWidth; /* absolute coordinate of right hand edge on virtual desktop */ virt += t->width - 1; /* to calculate the right edge, mirror the window and use the same * calculations as for the left edge for consistency. */ virt2 = Scr.VWidth - 1 - virt; edge2 = (virt2 * win_w) / Scr.VWidth; /* then mirror it back to get the real coordinate */ edge2 = win_w - 1 - edge2; /* Calculate the mini-window's width by subtracting its LHS * from its RHS. This theoretically means that the width will * vary slightly as the window travels around the screen, but * this way ensures that the mini-windows in the pager match * the actual screen layout. */ size = edge2 - edge + 1; /* Make size big enough to be visible */ if (size < MinSize) { size = MinSize; /* this mini-window has to be grown to be visible * which way it grows depends on some magic: * normally it will grow right but if the window is on the right hand * edge of a page it should be grown left so that the pager looks better */ /* work out the page that the right hand edge is on */ page = virt / Scr.MyDisplayWidth; /* if the left edge is on the same page then possibly move it left */ if (page == ((virt - t->width + 1) / Scr.MyDisplayWidth)) { /* calculate how far the mini-window right edge overlaps the page line */ /* beware that the "over" is actually one greater than on screen, but this discrepancy is catered for in the next two lines */ over = edge + size - ((page + 1) * win_w * Scr.MyDisplayWidth) / Scr.VWidth; /* if the mini-window right edge is beyond the mini-window pager grid */ if (over > 0) { /* move it left by the amount of pager grid overlap (!== the growth) */ edge -= over; } } } /* fill in return values */ *x_ret = edge; *w_ret = size; /* same code for y axis */ virt = Scr.Vy + t->y; edge = (virt * win_h) / Scr.VHeight; virt += t->height - 1; virt2 = Scr.VHeight - 1 - virt; edge2 = (virt2 * win_h) / Scr.VHeight; edge2 = win_h - 1 - edge2; size = edge2 - edge + 1; if (size < MinSize) { size = MinSize; page = virt / Scr.MyDisplayHeight; if (page == ((virt - t->height + 1) / Scr.MyDisplayHeight)) { over = edge + size - ((page + 1) * win_h * Scr.MyDisplayHeight) / Scr.VHeight; if (over > 0) edge -= over; } } *y_ret = edge; *h_ret = size; } /* * * Procedure: * Initialize_viz_pager - creates a temp window of the correct visual * so that pixmaps may be created for use with the main window */ void initialize_viz_pager(void) { XSetWindowAttributes attr; XGCValues xgcv; /* FIXME: I think that we only need that Pdepth == * DefaultDepth(dpy, Scr.screen) to use the Scr.Root for Scr.Pager_w */ if (Pdefault) { Scr.Pager_w = Scr.Root; } else { attr.background_pixmap = None; attr.border_pixel = 0; attr.colormap = Pcmap; Scr.Pager_w = XCreateWindow( dpy, Scr.Root, -10, -10, 10, 10, 0, Pdepth, InputOutput, Pvisual, CWBackPixmap|CWBorderPixel|CWColormap, &attr); Scr.NormalGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, 0, &xgcv); } Scr.NormalGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, 0, NULL); xgcv.plane_mask = AllPlanes; Scr.MiniIconGC = fvwmlib_XCreateGC( dpy, Scr.Pager_w, GCPlaneMask, &xgcv); Scr.black = GetColor("Black"); /* Transparent background are only allowed when the depth matched the * root */ if (Pdepth == DefaultDepth(dpy, Scr.screen)) { default_pixmap = ParentRelative; } return; } /* see also change colorset */ void draw_desk_background(int i, int page_w, int page_h) { if (Desks[i].colorset > -1) { XSetWindowBorder( dpy, Desks[i].title_w, Colorset[Desks[i].colorset].fg); XSetWindowBorder( dpy, Desks[i].w, Colorset[Desks[i].colorset].fg); XSetForeground( dpy, Desks[i].NormalGC,Colorset[Desks[i].colorset].fg); XSetForeground( dpy, Desks[i].DashedGC,Colorset[Desks[i].colorset].fg); if (uselabel) { if (CSET_IS_TRANSPARENT(Desks[i].colorset)) { SetWindowBackground( dpy, Desks[i].title_w, desk_w, label_h, &Colorset[Desks[i].colorset], Pdepth, Scr.NormalGC, True); } else { SetWindowBackground( dpy, Desks[i].title_w, desk_w, desk_h + label_h, &Colorset[Desks[i].colorset], Pdepth, Scr.NormalGC, True); } } if (label_h != 0 && uselabel && !LabelsBelow && !CSET_IS_TRANSPARENT(Desks[i].colorset)) { SetWindowBackgroundWithOffset( dpy, Desks[i].w, 0, -label_h, desk_w, desk_h + label_h, &Colorset[Desks[i].colorset], Pdepth, Scr.NormalGC, True); } else { if (CSET_IS_TRANSPARENT(Desks[i].colorset)) { SetWindowBackground( dpy, Desks[i].w, desk_w, desk_h, &Colorset[Desks[i].colorset], Pdepth, Scr.NormalGC, True); } else { SetWindowBackground( dpy, Desks[i].w, desk_w, desk_h + label_h, &Colorset[Desks[i].colorset], Pdepth, Scr.NormalGC, True); } } } XClearArea(dpy,Desks[i].w, 0, 0, 0, 0,True); if (Desks[i].highcolorset > -1) { XSetForeground( dpy, Desks[i].HiliteGC, Colorset[Desks[i].highcolorset].bg); XSetForeground( dpy, Desks[i].rvGC, Colorset[Desks[i].highcolorset].fg); if (HilightDesks) { SetWindowBackground( dpy, Desks[i].CPagerWin, page_w, page_h, &Colorset[Desks[i].highcolorset], Pdepth, Scr.NormalGC, True); } } if (uselabel) { XClearArea(dpy,Desks[i].title_w, 0, 0, 0, 0,True); } return; } /* * * Procedure: * Initialize_pager - creates the pager window, if needed * * Inputs: * x,y location of the window * */ char *pager_name = "Fvwm Pager"; XSizeHints sizehints = { (PMinSize | PResizeInc | PBaseSize | PWinGravity), 0, 0, 100, 100, /* x, y, width and height */ 1, 1, /* Min width and height */ 0, 0, /* Max width and height */ 1, 1, /* Width and height increments */ {0, 0}, {0, 0}, /* Aspect ratio - not used */ 1, 1, /* base size */ (NorthWestGravity) /* gravity */ }; void initialize_balloon_window(void) { XGCValues xgcv; unsigned long valuemask; XSetWindowAttributes attributes; extern int BalloonBorderWidth; /* create balloon window -- ric@giccs.georgetown.edu */ if (!ShowBalloons) { Scr.balloon_w = None; return; } valuemask = CWOverrideRedirect | CWEventMask | CWColormap; /* tell WM to ignore this window */ attributes.override_redirect = True; attributes.event_mask = ExposureMask; attributes.colormap = Pcmap; /* now create the window */ Scr.balloon_w = XCreateWindow( dpy, Scr.Root, 0, 0, /* coords set later */ 1, 1, BalloonBorderWidth, Pdepth, InputOutput, Pvisual, valuemask, &attributes); Scr.balloon_gc = fvwmlib_XCreateGC(dpy, Scr.balloon_w, 0, &xgcv); /* Make sure we don't get balloons initially with the Icon option. */ ShowBalloons = ShowPagerBalloons; return; } void initialize_pager(void) { XWMHints wmhints; XClassHint class1; XTextProperty name; unsigned long valuemask; XSetWindowAttributes attributes; extern char *WindowBack, *WindowFore, *WindowHiBack, *WindowHiFore; extern char *BalloonFont; extern char *font_string, *smallFont; int n,m,w,h,i,x,y; XGCValues gcv; char dash_list[2]; FlocaleFont *balloon_font; /* I don't think that this is necessary - just let pager die */ /* domivogt (07-mar-1999): But it is! A window being moved in the pager * might die at any moment causing the Xlib calls to generate BadMatch * errors. Without an error handler the pager will die! */ XSetErrorHandler(FvwmErrorHandler); wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); /* load the font */ /* Note: "font" is always created, whether labels are used or not because a GC below is set to use a font. dje Dec 2001. OK, I fixed the GC below, but now something else is blowing up. Right now, I've got to do some Real Life stuff, so this kludge is in place, its still better than I found it. I hope that I've fixed this (olicha) */ Ffont = FlocaleLoadFont(dpy, font_string, MyName); label_h = (uselabel) ? Ffont->height + 2 : 0; /* init our Flocale window string */ FlocaleAllocateWinString(&FwinString); /* Check that shape extension exists. */ if (FHaveShapeExtension && ShapeLabels) { ShapeLabels = (FShapesSupported) ? 1 : 0; } if(smallFont != NULL) { FwindowFont = FlocaleLoadFont(dpy, smallFont, MyName); } /* Load the colors */ fore_pix = GetColor(PagerFore); back_pix = GetColor(PagerBack); hi_pix = GetColor(HilightC); if (windowcolorset >= 0) { win_back_pix = Colorset[windowcolorset].bg; win_fore_pix = Colorset[windowcolorset].fg; win_pix_set = True; } else if (WindowBack && WindowFore) { win_back_pix = GetColor(WindowBack); win_fore_pix = GetColor(WindowFore); win_pix_set = True; } if (activecolorset >= 0) { win_hi_back_pix = Colorset[activecolorset].bg; win_hi_fore_pix = Colorset[activecolorset].fg; win_hi_pix_set = True; } else if (WindowHiBack && WindowHiFore) { win_hi_back_pix = GetColor(WindowHiBack); win_hi_fore_pix = GetColor(WindowHiFore); win_hi_pix_set = True; } /* Load pixmaps for mono use */ if(Pdepth<2) { Scr.gray_pixmap = XCreatePixmapFromBitmapData(dpy,Scr.Pager_w,g_bits, g_width,g_height, fore_pix,back_pix,Pdepth); Scr.light_gray_pixmap = XCreatePixmapFromBitmapData(dpy,Scr.Pager_w,l_g_bits,l_g_width, l_g_height, fore_pix,back_pix,Pdepth); Scr.sticky_gray_pixmap = XCreatePixmapFromBitmapData(dpy,Scr.Pager_w,s_g_bits,s_g_width, s_g_height, fore_pix,back_pix,Pdepth); } n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; /* Size the window */ if(Rows < 0) { if(Columns < 0) { Columns = ndesks; Rows = 1; } else { Rows = ndesks/Columns; if(Rows*Columns < ndesks) Rows++; } } if(Columns < 0) { if (Rows == 0) Rows = 1; Columns = ndesks/Rows; if(Rows*Columns < ndesks) Columns++; } if(Rows*Columns < ndesks) { if (Columns == 0) Columns = 1; Rows = ndesks/Columns; if (Rows*Columns < ndesks) Rows++; } sizehints.width_inc = Columns*(n+1); sizehints.height_inc = Rows*(m+1); sizehints.base_width = Columns * n + Columns - 1; sizehints.base_height = Rows * (m + label_h + 1) - 1; if (window_w > 0) { window_w = (window_w - sizehints.base_width) / sizehints.width_inc; window_w = window_w * sizehints.width_inc + sizehints.base_width; } else { window_w = Columns * (Scr.VWidth / Scr.VScale + n) + Columns - 1; } if (window_h > 0) { window_h = (window_h - sizehints.base_height) / sizehints.height_inc; window_h = window_h * sizehints.height_inc + sizehints.base_height; } else { window_h = Rows * (Scr.VHeight / Scr.VScale + m + label_h + 1) - 1; } desk_w = (window_w - Columns + 1) / Columns; desk_h = (window_h - Rows * label_h - Rows + 1) / Rows; if (is_transient) { rectangle screen_g; fscreen_scr_arg fscr; fscr.xypos.x = window_x; fscr.xypos.y = window_y; FScreenGetScrRect( &fscr, FSCREEN_XYPOS, &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); if (window_w + window_x > screen_g.x + screen_g.width) { window_x = screen_g.x + screen_g.width - Scr.MyDisplayWidth; xneg = 1; } if (window_h + window_y > screen_g.y + screen_g.height) { window_y = screen_g.y + screen_g.height - Scr.MyDisplayHeight; yneg = 1; } } if (xneg) { sizehints.win_gravity = NorthEastGravity; window_x = Scr.MyDisplayWidth - window_w + window_x; } if (yneg) { window_y = Scr.MyDisplayHeight - window_h + window_y; if(sizehints.win_gravity == NorthEastGravity) sizehints.win_gravity = SouthEastGravity; else sizehints.win_gravity = SouthWestGravity; } sizehints.width = window_w; sizehints.height = window_h; if(usposition) sizehints.flags |= USPosition; valuemask = (CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask); attributes.background_pixmap = default_pixmap; attributes.border_pixel = 0; attributes.colormap = Pcmap; attributes.event_mask = (StructureNotifyMask); /* destroy the temp window first, don't worry if it's the Root */ if (Scr.Pager_w != Scr.Root) XDestroyWindow(dpy, Scr.Pager_w); Scr.Pager_w = XCreateWindow (dpy, Scr.Root, window_x, window_y, window_w, window_h, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); XSetWMProtocols(dpy,Scr.Pager_w,&wm_del_win,1); /* hack to prevent mapping on wrong screen with StartsOnScreen */ FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &sizehints); XSetWMNormalHints(dpy,Scr.Pager_w,&sizehints); if (is_transient) { XSetTransientForHint(dpy, Scr.Pager_w, Scr.Root); } if((desk1==desk2)&&(Desks[0].label != NULL)) { if (FlocaleTextListToTextProperty( dpy, &Desks[0].label, 1, XStdICCTextStyle, &name) == 0) { fprintf(stderr,"%s: fatal error: cannot allocate desk name", MyName); exit(0); } } else { if (FlocaleTextListToTextProperty( dpy, &Desks[0].label, 1, XStdICCTextStyle, &name) == 0) { fprintf(stderr,"%s: fatal error: cannot allocate pager name", MyName); exit(0); } } attributes.event_mask = (StructureNotifyMask| ExposureMask); if(icon_w < 1) icon_w = (window_w - Columns+1)/Columns; if(icon_h < 1) icon_h = (window_h - Rows* label_h - Rows + 1)/Rows; icon_w = (icon_w / (n+1)) *(n+1)+n; icon_h = (icon_h / (m+1)) *(m+1)+m; icon_win = XCreateWindow (dpy, Scr.Root, window_x, window_y, icon_w, icon_h, 0, Pdepth, InputOutput, Pvisual, valuemask, &attributes); XGrabButton(dpy, 1, AnyModifier, icon_win, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(dpy, 2, AnyModifier, icon_win, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(dpy, 3, AnyModifier, icon_win, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); if(!StartIconic) wmhints.initial_state = NormalState; else wmhints.initial_state = IconicState; wmhints.flags = 0; if (icon_x != -10000) { if (icon_xneg) icon_x = Scr.MyDisplayWidth + icon_x - icon_w; if (icon_y != -10000) { if (icon_yneg) icon_y = Scr.MyDisplayHeight + icon_y - icon_h; } else { icon_y = 0; } icon_xneg = 0; icon_yneg = 0; wmhints.icon_x = icon_x; wmhints.icon_y = icon_y; wmhints.flags = IconPositionHint; } wmhints.icon_window = icon_win; wmhints.input = False; wmhints.flags |= InputHint | StateHint | IconWindowHint; class1.res_name = MyName; class1.res_class = "FvwmPager"; XSetWMProperties(dpy,Scr.Pager_w,&name,&name,NULL,0, &sizehints,&wmhints,&class1); XFree((char *)name.value); /* change colour/font for labelling mini-windows */ XSetForeground(dpy, Scr.NormalGC, focus_fore_pix); if (FwindowFont != NULL && FwindowFont->font != NULL) XSetFont(dpy, Scr.NormalGC, FwindowFont->font->fid); /* create the 3d bevel GC's if necessary */ if (windowcolorset >= 0) { gcv.foreground = Colorset[windowcolorset].hilite; Scr.whGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); gcv.foreground = Colorset[windowcolorset].shadow; Scr.wsGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); } if (activecolorset >= 0) { gcv.foreground = Colorset[activecolorset].hilite; Scr.ahGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); gcv.foreground = Colorset[activecolorset].shadow; Scr.asGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); } balloon_font = FlocaleLoadFont(dpy, BalloonFont, MyName); for(i=0;ifont) { gcv.font = Ffont->font->fid; Desks[i].NormalGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground | GCFont, &gcv); } else { Desks[i].NormalGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); } /* create the active desk hilite GC */ if(Pdepth < 2) gcv.foreground = fore_pix; else gcv.foreground = (Desks[i].highcolorset < 0) ? hi_pix : Colorset[Desks[i].highcolorset].bg; Desks[i].HiliteGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); /* create the hilight desk title drawing GC */ if ((Pdepth < 2) || (fore_pix == hi_pix)) gcv.foreground = (Desks[i].highcolorset < 0) ? back_pix : Colorset[Desks[i].highcolorset].fg; else gcv.foreground = (Desks[i].highcolorset < 0) ? fore_pix : Colorset[Desks[i].highcolorset].fg; if (uselabel && Ffont && Ffont->font) { Desks[i].rvGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground | GCFont, &gcv); } else { Desks[i].rvGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground, &gcv); } /* create the virtual page boundary GC */ gcv.foreground = (Desks[i].colorset < 0) ? fore_pix : Colorset[Desks[i].colorset].fg; gcv.line_width = 1; gcv.line_style = (use_dashed_separators) ? LineOnOffDash : LineSolid; Desks[i].DashedGC = fvwmlib_XCreateGC( dpy, Scr.Pager_w, GCForeground | GCLineStyle | GCLineWidth, &gcv); if (use_dashed_separators) { /* Although this should already be the default for a freshly created GC, * some X servers do not draw properly dashed lines if the dash style is * not set explicitly. */ dash_list[0] = 4; dash_list[1] = 4; XSetDashes(dpy, Desks[i].DashedGC, 0, dash_list, 2); } valuemask = (CWBorderPixel | CWColormap | CWEventMask); if (Desks[i].colorset >= 0 && Colorset[Desks[i].colorset].pixmap) { valuemask |= CWBackPixmap; attributes.background_pixmap = Colorset[Desks[i].colorset].pixmap; } else { valuemask |= CWBackPixel; attributes.background_pixel = (Desks[i].colorset < 0) ? (Desks[i].Dcolor ? GetColor(Desks[i].Dcolor) : back_pix) : Colorset[Desks[i].colorset].bg; } attributes.border_pixel = (Desks[i].colorset < 0) ? fore_pix : Colorset[Desks[i].colorset].fg; attributes.event_mask = (ExposureMask | ButtonReleaseMask); Desks[i].title_w = XCreateWindow( dpy, Scr.Pager_w, x - 1, y - 1, w, h, 1, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); attributes.event_mask = (ExposureMask | ButtonReleaseMask | ButtonPressMask |ButtonMotionMask); /* or just: desk_h = h - label_h; */ desk_h = (window_h - Rows * label_h - Rows + 1) / Rows; valuemask &= ~(CWBackPixel); if (Desks[i].colorset > -1 && Colorset[Desks[i].colorset].pixmap) { valuemask |= CWBackPixmap; attributes.background_pixmap = None; /* set later */ } else if (Desks[i].bgPixmap) { valuemask |= CWBackPixmap; attributes.background_pixmap = Desks[i].bgPixmap->picture; } else if (Desks[i].Dcolor) { valuemask |= CWBackPixel; attributes.background_pixel = GetColor(Desks[i].Dcolor); } else if (PixmapBack) { valuemask |= CWBackPixmap; attributes.background_pixmap = PixmapBack->picture; } else { valuemask |= CWBackPixel; attributes.background_pixel = (Desks[i].colorset < 0) ? back_pix : Colorset[Desks[i].colorset].bg; } Desks[i].w = XCreateWindow( dpy, Desks[i].title_w, x - 1, LabelsBelow ? -1 : label_h - 1, w, desk_h, 1, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); if (HilightDesks) { valuemask &= ~(CWBackPixel | CWBackPixmap); attributes.event_mask = 0; if (Desks[i].highcolorset > -1 && Colorset[Desks[i].highcolorset].pixmap) { valuemask |= CWBackPixmap; attributes.background_pixmap = None; /* set later */ } else if (HilightPixmap) { valuemask |= CWBackPixmap; attributes.background_pixmap = HilightPixmap->picture; } else { valuemask |= CWBackPixel; attributes.background_pixel = (Desks[i].highcolorset < 0) ? hi_pix : Colorset[Desks[i].highcolorset].bg; } w = w / (n + 1); h = desk_h / (m + 1); Desks[i].CPagerWin=XCreateWindow(dpy, Desks[i].w, -32768, -32768, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); draw_desk_background(i, w, h); XMapRaised(dpy,Desks[i].CPagerWin); } else { draw_desk_background(i, 0, 0); } XMapRaised(dpy,Desks[i].w); XMapRaised(dpy,Desks[i].title_w); /* get font for balloon */ Desks[i].balloon.Ffont = balloon_font; if (Desks[i].balloon.Ffont == NULL) { fprintf(stderr, "%s: No fonts available, giving up!.\n", MyName); } Desks[i].balloon.height = Desks[i].balloon.Ffont->height + 1; } initialize_balloon_window(); XMapRaised(dpy,Scr.Pager_w); } void UpdateWindowShape(void) { if (FHaveShapeExtension) { int i, j, cnt, shape_count, x_pos, y_pos; XRectangle *shape; if (!ShapeLabels || !uselabel || label_h<=0) return; shape_count = ndesks + ((Scr.CurrentDesk < desk1 || Scr.CurrentDesk >desk2) ? 0 : 1); shape = (XRectangle *)alloca (shape_count * sizeof (XRectangle)); if (shape == NULL) return; cnt = 0; y_pos = (LabelsBelow ? 0 : label_h); for (i = 0; i < Rows; ++i) { x_pos = 0; for (j = 0; j < Columns; ++j) { if (cnt < ndesks) { shape[cnt].x = x_pos; shape[cnt].y = y_pos; shape[cnt].width = desk_w + 1; shape[cnt].height = desk_h + 2; if (cnt == Scr.CurrentDesk - desk1) { shape[ndesks].x = x_pos; shape[ndesks].y = (LabelsBelow ? y_pos + desk_h + 2 : y_pos - label_h); shape[ndesks].width = desk_w; shape[ndesks].height = label_h + 2; } } ++cnt; x_pos += desk_w + 1; } y_pos += desk_h + 2 + label_h; } FShapeCombineRectangles( dpy, Scr.Pager_w, FShapeBounding, 0, 0, shape, shape_count, FShapeSet, 0); } } /* * * Decide what to do about received X events * */ void DispatchEvent(XEvent *Event) { int i,x,y; Window JunkRoot, JunkChild; Window w; int JunkX, JunkY; unsigned JunkMask; char keychar; KeySym keysym; Bool do_move_page = False; short dx = 0; short dy = 0; switch(Event->xany.type) { case EnterNotify: HandleEnterNotify(Event); break; case LeaveNotify: if ( ShowBalloons ) UnmapBalloonWindow(); break; case ConfigureNotify: fev_sanitise_configure_notify(&Event->xconfigure); w = Event->xconfigure.window; discard_events(ConfigureNotify, Event->xconfigure.window, Event); fev_sanitise_configure_notify(&Event->xconfigure); if (w != icon_win) { /* icon_win is not handled here */ discard_events(Expose, w, NULL); ReConfigure(); } break; case Expose: HandleExpose(Event); break; case KeyPress: if (is_transient) { XLookupString(&(Event->xkey), &keychar, 1, &keysym, NULL); switch(keysym) { case XK_Up: dy = -100; do_move_page = True; break; case XK_Down: dy = 100; do_move_page = True; break; case XK_Left: dx = -100; do_move_page = True; break; case XK_Right: dx = 100; do_move_page = True; break; default: /* does not return */ ExitPager(); break; } if (do_move_page) { char command[64]; sprintf(command,"Scroll %d %d", dx, dy); SendText(fd, command, 0); } } break; case ButtonRelease: if (do_ignore_next_button_release) { do_ignore_next_button_release = False; break; } if (Event->xbutton.button == 3) { for(i=0;ixany.window == Desks[i].w) { if (FQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ } Scroll(desk_w, desk_h, x, y, i, False); } } if(Event->xany.window == icon_win) { if (FQueryPointer(dpy, icon_win, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ } Scroll(icon_w, icon_h, x, y, 0, True); } /* Flush any pending scroll operations */ do_scroll(0, 0, True, False); } else if((Event->xbutton.button == 1)|| (Event->xbutton.button == 2)) { for(i=0;ixany.window == Desks[i].w) SwitchToDeskAndPage(i,Event); else if(Event->xany.window == Desks[i].title_w) SwitchToDesk(i); } if(Event->xany.window == icon_win) { IconSwitchPage(Event); } } if (is_transient) { /* does not return */ ExitPager(); } break; case ButtonPress: do_ignore_next_button_release = False; if ( ShowBalloons ) UnmapBalloonWindow(); if (((Event->xbutton.button == 2)|| ((Event->xbutton.button == 3)&& (Event->xbutton.state & Mod1Mask)))&& (Event->xbutton.subwindow != None)) { MoveWindow(Event); } else if (Event->xbutton.button == 3) { /* save initial virtual desk position for drag */ MyVx=Scr.Vx; MyVy=Scr.Vy; for(i=0;ixany.window == Desks[i].w) { if (FQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ } Scroll(desk_w, desk_h, x, y, Scr.CurrentDesk, False); if (Scr.CurrentDesk != i + desk1) { Wait = 0; SwitchToDesk(i); } break; } } if(Event->xany.window == icon_win) { if (FQueryPointer(dpy, icon_win, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ } Scroll(icon_w, icon_h, x, y, 0, True); } } break; case MotionNotify: do_ignore_next_button_release = False; while(FCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask,Event)) ; if(Event->xmotion.state & Button3MotionMask) { for(i=0;ixany.window == Desks[i].w) { if (FQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ } Scroll(desk_w, desk_h, x, y, i, False); } } if(Event->xany.window == icon_win) { if (FQueryPointer(dpy, icon_win, &JunkRoot, &JunkChild, &JunkX, &JunkY,&x, &y, &JunkMask) == False) { /* pointer is on a different screen - that's okay here */ } Scroll(icon_w, icon_h, x, y, 0, True); } } break; case ClientMessage: if ((Event->xclient.format==32) && (Event->xclient.data.l[0]==wm_del_win)) { /* does not return */ ExitPager(); } break; } } void HandleEnterNotify(XEvent *Event) { PagerWindow *t; Bool is_icon_view = False; extern Bool do_focus_on_enter; if (!ShowBalloons && !do_focus_on_enter) /* nothing to do */ return; /* is this the best way to match X event window ID to PagerWindow ID? */ for ( t = Start; t != NULL; t = t->next ) { if ( t->PagerView == Event->xcrossing.window ) { break; } if ( t->IconView == Event->xcrossing.window ) { is_icon_view = True; break; } } if (t == NULL) { return; } if (ShowBalloons) { MapBalloonWindow(t, is_icon_view); } if (do_focus_on_enter) { SendText(fd, "Silent FlipFocus NoWarp", t->w); } } XRectangle get_expose_bound(XEvent *Event) { XRectangle r; int ex, ey, ex2, ey2; ex = Event->xexpose.x; ey = Event->xexpose.y; ex2 = Event->xexpose.x + Event->xexpose.width; ey2 = Event->xexpose.y + Event->xexpose.height; while (FCheckTypedWindowEvent(dpy, Event->xany.window, Expose, Event)) { ex = min(ex, Event->xexpose.x); ey = min(ey, Event->xexpose.y); ex2 = max(ex2, Event->xexpose.x + Event->xexpose.width); ey2= max(ey2 , Event->xexpose.y + Event->xexpose.height); } r.x = ex; r.y = ey; r.width = ex2-ex; r.height = ey2-ey; return r; } void HandleExpose(XEvent *Event) { int i; PagerWindow *t; XRectangle r; /* it will be good to have full "clipping redraw". Do that for * desk label only for now */ for(i=0;ixany.window == Desks[i].w || Event->xany.window == Desks[i].title_w) { r = get_expose_bound(Event); DrawGrid(i, 0, Event->xany.window, &r); return; } } if (Event->xany.window == Scr.balloon_w) { DrawInBalloonWindow(Scr.balloon_desk); return; } if(Event->xany.window == icon_win) DrawIconGrid(0); for (t = Start; t != NULL; t = t->next) { if (t->PagerView == Event->xany.window) { LabelWindow(t); PictureWindow(t); BorderWindow(t); } else if(t->IconView == Event->xany.window) { LabelIconWindow(t); PictureIconWindow(t); BorderIconWindow(t); } } discard_events(Expose, Event->xany.window, NULL); } /* * * Respond to a change in window geometry. * */ void ReConfigure(void) { Window root; unsigned border_width, depth; int n,m,w,h,n1,m1,x,y,i,j,k; int old_ww; int old_wh; int is_size_changed; old_ww = window_w; old_wh = window_h; if (!XGetGeometry(dpy, Scr.Pager_w, &root, &x, &y, (unsigned *)&window_w, (unsigned *)&window_h, &border_width,&depth)) { return; } is_size_changed = (old_ww != window_w || old_wh != window_h); n1 = Scr.Vx / Scr.MyDisplayWidth; m1 = Scr.Vy / Scr.MyDisplayHeight; n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; sizehints.width_inc = Columns * (n + 1); sizehints.height_inc = Rows * (m + 1); sizehints.base_width = Columns * n + Columns - 1; sizehints.base_height = Rows*(m + label_h+1) - 1; sizehints.min_width = sizehints.base_width; sizehints.min_height = sizehints.base_height; if (window_w > 0) { window_w = (window_w - sizehints.base_width) / sizehints.width_inc; window_w = window_w * sizehints.width_inc + sizehints.base_width; } if (window_h > 0) { window_h = (window_h - sizehints.base_height) / sizehints.height_inc; window_h = window_h * sizehints.height_inc + sizehints.base_height; } desk_w = (window_w - Columns + 1) / Columns; desk_h = (window_h - Rows * label_h - Rows + 1) / Rows; w = (desk_w - n)/(n+1); h = (desk_h - m)/(m+1); XSetWMNormalHints(dpy,Scr.Pager_w,&sizehints); x = (desk_w - n) * Scr.Vx / Scr.VWidth + n1; y = (desk_h - m) * Scr.Vy / Scr.VHeight + m1; for(k=0;k pager window (pr) -> title window -> desk window -> window view * | |-> hilight desk * |-> icon_window -> icon view * |-> ballon window */ /* update the hilight desk and the windows: desk color change */ static void update_pr_transparent_subwindows(int i) { int cset; int n,m,w,h; PagerWindow *t; n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; w = (desk_w - n)/(n+1); h = (desk_h - m)/(m+1); if (CSET_IS_TRANSPARENT_PR(Desks[i].highcolorset) && HilightDesks) { SetWindowBackground( dpy, Desks[i].CPagerWin, w, h, &Colorset[Desks[i].highcolorset], Pdepth, Scr.NormalGC, True); } t = Start; for(t = Start; t != NULL; t = t->next) { cset = (t != FocusWin) ? windowcolorset : activecolorset; if (t->desk != i && !CSET_IS_TRANSPARENT_PR(cset)) { continue; } if (t->PagerView != None) { SetWindowBackground( dpy, t->PagerView, t->pager_view_width, t->pager_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } if (t->IconView) { SetWindowBackground( dpy, t->IconView, t->icon_view_width, t->icon_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } } /* update all the parental relative windows: pr background change */ void update_pr_transparent_windows(void) { int i,j,k,cset; int n,m,w,h; PagerWindow *t; n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; w = (desk_w - n)/(n+1); h = (desk_h - m)/(m+1); for(k=0;knext) { cset = (t != FocusWin) ? windowcolorset : activecolorset; if (!CSET_IS_TRANSPARENT_PR(cset) || (fAlwaysCurrentDesk && !CSET_IS_TRANSPARENT_PR(Desks[0].colorset)) || (!fAlwaysCurrentDesk && !CSET_IS_TRANSPARENT_PR(Desks[t->desk].colorset))) { continue; } if (t->PagerView != None) { SetWindowBackground( dpy, t->PagerView, t->pager_view_width, t->pager_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } if (t->desk && t->IconView) { SetWindowBackground( dpy, t->IconView, t->icon_view_width, t->icon_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } /* ballon */ if (BalloonView != None) { cset = Desks[Scr.balloon_desk].ballooncolorset; if (CSET_IS_TRANSPARENT_PR(cset)) { XClearArea(dpy, Scr.balloon_w, 0, 0, 0, 0, True); } } } void MovePage(Bool is_new_desk) { int n1,m1,x,y,n,m,i,w,h; XTextProperty name; char str[100],*sptr; static int icon_desk_shown = -1000; Wait = 0; n1 = Scr.Vx/Scr.MyDisplayWidth; m1 = Scr.Vy/Scr.MyDisplayHeight; n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; x = (desk_w - n) * Scr.Vx / Scr.VWidth + n1; y = (desk_h - m) * Scr.Vy / Scr.VHeight + m1; w = (desk_w - n)/(n+1); h = (desk_h - m)/(m+1); for(i=0;i= desk1)&&(Scr.CurrentDesk <=desk2)) sptr = Desks[Scr.CurrentDesk -desk1].label; else { sprintf(str, "GotoDesk %d", Scr.CurrentDesk); sptr = &str[0]; } if (FlocaleTextListToTextProperty( dpy, &sptr, 1, XStdICCTextStyle, &name) == 0) { fprintf(stderr,"%s: cannot allocate window name", MyName); return; } XSetWMIconName(dpy,Scr.Pager_w,&name); XFree(name.value); } } void ReConfigureAll(void) { PagerWindow *t; t = Start; while(t!= NULL) { MoveResizePagerView(t, True); t = t->next; } } void ReConfigureIcons(Bool do_reconfigure_desk_only) { PagerWindow *t; int x, y, w, h; for (t = Start; t != NULL; t = t->next) { if (do_reconfigure_desk_only && t->desk != Scr.CurrentDesk) continue; CalcGeom(t, icon_w, icon_h, &x, &y, &w, &h); t->icon_view_x = x; t->icon_view_y = y; t->icon_view_width = w; t->icon_view_height = h; if(Scr.CurrentDesk == t->desk) XMoveResizeWindow(dpy, t->IconView, x, y, w, h); else XMoveResizeWindow(dpy, t->IconView, -32768, -32768, w, h); } } /* * * Draw grid lines for desk #i * */ void DrawGrid(int desk, int erase, Window ew, XRectangle *r) { int y, y1, y2, x, x1, x2,d,w; char str[15], *ptr; int cs; XRectangle bound; Region region = 0; if((desk < 0 ) || (desk >= ndesks)) return; /* desk grid */ if (!ew || ew == Desks[desk].w) { x = Scr.MyDisplayWidth; y1 = 0; y2 = desk_h; while (x < Scr.VWidth) { x1 = (x * desk_w) / Scr.VWidth; if (!use_no_separators) { XDrawLine( dpy,Desks[desk].w,Desks[desk].DashedGC, x1,y1,x1,y2); } x += Scr.MyDisplayWidth; } y = Scr.MyDisplayHeight; x1 = 0; x2 = desk_w; while(y < Scr.VHeight) { y1 = (y * desk_h) / Scr.VHeight; if (!use_no_separators) { XDrawLine( dpy,Desks[desk].w,Desks[desk].DashedGC, x1,y1,x2,y1); } y += Scr.MyDisplayHeight; } } if (ew && ew != Desks[desk].title_w) { return; } /* desk label */ if (r) { bound.x = r->x; bound.y = r->y; bound.width = r->width; bound.height = r->height; region = XCreateRegion(); XUnionRectWithRegion (&bound, region, region); } else { bound.x = 0; bound.y = (LabelsBelow ? desk_h : 0); bound.width = desk_w; bound.height = label_h; } if (FftSupport && Ffont->fftf.fftfont != NULL) { erase = True; } if(((Scr.CurrentDesk - desk1) == desk) && !ShapeLabels) { if (uselabel) { XFillRectangle( dpy,Desks[desk].title_w,Desks[desk].HiliteGC, bound.x, bound.y, bound.width, bound.height); } } else { if(uselabel && erase) { XClearArea(dpy,Desks[desk].title_w, bound.x, bound.y, bound.width, bound.height, False); } } d = desk1+desk; ptr = Desks[desk].label; w = FlocaleTextWidth(Ffont,ptr,strlen(ptr)); if( w > desk_w) { sprintf(str,"%d",d); ptr = str; w = FlocaleTextWidth(Ffont,ptr,strlen(ptr)); } if((w <= desk_w)&&(uselabel)) { FwinString->str = ptr; FwinString->win = Desks[desk].title_w; if(desk == (Scr.CurrentDesk - desk1)) { cs = Desks[desk].highcolorset; FwinString->gc = Desks[desk].rvGC; } else { cs = Desks[desk].colorset; FwinString->gc = Desks[desk].NormalGC; } FwinString->flags.has_colorset = False; if (cs >= 0) { FwinString->colorset = &Colorset[cs]; FwinString->flags.has_colorset = True; } FwinString->x = (desk_w - w)/2; FwinString->y = (LabelsBelow ? desk_h + Ffont->ascent + 1 : Ffont->ascent + 1); if (region) { FwinString->flags.has_clip_region = True; FwinString->clip_region = region; XSetRegion(dpy, FwinString->gc, region); } else { FwinString->flags.has_clip_region = False; } FlocaleDrawString(dpy, Ffont, FwinString, 0); if (region) { XDestroyRegion(region); FwinString->flags.has_clip_region = False; FwinString->clip_region = None; XSetClipMask(dpy, FwinString->gc, None); } } if (FShapesSupported) { UpdateWindowShape (); } } void DrawIconGrid(int erase) { int y, y1, y2, x, x1, x2,w,h,n,m,n1,m1; int i; if(erase) { int tmp=(Scr.CurrentDesk - desk1); if ((tmp < 0) || (tmp >= ndesks)) { if (PixmapBack) XSetWindowBackgroundPixmap(dpy, icon_win,PixmapBack->picture); else XSetWindowBackground(dpy, icon_win, back_pix); } else { if (Desks[tmp].bgPixmap) XSetWindowBackgroundPixmap( dpy, icon_win,Desks[tmp].bgPixmap->picture); else if (Desks[tmp].Dcolor) XSetWindowBackground(dpy, icon_win, GetColor(Desks[tmp].Dcolor)); else if (PixmapBack) XSetWindowBackgroundPixmap(dpy, icon_win, PixmapBack->picture); else XSetWindowBackground(dpy, icon_win, back_pix); } XClearWindow(dpy,icon_win); } x = Scr.MyDisplayWidth; y1 = 0; y2 = icon_h; while(x < Scr.VWidth) { x1 = x * icon_w / Scr.VWidth; if (!use_no_separators) for(i=0;ipicture, icon_win, Scr.NormalGC, 0, 0, w, h, x, y); } else { for(i=0;ixbutton.x * Scr.VWidth / (desk_w * Scr.MyDisplayWidth); vy = Event->xbutton.y * Scr.VHeight / (desk_h * Scr.MyDisplayHeight); Scr.Vx = vx * Scr.MyDisplayWidth; Scr.Vy = vy * Scr.MyDisplayHeight; sprintf(command, "GotoDeskAndPage %d %d %d", Desk + desk1, vx, vy); SendText(fd, command, 0); } else { int x = Event->xbutton.x * Scr.VWidth / (desk_w * Scr.MyDisplayWidth); int y = Event->xbutton.y * Scr.VHeight / (desk_h * Scr.MyDisplayHeight); /* Fix for buggy XFree86 servers that report button release events * incorrectly when moving fast. Not perfect, but should at least prevent * that we get a random page. */ if (x < 0) x = 0; if (y < 0) y = 0; if (x * Scr.MyDisplayWidth > Scr.VxMax) x = Scr.VxMax / Scr.MyDisplayWidth; if (y * Scr.MyDisplayHeight > Scr.VyMax) y = Scr.VyMax / Scr.MyDisplayHeight; sprintf(command, "GotoPage %d %d", x, y); SendText(fd, command, 0); } Wait = 1; } void IconSwitchPage(XEvent *Event) { char command[34]; sprintf(command,"GotoPage %d %d", Event->xbutton.x * Scr.VWidth / (icon_w * Scr.MyDisplayWidth), Event->xbutton.y * Scr.VHeight / (icon_h * Scr.MyDisplayHeight)); SendText(fd, command, 0); Wait = 1; } void AddNewWindow(PagerWindow *t) { unsigned long valuemask; XSetWindowAttributes attributes; int i, x, y, w, h; i = t->desk - desk1; CalcGeom(t, desk_w, desk_h, &x, &y, &w, &h); t->pager_view_x = x; t->pager_view_y = y; t->pager_view_width = w; t->pager_view_height = h; valuemask = CWBackPixel | CWEventMask; attributes.background_pixel = t->back; attributes.event_mask = ExposureMask; /* ric@giccs.georgetown.edu -- added Enter and Leave events for popping up balloon window */ attributes.event_mask = ExposureMask | EnterWindowMask | LeaveWindowMask; if ((i >= 0) && (i < ndesks)) { t->PagerView = XCreateWindow( dpy,Desks[i].w, x, y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); if (windowcolorset > -1) { SetWindowBackground( dpy, t->PagerView, w, h, &Colorset[windowcolorset], Pdepth, Scr.NormalGC, True); } if (!UseSkipList || !DO_SKIP_WINDOW_LIST(t)) { if (IS_ICONIFIED(t)) { XMoveResizeWindow( dpy, t->PagerView, -32768, -32768, 1, 1); } XMapRaised(dpy, t->PagerView); } } else { t->PagerView = None; } CalcGeom(t, icon_w, icon_h, &x, &y, &w, &h); t->icon_view_x = x; t->icon_view_y = y; t->icon_view_width = w; t->icon_view_height = h; if(Scr.CurrentDesk != t->desk) { x = -32768; y = -32768; } t->IconView = XCreateWindow( dpy,icon_win, x, y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); if (windowcolorset > -1) { SetWindowBackground( dpy, t->IconView, w, h, &Colorset[windowcolorset], Pdepth, Scr.NormalGC, True); } if(Scr.CurrentDesk == t->desk) { XGrabButton( dpy, 2, AnyModifier, t->IconView, True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); } if (!UseSkipList || !DO_SKIP_WINDOW_LIST(t)) { if (IS_ICONIFIED(t)) { XMoveResizeWindow( dpy, t->IconView, -32768, -32768, 1, 1); } XMapRaised(dpy, t->IconView); t->myflags.is_mapped = 1; } else { t->myflags.is_mapped = 0; } Hilight(t, False); return; } void ChangeDeskForWindow(PagerWindow *t,long newdesk) { int i, x, y, w, h; Bool size_changed = False; i = newdesk - desk1; if(t->PagerView == None) { t->desk = newdesk; XDestroyWindow(dpy,t->IconView); AddNewWindow( t); return; } CalcGeom(t, desk_w, desk_h, &x, &y, &w, &h); size_changed = (t->pager_view_width != w || t->pager_view_height != h); t->pager_view_x = x; t->pager_view_y = y; t->pager_view_width = w; t->pager_view_height = h; if ((i >= 0) && (i < ndesks)) { int cset; XReparentWindow(dpy, t->PagerView, Desks[i].w, x, y); if (size_changed) XResizeWindow(dpy, t->PagerView, w, h); cset = (t != FocusWin) ? windowcolorset : activecolorset; if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( dpy, t->PagerView, t->pager_view_width, t->pager_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } else { XDestroyWindow(dpy,t->PagerView); t->PagerView = None; } t->desk = i+desk1; CalcGeom(t, icon_w, icon_h, &x, &y, &w, &h); size_changed = (t->icon_view_width != w || t->icon_view_height != h); t->icon_view_x = x; t->icon_view_y = y; t->icon_view_width = w; t->icon_view_height = h; if(Scr.CurrentDesk != t->desk) XMoveResizeWindow(dpy,t->IconView,-32768,-32768,w,h); else { int cset; XMoveResizeWindow(dpy,t->IconView,x,y,w,h); cset = (t != FocusWin) ? windowcolorset : activecolorset; if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( dpy, t->IconView, t->icon_view_width, t->icon_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } } void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) { int x, y, w, h; Bool size_changed; Bool position_changed; if (UseSkipList && DO_SKIP_WINDOW_LIST(t) && t->myflags.is_mapped) { if (t->PagerView) XUnmapWindow(dpy, t->PagerView); if (t->IconView) XUnmapWindow(dpy, t->IconView); t->myflags.is_mapped = 0; } else if (UseSkipList && !DO_SKIP_WINDOW_LIST(t) && !t->myflags.is_mapped) { if (t->PagerView) XMapRaised(dpy, t->PagerView); if (t->IconView) XMapRaised(dpy, t->IconView); t->myflags.is_mapped = 1; } CalcGeom(t, desk_w, desk_h, &x, &y, &w, &h); position_changed = (t->pager_view_x != x || t->pager_view_y != y); size_changed = (t->pager_view_width != w || t->pager_view_height != h); t->pager_view_x = x; t->pager_view_y = y; t->pager_view_width = w; t->pager_view_height = h; if (t->PagerView != None) { if (size_changed || position_changed || do_force_redraw) { int cset; XMoveResizeWindow(dpy, t->PagerView, x, y, w, h); cset = (t != FocusWin) ? windowcolorset : activecolorset; if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( dpy, t->PagerView, t->pager_view_width, t->pager_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } } else if (t->desk >= desk1 && t->desk <= desk2) { XDestroyWindow(dpy, t->IconView); AddNewWindow(t); return; } CalcGeom(t, icon_w, icon_h, &x, &y, &w, &h); position_changed = (t->icon_view_x != x || t->icon_view_y != y); size_changed = (t->icon_view_width != w || t->icon_view_height != h); t->icon_view_x = x; t->icon_view_y = y; t->icon_view_width = w; t->icon_view_height = h; if (Scr.CurrentDesk == t->desk) { int cset; XMoveResizeWindow(dpy, t->IconView, x, y, w, h); cset = (t != FocusWin) ? windowcolorset : activecolorset; if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( dpy, t->IconView, t->icon_view_width, t->icon_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } else { XMoveResizeWindow(dpy, t->IconView, -32768, -32768, w, h); } } void MoveStickyWindow(Bool is_new_page, Bool is_new_desk) { PagerWindow *t; for (t = Start; t != NULL; t = t->next) { if ( is_new_desk && t->desk != Scr.CurrentDesk && ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) || IS_STICKY_ACROSS_DESKS(t))) { ChangeDeskForWindow(t, Scr.CurrentDesk); } else if ( is_new_page && ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_PAGES(t)) || IS_STICKY_ACROSS_PAGES(t))) { MoveResizePagerView(t, True); } } } void Hilight(PagerWindow *t, int on) { if(!t) return; if(Pdepth < 2) { if(on) { if(t->PagerView != None) XSetWindowBackgroundPixmap(dpy,t->PagerView,Scr.gray_pixmap); XSetWindowBackgroundPixmap(dpy,t->IconView,Scr.gray_pixmap); } else { if(IS_STICKY_ACROSS_DESKS(t) || IS_STICKY_ACROSS_PAGES(t)) { if(t->PagerView != None) XSetWindowBackgroundPixmap(dpy,t->PagerView, Scr.sticky_gray_pixmap); XSetWindowBackgroundPixmap(dpy,t->IconView, Scr.sticky_gray_pixmap); } else { if(t->PagerView != None) XSetWindowBackgroundPixmap(dpy,t->PagerView, Scr.light_gray_pixmap); XSetWindowBackgroundPixmap(dpy,t->IconView, Scr.light_gray_pixmap); } } if(t->PagerView != None) XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); } else { int cset; Pixel pix; cset = (on) ? activecolorset : windowcolorset; pix = (on) ? focus_pix : t->back; if (cset < 0) { if (t->PagerView != None) { XSetWindowBackground(dpy,t->PagerView,pix); XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); } XSetWindowBackground(dpy,t->IconView,pix); XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); } else { if (t->PagerView != None) { SetWindowBackground( dpy, t->PagerView, t->pager_view_width, t->pager_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } SetWindowBackground( dpy, t->IconView, t->icon_view_width, t->icon_view_height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } } /* Use Desk == -1 to scroll the icon window */ void Scroll(int window_w, int window_h, int x, int y, int Desk, Bool do_scroll_icon) { static int last_sx = -999999; static int last_sy = -999999; int sx; int sy; int adjx,adjy; /* Desk < 0 means we want to scroll an icon window */ if (Desk >= 0 && Desk + desk1 != Scr.CurrentDesk) { return; } /* center around mouse */ adjx = (desk_w / (1 + Scr.VxMax / Scr.MyDisplayWidth)); adjy = (desk_h / (1 + Scr.VyMax / Scr.MyDisplayHeight)); x -= adjx/2; y -= adjy/2; /* adjust for pointer going out of range */ if (x < 0) { x = 0; } if (y < 0) { y = 0; } if (x > window_w-adjx) { x = window_w-adjx; } if (y > window_h-adjy) { y = window_h-adjy; } sx = 0; sy = 0; if (window_w != 0) { sx = (x * Scr.VWidth / window_w - MyVx); } if (window_h != 0) { sy = (y * Scr.VHeight / window_h - MyVy); } MYFPRINTF((stderr,"[scroll]: %d %d %d %d %d %d\n", window_w, window_h, x, y, sx, sy)); if (sx == 0 && sy == 0) { return; } if (Wait == 0 || last_sx != sx || last_sy != sy) { do_scroll(sx, sy, False, False); /* Here we need to track the view offset on the desk. */ /* sx/y are are pixels on the screen to scroll. */ /* We don't use Scr.Vx/y since they lag the true position. */ MyVx += sx; if (MyVx < 0) { MyVx = 0; } MyVy += sy; if (MyVy < 0) { MyVy = 0; } Wait = 1; } if (Wait == 0) { last_sx = sx; last_sy = sy; } return; } void MoveWindow(XEvent *Event) { char command[100]; int x1, y1, wx, wy, n, x, y, xi = 0, yi = 0, wx1, wy1, x2, y2; int finished = 0; Window dumwin; PagerWindow *t; int m, n1, m1; int NewDesk, KeepMoving = 0; int moved = 0; int row, column; Window JunkRoot, JunkChild; int JunkX, JunkY; unsigned JunkMask; int do_switch_desk_later = 0; t = Start; while (t != NULL && t->PagerView != Event->xbutton.subwindow) { t = t->next; } if (t == NULL) { t = Start; while (t != NULL && t->IconView != Event->xbutton.subwindow) { t = t->next; } if (t != NULL) { IconMoveWindow(Event, t); return; } } if (t == NULL || !t->allowed_actions.is_movable) { return; } NewDesk = t->desk - desk1; if (NewDesk < 0 || NewDesk >= ndesks) { return; } n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; n1 = (Scr.Vx + t->x) / Scr.MyDisplayWidth; m1 = (Scr.Vy + t->y) / Scr.MyDisplayHeight; wx = (Scr.Vx + t->x) * (desk_w - n) / Scr.VWidth + n1; wy = (Scr.Vy + t->y) * (desk_h - m) / Scr.VHeight + m1; wx1 = wx + (desk_w + 1) * (NewDesk % Columns); wy1 = wy + label_h + (desk_h + label_h + 1) * (NewDesk / Columns); if (LabelsBelow) { wy1 -= label_h; } XReparentWindow(dpy, t->PagerView, Scr.Pager_w, wx1, wy1); XRaiseWindow(dpy, t->PagerView); XTranslateCoordinates(dpy, Event->xany.window, t->PagerView, Event->xbutton.x, Event->xbutton.y, &x1, &y1, &dumwin); xi = x1; yi = y1; while (!finished) { FMaskEvent(dpy, ButtonReleaseMask | ButtonMotionMask | ExposureMask, Event); if (Event->type == MotionNotify) { XTranslateCoordinates(dpy, Event->xany.window, Scr.Pager_w, Event->xmotion.x, Event->xmotion.y, &x, &y, &dumwin); if (moved == 0) { xi = x; yi = y; moved = 1; } if (x < -5 || y < -5 || x > window_w + 5 || y > window_h + 5) { KeepMoving = 1; finished = 1; } XMoveWindow(dpy, t->PagerView, x - x1, y - y1); } else if (Event->type == ButtonRelease) { XTranslateCoordinates(dpy, Event->xany.window, Scr.Pager_w, Event->xbutton.x, Event->xbutton.y, &x, &y, &dumwin); XMoveWindow(dpy, t->PagerView, x - x1, y - y1); finished = 1; } else if (Event->type == Expose) { HandleExpose(Event); } } if (moved) { if (abs(x - xi) < MoveThreshold && abs(y - yi) < MoveThreshold) { moved = 0; } } if (KeepMoving) { NewDesk = Scr.CurrentDesk; if (NewDesk >= desk1 && NewDesk <= desk2) { XReparentWindow(dpy, t->PagerView, Desks[NewDesk-desk1].w, 0, 0); } else { XDestroyWindow(dpy, t->PagerView); t->PagerView = None; } if (FQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ x = 0; y = 0; } XUngrabPointer(dpy,CurrentTime); XSync(dpy,0); if (NewDesk != t->desk) { /* griph: This used to move to NewDesk, but NewDesk * is current desk, and if fvwm is on another * desk (due to async operation) we have to move * the window to it anyway or "Move Pointer" will * move an invisible window. */ SendText(fd, "Silent MoveToDesk", t->w); t->desk = NewDesk; } SendText(fd, "Silent Raise", t->w); SendText(fd, "Silent Move Pointer", t->w); return; } else { column = x / (desk_w + 1); if (column >= Columns) { column = Columns - 1; } if (column < 0) { column = 0; } row = y / (desk_h + label_h + 1); if (row >= Rows) { row = Rows - 1; } if (row < 0) { row = 0; } NewDesk = column + row * Columns; while (NewDesk < 0) { NewDesk += Columns; if (NewDesk >= ndesks) { NewDesk = 0; } } while (NewDesk >= ndesks) { NewDesk -= Columns; if (NewDesk < 0) { NewDesk = ndesks - 1; } } XTranslateCoordinates(dpy, Scr.Pager_w, Desks[NewDesk].w, x - x1, y - y1, &x2, &y2, &dumwin); n1 = x2 * Scr.VWidth / (desk_w * Scr.MyDisplayWidth); m1 = y2 * Scr.VHeight / (desk_h * Scr.MyDisplayHeight); x = (x2 - n1) * Scr.VWidth / (desk_w - n) - Scr.Vx; y = (y2 - m1) * Scr.VHeight / (desk_h - m) - Scr.Vy; /* force onto desk */ if (x + t->frame_width + Scr.Vx < 0 ) { x = -Scr.Vx - t->frame_width; } if (y + t->frame_height + Scr.Vy < 0) { y = -Scr.Vy - t->frame_height; } if (x + Scr.Vx >= Scr.VWidth) { x = Scr.VWidth - Scr.Vx - 1; } if (y + Scr.Vy >= Scr.VHeight) { y = Scr.VHeight - Scr.Vy - 1; } if ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) || (IS_STICKY_ACROSS_DESKS(t))) { NewDesk = Scr.CurrentDesk - desk1; if (x > Scr.MyDisplayWidth - 16) { x = Scr.MyDisplayWidth - 16; } if (y > Scr.MyDisplayHeight - 16) { y = Scr.MyDisplayHeight - 16; } if (x + t->width < 16) { x = 16 - t->width; } if (y + t->height < 16) { y = 16 - t->height; } } if (NewDesk + desk1 != t->desk) { if ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) || (IS_STICKY_ACROSS_DESKS(t))) { NewDesk = Scr.CurrentDesk - desk1; if (t->desk != Scr.CurrentDesk) { ChangeDeskForWindow(t,Scr.CurrentDesk); } } else if (NewDesk + desk1 != Scr.CurrentDesk) { sprintf(command, "Silent MoveToDesk 0 %d", NewDesk + desk1); SendText(fd, command, t->w); t->desk = NewDesk + desk1; } else { do_switch_desk_later = 1; } } if (NewDesk >= 0 && NewDesk < ndesks) { XReparentWindow(dpy, t->PagerView, Desks[NewDesk].w, x2, y2); t->desk = NewDesk; XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); if (moved) { char buf[64]; sprintf(buf, "Silent Move +%dp +%dp", x, y); SendText(fd, buf, t->w); XSync(dpy,0); } else { MoveResizePagerView(t, True); } SendText(fd, "Silent Raise", t->w); } if (do_switch_desk_later) { sprintf(command, "Silent MoveToDesk 0 %d", NewDesk + desk1); SendText(fd, command, t->w); t->desk = NewDesk + desk1; } if (Scr.CurrentDesk == t->desk) { XSync(dpy,0); usleep(5000); XSync(dpy,0); SendText(fd, "Silent FlipFocus NoWarp", t->w); } } if (is_transient) { /* does not return */ ExitPager(); } } /* * * Procedure: * FvwmErrorHandler - displays info on internal errors * */ int FvwmErrorHandler(Display *dpy, XErrorEvent *event) { #if 1 extern Bool error_occured; error_occured = True; return 0; #else /* really should just exit here... */ /* domivogt (07-mar-1999): No, not really. See comment above. */ PrintXErrorAndCoredump(dpy, event, MyName); return 0; #endif /* 1 */ } static void draw_window_border(PagerWindow *t, Window w, int width, int height) { if (w != None) { if (!WindowBorders3d || windowcolorset < 0 || activecolorset < 0) { XSetForeground(dpy, Scr.NormalGC, Scr.black); RelieveRectangle( dpy, w, 0, 0, width - 1, t->pager_view_height - 1, Scr.NormalGC, Scr.NormalGC, WindowBorderWidth); } else if (t == FocusWin) { RelieveRectangle( dpy, w, 0, 0, width - 1, height - 1, Scr.ahGC, Scr.asGC, WindowBorderWidth); } else { RelieveRectangle( dpy, w, 0, 0, width - 1, height - 1, Scr.whGC, Scr.wsGC, WindowBorderWidth); } } } void BorderWindow(PagerWindow *t) { draw_window_border( t, t->PagerView, t->pager_view_width, t->pager_view_height); } void BorderIconWindow(PagerWindow *t) { draw_window_border( t, t->IconView, t->icon_view_width, t->icon_view_height); } /* draw the window label with simple greedy wrapping */ static void label_window_wrap(PagerWindow *t) { char *cur, *next, *end; int space_width, cur_width; space_width = FlocaleTextWidth(FwindowFont, " ", 1); cur_width = 0; cur = next = t->window_label; end = cur + strlen(cur); while (*cur) { while (*next) { int width; char *p; if (!(p = strchr(next, ' '))) p = end; width = FlocaleTextWidth(FwindowFont, next, p - next ); if (width > t->pager_view_width - cur_width - space_width - 2*label_border) break; cur_width += width + space_width; next = *p ? p + 1 : p; } if (cur == next) { /* word too large for window */ while (*next) { int len, width; len = FlocaleStringNumberOfBytes(FwindowFont, next); width = FlocaleTextWidth(FwindowFont, next, len); if (width > t->pager_view_width - cur_width - 2*label_border && cur != next) break; next += len; cur_width += width; } } FwinString->str = safemalloc(next - cur + 1); strncpy(FwinString->str, cur, next - cur); FwinString->str[next - cur] = 0; FlocaleDrawString(dpy, FwindowFont, FwinString, 0); free(FwinString->str); FwinString->str = NULL; FwinString->y += FwindowFont->height; cur = next; cur_width = 0; } } static void do_label_window(PagerWindow *t, Window w) { int cs; if (t == FocusWin) { XSetForeground(dpy, Scr.NormalGC, focus_fore_pix); cs = activecolorset; } else { XSetForeground(dpy, Scr.NormalGC, t->text); cs = windowcolorset; } if (FwindowFont == NULL) { return; } if (MiniIcons && t->mini_icon.picture && (t->PagerView != None)) { /* will draw picture instead... */ return; } if (t->icon_name == NULL) { return; } /* Update the window label for this window */ if (t->window_label) free(t->window_label); t->window_label = GetBalloonLabel(t, WindowLabelFormat); if (w != None) { if (FftSupport && FwindowFont != NULL && FwindowFont->fftf.fftfont != NULL) XClearWindow(dpy, w); FwinString->win = w; FwinString->gc = Scr.NormalGC; FwinString->flags.has_colorset = False; if (cs >= 0) { FwinString->colorset = &Colorset[cs]; FwinString->flags.has_colorset = True; } FwinString->x = label_border; FwinString->y = FwindowFont->ascent+2; label_window_wrap(t); } } void LabelWindow(PagerWindow *t) { do_label_window(t, t->PagerView); } void LabelIconWindow(PagerWindow *t) { do_label_window(t, t->IconView); } static void do_picture_window( PagerWindow *t, Window w, int width, int height) { int iconX; int iconY; int src_x = 0; int src_y = 0; int dest_w, dest_h; int cs; FvwmRenderAttributes fra; if (MiniIcons) { if (t->mini_icon.picture && w != None) { dest_w = t->mini_icon.width; dest_h = t->mini_icon.height; if (width > t->mini_icon.width) { iconX = (width - t->mini_icon.width) / 2; } else if (width < t->mini_icon.width) { iconX = 0; src_x = (t->mini_icon.width - width) / 2; dest_w = width; } else { iconX = 0; } if (height > t->mini_icon.height) { iconY = (height - t->mini_icon.height) / 2; } else if (height < t->mini_icon.height) { iconY = 0; src_y = (t->mini_icon.height - height) / 2; dest_h = height; } else { iconY = 0; } fra.mask = FRAM_DEST_IS_A_WINDOW; if (t == FocusWin) { cs = activecolorset; } else { cs = windowcolorset; } if (t->mini_icon.alpha != None || (cs >= 0 && Colorset[cs].icon_alpha_percent < 100)) { XClearArea(dpy, w, iconX, iconY, t->mini_icon.width, t->mini_icon.height, False); } if (cs >= 0) { fra.mask |= FRAM_HAVE_ICON_CSET; fra.colorset = &Colorset[cs]; } PGraphicsRenderPicture( dpy, w, &t->mini_icon, &fra, w, Scr.MiniIconGC, None, None, src_x, src_y, t->mini_icon.width - src_x, t->mini_icon.height - src_y, iconX, iconY, dest_w, dest_h, False); } } } void PictureWindow (PagerWindow *t) { do_picture_window(t, t->PagerView, t->pager_view_width, t->pager_view_height); } void PictureIconWindow (PagerWindow *t) { do_picture_window(t, t->IconView, t->icon_view_width, t->icon_view_height); } void IconMoveWindow(XEvent *Event, PagerWindow *t) { int x1, y1, finished = 0, n, x = 0, y = 0, xi = 0, yi = 0; Window dumwin; int m, n1, m1; int moved = 0; int KeepMoving = 0; Window JunkRoot, JunkChild; int JunkX, JunkY; unsigned JunkMask; if (t == NULL || !t->allowed_actions.is_movable) { return; } n = Scr.VxMax / Scr.MyDisplayWidth; m = Scr.VyMax / Scr.MyDisplayHeight; n1 = (Scr.Vx + t->x) / Scr.MyDisplayWidth; m1 = (Scr.Vy + t->y) / Scr.MyDisplayHeight; XRaiseWindow(dpy, t->IconView); XTranslateCoordinates(dpy, Event->xany.window, t->IconView, Event->xbutton.x, Event->xbutton.y, &x1, &y1, &dumwin); while (!finished) { FMaskEvent(dpy, ButtonReleaseMask | ButtonMotionMask | ExposureMask, Event); if (Event->type == MotionNotify) { x = Event->xbutton.x; y = Event->xbutton.y; if (moved == 0) { xi = x; yi = y; moved = 1; } XMoveWindow(dpy, t->IconView, x - x1, y - y1); if (x < -5 || y < -5 || x > icon_w + 5 || y > icon_h + 5) { finished = 1; KeepMoving = 1; } } else if (Event->type == ButtonRelease) { x = Event->xbutton.x; y = Event->xbutton.y; XMoveWindow(dpy, t->PagerView, x - x1, y - y1); finished = 1; } else if (Event->type == Expose) { HandleExpose(Event); } } if (moved) { if (abs(x - xi) < MoveThreshold && abs(y - yi) < MoveThreshold) { moved = 0; } } if (KeepMoving) { if (FQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild, &x, &y, &JunkX, &JunkY, &JunkMask) == False) { /* pointer is on a different screen */ x = 0; y = 0; } XUngrabPointer(dpy, CurrentTime); XSync(dpy, 0); SendText(fd, "Silent Raise", t->w); SendText(fd, "Silent Move Pointer", t->w); } else { x = x - x1; y = y - y1; n1 = x * Scr.VWidth / (icon_w * Scr.MyDisplayWidth); m1 = y * Scr.VHeight / (icon_h * Scr.MyDisplayHeight); x = (x - n1) * Scr.VWidth / (icon_w - n) - Scr.Vx; y = (y - m1) * Scr.VHeight / (icon_h - m) - Scr.Vy; /* force onto desk */ if (x + t->icon_width + Scr.Vx < 0 ) { x = - Scr.Vx - t->icon_width; } if (y + t->icon_height + Scr.Vy < 0) { y = - Scr.Vy - t->icon_height; } if (x + Scr.Vx >= Scr.VWidth) { x = Scr.VWidth - Scr.Vx - 1; } if (y + Scr.Vy >= Scr.VHeight) { y = Scr.VHeight - Scr.Vy - 1; } if ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) || IS_STICKY_ACROSS_DESKS(t)) { if (x > Scr.MyDisplayWidth - 16) { x = Scr.MyDisplayWidth - 16; } if (y > Scr.MyDisplayHeight - 16) { y = Scr.MyDisplayHeight - 16; } if (x + t->width < 16) { x = 16 - t->width; } if (y + t->height < 16) { y = 16 - t->height; } } if (moved) { char buf[64]; sprintf(buf, "Silent Move +%dp +%dp", x, y); SendText(fd, buf, t->w); XSync(dpy, 0); } else { MoveResizePagerView(t, True); } SendText(fd, "Silent Raise", t->w); SendText(fd, "Silent FlipFocus NoWarp", t->w); } if (is_transient) { /* does not return */ ExitPager(); } } void setup_balloon_window(int i) { XSetWindowAttributes xswa; unsigned long valuemask; if (!ShowBalloons && Scr.balloon_w == None) { return; } XUnmapWindow(dpy, Scr.balloon_w); if (Desks[i].ballooncolorset < 0) { xswa.border_pixel = (!BalloonBorderColor) ? fore_pix : GetColor(BalloonBorderColor); xswa.background_pixel = (!BalloonBack) ? back_pix : GetColor(BalloonBack); valuemask = CWBackPixel | CWBorderPixel; } else { xswa.border_pixel = Colorset[Desks[i].ballooncolorset].fg; xswa.background_pixel = Colorset[Desks[i].ballooncolorset].bg; if (Colorset[Desks[i].ballooncolorset].pixmap) { /* set later */ xswa.background_pixmap = None; valuemask = CWBackPixmap | CWBorderPixel;; } else { valuemask = CWBackPixel | CWBorderPixel; } } XChangeWindowAttributes(dpy, Scr.balloon_w, valuemask, &xswa); return; } void setup_balloon_gc(int i, PagerWindow *t) { XGCValues xgcv; unsigned long valuemask; valuemask = GCForeground; if (Desks[i].ballooncolorset < 0) { xgcv.foreground = (!BalloonFore) ? fore_pix : GetColor(BalloonFore); if (BalloonFore == NULL) { XSetForeground(dpy, Scr.balloon_gc, t->text); } } else { xgcv.foreground = Colorset[Desks[i].ballooncolorset].fg; } if (Desks[i].balloon.Ffont->font != NULL) { xgcv.font = Desks[i].balloon.Ffont->font->fid; valuemask |= GCFont; } XChangeGC(dpy, Scr.balloon_gc, valuemask, &xgcv); return; } /* Just maps window ... draw stuff in it later after Expose event -- ric@giccs.georgetown.edu */ void MapBalloonWindow(PagerWindow *t, Bool is_icon_view) { extern char *BalloonBack; extern int BalloonYOffset; extern int BalloonBorderWidth; Window view, dummy; int view_width, view_height; int x, y; rectangle new_g; int i; if (!is_icon_view) { view = t->PagerView; view_width = t->pager_view_width; view_height = t->pager_view_height; } else { view = t->IconView; view_width = t->icon_view_width; view_height = t->icon_view_height; } BalloonView = view; /* associate balloon with its pager window */ if (fAlwaysCurrentDesk) { i = 0; } else { i = t->desk - desk1; } if (i < 0) return; Scr.balloon_desk = i; /* get the label for this balloon */ if (Scr.balloon_label) { free(Scr.balloon_label); } Scr.balloon_label = GetBalloonLabel(t, BalloonFormatString); #if 0 if (Scr.balloon_label == NULL) { /* dont draw empty labels */ return; } #endif setup_balloon_window(i); setup_balloon_gc(i, t); /* calculate window width to accommodate string */ new_g.height = Desks[i].balloon.height; new_g.width = 4; if (Scr.balloon_label) { new_g.width += FlocaleTextWidth( Desks[i].balloon.Ffont, Scr.balloon_label, strlen(Scr.balloon_label)); } /* get x and y coords relative to pager window */ x = (view_width / 2) - (new_g.width / 2) - BalloonBorderWidth; if (BalloonYOffset > 0) { y = view_height + BalloonYOffset - 1; } else { y = BalloonYOffset - new_g.height + 1 - (2 * BalloonBorderWidth); } /* balloon is a top-level window, therefore need to translate pager window coords to root window coords */ XTranslateCoordinates( dpy, view, Scr.Root, x, y, &new_g.x, &new_g.y, &dummy); /* make sure balloon doesn't go off screen * (actually 2 pixels from edge rather than 0 just to be pretty :-) */ /* too close to top ... make yoffset +ve */ if ( new_g.y < 2 ) { y = - BalloonYOffset - 1 + view_height; XTranslateCoordinates( dpy, view, Scr.Root, x, y, &new_g.x, &new_g.y, &dummy); } /* too close to bottom ... make yoffset -ve */ else if ( new_g.y + new_g.height > Scr.MyDisplayHeight - (2 * BalloonBorderWidth) - 2 ) { y = - BalloonYOffset + 1 - new_g.height - (2 * BalloonBorderWidth); XTranslateCoordinates( dpy, view, Scr.Root, x, y, &new_g.x, &new_g.y, &dummy); } /* too close to left */ if ( new_g.x < 2 ) { new_g.x = 2; } /* too close to right */ else if (new_g.x + new_g.width > Scr.MyDisplayWidth - (2 * BalloonBorderWidth) - 2 ) { new_g.x = Scr.MyDisplayWidth - new_g.width - (2 * BalloonBorderWidth) - 2; } /* make changes to window */ XMoveResizeWindow( dpy, Scr.balloon_w, new_g.x, new_g.y, new_g.width, new_g.height); /* if background not set in config make it match pager window */ if ( BalloonBack == NULL ) { XSetWindowBackground(dpy, Scr.balloon_w, t->back); } if (Desks[i].ballooncolorset > -1) { SetWindowBackground( dpy, Scr.balloon_w, new_g.width, new_g.height, &Colorset[Desks[i].ballooncolorset], Pdepth, Scr.NormalGC, True); XSetWindowBorder( dpy, Scr.balloon_w, Colorset[Desks[i].ballooncolorset].fg); } XMapRaised(dpy, Scr.balloon_w); return; } static void InsertExpand(char **dest, char *s) { int len; char *tmp = *dest; if (!s || !*s) return; len = strlen(*dest) + strlen(s) + 1; *dest = (char *)safemalloc(len); strcpy(*dest, tmp); free(tmp); strcat(*dest, s); return; } /* Generate the BallonLabel from the format string -- disching@fmi.uni-passau.de */ char *GetBalloonLabel(const PagerWindow *pw,const char *fmt) { char *dest = safestrdup(""); const char *pos = fmt; char buffer[2]; buffer[1] = '\0'; while (*pos) { if (*pos=='%' && *(pos+1)!='\0') { pos++; switch (*pos) { case 'i': InsertExpand(&dest, pw->icon_name); break; case 't': InsertExpand(&dest, pw->window_name); break; case 'r': InsertExpand(&dest, pw->res_name); break; case 'c': InsertExpand(&dest, pw->res_class); break; case '%': buffer[0] = '%'; InsertExpand(&dest, buffer); break; default:; } } else { buffer[0] = *pos; InsertExpand(&dest, buffer); } pos++; } return dest; } /* -- ric@giccs.georgetown.edu */ void UnmapBalloonWindow (void) { XUnmapWindow(dpy, Scr.balloon_w); BalloonView = None; } /* Draws string in balloon window -- call after it's received Expose event -- ric@giccs.georgetown.edu */ void DrawInBalloonWindow (int i) { FwinString->str = Scr.balloon_label; FwinString->win = Scr.balloon_w; FwinString->gc = Scr.balloon_gc; if (Desks[i].ballooncolorset >= 0) { FwinString->colorset = &Colorset[Desks[i].ballooncolorset]; FwinString->flags.has_colorset = True; } else { FwinString->flags.has_colorset = False; } FwinString->x = 2; FwinString->y = Desks[i].balloon.Ffont->ascent; FlocaleDrawString(dpy, Desks[i].balloon.Ffont, FwinString, 0); return; } static void set_window_colorset_background( PagerWindow *t, colorset_t *csetp) { if (t->PagerView != None) { SetWindowBackground( dpy, t->PagerView, t->pager_view_width, t->pager_view_height, csetp, Pdepth, Scr.NormalGC, True); } SetWindowBackground( dpy, t->IconView, t->icon_view_width, t->icon_view_height, csetp, Pdepth, Scr.NormalGC, True); return; } /* should be in sync with draw_desk_background */ void change_colorset(int colorset) { int i; PagerWindow *t; /* just in case */ if (colorset < 0) return; XSetWindowBackgroundPixmap(dpy, Scr.Pager_w, default_pixmap); for(i=0;ihilite); XSetForeground(dpy, Scr.wsGC, csetp->shadow); win_back_pix = csetp->bg; win_fore_pix = csetp->fg; win_pix_set = True; for (t = Start; t != NULL; t = t->next) { t->text = Colorset[colorset].fg; if (t != FocusWin) { set_window_colorset_background(t, csetp); } } } if (activecolorset == colorset) { colorset_t *csetp = &Colorset[colorset]; focus_fore_pix = csetp->fg; XSetForeground(dpy, Scr.ahGC, csetp->hilite); XSetForeground(dpy, Scr.asGC, csetp->shadow); win_hi_back_pix = csetp->bg; win_hi_fore_pix = csetp->fg; win_hi_pix_set = True; if (FocusWin) { set_window_colorset_background(FocusWin, csetp); } } return; } fvwm-2.6.7/modules/FvwmPager/FvwmPager.10000644000175700017570000003706113010101137014764 00000000000000.\" t .\" @(#)fvwm-2.6.7 06 November 2016 .TH FvwmPager 1 "06 November 2016 (2.6.7)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmPager \- the Fvwm Pager module .SH SYNOPSIS \fBFvwmPager\fP [ \fI-transient\fP ] [ \fIname\fP ] [ \fIfirst desk\fP [ \fIlast desk\fP ] ] FvwmPager is spawned by fvwm, so no command line invocation will work. All desks with desk numbers between \fIfirst desk\fP and \fIlast desk\fP are displayed. If \fIlast desk\fP is omitted only the \fIfirst desk\fP is shown. If both desk numbers are omitted, the current desk is used instead. If you use an asterisk '*' in place of \fIfirst desk\fP the pager will always show the current desktop, even when you switch desks. Example lines to put in your .fvwm2rc: .nf .sp Module FvwmPager 0 3 .sp .fi or .nf .sp Module FvwmPager * .sp .fi or from within an fvwm pop-up menu: .nf .sp AddToMenu Module-Popup Modules Title + Audio Module FvwmAudio + Auto Module FvwmAuto 200 + Buttons Module FvwmButtons + Console Module FvwmConsole + Ident Module FvwmIdent + Banner Module FvwmBanner + Pager Module FvwmPager 0 3 .sp .fi or .nf .sp + Pager Module FvwmPager * .sp .fi If the pager is started with the \fI-transient\fP option, the next time a button is released the pager is closed. Note that this option does only work if the window style of the pager window is 'sticky' (see the fvwm man page). You should use the 'StaysOnTop' style too. Example: .nf .sp Style FvwmPager Sticky, StaysOnTop *FvwmPager: Rows 1 *FvwmPager: Columns 1 Mouse 3 R C Module FvwmPager -transient .sp .fi With this in your .fvwm2rc, if you press control and button 3 in the root window the pager pops up under the mouse and while the viewport moves with the mouse. .SH DESCRIPTION The FvwmPager module shows a miniature view of the Fvwm desktops which are specified in the command line. This is a useful reminder of where your active windows are. Windows in the pager are shown in the same color as their fvwm decorations. The pager can be used to change your viewport into the current desktop, to change desktops, or to move windows around. Pressing mouse button 1 in the pager will cause you viewport to change to the selected page of the selected desk. If you click with button 1 in the desk-label area, you will switch desks but not pages within the desk. Dragging mouse button 2 on a miniature view of a window will cause that window to be move to the location where you release the mouse button, but your viewport will not change. If you drag the window out of the pager and onto your desktop, a full size image of the window will appear for you to place. There is no way to pick up a full size image of the window and move it into the pager, however. Since some mice do not have button 2, I have made provisions to drag windows in the pager by using pressing modifier-1 (usually Alt) and dragging with button 3. Clicking mouse button 3 on a location will cause the viewport to move to the selected location and switch desks if necessary, but will not align the viewport to a page boundary. Dragging button 3 will cause the viewport to move as you drag but not switch desktops, even if the pointer moves to another desktop. With the \fI*FvwmPager: SloppyFocus\fP option the focus is transferred to the window pointed at with the mouse when the pointer is inside the pager. When iconified, the pager will work as a fully functional current desk only pager. Windows and viewports can be moved within the icon of the pager. Users will want to make sure that they have no lines similar to .nf .sp Icon "Fvwm Pager" whatever .sp .fi in their .fvwm2rc files. .SH COPYRIGHTS The FvwmPager program, and the concept for interfacing this module to the Window Manager, are all original work by Robert Nation. Copyright 1994, Robert Nation. No guarantees or warranties or anything are provided or implied in any way whatsoever. Use this program at your own risk. Permission to use this program for any purpose is given, as long as the copyright is kept intact. .SH INITIALIZATION During initialization, \fIFvwmPager\fP gets config info from \fBfvwm\fP's module configuration database (see .IR fvwm (1), section .BR "MODULE COMMANDS" ). To use FvwmPager with several different configurations, you can invoke FvwmPager with an optional parameter, which it will use as its \fIname\fP instead (e.g "Module FvwmPager OtherPager"). OtherPager will then read only the lines in the configuration file starting with "*OtherPager", and not the lines belonging to FvwmPager. This way multiple pager instances may be used. Note: the old way to use the FvwmPager with several different configurations is to link the executable to another name, i.e. .nf .sp ln -s FvwmPager OtherPager .sp .fi This may work, but this method is not supported. .SH KEYBOARD FOCUS CONTROL You can direct the keyboard focus to any window on the current desktop by clicking with button 2 on its image in the pager. The window does not need to be visible, but it does need to be on the current page. .SH INVOCATION The invocation method was shown in the synopsis section .SH CONFIGURATION OPTIONS .IP "*FvwmPager: Geometry \fIgeometry\fP" Completely or partially specifies the pager windows location and geometry, in standard X11 notation. In order to maintain an undistorted aspect ratio, you might want to leave out either the width or height dimension of the geometry specification. .IP "*FvwmPager: Rows \fIrows\fP" Tells fvwm how many rows of desks to use when laying out the pager window. .IP "*FvwmPager: Columns \fIcolumns\fP" Tells fvwm how many columns of desks to use when laying out the pager window. .IP "*FvwmPager: IconGeometry \fIgeometry\fP" Specifies a size (optional) and location (optional) for the pager's icon window. Since there is no easy way for FvwmPager to determine the height of the icon's label, you will have to make an allowance for the icon label height when using negative y-coordinates in the icon location specification (used to specify a location relative to the bottom instead of the top of the screen). .IP "*FvwmPager: StartIconic" Causes the pager to start iconified. .IP "*FvwmPager: NoStartIconic" Causes the pager to start normally. Useful for canceling the effect of the \fIStartIconic\fP option. .IP "*FvwmPager: LabelsBelow" Causes the pager to draw desk labels below the corresponding desk. .IP "*FvwmPager: LabelsAbove" Causes the pager to draw desk labels above the corresponding desk. Useful for canceling the effect of the \fILabelsBelow\fP option. .IP "*FvwmPager: ShapeLabels" Causes the pager to hide the labels of all but the current desk. This turns off label hilighting. .IP "*FvwmPager: NoShapeLabels" Causes the pager to show the labels of all visible desks. Useful for canceling the effect of the \fIShapeLabels\fP option. .IP "*FvwmPager: Font \fIfont-name\fP" Specified a font to use to label the desktops. If \fIfont_name\fP is "none" then no desktop labels will be displayed. .IP "*FvwmPager: SmallFont \fIfont-name\fP" Specified a font to use to label the window names in the pager. If not specified, the window labels will be omitted. Window labels seem to be fairly useless for desktop scales of 32 or greater. If \fIfont_name\fP is "none" then no window names will be displayed. .IP "*FvwmPager: Fore \fIcolor\fP" Specifies the color to use to write the desktop labels, and to draw the page-grid lines. .IP "*FvwmPager: Back \fIcolor\fP" Specifies the background color for the window. .IP "*FvwmPager: Hilight \fIcolor\fP" The active page and desk label will be highlighted by using this background pattern instead of the normal background. .IP "*FvwmPager: HilightPixmap \fIpixmap\fP" The active page will be highlighted by using this background pattern instead of the normal background. .IP "*FvwmPager: DeskHilight" Hilight the active page with the current hilight color/pixmap. Useful for canceling the effect of the \fINoDeskHilight\fP option. .IP "*FvwmPager: NoDeskHilight" Don't hilight the active page. .IP "*FvwmPager: WindowColors \fIfore back hiFore hiBack\fP" Change the normal/highlight colors of the windows. \fIfore\fP and \fIhiFore\fP specify the colors as used for the font inside the windows. \fIback\fP and \fIhiBack\fP are used to fill the windows with. .IP "*FvwmPager: WindowLabelFormat \fIformat\fP" This specifies a printf() like format for the labels in the mini window. Possible flags are: %t, %i, %c, and %r for the window's title, icon title, class, or resource name, respectively. The default is "%i". .IP "*FvwmPager: Label \fIdesk label\fP" Assigns the text \fIlabel\fP to desk \fIdesk\fP (or the current desk if desk is "*") in the pager window. Useful for assigning symbolic names to desktops, i.e. .nf .sp *FvwmPager: Label 1 Mail *FvwmPager: Label 2 Maker *FvwmPager: Label * Matlab .sp .fi .BR Note : There is currently a much better way to specify desk names globally (and not just in FvwmPager) using .B DesktopName command, so you should not use this option anymore. .IP "*FvwmPager: DeskColor \fIdesk color\fP" Assigns the color \fIcolor\fP to desk \fIdesk\fP (or the current desk if desk is "*") in the pager window. This replaces the background color for the particular \fIdesk\fP. This only works when the pager is full sized. When Iconified, the pager uses the color specified by *FvwmPager: Back. .sp \fBTIP:\fP Try using *FvwmPager: DeskColor in conjunction with FvwmCpp (or FvwmM4) and FvwmBacker to assign identical colors to your various desktops and the pager representations. .IP "*FvwmPager: Pixmap \fIpixmap\fP" Use \fIpixmap\fP as background for the pager. .IP "*FvwmPager: DeskPixmap \fIdesk pixmap\fP" Assigns the pixmap \fIcolor\fP to desk \fIdesk\fP (or the current desk if desk is "*") in the pager window. This replaces the background pixmap for the particular \fIdesk\fP. .sp \fBTIP:\fP Try using *FvwmPager: DeskPixmap in conjunction with FvwmCpp (or FvwmM4) and FvwmBacker to assign identical pixmaps to your various desktops and the pager representations. .IP "*FvwmPager: DeskTopScale \fInumber\fP" If the geometry is not specified, then a desktop reduction factor is used to calculate the pager's size. Things in the pager window are shown at 1/\fInumber\fP of the actual size. .IP "*FvwmPager: MiniIcons" Allow the pager to display a window's mini icon in the pager, if it has one, instead of showing the window's name. .IP "*FvwmPager: MoveThreshold \fIpixels\fP" Defines the distance the pointer has to be moved before a window being dragged with button 2 is actually moved. The default value is three pixels. If the pointer moved less that this amount the window snaps back to its original position when the button is released. If \fIpixels\fP is less than zero the default value is used. The value set with the \fIMoveThreshold\fP command in fvwm is inherited by FvwmPager but can be overridden with this option. .IP "*FvwmPager: SloppyFocus" If the SloppyFocus option is used, you do not need to click into the mini window in the pager to give the real window the focus. Simply putting the pointer over the window inside the pager is enough. Note: This option interferes slightly with the MouseFocus and SloppyFocus styles of fvwm. Sometimes, if you click into the pager window to change pages or desks and then move the pointer to a place on the screen where a window of the new page will appear, this new window does not get the input focus. This may happen if you drag the pointer over one of the mini windows in the pager. There is nothing that can be done about this - except not using SloppyFocus in the pager. .IP "*FvwmPager: SolidSeparators" By default the pages of the virtual desktop are separated by dashed lines in the pager window. This option causes FvwmPager to use solid lines instead. .IP "*FvwmPager: NoSeparators" Turns off the lines separating the pages of the virtual desktop. .IP "*FvwmPager: Balloons [\fItype\fP]" Show a balloon describing the window when the pointer is moved into a window in the pager. The default format (the window's icon name) can be changed using BalloonStringFormat. If \fItype\fP is \fIPager\fP balloons are just shown for an un-iconified pager; if \fItype\fP is \fIIcon\fP balloons are just shown for an iconified pager. If \fItype\fP is anything else (or null) balloons are always shown. .IP "*FvwmPager: BalloonFore \fIcolor\fP" Specifies the color for text in the balloon window. If omitted it defaults to the foreground color for the window being described. .IP "*FvwmPager: BalloonBack \fIcolor\fP" Specifies the background color for the balloon window. If omitted it defaults to the background color for the window being described. .IP "*FvwmPager: BalloonFont \fIfont-name\fP" Specifies a font to use for the balloon text. Defaults to \fIfixed\fP. .IP "*FvwmPager: BalloonBorderWidth \fInumber\fP" Sets the width of the balloon window's border. Defaults to 1. .IP "*FvwmPager: BalloonBorderColor \fIcolor\fP" Sets the color of the balloon window's border. Defaults to black. .IP "*FvwmPager: BalloonYOffset \fInumber\fP" The balloon window is positioned to be horizontally centered against the pager window it is describing. The vertical position may be set as an offset. Negative offsets of \fI-n\fP are placed \fIn\fP pixels above the pager window, positive offsets of \fI+n\fP are placed \fIn\fP pixels below. Offsets of -1 and 1 represent the balloon window close to the original window without a gap. Offsets of 0 are not permitted, as this would permit direct transit from pager window to balloon window, causing an event loop. Defaults to +3. The offset will change sign automatically, as needed, to keep the balloon on the screen. .IP "*FvwmPager: BalloonStringFormat \fTformat\fP" The same as \fI*FvwmPager: WindowLabelFormat\fP, it just specifies the string to display in the balloons. The default is "%i". .IP "*FvwmPager: Colorset \fIdesk colorset\fP" Tells the module to use colorset \fIcolorset\fP for \fIdesk\fP. If you use an asterisk '*' in place of \fIdesk\fP, the colorset is used on all desks. Please refer to the man page of the FvwmTheme module for details about colorsets. .IP "*FvwmPager: BalloonColorset \fIdesk colorset\fP" Tells the module to use colorset \fIcolorset\fP for balloons on \fIdesk\fP. If you use an asterisk '*' in place of \fIdesk\fP, the colorset is used on all desks. Please refer to the man page of the FvwmTheme module for details about colorsets. .IP "*FvwmPager: HilightColorset \fIdesk colorset\fP" Tells the module to use colorset \fIcolorset\fP for hilighting on \fIdesk\fP. If you use an asterisk '*' in place of \fIdesk\fP, the colorset is used on all desks. Please refer to the man page of the FvwmTheme module for details about colorsets. .IP "*FvwmPager: WindowColorsets \fIcolorset activecolorset\fP" Uses colorsets in the same way as *FvwmPager: WindowColors. Please refer to the man page of the FvwmTheme module for details about colorsets. The shadow and hilight colors of the colorset are only used for the window borders if the *FvwmPager: Window3DBorders is specified too. .IP "*FvwmPager: WindowBorderWidth \fIn\fP" Specifies the width of the border drawn around the mini windows. This also sets the minimum size of the mini windows to (2 * \fIn\fP + 1). The default is 1. .IP "*FvwmPager: Window3DBorders" Specifies that the mini windows should have a 3d borders based on the mini window background. This option only works if *FvwmPager: WindowColorsets is specified. .IP "*FvwmPager: UseSkipList" Tells FvwmPager to not show the windows that are using the WindowListSkip style. .SH AUTHOR Robert Nation .br DeskColor patch contributed by Alan Wild .br MiniIcons & WindowColors patch contributed by Rob Whapham .br Balloons patch by Ric Lister .br fvwm-workers: Dominik, Olivier, Hippo and others. fvwm-2.6.7/modules/FvwmPager/FvwmPager.c0000644000175700017570000013666113001406607015066 00000000000000/* -*-c-*- */ /* This module, and the entire ModuleDebugger program, and the concept for * interfacing this module to the Window Manager, are all original work * by Robert Nation * * Copyright 1994, Robert Nation. No guarantees or warantees or anything * are provided or implied in any way whatsoever. Use this program at your * own risk. Permission to use this program for any purpose is given, * as long as the copyright is kept intact. */ /* 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 #include #include #include #include "libs/ftime.h" #include #ifdef HAVE_SYS_BSDTYPES_H #include /* Saul */ #endif /* Saul */ #include #include #include #include #include #include #include "libs/Module.h" #include "libs/fvwmlib.h" #include "libs/FScreen.h" #include "libs/FShape.h" #include "libs/FRenderInit.h" #include "libs/Colorset.h" #include "libs/Flocale.h" #include "libs/fvwmsignal.h" #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/Strings.h" #include "libs/System.h" #include "fvwm/fvwm.h" #include "FvwmPager.h" char *MyName; int fd[2]; PagerStringList *FindDeskStrings(int desk); PagerStringList *NewPagerStringItem(PagerStringList *last, int desk); extern FlocaleFont *FwindowFont; extern Pixmap default_pixmap; /* * * Screen, font, etc info * */ ScreenInfo Scr; PagerWindow *Start = NULL; PagerWindow *FocusWin = NULL; Display *dpy; /* which display are we talking to */ int x_fd; fd_set_size_t fd_width; char *PagerFore = NULL; char *PagerBack = NULL; char *font_string = NULL; char *smallFont = NULL; char *HilightC = NULL; FvwmPicture *HilightPixmap = NULL; int HilightDesks = 1; char *WindowBack = NULL; char *WindowFore = NULL; char *WindowHiBack = NULL; char *WindowHiFore = NULL; char *WindowLabelFormat = NULL; unsigned int WindowBorderWidth = DEFAULT_PAGER_WINDOW_BORDER_WIDTH; unsigned int MinSize = 2 * DEFAULT_PAGER_WINDOW_BORDER_WIDTH + 1; Bool WindowBorders3d = False; Bool UseSkipList = False; FvwmPicture *PixmapBack = NULL; char *ImagePath = NULL; #define DEFAULT_PAGER_MOVE_THRESHOLD 3 int MoveThreshold = DEFAULT_PAGER_MOVE_THRESHOLD; int ShowBalloons = 0, ShowPagerBalloons = 0, ShowIconBalloons = 0; Bool do_focus_on_enter = False; Bool use_dashed_separators = True; Bool use_no_separators = False; char *BalloonTypeString = NULL; char *BalloonBack = NULL; char *BalloonFore = NULL; char *BalloonFont = NULL; char *BalloonBorderColor = NULL; char *BalloonFormatString = NULL; int BalloonBorderWidth = 1; int BalloonYOffset = 3; Window BalloonView = None; int window_w=0, window_h=0, window_x=0, window_y=0; int icon_x=-10000, icon_y=-10000, icon_w=0, icon_h=0; int usposition = 0,uselabel = 1; int xneg = 0, yneg = 0; int icon_xneg = 0, icon_yneg = 0; extern DeskInfo *Desks; int StartIconic = 0; int MiniIcons = 0; int LabelsBelow = 0; int ShapeLabels = 0; int Rows = -1, Columns = -1; int desk1=0, desk2 =0; int ndesks = 0; int windowcolorset = -1; int activecolorset = -1; static int globalcolorset = -1; static int globalballooncolorset = -1; static int globalhighcolorset = -1; Pixel win_back_pix; Pixel win_fore_pix; Bool win_pix_set = False; Pixel win_hi_back_pix; Pixel win_hi_fore_pix; Bool win_hi_pix_set = False; char fAlwaysCurrentDesk = 0; PagerStringList string_list = { NULL, 0, -1, -1, -1, NULL, NULL, NULL }; Bool is_transient = False; Bool do_ignore_next_button_release = False; Bool error_occured = False; Bool Swallowed = False; static void SetDeskLabel(int desk, const char *label); static RETSIGTYPE TerminateHandler(int); void ExitPager(void); /* * * Procedure: * main - start of module * */ int main(int argc, char **argv) { char *display_name = NULL; int itemp,i; char line[100]; short opt_num; Window JunkRoot, JunkChild; int JunkX, JunkY; unsigned JunkMask; FlocaleInit(LC_CTYPE, "", "", "FvwmPager"); /* Tell the FEvent module an event type that is not used by fvwm. */ fev_init_invalid_event_type(KeymapNotify); /* Save our program name - for error messages */ MyName = GetFileNameFromPath(argv[0]); if(argc < 6) { fprintf(stderr,"%s Version %s should only be executed by fvwm!\n",MyName, VERSION); exit(1); } #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGPIPE); sigaddset(&sigact.sa_mask, SIGTERM); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); # ifdef SA_INTERRUPT sigact.sa_flags = SA_INTERRUPT; # else sigact.sa_flags = 0; # endif sigact.sa_handler = TerminateHandler; sigaction(SIGPIPE, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); } #else /* We don't have sigaction(), so fall back to less robust methods. */ #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGPIPE) | sigmask(SIGTERM) | sigmask(SIGQUIT) | sigmask(SIGINT) | sigmask(SIGHUP) ); #endif signal(SIGPIPE, TerminateHandler); signal(SIGTERM, TerminateHandler); signal(SIGQUIT, TerminateHandler); signal(SIGINT, TerminateHandler); signal(SIGHUP, TerminateHandler); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGPIPE, 1); siginterrupt(SIGTERM, 1); siginterrupt(SIGQUIT, 1); siginterrupt(SIGINT, 1); siginterrupt(SIGHUP, 1); #endif #endif fd[0] = atoi(argv[1]); fd[1] = atoi(argv[2]); fd_width = GetFdWidth(); opt_num = 6; if (argc >= 7 && (StrEquals(argv[opt_num], "-transient") || StrEquals(argv[opt_num], "transient"))) { opt_num++; is_transient = True; do_ignore_next_button_release = True; } /* Check for an alias */ if (argc >= opt_num + 1) { char *s; if (!StrEquals(argv[opt_num], "*")) { for (s = argv[opt_num]; *s; s++) { if (!isdigit(*s) && (*s != '-' || s != argv[opt_num] || *(s+1) == 0)) { free(MyName); MyName=safestrdup(argv[opt_num]); opt_num++; break; } } } } if (argc < opt_num + 1) { desk1 = Scr.CurrentDesk; desk2 = Scr.CurrentDesk; } else if (StrEquals(argv[opt_num], "*")) { desk1 = Scr.CurrentDesk; desk2 = Scr.CurrentDesk; fAlwaysCurrentDesk = 1; } else { desk1 = atoi(argv[opt_num]); if (argc == opt_num+1) desk2 = desk1; else desk2 = atoi(argv[opt_num+1]); if(desk2 < desk1) { itemp = desk1; desk1 = desk2; desk2 = itemp; } } ndesks = desk2 - desk1 + 1; Desks = (DeskInfo *)safemalloc(ndesks*sizeof(DeskInfo)); memset(Desks, 0, ndesks * sizeof(DeskInfo)); for(i=0;itype; unsigned long length = packet->size; unsigned long* body = packet->body; switch (type) { case M_ADD_WINDOW: list_configure(body); break; case M_CONFIGURE_WINDOW: list_configure(body); break; case M_DESTROY_WINDOW: list_destroy(body); break; case M_FOCUS_CHANGE: list_focus(body); break; case M_NEW_PAGE: list_new_page(body); break; case M_NEW_DESK: list_new_desk(body); break; case M_RAISE_WINDOW: list_raise(body); break; case M_LOWER_WINDOW: list_lower(body); break; case M_ICONIFY: case M_ICON_LOCATION: list_iconify(body); break; case M_DEICONIFY: list_deiconify(body, length); break; case M_RES_CLASS: case M_RES_NAME: case M_VISIBLE_NAME: list_window_name(body,type); break; case MX_VISIBLE_ICON_NAME: list_icon_name(body); break; case M_MINI_ICON: list_mini_icon(body); break; case M_END_WINDOWLIST: list_end(); break; case M_RESTACK: list_restack(body,length); break; case M_CONFIG_INFO: list_config_info(body); break; case MX_PROPERTY_CHANGE: list_property_change(body); break; case MX_REPLY: list_reply(body); break; default: /* ignore unknown packet */ break; } } /* * * Procedure: * SIGPIPE handler - SIGPIPE means fvwm is dying * */ static RETSIGTYPE TerminateHandler(int sig) { fvwmSetTerminate(sig); SIGNAL_RETURN; } RETSIGTYPE DeadPipe(int nonsense) { exit(0); SIGNAL_RETURN; } /* * Procedure: * handle_config_win_package - updates a PagerWindow * with respect to a ConfigWinPacket */ void handle_config_win_package(PagerWindow *t, ConfigWinPacket *cfgpacket) { if (t->w != None && t->w != cfgpacket->w) { /* Should never happen */ fprintf(stderr,"%s: Error: Internal window list corrupt\n",MyName); /* might be a good idea to exit here */ return; } t->w = cfgpacket->w; t->frame = cfgpacket->frame; t->frame_x = cfgpacket->frame_x; t->frame_y = cfgpacket->frame_y; t->frame_width = cfgpacket->frame_width; t->frame_height = cfgpacket->frame_height; t->desk = cfgpacket->desk; t->title_height = cfgpacket->title_height; t->border_width = cfgpacket->border_width; t->icon_w = cfgpacket->icon_w; t->icon_pixmap_w = cfgpacket->icon_pixmap_w; memcpy(&(t->flags), &(cfgpacket->flags), sizeof(cfgpacket->flags)); memcpy(&(t->allowed_actions), &(cfgpacket->allowed_actions), sizeof(cfgpacket->allowed_actions)); if (win_pix_set) { t->text = win_fore_pix; t->back = win_back_pix; } else { t->text = cfgpacket->TextPixel; t->back = cfgpacket->BackPixel; } if (IS_ICONIFIED(t)) { /* For new windows icon_x and icon_y will be zero until * iconify message is recived */ t->x = t->icon_x; t->y = t->icon_y; t->width = t->icon_width; t->height = t->icon_height; if(IS_ICON_SUPPRESSED(t) || t->width == 0 || t->height == 0) { t->x = -32768; t->y = -32768; } } else { t->x = t->frame_x; t->y = t->frame_y; t->width = t->frame_width; t->height = t->frame_height; } } /* * * Procedure: * list_add - displays packet contents to stderr * */ void list_add(unsigned long *body) { PagerWindow *t,**prev; int i=0; struct ConfigWinPacket *cfgpacket = (void *) body; t = Start; prev = &Start; while(t!= NULL) { if (t->w == cfgpacket->w) { /* it's already there, do nothing */ return; } prev = &(t->next); t = t->next; i++; } *prev = (PagerWindow *)safemalloc(sizeof(PagerWindow)); memset(*prev, 0, sizeof(PagerWindow)); handle_config_win_package(*prev, cfgpacket); AddNewWindow(*prev); return; } /* * * Procedure: * list_configure - displays packet contents to stderr * */ void list_configure(unsigned long *body) { PagerWindow *t; Window target_w; struct ConfigWinPacket *cfgpacket = (void *) body; Bool is_new_desk; target_w = cfgpacket->w; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if(t== NULL) { list_add(body); return; } is_new_desk = (t->desk != cfgpacket->desk); handle_config_win_package(t, cfgpacket); if (is_new_desk) { ChangeDeskForWindow(t, cfgpacket->desk); } else { MoveResizePagerView(t, False); } } /* * * Procedure: * list_destroy - displays packet contents to stderr * */ void list_destroy(unsigned long *body) { PagerWindow *t,**prev; Window target_w; target_w = body[0]; t = Start; prev = &Start; while((t!= NULL)&&(t->w != target_w)) { prev = &(t->next); t = t->next; } if(t!= NULL) { if(prev != NULL) *prev = t->next; /* remove window from the chain */ if(t->PagerView != None) XDestroyWindow(dpy,t->PagerView); XDestroyWindow(dpy,t->IconView); if(FocusWin == t) FocusWin = NULL; if(t->res_class != NULL) free(t->res_class); if(t->res_name != NULL) free(t->res_name); if(t->window_name != NULL) free(t->window_name); if(t->icon_name != NULL) free(t->icon_name); free(t); } } /* * * Procedure: * list_focus - displays packet contents to stderr * */ void list_focus(unsigned long *body) { PagerWindow *t; Window target_w; extern Pixel focus_pix, focus_fore_pix; Bool do_force_update = False; target_w = body[0]; if (win_hi_pix_set) { if (focus_pix != win_hi_back_pix || focus_fore_pix != win_hi_fore_pix) { do_force_update = True; } focus_pix = win_hi_back_pix; focus_fore_pix = win_hi_fore_pix; } else { if (focus_pix != body[4] || focus_fore_pix != body[3]) { do_force_update = True; } focus_pix = body[4]; focus_fore_pix = body[3]; } t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if (t != FocusWin || do_force_update) { if (FocusWin != NULL) Hilight(FocusWin, False); FocusWin = t; if (FocusWin != NULL) Hilight(FocusWin, True); } } /* * * Procedure: * list_new_page - displays packet contents to stderr * */ void list_new_page(unsigned long *body) { Scr.Vx = body[0]; Scr.Vy = body[1]; if (Scr.CurrentDesk != body[2]) { /* first handle the new desk */ body[0] = body[2]; list_new_desk(body); } if (Scr.VxPages != body[5] || Scr.VyPages != body[6]) { Scr.VxPages = body[5]; Scr.VyPages = body[6]; Scr.VWidth = Scr.VxPages * Scr.MyDisplayWidth; Scr.VHeight = Scr.VyPages * Scr.MyDisplayHeight; Scr.VxMax = Scr.VWidth - Scr.MyDisplayWidth; Scr.VyMax = Scr.VHeight - Scr.MyDisplayHeight; ReConfigure(); } MovePage(False); MoveStickyWindow(True, False); Hilight(FocusWin,True); } /* * * Procedure: * list_new_desk - displays packet contents to stderr * */ void list_new_desk(unsigned long *body) { int oldDesk; int change_cs = -1; int change_ballooncs = -1; int change_highcs = -1; oldDesk = Scr.CurrentDesk; Scr.CurrentDesk = (long)body[0]; if (fAlwaysCurrentDesk && oldDesk != Scr.CurrentDesk) { PagerWindow *t; PagerStringList *item; char line[100]; desk1 = Scr.CurrentDesk; desk2 = Scr.CurrentDesk; for (t = Start; t != NULL; t = t->next) { if (t->desk == oldDesk || t->desk == Scr.CurrentDesk) ChangeDeskForWindow(t, t->desk); } item = FindDeskStrings(Scr.CurrentDesk); if (Desks[0].label != NULL) { free(Desks[0].label); Desks[0].label = NULL; } if (item->next != NULL && item->next->label != NULL) { CopyString(&Desks[0].label, item->next->label); } else { sprintf(line, "Desk %d", desk1); CopyString(&Desks[0].label, line); } XStoreName(dpy, Scr.Pager_w, Desks[0].label); XSetIconName(dpy, Scr.Pager_w, Desks[0].label); if (Desks[0].bgPixmap != NULL) { PDestroyFvwmPicture(dpy, Desks[0].bgPixmap); Desks[0].bgPixmap = NULL; } if (Desks[0].Dcolor != NULL) { free (Desks[0].Dcolor); Desks[0].Dcolor = NULL; } if (item->next != NULL) { change_cs = item->next->colorset; change_ballooncs = item->next->ballooncolorset; change_highcs = item->next->highcolorset; } if (change_cs < 0) { change_cs = globalcolorset; } Desks[0].colorset = change_cs; if (change_cs > -1) { /* use our colour set if we have one */ change_colorset(change_cs); } else if (item->next != NULL && item->next->bgPixmap != NULL) { Desks[0].bgPixmap = item->next->bgPixmap; Desks[0].bgPixmap->count++; XSetWindowBackgroundPixmap(dpy, Desks[0].w, Desks[0].bgPixmap->picture); } else if (item->next != NULL && item->next->Dcolor != NULL) { CopyString(&Desks[0].Dcolor, item->next->Dcolor); XSetWindowBackground(dpy, Desks[0].w, GetColor(Desks[0].Dcolor)); } else if (PixmapBack != NULL) { Desks[0].bgPixmap = PixmapBack; Desks[0].bgPixmap->count++; XSetWindowBackgroundPixmap(dpy, Desks[0].w, Desks[0].bgPixmap->picture); } else { CopyString(&Desks[0].Dcolor, PagerBack); XSetWindowBackground(dpy, Desks[0].w, GetColor(Desks[0].Dcolor)); } if (item->next != NULL && item->next->Dcolor != NULL) { CopyString(&Desks[0].Dcolor, item->next->Dcolor); } else { CopyString(&Desks[0].Dcolor, PagerBack); } if (change_cs < 0 || Colorset[change_cs].pixmap != ParentRelative) XSetWindowBackground(dpy, Desks[0].title_w, GetColor(Desks[0].Dcolor)); /* update the colour sets for the desk */ if (change_ballooncs < 0) { change_ballooncs = globalballooncolorset; } Desks[0].ballooncolorset = change_ballooncs; if (change_highcs < 0) { change_highcs = globalhighcolorset; } Desks[0].highcolorset = change_highcs; if (change_ballooncs > -1 && change_ballooncs != change_cs) { change_colorset(change_ballooncs); } if (change_highcs > -1 && change_highcs != change_cs && change_highcs != change_ballooncs) { change_colorset(change_highcs); } XClearWindow(dpy, Desks[0].w); XClearWindow(dpy, Desks[0].title_w); } /* if (fAlwaysCurrentDesk && oldDesk != Scr.CurrentDesk) */ else if (!fAlwaysCurrentDesk) { int i; char *name; char line[100]; i = Scr.CurrentDesk - desk1; if (i >= 0 && i < ndesks && Desks[i].label != NULL) { name = Desks[i].label; } else { sprintf(line, "Desk %d", Scr.CurrentDesk); name = &(line[0]); } XStoreName(dpy, Scr.Pager_w, name); XSetIconName(dpy, Scr.Pager_w, name); } MovePage(True); DrawGrid(oldDesk - desk1, 1, None, NULL); DrawGrid(Scr.CurrentDesk - desk1, 1, None, NULL); MoveStickyWindow(False, True); /* Hilight(FocusWin,False); */ Hilight(FocusWin,True); } /* * * Procedure: * list_raise - displays packet contents to stderr * */ void list_raise(unsigned long *body) { PagerWindow *t; Window target_w; target_w = body[0]; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if(t!= NULL) { if(t->PagerView != None) XRaiseWindow(dpy,t->PagerView); XRaiseWindow(dpy,t->IconView); } } /* * * Procedure: * list_lower - displays packet contents to stderr * */ void list_lower(unsigned long *body) { PagerWindow *t; Window target_w; target_w = body[0]; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if(t!= NULL) { if(t->PagerView != None) XLowerWindow(dpy,t->PagerView); if (HilightDesks && (t->desk - desk1>=0) && (t->desk - desk1desk - desk1].CPagerWin); XLowerWindow(dpy,t->IconView); } } /* * * Procedure: * list_iconify - displays packet contents to stderr * */ void list_iconify(unsigned long *body) { PagerWindow *t; Window target_w; target_w = body[0]; t = Start; while (t != NULL && t->w != target_w) { t = t->next; } if (t != NULL) { t->t = (char *)body[2]; t->frame = body[1]; t->icon_x = body[3]; t->icon_y = body[4]; t->icon_width = body[5]; t->icon_height = body[6]; SET_ICONIFIED(t, True); if (IS_ICON_SUPPRESSED(t) || t->icon_width == 0 || t->icon_height == 0) { t->x = -32768; t->y = -32768; } else { t->x = t->icon_x; t->y = t->icon_y; } t->width = t->icon_width; t->height = t->icon_height; /* if iconifying main pager window turn balloons on or off */ if ( t->w == Scr.Pager_w ) { ShowBalloons = ShowIconBalloons; } MoveResizePagerView(t, True); } return; } /* * * Procedure: * list_deiconify - displays packet contents to stderr * */ void list_deiconify(unsigned long *body, unsigned long length) { PagerWindow *t; Window target_w; target_w = body[0]; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if (t == NULL) { return; } else { SET_ICONIFIED(t, False); if (length >= 11 + FvwmPacketHeaderSize) { t->frame_x = body[7]; t->frame_y = body[8]; t->frame_width = body[9]; t->frame_height = body[10]; } t->x = t->frame_x; t->y = t->frame_y; t->width = t->frame_width; t->height = t->frame_height; /* if deiconifying main pager window turn balloons on or off */ if ( t->w == Scr.Pager_w ) ShowBalloons = ShowPagerBalloons; MoveResizePagerView(t, True); } return; } void list_window_name(unsigned long *body,unsigned long type) { PagerWindow *t; Window target_w; target_w = body[0]; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if(t!= NULL) { switch (type) { case M_RES_CLASS: if(t->res_class != NULL) free(t->res_class); CopyString(&t->res_class,(char *)(&body[3])); break; case M_RES_NAME: if(t->res_name != NULL) free(t->res_name); CopyString(&t->res_name,(char *)(&body[3])); break; case M_VISIBLE_NAME: if(t->window_name != NULL) free(t->window_name); CopyString(&t->window_name,(char *)(&body[3])); break; } /* repaint by clearing window */ if ((FwindowFont != NULL) && (t->icon_name != NULL) && !(MiniIcons && t->mini_icon.picture)) { if (t->PagerView) XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); if (t->IconView) XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); } if (ShowBalloons && BalloonView) { /* update balloons */ if (BalloonView == t->PagerView) { UnmapBalloonWindow(); MapBalloonWindow(t, False); } else if (BalloonView == t->IconView) { UnmapBalloonWindow(); MapBalloonWindow(t, True); } } } } /* * * Procedure: * list_icon_name - displays packet contents to stderr * */ void list_icon_name(unsigned long *body) { PagerWindow *t; Window target_w; target_w = body[0]; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if(t!= NULL) { if(t->icon_name != NULL) free(t->icon_name); CopyString(&t->icon_name,(char *)(&body[3])); /* repaint by clearing window */ if ((FwindowFont != NULL) && (t->icon_name != NULL) && !(MiniIcons && t->mini_icon.picture)) { if (t->PagerView) XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); if (t->IconView) XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); } } } void list_mini_icon(unsigned long *body) { PagerWindow *t; MiniIconPacket *mip = (MiniIconPacket *) body; t = Start; while (t && (t->w != mip->w)) t = t->next; if (t) { t->mini_icon.width = mip->width; t->mini_icon.height = mip->height; t->mini_icon.depth = mip->depth; t->mini_icon.picture = mip->picture; t->mini_icon.mask = mip->mask; t->mini_icon.alpha = mip->alpha; /* repaint by clearing window */ if (MiniIcons && t->mini_icon.picture) { if (t->PagerView) XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); if (t->IconView) XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); } } } void list_restack(unsigned long *body, unsigned long length) { PagerWindow *t; Window target_w; Window *wins; int i, j, d; wins = (Window *) safemalloc (length * sizeof (Window)); /* first restack in the icon view */ j = 0; for (i = 0; i < (length - FvwmPacketHeaderSize); i += 3) { target_w = body[i]; t = Start; while((t!= NULL)&&(t->w != target_w)) { t = t->next; } if (t != NULL) { wins[j++] = t->IconView; } } XRestackWindows(dpy, wins, j); /* now restack each desk separately, since they have separate roots */ for (d = 0; d < ndesks; d++) { j = 0; for (i = 0; i < (length - 4); i+=3) { target_w = body[i]; t = Start; while((t!= NULL)&&((t->w != target_w)||(t->desk != d+desk1))) { t = t->next; } if (t != NULL) { if (t->PagerView != None) { wins[j++] = t->PagerView; } } } XRestackWindows(dpy, wins, j); } free (wins); } /* * * Procedure: * list_end - displays packet contents to stderr * */ void list_end(void) { unsigned int nchildren,i; Window root, parent, *children; PagerWindow *ptr; if(!XQueryTree(dpy, Scr.Root, &root, &parent, &children, &nchildren)) return; for(i=0; iframe == children[i])||(ptr->icon_w == children[i])|| (ptr->icon_pixmap_w == children[i])) { if(ptr->PagerView != None) XRaiseWindow(dpy,ptr->PagerView); XRaiseWindow(dpy,ptr->IconView); } ptr = ptr->next; } } if(nchildren > 0) XFree((char *)children); } void list_config_info(unsigned long *body) { char *tline, *token; int color; tline = (char*)&(body[3]); token = PeekToken(tline, &tline); if (StrEquals(token, "Colorset")) { color = LoadColorset(tline); change_colorset(color); } else if (StrEquals(token, XINERAMA_CONFIG_STRING)) { FScreenConfigureModule(tline); } else if (StrEquals(token, "DesktopName")) { int val; if (GetIntegerArguments(tline, &tline, &val, 1) > 0) { SetDeskLabel(val, (const char *)tline); } else { return; } if (fAlwaysCurrentDesk) { if (Scr.CurrentDesk == val) val = 0; } else if ((val >= desk1) && (val <=desk2)) { val = val - desk1; } DrawGrid(val, True, None, NULL); } } void list_property_change(unsigned long *body) { if (body[0] == MX_PROPERTY_CHANGE_BACKGROUND) { if (((!Swallowed && body[2] == 0) || (Swallowed && body[2] == Scr.Pager_w))) { update_pr_transparent_windows(); } } else if (body[0] == MX_PROPERTY_CHANGE_SWALLOW && body[2] == Scr.Pager_w) { Swallowed = body[1]; } } void list_reply(unsigned long *body) { char *tline; tline = (char*)&(body[3]); if (strcmp(tline, "ScrollDone") == 0) { HandleScrollDone(); } } /* * * Waits for next X event, or for an auto-raise timeout. * */ int My_XNextEvent(Display *dpy, XEvent *event) { fd_set in_fdset; static int miss_counter = 0; if(FPending(dpy)) { FNextEvent(dpy,event); return 1; } FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_SET(fd[1],&in_fdset); if (fvwmSelect(fd_width, &in_fdset, 0, 0, NULL) > 0) { if(FD_ISSET(x_fd, &in_fdset)) { if(FPending(dpy)) { FNextEvent(dpy,event); miss_counter = 0; return 1; } miss_counter++; #ifdef WORRY_ABOUT_MISSED_XEVENTS if(miss_counter > 100) DeadPipe(0); #endif } if(FD_ISSET(fd[1], &in_fdset)) { FvwmPacket* packet = ReadFvwmPacket(fd[1]); if ( packet == NULL ) exit(0); process_message( packet ); } } return 0; } /* This function is really tricky. The two offsets are the offsets of the * colorset members of the DeskInfo and PagerSringList structures to be * modified. The lines accessing this info look very ugly, but they work. */ static void ParseColorset(char *arg1, char *arg2, void *offset_deskinfo, void *offset_item, int *colorset_global) { Bool all_desks = False; int colorset = 0; int i; int desk; unsigned long colorset_offset = (unsigned long)offset_deskinfo; unsigned long item_colorset_offset = (unsigned long)offset_item; sscanf(arg2, "%d", &colorset); AllocColorset(colorset); if (StrEquals(arg1, "*")) { all_desks = True; desk = Scr.CurrentDesk; } else { desk = desk1; sscanf(arg1,"%d",&desk); } if (fAlwaysCurrentDesk) { if (all_desks) { *colorset_global = colorset; } else { PagerStringList *item; item = FindDeskStrings(desk); if (item->next != NULL) { *(int *)(((char *)(item->next)) + item_colorset_offset) = colorset; } else { /* new Dcolor and desktop */ item = NewPagerStringItem(item, desk); *(int *)(((char *)item) + item_colorset_offset) = colorset; } } if (desk == Scr.CurrentDesk || all_desks) { *(int *)(((char *)&Desks[0]) + colorset_offset) = colorset; } } else if (all_desks) { for (i = 0; i < ndesks; i++) { *(int *)(((char *)&Desks[i]) + colorset_offset) = colorset; } } else if((desk >= desk1)&&(desk <=desk2)) { *(int *)(((char *)&Desks[desk - desk1]) + colorset_offset) = colorset; } return; } static void SetDeskLabel(int desk, const char *label) { PagerStringList *item; if (fAlwaysCurrentDesk) { item = FindDeskStrings(desk); if (item->next != NULL) { /* replace label */ if (item->next->label != NULL) { free(item->next->label); item->next->label = NULL; } CopyString(&(item->next->label), label); } else { /* new Dcolor and desktop */ item = NewPagerStringItem(item, desk); CopyString(&(item->label), label); } if (desk == Scr.CurrentDesk) { free(Desks[0].label); CopyString(&Desks[0].label, label); } } else if((desk >= desk1)&&(desk <=desk2)) { free(Desks[desk - desk1].label); CopyString(&Desks[desk - desk1].label, label); } } /* * * This routine is responsible for reading and parsing the config file * */ void ParseOptions(void) { char *tline= NULL; int desk; int dx = 3; int dy = 3; FvwmPictureAttributes fpa; Scr.FvwmRoot = NULL; Scr.Hilite = NULL; Scr.VScale = 32; Scr.MyDisplayWidth = DisplayWidth(dpy, Scr.screen); Scr.MyDisplayHeight = DisplayHeight(dpy, Scr.screen); fpa.mask = 0; if (Pdepth <= 8) { fpa.mask |= FPAM_DITHER; } InitGetConfigLine(fd,CatString3("*",MyName,0)); for (GetConfigLine(fd,&tline); tline != NULL; GetConfigLine(fd,&tline)) { int g_x, g_y, flags; unsigned width,height; char *resource; char *arg1; char *arg2; char *tline2; char *token; char *next; Bool MoveThresholdSetForModule = False; arg1 = arg2 = NULL; token = PeekToken(tline, &next); if (StrEquals(token, "Colorset")) { LoadColorset(next); continue; } else if (StrEquals(token, XINERAMA_CONFIG_STRING)) { FScreenConfigureModule(next); } else if (StrEquals(token, "DesktopSize")) { token = PeekToken(next, &next); if (token) { sscanf(token, "%d", &dx); token = PeekToken(next, &next); if (token) sscanf(token, "%d", &dy); } continue; } else if (StrEquals(token, "ImagePath")) { if (ImagePath != NULL) { free(ImagePath); ImagePath = NULL; } GetNextToken(next, &ImagePath); continue; } else if (StrEquals(token, "MoveThreshold")) { if (!MoveThresholdSetForModule) { int val; if (GetIntegerArguments(next, NULL, &val, 1) > 0) { if (val >= 0) MoveThreshold = val; else MoveThreshold = DEFAULT_PAGER_MOVE_THRESHOLD; } } continue; } else if (StrEquals(token, "DesktopName")) { int val; if (GetIntegerArguments(next, &next, &val, 1) > 0) { SetDeskLabel(val, (const char *)next); } continue; } tline2 = GetModuleResource(tline, &resource, MyName); if (!resource) continue; tline2 = GetNextToken(tline2, &arg1); if (!arg1) { arg1 = (char *)safemalloc(1); arg1[0] = 0; } tline2 = GetNextToken(tline2, &arg2); if (!arg2) { arg2 = (char *)safemalloc(1); arg2[0] = 0; } if(StrEquals(resource,"Colorset")) { ParseColorset(arg1, arg2, &(((DeskInfo *)(NULL))->colorset), &(((PagerStringList *)(NULL))->colorset), &globalcolorset); } else if(StrEquals(resource,"BalloonColorset")) { ParseColorset(arg1, arg2, &(((DeskInfo *)(NULL))->ballooncolorset), &(((PagerStringList *)(NULL))->ballooncolorset), &globalballooncolorset); } else if(StrEquals(resource,"HilightColorset")) { ParseColorset(arg1, arg2, &(((DeskInfo *)(NULL))->highcolorset), &(((PagerStringList *)(NULL))->highcolorset), &globalhighcolorset); } else if (StrEquals(resource, "Geometry")) { window_w = 0; window_h = 0; window_x = 0; window_y = 0; xneg = 0; yneg = 0; usposition = 0; flags = FScreenParseGeometry(arg1,&g_x,&g_y,&width,&height); if (flags & WidthValue) { window_w = width; } if (flags & HeightValue) { window_h = height; } if (flags & XValue) { window_x = g_x; usposition = 1; if (flags & XNegative) { xneg = 1; } } if (flags & YValue) { window_y = g_y; usposition = 1; if (flags & YNegative) { yneg = 1; } } } else if (StrEquals(resource, "IconGeometry")) { icon_w = 0; icon_h = 0; icon_x = -10000; icon_y = -10000; icon_xneg = 0; icon_yneg = 0; flags = FScreenParseGeometry(arg1,&g_x,&g_y,&width,&height); if (flags & WidthValue) icon_w = width; if (flags & HeightValue) icon_h = height; if (flags & XValue) { icon_x = g_x; if (flags & XNegative) { icon_xneg = 1; } } if (flags & YValue) { icon_y = g_y; if (flags & YNegative) { icon_yneg = 1; } } } else if (StrEquals(resource, "Label")) { if (StrEquals(arg1, "*")) { desk = Scr.CurrentDesk; } else { desk = desk1; sscanf(arg1,"%d",&desk); } SetDeskLabel(desk, (const char *)arg2); } else if (StrEquals(resource, "Font")) { if (font_string) free(font_string); CopyStringWithQuotes(&font_string, next); if(strncasecmp(font_string,"none",4) == 0) { uselabel = 0; if (font_string) { free(font_string); font_string = NULL; } } } else if (StrEquals(resource, "Fore")) { if(Pdepth > 1) { if (PagerFore) free(PagerFore); CopyString(&PagerFore,arg1); } } else if (StrEquals(resource, "Back")) { if(Pdepth > 1) { if (PagerBack) free(PagerBack); CopyString(&PagerBack,arg1); } } else if (StrEquals(resource, "DeskColor")) { if (StrEquals(arg1, "*")) { desk = Scr.CurrentDesk; } else { desk = desk1; sscanf(arg1,"%d",&desk); } if (fAlwaysCurrentDesk) { PagerStringList *item; item = FindDeskStrings(desk); if (item->next != NULL) { /* replace Dcolor */ if (item->next->Dcolor != NULL) { free(item->next->Dcolor); item->next->Dcolor = NULL; } CopyString(&(item->next->Dcolor), arg2); } else { /* new Dcolor and desktop */ item = NewPagerStringItem(item, desk); CopyString(&(item->Dcolor), arg2); } if (desk == Scr.CurrentDesk) { free(Desks[0].Dcolor); CopyString(&Desks[0].Dcolor, arg2); } } else if((desk >= desk1)&&(desk <=desk2)) { free(Desks[desk - desk1].Dcolor); CopyString(&Desks[desk - desk1].Dcolor, arg2); } } else if (StrEquals(resource, "DeskPixmap")) { if (StrEquals(arg1, "*")) { desk = Scr.CurrentDesk; } else { desk = desk1; sscanf(arg1,"%d",&desk); } if (fAlwaysCurrentDesk) { PagerStringList *item; item = FindDeskStrings(desk); if (item->next != NULL) { if (item->next->bgPixmap != NULL) { PDestroyFvwmPicture(dpy, item->next->bgPixmap); item->next->bgPixmap = NULL; } item->next->bgPixmap = PCacheFvwmPicture( dpy, Scr.Pager_w, ImagePath, arg2, fpa); } else { /* new Dcolor and desktop */ item = NewPagerStringItem(item, desk); item->bgPixmap = PCacheFvwmPicture( dpy, Scr.Pager_w, ImagePath, arg2, fpa); } if (desk == Scr.CurrentDesk) { if (Desks[0].bgPixmap != NULL) { PDestroyFvwmPicture(dpy, Desks[0].bgPixmap); Desks[0].bgPixmap = NULL; } Desks[0].bgPixmap = PCacheFvwmPicture( dpy, Scr.Pager_w, ImagePath, arg2, fpa); } } else if((desk >= desk1)&&(desk <=desk2)) { int dNr = desk - desk1; if (Desks[dNr].bgPixmap != NULL) { PDestroyFvwmPicture(dpy, Desks[dNr].bgPixmap); Desks[dNr].bgPixmap = NULL; } Desks[dNr].bgPixmap = PCacheFvwmPicture( dpy, Scr.Pager_w, ImagePath, arg2, fpa); } } else if (StrEquals(resource, "Pixmap")) { if(Pdepth > 1) { if (PixmapBack) { PDestroyFvwmPicture (dpy, PixmapBack); PixmapBack = NULL; } PixmapBack = PCacheFvwmPicture( dpy, Scr.Pager_w, ImagePath, arg1, fpa); } } else if (StrEquals(resource, "HilightPixmap")) { if(Pdepth > 1) { if (HilightPixmap) { PDestroyFvwmPicture (dpy, HilightPixmap); HilightPixmap = NULL; } HilightPixmap = PCacheFvwmPicture ( dpy, Scr.Pager_w, ImagePath, arg1, fpa); } } else if (StrEquals(resource, "DeskHilight")) { HilightDesks = 1; } else if (StrEquals(resource, "NoDeskHilight")) { HilightDesks = 0; } else if (StrEquals(resource, "Hilight")) { if(Pdepth > 1) { if (HilightC) free(HilightC); CopyString(&HilightC,arg1); } } else if (StrEquals(resource, "SmallFont")) { if (smallFont) free(smallFont); CopyStringWithQuotes(&smallFont, next); if (strncasecmp(smallFont,"none",4) == 0) { free(smallFont); smallFont = NULL; } } else if (StrEquals(resource, "MiniIcons")) { MiniIcons = 1; } else if (StrEquals(resource, "StartIconic")) { StartIconic = 1; } else if (StrEquals(resource, "NoStartIconic")) { StartIconic = 0; } else if (StrEquals(resource, "LabelsBelow")) { LabelsBelow = 1; } else if (StrEquals(resource, "LabelsAbove")) { LabelsBelow = 0; } else if (FHaveShapeExtension && StrEquals(resource, "ShapeLabels")) { ShapeLabels = 1; } else if (FHaveShapeExtension && StrEquals(resource, "NoShapeLabels")) { ShapeLabels = 0; } else if (StrEquals(resource, "Rows")) { sscanf(arg1,"%d",&Rows); } else if (StrEquals(resource, "Columns")) { sscanf(arg1,"%d",&Columns); } else if (StrEquals(resource, "DeskTopScale")) { sscanf(arg1,"%d",&Scr.VScale); } else if (StrEquals(resource, "WindowColors")) { if (Pdepth > 1) { if (WindowFore) free(WindowFore); if (WindowBack) free(WindowBack); if (WindowHiFore) free(WindowHiFore); if (WindowHiBack) free(WindowHiBack); CopyString(&WindowFore, arg1); CopyString(&WindowBack, arg2); tline2 = GetNextToken(tline2, &WindowHiFore); GetNextToken(tline2, &WindowHiBack); } } else if (StrEquals(resource, "WindowBorderWidth")) { sscanf(arg1, "%d", &WindowBorderWidth); MinSize = 2 * WindowBorderWidth + 1; } else if (StrEquals(resource, "Window3dBorders")) { WindowBorders3d = True; } else if (StrEquals(resource,"WindowColorsets")) { sscanf(arg1,"%d",&windowcolorset); AllocColorset(windowcolorset); sscanf(arg2,"%d",&activecolorset); AllocColorset(activecolorset); } else if (StrEquals(resource,"WindowLabelFormat")) { if (WindowLabelFormat) free(WindowLabelFormat); CopyString(&WindowLabelFormat,arg1); } else if (StrEquals(resource,"UseSkipList")) { UseSkipList = True; } else if (StrEquals(resource, "MoveThreshold")) { int val; if (GetIntegerArguments(next, NULL, &val, 1) > 0 && val >= 0) { MoveThreshold = val; MoveThresholdSetForModule = True; } } else if (StrEquals(resource, "SloppyFocus")) { do_focus_on_enter = True; } else if (StrEquals(resource, "SolidSeparators")) { use_dashed_separators = False; use_no_separators = False; } else if (StrEquals(resource, "NoSeparators")) { use_no_separators = True; } /* ... and get Balloon config options ... -- ric@giccs.georgetown.edu */ else if (StrEquals(resource, "Balloons")) { if (BalloonTypeString) free(BalloonTypeString); CopyString(&BalloonTypeString, arg1); if ( strncasecmp(BalloonTypeString, "Pager", 5) == 0 ) { ShowPagerBalloons = 1; ShowIconBalloons = 0; } else if ( strncasecmp(BalloonTypeString, "Icon", 4) == 0 ) { ShowPagerBalloons = 0; ShowIconBalloons = 1; } else { ShowPagerBalloons = 1; ShowIconBalloons = 1; } /* turn this on initially so balloon window is created; later this variable is changed to match ShowPagerBalloons or ShowIconBalloons whenever we receive iconify or deiconify packets */ ShowBalloons = 1; } else if (StrEquals(resource, "BalloonBack")) { if (Pdepth > 1) { if (BalloonBack) free(BalloonBack); CopyString(&BalloonBack, arg1); } } else if (StrEquals(resource, "BalloonFore")) { if (Pdepth > 1) { if (BalloonFore) free(BalloonFore); CopyString(&BalloonFore, arg1); } } else if (StrEquals(resource, "BalloonFont")) { if (BalloonFont) free(BalloonFont); CopyStringWithQuotes(&BalloonFont, next); } else if (StrEquals(resource, "BalloonBorderColor")) { if (BalloonBorderColor) free(BalloonBorderColor); CopyString(&BalloonBorderColor, arg1); } else if (StrEquals(resource, "BalloonBorderWidth")) { sscanf(arg1, "%d", &BalloonBorderWidth); } else if (StrEquals(resource, "BalloonYOffset")) { sscanf(arg1, "%d", &BalloonYOffset); if (BalloonYOffset == 0) { fprintf(stderr, "%s: Warning:" " you're not allowed BalloonYOffset 0; defaulting to +3\n", MyName); /* we don't allow yoffset of 0 because it allows direct transit from * pager window to balloon window, setting up a LeaveNotify/EnterNotify * event loop */ BalloonYOffset = 3; } } else if (StrEquals(resource,"BalloonStringFormat")) { if (BalloonFormatString) free(BalloonFormatString); CopyString(&BalloonFormatString,arg1); } free(resource); free(arg1); free(arg2); } Scr.VxMax = dx * Scr.MyDisplayWidth - Scr.MyDisplayWidth; Scr.VyMax = dy * Scr.MyDisplayHeight - Scr.MyDisplayHeight; if (Scr.VxMax < 0) Scr.VxMax = 0; if (Scr.VyMax < 0) Scr.VyMax = 0; Scr.VWidth = Scr.VxMax + Scr.MyDisplayWidth; Scr.VHeight = Scr.VyMax + Scr.MyDisplayHeight; Scr.VxPages = Scr.VWidth / Scr.MyDisplayWidth; Scr.VyPages = Scr.VHeight / Scr.MyDisplayHeight; Scr.Vx = 0; Scr.Vy = 0; return; } /* Returns the item in the sring list that has item->next->desk == desk or * the last item (item->next == NULL) if no entry matches the desk number. */ PagerStringList *FindDeskStrings(int desk) { PagerStringList *item; item = &string_list; while (item->next != NULL) { if (item->next->desk == desk) break; item = item->next; } return item; } PagerStringList *NewPagerStringItem(PagerStringList *last, int desk) { PagerStringList *newitem; newitem = (PagerStringList *)safemalloc(sizeof(PagerStringList)); memset(newitem, 0, sizeof(PagerStringList)); last->next = newitem; newitem->colorset = -1; newitem->highcolorset = -1; newitem->ballooncolorset = -1; newitem->desk = desk; return newitem; } void ExitPager(void) { if (is_transient) { XUngrabPointer(dpy,CurrentTime); MyXUngrabServer(dpy); XSync(dpy,0); } XUngrabKeyboard(dpy, CurrentTime); exit(0); } fvwm-2.6.7/modules/FvwmPager/FvwmPager.h0000644000175700017570000001344312773467232015103 00000000000000/* -*-c-*- */ #include "libs/Picture.h" #include "libs/vpacket.h" #include "libs/Flocale.h" typedef struct ScreenInfo { unsigned long screen; int MyDisplayWidth; /* my copy of DisplayWidth(dpy, screen) */ int MyDisplayHeight; /* my copy of DisplayHeight(dpy, screen) */ char *FvwmRoot; /* the head of the fvwm window list */ Window Root; Window Pager_w; Window label_w; Window balloon_w; Font PagerFont; /* font struct for window labels in pager (optional)*/ GC NormalGC; /* used for window names and setting backgrounds */ GC MiniIconGC; /* used for clipping mini-icons */ GC whGC, wsGC, ahGC, asGC; /* used for 3d shadows on mini-windows */ GC label_gc; GC balloon_gc; int balloon_desk; char *balloon_label; /* the label displayed inside the balloon */ char *Hilite; /* the fvwm window that is highlighted * except for networking delays, this is the * window which REALLY has the focus */ unsigned VScale; /* Panner scale factor */ int VxMax; /* Max location for top left of virt desk*/ int VyMax; int VxPages; /* desktop size */ int VyPages; int VWidth; /* Size of virtual desktop */ int VHeight; int Vx; /* Current loc for top left of virt desk */ int Vy; int CurrentDesk; Pixmap sticky_gray_pixmap; Pixmap light_gray_pixmap; Pixmap gray_pixmap; Pixel black; } ScreenInfo; typedef struct pager_window { char *t; Window w; Window frame; int x; int y; int width; int height; int desk; int frame_x; int frame_y; int frame_width; int frame_height; int title_height; int border_width; int icon_x; int icon_y; int icon_width; int icon_height; Pixel text; Pixel back; window_flags flags; action_flags allowed_actions; struct { unsigned is_mapped : 1; } myflags; Window icon_w; Window icon_pixmap_w; char *icon_name; char *window_name; char *res_name; char *res_class; char *window_label; /* This is displayed inside the mini window */ FvwmPicture mini_icon; int pager_view_x; int pager_view_y; int pager_view_width; int pager_view_height; int icon_view_x; int icon_view_y; int icon_view_width; int icon_view_height; Window PagerView; Window IconView; struct pager_window *next; } PagerWindow; typedef struct balloon_window { FlocaleFont *Ffont; int height; /* height of balloon window based on font */ int desk; } BalloonWindow; typedef struct desk_info { Window w; Window title_w; Window CPagerWin; FvwmPicture *bgPixmap; /* Pixmap used as background. */ BalloonWindow balloon; int colorset; int highcolorset; int ballooncolorset; char *Dcolor; char *label; GC NormalGC; GC DashedGC; /* used the the pages boundary lines */ GC HiliteGC; /* used for hilighting the active desk */ GC rvGC; /* used for drawing hilighted desk title */ } DeskInfo; typedef struct pager_string_list { struct pager_string_list *next; int desk; int colorset; int highcolorset; int ballooncolorset; char *Dcolor; char *label; FvwmPicture *bgPixmap; /* Pixmap used as background. */ } PagerStringList; /* * * Subroutine Prototypes * */ char *GetNextToken(char *indata,char **token); void Loop(int *fd); RETSIGTYPE DeadPipe(int nonsense); void process_message(FvwmPacket*); void ParseOptions(void); void list_add(unsigned long *body); void list_configure(unsigned long *body); void list_config_info(unsigned long *body); void list_destroy(unsigned long *body); void list_focus(unsigned long *body); void list_toggle(unsigned long *body); void list_new_page(unsigned long *body); void list_new_desk(unsigned long *body); void list_raise(unsigned long *body); void list_lower(unsigned long *body); void list_unknown(unsigned long *body); void list_iconify(unsigned long *body); void list_deiconify(unsigned long *body, unsigned long length); void list_window_name(unsigned long *body,unsigned long type); void list_icon_name(unsigned long *body); void list_class(unsigned long *body); void list_res_name(unsigned long *body); void list_mini_icon(unsigned long *body); void list_restack(unsigned long *body, unsigned long length); void list_property_change(unsigned long *body); void list_end(void); void list_reply(unsigned long *body); int My_XNextEvent(Display *dpy, XEvent *event); /* Stuff in x_pager.c */ void change_colorset(int colorset); void initialize_pager(void); void initialize_viz_pager(void); Pixel GetColor(char *name); void DispatchEvent(XEvent *Event); void ReConfigure(void); void ReConfigureAll(void); void update_pr_transparent_windows(void); void MovePage(Bool is_new_desk); void DrawGrid(int desk,int erase,Window ew,XRectangle *r); void DrawIconGrid(int erase); void SwitchToDesk(int Desk); void SwitchToDeskAndPage(int Desk, XEvent *Event); void AddNewWindow(PagerWindow *prev); void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw); void ChangeDeskForWindow(PagerWindow *t,long newdesk); void MoveStickyWindow(Bool is_new_page, Bool is_new_desk); void Hilight(PagerWindow *, int); void Scroll(int window_w, int window_h, int x, int y, int Desk, Bool do_scroll_icon); void MoveWindow(XEvent *Event); void BorderWindow(PagerWindow *t); void BorderIconWindow(PagerWindow *t); void LabelWindow(PagerWindow *t); void LabelIconWindow(PagerWindow *t); void PictureWindow(PagerWindow *t); void PictureIconWindow(PagerWindow *t); void ReConfigureIcons(Bool do_reconfigure_desk_only); void IconSwitchPage(XEvent *Event); void IconMoveWindow(XEvent *Event,PagerWindow *t); void HandleEnterNotify(XEvent *Event); void HandleExpose(XEvent *Event); void MapBalloonWindow(PagerWindow *t, Bool is_icon_view); void UnmapBalloonWindow(void); void DrawInBalloonWindow(int i); void HandleScrollDone(void); fvwm-2.6.7/modules/FvwmCommand/0000755000175700017570000000000013010103343013376 500000000000000fvwm-2.6.7/modules/FvwmCommand/Makefile.am0000644000175700017570000000244212773470550015402 00000000000000## Process this file with automake to create Makefile.in PERL = @PERL@ SUBDIRS = scripts bin_PROGRAMS = FvwmCommand moduledir = @FVWM_MODULEDIR@ module_PROGRAMS = FvwmCommandS module_DATA = FvwmCommand.sh FvwmCommand.pm FvwmCommandS_SOURCES = FvwmCommandS.c FvwmCommand.h fifos.c FvwmCommand_SOURCES = FvwmCommand.c FvwmCommand.h fifos.c FvwmCommand.sh: findcmd.pl $(top_srcdir)/fvwm/functable.c if test -n "$(PERL)" -a -x "$(PERL)"; then \ $(PERL) $(srcdir)/findcmd.pl $(bindir) -sh \ < $(top_srcdir)/fvwm/functable.c > $@; \ else echo '# Did not find perl during fvwm install' > $@; fi FvwmCommand.pm: findcmd.pl $(top_srcdir)/fvwm/functable.c if test -n "$(PERL)" -a -x "$(PERL)"; then \ $(PERL) $(srcdir)/findcmd.pl $(bindir) \ < $(top_srcdir)/fvwm/functable.c > $@; \ else echo '# Did not find perl during fvwm install' > $@; fi CLEANFILES = FvwmCommand.sh FvwmCommand.pm FvwmCommandS_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a FvwmCommand_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a man_MANS = FvwmCommand.1 EXTRA_DIST = $(man_MANS) findcmd.pl LDADD = -L$(top_builddir)/libs -lfvwm # FIXME: # Despite not using X functions explicitly, the code includes # fvwmlib.h, which *does* include X headers and xpm.h! AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(Xft_CFLAGS) $(X_CFLAGS) fvwm-2.6.7/modules/FvwmCommand/FvwmCommandS.c0000644000175700017570000003157313001406607016045 00000000000000/* -*-c-*- */ /* * Fvwm command input interface. * * Copyright 1997, Toshi Isogai. No guarantees or warantees or anything * are provided. Use this program at your own risk. Permission to use * this program for any purpose is given, * as long as the copyright is kept intact. * */ /* 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "FvwmCommand.h" #include "libs/fvwmlib.h" #include "libs/fvwmsignal.h" #include "libs/Strings.h" #define MYNAME "FvwmCommandS" static int Fd[2]; /* pipes to fvwm */ static int FfdC; /* command fifo file discriptors */ static int FfdM; /* message fifo file discriptors */ static struct stat stat_buf; static char *FfdC_name = NULL, *FfdM_name = NULL; /* fifo names */ static ino_t FfdC_ino, FfdM_ino; /* fifo inode numbers */ int open_fifos(const char *f_stem); void close_fifos(void); void close_pipes(void); void err_msg(const char *msg); void err_quit(const char *msg) __attribute__((noreturn)); void process_message(unsigned long type,unsigned long *body); void relay_packet(unsigned long, unsigned long, unsigned long *); void server(char *); static RETSIGTYPE sig_handler(int); static char *bugger_off = "killme\n"; /* a queue of messages for FvwmCommand to receive */ typedef struct Q { unsigned long length; unsigned long sent; char *body; struct Q *next; } Q; /* head and tail of the queue */ static Q *Qstart = NULL; static Q *Qlast = NULL; /* flag to indicate new queue items available */ static Bool queueing = False; int main(int argc, char *argv[]) { char *fifoname; if (argc < FARGS) { fprintf(stderr, "%s version %s should only be executed by fvwm!\n", MYNAME, VERSION); exit(1); } if (argc == FARGS + 1) { fifoname = argv[FARGS]; } else { fifoname = NULL; } #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGTERM); sigaddset(&sigact.sa_mask, SIGPIPE); #ifdef SA_RESTART sigact.sa_flags = SA_RESTART; #else sigact.sa_flags = 0; #endif sigact.sa_handler = sig_handler; sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); } #else #ifdef USE_BSD_SIGNALS fvwmSetSignalMask(sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) | sigmask(SIGPIPE)); #endif signal(SIGPIPE, sig_handler); signal(SIGINT, sig_handler); signal(SIGQUIT, sig_handler); signal(SIGHUP, sig_handler); signal(SIGTERM, sig_handler); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGINT, 0); siginterrupt(SIGHUP, 0); siginterrupt(SIGQUIT, 0); siginterrupt(SIGTERM, 0); siginterrupt(SIGPIPE, 0); #endif #endif Fd[0] = atoi(argv[1]); Fd[1] = atoi(argv[2]); server(fifoname); close_pipes(); return 1; } /* * Signal handler */ static RETSIGTYPE sig_handler(int signo) { fvwmSetTerminate(signo); SIGNAL_RETURN; } /* * setup server and communicate with fvwm and the client */ void server (char *name) { char *f_stem; int len; fd_set fdrset, fdwset; char buf[MAX_MODULE_INPUT_TEXT_LEN + 1]; /* command receiving buffer */ char cmd[MAX_MODULE_INPUT_TEXT_LEN + 1]; int ix,cix; struct timeval tv; tv.tv_sec = 10; tv.tv_usec = 0; if (name == NULL) { if ((f_stem = fifos_get_default_name()) == NULL) { exit(-1); } } else { f_stem = name; } if (open_fifos(f_stem) < 0) { exit (-1); } cix = 0; /*Accept reply-messages */ SetMessageMask(Fd, MX_REPLY); /* tell fvwm we're running */ SendFinishedStartupNotification(Fd); while (!isTerminated) { int ret; FD_ZERO(&fdrset); FD_ZERO(&fdwset); FD_SET(FfdC, &fdrset); FD_SET(Fd[1], &fdrset); if (queueing) FD_SET(FfdM, &fdwset); ret = fvwmSelect(FD_SETSIZE, &fdrset, &fdwset, 0, queueing ? &tv : NULL); if (ret < 0) continue; if (queueing && ret == 0) { /* a timeout has occurred, this means the pipe to FvwmCommand is full * dump any messages in the queue that have not been partially sent */ Q *q1, *q2; #ifdef PARANOMIA /* do nothing if there are no messages (should never happen) */ if (!Qstart) { queueing = False; continue; } #endif q1 = Qstart->next; /* if the first message has been partially sent don't remove it */ if (!Qstart->sent) { free(Qstart->body); free(Qstart); Qstart = NULL; } else fprintf(stderr, "FvwmCommandS: leaving a partially sent message in the queue\n"); /* now remove the rest of the message queue */ while ((q2 = q1) != NULL) { q1 = q1->next; free(q2->body); free(q2); } /* there is either one message left (partially complete) or none */ Qlast = Qstart; queueing = False; continue; } if (FD_ISSET(Fd[1], &fdrset)) { FvwmPacket* packet = ReadFvwmPacket(Fd[1]); if (packet == NULL) { break; } process_message(packet->type, packet->body); } if (FD_ISSET(FfdC, &fdrset)) { /* * This descriptor is non-blocking, hence we should never * block here! Also, the select() call should guarantee that * there is something here to read, and the signal handling * should be restarting interrupted reads. Together, these * should severely restrict the types of errors that we can see. */ len = read(FfdC, buf, MAX_MODULE_INPUT_TEXT_LEN); if (len <= 0) { if ((len < 0) && (errno == EAGAIN)) { /* * This probably won't happen - the select() has told us that * there's something to read. The only possible thing that could * cause this is if somebody else read the data first ... (who?) */ continue; } /* * Any other error, such as an invalid descriptor (?) or someone * closing the remote end of our pipe, and we give up! */ err_quit("reading fifo"); } /* in case of multiple long lines */ for (ix = 0; ix < len; ix++) { cmd[cix] = buf[ix]; if (cmd[cix] == '\n') { cmd[cix] = '\0'; cix = 0; if (StrHasPrefix(bugger_off, cmd)) /* fvwm will close our pipes when it has processed this */ SendQuitNotification(Fd); else SendText(Fd, cmd, 0); } else if (cix >= MAX_MODULE_INPUT_TEXT_LEN) { err_msg("command too long"); cix = 0; } else { cix++; } } /* for */ } /* FD_ISSET */ if (queueing && FD_ISSET(FfdM, &fdwset)) { int sent; Q *q = Qstart; /* send one packet to FvwmCommand, try to send it all but cope * with partial success */ sent = write(FfdM, q->body + q->sent, q->length - q->sent); if (sent == q->length - q->sent) { Qstart = q->next; free(q->body); free(q); if (Qstart == NULL) { Qlast = NULL; queueing = False; } } else if (sent >= 0) q->sent += sent; } } /* while */ } /* * close fifos and pipes */ void close_pipes(void) { static char is_closed = 0; /* prevent that this is executed twice */ if (!is_closed) { is_closed = 1; close(Fd[0]); close(Fd[1]); close_fifos(); } } void close_fifos(void) { struct stat stat_buf; /* only unlink this file if it is the same as FfdC */ /* I know there's a race here between the stat and the unlink, if you know * of a way to unlink from a fildes use it here */ if ((stat(FfdC_name, &stat_buf) == 0) && (stat_buf.st_ino == FfdC_ino)) unlink(FfdC_name); /* only unlink this file if it is the same as FfdM */ if ((stat(FfdM_name, &stat_buf) == 0) && (stat_buf.st_ino == FfdM_ino)) unlink(FfdM_name); /* construct the name of the lock file and remove it */ FfdM_name[strlen(FfdM_name)-1] = 'R'; unlink(FfdM_name); close(FfdM); close(FfdC); FfdC = -1; FfdM = -1; } /* * open fifos */ int open_fifos(const char *f_stem) { /* create 2 fifos */ FfdC_name = malloc(strlen(f_stem) + 2); if (FfdC_name == NULL) { err_msg( "allocating command" ); return -1; } FfdM_name = malloc(strlen(f_stem) + 2); if (FfdM_name == NULL) { err_msg("allocating message"); return -1; } strcpy(FfdC_name, f_stem); strcpy(FfdM_name, f_stem); strcat(FfdC_name, "C"); strcat(FfdM_name, "M"); /* check to see if another FvwmCommandS is running by trying to talk to it */ FfdC = open(FfdC_name, O_RDWR | O_NONBLOCK | O_NOFOLLOW); /* remove the fifo's if they exist */ unlink(FfdM_name); unlink(FfdC_name); /* If a previous FvwmCommandS is lingering tell it to go away * It will check that it owns the fifo's before removing them so no * there is no need to wait before creating our own */ if (FfdC > 0) { int n; n = write(FfdC, bugger_off, strlen(bugger_off)); (void)n; close(FfdC); } /* now we can create the fifos knowing that they don't already exist * and any lingering FvwmCommandS will not share them or remove them */ if (mkfifo(FfdM_name, FVWM_S_IRUSR | FVWM_S_IWUSR) < 0) { err_msg(FfdM_name); return -1; } if (mkfifo(FfdC_name, FVWM_S_IRUSR | FVWM_S_IWUSR) < 0) { err_msg(FfdC_name); return -1; } if ((FfdM = open(FfdM_name, O_RDWR | O_NONBLOCK | O_NOFOLLOW)) < 0) { err_msg("opening message fifo"); return -1; } if ((FfdC = open(FfdC_name, O_RDWR | O_NONBLOCK | O_NOFOLLOW)) < 0) { err_msg("opening command fifo"); return -1; } /* get the inode numbers for use when quiting */ if (fstat(FfdC, &stat_buf) != 0) { err_msg("stat()ing command fifo"); return -1; } else { FfdC_ino = stat_buf.st_ino; if (!(S_IFIFO & stat_buf.st_mode)) { err_msg("command fifo is not a fifo"); return -1; } if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) { err_msg("command fifo is too permissive"); return -1; } } if (fstat(FfdM, &stat_buf) != 0) { err_msg("stat()ing message fifo"); return -1; } else { FfdM_ino = stat_buf.st_ino; if (!(S_IFIFO & stat_buf.st_mode)) { err_msg("message fifo is not a fifo"); return -1; } if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) { err_msg("message fifo is too permissive"); return -1; } } return 0; } /* * Process window list messages */ void process_message(unsigned long type,unsigned long *body) { int msglen; switch (type) { case M_ADD_WINDOW: case M_CONFIGURE_WINDOW: relay_packet(type, sizeof(struct ConfigWinPacket) * SOL, body); break; case M_ICON_LOCATION: case M_ICONIFY: relay_packet(type, 7 * SOL, body); break; case M_MINI_ICON: relay_packet(type, 6 * SOL, body); break; case M_NEW_PAGE: relay_packet(type, 5 * SOL, body); break; case M_NEW_DESK: relay_packet(type, 1 * SOL, body); break; case M_END_WINDOWLIST: case M_END_CONFIG_INFO: relay_packet(type, 0 * SOL, body); break; case M_WINDOW_NAME: case M_ICON_NAME: case M_RES_CLASS: case M_RES_NAME: case M_ICON_FILE: case M_DEFAULTICON: case M_ERROR: case M_STRING: case M_CONFIG_INFO: case MX_REPLY: msglen = strlen((char *)&body[3]); relay_packet(type, msglen + 1 + 3 * SOL, body); break; default: relay_packet(type, 4 * SOL, body); } } /* * print error message on stderr and exit */ void err_msg(const char *msg) { fprintf(stderr, "%s server error in %s, %s\n", MYNAME, msg, strerror(errno)); } void err_quit(const char *msg) { err_msg(msg); close_pipes(); exit(1); } /* * relay packet to front-end * this is now implemented by simply adding the packet to a queue * and letting the main select loop handle sending from the queue to * the front end. In this way FvwmCommandS is always responsive to commands * from the input pipes. (it will also die a lot faster when fvwm quits) */ void relay_packet(unsigned long type, unsigned long length, unsigned long *body) { Q *new; if (!body) return; new = (Q *)safemalloc(sizeof(Q)); new->length = length + 2 * SOL; new->sent = 0L; new->body = safemalloc(new->length); memcpy(new->body, &type, SOL); memcpy(new->body + SOL, &length, SOL); memcpy(new->body + 2 * SOL, body, length); new->next = NULL; if (Qlast) Qlast->next = new; Qlast = new; if (!Qstart) Qstart = Qlast; queueing = True; } fvwm-2.6.7/modules/FvwmCommand/scripts/0000755000175700017570000000000013010103343015065 500000000000000fvwm-2.6.7/modules/FvwmCommand/scripts/test2.sh0000755000175700017570000000252712673746443016447 00000000000000#!/bin/sh # FvwmCommand test # arg1 b to invoke FvwmButtons # kb to kill FvwmButtons # r to change button rows # c to change button columns # 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., 675 Mass Ave, Cambridge, MA 02139, USA. . ./FvwmCommand.sh if [ "$1" = 'b' ] ; then Module FvwmButtons; elif [ "$1" = 'kb' ] ; then KillModule FvwmButtons; elif [ "$1" = 'r' ] ; then n=$2 DestroyModuleConfig '*FvwmButtonsRows' FvwmCommand "*FvwmButtonsRows $n" elif [ "$1" = 'c' ] ; then n=$2 DestroyModuleConfig '*FvwmButtonsColumns' FvwmCommand "*FvwmButtonsColumns $n" else echo " arg1 b to invoke FvwmButtons" echo " kb to kill FvwmButtons" echo " r to change button rows" echo " c to change button columns" fi fvwm-2.6.7/modules/FvwmCommand/scripts/ex-auto.pl0000755000175700017570000000321212673746443016761 00000000000000#! xPERLx # FvwmCommand example - auto raise small windows # arg1 - size ( w * h in pixel) (default 60000) # arg2 - delay (second) (default 1) # 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., 675 Mass Ave, Cambridge, MA 02139, USA. open( FCM, "FvwmCommand -m -i3 send_windowlist |" ) || die "FCM"; open( FCC, ">$ENV{'HOME'}/.FvwmCommandC" ) || die "FCC"; select( FCC ); $| = 1; select( STDOUT ); $| = 1; $Size = shift; if( $Size <= 0 ) { $Size = 60000; } if( $#ARGV >= 0) { $Delay = shift; }else{ $Delay = 1; } LOOP1:while( ) { if( /^0x(\S+) frame .*width (\d+), height (\d+)/ ) { $Config{$1}{'area'} = $2 * $3; }elsif( /^0x(\S+) (focus change|end windowlist)/ ) { if( $1 != 0 ) { # delay longer than FvwmAuto select(undef,undef,undef,$Delay); foreach $w (keys %Config) { if( $Config{$w}{'area'} < $Size ) { print FCC "windowid 0x$w Raise\n"; # ignore while() { last if /^0x$w raise/; redo LOOP1 if /^0x\S+ focus change/; } select(undef,undef,undef,0.1); } } } } } fvwm-2.6.7/modules/FvwmCommand/scripts/Makefile.am0000644000175700017570000000117412773470550017072 00000000000000## Process this file with automake to create Makefile.in ## The script "focus-link" has a manpage, so perhaps it is intended to be ## installed? (it is not installed currently) ## migo: if we ever fix and install this, it should be renamed to ## fvwm-focus-list or fvwm-command-focus PERL = @PERL@ noinst_SCRIPTS = ex-auto ex-cascade ex-grpmv focus-Netscape \ focus-link push-away test1 EXTRA_DIST = ex-auto.pl ex-cascade.pl ex-grpmv.pl focus-Netscape.pl \ focus-link.pl push-away.pl test1.pl focus-link.1 test2.sh CLEANFILES = $(noinst_SCRIPTS) SUFFIXES = .pl .pl: @rm -f $@ sed -e 's,xPERLx,$(PERL),' $< > $@-t mv $@-t $@ fvwm-2.6.7/modules/FvwmCommand/scripts/Makefile.in0000644000175700017570000003571513010103323017063 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules/FvwmCommand/scripts DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SCRIPTS = $(noinst_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ noinst_SCRIPTS = ex-auto ex-cascade ex-grpmv focus-Netscape \ focus-link push-away test1 EXTRA_DIST = ex-auto.pl ex-cascade.pl ex-grpmv.pl focus-Netscape.pl \ focus-link.pl push-away.pl test1.pl focus-link.1 test2.sh CLEANFILES = $(noinst_SCRIPTS) SUFFIXES = .pl all: all-am .SUFFIXES: .SUFFIXES: .pl $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmCommand/scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmCommand/scripts/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .pl: @rm -f $@ sed -e 's,xPERLx,$(PERL),' $< > $@-t mv $@-t $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmCommand/scripts/ex-cascade.pl0000755000175700017570000000343212673746443017400 00000000000000#! xPERLx # FvwmCommand example - cascade windows # 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., 675 Mass Ave, Cambridge, MA 02139, USA. open( F, "FvwmCommand -ri2 send_windowlist |" ) || die "command" ; while( ) { if( /^(0x[0-9a-f]+) frame *x (\d+), y (\d+), width (\d+), height (\d+)/ ) { $config{$1}{'area'} = $4 * $5; $config{$1}{'x'} = $2; $config{$1}{'y'} = $3; }elsif( /^(0x[0-9a-f]+) Sticky +(yes|no)$/ ) { $config{$1}{'sticky'} = $2; }elsif( /^(0x[0-9a-f]+) desktop +(\d+)/ ) { $config{$1}{'desktop'} = $2; } } close F; $x = $y = 0; $delay = 3000; #need bigger number for slower machine foreach $i (keys %config) { next if( $config{$i}{'sticky'} =~ /yes/ ) ; system("FvwmCommand -w $delay 'windowid $i windowsdesk 0' " ); system("FvwmCommand -w 0 'windowid $i move ${x}p ${y}p' " ); system("FvwmCommand -w 0 'windowid $i raise' " ); $x += 50; $y += 50; } print( 'hit return to move them back!' ); <>; foreach $i (keys %config) { next if( $config{$i}{'sticky'} =~ /yes/ ) ; system("FvwmCommand -w 0 'windowid $i windowsdesk $config{$i}{desktop}'>/dev/null"); system("FvwmCommand -w $delay 'gotopage 0 0' 'windowid $i move $config{$i}{x}p $config{$i}{y}p' >/dev/null" ); } fvwm-2.6.7/modules/FvwmCommand/scripts/focus-Netscape.pl0000755000175700017570000000477212673746443020272 00000000000000#! xPERLx # FvwmCommand script # Written by Toshi Isogai # # 1. auto focus Netscape dialog when opened # 2. move download/upload window to right edge of the screen # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # screen width if( `xwininfo -root` =~ /Width: (\d+)/ ) { $SW = $1; }else{ # some resonable number if xwininfo doesn't work $SW = 1024; } # start a dedicated server $fifo = "$ENV{'HOME'}/.FCMfocus"; system( "FvwmCommand 'FvwmCommandS $fifo'"); #for slow machine select(undef,undef,undef,1); # we need this to run this script in background job $SIG{'TTIN'} = "IGNORE"; # start monitoring (-m option ) all fvwm transaction (-i3 option ) open( FCM, "FvwmCommand -f $fifo -m -i3 |" ) || die "FCM $fifo"; # send command through the new fifo which is "$fifo" + "C" open( FCC, ">${fifo}C" ) || die "FCC $fifo" ; # appearantly, it has be unbuffered select( FCC ); $| = 1; select( STDOUT ); $| = 1; LOOP1: while( ) { if( /^(0x[\da-f]+) add/ ) { $id = $1; while( ) { # keep window frame if( /^$id frame\s+x -?\d+, y (-?\d+), width (\d+)/ ) { $y = $1; $width = $2; # search for class line }elsif( /^$id class/ ) { if( !/\sNetscape/ ) { # not Netscape last; } # the next line should be resource line $_ = ; # resource line tells what the window is if( /^$id resource/ ) { # search for Netscape popups if( /\s+\w+popup/ ) { # fvwm doesn't like commands from modules too fast select(undef,undef,undef, 0.4 ); # focus it print FCC "windowid $id focus\n"; } # search for Netscape download or upload window elsif( /\s+(Down|Up)load/ ) { select(undef,undef,undef, 0.4 ); # move to the right edge, keep the whole window in screen $x = $SW - $width; print FCC "windowid $id move ${x}p ${y}p\n"; } last; } } } } } print "end\n"; fvwm-2.6.7/modules/FvwmCommand/scripts/push-away.pl0000755000175700017570000001123312673746443017317 00000000000000#! xPERLx # FvwmCommand script # Written by Toshi Isogai # # push-away # push other windows back when they overlap # usage: push-away # direction - direction (down,up,left,right) to push away # window name - windows to be protected, name can be regular expression # icons are ignored # 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., 675 Mass Ave, Cambridge, MA 02139, USA. $Dir = shift; $Wn = shift; if( $Dir =~ /down/i ) { $Dir = 1; }elsif( $Dir =~ /up/i ) { $Dir = 2; }elsif( $Dir =~ /left/i ) { $Dir = 3; }elsif( $Dir =~ /right/i ) { $Dir = 4; } if( $Dir == 0 || $Wn eq '' ) { print STDERR "push other windows back when they overlap\n"; print STDERR "usage: push-away \n"; print STDERR " direction - direction (down,up,left,right) to push away\n"; print STDERR " window name - windows to be protected\n"; print STDERR " name can be regular expression\n"; exit(1); } # start a dedicated server $fifo = "$ENV{'HOME'}/.FCMpb"; system( "FvwmCommand 'FvwmCommandS $fifo'"); # larger number for slow machine select(undef,undef,undef,0.5); # we need this to run this script in background job $SIG{'TTIN'} = "IGNORE"; # start monitoring (-m option ) all fvwm transaction (-i3 option ) open( FCM, "FvwmCommand -f $fifo -m -i3 |" ) || die "FCM $fifo"; # send command through the new fifo which is "$fifo" + "C" open( FCC, ">${fifo}C" ) || die "FCC $fifo" ; # non blocking outputs select( FCC ); $| = 1; select( STDOUT ); $| = 1; # some delay for slow one select(undef,undef,undef,0.1); print FCC "send_windowlist\n"; # yet some more delay for slow one select(undef,undef,undef,0.1); $endlist = 0; while( ) { if( /^(0x\S+) frame\s+x (-?\d+), y (-?\d+), width (\d+), height (\d+)/ ) { $id = $1; $Config{$id}{'x'} = $2; $Config{$id}{'y'} = $3; $Config{$id}{'w'} = $4; $Config{$id}{'h'} = $5; next if ! $endlist ; # move other windows if necessary if( $Config{$id}{'protect'} ) { foreach $w (keys %Config) { if( $id ne $w ) { move_if_overlap( $w, $id ); } } }else{ foreach $w (keys %Config) { if( $Config{$w}{'protect'} ) { move_if_overlap( $id, $w ); } } } }elsif( /^(0x\S+) desktop +(-?\d+)/ ) { $Config{$1}{'desk'} = $2; }elsif( /^(0x\S+) Iconified +(yes|no)/ ) { $Config{$1}{'Iconified'} = $2; }elsif( /^(0x\S+) window +(.*)/ ) { $id = $1; $window = $2; if( $window =~ /$Wn/ ) { $Config{$id}{'protect'} = 1; } }elsif( /end windowlist/ ) { $endlist = 1; foreach $id (keys %Config) { if( $Config{$id}{'protect'} ) { foreach $w (keys %Config) { if( $id ne $w ) { move_if_overlap( $w, $id ); } } } } }elsif( /^(0x\S+) destroy/ ) { delete $Config{$1}; } } sub move_if_overlap { my($id1, $id2) = @_; my($ov); my($c1xl,$c1xh,$c1yl,$c1yh); my($c2xl,$c2xh,$c2yl,$c2yh); if( $Config{$id1}{'desk'} != $Config{$id2}{'desk'} || $Config{$id1}{'Iconified'} eq 'yes' || $Config{$id2}{'Iconified'} eq 'yes' ) { return; } $ov = 0; $c1xl = $Config{$id1}{'x'}; $c1yl = $Config{$id1}{'y'}; $c1xh = $Config{$id1}{'x'}+$Config{$id1}{'w'}; $c1yh = $Config{$id1}{'y'}+$Config{$id1}{'h'}; $c2xl = $Config{$id2}{'x'}; $c2yl = $Config{$id2}{'y'}; $c2xh = $Config{$id2}{'x'}+$Config{$id2}{'w'}; $c2yh = $Config{$id2}{'y'}+$Config{$id2}{'h'}; if( $c2xl >= $c1xl && $c2xl <= $c1xh || $c2xh >= $c1xl && $c2xh <= $c1xh ) { if($c2yl >= $c1yl && $c2yl <= $c1yh || $c2yh >= $c1yl && $c2yh <= $c1yh ) { $ov = 1; } }elsif( $c1xl >= $c2xl && $c1xl <= $c2xh || $c1xh >= $c2xl && $c1xh <= $c2xh ) { if($c1yl >= $c2yl && $c1yl <= $c2yh || $c1yh >= $c2yl && $c1yh <= $c2yh ) { $ov = 1; } } if( $ov ) { $x = $c1xl; $y = $c1yl; if( $Dir==1 ) { $y = $c2yh+1; }elsif( $Dir==2 ) { $y = $c2yl-($c1yh-$c1yl)-1; }elsif( $Dir==3 ) { $x = $c2xl-($c1xh-$c1xl)-1; }elsif( $Dir==4 ) { $x = $c2xh+1; } print FCC "windowid $id1 move ${x}p ${y}p\n"; # ignore - pixel info is the last info for move while() { last if /^0x\S+ pixel/; } select(undef,undef,undef,0.1); } } fvwm-2.6.7/modules/FvwmCommand/scripts/focus-link.pl0000755000175700017570000004521112673746443017456 00000000000000#! xPERLx # 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., 675 Mass Ave, Cambridge, MA 02139, USA. #### # NAME # focus-link.pl - perl FvwmCommand script #### # SYNOPSIS # focus-link.pl [-v] #### # OPTION # -v show version number and exit. #### # DESCRIPTION # This is a user programmable window focus script. # It requires FvwmCommand version 1.5 or later. # FvwmCommandS must be invoked from fvwm prior to this command. # # This script can be invoked from a shell or from .fvwm2rc. For example. # # AddToFunc "InitFunction" "I" Module FvwmBanner # + "I" Module FvwmPager 0 8 # + "I" Exec xcb -n 4 -l vertical -g 240x180-0+530 & # + "I" Exec sh -c "sleep 2;$HOME/scripts/focus-link.pl & " # # Sleep is used in order to avoid un-necessary reaction during initial # window creation. A shell is invoked to avoid fvwm itself sleeps for # 2 seconds. # # Default behavior is listed below. # In order to change the behavior, modify user_function using user # functions. # 1. When a window is opened up, focus the window and move the pointer # to it. The parent window regains focus when a window is closed. # Parenthood is determined when a window is opened. It is the last # focused window with the same X class. # 2. #1 would not occur to AcroRead opening window. # 3. #1 would not occur when SkipMapping is set and the window is the # only window of its class. # 4. For Netscape find dialog window, addition to #1, resize the window # to 300x150 pixels and move it to East edge of the screen. # Download/upload windows will not be focused nor be in focus link # list. # 5. Move appletviewer to NorthWest corner. # 6. Xterm won't focus back to its parent after closed. # 7. When a window is de-iconified, focus it and move the pointer. # #### # USER FUNCTIONS # These are collection of functions a user can call from programmable # section. # user function description are comments that start with ## # change path if necessary $FVWMCOMMAND = "/usr/X11/lib/X11/fvwm/FvwmCommand"; # if not there, try this if (! -x $FVWMCOMMAND) { $FVWMCOMMAND = "$ENV{HOME}/usr/X11/lib/X11/fvwm/FvwmCommand"; } #********** user configurable function ************************** sub user_function { if (action_was ("add")) { # don't do anything to opening window of acrobat reader return if class_matches ("AcroRead", "splashScreen_popup"); # if skipmapping is specified with 'style' command and # if the window is the first of its class, then don't focus if (window_flag('SkipMapping') && no_parent_window()) { return(); } # don't focus download/upload window. do not put it in focus link list if (class_matches ("Netscape", "(Download|upload)")) { delete_from_list(); return(); } focus_window(); # move Netscape find dialog to edge if (class_matches ("Netscape", "find")) { resize_window ('300p','150p'); # resize before move to be on the edge move_window ("East"); # move_window ('-0p', '-100p'); # just an example } # move appletviewer to corner move_window ("Northwest") if class_matches ("VendorShell", "AWTapp"); # if you don't want move the pointer, comment out the next line warp_to_window (50, 50); # center of the window }elsif (action_was ("destroy")) { #don't focus back to parent if its xterm return if (class_matches ("XTerm")); focus_window (get_parent_window()); # if you don't want move the pointer, comment out the next line warp_to_window (get_parent_window(), 50, 50); #center of window }elsif (action_was ("deiconify")) { focus_window(); }elsif (action_was ("iconify")) { # focus_window (get_parent_window()); } } #********** end of user configurable function ************************** init(); #package FvwmFocusLink; #require Exporter; #@ISA = qw(Exporter); # #@EXPORT = qw( &move_window # &resize_window # &focus_window # &warp_to_window # &class_matches # &window_flag # &resource_matches # &action_was # &get_parent_window # &no_parent_window # &delete_from_list # &init ); # # # user callable functions # ### # move_window [] # or ### # move_window [] # # If is prensent in hex format, then move window. # Otherwise, move the window in question. # # If is present, move window to in percentage of screen. # # If 'p' is appended to or , it specifies in # pixel count. And, if or is lead with '-', # it signifies that pixel count from right or bottom edge. # # If does not exist, must be one of North Northeast East # Southeast South Southwest West Northwest to move window to edge. sub move_window { my (@a) = @_; my ($height, $width, $x, $y, $w, $dir); ($id) = @a; if ($id =~ /^$HEX$/) { shift @a; }else{ $id = $W->{id}; } return undef if ($id eq $NULLWINDOW || $id eq '' || !defined $Window{$id} || defined $Window{$id}{destroy} ); ($dir,$y) = @a; if (defined $y) { $x = $dir; if ($x =~ s/^-(.*)p$/$1/) { ($width) = ($Window{$id}{frame} =~ /width (\d+)/); $x = $SW - $width - $x . "p"; } if ($y =~ s/^-(.*)p$/$1/) { ($height) = ($Window{$id}{frame} =~ /height (\d+)/); $y = $SH - $height - $y . "p"; } send_cmd("windowid $id move $x $y", $id, "^$id $ACTPAIR{frame}"); }else{ ($x,$y,$width,$height) = ($Window{$id}{frame} =~ /x (-?\d+), y (-?\d+), width (\d+), height (\d+)/); if ($dir =~ /[Ee]ast/) { $x = $SW - $width; }elsif ($dir =~ /[Ww]est/) { $x = 0; } if ($dir =~ /[Nn]orth/) { $y = 0; }elsif ($dir =~ /[Ss]outh/) { $y = $SH - $height; } send_cmd("windowid $id move ${x}p ${y}p\n", $id, "^$id $ACTPAIR{frame}"); } !defined $Window{$id}{'destroy'}; } ### # resize_window [] # # Resize window to and in percentage of screen size. # # If is not null, resize . Otherwise resize the # window in question. # # Letter 'p' can be appended to and to specify in # pixel count. sub resize_window { my ($id,$wd,$ht) = @_; if (!defined $ht) { $ht = $wd; $wd = $id; $id = $W->{id}; } return undef if ($id eq $NULLWINDOW || $id eq '' || !defined $Window{$id} || defined $Window{$id}{destroy} ); send_cmd("windowid $id resize $wd $ht\n", $id, "^$id $ACTPAIR{frame}"); !defined $Window{$id}{'destroy'}; } ### # focus_window [] # # If is not null, focus on . # Otherwise, focus on the window in question. sub focus_window { my ($id) = @_; my ($l); if (!defined $id) { $id = $W->{id}; } return undef if ($id eq $NULLWINDOW || $id eq '' || !defined $Window{$id} || defined $Window{$id}{destroy} ); send_cmd("windowid $id focus\n"); keep_last_focused ($id); !defined $Window{$id}{'destroy'}; } ### # warp_to_window [] [ ] # # Move pointer to window. # # If is a window id, warp to . # Otherwise, warp to the window in question. # # If and are present, warp to and percentage of window # size down and in from the upper left hand corner. # # Letter 'p' can be appended to and to specify in pixel # count. sub warp_to_window { my (@a) = @_; my ($id) = @a; if ($id !~ /^$HEX$/) { $id = $W->{id}; }else{ shift @a; } return undef if ($id eq $NULLWINDOW || $id eq '' || !defined $Window{$id} || defined $Window{$id}{destroy} ); my ($x, $y) = @a; # ensure both exists or none if (!defined $x || !defined $y) { $x = $y = ''; } send_cmd ("windowid $id WarpToWindow $x $y"); !defined $Window{$id}{'destroy'}; } ### # class_matches [] # # Check if window class and optional resource match. # # If arg1 is present, and if class matches with and resource # matches with , then return 1. # # If arg1 is not present, and if class matches with then # return 1. # Otherwise, return null. sub class_matches { my($c,$r) = @_; if (defined $r) { return $W->{class} =~ /$c/ && $W->{resource} =~ /$r/; } return $W->{class} =~ /$c/; } ### # window_flag [] # # Return 1 if is true in the window in question. # If is not null, check on . Otherwise check on the # window in question. # must be a exact match to one of these: # # StartIconic # OnTop # Sticky # WindowListSkip # SuppressIcon # NoiconTitle # Lenience # StickyIcon # CirculateSkipIcon # CirculateSkip # ClickToFocus # SloppyFocus # SkipMapping # Handles # Title # Mapped # Iconified # Transient # Visible # IconOurs # PixmapOurs # ShapedIcon # Maximized # WmTakeFocus # WmDeleteWindow # IconMoved # IconUnmapped # MapPending # HintOverride # MWMButtons # MWMBorders sub window_flag { my ($id, $f) = @_; if (!defined $f) { $f = $id; $id = $W->{id}; } return undef if ($id eq $NULLWINDOW || $id eq ''); return $Window{$id}{$f} eq 'yes'; } ### # resource_matches # Check if window resource matches pattern . # If it matches, return 1. # Otherwise return null. sub resource_matches { my($r) = @_; return $W->{resource} =~ /$r/; } ### # action_was # Check if was taken place. # # must be a exact match to one of these: # # new page # new desk # add # raise # lower # focus change # destroy # iconify # deiconify # windowshade # dewindowshade # end windowlist # icon location # end configinfo # string sub action_was { my ($act) = @_; return $W->{act} eq $act; } ### # get_parent_window [] # # Return parent window id. # # If is not null, check on . Otherwise check on the # window in question. sub get_parent_window { my ($id) = @_; if (!defined $id) { $id = $W->{id}; } return $NULLWINDOW if ($id eq $NULLWINDOW || $id eq '' || !defined $Window{$id} ); if (defined $Window{$id}{parent}) { $Window{$id}{parent}; }else{ $NULLWINDOW; # must be an orphan } } ### # no_parent_window [] # # Return 1 if no parent window exits. # # If is not null, check on . Otherwise check on the # window in question. sub no_parent_window { return get_parent_window(@_) eq $NULLWINDOW; } ### # delete_from_list # # Delete the window from link list sub delete_from_list { my ($id); my ($f, $i); return if $W->{id} eq $NULLWINDOW || $W->{id} eq ''; $id = $W->{id}; $f = $Focus{$W->{class}}; foreach $i (0..1) { if ($f->[$i] eq $id) { $f->[$i] = $NULLWINDOW; } } # adopt orphans foreach $i (keys %Window) { if ($Window{$i}{parent} eq $id) { # avoid being parent of itself if ($Window{$id}{parent} ne $i) { $Window{$i}{parent} = $Window{$id}{parent}; }else{ $Window{$i}{parent} = $NULLWINDOW; } } } undef %{$Window{$id}}; delete $Window{$id}; } # # Supporting routines # # add_to_list # Add the window to link list. # Link points back to the last focused window among the same class sub add_to_list { return if ( $W->{id} eq '' || $W->{id} eq $NULLWINDOW); if (!defined @{$Focus{$W->{class}}}) { # no parent listed $W->{parent} = $NULLWINDOW; $Focus{$W->{class}}[0] = $NULLWINDOW; }else{ $W->{parent} = $Focus{$W->{class}}[0]; # can't be parent of itself if ($W->{parent} eq $W->{id}) { $W->{parent} = $Focus{$W->{class}}[1]; if ($W->{parent} eq $W->{id}) { $W->{parent} = $NULLWINDOW; } } } } # Send command # Optionally wait for a keyword to come back sub send_cmd { my($cmd,$id,$key)=@_; my($cid); $cmd =~ s/\n*$/\n/; # ensure 1 cr at eol # ensure not to send command for window already destroyed if ($cmd =~ /^windowid ($HEX)/) { $cid = $1; return if ($cid eq $NULLWINDOW || $cid eq '' || !defined $Window{$cid} || defined $Window{$cid}{destory} ); } print FCC $cmd; print STDERR $cmd if $Debug & 2; # if specified wait for the keyword if (defined $key) { read_message($id,$key); } } # Wait until action defined in $STATUS occure, then call process. # If a window focused, keep in focus list as the last window # among the class. # Create current window info from lines leaded with the same id # number. sub next_action { my ($act, $id); read_message(); undef ($id); ($act) = /^\s+(\w+(\s\w+)?)/; # such as "new page" if (!$act) { ($id, $act) = (/^($HEX) ($STATUS)/); } #undef $W; if ($id ne '') { if ($act eq 'add') { # create new window info $Window{"$id"} = {id=>"$id"}; } $W = $Window{"$id"}; if (defined $ACTPAIR{$act}) { # multi line action read_message($id, "$id $ACTPAIR{$act}"); } } else { $W = {}; } $W->{act} = $act; } # read message fifo or stack # if $id is defined and the message is not for $id then # push it on to the stack and read it again # if $key is also defined, loop until $key is matched sub read_message { my ($id,$key) = @_; my ($sk); $sk = 0; LOOP_ID: { do { if ($sk==0 && $#Message >= 0) { $_ = shift (@Message); }else{ $_ = ; if (/^$/ && eof(FCM)) { eof_quit() } } } while (/^\s*$/); if (/^($HEX) ($STATUS)\s*(.*)/ && $1 ne $NULLWINDOW) { $Window{$1}{$2} = $3; if ($2 eq 'class') { $Window{$1}{id} = $1; $Window{$1}{parent} = $NULLWINDOW; push (@{$Focus{$3}}, $1); } } # for $id only if ($id ne '') { if (!/^$id/) { push (@Message,$_); $sk = 1; # don't read from @Message redo LOOP_ID; } return undef if !defined $Window{$id}; return undef if defined $Window{$id}{destroy}; } # wait for keyword if (defined $key && !/$key/) { $sk = 1; redo LOOP_ID; } } } # Keep the last 2 focused windows of each class. # This allows focus_window and add_to_list to be any order sub keep_last_focused { my ($id) = @_; my ($l); return undef if ($id eq '' || $id eq $NULLWINDOW || !defined $Window{$id} || defined $Window{$id}{destroy} ); # consider for cases that Focus is not defined yet if (!defined $Focus{$Window{$id}{class}}) { @{$Focus{$Window{$id}{class}}} = ($NULLWINDOW); } $l = $Focus{$Window{$id}{class}}; if ($l->[0] ne $id) { # only if changed unshift (@$l, $id); splice (@$l,2); } } sub kill_server { send_cmd ("killme"); # kill FvwmCommandS close (FCM); close (FCC); } # error. quit. sub eof_quit { print STDERR "FCM EOF "; exit 1; } # signal handler sub sig_quit { my($sig) = @_; print STDERR "signal $sig\n"; exit 2; } # # debug # # print window list sub print_list { my($k, $w); foreach $k (keys %Window) { $w = $Window{$k}; print (STDERR "id $w->{id} parent $w->{parent} " , "class $w->{class} \tresource $w->{resource}\n"); } print STDERR "\n"; } # print the current list of parents for each class sub print_focused_list { my ($k); local($,); $, = ";"; foreach $k (keys %Focus) { print (STDERR "class $k parents @{$Focus{$k}}\n"); } print STDERR "\n"; } # # initialize # setup new fifos # get screen size - to move # get window list # # debug option -d # 1 to print window info # 2 to print command sent # 4 to print focused window list # 8 to print action sub init { my ($count, $type); $Debug = 0; if ($ARGV[0] =~ /^-v/) { print STDERR "focus-link.pl version 2.0\n"; exit; } if ($ARGV[0] =~ /^-d(\d+)/) { $Debug = $1; shift @ARGV; } $SIG{'TTIN'} = "IGNORE"; $SIG{'TTOUT'} = "IGNORE"; $SIG{'QUIT'} = "sig_quit"; $SIG{'INT'} = "sig_quit"; $SIG{'HUP'} = "sig_quit"; $SIG{'PIPE'} = "sig_quit"; $STATUS = '(?:\w+(?:\s\w+)?)'; #status to be captured # matching pair for some action %ACTPAIR = ('add'=>'map', 'deiconify'=>'map', 'iconify'=>'lower', 'frame'=>'pixel' ); $HEX = '0x[\da-f]+'; #for regex $NULLWINDOW = '0x00000000'; # root or invalid window id $FIFO = "$ENV{'HOME'}/.FCMfocus"; # screen width if( `xwininfo -root` =~ /Width: (\d+)\s+Height: (\d+)/ ) { $SW = $1; $SH = $2; }else{ # some resonable number if xwininfo doesn't work $SW = 1024; $SH = 786; } # start a dedicated server # start a client monitoring (-m option ) all fvwm transaction (-i3 option ) # unlinking and verifying M FIFO ensures that new FvwmCommand is running unlink( "${FIFO}M" ); open( FCM, "$main::FVWMCOMMAND -S $FIFO -f $FIFO -m -i3 5) { die "Can't open ${FIFO}M"; } } # send command through the new fifo which is "$FIFO" + "C" open( FCC, ">${FIFO}C" ) || die "FCC $FIFO" ; # appearantly, it has to be unbuffered select( FCC ); $| = 1; select( STDOUT ); $| = 1; %Focus = (); # last focused windows for each class @Message = (); # message queue %Window = (); #get current screen info send_cmd("Send_WindowList\n"); # while() { # last if /^end windowlist/; # # # create window list # if (/^($HEX) ($STATUS)\s*(.*)/) { # if ($1 ne $NULLWINDOW) { # $Window{$1}{$2} = $3; # # make focused window list # if ($2 eq 'class') { # $Window{$1}{id} = $1; # $Window{$1}{parent} = $NULLWINDOW; # push (@{$Focus{$3}}, $1); # } # } # } # } print_list() if ($Debug & 1); print_focused_list() if ($Debug & 4); main_loop(); } sub main_loop { while (1) { next_action (); $Window{$W->{id}} = $W if $W->{id} ne ''; add_to_list() if action_was("add"); print STDERR "Action $W->{act} $W->{id}\n" if $Debug & 8; main::user_function(); if ($W->{act} eq 'destroy') { delete_from_list(); } if ($W->{act} eq 'focus change') { keep_last_focused ($W->{id}); } print_list() if ($Debug & 1 && !action_was("focus change")) ; print_focused_list() if ($Debug & 4 && !action_was("focus change")); } } END { kill_server(); print STDERR "end\n"; } 1; #### # SEE ALSO # FvwmCommand #### # AUTHOR # Toshi Isogai isogai@ucsub.colorado.edu fvwm-2.6.7/modules/FvwmCommand/scripts/test1.pl0000755000175700017570000000166512673746443016451 00000000000000#! xPERLx # arg1 t to invoke FvwmTalk # td to kill FvwmTalk # none to move windows # 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., 675 Mass Ave, Cambridge, MA 02139, USA. use FvwmCommand; if( $ARGV[0] eq 't' ) { Desk ( 0,1); GotoPage (1, 1); Module (FvwmTalk); }elsif( $ARGV[0] eq 'td' ) { KillModule (FvwmTalk); }else { Move ; } fvwm-2.6.7/modules/FvwmCommand/scripts/ex-grpmv.pl0000755000175700017570000000507512673746443017155 00000000000000#! xPERLx # FvwmCommand example - move a group of windows # 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., 675 Mass Ave, Cambridge, MA 02139, USA. ask(); open( FCM, "FvwmCommand -m -i3 |" ) || die "$! FvwmCommand"; open( FCC, ">$ENV{'HOME'}/.FvwmCommandC" ) || die "FCC"; select( FCC ); $| = 1; select( STDOUT ); $| = 1; while( ) { if( /^0x(\S+) frame +x (\d+), y (\d+)/ ) { # check if a member window is moved ($id,$x,$y) = ($1,$2,$3); if( defined $Config{$id} ) { foreach $w (keys %Config) { $newx = $x + $Config{$w}{'x'}-$Config{$id}{'x'}; $newy = $y + $Config{$w}{'y'}-$Config{$id}{'y'}; if( $newx < 0 ) { $newx = 0; } if( $newy < 0 ) { $newy = 0; } print FCC "windowid 0x$w move ${newx}p ${newy}p\n"; # ignore - pixel info is the last info for move while() { last if /^0x$w pixel/; } select(undef,undef,undef,0.1); } } } } sub ask { my($k,$c,$w, $mark); # list up windows open( FCM, "FvwmCommand -i2 send_windowlist |" ) || die "$! FvwmCommand"; while( ) { if( /^0x(\S+) (id|window) +(.*)/ ) { $Config{$1}{$2} = $3; }elsif( /^0x(\S+) frame +x (\d+), y (\d+)/ ) { $Config{$1}{'x'} = $2; $Config{$1}{'y'} = $3; } } close( FCM ); $k = 'a'; foreach $w (keys %Config) { $win{$k++} = $w; $Config{$w}{'grp'} = 0; } while(1) { print "\nWhich windwow to group (* for all, ENTER to Start)?\n"; foreach $k (keys %win) { $mark = $Config{$win{$k}}{'grp'} ? 'X':' '; print "($k) ($mark) $Config{$win{$k}}{'window'}\n"; } system "stty -icanon min 1 time 0"; $c = getc(); system "stty icanon"; if( $c eq '*' ) { foreach(keys %win) { $Config{$_}{'grp'} = 1; } }elsif( $c eq "\n" ) { last; }elsif( !grep( /$c/,keys %win) ) { print "\aUndefine process\n"; }else{ $Config{$win{$c}}{'grp'} = ! $Config{$win{$c}}{'grp'}; } } print "Group move on effect\n"; foreach $w (keys %Config) { delete $Config{$w} if $Config{$w}{'grp'}!=1; } } fvwm-2.6.7/modules/FvwmCommand/scripts/focus-link.10000644000175700017570000001110412673746443017172 00000000000000.TH focus-link.pl 1 .SH NAME focus-link.pl - perl FvwmCommand script .SH SYNOPSIS focus-link.pl [-v] .SH OPTION -v show version number and exit. .SH DESCRIPTION This is a user programmable window focus script. It requires FvwmCommand version 1.5 or later. FvwmCommandS must be invoked from fvwm prior to this command. This script can be invoked from a shell or from .fvwm2rc. For example. AddToFunc "InitFunction" + "I" Exec exec xcb -n 4 -l vertical -g 240x180-0+530 + "I" Exec sleep 2; $HOME/scripts/focus-link.pl Sleep is used in order to avoid un-necessary reaction during initial window creation. Note, fvwm itself continues to run during these 2 seconds. Default behavior is listed below. In order to change the behavior, modify user_function using user functions. .IP 1. When a window is opened up, focus the window and move the pointer to it. The parent window regains focus when a window is closed. Parenthood is determined when a window is opened. It is the last focused window with the same X class. .IP 2. #1 would not occur to AcroRead opening window. .IP 3. #1 would not occur when SkipMapping is set and the window is the only window of its class. .IP 4. For Netscape find dialog window, addition to #1, resize the window to 300x150 pixels and move it to East edge of the screen. Download/upload windows will not be focused nor be in focus link list. .IP 5. Move appletviewer to NorthWest corner. .IP 6. Xterm won't focus back to its parent after closed. .IP 7. When a window is de-iconified, focus it and move the pointer. .SH USER FUNCTIONS These are collection of functions a user can call from programmable section. .SS move_window [] or .SS move_window [] If is prensent in hex format, then move window. Otherwise, move the window in question. If is present, move window to in percentage of screen. If 'p' is appended to or , it specifies in pixel count. And, if or is lead with '-', it signifies that pixel count from right or bottom edge. If does not exist, must be one of North Northeast East Southeast South Southwest West Northwest to move window to edge. .SS resize_window [] Resize window to and in percentage of screen size. If is not null, resize . Otherwise resize the window in question. Letter 'p' can be appended to and to specify in pixel count. .SS focus_window [] If is not null, focus on . Otherwise, focus on the window in question. .SS warp_to_window [] [ ] Move pointer to window. If is a window id, warp to . Otherwise, warp to the window in question. If and are present, warp to and percentage of window size down and in from the upper left hand corner. Letter 'p' can be appended to and to specify in pixel count. .SS class_matches [] Check if window class and optional resource match. If arg1 is present, and if class matches with and resource matches with , then return 1. If arg1 is not present, and if class matches with then return 1. Otherwise, return null. .SS window_flag [] Return 1 if is true in the window in question. If is not null, check on . Otherwise check on the window in question. must be a exact match to one of these: StartIconic OnTop Sticky WindowListSkip SuppressIcon NoiconTitle Lenience StickyIcon CirculateSkipIcon CirculateSkip ClickToFocus SloppyFocus SkipMapping Handles Title Mapped Iconified Transient Visible IconOurs PixmapOurs ShapedIcon Maximized WmTakeFocus WmDeleteWindow IconMoved IconUnmapped MapPending HintOverride MWMButtons MWMBorders .SS resource_matches Check if window resource matches pattern . If it matches, return 1. Otherwise return null. .SS action_was Check if was taken place. must be a exact match to one of these: new page new desk add raise lower focus change destroy iconify deiconify windowshade dewindowshade end windowlist icon location end configinfo string .SS get_parent_window [] Return parent window id. If is not null, check on . Otherwise check on the window in question. .SS no_parent_window [] Return 1 if no parent window exits. If is not null, check on . Otherwise check on the window in question. .SS delete_from_list Delete the window from link list .SH SEE ALSO FvwmCommand .SH AUTHOR Toshi Isogai isogai@ucsub.colorado.edu fvwm-2.6.7/modules/FvwmCommand/FvwmCommand.c0000644000175700017570000005452113001406607015720 00000000000000/* -*-c-*- */ /* * Fvwm command input interface. * * Copyright 1998, Toshi Isogai. * Use this program at your own risk. * Permission to use this program for any purpose is given, * as long as the copyright is kept intact. * */ /* 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "FvwmCommand.h" #include "libs/fvwmsignal.h" #include "libs/fvwmlib.h" #define MYNAME "FvwmCommand" static int Fdr, Fdw; /* file discriptor for fifo */ static int Fdrun; /* file discriptor for run file */ static char *Fr_name = NULL; static fd_set fdset; static struct timeval Tv; static int Opt_reply; /* wait for replay */ static int Opt_monitor; static int Opt_stdin; static int Opt_info; static int Opt_Serv; static int Opt_flags; volatile sig_atomic_t Bg; /* FvwmCommand in background */ void err_msg( const char *msg ); void err_quit( const char *msg ); void sendit( char *cmd ); void receive( void ); static RETSIGTYPE sig_ttin(int); static RETSIGTYPE sig_quit(int); void usage(void); int read_f(int fd, char *p, int len); void close_fifos(void); void process_message( void ) ; void list( unsigned long *body, char *) ; void list_configure(unsigned long *body); void list_focus_change(unsigned long *body) ; void list_header(unsigned long *body, char *) ; void list_icon_loc(unsigned long *body) ; void list_iconify(unsigned long *body); void list_mini_icon(unsigned long *body) ; void list_new_desk(unsigned long *body) ; void list_new_page(unsigned long *body) ; void list_string (char *str); void spawn_child( void ); /* * * send command to and receive message from the server * */ int main ( int argc, char *argv[]) { char cmd[MAX_MODULE_INPUT_TEXT_LEN + 1]; char *f_stem, *fc_name, *fm_name; char *sf_stem; char *s; int i; int opt; int ncnt; int count; int Rc; struct timeval tv2; extern char *optarg; extern int optind; #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); #ifdef SA_RESTART sigact.sa_flags = SA_RESTART; #else sigact.sa_flags = 0; #endif sigact.sa_handler = sig_ttin; sigaction(SIGTTIN, &sigact, NULL); sigaction(SIGTTOU, &sigact, NULL); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGTERM); #ifdef SA_INTERRUPT sigact.sa_flags = SA_INTERRUPT; #else sigact.sa_flags = 0; #endif sigact.sa_handler = sig_quit; sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); } #else #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) | sigmask(SIGPIPE)); #endif signal(SIGINT, sig_quit); signal(SIGHUP, sig_quit); signal(SIGQUIT, sig_quit); signal(SIGTERM, sig_quit); signal(SIGPIPE, sig_quit); signal(SIGTTIN, sig_ttin); signal(SIGTTOU, sig_ttin); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGINT, 1); siginterrupt(SIGHUP, 1); siginterrupt(SIGQUIT, 1); siginterrupt(SIGTERM, 1); siginterrupt(SIGPIPE, 1); siginterrupt(SIGTTIN, 0); siginterrupt(SIGTTOU, 0); #endif #endif Opt_reply = 0; Opt_info = -1; f_stem = NULL; sf_stem = NULL; Opt_monitor = 0; Opt_stdin = 0; Opt_Serv = 0; Opt_flags = 2; Tv.tv_sec = 0; Tv.tv_usec = 500000; Rc = 0; Bg = 0; while( (opt = getopt( argc, argv, "S:hvF:f:w:i:rmc" )) != EOF ) { switch(opt) { case 'h': usage(); exit(0); break; case 'f': f_stem = optarg; break; case 'F': Opt_flags = atoi (optarg); break; case 'S': sf_stem = optarg; Opt_Serv = 1; break; case 'i': Opt_info = atoi( optarg ); break; case 'v': printf("%s %s\n", MYNAME, VERSION ); exit(0); case 'w': Tv.tv_usec = atoi( optarg ) % 1000000; Tv.tv_sec = atoi( optarg ) / 1000000; break; case 'm': Opt_monitor = 1; break; case 'r': Opt_reply = 1; break; case 'c': Opt_stdin = 1; break; case '?': exit(3); } } if( f_stem == NULL ) { if ((f_stem = fifos_get_default_name()) == NULL) { fprintf (stderr, "\n%s can't decide on fifo-name. " "Make sure that $FVWM_USERDIR is set.\n", MYNAME ); exit(1); } } /* create 2 fifos */ fm_name = safemalloc( strlen(f_stem) + 2 ); strcpy(fm_name,f_stem); strcat(fm_name, "M"); fc_name = safemalloc( strlen(f_stem) + 2 ); strcpy(fc_name,f_stem); strcat(fc_name, "C"); s = safemalloc( strlen(f_stem) + 2 ); strcpy(s,f_stem); strcat(s, "R"); Fdrun = open(s, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600); if (Fdrun < 0) { FILE *f; if ((f = fopen (s,"r" )) != NULL) { char *p; *cmd = 0; p = fgets(cmd, 20, f); (void)p; fclose(f); fprintf (stderr, "\nFvwmCommand lock file %sR is detected. " "This may indicate another FvwmCommand is running. " "It appears to be running under process ID:\n%s\n", f_stem, (*cmd) ? cmd : "(unknown)" ); fprintf (stderr, "You may either kill the process or run FvwmCommand " "with another FIFO set using option -S and -f. " "If the process doesn't exist, simply remove file:\n%sR\n\n", f_stem); exit(1); } else { err_quit ("writing lock file"); } } Fr_name = s; if( Opt_Serv ) { int n; sprintf (cmd,"%s '%sS %s'", argv[0], MYNAME, sf_stem); n = system (cmd); (void)n; } { char buf[64]; int n; sprintf(buf, "%d\n", (int)getpid()); n = write(Fdrun, buf, strlen(buf)); (void)n; close(Fdrun); } Fdr = Fdw = -1; count = 0; while ((Fdr=open (fm_name, O_RDONLY | O_NOFOLLOW)) < 0) { if (count++>5) { err_quit ("opening message fifo"); } sleep(1); } count = 0; while ((Fdw=open (fc_name, O_WRONLY | O_NOFOLLOW)) < 0) { if (count++>2) { err_quit ("opening command fifo"); } sleep(1); } i = optind; if (Opt_stdin) { while (fgets(cmd, MAX_MODULE_INPUT_TEXT_LEN - 1, stdin)) { sendit(cmd); } } else if( Opt_monitor ) { /* test if its stdin is closed for coprocess */ tv2.tv_sec = 0; tv2.tv_usec = 5; FD_ZERO(&fdset); FD_SET(STDIN_FILENO, &fdset); ncnt = fvwmSelect(FD_SETSIZE, &fdset, 0, 0, &tv2); if( ncnt && (fgets( cmd, 1, stdin )==0 || cmd[0] == 0)) { Bg = 1; } /* line buffer stdout for coprocess */ setvbuf( stdout, NULL, _IOLBF, 0); /* send arguments first */ for( ;i < argc; i++ ) { strncpy( cmd, argv[i], MAX_MODULE_INPUT_TEXT_LEN - 1 ); sendit( cmd ); } while( !isTerminated ) { FD_ZERO(&fdset); FD_SET(Fdr, &fdset); if( Bg == 0 ) { FD_SET(STDIN_FILENO, &fdset); } ncnt = fvwmSelect(FD_SETSIZE, &fdset, 0, 0, NULL); /* message from fvwm */ if (FD_ISSET(Fdr, &fdset)) { process_message(); } if( Bg == 0 ) { /* command input */ if( FD_ISSET(STDIN_FILENO, &fdset) ) { if( fgets( cmd, MAX_MODULE_INPUT_TEXT_LEN - 1, stdin ) == 0 ) { if( Bg == 0 ) { /* other than SIGTTIN */ break; } continue; } sendit( cmd ); } } } } else { for( ;i < argc; i++ ) { strncpy( cmd, argv[i], MAX_MODULE_INPUT_TEXT_LEN - 1 ); sendit( cmd ); if (Opt_info >= 0) receive(); } } close_fifos(); return Rc; } /* * send exit notice and close fifos */ void close_fifos (void) { unlink (Fr_name); close(Fdr); close(Fdw); } /* * signal handlers */ static RETSIGTYPE sig_quit(int sig) { close_fifos(); fvwmSetTerminate(sig); SIGNAL_RETURN; } static RETSIGTYPE sig_ttin(int dummy) { (void)dummy; Bg = 1; signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); SIGNAL_RETURN; } /* * print error message on stderr */ void err_quit( const char *msg ) { fprintf (stderr, "%s ", strerror(errno)); err_msg(msg); close_fifos(); exit(1); } void err_msg( const char *msg ) { fprintf( stderr, "%s error in %s\n", MYNAME , msg ); } /* * add cr to the command and send it */ void sendit( char *cmd ) { int clen; if( cmd[0] != '\0' ) { clen = strlen(cmd); /* add cr */ if( cmd[clen-1] != '\n' ) { strcat(cmd, "\n"); clen++; } if( clen != 1 ) { int n; n = write( Fdw, cmd, clen ); (void)n; } } } void receive(void) { int ncnt; struct timeval tv; if( Opt_reply ) { /* wait indefinitely */ FD_ZERO(&fdset); FD_SET( Fdr, &fdset); ncnt = select(FD_SETSIZE, SELECT_FD_SET_CAST &fdset, 0, 0, NULL); } while (1) { tv.tv_sec = Tv.tv_sec; tv.tv_usec = Tv.tv_usec; FD_ZERO(&fdset); FD_SET(Fdr, &fdset); ncnt = select(FD_SETSIZE, SELECT_FD_SET_CAST &fdset, 0, 0, &tv); if( ncnt < 0 ) { err_quit("receive"); break; } if( ncnt == 0 ) { /* timeout */ break; } if (FD_ISSET(Fdr, &fdset)) { process_message(); } } } /* * print usage */ void usage(void) { fprintf (stderr, "Usage: %s [OPTION] [COMMAND]...\n", MYNAME); fprintf (stderr, "Send commands to fvwm via %sS\n\n", MYNAME); fprintf (stderr, " -c read and send commands from stdin\n" " The COMMAND if any is ignored.\n"); fprintf (stderr, " -S " "invoke another %s server with fifo \n", MYNAME); fprintf (stderr, " -f use fifo to connect to %sS\n", MYNAME); fprintf (stderr, " -i 0 - error only\n" ); fprintf (stderr, " 1 - above and config info (default)\n" ); fprintf (stderr, " 2 - above and static info\n" ); fprintf (stderr, " 3 - above and dynamic info\n" ); fprintf (stderr, " -1 - none (default, much faster)\n" ); fprintf (stderr, " -F 0 - no flag info\n"); fprintf (stderr, " 2 - full flag info (default)\n"); fprintf (stderr, " -m monitor fvwm message transaction\n"); fprintf (stderr, " -r " "wait for a reply (overrides waiting time)\n"); fprintf (stderr, " -v print version number\n"); fprintf (stderr, " -w waiting time for the reponse from fvwm\n"); fprintf (stderr, "\nDefault fifo names are ~/.%sC and ~/.%sM\n", MYNAME, MYNAME); fprintf (stderr, "Default waiting time is 500,000 us\n"); } /* * read fifo */ int read_f(int fd, char *p, int len) { int i, n; for (i=0; i= 1 ) { switch( type ) { case M_WINDOW_NAME: list( body, "window"); break; case M_ICON_NAME: list(body, "icon"); break; case M_RES_CLASS: list(body, "class" ); break; case M_RES_NAME: list(body, "resource"); break; case M_END_WINDOWLIST: list_string("end windowlist"); break; case M_ICON_FILE: list(body, "icon file"); break; case M_ICON_LOCATION: list_icon_loc(body); break; case M_END_CONFIG_INFO: list_string("end configinfo"); break; case M_DEFAULTICON: list(body, "default icon"); break; case M_MINI_ICON: list_mini_icon( body ); break; case M_CONFIG_INFO: printf( "%s\n", (char *)&body[3] ); break; case MX_REPLY: list(body, "reply"); break; default: if( Opt_info >=2 ) { switch(type) { case M_CONFIGURE_WINDOW: list_configure( body); break; case M_STRING: list(body, "string"); break; default: if( Opt_info >= 3 ) { switch( type ) { case M_NEW_PAGE: list_new_page(body); break; case M_NEW_DESK: list_new_desk(body); break; case M_ADD_WINDOW: list_header(body, "add"); list_configure( body); break; case M_RAISE_WINDOW: list_header(body, "raise"); break; case M_LOWER_WINDOW: list_header(body, "lower"); break; case M_FOCUS_CHANGE: list_focus_change( body ); break; case M_DESTROY_WINDOW: list_header(body, "destroy"); break; case M_ICONIFY: list_iconify( body ); break; case M_DEICONIFY: list_header(body, "deiconify"); break; case M_MAP: list_header(body, "map"); break; case M_WINDOWSHADE: list_header(body, "windowshade"); break; case M_DEWINDOWSHADE: list_header(body, "dewindowshade"); break; default: printf("0x%lx type 0x%lx\n", body[0], type ); } } } } } } } /* * * print configuration info * */ void list_configure(unsigned long *body) { struct ConfigWinPacket *cfgpacket = (void *)body; char *grav; printf( "0x%08lx %-20s x %ld, y %ld, width %ld, height %ld\n", cfgpacket->w, "frame", cfgpacket->frame_x, cfgpacket->frame_y, cfgpacket->frame_width, cfgpacket->frame_height ); printf( "0x%08lx %-20s %ld\n" ,cfgpacket->w, "desktop", cfgpacket->desk); /* Oooh, you asked for it... */ if (Opt_flags == 2) { printf( "Packet flags\n" ); printf( "is_sticky_across_pages: %d\n", IS_STICKY_ACROSS_PAGES( cfgpacket ) ); printf( "is_sticky_across_desks: %d\n", IS_STICKY_ACROSS_DESKS( cfgpacket ) ); printf( "has_icon_font: %d\n", HAS_ICON_FONT( cfgpacket ) ); printf( "has_window_font: %d\n", HAS_WINDOW_FONT( cfgpacket ) ); printf( "do_circulate_skip: %d\n", DO_SKIP_CIRCULATE( cfgpacket ) ); printf( "do_circulate_skip_icon: %d\n", DO_SKIP_ICON_CIRCULATE( cfgpacket ) ); printf( "do_circulate_skip_shaded: %d\n", DO_SKIP_SHADED_CIRCULATE( cfgpacket ) ); printf( "do_grab_focus_when_created: %d\n", FP_DO_GRAB_FOCUS( FW_FOCUS_POLICY(cfgpacket) ) ); printf( "do_grab_focus_when_transient_created: %d\n", FP_DO_GRAB_FOCUS_TRANSIENT( FW_FOCUS_POLICY(cfgpacket) ) ); printf( "do_ignore_restack: %d\n", DO_IGNORE_RESTACK( cfgpacket ) ); printf( "do_lower_transient: %d\n", DO_LOWER_TRANSIENT( cfgpacket ) ); printf( "do_not_show_on_map: %d\n", DO_NOT_SHOW_ON_MAP( cfgpacket ) ); printf( "do_not_pass_click_focus_click: %d\n", FP_DO_PASS_FOCUS_CLICK( FW_FOCUS_POLICY(cfgpacket) ) ); printf( "do_raise_transient: %d\n", DO_RAISE_TRANSIENT( cfgpacket ) ); printf( "do_resize_opaque: %d\n", DO_RESIZE_OPAQUE( cfgpacket ) ); printf( "do_shrink_windowshade: %d\n", DO_SHRINK_WINDOWSHADE( cfgpacket ) ); printf( "do_stack_transient_parent: %d\n", DO_STACK_TRANSIENT_PARENT( cfgpacket ) ); printf( "do_window_list_skip: %d\n", DO_SKIP_WINDOW_LIST( cfgpacket ) ); printf( "has_depressable_border: %d\n", HAS_DEPRESSABLE_BORDER( cfgpacket ) ); printf( "has_mwm_border: %d\n", HAS_MWM_BORDER( cfgpacket ) ); printf( "has_mwm_buttons: %d\n", HAS_MWM_BUTTONS( cfgpacket ) ); printf( "has_mwm_override: %d\n", HAS_MWM_OVERRIDE_HINTS( cfgpacket ) ); printf( "has_no_icon_title: %d\n", HAS_NO_ICON_TITLE( cfgpacket ) ); printf( "has_override_size: %d\n", HAS_OVERRIDE_SIZE_HINTS( cfgpacket ) ); printf( "has_stippled_title: %d\n", HAS_STIPPLED_TITLE( cfgpacket ) ); printf( "is_fixed: %d\n", IS_FIXED( cfgpacket ) ); printf( "is_icon_sticky_across_pages: %d\n", IS_ICON_STICKY_ACROSS_PAGES( cfgpacket ) ); printf( "is_icon_sticky_across_desks: %d\n", IS_ICON_STICKY_ACROSS_DESKS( cfgpacket ) ); printf( "is_icon_suppressed: %d\n", IS_ICON_SUPPRESSED( cfgpacket ) ); printf( "is_lenient: %d\n", FP_IS_LENIENT( FW_FOCUS_POLICY(cfgpacket) ) ); printf( "does_wm_delete_window: %d\n", WM_DELETES_WINDOW( cfgpacket ) ); printf( "does_wm_take_focus: %d\n", WM_TAKES_FOCUS( cfgpacket ) ); printf( "do_iconify_after_map: %d\n", DO_ICONIFY_AFTER_MAP( cfgpacket ) ); printf( "do_reuse_destroyed: %d\n", DO_REUSE_DESTROYED( cfgpacket ) ); printf( "has_border: %d\n", !HAS_NO_BORDER( cfgpacket ) ); printf( "has_title: %d\n", HAS_TITLE( cfgpacket ) ); printf( "is_iconify_pending: %d\n", IS_ICONIFY_PENDING( cfgpacket ) ); printf( "is_fully_visible: %d\n", IS_FULLY_VISIBLE( cfgpacket ) ); printf( "is_iconified: %d\n", IS_ICONIFIED( cfgpacket ) ); printf( "is_iconfied_by_parent: %d\n", IS_ICONIFIED_BY_PARENT( cfgpacket ) ); printf( "is_icon_entered: %d\n", IS_ICON_ENTERED( cfgpacket ) ); printf( "is_icon_font_loaded: %d\n", IS_ICON_FONT_LOADED( cfgpacket ) ); printf( "is_icon_moved: %d\n", IS_ICON_MOVED( cfgpacket ) ); printf( "is_icon_ours: %d\n", IS_ICON_OURS( cfgpacket ) ); printf( "is_icon_shaped: %d\n", IS_ICON_SHAPED( cfgpacket ) ); printf( "is_icon_unmapped: %d\n", IS_ICON_UNMAPPED( cfgpacket ) ); printf( "is_mapped: %d\n", IS_MAPPED( cfgpacket ) ); printf( "is_map_pending: %d\n", IS_MAP_PENDING( cfgpacket ) ); printf( "is_maximized: %d\n", IS_MAXIMIZED( cfgpacket ) ); printf( "is_name_changed: %d\n", IS_NAME_CHANGED( cfgpacket ) ); printf( "is_partially_visible: %d\n", IS_PARTIALLY_VISIBLE( cfgpacket ) ); printf( "is_pixmap_ours: %d\n", IS_PIXMAP_OURS( cfgpacket ) ); printf( "is_size_inc_set: %d\n", IS_SIZE_INC_SET( cfgpacket ) ); printf( "is_transient: %d\n", IS_TRANSIENT( cfgpacket ) ); printf( "is_window_drawn_once: %d\n", cfgpacket->flags.is_window_drawn_once ); printf( "is_viewport_moved: %d\n", IS_VIEWPORT_MOVED( cfgpacket ) ); printf( "is_window_being_moved_opaque: %d\n", IS_WINDOW_BEING_MOVED_OPAQUE( cfgpacket ) ); printf( "is_window_font_loaded: %d\n", IS_WINDOW_FONT_LOADED( cfgpacket ) ); printf( "is_window_shaded %d\n", IS_SHADED( cfgpacket ) ); printf( "title_dir: %d\n", GET_TITLE_DIR( cfgpacket ) ); } printf( "0x%08lx %-20s %hd\n", cfgpacket->w, "title height", cfgpacket->title_height); printf( "0x%08lx %-20s %hd\n", cfgpacket->w, "border width", cfgpacket->border_width); printf( "0x%08lx %-20s width %ld, height %ld\n", cfgpacket->w, "base size", cfgpacket->hints_base_width, cfgpacket->hints_base_height); printf( "0x%08lx %-20s width %ld, height %ld\n", cfgpacket->w, "size increment", cfgpacket->hints_width_inc, cfgpacket->hints_height_inc); printf( "0x%08lx %-20s width %ld, height %ld\n", cfgpacket->w, "min size", cfgpacket->hints_min_width, cfgpacket->hints_min_height); printf( "0x%08lx %-20s width %ld, height %ld\n", cfgpacket->w, "max size", cfgpacket->hints_max_width, cfgpacket->hints_max_height); switch(cfgpacket->hints_win_gravity) { case ForgetGravity: grav = "Forget"; break; case NorthWestGravity: grav = "NorthWest"; break; case NorthGravity: grav = "North"; break; case NorthEastGravity: grav = "NorthEast"; break; case WestGravity: grav = "West"; break; case CenterGravity: grav = "Center"; break; case EastGravity: grav = "East"; break; case SouthWestGravity: grav = "SouthWest"; break; case SouthGravity: grav = "South"; break; case SouthEastGravity: grav = "SouthEast"; break; case StaticGravity: grav = "Static"; break; default: grav = "Unknown"; break; } printf( "0x%08lx %-20s %s\n", cfgpacket->w, "gravity", grav); printf( "0x%08lx %-20s text 0x%lx, back 0x%lx\n", cfgpacket->w, "pixel", cfgpacket->TextPixel, cfgpacket->BackPixel); } /* * * print info icon location * */ void list_icon_loc(unsigned long *body) { printf( "0x%08lx %-20s x %ld, y %ld, width %ld, height%ld\n", body[0], "icon location", body[3], body[4], body[5], body[6] ); } /* * * print info mini icon * */ void list_mini_icon(unsigned long *body) { printf( "0x%08lx %-20s width %ld, height %ld, depth %ld\n", body[0], "mini icon",body[5], body[6], body[7] ); } /* * * print info message body[3] * */ void list( unsigned long *body, char *text ) { printf( "0x%08lx %-20s %s\n", body[0], text, (char *)&body[3] ); } /* * * print info new page * */ void list_new_page(unsigned long *body) { printf( " %-20s x %ld, y %ld, desk %ld, max x %ld, max y %ld\n", "new page", body[0], body[1], body[2], body[3], body[4]); } /* * * print info new desk * */ void list_new_desk(unsigned long *body) { printf( " %-20s %ld\n", "new desk", body[0] ); } /* * * print string * */ void list_string (char *str) { printf( "%-20s\n", str ); } /* * * print info header * */ void list_header(unsigned long *body, char *text) { printf("0x%08lx %s\n", body[0], text); } /* * * print info focus change * */ void list_focus_change(unsigned long *body) { printf( "0x%08lx %-20s highlight 0x%lx, foreground 0x%lx, background 0x%lx\n", body[0], "focus change", body[3], body[4], body[5] ); } /* * * print info iconify * */ void list_iconify(unsigned long *body) { printf( "0x%08lx %-20s x %ld, y %ld, width %ld, hight %ld\n", body[0], "iconify", body[3], body[4], body[5], body[6] ); } fvwm-2.6.7/modules/FvwmCommand/Makefile.in0000644000175700017570000010110213010103323015354 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = FvwmCommand$(EXEEXT) module_PROGRAMS = FvwmCommandS$(EXEEXT) subdir = modules/FvwmCommand DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/FvwmCommand.1.in $(top_srcdir)/etc/depcomp README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = FvwmCommand.1 CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(moduledir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(moduledir)" PROGRAMS = $(bin_PROGRAMS) $(module_PROGRAMS) am_FvwmCommand_OBJECTS = FvwmCommand.$(OBJEXT) fifos.$(OBJEXT) FvwmCommand_OBJECTS = $(am_FvwmCommand_OBJECTS) FvwmCommand_LDADD = $(LDADD) am_FvwmCommandS_OBJECTS = FvwmCommandS.$(OBJEXT) fifos.$(OBJEXT) FvwmCommandS_OBJECTS = $(am_FvwmCommandS_OBJECTS) FvwmCommandS_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/etc/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(FvwmCommand_SOURCES) $(FvwmCommandS_SOURCES) DIST_SOURCES = $(FvwmCommand_SOURCES) $(FvwmCommandS_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(module_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_DOMAINS = @ALL_DOMAINS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR_FLAGS = @AR_FLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ Bidi_CFLAGS = @Bidi_CFLAGS@ Bidi_LIBS = @Bidi_LIBS@ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC_COMMANDS = @DOC_COMMANDS@ DOC_COMMANDS_HTML = @DOC_COMMANDS_HTML@ DOC_COMMANDS_XML = @DOC_COMMANDS_XML@ DOC_COMMANDS_XML_PATH = @DOC_COMMANDS_XML_PATH@ DOC_MODULES = @DOC_MODULES@ DOC_MODULES_HTML = @DOC_MODULES_HTML@ DOC_SECTIONS = @DOC_SECTIONS@ DOC_SECTIONS_XML = @DOC_SECTIONS_XML@ DOC_SECTIONS_XML_PATH = @DOC_SECTIONS_XML_PATH@ DUMMYPOFILES = @DUMMYPOFILES@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FC_CFLAGS = @FC_CFLAGS@ FC_CONFIG = @FC_CONFIG@ FC_LIBS = @FC_LIBS@ FRIBIDI_CONFIG = @FRIBIDI_CONFIG@ FT2_CFLAGS = @FT2_CFLAGS@ FT2_CONFIG = @FT2_CONFIG@ FT2_LIBS = @FT2_LIBS@ FVWMALTFTP = @FVWMALTFTP@ FVWMALTFTPDIR = @FVWMALTFTPDIR@ FVWMFTP = @FVWMFTP@ FVWMFTPDIR = @FVWMFTPDIR@ FVWMHOMEPAGE = @FVWMHOMEPAGE@ FVWMLIST = @FVWMLIST@ FVWMNAMELONG = @FVWMNAMELONG@ FVWMSCRIPT_DOMAIN = @FVWMSCRIPT_DOMAIN@ FVWMTASKBAR_DOMAIN = @FVWMTASKBAR_DOMAIN@ FVWMWORKERSLIST = @FVWMWORKERSLIST@ FVWMWORKERSLISTLONG = @FVWMWORKERSLISTLONG@ FVWM_CONFDIR = @FVWM_CONFDIR@ FVWM_CPP = @FVWM_CPP@ FVWM_DATADIR = @FVWM_DATADIR@ FVWM_DOCDIR = @FVWM_DOCDIR@ FVWM_DOMAIN = @FVWM_DOMAIN@ FVWM_IMAGEPATH = @FVWM_IMAGEPATH@ FVWM_MODULEDIR = @FVWM_MODULEDIR@ FVWM_PERLLIB = @FVWM_PERLLIB@ FVWM_PERLLIBDIR = @FVWM_PERLLIBDIR@ GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ IMLIBCONF = @IMLIBCONF@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INST_LINGUAS = @INST_LINGUAS@ ISRELEASED = @ISRELEASED@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LOCALEDIR = @LOCALEDIR@ LOCAL_BUGADDR = @LOCAL_BUGADDR@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANPAGE_PREAMBLE = @MANPAGE_PREAMBLE@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ MSGUNIQ = @MSGUNIQ@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POFILES = @POFILES@ POSUB = @POSUB@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RELDATELONG = @RELDATELONG@ RELDATENUM = @RELDATENUM@ RELDATESHORT = @RELDATESHORT@ REQUIRED_PERL_VERSION = @REQUIRED_PERL_VERSION@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPDATEPOFILES = @UPDATEPOFILES@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ VERSIONINFO = @VERSIONINFO@ XFT_CFLAGS = @XFT_CFLAGS@ XFT_CONFIG = @XFT_CONFIG@ XFT_LIBS = @XFT_LIBS@ XGETTEXT = @XGETTEXT@ XMKMF = @XMKMF@ XSLTPROC = @XSLTPROC@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ Xcursor_CFLAGS = @Xcursor_CFLAGS@ Xcursor_LIBS = @Xcursor_LIBS@ Xft_CFLAGS = @Xft_CFLAGS@ Xft_LIBS = @Xft_LIBS@ Xinerama_CFLAGS = @Xinerama_CFLAGS@ Xinerama_LIBS = @Xinerama_LIBS@ Xrender_CFLAGS = @Xrender_CFLAGS@ Xrender_LIBS = @Xrender_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ iconv_CFLAGS = @iconv_CFLAGS@ iconv_LIBS = @iconv_LIBS@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intl_CFLAGS = @intl_CFLAGS@ intl_LIBS = @intl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ png_CFLAGS = @png_CFLAGS@ png_LIBS = @png_LIBS@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ readline_CFLAGS = @readline_CFLAGS@ readline_LIBS = @readline_LIBS@ rplay_CFLAGS = @rplay_CFLAGS@ rplay_LIBS = @rplay_LIBS@ rsvg_CFLAGS = @rsvg_CFLAGS@ rsvg_LIBS = @rsvg_LIBS@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ stroke_CFLAGS = @stroke_CFLAGS@ stroke_LIBS = @stroke_LIBS@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ with_bidi = @with_bidi@ with_gdkimlib = @with_gdkimlib@ with_gettext = @with_gettext@ with_iconv = @with_iconv@ with_perllib = @with_perllib@ with_png = @with_png@ with_readline = @with_readline@ with_rplay = @with_rplay@ with_rsvg = @with_rsvg@ with_shape = @with_shape@ with_shm = @with_shm@ with_sm = @with_sm@ with_stroke = @with_stroke@ with_xcursor = @with_xcursor@ with_xft = @with_xft@ with_xinerama = @with_xinerama@ with_xpm = @with_xpm@ with_xrender = @with_xrender@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ SUBDIRS = scripts moduledir = @FVWM_MODULEDIR@ module_DATA = FvwmCommand.sh FvwmCommand.pm FvwmCommandS_SOURCES = FvwmCommandS.c FvwmCommand.h fifos.c FvwmCommand_SOURCES = FvwmCommand.c FvwmCommand.h fifos.c CLEANFILES = FvwmCommand.sh FvwmCommand.pm FvwmCommandS_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a FvwmCommand_DEPENDENCIES = $(top_builddir)/libs/libfvwm.a man_MANS = FvwmCommand.1 EXTRA_DIST = $(man_MANS) findcmd.pl LDADD = -L$(top_builddir)/libs -lfvwm # FIXME: # Despite not using X functions explicitly, the code includes # fvwmlib.h, which *does* include X headers and xpm.h! AM_CPPFLAGS = -I$(top_srcdir) $(xpm_CFLAGS) $(Xft_CFLAGS) $(X_CFLAGS) all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign modules/FvwmCommand/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign modules/FvwmCommand/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): FvwmCommand.1: $(top_builddir)/config.status $(srcdir)/FvwmCommand.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) install-modulePROGRAMS: $(module_PROGRAMS) @$(NORMAL_INSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(moduledir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(moduledir)$$dir" || exit $$?; \ } \ ; done uninstall-modulePROGRAMS: @$(NORMAL_UNINSTALL) @list='$(module_PROGRAMS)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(moduledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(moduledir)" && rm -f $$files clean-modulePROGRAMS: -test -z "$(module_PROGRAMS)" || rm -f $(module_PROGRAMS) FvwmCommand$(EXEEXT): $(FvwmCommand_OBJECTS) $(FvwmCommand_DEPENDENCIES) $(EXTRA_FvwmCommand_DEPENDENCIES) @rm -f FvwmCommand$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmCommand_OBJECTS) $(FvwmCommand_LDADD) $(LIBS) FvwmCommandS$(EXEEXT): $(FvwmCommandS_OBJECTS) $(FvwmCommandS_DEPENDENCIES) $(EXTRA_FvwmCommandS_DEPENDENCIES) @rm -f FvwmCommandS$(EXEEXT) $(AM_V_CCLD)$(LINK) $(FvwmCommandS_OBJECTS) $(FvwmCommandS_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FvwmCommandS.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fifos.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-moduleDATA: $(module_DATA) @$(NORMAL_INSTALL) @list='$(module_DATA)'; test -n "$(moduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(moduledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(moduledir)" || exit $$?; \ done uninstall-moduleDATA: @$(NORMAL_UNINSTALL) @list='$(module_DATA)'; test -n "$(moduledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(moduledir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(moduledir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-modulePROGRAMS \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-moduleDATA install-modulePROGRAMS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man1 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-moduleDATA \ uninstall-modulePROGRAMS uninstall-man: uninstall-man1 .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-binPROGRAMS clean-generic \ clean-modulePROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-moduleDATA install-modulePROGRAMS \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 \ uninstall-moduleDATA uninstall-modulePROGRAMS FvwmCommand.sh: findcmd.pl $(top_srcdir)/fvwm/functable.c if test -n "$(PERL)" -a -x "$(PERL)"; then \ $(PERL) $(srcdir)/findcmd.pl $(bindir) -sh \ < $(top_srcdir)/fvwm/functable.c > $@; \ else echo '# Did not find perl during fvwm install' > $@; fi FvwmCommand.pm: findcmd.pl $(top_srcdir)/fvwm/functable.c if test -n "$(PERL)" -a -x "$(PERL)"; then \ $(PERL) $(srcdir)/findcmd.pl $(bindir) \ < $(top_srcdir)/fvwm/functable.c > $@; \ else echo '# Did not find perl during fvwm install' > $@; fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: fvwm-2.6.7/modules/FvwmCommand/FvwmCommand.1.in0000644000175700017570000002703712673746443016270 00000000000000.\" t .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .de EX \"Begin example .ne 5 .if n .sp 1 .if t .sp .5 .nf .in +.25i .. .de EE .fi .in -.25i .if n .sp 1 .if t .sp .5 .. .ta .2i .4i .6i .8i .TH FvwmCommand 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .UC .SH NAME FvwmCommand \- fvwm command external interface .SH SYNOPSIS FvwmCommand [-cmrvw] [-S name] [-i level] [-f name] [-F level] [command...] .SH DESCRIPTION FvwmCommand lets you monitor fvwm transaction and issue fvwm command from a shell command line or scripts. FvwmCommand takes each argument as a fvwm command. Quotes can be used to send commands including spaces. .EX FvwmCommand 'FvwmPager 0 1' .EE .br .SH INVOCATION FvwmCommandS should be spawned once by fvwm, either in .fvwm2rc file, from menu, or from FvwmConsole. From then on, FvwmCommand can be called from a shell or script to execute fvwm commands. From within .fvwm2rc file: .EX Module FvwmCommandS or AddToFunc StartFunction "I" Module FvwmCommandS .EE Then, in script file or from shell: .EX FvwmCommand 'popup Utilities' .EE .SH OPTIONS .IP "\fI-c\fR" 0.4i Informs FvwmCommand to read multiple commands from the standard input instead of the one command specified in the command line arguments. This disables \fI-m\fR or \fI-i\fR. .sp .EX (echo "Exec xload"; echo "Beep") | FvwmCommand -c .EE .IP "\fI-F \fR" 0.4i Specifies the level of fvwm window flags FvwmCommand outputs. .sp .RS .IP 0 0.4i No window flags will be printed. .RE .RS .IP 2 0.4i Full window flags will be printed if information level, -i option, is 2 or 3. .sp .RE .IP "\fI-f \fR" 0.4i Specifies an alternative FIFO set to communicate with a server. The default FIFO set is /var/tmp/FvwmCommand-${DISPLAY}C, in which FvwmCommand..C is used to send commands and FvwmCommand..M is to receive messages. If that path is unusable ${FVWM_USERDIR}/FvwmCommand-${DISPLAY} will be used instead. FvwmCommandS must have been invoked with the same as its first argument prior to FvwmCommand invocation. Alternatively, option -S can be used. Refer option -S. This option -f is useful when a dedicated connection is necessary to run a background job while another connection is kept for interactive use. .IP "\fI-i \fR" Specifies the level of information that FvwmCommand outputs. .sp .RS .IP 0 0.4i Error messages only. .EX FvwmCommand -i0 FvwmBanner .EE will show a banner without any output. On the other hand, .EX FvwmCommand -i 0 foobar .EE will return, .EX [fvwm][executeModule]: <> No such module \'foobar\' in ModulePath '/usr/lib/X11/fvwm' .EE Note that Fvwm doesn't return any error messages in cases like below since 'windowid' itself is a valid command. .sp .EX FvwmCommand -i 0 'windowid foo bar' .EE .IP 1 Errors, replies and window configuration information. This is the default. .EX FvwmCommand send_windowlist .EE Information like below will show up. .EX 0x02000014 window FvwmConsole 0x02000014 icon FvwmConsole 0x02000014 class XTerm 0x02000014 resource FvwmConsole 0x01c00014 window console 0x01c00014 icon console 0x01c00014 class XTerm 0x01c00014 resource console 0x01000003 window Fvwm Pager 0x01000003 icon 0x01000003 class FvwmModule 0x01000003 resource FvwmPager 0x00c0002c window emacs: FvwmCommand.man 0x00c0002c icon FvwmCommand.man 0x00c0002c icon file xemacs.xpm 0x00c0002c class Emacs 0x00c0002c resource emacs end windowlist .EE The first column shows the window ID number, which can be used in 'windowid' command. The second column shows the information types. The last column shows the information contents. If no information is returned, add -w

    Zk  IMrEg n~4겘 e50zoæʥٶ"g B-%,_.Z}N"b6B7zo?dYfFG if(_[Uu4fd558`܇<! 8Bk=U!uJK{L=5cHJP6oΈ.^+6|'n:EI%j4<'QO=gwLp@2pۮMi6c To'5m嶚:-"jS]aA|EIO\9/K_ ;Hڻ ^K?_?*;b<7tF9Yriwo.Rrk;8ZOhBonj Ot;y0`=LR qK@X vͼٲD@+@t0JwO].7xBP]+ovIE7U #~鶍KDɅyR覞|0h8e")D 񁗠M]-5Jr13`jt; 'fdĐK 2)}>|ӧOw'0lEW4V0ٞ =xHLS D vCayc&P#3DAdB^x9!raۺ[,P$ԙ;#^=F#H*oPX{PL½z'6c\]Rh%i@DJYjkM[j2:Q'm,S&ѡ1g2GF1^D"ҴBK)hiL , =><  н)٠wF7;o1";]C;QDH xZ Sg4Mr`M`6)U@dG w`32 ӿgpp7Cy`BF#KKɦ[?G,&5X@r,_5Aykβ{CrZj5 Av2S)̻u::R,C\CȻ{_0P gBj[s4$0Z2~J \*V$62"(X$H:IM1TG ).ШmeYRJ`TLDoc1̙zYGDgF"O hۮ{)%j>ˠ3O_UјeE3ѳ/wwwOOOief )^.W ,2"{w`؎ja,rę9up@ ]D|3j„)ﳨs:^W)5WBȅ{ۉYDie(0*c}VOi63v_lLĊ,1%v2n Or،dS,&Dcd$ c ꓾g3|,$μm&ehLV t??fy1X>/dedzȁ Hpy}Ϳ(,I,iKXМݻٿ/O>P -zRDO*aop;Kq$dZ7@GFfHWljd9;9𲬈*bA 6wa&>ֹG5":xWmx't47F4 @. BLT5x\߼ͻIEr!® F@pD5b!cTUHzRJxqc K%fKkq7oǏ/OM ~__ܻ:3ufjƣ8fDdQAk4vnjxE S$[I2:D50abnflQEURU&̣p;1GM?MQ$颎4N#MB򉏽هY((H=Ntnu.ǣ'/LUfo18QwGD"z^}U- ¦ +&3CU[8Zנ {N$E4 Aw RoF񑈴l{L.(P^]3GJA5Y/ W j\,Jb$d@z 9YdwXrS8^*I2OvG@Tk`#`1YS_;P)tv5Xһ:.b؛7oDҲvAGՎ-Yh~ ,B7`&>E) d>r.t b?Ytpw:4O獅s<٦K]3?cZRfDSU@p5s(f?ϭ&H6 )nf6kXi{(!%ź,WLŽc@Պ3$Z {ﻁ3s)rh9=d<*N浝34g4=sj]APP *HN:~|Cwzt|C̜X9`"#.dnLHjwAcɵ.ڻ)gKepg&.YtUJYkﶮRj)ea."H1ofaBDH+ :*0s!˲ƘNϞ4<J7 @aaHWf)J,HD:wGTUS9^  @a9K@nfJx*c6‚XucaJH T|wz]|ZòTpG]%\ݭ'{qf+R vr6]f{k؜pZ;14.N@˫͌-&$'umPw!fkDaؤgS8t$6N%"L5r76Q t0p>9c3%.̲@h ހH8N.z ]Us0bAit7t"uo0dI) }Mx=""]T>FCD9=8E4{0"1u?a@_Vsp "R^G@"}P:qwb KE-NZ\] 0"6)1"!"f!D!bsTU[ [ھm&L벸Yo-'' F"w&fbFDJ&]C L32"mgf R H,HPqrCi 嚀qRMR-@M{kM6e=s4@HjC. b-ITEFZrYHVֺk>?o#~9bwR=VEF83"`)8 NXfnQ7d̝AȞ;9Wy]OC7%L?4Y# OOObNDn{1[1lOłx$n=g]%RjtbLh0u҈u4Bsfs|&0pfv!|ffkj5ײ{/1sj!"= ѧ.KE}o"޶-޴.%+I|ݮPYHJeEZO<֤"BH<%#w.k,-4sg7Hp-\:?F&s fNuow/d3l=!}Y־꛻w/?ǧOzAr;]u[޾5ǧ` z-ȗeJtI\Xhs1ňu bwfy?ГL3!~03+H1:gcz2*lm">hofTTun|֏z`62twwGėg@Bmn.„B=V\J1S,6SwKFnH I= -$u]믿V3y믿^%O+1"J?,@R<Q&1mww.)y\-{@1aAfhU%" ӋlH+0Z?03T5\պw/cJ"|ݾ;!.25Qݺ ,MMA!:5ZKo;9j7Y+o&c@Gյo?u ئ\7v@:+@ڎT0(P`榐Ėh"|`d[Ȣ9O~7~e}8 ~t:GpTӛ/==_A}ۖZ{_EÙb#10!1wSSCettbr`Pdžָ=Hح=V$UmxUK0ldNl0`<"%7QAԾuY/+1 Ec6, n](&hvV$X{"A .YTC,M ٘Uc€LЬ(!TG8LCe(zVץ1)şEo8dP][ۣ׿r弒6)ON몽_/W5F3p=6\+hfj-ĶqvIH]1}aIuST5Cpq1ƘR6i+; ,iy[[D2v>.a#B"%t]b0Z#(CDDzT5N`t̬ZzWBzԡbA<)|[oD 2-Joj^/WӦ7oZvu󘚂A1E_SpLG@OըY Rq0JKe@9DBQh!bRH)<.Lj\jm] y >ӏߛ!%Oc@H4"D$IPcM;Q~G22Si~7g Ptc^JwwwuiV0#Ϛ+Ls9Kmjx(5TbT~nmq jȺ}o/m窰iX ٬9;tݝ\2T*KWOKww6ќ޼yP>.*RB2܍'^J9˲ӷ_C? }^۾{2'QZԡ\=syO/۟t=v辷mX|>'WW_}?l55z60SS0)l7Gp0Hx<Ѩ/>P܃2!l@f]}C]a66oݹѴ-Z“f)7t}S 7q'&DF t@gomOHRJ㲮;RM5.B"`w_tý~]/e]Hy(J޶ ZWLJxaw7S&D(r:rRܮ̣|Ut8eh밢GFԁQP3a0J D.`i!/8 L}0Q*ĠO#O0b1@`WChKv3rzETdf& ӕo^vGmzn'U!i[<1pϞIݛf_OϟDp{H_~_0_~`?S޴'m6ԇ$춍\|:iXFf&Dj[R/鹵d婮Ry߷(1,4P:ԶDLEjD&wt[ƿ8 &}-[g&;`JˈP@F)9ALYp)*ȈT޿߷g+"~j7mu/}"zv݊apޅRh J]AAaf+mw^q>N0QUY#w%g,q$OjM\~Y"qb ߽SSw@7PB4# !v]bVXp /U3*@ "0 ɤ a.ihu]@xem'$f(cHfN"L.[DFBEҩo=Clx_GS,}f-mdGg"o.ﭜ֯v}v@hw_|5Ͷ_-˲m3K1G.˛_l]UkH wU5Umv>2 /*74(X}Onaj-Kl 988g7y&D"E)Ѿ@y,)K6: x&~+G{8y9aWgDzxv[JDDֲZ)͛7ww-AHԵ-Uw%,@5e(b,RkU37`bR%5̴Lê |J=n"8S)@l$ aRT{swp R(5}ͯ~O>},o>]va^u۷_|q_˧۶mv ,wǹKkϐŤf=E68&6qew氙u/ꇘI.Wfc7:|f#]fV3S#")jDO?]OǏ/K)1{#_fz*u򋯞/A wa1uuRθ,wB\?wRJK]Y!X56:x2f6nߌh4:iS^H͌莫ġ˺İ7IE 7ubK][k[ۣ޵Va0,t,]T }eFC`v0u+~>\6OXs%C&s9oj܂#U"`V'<o KYnmřO+CT D8 g0w 5IB&S0p3׈5#hBE۷*]6UMGvMMm7m!Ju9cpLֵ)4VM=Ef?|}m vF5Wt.,bݻVNf}_APjl]Jښ(|JY!jA RkD,d=#t6133Fi˲ xםEqYi]DL2Xݻwo/B`sADr\||-eÿ^~V*x/fvݕ !!Srʺr:e,g$sflq"C !f@Nzw$&8^*[J:,u=?#.jQ}ݴ so{Kpcv!n#|DGUY"u8x`?F̈ҵZkk 38hmu]}m{Zz;q_¿8juV"([OFeYq2TI辶aHLn@DU4Rdzښ mMwS%buRևtBBk-{/k30"_~rC/)S#sTRVwM5D86P2 AעL3׶!&ӌ - '={Ծg?$m1M$9Heiƅuc 5Ņj벎΅Z֟]wm;r I(/WA|rcA7a)UCpd ]uw3LޙRĥƧNb; ߵ}W풩417\z>߅ $df bÑSY |]N{oEOz)eDZL]Цki~{␤HvW V1!"拯m1 u5^ ey[jUV.DDdߛ gSIx-%)r؆B pla:Yf33h0%v^\CspW5vD즿կ[wz*\+"FFo橔Lo}zz5ہ"mߧUӎpC^F2íh_i]Ç 51pD̢= 힦HRjE")5-,$!Ɗca1Ddn<\1YJ: F`&^)rt00i)eZ{fԪݘR}g03n֑[tEnnRJh=vFS9Zk>[UUF9T0sȇyqP c&}:80ဓzS҇\`9k-=s>;߀pDj͒ࡩI>{ofLr)2>@S 9.73 z8zK4jUuT9A-ݭwծ""Eaoz>J5eZvmmL-@)RG3]MEJ*#2 ?,B&`ǁ-"6.sPt쯼 c:C5o@q4i7daN!Puhf (IaCMMa62(T6=)$kvUc+B{kw-jrwZJ1[4۾wm8zRٝT(\%Z~Gt7.׍0A)@վ֥dxyH)'fXK;vw?=?=~b@*4dkD]жZ辵 W9sU5BU;ei{C/w`jZaz6iK|;tm˲Rb͗eto.-X?=w?=eݙ}C*%w̦o \{pwu0f*9!hf~ SabBqG3aJDp2m^CgaI~<)B;3~S{rqx%qB7SfJJY]ETuCb7ZexR3Egy/z?}۽ѯth8Oi^9 {dPJER*׌ݡ[*Qڴ s0t:Z'xː m40dYLHKYyEmHpݴ`]//R]-&K}~ukqx!9}HV:*s 3cUaJ黔 Ws xAXܓ]TU QYB\/,;3";@˶7$}Y;2y: eVV'"f="I)f!.˲v3p\ҐOnci߷ܷm߷÷ J,,xtu|hx3! >8‡d$zCy RC nXdݗo޼}B!`9>h(|dF]։>'ͬ́yt) 49cpqE&XKڞ&S6HÓ=G 榦>]=3H3Fy!IR.w1Qt0"4NǴ1 ܝI?/=I]*:誝p܍e2 tm۶ HX9,Xm0" d"$2UDrd#ÖEx]jY@Dr>˲z*eSY}zӾ?zPN֚j9mۿ?G ²oЮ}݊poX佷KY OXᩝ(cr1b!ɰ!zN,j,-\a|?e}>Іc7&69E$M7V 6rFcu&Q7hS)1t ,E=+@E@@D[@$i7`fws\dDlnh@ݜzo{dk5p_k4UnB"03JI~ݙ+/'uޑX˲`JXrn #9e]{;.m_`Y I1\!M\>;|ҾkW! .M!C HXmP ^T 3{olfOzff$[&)#(IQ skmau]NVZ ~BN͛, X@/a Kj]+֑ھ]jiNܺ׳)~\>}Bv7Bvb,ruo׮=ޡ VrZdA ܚi7,R}NHUZoPO+qQu=o֮׋2 .!a?,e)"?5~>Y ʘ DmuYD~?m?F[wΌ_c@B}.y+*P7$ iLGƊD$\] p+5LmL#"3;:q*Ea뭃YaA7gf 63uDp1Udڶ<-NR%\bdTO }"2pn,u̺=QqF ɲ%K8iHT%.߶mqlFvV ChS KnKΠ,L> xÂ@Y(zOzQA"BH*#RssXJb}w0LX+׺H|,0_O0z^,u>/Tf$U ծcm""[O1}L=,"i"!(B G^svYϪ8fۘ<qȈ{ u[soRJ1ȱY|ZBbaY 3[ 5:{o>|j}V;S!`Rjee"Wg@뺳P:ͺ\."|"ޡRn%r@ey43bʸm{||r=\.fJLϗgUuX /ꫯKRRXN[?*0Fھawpe"u<]/˲H[ B@`N]WAuiҏ#OtHP{oNex*Ɉ8^,v` u]'@_uS69)%b!(jrk#Ng|:uYN#n=zw/a_57ȩ Sl3"G0q4O{n$/M0 9J-1eg es{]IS~Y˲3Lx]L[I&*bv]~=Sov po~!9[JY# \b !&h΄Ե\ IqpqgߛoI rp8fAFFSve3Uf{A%") )]-Ͻzڷ5kim}ݖZ18dz@)9X /ϼЮ9'Ƥ&͚BZtD-5z3 "Z SI–)]5wU},}sS H8Z!*HR@RFMՁ=r$ZBp2׫#k 3Cʲz.Pv;ҎnjRHq_m^3J݇I[Gr-HTLn5uameHΛXq4 ,pAښ;KxALRc0|j8`qhN5xmWe֛"n{k!j7p05D D@dBGGn۶pzRdnHѮ7tݶg$~M$W&v6U5DdP(Ltq{ Lo/&)B!E3՜U.d')(H$3"^3ճ"bWApꫯT0[CgELTi*uG7X#&MADseV.,zo۶,Ւط1̅8MQOlRΟR3x1R#\gRvE1:i6Wkn N(SŽ΃zDD MjJYp6Qrڹ,`Nb3 39_? 'e,'vL0ue I=DH`a 4 Tf>E@G"H sO`DHYi $OtCfU! 0#2v$Q,T<e{ ^g?nH3Rk[0>(|z!>08H>}j>?}S"T9l=YȌz5.2t't)u@8L63`,!5%b@@.,/ǾV ˲Vj-53K9 ?x2 ,XXDTG.ꧧ/u],TՏdf)FD;lەa2m۷RcjR/ΐKB%qNϹ{81 L@ D4L)#v-o_owQ>ƶmq>L$ϊ^S5iFDA\DUf9U]ZO۠L Yhu _~0y{yu.Ϣ8ŚLҎe rZ.KN=N q;ӂ5s>8{.G\Fz f03Q"3N!"Z'=1Ҷ~sKyԖ]8X) IA~il#ĶZTL%Rz]A$Жog}^4KV53ܭfBEG}0{s)AfC<~&MmDvLon@D`$; VӀC4"L\քI]Kv.me),oo:ZZjDݤ!Ny~d{?جRkk-m۶f]m "eޗ3k+1yݣH)VMwfP4TcY| n4r9keIާZ"p2ac0XryߙpyCK)1I-~+cS$w"AXZs02"UG-K̕ <S͂"\yU576CC0HD<qj5YGHGD,KL޳tS⒄Ðp"s$QD'x#wjĒϪ8vw癈~2 hXs?+ȥTf1\?RJQ߮7~||>"SD?UiA' Hw!fdb(:|!}nLj}Tx2% :j!q nG@I_n>)" c]J6+$@>1djknn:v;'Mvf}舤ƄDB R밀@R 1׶Qi,_W"nk<@63Ҁ)IX/e]/?~6v ڑ%b̘C\{9ať@fbs:fRG "!E"F+ v=3[kfuݶ-Z*Q]HLv; JϲI 킴H)̈9 eik2rm۲wDTT4 :Ydž'_>v%ARO0 *Y-菶G\i-y^8Zҕ}1E܈r2:MlfjZDjnƗR^iw?=<<><B`:ӵ. "=Cz锏ԶZ<|mp"^Is0@bB$-,l `8ScpSbp'pC  A)KZS w&-Da8biPXp337#" @bpQJqSA5ATp7$?weR!)߉n1 %bnhDؑBj(1˼<խ> Hf[_b.<@ Z(1 CB2Ap5Tx0If~-Ͻy1<鳏`:ҁͥw_! q[-l|ʭ_Ē>FNٲ 0y iY]$COFʱ,~rZz"'#[cV"&&& /T!sH$Rsl|Rӯٯ9";!y|p^U- 痗*ێ˲DS#bYR[Zk///P[C@%f) S<>>޶=ٖݫswsMrdUH\9sɏ9刃Mļ.wvw]|]/R$LWf^5rqDd<V)CǺlc!"!] I~3Jz y;APsP#>AZafS()cp$C=ܘY"\fh5/"΍q7pʏ,|ļݦ3.g)oكMo<:I/HZJM(99%pٌ7*L8Tmf!1wy6L @*Re e"><~ͳ\!&cƲ}"x} F}\5$"`ZZ|mj-GΑ3w9cLy E`.lr@"Ez$O:Zw›S~K&h\u)уm|Nl5:zfI%Z8i>SBt:vS#$01(S_& pʥ"-Is {g$dzrpj Jds *yZgA<[mG:>wB+ "pSw7~J3J8+j-HkUPa>nM=.zyv.%c7He}~zڷm7B^#GÄm{Tn//IǐPZrF"4wDyz9*s_ܿ{8NU,&&"rtǢ`M|WmfjVJn۾\.ѻ!D[dvTږДA\޸/O_}!www> r_\V~'fA)U}g}=4"J.xyy飛ڶm:.O@}vG.ijTЎV[T0'c)עinӑ{0%)-F3/, nCG)*xJ]/w*t(\ֻ"S@5sW@8nCg$~}wݒ-Δ2ŠAG!秙Wj SIHGTZt$eWtrۧY3% "01` Ethr)spbJ09* (PDޅ{סD/ϥmj)AD&mO#KDu~2,HMu$ʍ?<34`Ӌ4 3*cjMPTH2hBO L%t@8gDGD6?d.wyCAR-8e4i=ZyD@D0]Aw;F$:*XK\`Dۍ!B9frB"ATfHR*"R[6‚᎘#"ܭڊ1 1T@:a ._^|證@bs ,a"~v3} @,‘9/$$S nz٪<_9Nە R,R[枙" Бk@Lփr2=2? "f1og,Wm-ͨ6"zOҾ<}[OR~NN14|A!1w&q"KGHPK/L0v*Fdfs]4O;/;ir(;Lu&u!p- 1#[wG^jE?~/"KK[r>8Duġ?󷫝`*iKA^{R:'߸{C^uIiJj;/R)N H6OVy1*`s2bR&'fG^vN5܁0˯^p'lyg-"Q\Q17Kf$=AӋ֚);I(2rE@ȔơyDVs,(s#"3>1jPws`Y zݴRp.. WYݶxxnD-GRfFDAB{q8 "c>V1%CFnԖi:CUBOD4 `Mߞ·Zz}2@‰F?3`Fr÷キ.X>z%{⼥sB>tz+g}aFRJ'k<T4S#k G"Ab&\ZCαN2mG]:`),uY{"Lnʇj¾crnRJ[m]®z^մrs qBgpGf0SN)NKGj51<'ދUlN)6@?"󿑂 E!!cR_<-"(̶1O'.mqWJRھS )wSd O]1z; d4:7">]`i>pOǙPXsL#G.R""54e|SszSTㅊ#ܚ76C0w<- J ;hz&l0"  T)QY, n ql03!χ0Ô`D(T #T\K)wwmDk˔f99$ Cnkx df Maic ^ŧzQiLa0ۯ{L`}degnuY˚zYmG/+Ja̳b.R/O3 כ, .ASwU-'>1.1UD,%ߠG}Ք05$邱\"@jn:L=! ɎG*z |y_jfwww1 pi^_kmxV{ܐ:)ɸ S}0zYKnVkA("rx0rn32՞jR "Zk917U:+SU0Nv~;ᙇ 13W1YD?{e:DnFŸ?^FȈj߮/[ߖe"콫wdⱪHQU~HtP,lsIZIGzD>DLO&yY%Q>̼K-`Y.D=u9Vg4%#? .>p ILtxRČEX/mAJ Up4F̹'̙+46!\umݧP]F]u5 7wAf$4Dx>_gio NDd2 a.x^@KRJZE`vZc4i7֨1 sE DzB'fK1u (IAp* n^SOZH=TK,a 0ș.LR>`5bB1̽qe) #Fc/_>2`=_+^F)4WіNEc I<fz\R1zr6V 'A$K)1UsD2'28t-lfQ~z 8əN~8 PJe^3 #%8u!S v+uɘqHQ>ܕ 9n9 P̫=bֿnǡjtL0dT2akuWT{:rOVfe9Ykf1u _o8#ZXBzL` ^F 1ƾoT!"WzgZB#$H%7O ^o1e ?ZdeZD,׿gBY.}292g;?9VKPJy~~N[HH3chwA̖J(GF\sR{׿oR RGZJ1b-E-ƒLP5kM\ou]mk!7|˗/Yd.umW ei6Sb! \&fĔyrd(9֌9gfciFQ"i#EIA,K+"VSe|VG"[A4L{ۃu Zn/W¹J!Z*9`x`J 0+@\xy >jf~mﻪeIMtρ f) sA#B̜r00HA%:ͦ137F485H LJut WSUNiDþt?AIDà m RJ\"" 5=nS9,?o9x#_|{:"R6Zu߻ d.LDf!bHP!TsC( <<g"ɋr3aR̞'T`?gޙLos4ވ|JRoLTkBVkDC!@~D 3 @8H#H˖>"rČ*#& =~.Df.w.w" ji9k.D讉[Hl"rDv2#S3i^J?}tvZ{2R[fJ)eA!D:T^/EćzؾVcA9L6}칃}||,HÆ0_ob&"]֕m[kÏuib3Rf](&CG'% N1]eμ}0Vᾏag"V)EYMDkkfjmV6#,QaACx\r"Q03Z@Hk pּ9p[ےII4,ͼz\݇ZkN#%q02{l~' kBdKS85p[k}|J WUf&;vgs)`Vײ柚K]EeƧ8s:>,,ڊu<*`M@r^NCYG"q*Yfa pȴs*k[DTWJTy07K9~:3mWva)#<e<0eMrb`ޙfjHTbah"EjIE9C3Inecg ๦ǓxNh*̭V[5sr^K eEX #}"g/eY^K)Ln>HEzۦ$gw]#ՖOB:ZId\> Z QZQSLm{ѵo><<1}Y/ww{LX_W?b2pdN;vV\뭵mKZ@~TKXS+{k.5th T@x­!րX.ļܯݮ?7.}(-J}t[օC ę#Oח_ӧ/!~oc0>1/5Zk: He"DFdBT1'm0_y\}̅X8"kub]1K{Ǟ))ɚJHsffPD%^[ "䙍NS؏r"Ĭff6&ڰv1aCMHƄ f^r o.燖 ;Lv71Б#JDsr37Ccѓg<JGmY20 1iCCD?2MNKrål=Kicjm)R_~Q݋"N![d,EfOLoUsX6mL2Ӛ tўS,+IQmRmr G4 D P3@R,\*!rM;4!">Zdn@ KF#xVrkqZcPw}J`fy].#< 0"qSjt` g劽wl]*`1Im:@@V}e3QU@*5""2L1)R=>;!nE?p^"*Wb)<8gܝ͎i}k[j*~~L1}ic{a]@ 5D^/Q v=>{~ , zyz g6%d9{" 0瞌'A:=PyA8i'L 2Ql:IN}.,5,q k2ՍaJLDE8W99}`QDrM= +rvwsc}'LFj#>8:Fk )c֋I);njs2 Hb7; t˜^$fd ("fjCuwÉVqp?}{[Y69 8(sEoEF!J鷪D4 v0s`Y2k,s:6=A8yP WR 3f}0C&5{0[+ VBBD qK9vŠ?ScԖI87Fz,P<"#>Xv]'*!Z]X YZ[eUɐWY1cfJ)5y !#~.8뤭̤v}ts4㥉oE!27߂2p9#"9|cޑt{Gbd"c^UU[[V†y=b]zPqBs-X ~m!F yHf.و0 Gp:PEp:\Z"LլD~s~ZW=2(H̴ZkY6V?9y~"R!,0Z-ÿ?Kקe矿~[se&7?< նo[-vݮx0W_}㧇LJ7sB*R&L!RlmyxRks__PÝuu}>lUa 32 E岶ZlƑrgxx|߇`w"z}Q35ˆS+q#}J ϟ?TbDc",}W,˄c@@1<K#3]Dz"rm:"<ܑhL.CP`grL?!Z3לV&-*>Fxf1Rܦ_L`j^r쬐HD2ŝC\ߩjLaV V "nuͬT(N Yjk>չY(1a3#p ]挈r v 0O#qYBxBŘ(9,tߏqsH%S]&e*FQ|C% +zvaraµD#f!${@Rٯz1W"e]u=K p;yxxw`/O_4"Jkga@)5xd"|淝8dD,:4 KEt" v^2P╣5lpQ1_??}{P|dmۊLVF<*2-:/oZʇ}ckm;"۵X))t<,n|aۮ}/Ӳ,R+\gB-tR[ۂ#_x-whTu u1K&|M d U5Oz 1NE#$TZm=e.}pp" ጄuQ<ؙ!$\(b,=ANQ?EIˆxF)Ŧ j&7=gtDR&M(܆i}ݿ+o}/,QB[18n/׻e\1jQK}>ݺ>?=w{f&,dzg "U>ūZh TÍly%E2#RK):t&jm̵eY[)ew8FH$BXJ\Pc:y̜%y"-T jm@"M %NfL$4D\"RyD¥^3sCUmۮfضZ3L=LgŲL8CyS|NfmA-"LDȔ匈Ⱦﭵ" Q('9dl?́dafD$d&l1c!WeAiں! T'ʛ#j)o?~\KM  \kRa3K.)&wޗDGBbpb&ku[by8 qn3ri1C"LHB "q7n,,v#- }ߑ`]u'ރR`:4l›AXeI(uV[3w>cU5f`H@!r~9"m‚HcT_lۭ2'c!y poE$a&ȼՆfB^)KE\{) `zJG{k\3\h]ml 5DRg\sqN_v{s/&Ds:u~k5N~Ybl0Q>ZiLpY )Rry7X$ʵ*q`/RcZ}r-YT^. 1pR)Yr $r d3~0/H}Ie x|CFR݁DPKffX7 juY !b )mo>~,ݔK]z掠"mYX]XYm!!|\J)TH!.K73km I//]mNEdKqB rb۶3 @v@\,_^AMkaZ\.:F\.aoO_~y~Ç1a}jF]XX`U><<{ ),-0_ ,]LY: !lsR!$EJe}{^z{|80"̌rDԓ-˒jnwU@   BB9!˅MRtw@͹H^T ]0=;{ܶmݲ^,ȔIEDtAX"D$'od{߶p7̡MD)%3'IԲ.q0^D6s'IJضm2 О5䭾Ob-5sKEjțYbn3$;W!dBJSK \ThNMTM5r׵A~”ު $R"NRfހ-miR SYrUBjJXd+G Cm)aCnwͭ-1 ADi."͙uLiBA}`Bf@,mY/$?~H,e155c;@U\rX^OLSEhIrSU7Jj ³]Ӓu]*uw&.۾*Qzw.-e!!VS@cpHK-Pgo`5v??Tu]>z Afb/ Hp͈.`1vp07_^W3PiSROط 0 < 9h$B W?\k}u s"l9s d޷updHx8`-6 Rjk˗l"R13E@4zB0 0&k."UQ B\{Uݐ3یK(e] ~\kBz^}1 ";*uxR ?m*B-w#f#pgS%.Pddjj755PKcuifK-0*oc!z"PO2J9̮C-#.b`X0}vn;٫v&"9eH5۶#@x)eYnə#)L0p&f5n`6+pP@@ɰ6"Jk#P{' W϶@k8,U2SV~O8hH/@srb86@T$@J 9Ha@4ޗV.P)/BHy@ q*`JA)E J1`Ѭ aC+ Jkm2G{1ppzw&10!ຬFw`SOMksv wpBTPj-oY擟O5߲ "t}ߗ2e7\X?\{7"R>z*qa9<1[D Zh0e3<ߊFޜ 2́v9Tk-aw8!RDDZwzXJ"'Q,"@"2k|/lxȘ(_רS4BsWo gW6 flVJ@KA㑔y)+tlw4bmy<`=򉗛{:H ɞ?Idžc졖j j]/ypHӠHenm),`fc.37Qkk)кԜ䜜d;Z bfo,Ce䓝z :pCKD԰eYdǜ{Ǻ^kLtIdʼnMM3GF>$bG3e8оpc "u;A-IPfa¬CS{o p_?ov}RxfD,uXӻ$.RhiU<!݌ SHWH:v= I*uœncv&u(Ȃ(,>-98`RJ`P]=XaUe Ϟ1^nfnC5%eOSNNс<"oFBȒd)49MbY!!8XL=Ѿ` 0)+&R۲y"+|L.kK<t|yҀxn0;_1b6R/A$(Da"B6=o v i_xrichZqܛb:yf}ߙ0k)_?abY<H6wc3( U]Ei*Cd(4E89n 5IAġc:"J\ȼ$eYa.x!$4"jofFȥ4w^޽߶[4<)Y#*3=3=RNM族0(Ё۾Cľ-EnVr^!nYІ.i`de^jVZo?}{wcOXqƧ6 %̉D{BkGWe:tw۾# y)վmvEX,Lg^1[XO1g/&\_HܼpwF"|"j]1ܔ!ZT!N] ~7,ܑim567E_|.h1ĒL"wBL1=[ӲޥTf|y:;01LU#:!|v%l. P\ƞ`䓙,tAQisbY[g0LĪ))lkm/Dy-Lq$+i˾fLDHB&wFҀu%tEXtdate:create2016-10-10T23:52:04-06:002%tEXtdate:modify2016-10-10T23:51:48-06:00޵tEXtexif:ColorSpace1I!tEXtexif:DateTime2013:06:23 12:04:13vjtEXtexif:ExifImageLength1200BVtEXtexif:ExifImageWidth1200sf`tEXtexif:ExifOffset164{++tEXtexif:SoftwareAdobe Photoshop CS6 (Windows);8tEXticc:copyrightCopyright (c) 1998 Hewlett-Packard CompanyWy7!tEXticc:descriptionsRGB IEC61966-2.1WG&tEXticc:manufacturerIEC http://www.iec.chL7tEXticc:modelIEC 61966-2.1 Default RGB colour space - sRGBDSHIENDB`fvwm-2.6.7/default-config/images/bgicons/0000755000175700017570000000000013006057357015312 500000000000000fvwm-2.6.7/default-config/images/bgicons/bg2.png0000644000175700017570000000336613006057357016422 00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<bKGD pHYs.#.#x?vtIME 'cf6IDATHǍr9DQNWRU.{4?nRHH$s؝v*p>ZUzǂtL8׎ U ^nzŵ'dmZ<&^I0E5w#Gdd! } #Zd^w௏yji3vU)xȒ,Ozҫo]O֭Pf^{ n`UB2顅Bs<'j_9jjJCMY }y rT^݀Ũ7F-r]y+o0k\Df)s@.=[poQ1KJH|a :<űXpxJ1`jwDa^Fbibk{>jQ+豦QfF4rUIē#`w :zHE!5CzI4݈Πsp 8zHI~ ;E2lo@eשWɴpMFuV%ͼwv= WTӫJo8SHQ0.{uĀ)B|Pt 0H 7;)depYFqW"Н5@}}M1ǪR&D"K(2 )s Q5H (o$AHDb77d`^ zcL 8ڊ"! -e! wNcףDHdL/z4?Ƭisv=N Xr-jGˊRÜF7'MF  Rtgƃ}G|끞=+;'y}aA<{ƤQ+c֢E\GϡzŏكEGExSߡ =0(Pp,8V|q4;z%NWH4I"T'P@&ҟEAOv:{PR߫mDA2L)`RD %v $Kɬ5.4K{uP].`(cq{繷 ]\ddcfﻩĩo.=HYڜugTn㉏xAi} Yh8],er=/i}%tEXtdate:create2016-10-10T23:52:46-06:00W%tEXtdate:modify2016-10-10T23:45:45-06:00IENDB`fvwm-2.6.7/default-config/images/bgicons/bg1.png0000644000175700017570000000122013006057357016404 00000000000000PNG  IHDR P+bKGD̿ pHYsddtIME 'cf6FtEXtRaw profile type app12 app12 15 4475636b79000100040000002f0000 :rmIDAT(R0 oZk[i;@hQy>=ɢf鹘קN皩_ ygI|MQG=',[')H!ڋL7ڰF̴X.f4}&cP~Xg@O%Ĕh`^!N%z[H(/BU 'JLwɑA8[C ; a3mQF*z8pmdDeIr{7N+:v}QS`!:t~: @=Q^Գ ^'M@J4>DQM_[T.ԌLdTp %tEXtdate:create2016-10-10T23:52:41-06:00@%tEXtdate:modify2016-10-10T23:45:45-06:00IENDB`fvwm-2.6.7/default-config/images/bgicons/bg3.png0000644000175700017570000000463713006057357016425 00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<bKGD pHYs  ~tIME 'cf6IDATH5Kdm#HsofVu譅$H`61BtwUu9dh-?*0F=,$[Ͷ{mZVm۱[B'I4~1(iG[̜c5gn^kze}ߖvEh/c*0A/?朻ܿrQYsҌf G~3<̒e]}~9Hsw_y߾}c4c{@ebhUEr] |@Uӣh2ﯭYEhr*A7kAEZN\$x?/dev/null; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) AC_MSG_WARN([$PERL not found or too old]) fi else HAVE_PERL_FOR_DOCS=0 AC_MSG_WARN([perl is not found, it is required for some scripts and modules]) AC_MSG_WARN([It is recommended to install perl $REQUIRED_PERL_VERSION or better later]) PERL=/usr/bin/perl fi AC_MSG_RESULT([assuming $PERL as perl location]) AC_SUBST(PERL) # installation paths FVWM_MODULESUBDIR=/${PACKAGE}/${VERSION} FVWM_DATASUBDIR=/${PACKAGE} FVWM_DOCSUBDIR=/doc/${PACKAGE} AC_ARG_ENABLE(package-subdirs, AS_HELP_STRING([--disable-package-subdirs], [do not create subdirs for modules and data]), [if test x"$enableval" = xno; then FVWM_MODULESUBDIR=""; FVWM_DATASUBDIR=""; fi], []) FVWM_MODULEDIR='${libexecdir}'"$FVWM_MODULESUBDIR" FVWM_DATADIR='${datadir}'"$FVWM_DATASUBDIR" FVWM_DOCDIR='${datadir}'"$FVWM_DOCSUBDIR" FVWM_PERLLIBDIR='${datadir}'"$FVWM_DATASUBDIR/perllib" FVWM_CONFDIR='${sysconfdir}'dnl used _only_ to search for system.fvwm2rc AC_SUBST(FVWM_MODULEDIR) AC_SUBST(FVWM_DATADIR) AC_SUBST(FVWM_PERLLIBDIR) AC_SUBST(FVWM_CONFDIR) AC_SUBST(FVWM_DOCDIR) AH_TEMPLATE([FVWM_CONFIG], [Name of config filenames in FVWM_USERDIR and FVWM_DATADIR]) AC_DEFINE(FVWM_CONFIG, "config") AH_TEMPLATE([FVWM2RC],[Suffix for old (to be deprecated) config filenames]) AC_DEFINE(FVWM2RC, ".fvwm2rc") # Various configure-time options AC_ARG_ENABLE(dmalloc, AS_HELP_STRING([--enable-dmalloc], [enable support for the dmalloc debugging library]), [ac_cv_dmalloc="$enableval"], [ac_cv_dmalloc="no"]) AC_ARG_ENABLE(efence, AS_HELP_STRING([--enable-efence], [enable support for the efence debugging library]), [ac_cv_efence="$enableval"], [ac_cv_efence="no"]) smr_SWITCH(command-log, command logging, off, FVWM_COMMAND_LOG,, [Produces a log of all executed commands and their times on stderr.]) AH_VERBATIM([_FVWM_COMMAND_LOG], [#ifdef FVWM_COMMAND_LOG # define FVWM_DEBUG_TIME 1 #endif]) smr_SWITCH(debug-msgs, debugging messages, off, FVWM_DEBUG_MSGS,, [if you would like to see lots of debug messages from fvwm, for debugging purposes, uncomment the next line]) AH_VERBATIM([_FVWM_DEBUG_MSGS], [#ifdef FVWM_DEBUG_MSGS # define DBUG(x,y) fvwm_msg(DBG,x,y) #else # define DBUG(x,y) /* no messages */ #endif]) dnl dummy: smr_SWITCH(sm, dummy for test script, on, SESSION) # Need to know where X is, for finding some libraries (e.g. xpm) no_x="" AC_PATH_XTRA if test x"$no_x" = x"yes"; then echo echo "X11 libraries or header files could not be found. Please make" echo "sure the X11 development package is installed on your system." echo "If it is definitely installed, try setting the include and library" echo "paths with the --x-include and --x-libraries options of configure." echo "Fvwm can not be compiled without the X11 development environment." echo echo "Aborting." echo exit 1 fi # FIXME: default value should be derived from computed path to X # includes. Actually, this should probably not appear in configure # at all: it is settable at runtime, and only confuses the issue to # have it settable here too. # AC_MSG_CHECKING(imagepath) val="/usr/include/X11/bitmaps:/usr/include/X11/pixmaps" AC_ARG_WITH(imagepath, AS_HELP_STRING([--with-imagepath=PATH], [colon-delimited search path for images]), [ case "$withval" in no) AC_MSG_ERROR([Can not disable image path.]) ;; yes) ;; *) val="$withval" ;; esac ]) AH_TEMPLATE([FVWM_IMAGEPATH],[Where to search for images.]) AC_DEFINE_UNQUOTED(FVWM_IMAGEPATH, "$val") FVWM_IMAGEPATH="$val" AC_SUBST(FVWM_IMAGEPATH) AC_MSG_RESULT($val) # Minimal checks for programs: enough to enable checking for # optional libraries. AC_PROG_CC AC_PROG_CPP # added -Wall for gcc, what about for others? if test "x$GCC" = "xyes"; then CFLAGS="-Wall -Wno-implicit-int $CFLAGS" fi # Help finding POSIX functions on some systems AC_ISC_POSIX AC_MINIX # catch -Werror and similar options when running configure AC_TRY_COMPILE([#include ], [int i; static j; int *p; char *c; switch (*p = p = *c) { case 0: printf("%Q", c, p); } *c = &i; c = p; while (1 || (unsigned int)3 >= 0 || ((int)-1) == ((unsigned int)1)); ], , AC_MSG_ERROR(" configure is not able to compile programs with warnings. Please remove all offending options like -Werror from the CFLAGS and CPPFLAGS variables and run configure again.")) # check size of some types ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $X_CFLAGS" AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(Window, , [#include #include ]) AC_CHECK_SIZEOF(Pixel, , [#include #include ]) AC_CHECK_SIZEOF(void *) CFLAGS="$ac_save_CFLAGS" size_check_failed="" if test "$ac_cv_sizeof_void_p" -gt "$ac_cv_sizeof_long"; then echo "The type void * is bigger than long." size_check_failed=1 fi if test "$ac_cv_sizeof_Window" -gt "$ac_cv_sizeof_long"; then echo "The type Window is bigger than long." size_check_failed=1 fi if test "$ac_cv_sizeof_Pixel" -gt "$ac_cv_sizeof_long"; then echo "The type Pixel is bigger than long." size_check_failed=1 fi if test x"$size_check_failed" = x1; then echo "This is not supported by the module interface yet (make_new_vpacket)." echo "Detected type sizes are: int($ac_cv_sizeof_int), long($ac_cv_sizeof_long), void*($ac_cv_sizeof_void_p), Window($ac_cv_sizeof_Window), Pixel($ac_cv_sizeof_Pixel)" echo "Please report details of your system and this message to ${FVWMWORKERSLIST}." echo exit 1 fi # 'unset' is not portable, but setting to null is not enough to avoid using # the cached value! For ancient shells "rm config.cache" is a solution. UNSET=true if unset UNSET 2>/dev/null; then UNSET=unset; fi # ********* multibyte # FreeBSD has libxpg4, check this and use if found. AC_CANONICAL_HOST case $host_os in freebsd*) AC_CHECK_LIB(xpg4, setlocale, [LIBS="$LIBS -lxpg4"]);; *) ;; esac # *** pkg-config # unfortunately, we need pkg-config for the detection of certain libs: # - version of fontconfig without fontconfig-config # - version of fribidi without fribidi-config AM_CHECK_PKG_CONFIG # Building man pages & HTML documentation (from XML source). # extract command names if test ! x"$SED" = x; then DOC_COMMANDS=` sed -n ' :findhead /#.*define.*CMD_ENT/bfindcmd n bfindhead :findcmd n /CMD_ENT/bfound bfindcmd :found /"#"/bfindcmd /"propertychange"/bfindcmd /"readwritecolors"/bfindcmd /"send_.*"/bfindcmd /"set_.*"/bfindcmd s/.*CMD_ENT.*CMD_// s/,.*// p n bfindcmd ' < fvwm/functable.c` DOC_COMMANDS=`echo $DOC_COMMANDS` # with .xml suffix DOC_COMMANDS_XML=`for i in $DOC_COMMANDS; do echo ${i}.xml; done` DOC_COMMANDS_XML=`echo $DOC_COMMANDS_XML` # with .xml suffix and path DOC_COMMANDS_XML_PATH=` for i in $DOC_COMMANDS; do echo ../commands/${i}.xml; done ` DOC_COMMANDS_XML_PATH=`echo $DOC_COMMANDS_XML_PATH` # with .html suffix DOC_COMMANDS_HTML=`for i in $DOC_COMMANDS; do echo ${i}.html; done` DOC_COMMANDS_HTML=`echo $DOC_COMMANDS_HTML` # extract module names DOC_MODULES="" DOC_MODULES=` for i in modules/*; do echo "$i"; done | sed -n ' :search /^modules.Fvwm/bfound bnext :found s/modules.// p :next n bsearch ' ` DOC_MODULES=`echo $DOC_MODULES` DOC_MODULES_HTML=`for i in $DOC_MODULES; do echo ${i}.html; done` DOC_MODULES_HTML=`echo $DOC_MODULES_HTML` # extract man page section names DOC_SECTIONS=`cat doc/fvwm/sections` DOC_SECTIONS=`echo $DOC_SECTIONS` DOC_SECTIONS_XML=`for i in $DOC_SECTIONS; do echo ${i}.xml; done` DOC_SECTIONS_XML=`echo $DOC_SECTIONS_XML` DOC_SECTIONS_XML_PATH=`for i in $DOC_SECTIONS; do echo ${i}.xml; done` DOC_SECTIONS_XML_PATH=`echo $DOC_SECTIONS_XML` else DOC_COMMANDS="" DOC_COMMANDS_XML="" DOC_COMMANDS_XML_PATH="" DOC_COMMANDS_HTML="" DOC_MODULES="" DOC_MODULES_HTML="" DOC_SECTIONS="" DOC_SECTIONS_XML="" DOC_SECTIONS_XML_PATH="" fi AC_SUBST(DOC_COMMANDS) AC_SUBST(DOC_COMMANDS_XML) AC_SUBST(DOC_COMMANDS_XML_PATH) AC_SUBST(DOC_COMMANDS_HTML) AC_SUBST(DOC_MODULES) AC_SUBST(DOC_MODULES_HTML) AC_SUBST(DOC_SECTIONS) AC_SUBST(DOC_SECTIONS_XML) AC_SUBST(DOC_SECTIONS_XML_PATH) problem_mandoc="" AC_CHECK_PROG(XSLTPROC, xsltproc, xsltproc, "") AC_ARG_ENABLE(mandoc, AS_HELP_STRING([--disable-mandoc], [disable generation of man pages]), [ if test x"$enableval" = xyes; then with_mandoc="yes, check" else with_mandoc="no" problem_mandoc=": Explicitly disabled" fi ], [ with_mandoc="not specified, check" ] ) if test ! x"$with_mandoc" = xno; then if test x"$XSLTPROC" = x ; then with_mandoc="no" problem_mandoc=": No xsltproc found in PATH" elif test x"$SED" = x ; then with_mandoc="no" problem_mandoc=": No sed found in PATH" elif test x"$HAVE_PERL_FOR_DOCS" = x0 ; then with_mandoc="no" problem_mandoc=": No perl found in PATH" else with_mandoc="yes" fi fi AM_CONDITIONAL([FVWM_BUILD_MANDOC], [test x"$with_mandoc" = xyes]) problem_htmldoc="" AC_ARG_ENABLE(htmldoc, AS_HELP_STRING([--enable-htmldoc],[enable generation of HTML documentation]), [ if test x"$enableval" = xyes; then with_htmldoc="yes, check" else with_htmldoc="no" problem_htmldoc=": Explicitly disabled" fi ], [ with_htmldoc="no" ] ) if test ! x"$with_htmldoc" = xno; then if test x"$XSLTPROC" = x ; then with_htmldoc="no" problem_htmldoc=": No xsltproc found in PATH" elif test x"$SED" = x ; then with_htmldoc="no" problem_htmldoc=": No sed found in PATH" elif test x"$HAVE_PERL_FOR_DOCS" = x0 ; then with_htmldoc="no" problem_htmldoc=": No perl found in PATH" else with_htmldoc="yes" fi fi AM_CONDITIONAL([FVWM_BUILD_HTMLDOC], [test x"$with_htmldoc" = xyes]) # ********* session management # Check the availability of SM; we don't have to add any extra libraries, # since -lSM -lICE are in X_PRE_LIBS when they exist. dnl [old check] AC_CHECK_LIB(SM, SmcOpenConnection, AC_DEFINE(SESSION), , dnl [old check] [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) problem_sm="" AC_ARG_ENABLE(sm, AS_HELP_STRING([--disable-sm],[disable session management support]), [ if test x"$enableval" = xyes; then with_sm="yes, check" else with_sm="no" problem_sm=": Explicitly disabled" fi ], [ with_sm="not specified, check" ] ) if test ! x"$with_sm" = xno; then dnl Uncomment the following and comment out AC_CHECK_LIB to get --with-sm-* dnl $UNSET ac_cv_lib_SM_SmcOpenConnection dnl $UNSET ac_cv_header_X11_SM_SMlib_h dnl smr_CHECK_LIB(sm, SM, adds session management support, SmcOpenConnection, dnl X11/SM/SMlib.h, dnl [$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS], $X_CFLAGS) dnl test "$sm_LIBS" && AC_DEFINE(SESSION) $UNSET ac_cv_lib_SM_SmcOpenConnection AH_TEMPLATE([SESSION],[Enables session management functionality.]) AC_CHECK_LIB(SM, SmcOpenConnection, with_sm=yes; AC_DEFINE(SESSION), with_sm=no; problem_sm=": Failed to detect libSM", [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) fi dnl AC_SUBST(sm_LIBS) dnl AC_SUBST(sm_CFLAGS) # Checking for optional libraries # Default is to use them if found; can be disable using --without # These are put up front so that if they are requested, but # configure fails to find them, we fail early. # ********* shape extension dnl smr_SWITCH(shape, shape extensions, on, SHAPE) AC_ARG_ENABLE(shape, AS_HELP_STRING([--disable-shape],[disable shaped window support]), [ if test x"$enableval" = xyes; then with_shape="yes, check" else with_shape="no" problem_shape=": Explicitly disabled" fi ], [ with_shape="not specified, check" ] ) AH_TEMPLATE(SHAPE, [ Define if you want the Shaped window extensions. Shaped window extensions seem to increase the window managers RSS by about 60 Kbytes. They provide for leaving a title-bar on the window without a border. If you don't use shaped window extension, you can either make your shaped windows undecorated, or live with a border and backdrop around all your shaped windows (oclock, xeyes) If you normally use a shaped window (xeyes or oclock), you might as well compile this extension in, since the memory cost is minimal in this case (The shaped window shared libs will be loaded anyway). If you don't normally use a shaped window, you have to decide for yourself. Note: if it is compiled in, run time detection is used to make sure that the currently running X server supports it.]) if test ! x"$with_shape" = xno; then $UNSET ac_cv_lib_Xext_XShapeQueryExtension AC_CHECK_LIB(Xext, XShapeQueryExtension, with_shape=yes; AC_DEFINE(SHAPE), with_shape=no; problem_shape=": Failed to detect Shape extension", [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) fi # ********* MIT Shared Memory Extension AC_ARG_ENABLE(shm, AS_HELP_STRING([--disable-shm],[disable MIT Shared Memory Extension]), [ if test x"$enableval" = xyes; then with_shm="yes, check" else with_shm="no" problem_shm=": Explicitly disabled" fi ], [ with_shm="not specified, check" ] ) AH_TEMPLATE([HAVE_XSHM],[Define if MIT Shared Memory extension is used.]) if test ! x"$with_shm" = xno; then $UNSET ac_cv_lib_Xext_XShmQueryExtension AC_CHECK_LIB(Xext, XShmQueryExtension, with_shm=yes; AC_DEFINE(HAVE_XSHM), with_shm=no; problem_shm=": Can't detect MIT Shared Memory ext.", [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) fi # Silently look for X11/XKBlib.h AH_TEMPLATE([HAVE_X11_XKBLIB_H],[Define if Xkb extension is used.]) AC_CHECK_HEADER(X11/XKBlib.h, AC_DEFINE(HAVE_X11_XKBLIB_H)) # ********* xineramA problem_xinerama="" AC_ARG_ENABLE(xinerama, AS_HELP_STRING([--disable-xinerama],[disable Xinerama multi screen support]), [ if test x"$enableval" = xyes; then with_xinerama="yes, check" else with_xinerama="no" problem_xinerama=": Explicitly disabled" fi ], [ with_xinerama="not specified, check" ] ) AH_TEMPLATE([HAVE_XINERAMA],[Define if Xinerama library is used.]) AH_TEMPLATE([HAVE_SOLARIS_XINERAMA], [Define if Solaris' Xinerama calls are being used. (Solaris 7 11/99 and later)]) AH_TEMPLATE([HAVE_SOLARIS_XINERAMA_H], [Define if Solaris' X11/extensions/xinerama.h header is provided. (Solaris 9 and later)]) if test ! x"$with_xinerama" = xno; then $UNSET ac_cv_lib_Xinerama_XineramaIsActive _check_solaris_xinerama=no AC_CHECK_LIB(Xinerama, XineramaIsActive, with_xinerama=yes; Xinerama_LIBS=-lXinerama; AC_DEFINE(HAVE_XINERAMA), _check_solaris_xinerama=yes, [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS]) if test x"$_check_solaris_xinerama" = xyes; then AC_CHECK_LIB(Xext, XineramaGetState, [ AC_DEFINE(HAVE_XINERAMA) AC_DEFINE(HAVE_SOLARIS_XINERAMA) with_xinerama=yes; Xinerama_LIBS=-lXext my_CPPFLAGS="$CPPFLAGS"; CPPFLAGS="$X_CPPFLAGS $CPPFLAGS" my_hdr="X11/extensions/xinerama.h" AC_CHECK_HEADER($my_hdr, AC_DEFINE(HAVE_SOLARIS_XINERAMA_H) problem_xinerama=" (Using Solaris Xinerama calls)", problem_xinerama=" (Using Solaris 9 prototypes for missing header)") CPPFLAGS="$my_CPPFLAGS"], with_xinerama=no; Xinerama_LIBS= problem_xinerama=": Failed to detect libXinerama", [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS]) fi $UNSET _check_solaris_xinerama fi AC_SUBST(Xinerama_LIBS) AC_SUBST(Xinerama_CFLAGS) # ********* xinerama-emulation smr_SWITCH( xinerama-emulation, [Xinerama emulation on one screen (useful only for developers)], off, USE_XINERAMA_EMULATION,, [Define if Xinerama should be emulated on a single screen.]) if test x"$enable_xinerama_emulation" = xyes; then with_xinerama_emulation=yes else with_xinerama_emulation=no fi # ********* xrender problem_xrender="" AC_ARG_ENABLE(xrender, AS_HELP_STRING([--disable-xrender],[disable Xrender alpha-blend rendering]), [ if test x"$enableval" = xyes; then with_xrender="yes, check" else with_xrender="no" problem_xrender=": Explicitly disabled" fi ], [ with_xrender="not specified, check" ] ) AH_TEMPLATE([HAVE_XRENDER],[Define if Xrender library is used.]) if test ! x"$with_xrender" = xno; then $UNSET ac_cv_lib_Xrender_XRenderComposite AC_CHECK_LIB(Xrender, XRenderComposite, with_xrender=yes; Xrender_LIBS=-lXrender; AC_DEFINE(HAVE_XRENDER), with_xrender=no; Xrender_LIBS= problem_xrender=": Failed to detect libXrender", [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS]) fi AC_SUBST(Xrender_LIBS) AC_SUBST(Xrender_CFLAGS) # ********* xcursor AH_TEMPLATE([HAVE_XCURSOR],[Define if Xcursor library is used.]) xcursor_CFLAGS="" xcursor_LIBS="" AC_ARG_ENABLE(xcursor, AS_HELP_STRING([--disable-xcursor], [disable Xcursor ARGB/animated cursor loading]), [ if test x"$enableval" = xno; then with_xcursor=no problem_xcursor=": Explicitly disabled" fi ], ) if test ! x"$with_xcursor" = xno; then with_xcursor=no if test ! x"$with_xrender" = xno; then $UNSET ac_cv_lib_Xrender_XRenderCreateCursor AC_CHECK_LIB(Xrender, XRenderCreateCursor, [ with_xcursor=yes ],[ problem_xcursor=": Your libXrender version is too old" ], [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS]) else problem_xcursor=": Need Xrender support" fi fi if test x"$with_xcursor" = xyes ; then $UNSET ac_cv_lib_Xcursor_XcursorImageLoadCursor AC_CHECK_LIB(Xcursor, XcursorImageLoadCursor, [ AC_DEFINE(HAVE_XCURSOR) Xcursor_LIBS=-lXcursor problem_xcursor="" ],[ with_xcursor=no problem_xcursor=": Failed to detect libXcursor" ],[$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS]) fi AC_SUBST(Xcursor_CFLAGS) AC_SUBST(Xcursor_LIBS) # ********* xft problem_xft="" AC_ARG_ENABLE(xft, AS_HELP_STRING([--disable-xft],[disable Xft anti-aliased font rendering]), [ if test x"$enableval" = xyes; then with_xft="yes, check" else with_xft="no" problem_xft=": Explicitly disabled" fi ], [ with_xft="not specified, check" ] ) AH_TEMPLATE([HAVE_XFT],[Define if Xft library is used.]) AH_TEMPLATE([HAVE_XFT2],[Define if Xft 2 library is used.]) AH_TEMPLATE([HAVE_XFT_UTF8],[Define if Xft library can handle utf8 encoding]) if test ! x"$with_xft" = xno; then # first check for freetype2 have_freetype=no AM_CHECK_FT2(6.1.0) if test x"$no_ft" = x; then have_freetype=yes else have_freetype=no problem_xft=": Can't detect freetype2 >= 6.1.0/2.0.6" fi # check for fontconfig for Xft 2 have_fontconfig=no if test ! x"$have_freetype" = xno ; then AM_CHECK_FC(1.0.1) if test x"$no_fc" = x ; then have_fontconfig=yes fontconfig_CFLAGS=`$PKG_CONFIG --cflags fontconfig` fontconfig_LIBS=`$PKG_CONFIG --libs fontconfig` CFLAGS="$CFLAGS $fontconfig_CFLAGS" LIBS="$LIBS $fontconfig_LIBS" else have_fontconfig=no problem_xft=": Can't detect fontconfig >= 1.0.1" fi fi # now check for Xft 2 with_xft=no if test ! x"$have_fontconfig" = xno ; then # Xft 2 AM_CHECK_XFT(2.0.0) if test x"$no_xft" = x; then with_xft=yes problem_xft=" (version 2)" AC_DEFINE(HAVE_XFT2) AC_DEFINE(HAVE_XFT) AC_DEFINE(HAVE_XFT_UTF8) Xft_LIBS=$XFT_LIBS Xft_CFLAGS=$XFT_CFLAGS else problem_xft=": Can't detect Xft2, detected fontconfig" fi fi # if Xft2 not detected check for Xft1 if test ! x"$have_freetype" = xno && test ! x"$with_xft" = xyes; then #Xft 1 $UNSET ac_cv_lib_XftConfigSubstitute $UNSET ac_cv_lib_Xft_XftFontOpen $UNSET ac_cv_lib_Xft_XftDrawStringUtf8 AC_CHECK_LIB(Xft, XftFontOpen, with_xft=yes, with_xft=no, [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS $FT2_LIBS $Xrender_LIBS]) if test x"$with_xft" = xyes ; then AC_CHECK_LIB(Xft, XftConfigSubstitute, is_xft1=yes, is_xft1=no, [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS $FT2_LIBS $Xrender_LIBS]) if test x"$is_xft1" = xyes; then Xft_LIBS="-lXft $FT2_LIBS" Xft_CFLAGS="$Xft_CFLAGS $FT2_CFLAGS" problem_xft=" (version 1)" AC_DEFINE(HAVE_XFT) else with_xft=no problem_xft=": Can't detect Xft 1 or fontconfig" fi else problem_xft=": Can't detect Xft 1 or 2 and fontconfig" fi if test x"$with_xft" = xyes; then AC_CHECK_LIB(Xft, XftDrawStringUtf8, AC_DEFINE(HAVE_XFT_UTF8),, [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS $FT2_LIBS $Xrender_LIBS]) fi fi fi AC_SUBST(Xft_LIBS) AC_SUBST(Xft_CFLAGS) # ********* xpm problem_xpm=": Xpm library or header not found" $UNSET ac_cv_header_X11_xpm_h $UNSET ac_cv_lib_Xpm_XpmReadFileToXpmImage smr_CHECK_LIB(xpm, Xpm, for coloured or shaped icons, XpmReadFileToXpmImage, X11/xpm.h, [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS], $X_CFLAGS) if test ! x"$xpm_LIBS" = x; then # Check for proper version of Xpm -- from XEmacs 21.x configure.in AC_MSG_CHECKING([for Xpm 3.4g or better]) my_CPPFLAGS="$CPPFLAGS" my_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $xpm_CFLAGS $X_CFLAGS" LIBS="$LIBS $xpm_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" AC_TRY_RUN([#include int main(int c, char **v) { return c == 1 ? 0 : XpmIncludeVersion != XpmLibraryVersion() ? 1 : XpmIncludeVersion < 30407 ? 2 : 0 ;}], [./conftest dummy_arg; xpm_status=$?; if test x"$xpm_status" = x0; then with_xpm=yes problem_xpm="" else with_xpm=no; if test x"$xpm_status" = x1; then problem_xpm=": Xpm library and header versions don't match" elif test x"$xpm_status" = x2x; then problem_xpm=": Xpm library version is too old" else problem_xpm=": Internal xpm detection logic error" fi fi], [with_xpm=no; problem_xpm=": Xpm test error, see config.log"], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) AC_MSG_RESULT($with_xpm) CPPFLAGS="$my_CPPFLAGS" LIBS="$my_LIBS" AH_TEMPLATE([XPM],[Define if Xpm library is used.]) if test x"$with_xpm" = xyes; then AC_DEFINE(XPM) # FVWMBANNER=FvwmBanner AC_SUBST(FVWMBANNER) # XPMROOT=xpmroot AC_SUBST(XPMROOT) # FVWMSCRIPT=FvwmScript AC_SUBST(FVWMSCRIPT) else xpm_LIBS= xpm_CFLAGS= fi fi AC_SUBST(xpm_LIBS) AC_SUBST(xpm_CFLAGS) # ********* png png_LIBS="" png_CFLAGS="" AH_TEMPLATE([HAVE_PNG], [Define PNG]) AC_ARG_ENABLE(png, AS_HELP_STRING([--disable-png], [Disables libpng support.]), [with_png="$enableval"], [with_png="yes"]) if test "$with_png" = no; then AC_MSG_WARN([*** disabling PNG support will mean the default configuration shipped with FVWM will be without icon support. Be sure this is what you mean to do. ***]) else AC_MSG_CHECKING([for libpng...]) PKG_CHECK_MODULES([png], [libpng >= 1.2], [ AC_DEFINE(HAVE_PNG) ], [ AC_MSG_ERROR([*** libpng not found, and --disable-png not given. It is recommended to use libpng so that PNG icons can be rendered by FVWM, which the default configuration file needs, as well as other third-party programs which generate menus, for example. If it is critical that FVWM does not link against libpng (perhaps due to size limitations of the binary), then use --disable-png ***]) ]) # ** needed by the png support AC_C_BIGENDIAN fi AC_SUBST(png_LIBS) AC_SUBST(png_CFLAGS) # ********* rsvg rsvg_min_version=2.13.92 AH_TEMPLATE([HAVE_RSVG], [Define if librsvg library is used.]) AC_ARG_ENABLE(rsvg, AS_HELP_STRING([--disable-rsvg], [disable scalable vector graphics (SVG images)]), [ if test x"$enableval" = xno; then with_rsvg=no problem_rsvg=": Explicitly disabled" fi ], ) if test ! x"$with_rsvg" = xno; then with_rsvg=no if test ! x"$PKG_CONFIG" = xno ; then AC_MSG_CHECKING(for librsvg - version >= $rsvg_min_version) if $PKG_CONFIG --exists librsvg-2.0 ; then if $PKG_CONFIG --exists "librsvg-2.0 >= $rsvg_min_version" ; then AC_MSG_RESULT(yes) AC_MSG_CHECKING(for cairo svg backend) if $PKG_CONFIG --exists cairo-svg ; then svg_packages="librsvg-2.0 cairo-svg" elif $PKG_CONFIG --exists libsvg-cairo ; then svg_packages="librsvg-2.0 libsvg-cairo" elif $PKG_CONFIG --exists cairo ; then svg_packages="librsvg-2.0 cairo" else svg_packages="" fi if test ! x"$svg_packages" = x ; then AC_MSG_RESULT(yes) rsvg_CFLAGS=`$PKG_CONFIG --cflags $svg_packages` rsvg_LIBS=`$PKG_CONFIG --libs $svg_packages` with_rsvg=yes else AC_MSG_RESULT(no) AC_MSG_WARN([*** cairo was not found in the pkg-config search]) AC_MSG_WARN([*** path. Add the directory containing cairo.pc]) AC_MSG_WARN([*** to the PKG_CONFIG_PATH environment variable.]) problem_rsvg=": Cannot detect cairo backend" fi else AC_MSG_RESULT(no) AC_MSG_WARN([*** Your librsvg version is < $rsvg_min_version]) problem_rsvg=": Your librsvg version is too old" fi else AC_MSG_RESULT(no) AC_MSG_WARN([*** librsvg-2.0 was not found in the pkg-config search]) AC_MSG_WARN([*** path. Either librsvg is not installed or you need]) AC_MSG_WARN([*** to add the directory containing librsvg-2.0.pc to]) AC_MSG_WARN([*** the PKG_CONFIG_PATH environment variable.]) problem_rsvg=": librsvg library or header not found" fi else problem_rsvg=": pkg-config not found" fi fi if test x"$with_rsvg" = xyes ; then AC_MSG_CHECKING(whether a librsvg program compiles and runs) original_CFLAGS="$CFLAGS" original_LIBS="$LIBS" CFLAGS="$CFLAGS $rsvg_CFLAGS" LIBS="$LIBS $rsvg_LIBS" AC_TRY_RUN([ #include #include int main() { RsvgHandle *rsvg; g_type_init(); if(!(rsvg = rsvg_handle_new())) return 1; g_object_unref(G_OBJECT(rsvg)); return 0; } ], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) AC_MSG_WARN([*** The librsvg test program failed to run. If your system]) AC_MSG_WARN([*** has shared libraries outside the normal system library]) AC_MSG_WARN([*** path, you need to make sure that the LD_LIBRARY_PATH]) AC_MSG_WARN([*** (or the like) environment variable is correctly set.]) with_rsvg=no problem_rsvg=": Failed to run test program" ], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$original_CFLAGS" LIBS="$original_LIBS" fi if test x"$with_rsvg" = xyes ; then AC_DEFINE(HAVE_RSVG) problem_rsvg="" else rsvg_CFLAGS="" rsvg_LIBS="" fi AC_SUBST(rsvg_CFLAGS) AC_SUBST(rsvg_LIBS) # ********* rplay $UNSET ac_cv_header_rplay_h $UNSET ac_cv_lib_rplay_rplay_create # Add in X_EXTRA_LIBS here to get things like connect(). smr_CHECK_LIB(rplay, , adds audio capability, rplay_create, rplay.h, $X_EXTRA_LIBS) AH_TEMPLATE([HAVE_RPLAY],[Define if rplay library is used.]) test ! x"$rplay_LIBS" = x && AC_DEFINE(HAVE_RPLAY) AC_SUBST(rplay_LIBS) AC_SUBST(rplay_CFLAGS) # ********* stroke $UNSET ac_cv_header_stroke_h $UNSET ac_cv_lib_stroke_stroke_init dnl Add in X_LIBS for MOUSE_DROPPINGS? dnl As of 23/Mar/2000 the only libstroke RPM has /usr/X11R6/include/stroke.h AH_TEMPLATE([HAVE_STROKE],[Define if stroke library is used.]) smr_CHECK_LIB(stroke, , mouse strokes recognition, stroke_init, stroke.h, [$X_LIBS -lX11], $X_CFLAGS -I/usr/X11R6/include) test ! x"$stroke_LIBS" = x && AC_DEFINE(HAVE_STROKE) AH_VERBATIM([_HAVE_STROKE], [#ifdef HAVE_STROKE # define STROKE_ARG(x) x, # define STROKE_CODE(x) x #else # define STROKE_ARG(x) # define STROKE_CODE(x) #endif]) AC_SUBST(stroke_LIBS) AC_SUBST(stroke_CFLAGS) # ********* readline with_readline=no problem_readline=": Both termcap and ncurses disabled" smr_ARG_WITHLIB(termcap, , to accomplish readline) AH_TEMPLATE([HAVE_READLINE],[Define if readline is available.]) if test ! x"$with_termcap" = xno; then # Forget cached values, so user can re-run configure $UNSET ac_cv_header_readline_history_h $UNSET ac_cv_lib_readline_readline AC_MSG_CHECKING([with termcap]) smr_CHECK_LIB(readline, , line editing/history, readline, readline/history.h, $termcap_LIBS) if test ! x"$readline_LIBS" = x; then with_readline=yes readline_LIBS="$readline_LIBS $termcap_LIBS" AC_DEFINE(HAVE_READLINE) fi fi smr_ARG_WITHLIB(ncurses, , to accomplish readline) if test ! x"$with_ncurses" = xno && test x"$readline_LIBS" = x; then # We couldn't use readline with termcap; try with ncurses? # Doesn't this seem a hacky way to do this?? # unset cached values from last check... $UNSET ac_cv_header_readline_history_h $UNSET ac_cv_lib_readline_readline AC_MSG_CHECKING([with ncurses]) dnl We can not call smr_CHECK_LIB twice here without having the usage twice. dnl old_LIBS=$LIBS dnl AC_CHECK_LIB(readline, readline, , , $ncurses_LIBS) dnl LIBS=$old_LIBS dnl if test x"$ac_cv_lib_readline_readline" = xyes; then dnl AC_CHECK_HEADERS(readline/history.h) dnl if test x"$ac_cv_header_readline_history_h" = xyes; then dnl with_readline=yes dnl readline_LIBS="$readline_LIBS $ncurses_LIBS" dnl AC_DEFINE(HAVE_READLINE) dnl fi dnl fi smr_CHECK_LIB(readline, , line editing/history, readline, readline/history.h, $ncurses_LIBS) if test ! x"$readline_LIBS" = x; then with_readline=yes readline_LIBS="$readline_LIBS $ncurses_LIBS" AC_DEFINE(HAVE_READLINE) fi fi dnl We need to check if we have GNU readline or BSD editline AH_TEMPLATE([HAVE_GNU_READLINE],[Define if readline has full GNU interface]) if test x"$with_readline" = xyes; then AC_CHECK_LIB(readline, append_history, AC_DEFINE(HAVE_GNU_READLINE), [], $readline_LIBS) fi AC_SUBST(readline_LIBS) AC_SUBST(readline_CFLAGS) # Check if Xsetlocale() is available or not. AH_TEMPLATE([X_LOCALE],[Enables to use setlocale() provided by X]) AC_CHECK_LIB(X11, _Xsetlocale, AC_DEFINE(X_LOCALE),, $X_LIBS -lX11) # Check if Xsetlocale() is available or not. AH_TEMPLATE([HAVE_XOUTPUT_METHOD],[Enable X output method]) AC_CHECK_LIB(X11, XOpenOM, AC_DEFINE(HAVE_XOUTPUT_METHOD),, $X_LIBS -lX11) # ******** iconv with_iconv=no with_iconv_type=no with_lib_iconv=no with_sys_iconv=no problem_iconv=": Explicitly disabled" AC_ARG_ENABLE(iconv, AS_HELP_STRING([--disable-iconv], [disable support for iconv character conversion]), [ac_cv_iconv="$enableval"], [ac_cv_iconv="yes"]) AH_TEMPLATE([USE_LIBICONV], [define if we use libiconv (not needed in general: for example iconv is native with recent glibc)]) AH_TEMPLATE([HAVE_ICONV], [Define if iconv (in the libc) or libiconv is available]) if test ! x"$ac_cv_iconv" = xno; then # * first check for gnu libiconv $UNSET ac_cv_header_libiconv_h $UNSET ac_cv_lib_libiconv_libiconv_open smr_CHECK_LIB( iconv, , if not found sys iconv is used, libiconv_open, iconv.h) if test ! x"$iconv_LIBS" = x; then AC_DEFINE(USE_LIBICONV) with_lib_iconv=yes fi AC_SUBST(iconv_LIBS) AC_SUBST(iconv_CFLAGS) # * check for system iconv AC_CHECK_FUNC(iconv_open, with_sys_iconv=yes) if test x"$with_lib_iconv" = xyes && test x"$with_sys_iconv" = xyes; then AC_MSG_WARN([*** Both system iconv and libiconv found: use libiconv]) AC_MSG_WARN([*** Use --with-iconv-library=no to use the system iconv]) fi # * libiconv found check for libcharset to get the good iconv charset if test x"$with_lib_iconv" = xyes; then CHECK_LIBCHARSET fi test x"$with_lib_iconv" = xyes -o x"$with_sys_iconv" = xyes && with_iconv=yes && problem_iconv="" test x"$with_lib_iconv" = xyes && with_iconv_type="yes (libiconv)" test x"$with_sys_iconv" = xyes && with_iconv_type="yes (from C library)" if test x"$with_iconv" = xno; then AC_MSG_WARN([*** ]) AC_MSG_WARN([*** No iconv() implementation found in C library or libiconv]) AC_MSG_WARN([*** Please install libiconv ftp://ftp.gnu.org/pub/gnu/libiconv/]) AC_MSG_WARN([*** ]) fi if test x"$with_iconv" = xyes; then AC_DEFINE(HAVE_ICONV) ICONV_SECOND_ARG fi fi AH_VERBATIM([_HAVE_LIBCHARSET], [#ifdef USE_LIBICONV /* define to use locale_charset in the place of nl_langinfog if libiconv * is used */ #undef HAVE_LIBCHARSET #endif]) # ******** nl_langinfo and CODESET AH_TEMPLATE([HAVE_CODESET],[Have nl_langinfo (CODESET)]) AC_MSG_CHECKING([for nl_langinfo (CODESET)]) AC_TRY_COMPILE([#include #include ], [char *codeset = nl_langinfo(CODESET); setlocale(LC_CTYPE, "");], AC_DEFINE(HAVE_CODESET) have_codeset=yes, have_codeset=no) AC_MSG_RESULT($have_codeset) # ********* fribidi AC_ARG_ENABLE(bidi, AS_HELP_STRING([--disable-bidi],[disable bi-directional text support]), [ if test x"$enableval" = xyes; then with_bidi="yes, check" else with_bidi="no" problem_bidi=": Explicitly disabled" fi ], [ with_bidi="not specified, check" ] ) fribidi_min_version=0.19.2 if test ! x"$with_bidi" = xno; then AC_ARG_WITH(fribidi-bindir, AS_HELP_STRING([--with-fribidi-bindir=DIR], [directory of fribidi-config if not in PATH]), FRIBIDI_BINDIR="$withval", FRIBIDI_BINDIR=".") if test ! x"$PKG_CONFIG" = xno && $PKG_CONFIG --exists "fribidi >= $fribidi_min_version"; then FRIBIDI_CONFIG="$PKG_CONFIG fribidi" else AC_PATH_PROG(FRIBIDI_CONFIG, fribidi-config,, [$FRIBIDI_BINDIR:$PATH]) fi if test x"$FRIBIDI_CONFIG" = x; then with_bidi=no problem_bidi=": pkgconfig fribidi: fribidi version >= $fribidi_min_version needed." else Bidi_CFLAGS=`$FRIBIDI_CONFIG --cflags` Bidi_LIBS=`$FRIBIDI_CONFIG --libs` AC_CHECK_LIB(fribidi, fribidi_log2vis, with_bidi=yes; problem_bidi=, with_bidi=no; problem_bidi=": No good libs via $FRIBIDI_CONFIG", [$Bidi_LIBS $Bidi_CFLAGS]) fi fi if test ! x"$with_bidi" = xno; then fribidi_in_path=yes ac_save_LIBS="$LIBS" LIBS="$LIBS $Bidi_LIBS" AC_TRY_RUN([#include #include int main() { FriBidiChar *logical_unicode_str = (FriBidiChar *)malloc((4 + 1) * sizeof(FriBidiChar)); fribidi_charset_to_unicode( fribidi_parse_charset("iso8859-8"), "test", 4, logical_unicode_str); return 0; } ], [:], [fribidi_in_path=no]) LIBS="$ac_save_LIBS" if test ! x"$fribidi_in_path" = xyes; then ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $Bidi_CFLAGS" LIBS="$LIBS $Bidi_LIBS" AC_TRY_RUN([#include #include int main() { FriBidiChar *logical_unicode_str = (FriBidiChar *)malloc((4 + 1) * sizeof(FriBidiChar)); fribidi_charset_to_unicode( fribidi_parse_charset("iso8859-8"), "test", 4, logical_unicode_str); return 0; } ], [:], [with_bidi=no; problem_bidi=": Bad fribidi version, see config.log"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi if test ! x"$fribidi_in_path" = xno; then Bidi_CFLAGS= Bidi_LIBS=-lfribidi fi fi AH_TEMPLATE([HAVE_BIDI],[Define if fribidi library is used.]) AH_TEMPLATE([FRIBIDI_CHARSET_SPELLING], [Support fribidi-0.10.4 and older with "CHARSET" spelling.]) if test x"$with_bidi" = xno; then Bidi_CFLAGS= Bidi_LIBS= else AC_DEFINE(HAVE_BIDI) AC_TRY_RUN([#include int main(int c, char **v) { return FRIBIDI_CHARSET_NOT_FOUND * 0; } ], [AC_DEFINE(FRIBIDI_CHARSET_SPELLING)]) fi AH_VERBATIM([_FRIBIDI_CHARSET_SPELLING], [#ifdef FRIBIDI_CHARSET_SPELLING # define FRIBIDI_CHAR_SET_NOT_FOUND FRIBIDI_CHARSET_NOT_FOUND #endif]) AC_SUBST(Bidi_LIBS) AC_SUBST(Bidi_CFLAGS) # ********* perllib with_perllib="yes" problem_perllib="" FVWM_PERLLIB=perllib AC_ARG_ENABLE(perllib, AS_HELP_STRING([--disable-perllib],[disable installing fvwm perl library]), [ if test x"$enableval" = xno; then with_perllib="no" problem_perllib=": Explicitly disabled" FVWM_PERLLIB="" fi ], ) AC_SUBST(FVWM_PERLLIB) # ******* gettext ALL_LINGUAS="ar de fr sv_SE zh_CN ru es" FVWM_DOMAIN="fvwm" FVWMSCRIPT_DOMAIN="FvwmScript" ALL_DOMAINS="$FVWM_DOMAIN $FVWMTASKBAR_DOMAIN $FVWMSCRIPT_DOMAIN" AC_SUBST(ALL_LINGUAS) AC_SUBST(FVWM_DOMAIN) AC_SUBST(FVWMTASKBAR_DOMAIN) AC_SUBST(FVWMSCRIPT_DOMAIN) AC_SUBST(ALL_DOMAINS) LOCALEDIR='${datadir}'"/locale" with_gettext="yes" problem_gettext="" AC_ARG_ENABLE(nls, AS_HELP_STRING([--disable-nls],[do not use Native Language Support]), [ if test x"$enableval" = xno; then with_gettext="no" problem_gettext=": Explicitly disabled" fi ], ) AH_TEMPLATE([HAVE_NLS], [Define to 1 if translation of program messages to the user's native language is requested.]) if test ! x"$with_gettext" = xno; then AM_GNU_FGETTEXT if test x"$USE_NLS" = "xyes"; then AC_DEFINE(HAVE_NLS, 1) else with_gettext="no" problem_gettext=": Failed to detected GNU gettext" fi else USE_NLS=no fi # libs and buil AC_SUBST(intl_LIBS) AC_SUBST(intl_CFLAGS) AC_SUBST(USE_NLS) AC_SUBST(POSUB) AC_SUBST(LOCALEDIR) AC_SUBST(MKINSTALLDIRS) # programs for devel AC_SUBST(XGETTEXT) AC_SUBST(GMSGFMT) AC_SUBST(MSGMERGE) AC_SUBST(MSGFMT) AC_SUBST(MSGUNIQ) #catalogs AC_SUBST(INST_LINGUAS) AC_SUBST(CATALOGS) AC_SUBST(POFILES) AC_SUBST(GMOFILES) AC_SUBST(UPDATEPOFILES) AC_SUBST(DUMMYPOFILES) AC_SUBST(CATOBJEXT) # Check for REQUIRED headers and functions before going any # further. # The module interface uses variadic functions for message passing. AC_CHECK_HEADERS(stdarg.h) AC_CHECK_FUNCS(vfprintf) if test x$ac_cv_header_stdarg_h = xno -o \ $ac_cv_func_vfprintf = no; then AC_MSG_ERROR([stdarg.h and vfprintf required]) fi # For reaping children, fvwm needs either waitpid() or wait3() # Some extra modules may need wait4() too AC_CHECK_FUNCS(waitpid) if test x$ac_cv_func_waitpid = xno; then AC_CHECK_FUNCS(wait3 wait4) if test x$ac_cv_func_wait3 = xno; then AC_MSG_ERROR([Either waitpid or wait3 function is required]) fi fi # C89/C99 signal handling AC_CHECK_FUNCS(sigsetjmp siglongjmp) # Look harder for a C preprocessor for FvwmCpp AC_PATH_PROG(FVWM_CPP, cpp, no, $PATH:/lib:/usr/lib:/usr/ccs/lib) if test x"$FVWM_CPP" = xno; then FVWM_CPP= AC_MSG_WARN([cannot locate a C preprocessor: run FvwmCpp with -cppprog]) fi dnl FIXME: make sure the cpp we found actually works... # Finish checking for programs. AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_RANLIB dnl lex+yacc now only needed for FvwmScript developers when syntax is changed dnl AM_PROG_LEX dnl AC_PROG_YACC # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(stdlib.h fcntl.h limits.h malloc.h string.h memory.h unistd.h) AC_CHECK_HEADERS(stdint.h inttypes.h) AC_CHECK_HEADERS(getopt.h sys/select.h sys/systeminfo.h sys/time.h) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME dnl AC_STRUCT_TM AC_TYPE_SIGNAL AC_TYPE_INT16_T AC_TYPE_UINT16_T # Checks for library functions. AC_FUNC_STRFTIME AC_FUNC_SETPGRP AC_CHECK_FUNCS(gettimeofday mkfifo putenv setvbuf socket waitpid) AC_CHECK_FUNCS(strdup strstr strtol memmove memcpy strchr sysconf uname div) AC_CHECK_FUNCS(sigaction siginterrupt getpwuid) AC_CHECK_FUNCS(setpgrp setpgid) AC_CHECK_FUNCS(lstat) pds_CHECK_TYPE(sig_atomic_t, int, [#include ], [Specify a type for sig_atomic_t if it's not available.]) if test x$ac_cv_func_setvbuf = xyes; then AC_FUNC_SETVBUF_REVERSED fi AC_FUNC_SELECT if test ! x"$ac_cv_func_select" = xyes; then AC_MSG_ERROR([select required]) fi # check for mkstemp, see the discution on this subject on the fvwm workers # list (2001-02-16 and 2001-02-24) AM_SAFETY_CHECK_MKSTEMP # ********* IMLIB, GNOME # Check the availability of gdk-imlib AH_TEMPLATE([GDK_IMLIB],[Define if gdk-imlib is used]) AM_PATH_GDK_IMLIB(1.8.0, AC_DEFINE(GDK_IMLIB)) if test x"$no_imlib" = x; then with_gdkimlib=yes problem_gdkimlib="" else with_gdkimlib=no problem_gdkimlib=": Failed on gdk-imlib, see config.log" fi GNOME_INIT_HOOK # Unfortunately we have 2 gnome supports: WM hints and gnome libs. # The $with_gnomehints below refers to the first, not GNOME_INIT_HOOK. if test ! x"$enable_gnome_hints" = xno; then with_gnomehints=yes problem_gnomehints="" else with_gnomehints=no problem_gnomehints=": Explicitly disabled" fi # Define some compatibility macros needed for config.h. mg_DEFINE_IF_NOT([#include ], [defined XK_Page_Up && defined XK_Page_Down], [COMPAT_OLD_KEYSYMDEF], [$X_CFLAGS], [Old AIX systems (3.2.5) don't define some common keysyms.]) AH_VERBATIM([_COMPAT_OLD_KEYSYMDEF], [#ifdef COMPAT_OLD_KEYSYMDEF # define XK_Page_Up XK_Prior # define XK_Page_Down XK_Next #endif]) if test x"$with_stroke" = xyes; then mg_DEFINE_IF_NOT([#include ], [defined STROKE_MAX_SEQUENCE], [COMPAT_OLD_LIBSTROKE], [$stroke_CFLAGS], [Old libstroke <= 0.4 does not use STROKE_ prefix for constants.]) fi AH_VERBATIM([_COMPAT_OLD_LIBSTROKE], [#ifdef COMPAT_OLD_LIBSTROKE /* currently we only use one constant */ # define STROKE_MAX_SEQUENCE MAX_SEQUENCE #endif]) # Allow building with dmalloc. Do this last to avoid screwing up any # other checks above. case "$ac_cv_dmalloc" in yes) AC_CHECK_HEADERS(dmalloc.h) AC_CHECK_LIB(dmalloc, dmalloc_shutdown) CPPFLAGS="$CPPFLAGS -DDMALLOC_FUNC_CHECK" ;; esac # Allow building with efence. case "$ac_cv_efence" in yes) AC_CHECK_LIB(efence, malloc) ;; esac # some explicit definitions for config.h file AH_VERBATIM([_ZEND_EXPLICIT_DEFINITIONS], [ /** * The next few defines are options that are only changed from their values * shown here on systems that _don't_ use the configure script. **/ /* Enable tests for missing too many XEvents. Usually you want this. */ #define WORRY_ABOUT_MISSED_XEVENTS 1 /* Define if the X11 ConnectionNumber is actually a file descriptor. */ #define HAVE_X11_FD 1 /* Define if fork() has unix semantics. On VMS, no child process is created until after a successful exec(). */ #define FORK_CREATES_CHILD 1 /* Suffix for executable filenames; NULL if no extension needed. */ #define EXECUTABLE_EXTENSION NULL /* Define to remove the extension from executable pathnames before calling exec(). */ #undef REMOVE_EXECUTABLE_EXTENSION /* Enables the "MiniIcon" Style option to specify a small pixmap which * can be used as one of the title-bar buttons, shown in window list, * utilized by modules, etc. Requires PIXMAP_BUTTONS to be defined * (see below). */ /* #undef MINI_ICONS */ /* NOTE: hard coded to 1 */ #if 1 #define FMiniIconsSupported 1 #else #define FMiniIconsSupported 0 #endif #if RETSIGTYPE != void #define SIGNAL_RETURN return 0 #else #define SIGNAL_RETURN return #endif /* Allow GCC extensions to work, if you have GCC. */ #ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ # define __attribute__(x) # endif /* The __-protected variants of `format' and `printf' attributes * are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) # define __format__ format # define __printf__ printf # endif #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_MEMORY_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #if defined (HAVE_MALLOC_H) && !defined (__FreeBSD__) && !defined (__OpenBSD__) && !defined(__NetBSD__) # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifndef HAVE_STRCHR # define strchr(_s,_c) index((_s),(_c)) # define strrchr(_s,_c) rindex((_s),(_c)) #endif #ifndef HAVE_MEMCPY # define memcpy(_d,_s,_l) bcopy((_s),(_d),(_l)) #endif #ifndef HAVE_MEMMOVE # define memmove(_d,_s,_l) bcopy((_s),(_d),(_l)) #endif #if HAVE_SYS_TYPES_H # include #endif #if HAVE_UNISTD_H # include #endif #ifndef min # define min(a,b) (((a)<(b)) ? (a) : (b)) #endif #ifndef max # define max(a,b) (((a)>(b)) ? (a) : (b)) #endif #ifndef abs # define abs(a) (((a)>=0)?(a):-(a)) #endif #include "libs/defaults.h" #ifndef FEVENT_C #include #include #include "libs/FEvent.h" #endif #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif #ifdef HAVE_LSTAT #define DO_USE_LSTAT 1 #define fvwm_lstat(x,y) lstat(x,y) #else #define DO_USE_LSTAT 0 #define fvwm_lstat(x,y) -1 #endif #ifdef HAVE_X11_XKBLIB_H #include #define fvwm_KeycodeToKeysym(d, k, l, g) \ (XkbKeycodeToKeysym((d), (k), (g), (l))) #else #define fvwm_KeycodeToKeysym(d, k, x, i) (XKeycodeToKeysym((d), (k), (i))) #endif /* A macro that touches a variable in a compiler independent way to suppress * warnings. */ #define SUPPRESS_UNUSED_VAR_WARNING(x) \ do { void *p; p = (void *)&x; (void)p; } while (0); ]) # mainly for fvwm-config AC_SUBST(with_bidi) AC_SUBST(with_gdkimlib) AC_SUBST(with_gettext) AC_SUBST(with_iconv) AC_SUBST(with_perllib) AC_SUBST(with_png) AC_SUBST(with_rsvg) AC_SUBST(with_readline) AC_SUBST(with_rplay) AC_SUBST(with_shape) AC_SUBST(with_shm) AC_SUBST(with_sm) AC_SUBST(with_stroke) AC_SUBST(with_xcursor) AC_SUBST(with_xft) AC_SUBST(with_xinerama) AC_SUBST(with_xrender) AC_SUBST(with_xpm) dnl with autoconf <2.60 this is needed AC_SUBST(datarootdir) AC_SUBST(docdir) LOCAL_BUGADDR=${FVWM_BUGADDR-${USER-${LOGNAME-`whoami`}}} AC_SUBST(LOCAL_BUGADDR) AC_OUTPUT( Makefile libs/Makefile fvwm/Makefile modules/Makefile dnl bin/fvwm-bug.1 bin/fvwm-config.1 bin/fvwm-convert-2.6.1 bin/fvwm-menu-desktop.1 dnl bin/fvwm-menu-directory.1 dnl bin/fvwm-menu-headlines.1 dnl bin/fvwm-menu-xlock.1 dnl bin/fvwm-perllib.1 bin/fvwm-root.1 modules/FvwmAnimate/FvwmAnimate.1 modules/FvwmAuto/FvwmAuto.1 modules/FvwmBacker/FvwmBacker.1 modules/FvwmBanner/FvwmBanner.1 modules/FvwmButtons/FvwmButtons.1 modules/FvwmCommand/FvwmCommand.1 modules/FvwmConsole/FvwmConsole.1 modules/FvwmConsole/FvwmConsoleC.pl.1 modules/FvwmCpp/FvwmCpp.1 modules/FvwmEvent/FvwmEvent.1 modules/FvwmForm/FvwmForm.1 modules/FvwmIconMan/FvwmIconMan.1 modules/FvwmIdent/FvwmIdent.1 modules/FvwmM4/FvwmM4.1 modules/FvwmPager/FvwmPager.1 dnl modules/FvwmPerl/FvwmPerl.1 modules/FvwmProxy/FvwmProxy.1 modules/FvwmRearrange/FvwmRearrange.1 modules/FvwmScript/FvwmScript.1 dnl modules/FvwmWindowMenu/FvwmWindowMenu.1 dnl bin/Makefile bin/fvwm-config bin/fvwm-bug bin/fvwm-perllib bin/fvwm-menu-xlock bin/fvwm-menu-directory bin/fvwm-menu-desktop bin/fvwm-menu-headlines bin/fvwm-convert-2.6 dnl utils/Makefile perllib/Makefile perllib/General/Makefile perllib/FVWM/Makefile perllib/FVWM/Module/Makefile perllib/FVWM/Tracker/Makefile perllib/FVWM/Module.pm default-config/Makefile doc/fvwm.ent doc/footer.html doc/Makefile doc/fvwm/Makefile doc/commands/Makefile doc/docbook-xml/Makefile doc/docbook-xml/ent/Makefile doc/docbook-xsl/Makefile doc/docbook-xsl/common/Makefile doc/docbook-xsl/manpages/Makefile doc/docbook-xsl/profiling/Makefile doc/docbook-xsl/highlighting/Makefile doc/docbook-xsl/lib/Makefile doc/docbook-xsl/html/Makefile doc/images/Makefile doc/images/svg_rendering/Makefile docs/Makefile tests/Makefile tests/hints/Makefile po/Makefile dnl modules/FvwmAnimate/Makefile modules/FvwmAuto/Makefile modules/FvwmBacker/Makefile modules/FvwmBanner/Makefile modules/FvwmButtons/Makefile modules/FvwmCommand/Makefile modules/FvwmCommand/scripts/Makefile modules/FvwmConsole/Makefile modules/FvwmConsole/FvwmConsoleC.pl modules/FvwmCpp/Makefile modules/FvwmEvent/Makefile modules/FvwmForm/Makefile modules/FvwmIconMan/Makefile modules/FvwmIdent/Makefile modules/FvwmM4/Makefile modules/FvwmPager/Makefile modules/FvwmPerl/Makefile modules/FvwmPerl/FvwmPerl modules/FvwmProxy/Makefile modules/FvwmRearrange/Makefile modules/FvwmScript/Makefile modules/FvwmScript/Scripts/Makefile modules/FvwmScript/Widgets/Makefile ) # --------------------------------------------------------------------------- # Original config.status is patched to make generated scripts executable. sed 's/> $ac_file/> $ac_file; test x"`head -1 $ac_file | cut -c1-2`" = x"#!" \&\& chmod a+rx $ac_file/' config.status-t && \ mv config.status-t config.status chmod +x config.status # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- cat >config.status-t <>config.status-t && \ mv config.status-t config.status chmod +x config.status # --------------------------------------------------------------------------- eval my_bindir="`eval echo ${bindir}`" eval my_mandir="`eval echo ${mandir}`" eval my_moddir="`eval echo ${FVWM_MODULEDIR}`"; eval my_moddir="$my_moddir" eval my_datdir="`eval echo ${FVWM_DATADIR}`" eval my_docdir="`eval echo ${FVWM_DOCDIR}`" eval my_plldir="`eval echo ${FVWM_PERLLIBDIR}`" test x"$FVWM_PERLLIB" = x && my_plldir="(Not installed) $my_plldir" eval my_localedir="`eval echo ${LOCALEDIR}`" test x"$USE_NLS" = xno && my_localedir="(Not installed) $my_localdir" echo " Fvwm Configuration: Version: $VERSION$VERSIONINFO Executables: $my_bindir Man pages: $my_mandir Modules: $my_moddir Data files: $my_datdir Doc files: $my_docdir Perl lib: $my_plldir Locale msg: $my_localedir $INST_LINGUAS With Asian bi-direct. text support? $with_bidi$problem_bidi With Gettext Native Lang support? $with_gettext$problem_gettext With Iconv support? $with_iconv_type$problem_iconv With Mouse strokes (gestures)? $with_stroke$problem_stroke With ReadLine sup. in FvwmConsole? $with_readline$problem_readline With RPlay support in FvwmEvent? $with_rplay$problem_rplay With Shaped window support? $with_shape$problem_shape With Shared memory for XImage? $with_shm$problem_shm With Session Management support? $with_sm$problem_sm With SVG image support? $with_rsvg$problem_rsvg With Xcursor support? $with_xcursor$problem_xcursor With Xinerama multi-head support? $with_xinerama$problem_xinerama With Xft anti-alias font support? $with_xft$problem_xft With XPM image support? $with_xpm$problem_xpm With Xrender image support? $with_xrender$problem_xrender Build man pages? $with_mandoc$problem_mandoc Build HTML documentation? $with_htmldoc$problem_htmldoc " case "$with_xinerama_emulation" in yes) echo " Xinerama emulation enabled." ;; esac case "$ac_cv_dmalloc" in yes) echo " DMALLOC heap debugging library enabled." ;; esac case "$ac_cv_efence" in yes) echo " EFENCE debugging library enabled." ;; esac fvwm-2.6.7/bin/0000755000175700017570000000000013010103344010261 500000000000000fvwm-2.6.7/bin/fvwm-perllib.in0000644000175700017570000003703512750325036013165 00000000000000#!@PERL@ # Copyright (c) 2002-2009 Mikhael Goikhman # # 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 # Filter this script to pod2man to get a man page: # pod2man -c "Fvwm Utilities" fvwm-perllib | nroff -man | less -e #use strict; # comment to make it faster BEGIN { # use vars qw($prefix $datarootdir $datadir $perllibdir); $prefix = "@prefix@"; $datarootdir = "@datarootdir@"; $datadir = "@datadir@"; $perllibdir = "@FVWM_PERLLIBDIR@"; # try to do it as fast as possible if ($ARGV[0] eq 'dir') { print $perllibdir; exit(0); } } use Getopt::Long; use lib $perllibdir; use General::FileSystem '-die'; my $version = "@VERSION@"; my $version_info = "@VERSIONINFO@"; my $pager = $ENV{PAGER} || "less -e"; my $do_man = 0; my $do_cat = 0; my $do_raw = 0; GetOptions( "help|h|?" => \&show_help, "version|v|V" => \&show_version, "man" => \$do_man, "cat" => \$do_cat, "raw" => \$do_raw, "dir" => sub { print $perllibdir; exit(0); }, ) || wrong_usage(); if ($ARGV[0] eq 'man') { $do_man = 1; shift; } elsif ($ARGV[0] eq 'cat') { $do_cat = 1; shift; } elsif ($ARGV[0] eq 'raw') { $do_raw = 1; shift; } wrong_usage() if !$do_man && !$do_cat && !$do_raw || @ARGV > 1; my $man_or_cat_str = $do_man || $do_raw ? "man" : "cat"; my $internal_pods = {}; $internal_pods->{index} = qq{ :head1 NAME index - lists all available help topics :head1 DESCRIPTION Recent I versions install the Perl library that makes creating fvwm modules in Perl possible and easy. You may read the Perl library documentation locally by running: % fvwm-perllib $man_or_cat_str Available topics: index tutorial events {{CLASS_NAMES}} For example: % fvwm-perllib $man_or_cat_str FVWM::Module :head1 AUTHOR Mikhael Goikhman . }; $internal_pods->{tutorial} = q{ :head1 NAME tutorial - common techniques for writting fvwm modules :head1 TUTORIAL :head2 What is a window manager A window manager is a program that runs on top of the X Window System and manages windows, menus, key and mouse bindings, virtual desktops and pages, draws window decorations using defined colors or images, title-bar buttons and fonts. The window manager defines window placement and focus policies. It may also manage such things as root background, mouse cursors, sounds, run applications and do other nice things. :head2 What is a module In the unix traditions, different functionality may be implemented by separate programs to reduce a bloat. A module is an optional program that is intended to extend the window manager using a defined module protocol. Fvwm modules are spawned by the main I executable. They usually listen to the window manager events, do some useful work and send back commands for execution. There are transient modules that exit immediately or shortly, and persistent modules that exit together with a window manager or when a user requests. Some modules may control windows or other modules. Some modules may supply a GUI, others may be non interactive. :head2 Creating a simple module Let's create a module that shows a flash window for one second when you change pages. We will use I with nifty options for our flash purposes, but you may use your fantasy to do this better. First, we should understand when our module works. Usually a module does nothing (sleeps) and is awaken when something interesting happens. This is achieved using events. A module defines events that it is interesting to receive and set-ups event handlers (perl functions) to be called when the event happens. Then a module enters the event loop where it sleeps all the time until one or another event happens. Most of the module work is done in the event handlers. When an event is processed, the module enters the event loop again. In our case, we should listen to an fvwm event I. The list of all events may be found in man page "events". When we receive the event we want to get new page coordinates and display them using our special xmessage window. Now, from theory to practice. The header of all modules written in Perl is pretty standard: #!/usr/bin/perl -w use lib `fvwm-perllib dir`; use FVWM::Module; Then create the actual module object: my $module = new FVWM::Module( Mask => M_NEW_PAGE | M_NEW_DESK, Debug => 1, ); The B option tells to print the event names that a module receives to help writing a module, it also echoes all sent commands. The B option tells which events a module wants to receive, in our case these are events generated on the page and desk changes. To handle events, event handlers that are perl functions, should be defined. It is ok not to define any event handler for I and to define two event handlers for I. But for our purposes one I would be more than enough: $module->add_handler(M_NEW_PAGE, \&got_new_page); It is a time to implement our C function that will be called every time the desktop page is changed. sub got_new_page { my ($module, $event) = @_; my $width = $event->_vp_width; my $height = $event->_vp_height; if (!$width || !$height) { # this may happen when doing DeskTopSize 1x1 on page 2 2 return; } my $page_nx = int($event->_vp_x / $width); my $page_ny = int($event->_vp_y / $height); # actually show the flash $module->send("Exec xmessage -name FlashWindow \ -bg cyan -fg white -center -timeout 1 -button '' \ -xrm '*cursorName: none' -xrm '*borderWidth: 2' \ -xrm '*borderColor: yellow' -xrm '*Margin: 12' \ '($page_nx, $page_ny)'"); } All event handlers are called with 2 parameters, a module and an event objects. The arguments for all events are defined in L. Each event type has its own arguments. Our I has 5 arguments: vp_x vp_y desk vp_width vp_height. We should do some calculations to get the page numbers from viewport coordinates. The B method passes the command to I for execution. It would be better to set-up the FlashWindow specially: $module->send("Style FlashWindow StaysOnTop, NoTitle, NoHandles, \ BorderWidth 10, WindowListSkip, NeverFocus, UsePPosition"); Finally, all persistent modules should enter the event loop: $module->event_loop; The full module source that we just wrote is available at ftp://ftp.fvwm.org/pub/fvwm/devel/sources/tests/perl/module-flash . To run it execute this fvwm command: Module /path/to/module-flash To kill the module, execute: KillModule /path/to/module-flash :head2 Using event trackers In fact, the task of calculating page coordinates, or managing information about all windows, or gathering colorset, module or global information is so often, that there are existing implentation in the form of event trackers. Tracker is an instance of L superclass. Currently these tracker classes are available (see their man pages): FVWM::Tracker::Colorsets FVWM::Tracker::GlobalConfig FVWM::Tracker::ModuleConfig FVWM::Tracker::PageInfo FVWM::Tracker::Scheduler FVWM::Tracker::WindowList Using a tracker is easy, something along lines: my $tracker = $module->track("WindowList"); my $colorset_tracker = $module->track("Colorsets"); Our module that we wrote above may be reduced if we use: my $viewport = $module->track("PageInfo"); my $page_nx = $viewport->data("page_nx"); my $page_ny = $viewport->data("page_ny"); Note that the tracker continues to work and maintain the up-to-date information about the current page and desk (or up-to-date windows or colorsets depending on the tracker type) at any given moment. Internally, trackers listen to appropriate events using the same event handler mechanism, so there is no speed advantage. However it is a good idea to reuse the existing verified code and reduce the number of events needed to be trapped manually. There is usually no problem if the developer and the tracker define handlers for the same events (besides the handler order maybe). :head2 On the module masks In our example above we explicitly defined Mask in constructor. This is not really needed. If not specified, the event mask is managed automatically (it is updated every time a new event handler is added). Note, there are actually two event masks, called "mask" and "xmask" (extended mask). If you are interested in the details, refer to the fvwm documentation or perllib sources. When trackers are added or removed, the module mask (and xmask) are automatically tweaked underhand. In short, there is often no reason to worry about the module masks. However, in rare cases you may want to define SyncMask (or SyncXMask), so that fvwm is synchronized with the module on certain events. :head2 Creating a more functional module Let's extend our new-page-flash example above and add a way to stop our module and to define another string format. This would be possible using the following I commands: SendToModule /path/to/module-flash stop SendToModule /path/to/module-flash format '[%d %d]' To handle such commands, we should define I event handler. use General::Parse; my $format = "(%d, %d)"; # the default format $module->mask($module->mask | M_STRING); $module->add_handler(M_STRING, sub { my ($module, $event) = @_; my $line = $event->_text; my ($action, @args) = get_tokens($line); if ($action eq "stop") { $module->terminate; } elsif ($action eq "format") { $format = $args[0]; } }); :head1 EXAMPLES Currently see I for examples. Learning the sources of B, B modules may help too. :head1 SEE ALSO See L for the module API. :head1 AUTHOR Mikhael Goikhman . }; $internal_pods->{events} = q{ :head1 NAME events - list of all fvwm events with arguments :head1 DESCRIPTION This list is automatically generated from L package. Given L object of certain event type, say I, here is the syntax to get value of its I argument: $win_id = $event->_win_id; There are several more ways to access arguments, like: $win_id = $event->arg_values->[0]; $text = $event->args->{text}; :head1 EVENTS WITH ARGUMENTS {{EVENT_NAMES}} :head1 ARGUMENT TYPE LEGEND Here is a mapping of fvwm argument types to perl native types: number - integer bool - boolean, true or false window - X window id in decimal, use sprintf("0x%07x", $wid) pixel - "rgb:" . join('/', sprintf("%06lx", $val) =~ /(..)(..)(..)/) string - string (scalar) wflags - window flags in binary string looped - loop of zero or more fixed argument bunches Run L to browse events. :head1 SEE ALSO See "tutorial", L, L and L. :head1 AUTHOR Mikhael Goikhman . }; my $topic = $ARGV[0] || "index"; my $file = "-"; my $text = ""; if (exists $internal_pods->{$topic}) { $text = $internal_pods->{$topic}; $text =~ s/^\t//mg; $text =~ s/^:/=/mg; if ($topic eq 'index') { my @class_names = sort @{list_filenames($perllibdir, 1)}; @class_names = map { s!\.pm$!!; s!/!::!g; $_ } @class_names; $text =~ s/{{CLASS_NAMES}}/join("\n ", @class_names)/seg; } if ($topic eq 'events') { my $content = `cat '$perllibdir/FVWM/EventNames.pm'`; my $result = ""; foreach ($content =~ /\t&([^\s]+.*?\t\tfields[^\n]+(?:\n\t\t\t[^\n]+)*)/sg) { my ($name, $rest) = /^([^\s]+).*?((?:\n\t\t\t[^\n]+)*)$/s; # ] $result .= " $name\n"; $rest =~ s/([^\s]+)\s*=>\s*([\w]+)/ $result .= sprintf(" %-16s\t%s\n", $1, $2) /eg; $result .= "\n"; } $text =~ s!{{EVENT_NAMES}}!$result!se; } } else { $file = "$perllibdir/$topic.pm"; $file =~ s!::!/!g; die "No $file found.\n" unless -f $file; } my $man_converter = $do_man ? " | nroff -man | $pager" : ""; open(MANPIPE, $do_cat ? "| pod2text '$file' | $pager" : "| pod2man --section 3 --release 'fvwm $version$version_info'" . " --center 'Fvwm Perl library' '$file'" . " | @SED@ 's//perllib/ig'$man_converter") or die "Can't open pipe to pod/man viewer\n"; print MANPIPE $text or die "Can't write to pod/man viewer\n"; close MANPIPE; # --------------------------------------------------------------------------- sub show_help { print "Shows documentation of the supplied FVWM Perl library.\n\n"; print "Usage: fvwm-perllib man|cat\n"; print "\tAn introduction to the FVWM Perl library\n\n"; print "Usage: fvwm-perllib man|cat|raw \n"; print "\tManual page for , try: man FVWM::Module\n"; print "\t\$PAGER is used for a pager, the default is '$pager'\n\n"; print "Usage: fvwm-perllib dir\n"; print "\tFor use in fvwm modules written in Perl\n\n"; print "Usage: fvwm-perllib [OPTIONS]\n"; print "Options:\n"; print "\t--help show this help and exit\n"; print "\t--version show the version and exit\n"; exit 0; } sub show_version { print "$version\n"; exit 0; } sub wrong_usage { print STDERR "Try '$0 --help' for more information.\n"; exit -1; } __END__ # --------------------------------------------------------------------------- =head1 NAME fvwm-perllib - shows the documentation of the Fvwm Perl library =head1 SYNOPSIS B [ B<--help>|B<-h>|B<-?> ] [ B<--version>|B<-v>|B<-V> ] [ B [ I ] ] [ B [ I ] ] [ B [ I ] ] [ B