From ef546fc3693aa9a578085c20f032dd180e00b56a Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Thu, 22 Jan 2015 17:00:43 -0600 Subject: [PATCH] wmmenu: Add version 1.2 to repository. Obtained from [1] at the request of Nerijus Baliunas [2]. [1] https://web.archive.org/web/20110720231607/http://www.fcoutant.freesurf.fr/download/wmmenu-1.2.tar.gz [2] http://lists.windowmaker.org/dev/msg07991.html --- wmmenu/COPYING | 340 +++++++++++++++++++++++++++++++ wmmenu/Makefile | 70 +++++++ wmmenu/README | 331 ++++++++++++++++++++++++++++++ wmmenu/TODO | 10 + wmmenu/buttonbar.c | 241 ++++++++++++++++++++++ wmmenu/buttonbar.h | 12 ++ wmmenu/defaultIcon.xpm | 302 +++++++++++++++++++++++++++ wmmenu/defaultTile.xpm | 197 ++++++++++++++++++ wmmenu/error.c | 32 +++ wmmenu/error.h | 8 + wmmenu/events.c | 251 +++++++++++++++++++++++ wmmenu/events.h | 7 + wmmenu/example/apps | 11 + wmmenu/example/defaults | 26 +++ wmmenu/example/extract_icon_back | 61 ++++++ wmmenu/menu.c | 196 ++++++++++++++++++ wmmenu/menu.h | 19 ++ wmmenu/options.c | 305 +++++++++++++++++++++++++++ wmmenu/options.h | 41 ++++ wmmenu/pixmaps.c | 238 ++++++++++++++++++++++ wmmenu/pixmaps.h | 10 + wmmenu/target-white.xpm | 69 +++++++ wmmenu/types.h | 16 ++ wmmenu/utils.c | 183 +++++++++++++++++ wmmenu/utils.h | 17 ++ wmmenu/version.h | 12 ++ wmmenu/wmmenu.1 | 196 ++++++++++++++++++ wmmenu/wmmenu.c | 36 ++++ wmmenu/xobjects.c | 11 + wmmenu/xobjects.h | 13 ++ 30 files changed, 3261 insertions(+) create mode 100644 wmmenu/COPYING create mode 100644 wmmenu/Makefile create mode 100644 wmmenu/README create mode 100644 wmmenu/TODO create mode 100644 wmmenu/buttonbar.c create mode 100644 wmmenu/buttonbar.h create mode 100644 wmmenu/defaultIcon.xpm create mode 100644 wmmenu/defaultTile.xpm create mode 100644 wmmenu/error.c create mode 100644 wmmenu/error.h create mode 100644 wmmenu/events.c create mode 100644 wmmenu/events.h create mode 100644 wmmenu/example/apps create mode 100644 wmmenu/example/defaults create mode 100755 wmmenu/example/extract_icon_back create mode 100644 wmmenu/menu.c create mode 100644 wmmenu/menu.h create mode 100644 wmmenu/options.c create mode 100644 wmmenu/options.h create mode 100644 wmmenu/pixmaps.c create mode 100644 wmmenu/pixmaps.h create mode 100644 wmmenu/target-white.xpm create mode 100644 wmmenu/types.h create mode 100644 wmmenu/utils.c create mode 100644 wmmenu/utils.h create mode 100644 wmmenu/version.h create mode 100644 wmmenu/wmmenu.1 create mode 100644 wmmenu/wmmenu.c create mode 100644 wmmenu/xobjects.c create mode 100644 wmmenu/xobjects.h diff --git a/wmmenu/COPYING b/wmmenu/COPYING new file mode 100644 index 0000000..eeb586b --- /dev/null +++ b/wmmenu/COPYING @@ -0,0 +1,340 @@ + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/wmmenu/Makefile b/wmmenu/Makefile new file mode 100644 index 0000000..0a0c193 --- /dev/null +++ b/wmmenu/Makefile @@ -0,0 +1,70 @@ +prefix = /usr/local +BINDIR = $(prefix)/bin +MANDIR = $(prefix)/man +ETCDIR = $(prefix)/etc + +# comment out both lines to get the old, Xpm-only, version +GDKPIXBUF = 1 +#GDKPIXBUF2 = 1 + +XROOT = /usr/X11R6 +DAROOT = /usr/local + +# If you want to use gdk-pixbuf, pass GDKPIXBUF=1 to make command +ifdef GDKPIXBUF +PIXBUF_DEF = -DWITH_GDKPIXBUF +PIXBUF_INC := $(shell gdk-pixbuf-config --cflags) +PIXBUF_LIB := -rdynamic -L$(shell gdk-pixbuf-config --prefix)/lib -lgdk_pixbuf_xlib +endif + +# If you want to use gdk-pixbuf-2.0, pass GDKPIXBUF2=1 to make command +ifdef GDKPIXBUF2 +PIXBUF_CFG = /opt/gtk2/bin/pkg-config gdk-pixbuf-xlib-2.0 +PIXBUF_DEF = -DWITH_GDKPIXBUF +PIXBUF_INC := $(shell $(PIXBUF_CFG) --cflags) +PIXBUF_LIB := -rdynamic -L$(shell $(PIXBUF_CFG) --variable=prefix)/lib -lgdk_pixbuf_xlib-2.0 +endif + +CC = gcc #-g +CFLAGS = -pipe $(CPPFLAGS) -O2 +CPPFLAGS = -MMD -ansi -pedantic -Wall $(INCDIRS) $(DEFINES) +INCDIRS = -I$(DAROOT)/include -I$(XROOT)/include $(PIXBUF_INC) +DEFINES = -DETCDIR='"$(ETCDIR)"' $(PIXBUF_DEF) +LDFLAGS = -s +LIBDIRS = -L$(DAROOT)/lib -L$(XROOT)/lib $(PIXBUF_LIB) +LDLIBS = -ldockapp -lXpm -lXext -lX11 -lm + +MKDIRHIER = mkdir -p +MAN1DIR = $(MANDIR)/man1 + +SRCS1 = \ + wmmenu.c options.c error.c menu.c utils.c pixmaps.c \ + xobjects.c buttonbar.c events.c + +OBJS1 = $(SRCS1:.c=.o) +PRGS = wmmenu +MAN1 = $(PRGS:%=%.1) + +RM = rm -f +INSTBIN = install -c +INSTMAN = install -c + +all : $(PRGS) + +.c.o : + $(CC) $(CFLAGS) -c $< + +wmmenu : $(OBJS1) + $(CC) $(LDFLAGS) -o $@ $(OBJS1) $(LIBDIRS) $(LDLIBS) + +install : $(PRGS) $(MAN1) + $(MKDIRHIER) $(BINDIR) + $(INSTBIN) $(PRGS) $(BINDIR) + $(MKDIRHIER) $(MAN1DIR) + $(INSTMAN) $(MAN1) $(MAN1DIR) + +clean : + $(RM) *.o *.d core tags $(PRGS) + +# dependencies -- do not change lines below +-include *.d diff --git a/wmmenu/README b/wmmenu/README new file mode 100644 index 0000000..0872350 --- /dev/null +++ b/wmmenu/README @@ -0,0 +1,331 @@ +WHAT IS IT +---------- + +This is a "dock application" for Windowmaker, that provides a button bar to +launch applications from. + +The bar opens automatically when either the mouse enters the button or you +click on it (this is configurable). + +Multiple instances of the program can run at the same time: each one provides +a menu that it reads from a separate file, so you can have as many different +menus as you want (you can also display the same menu more than once if you +want; dunno what it's useful for...). + +REQUIREMENTS +------------ + + Xlib, Xpm, libdockapp. + + By default only XPM format icons can be loaded. If you have + gdk-pixbuf (>= 0.9.0) installed, you can build wmmenu with it and all + image types supported by gdk-pixbuf will be loadable by wmmenu. + + NB: + - gdk-pixbuf 0.8.0 might work, but I didn't check + - the new gdk-pixbuf (2.0) provided with Gtk+ 2.0 is currently + broken: the Xlib part doesn't seem to be able to compile + without Gdk any more, making it useless. I have included + Makefile definitions so that you can check by yourself (please + complain to the maintainer(s) of gdk-pixbuf-xlib). + +LIBDOCKAPP WARNING +------------------ + +There is a bug in libdockapp-0.4.0: it does not setup the dockapp's title +correctly, and wmmenu appears as being named "DockApp". This prevents +using several wmmenus in WMaker's dock. + +To correct this, apply the following one-change patch: + +======================================================================== +diff -ru libdockapp-0.4.0.orig/src/damain.c libdockapp-0.4.0/src/damain.c +--- libdockapp-0.4.0.orig/src/damain.c Mon Feb 14 11:08:04 2000 ++++ libdockapp-0.4.0/src/damain.c Sat May 4 13:59:30 2002 +@@ -67,7 +67,7 @@ + /* Set ClassHint */ + if (!(classHint = XAllocClassHint())) + printf("%s: can't allocate memory for class hints!\n", progName), exit(1); +- classHint->res_class = "DockApp"; ++ classHint->res_class = name; + classHint->res_name = name; + + XSetClassHint(DADisplay, DALeader, classHint); +======================================================================== + +I also found my Debian package "libdockapp-dev" version 0.61.1-5 to have a +bug regarding timers: If you use the hide_timeout option, you should +definitely recompile your own version. + +QUICKSTART +---------- + +1. Make a ".wmmenu" directory in your home directory: + + mkdir ~/.wmmenu + +2. You have to make at least one file containing the menu definition. It's + also strongly advised to make a second file named "defaults", to contain + general settings such as pixmaps paths. + The syntax of those files is quite easy (and is detailed below) but as a + start point you can copy the example files and edit them: + + [from the sources main directory] + cp example/[ad]* ~/.wmmenu + vi ~/.wmmenu/* + + The menu would then be named "apps". + +3. The file in ~/.wmmenu you have put a menu definition in, must have its + name (relative to ~/.wmmenu) passed as argument to wmmenu like this: + + wmmenu -m apps + +USAGE +----- + +wmmenu [...] + +-h + show help message +-m MENUNAME (mandatory) + set the name of the menu file to load from ~/.wmmenu +-g WxH + set width and height of tile +-t XPMFILE + set the pixmap used as tile +-l XPMFILE + set the pixmap used as highlight to track pointer +-O oldleaving + use old behavior for hiding the button bar: hide only when + leaving the bar, not when leaving the tile. +-O click + activate the button bar only when clicking on the tile, not + when the mouse moves in and out. +-O noautoscale + disable automatic scaling of pixmaps, that makes them fit + inside specified tile size. +-O behind + draw highlight pixmap behind icon, not above. +-O hide=N + set the time delay necessary for the bar to close after the + cursor has left wmmenu. N is specified as a strictly positive + integer in milliseconds. 1 is used by default. +-r ROWS + arrange icons in the bar on multiple rows (specified as the + number ROWS). The default is one. Icons are arranged leftmost + from upper left corner. + +The tile is used in conjunction with transparent pixmaps as a background. When +drawing the button bar, for each button, the tile is drawn first, then the +specified icon is drawn over it. + +The tile also determines the width and height of the button bar, as each +button pixmap is cut to the size of the tile if it's bigger, or centered over +it if it's smaller. The height of the bar is the height of the tile, and the +width of the bar is the width of the tile multiplied by the number of entries +specified for the displayed menu. + +I have included a facility to arbitrarily set tile geometry independently of +the pixmap tile's size, but not sure it's useful. + + +When run, wmmenu first reads a file named "defaults" in ~/.wmmenu, from which +it gets settings common to all menus, currently the pixmap path and tile +and highlight pixmap names. The pixmap path is used to set a list of paths +from which to search pixmap file names; At each place a pixmap file name is +requested, you can then use the file name without it's directory prepended +(leaving only the "basename"). + +The syntax of this file is roughly the following: comments start with # and +end at the end of the line they start on. Blank lines are allowed and always +meaningless. Other lines are variable setting and take the form + where does NOT contain newlines (all this +must be on the same line). can be: + . xpmpath is a colon-separated list of path indicating where to + search for pixmap files (i.e. /some/path1:/some/path2). + . tile is the file name of the pixmap to use as tile; Or + use ! to specify a command to execute, that will + return the name of the pixmap file name. + . highlight is the file name of the pixmap to use for pointer + tracking + +Multiple xpmpath definitions can occur and are merged together. A default +path of ~/.wmmenu is always prepended to the path list. + + +Then wmmenu reads the file specified by "-m" option from ~/.wmmenu directory. +This file specifies a list of buttons for the resulting menu, with the pixmap +to be used for the button and the command to be run when the corresponding +button is pressed. + +The syntax is the following: the file is a suite of lines. Each line can be: + . blank, it is ignored + . a comment: it starts with # and is ignored too + . a menu entry: the line is written as "". + +For each menu entry specifies the file name of the pixmap to be used +for the button, and specifies a shell command to be run when the +button is pressed. can specify an absolute file name as well as a +path-less name, in which case it is searched in the pixmap path specified in +the "defaults" file. usually has & at the end because wmmenu runs it +synchronously (it waits for its termination); since this is run by the shell +you can also use redirections and all sort of things if you want to. You are +free to embed blanks in as well as , since the syntax has +been done to allow it; you can also use double-quotes in , though +obviously you cannot use them for the name of the pixmap file. + +Finally the first entry defined is not used as a command button but for wmmenu +itself. The of this first entry is used as dockapp icon, and in the +future it's will be used as title appearing in WindowMaker's dockapp +balloon. + +STATUS +------ + +1.2 2002/05/04 + + (Thanks to Daniel Déchelotte for many bug fixes, patches and + suggestions) + + New behaviour: + - also show the bar when entering the dockapp's tile. Hide it + after cursor has left all wmmenu windows (bar, icon or tile). + - as a side effect, "oldleaving" option has been removed. + + Corrections: + - remove flicker when cursor goes from icon/tile to bar and + vice-versa. + - forgot to remove highlight pixmap when cursor leaves bar with + "-O click" behaviour. + - fixed "garbaged" highlight effects after menu file changes + - don't paint highlight pixmap on empty bar slots (those can occur + when spreading menu entries over several rows). + - don't crash when WM terminates (or changes). Gracefully handles + dock-less WM. (useful when I try new WMs) + - some updates to README (and warnings about libdockapp) + +1.1 2002/04/14 + + New feature: + - the tile can now be specified by the value returned by an + external command. A sample script, extract_icon_back, is + provided to get the icon pixmap used by WindowMaker. + NB: this command is only used once at startup. + + Correction: + - default tile pixmap is now also used when no tile pixmap is + specified at all (or an empty one). + +1.0 2002/03/23 + + New feature: if you want to use a highlight pixmap that's designed + to cover most of tile's surface, current highlighting is not + adequate, because the highlight pixmap is drawn OVER other pixmaps. + A new drawing mechanism has been added to draw it BEHIND other menu + icons. + + Added option "-O behind" to trigger this behaviour. + Also added "highlight_behind" directive in the defaults file, which + also triggers this behaviour. + Updated the sample defaults file. + Updated man page to reflect changes (have a look at it for details). + + Corrections: + - Disable autoscaling of the dockapp icon (didn't scale to the + appropriate size), until someone tells me how wmmenu/libdockapp + is supposed to work in case it's too big. + (reported by Daniel Déchelotte) + + NB: gdk-pixbuf 2.0 (provided with Gtk+ 2.0) is currently not + compatible with wmmenu (see REQUIREMENTS section). + +0.9 2001/10/20 + + When using the gdk-pixbuf enabled version, pixmaps larger than tile + (either the tile pixmap itself, or the size specified on command + line) are automatically scaled to fit within the requested size. + This affects the dock icon, tile, highlight and application icons. + If you like pixmaps overriding each other (gasp!), this can be + disabled with "-O noautoscale". + + Through the "highlight" feature you can set a pixmap, that is drawn + over the menu item currently designated by the pointer, and that + follows it. This allows one to know for sure, which item will be + launched if clicked. A pixmap "target-white.xpm" is provided as a + sample: try adding its path after "-l" option on your wmmenu's + command line. + + Pixmap file names and xpmpath elements accept "~/" at their + beginning, to refer to your home directory (this was suggested a + long time ago). + + I have written a man page (thanks to manedit). + +0.8 2001/06/16 + + Speedup startup by providing a different color allocation routine + to gdk-pixbuf. (Startup speedup is observed with gdk-pixbuf; + Patch from Lukasz Pankowski) + +0.7 2001/04/21 + + Integrated "multi-rows" patch from Lukasz Pankowski: icons can be + arranged in multiple rows on the button bar. For this you have to + specify "-r ROWS" on command line. + +0.6 2001/03/24 + + Added click-only behavior with "-O click" option. + (Thanks to Matthew Gabeler-Lee for his patch) + +0.5 2001/02/03 + + The button bar is now hidden when the cursor leaves the dockapp + tile, and not only when it leaves the button bar (behavior + suggested by Guido Falsi). + + I added an option the get the previous behavior. Please report + whether you need it, else it will disappear in next releases since + I consider the new behavior to be more user firendly. + +0.4 2000/12/30 + + Simplify gdk-pixbuf selection as build option in Makefile. + + New feature: automatic menu reloading on menu file change. + Default icons are used for app and tile when specified pixmap is not + found or not loadable (helps to not exit prematurely when doing + changes). + +0.3 2000/11/01 + + Optionally (choice made at compile-time) use gdk-pixbuf(-xlib) to load + images. This provides loading ability for many image types: BMP, GIF, + ICO, JPEG, PNG, PNM, RAS, TIFF and XPM (on my host at least). Don't + forget that transparency is not available with BMP, PNM and (?) RAS. + + Caveat: may not work very well on pseudo-color displays (not tested) + because of bad (blind) color allocation strategy. This was already + the case with libXpm, so it's not a so great change. + +0.2 2000/08/05 + + install target in Makefile. + Accept multiple xpmpath specifications in defaults file, they are + appended to each other. + More documentation (and more explicit on usage). + Missing Xext link library on some systems. + +0.1 2000/06/25 + + First public release. + +COPYRIGHT +--------- + +This software is copyright (c)2000 F.COUTANT, and is placed under the GNU +General Public License (GPL), which is given in the file COPYING. + +E-mail: fcoutant@freesurf.fr + diff --git a/wmmenu/TODO b/wmmenu/TODO new file mode 100644 index 0000000..59f2c01 --- /dev/null +++ b/wmmenu/TODO @@ -0,0 +1,10 @@ +* Horizontal/Vertical bar on option +* Animations ! +* Solidify parsers + +External suggestions +-------------------- + +From: Benoît Smith +- drop app into the bar directly like in the dock + diff --git a/wmmenu/buttonbar.c b/wmmenu/buttonbar.c new file mode 100644 index 0000000..210318a --- /dev/null +++ b/wmmenu/buttonbar.c @@ -0,0 +1,241 @@ +#include + +#include + +#include "buttonbar.h" +#include "xobjects.h" +#include "pixmaps.h" +#include "options.h" +#include "menu.h" + +/* item number for last known highlight position */ +static int OldPos = -1 ; +/* Graphic context used to draw highlight */ +static GC HighlightGC = 0 ; +/* position where bar will be shown next time */ +static int BarX=0, BarY=0 ; + +extern void ButtonBar_Build (void) +{ + int i, n ; + int h, j, w ; + int width, height ; + GC imgOp ; + GC maskOp ; + XGCValues gc ; + Pixmap image, mask ; + int x, y ; + int x0, y0 ; + XSetWindowAttributes wa ; + + n = Menu_GetNbEntries () ; + assert (n > 0) ; + h = Menu_GetNbRows () ; + w = Menu_GetNbColumns () ; + width = TileXSize * w ; + height = TileYSize * h ; + + + ButtonBarWindow = XCreateSimpleWindow ( + DADisplay, DefaultRootWindow (DADisplay), 0, 0, width, height, 0, + BlackPixel (DADisplay, DefaultScreen (DADisplay)), + BlackPixel (DADisplay, DefaultScreen (DADisplay))) ; + ButtonBarImage = XCreatePixmap (DADisplay, ButtonBarWindow, + width, height, DADepth) ; + imgOp = XCreateGC (DADisplay, ButtonBarWindow, 0, & gc) ; + + HighlightBehindMask = XCreatePixmap (DADisplay, ButtonBarWindow, + width, height, 1) ; + maskOp = XCreateGC (DADisplay, HighlightBehindMask, 0, & gc) ; + + /* first apply tile to whole bar */ + for (i=0; i= TileXSize ? 0 : (TileXSize-width)/2) ; + y = (height >= TileYSize ? 0 : (TileYSize-height)/2) ; + + /* use GC to draw with pixmap's mask in the right cell */ + x0 = TileXSize*(i/h) ; + y0 = TileYSize*(i%h) ; + gc.clip_x_origin = x0 + x ; + gc.clip_y_origin = y0 + y ; + gc.clip_mask = mask ; /* may be None */ + XChangeGC (DADisplay, imgOp, + GCClipXOrigin | GCClipYOrigin | GCClipMask, & gc) ; + XCopyArea (DADisplay, image, ButtonBarImage, imgOp, 0, 0, + width, height, gc.clip_x_origin, gc.clip_y_origin) ; + + /* update highlight behind mask: cell &= ~iconmask */ + if (HighlightBehind && mask != None) + { + /* use "andInverted" (dst &= ~src) */ + XSetFunction (DADisplay, maskOp, GXandInverted) ; + XCopyArea (DADisplay, mask, HighlightBehindMask, maskOp, + 0, 0, width, height, gc.clip_x_origin, gc.clip_y_origin) ; + } + /* or highlight behind cell &= 0 if no mask */ + else + if (HighlightBehind && mask == None) + { + XSetFunction (DADisplay, maskOp, GXclear) ; + XFillRectangle (DADisplay, HighlightBehindMask, maskOp, + gc.clip_x_origin, gc.clip_y_origin, width, height) ; + } + + XFreePixmap (DADisplay, image) ; + if (mask != 0) XFreePixmap (DADisplay, mask) ; + } + + XFreeGC (DADisplay, imgOp) ; + XFreeGC (DADisplay, maskOp) ; + + wa.background_pixmap = ButtonBarImage ; + wa.event_mask = ButtonPressMask | ButtonReleaseMask ; + if (! ClickOnly) wa.event_mask |= EnterWindowMask | LeaveWindowMask ; + if (HighlightImage != 0) wa.event_mask |= PointerMotionMask ; + wa.override_redirect = True ; + XChangeWindowAttributes (DADisplay, ButtonBarWindow, + CWBackPixmap | CWEventMask | CWOverrideRedirect, & wa) ; +} + +extern void ButtonBar_SetPositionFromDockApp (int dockx, int docky, + int dockw, int dockh) +{ + int xMid, scrWidth, h, scrHeight ; + int x, y ; + + /* compute y */ + scrHeight = DisplayHeight (DADisplay, DefaultScreen (DADisplay)) ; + y = docky ; + h = TileYSize * Menu_GetNbRows () ; + if (y + h >= scrHeight) + { + y = scrHeight - h ; + } + + /* compute x */ + scrWidth = DisplayWidth (DADisplay, DefaultScreen (DADisplay)) ; + xMid = dockx + dockw/2 ; + if (xMid*2 < scrWidth) + { + /* we are rather on left, expand to right */ + x = dockx + dockw ; + } + else + { + /* we are rather on right, expand to left */ + x = dockx - TileXSize * Menu_GetNbColumns () ; + } + + BarX = x ; + BarY = y ; +} + +extern void ButtonBar_Show (void) +{ + XMoveWindow (DADisplay, ButtonBarWindow, BarX, BarY) ; + XMapRaised (DADisplay, ButtonBarWindow) ; +} + +static void BuildHighlightGC (void) +{ + XGCValues gc ; + gc.clip_mask = HighlightBehindMask ; + HighlightGC = XCreateGC (DADisplay, DAWindow, + GCClipMask, & gc) ; +} + +extern void ButtonBar_Highlight (int col, int row) +{ + int h ; + int newPos ; + + if (HighlightImage == 0) return ; + + h = Menu_GetNbRows () ; + newPos = col*h + row ; + + if (newPos != OldPos) + { + int x, y ; + XGCValues gc ; + + /* first clear old highlight position */ + ButtonBar_Unhighlight () ; + + /* don't draw highlight on empty slots */ + if (newPos >= Menu_GetNbEntries ()) return ; + + /* compute new draw position */ + x = col * TileXSize ; + y = row * TileYSize ; + /* and draw it */ + if (HighlightGC == 0) BuildHighlightGC () ; + gc.clip_x_origin = HighlightBehind ? 0 : x ; + gc.clip_y_origin = HighlightBehind ? 0 : y ; + XChangeGC (DADisplay, HighlightGC, + GCClipXOrigin | GCClipYOrigin, & gc) ; + XCopyArea (DADisplay, HighlightImage, ButtonBarWindow, + HighlightGC, 0, 0, TileXSize, TileYSize, x, y) ; + + OldPos = newPos ; + } +} + +extern void ButtonBar_Unhighlight (void) +{ + int x, y, h ; + + if (HighlightImage == 0 || OldPos < 0) return ; + + h = Menu_GetNbRows () ; + x = (OldPos / h) * TileXSize ; + y = (OldPos % h) * TileYSize ; + XClearArea (DADisplay, ButtonBarWindow, + x, y, TileXSize, TileYSize, False) ; + OldPos = -1 ; +} + +extern void ButtonBar_Hide (void) +{ + XUnmapWindow (DADisplay, ButtonBarWindow) ; + OldPos = -1 ; +} + +extern void ButtonBar_Rebuild (void) +{ + XDestroyWindow (DADisplay, ButtonBarWindow) ; + if (HighlightGC != 0) + { + XFreeGC (DADisplay, HighlightGC) ; + HighlightGC = 0 ; + } + OldPos = -1 ; + ButtonBar_Build () ; +} diff --git a/wmmenu/buttonbar.h b/wmmenu/buttonbar.h new file mode 100644 index 0000000..14bf830 --- /dev/null +++ b/wmmenu/buttonbar.h @@ -0,0 +1,12 @@ +#ifndef buttonbar_h_ +#define buttonbar_h_ + +extern void ButtonBar_Build (void) ; +extern void ButtonBar_SetPositionFromDockApp (int x, int y, int w, int h) ; +extern void ButtonBar_Show (void) ; +extern void ButtonBar_Highlight (int col, int row) ; +extern void ButtonBar_Unhighlight (void) ; +extern void ButtonBar_Hide (void) ; +extern void ButtonBar_Rebuild (void) ; + +#endif /* buttonbar_h_ */ diff --git a/wmmenu/defaultIcon.xpm b/wmmenu/defaultIcon.xpm new file mode 100644 index 0000000..cf6298e --- /dev/null +++ b/wmmenu/defaultIcon.xpm @@ -0,0 +1,302 @@ +/* XPM */ +static char *defaultIcon_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 43 48 247 2", +/* colors */ +".. c #040204", +".# c #44863c", +".a c #34420c", +".b c #58c404", +".c c #746a0c", +".d c #0f2217", +".e c #476a3f", +".f c #343204", +".g c #aecc04", +".h c #344454", +".i c #a08a04", +".j c #1c223c", +".k c #c4c6ac", +".l c #54591b", +".m c #9c9c9e", +".n c #3c562c", +".o c #4caa24", +".p c #446e4c", +".q c #2c3516", +".r c #3c433a", +".s c #8ac604", +".t c #3c5460", +".u c #0c131a", +".v c #74881c", +".w c #343949", +".x c #242304", +".y c #eac404", +".z c #dce6ec", +".A c #243245", +".B c #acaeac", +".C c #141304", +".D c #c1a604", +".E c #7c838c", +".F c #5c6254", +".G c #444649", +".H c #447c44", +".I c #7ce404", +".J c #0c2226", +".K c #543e34", +".L c #545655", +".M c #646e7c", +".N c #c8ce04", +".O c #3c427c", +".P c #ccd2d8", +".Q c #5cda04", +".R c #141524", +".S c #8c929c", +".T c #44490d", +".U c #846654", +".V c #b4ba9c", +".W c #343c68", +".X c #e0d804", +".Y c #243254", +".Z c #5c636c", +".0 c #242627", +".1 c #1c2531", +".2 c #444a54", +".3 c #1c2b3d", +".4 c #9cc204", +".5 c #f4f4f4", +".6 c #040a0b", +".7 c #6c8514", +".8 c #3c4a34", +".9 c #647e14", +"#. c #848b91", +"## c #ac8664", +"#a c #bcc2cc", +"#b c #9ca6ac", +"#c c #3c5248", +"#d c #445878", +"#e c #1a1b04", +"#f c #484e10", +"#g c #b0df04", +"#h c #b49604", +"#i c #363e46", +"#j c #444d34", +"#k c #545a61", +"#l c #c8db04", +"#m c #60e904", +"#n c #a47e64", +"#o c #6c6a6c", +"#p c #040a14", +"#q c #69c304", +"#r c #69630c", +"#s c #7ca21c", +"#t c #2c3a1c", +"#u c #ececed", +"#v c #d4dadc", +"#w c #747981", +"#x c #b4bbbf", +"#y c #383e28", +"#z c #fcd404", +"#A c #646a6f", +"#B c #242c2c", +"#C c #2c2e4f", +"#D c #70e904", +"#E c #84770c", +"#F c #3c4d59", +"#G c #9e9e06", +"#H c #544a44", +"#I c #9ca2a8", +"#J c #34464c", +"#K c #8ecb04", +"#L c #445e64", +"#M c #041c15", +"#N c #bcb6b4", +"#O c #a0dd04", +"#P c #343e11", +"#Q c #141c25", +"#R c #1c2a33", +"#S c #dabb04", +"#T c #64921c", +"#U c #747e84", +"#V c #3c4722", +"#W c #4c545d", +"#X c #f5cb04", +"#Y c #2c364c", +"#Z c #acb0b5", +"#0 c #142a34", +"#1 c #949ca0", +"#2 c #2c3a5e", +"#3 c #646664", +"#4 c #242c3f", +"#5 c #6c7a24", +"#6 c #919e0c", +"#7 c #69b904", +"#8 c #747637", +"#9 c #948a04", +"a. c #499a21", +"a# c #52d104", +"aa c #64d604", +"ab c #545644", +"ac c #5c622c", +"ad c #a4d004", +"ae c #8ca60c", +"af c #5cb604", +"ag c #1b2d14", +"ah c #444a8c", +"ai c #342a24", +"aj c #54782c", +"ak c #c4ccd0", +"al c #3c5e3c", +"am c #646a2c", +"an c #dcce04", +"ao c #bcb204", +"ap c #c4a204", +"aq c #2c2c04", +"ar c #645e0c", +"as c #5c7830", +"at c #4c522c", +"au c #ac9604", +"av c #fcfafb", +"aw c #1c2204", +"ax c #ac9204", +"ay c #446667", +"az c #d4d604", +"aA c #ecd404", +"aB c #bcdd04", +"aC c #3c4374", +"aD c #384d4a", +"aE c #4c5a3c", +"aF c #6c7684", +"aG c #6c8a14", +"aH c #2c322f", +"aI c #94c404", +"aJ c #cca904", +"aK c #d4da04", +"aL c #e4bd04", +"aM c #748e0c", +"aN c #646a54", +"aO c #545e3c", +"aP c #74d604", +"aQ c #ccb204", +"aR c #39393b", +"aS c #181c1c", +"aT c #474b4c", +"aU c #242e18", +"aV c #ccceb4", +"aW c #484e55", +"aX c #8c7e04", +"aY c #b4b6b6", +"aZ c #5e7e2c", +"a0 c #7c720c", +"a1 c #b4d204", +"a2 c #c7d604", +"a3 c #a4ca04", +"a4 c #dbb604", +"a5 c #445e6c", +"a6 c #444e20", +"a7 c #373e59", +"a8 c #62ee04", +"a9 c #74aa1c", +"b. c #383e3c", +"b# c #a3e204", +"ba c #4cd604", +"bb c #9fd604", +"bc c #343234", +"bd c #648a2c", +"be c #141519", +"bf c #2c3b34", +"bg c #3c4264", +"bh c #5c560c", +"bi c #e4e4e4", +"bj c #b4b29c", +"bk c #84868d", +"bl c #14252f", +"bm c #6c7278", +"bn c #3c3a04", +"bo c #949699", +"bp c #3c3e71", +"bq c #8c8e9a", +"br c #a4a7a6", +"bs c #5c5d60", +"bt c #dcdede", +"bu c #bcbcbc", +"bv c #1c1e33", +"bw c #445d41", +"bx c #7cea04", +"by c #64625c", +"bz c #a4a2a3", +"bA c #3c3e06", +"bB c #7c7e85", +"bC c #5c5e4c", +"bD c #3c440a", +"bE c #24253e", +"bF c #cccab0", +"bG c #445a28", +"bH c #445264", +"bI c #444683", +"bJ c #d4d3d4", +"bK c #4c4a0f", +"bL c #bcbea4", +"bM c #2c3658", +"bN c #0c0c08", +"bO c #c4c4c4", +"bP c #4c4e3c", +"bQ c #0c0d14", +"bR c #f4eeec", +"bS c #2c2c32", +"bT c #8c7a04", +"bU c #3c4349", +"bV c #0c1e1a", +"bW c #6c9520", +"bX c #4c4b8e", +"bY c #cccdcc", +"bZ c #6c6e34", +"b0 c #647a2c", +/* pixels */ +".....................6bN.x#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M.6bNbN........................", +"...................C#P#M#M#MbVagagagagagagagagagagagbVbVbV.J.q#e.C....................", +"...............Caw.a#M#MaU.q#P.Da4a4a4a4a4a4a4a4a4aJ.T#t.q.Jbl.J#V#e..................", +"............#ebD#M#M#M.q#h#SaL#X#z#z#z#z#z#z#z#z#z#X.y#S.D#V#ybl#0#V#e................", +"...........CbD#M#M.q.T#h#X#z#z#z#X#X.y#X.y#X#X#X#z#z#zaAaA#S#G#V.3.3a6aw..............", +"..........bD#M#M.q.iaL#X#z#X#Xa4aXbTbTbTbTbTbTapaLaA#zaAaA.Xan#G.8.3.A#faw............", +"........#ebD#M#t.i.y#z#z#zaLbTar#M#M#M#M#M#MbVbKa0aQanaA.X.X.X.N#G#j.A.Y.T............", +"#8#8#8bZac#MbV#raL#z#z#z.y.cbV#M#M#MaSaSblbV#MbV.J#9an.X.X.X.Xaz.N#6#j.Yatbh.l.l.l.l.l", +"#u#ubiaYaD#M#Pax#X#z#z#za4ag#M#Mbl.1bc.raTaT#i#0.J#faoan.XaK#l#l#l.g#5bMbM.M.m#Z#Z#Zbs", +".zbibt.S#M#MaraL#z#z#z#za4ag#MbVbS.G#3bkbobzbqbUblbl#GazazaKaK#la2a1.7bMbM#AaYbtbibi#W", +"bt#v.MaT#M#Pau#X#z#z#z#z#X#EbVbVbS.LbB.m.B#xaYbkbfbl#Gaz#laK#l#l#la1aeaEbMbs#Zbi.5.5#W", +"#vbY.AblbV#fa4#X#z#z#z#z#XaQbV#Mbc#3bq.m#Z#xbu#Z#Fbl#6.N#l#l#laBaBaBadb0.WaWbzbiavav#W", +"#vbY.L#i#Maw#E#X#z#z#z#z#za4bV#MbN.1.0#BbSaHbcaH#R#R#6a2#l#laBaB#g#gadb0#2bEbmbY.5.5aW", +".PbJ.ZaT#M#Mar.y#z#z#z#z#zapbVbV.6#Q.1#B.3#4#R.jbl.3#6#l#laBaB#g#g#gaIas.W.RbybObiavaW", +"akbJ#3.Lbf#Mbha4#X#z#z#XaJ.q#M#MbN#Q.3.A.A.A#4#R.3.3#6a1aB#g#g#g#gbbbW.W.W#Q#3bObR.5aT", +"bObJbybybU#M.d#raJa4a4ap#t#M#M#M#p#Q#4.A.A#4.3bl.3.3ae#gaB#g#g#g#Obbbd.Wbp.RbsbO#u.5aW", +"#abJ#3.Z.rbV#M#M#M#M#M#M#MbV#MbNbQ.1#C#Y#4.1#0.3.AaM.g#g#g#g#gb#b#.sajbpbE.6#3bO#u.5aT", +"#xbJ#3bybsaR#MbV#MbV#MbV#M#M.6ai.K.U###n#H.3#0aH.v.g#g#g#g#gb##O.sasbp.WbEbN#obJbR.5aT", +"#xbJ#3by#3.r.u#4.j#QbQbQbNbQbQbNbQ.ube#Qbl.3.AaGa3#g#g#g#gb#b#.sajbg.W.WbE.6bBbtbR.5.2", +"#Z.P#3by#3.rbl.A#4#R.j#Q.R#Q#Q.u.u#Q#Q.3#0bf.7a3#g#g#gb#b##O.saZ.Wbp.WbEbebN#.#u.5.5.2", +"#ZbJ#3by#3bU#Q#Y.A.A#4#4.3#4.3#Q#Q#Qbl#0bf.9a3#g#g#gb##Obb.saZ.hbp#2.jbQ.0bQ.mbR.5.5.G", +"brbJ#3by#o.r#Q.A#Y.A.A#Y.A.A#C#Q#Q#Qblbf.9a3#g#gb##Obb#KbWaj.Wbp.Wbv#paSaRbebz.5.5.5.G", +"#bbJ.Z#3by.G#Q#Y#4#Y.A#Y.A#Y.A#Q#Qbl.3bG.4#g#g#Obb#K#Taj.h.W.W#2.j#pbQ.0aTaSbr.5.5.5.G", +"#IbJby#3#3b.#Q#Y.A.A#Y.A#Y.A#Y#Q#Q.3bfaGad#g#OadbWaj.h#2.W.W.jbvbQ.u.RaRbC.0bz.5.5avbU", +"#1bJ#3by#3.G#Q.A.A#Y.A#Y.A#Y.A#Q#Q.3.naI#gb#bb#T#JbM.W.Wbvbv#p.u.ubv.1.2by.0bz.5.5.5.G", +".SbJ#3#3#3b.#Q.A#Y.A#Y.A#Y.A#Y#Q#Q.3bGaIb#b##K.ebM.Wbv#Q.6#p.R#Q.j.3#4.2#3.0bz.5.5.5bU", +".SbJ#3by#3.G#Q#Y#4#Y.A#Y.A#Y#4#Q#Q.3aD#s#K#Ka9bw.W#Q#p..#pbQ.1#4#4.A.A.2#3.0bz.5.5.5.G", +"#.bJ#3#3#3b.#Q#Y.A.A#Y.A#Y.A#Y#Q.R.A#YaDbGbw#c.W.W.u..bQ.u#Q.A.A.A.A#C.2#3.0bz.5.5.5bU", +"bkbJ#3by#3.G#Q.A.A#Y.A#Y.A#Y.A#Q#Q.Y.A.YbMbM#2.W.WbQ#pbQ.R#Q.A.A#Y.A.AbM.w.RbzbR.5.5.G", +".EbJ#3by#ob.#Q.A#Y.A#Y.AbM.A#Y#Q.Rbv.WbMbMbM.W.Wbv.6bQ.u#QbvbM.A.A.A#Y.A#Ybebz.5bR.5bU", +"#UbJ#3.Zby.G#Q#Y.A#Y.A#Y.A#Y.A#Q#Q.Y.YbMbMbM.W.W.WbQbQ.R#Q#Q#Y#4#Y.A.A#4.A.ubzbRbR.5.G", +"#wbJ#3by#3b.#Q#Y.A.A#Y.A#Y.A#Y.R.AbMbMbMbM.W.W.Wbpbp#Q.R#Q#Q#Y.A.A.A.A#Y.Abe.m.5#u.5.2", +"#wbJ#3#3#3.G#Q#Y#Y#Y#Y#Y#Y#Y.A.1bMbMal#7#q#qaf.e.Obp.O#4.A.A#Y.A.A#C.A.A.A.ubz#ubR.5aT", +"aFbJ#3by#3b.bc#3by#3#3#3#3#3.LbM.YaD#7.Ibx.I#D.b.p.ObI#4.A.A#Y.A.A#4#Y.A#Y.ubz#u#u.5aW", +"#wbJ#3#3#3.G#B.L#H.L.L.L.L.LaTbM#2.eaP.Ibx#D#D#D.b#LbIbIbv.1#4.j#4.3.1bE.1bQbz#u.5bRaW", +"#w.P.L#k.LaRbQbQbQbQbe.R.0bS.0bMaD#7.I#D#D#D#D#ma##LbIahaSbcaRaRaRaRaRaRaRaRaY.5.5.5.G", +"#wbY.A.A#Y.A.A#Ya7#FbH#k.Z.M.ZbMaD#q#D#D#Da8a8a8a#aybXbX#obY.5avavavavavavavavavavavbU", +"#wbJaF.MbmbmaFaFaFbB.E#.bq.SbB#2.ha.aa#D#Da8#m#ma#ayahbpbs#Nbi.5bR.5.5.5.5.5.5bR.5.5bU", +"#wbibibibibibibibibibibibibibu.W.W#Fa..Q#ma8#mbaa.#dbXbS.Lbr#vbibibibibibibibibibibibU", +"#W.Sbqbqbqbqbqbqbq.Sbq.S.SbqbB.Y.Wbp#Fa.baa#.o.##dbXbXaS.w#3bkbqbq#.bqbq#.bqbq#.bqbq.w", +".T.T.T.T.T.T.T.TaO#k#W#W#WbH.2#ia7.WaC.t.H.Ha5bIahbX#CbQbQ#Q.1.1.1.1#V.T.T.T.T.T.T.T#f", +"................ambB#wbs#A.Zbs#k.Ga7.ObpbIbIbIbX#C.j#p#p.u#Q#Q#Q.J#Q.T................", +"................aq.T.TbD#o.Zbs#kaW.Ga7.w#CbE.j.jbQ#pbNbQ.u#Q#BbAbnbnaq................", +"........................aN.Z#k.GaW.GbU.wbS.1#QbQbQbQbQ.RbV#QaU........................", +"........................aq.f.fbA#w.M#k.G#Y.1aS.u.R.ubVbnaqaqaq........................", +"..............................#ebkbm#kaTaR.1#Q#QbV#Q#Q.C..............................", +".......faV.kaVbF.kaVbF.k.kbL.VbjaY.B#I#1bq.EbB#wbm#A.ZaN.FaOabbP#j.r#y#taH#y#jaq......", +"......bDbibibibibibibibibibibibibtbJbYbY#abuaY.Bbz.mbobq#.bB#wbm#A.Z#k#WaTaTbU.f......" +}; diff --git a/wmmenu/defaultTile.xpm b/wmmenu/defaultTile.xpm new file mode 100644 index 0000000..a915d66 --- /dev/null +++ b/wmmenu/defaultTile.xpm @@ -0,0 +1,197 @@ +/* XPM */ +static char * defaultTile_xpm[] = { +"64 64 130 2", +" c #FFFFFFFFFFFF", +". c #A7A7A7A7B2B2", +"X c #A6A6A6A6B2B2", +"o c #A6A6A6A6B1B1", +"O c #A5A5A5A5B0B0", +"+ c #A4A4A4A4B0B0", +"@ c #A4A4A4A4AFAF", +"# c #A3A3A3A3AFAF", +"$ c #A3A3A3A3AEAE", +"% c #A2A2A2A2AEAE", +"& c #A1A1A1A1ADAD", +"* c #A1A1A1A1ACAC", +"= c #A0A0A0A0ACAC", +"- c #9F9F9F9FABAB", +"; c #9E9E9E9EAAAA", +": c #9D9D9D9DAAAA", +"> c #9D9D9D9DA9A9", +", c #9C9C9C9CA8A8", +"< c #9B9B9B9BA7A7", +"1 c #9A9A9A9AA7A7", +"2 c #9A9A9A9AA6A6", +"3 c #99999999A5A5", +"4 c #98989898A5A5", +"5 c #98989898A4A4", +"6 c #97979797A4A4", +"7 c #97979797A3A3", +"8 c #96969696A3A3", +"9 c #95959595A2A2", +"0 c #95959595A1A1", +"q c #94949494A1A1", +"w c #93939393A0A0", +"e c #929292929F9F", +"r c #919191919F9F", +"t c #919191919E9E", +"y c #909090909D9D", +"u c #8F8F8F8F9C9C", +"i c #8E8E8E8E9C9C", +"p c #8E8E8E8E9B9B", +"a c #8D8D8D8D9A9A", +"s c #8C8C8C8C9A9A", +"d c #8C8C8C8C9999", +"f c #8B8B8B8B9999", +"g c #8A8A8A8A9898", +"h c #898989899797", +"j c #898989899696", +"k c #888888889696", +"l c #878787879595", +"z c #868686869494", +"x c #858585859494", +"c c #858585859393", +"v c #848484849292", +"b c #838383839191", +"n c #828282829191", +"m c #828282829090", +"M c #818181819090", +"N c #474747475555", +"B c #808080808F8F", +"V c #808080808E8E", +"C c #7F7F7F7F8E8E", +"Z c #7E7E7E7E8D8D", +"A c #7D7D7D7D8C8C", +"S c #A2A2A2A2ADAD", +"D c #9B9B9B9BA8A8", +"F c #8F8F8F8F9D9D", +"G c #838383839292", +"H c #818181818F8F", +"J c #7C7C7C7C8B8B", +"K c #7B7B7B7B8A8A", +"L c #7A7A7A7A8989", +"P c #797979798888", +"I c #787878788787", +"U c #96969696A2A2", +"Y c #8D8D8D8D9B9B", +"T c #8A8A8A8A9797", +"R c #7E7E7E7E8C8C", +"E c #777777778787", +"W c #777777778686", +"Q c #767676768686", +"! c #757575758585", +"~ c #757575758484", +"^ c #747474748484", +"/ c #747474748383", +"( c #7A7A7A7A8A8A", +") c #767676768585", +"_ c #737373738383", +"` c #727272728282", +"' c #727272728181", +"] c #717171718181", +"[ c #707070708080", +"{ c #6F6F6F6F7F7F", +"} c #6E6E6E6E7F7F", +"| c #8B8B8B8B9898", +" . c #848484849393", +".. c #7F7F7F7F8D8D", +"X. c #787878788888", +"o. c #737373738282", +"O. c #6E6E6E6E7E7E", +"+. c #6D6D6D6D7D7D", +"@. c #6C6C6C6C7D7D", +"#. c #6C6C6C6C7C7C", +"$. c #6B6B6B6B7C7C", +"%. c #6B6B6B6B7B7B", +"&. c #6A6A6A6A7A7A", +"*. c #696969697A7A", +"=. c #888888889595", +"-. c #6A6A6A6A7B7B", +";. c #696969697979", +":. c #686868687979", +">. c #676767677878", +",. c #676767677777", +"<. c #666666667777", +"1. c #656565657676", +"2. c #646464647575", +"3. c #636363637474", +"4. c #626262627373", +"5. c #616161617272", +"6. c #606060607272", +"7. c #606060607171", +"8. c #5F5F5F5F7070", +"9. c #797979798989", +"0. c #6D6D6D6D7E7E", +"q. c #686868687878", +"w. c #616161617373", +"e. c #5E5E5E5E7070", +"r. c #5E5E5E5E6F6F", +"t. c #5D5D5D5D6F6F", +"y. c #5C5C5C5C6E6E", +"u. c #5C5C5C5C6D6D", +"i. c #5B5B5B5B6D6D", +"p. c #000000000000", +" ", +" . . X o O + @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M N ", +" . X o O + @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M N N ", +" X o O + @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M B N N ", +" o O + @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M B V N N ", +" O + @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M B V C N N ", +" + @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M B V C Z N N ", +" @ # $ % & * = - ; ; : > , < < 1 2 3 4 5 6 7 8 9 0 q w e e r t y u u i p a s d f g h h j k l z z x c v b b n m M B V C Z A N N ", +" # % S & * = - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A N N ", +" % S & * = - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J N N ", +" S & * = - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J K N N ", +" & * = - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J K K N N ", +" * = - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J K K L N N ", +" = - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J K K L L N N ", +" - ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J K K L L P N N ", +" ; ; > , , D < 1 2 3 4 5 6 8 9 9 0 q w e e t y y F u i p a s d f g h h j k l z z c v v G b n m H B V C Z A A J K K L L P I N N ", +" ; > , , D < 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I N N ", +" > , , D < 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E N N ", +" , , D < 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E W N N ", +" , D < 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E W Q N N ", +" D < 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E W Q ! N N ", +" < 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E W Q ! ~ N N ", +" 2 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E W Q ! ~ ^ N N ", +" 3 3 4 5 6 8 U 9 q w w e e t y y F u p Y a s d f g T h k l l z z c v v G b n M H B V C Z R A J K K L L P I I E W Q ! ~ ^ / N N ", +" 3 4 5 6 8 U 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` N N ", +" 4 5 6 8 U 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` N N ", +" 5 6 8 U 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` ' N N ", +" 6 8 U 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` ' ] N N ", +" 8 U 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` ' ] [ N N ", +" U 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` ' ] [ { N N ", +" 9 q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` ' ] [ { { N N ", +" q w w e t t y y F u p Y a s d f g T h k l l z c c v v G b m M H B C Z Z R A J K K ( L P I I E W ) ! ~ ^ _ ` ` ' ] [ { { } N N ", +" w w e t t y y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.N N ", +" w e t t y y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.N N ", +" e t t y y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.N N ", +" t t y y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.N N ", +" t y y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.$.N N ", +" y y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.$.%.N N ", +" y F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.$.%.&.N N ", +" F u p Y a s f | g T h k l l z c c .v G b m M H B C ..Z R A J K K L P P X.I E W ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.$.%.&.*.N N ", +" p p Y a s f | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.N N ", +" p Y a s f | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.N N ", +" Y a s f | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.>.N N ", +" a s f | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.>.,.N N ", +" s f | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.>.,.<.N N ", +" f | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.>.,.<.1.N N ", +" | g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.>.,.<.1.2.N N ", +" g h k k =.l z c c .v b m m M H B C ..Z A J J K K L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { { O.+.+.@.#.%.-.&.*.;.:.>.,.<.1.2.2.N N ", +" h k k l z z c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.N N ", +" k k l z z c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.N N ", +" k l z z c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.4.N N ", +" l z z c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.4.5.N N ", +" z z c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.4.5.5.N N ", +" z c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.4.5.5.6.N N ", +" c c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.4.5.5.6.7.N N ", +" c .v b n m M H V C ..Z A J J K L L P P X.I W Q ) ! ~ ^ _ o.` ] [ [ { O.O.+.+.@.#.%.-.&.*.:.>.>.,.<.1.2.2.3.4.4.5.5.6.7.8.N N ", +" v b b n m M B V C ..Z A J J K L L 9.P I W W Q ) ! ^ / _ o.` ] [ [ { O.O.0.+.#.%.%.-.&.*.:.q.>.,.<.1.2.2.3.4.4.w.5.6.7.8.e.N N ", +" b b n m M B V C ..Z A J J K L L 9.P I W W Q ) ! ^ / _ o.` ] [ [ { O.O.0.+.#.%.%.-.&.*.:.q.>.,.<.1.2.2.3.4.4.w.5.6.7.8.e.r.N N ", +" b n m M B V C ..Z A J J K L L 9.P I W W Q ) ! ^ / _ o.` ] [ [ { O.O.0.+.#.%.%.-.&.*.:.q.>.,.<.1.2.2.3.4.4.w.5.6.7.8.e.r.t.N N ", +" n m M B V C ..Z A J J K L L 9.P I W W Q ) ! ^ / _ o.` ] [ [ { O.O.0.+.#.%.%.-.&.*.:.q.>.,.<.1.2.2.3.4.4.w.5.6.7.8.e.r.t.y.N N ", +" m M B V C ..Z A J J K L L 9.P I W W Q ) ! ^ / _ o.` ] [ [ { O.O.0.+.#.%.%.-.&.*.:.q.>.,.<.1.2.2.3.4.4.w.5.6.7.8.e.r.t.y.u.N N ", +" M B V C ..Z A J J K L L 9.P I W W Q ) ! ^ / _ o.` ] [ [ { O.O.0.+.#.%.%.-.&.*.:.q.>.,.<.1.2.2.3.4.4.w.5.6.7.8.e.r.t.y.u.i.N N ", +" N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N ", +"p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p."}; diff --git a/wmmenu/error.c b/wmmenu/error.c new file mode 100644 index 0000000..641598e --- /dev/null +++ b/wmmenu/error.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +#include "error.h" + +extern void warn (const char * fmt, ...) +{ + va_list args ; + + assert (fmt != NULL) ; + va_start (args, fmt) ; + fprintf (stderr, "wmmenu warning: ") ; + vfprintf (stderr, fmt, args) ; + fprintf (stderr, "\n") ; + va_end (args) ; +} + +extern void error (const char * fmt, ...) +{ + va_list args ; + + assert (fmt != NULL) ; + va_start (args, fmt) ; + fprintf (stderr, "wmmenu error: ") ; + vfprintf (stderr, fmt, args) ; + fprintf (stderr, "\n") ; + va_end (args) ; + + exit (EXIT_FAILURE) ; +} diff --git a/wmmenu/error.h b/wmmenu/error.h new file mode 100644 index 0000000..d9c68d7 --- /dev/null +++ b/wmmenu/error.h @@ -0,0 +1,8 @@ +#ifndef error_h_ +#define error_h_ + +extern void warn (const char * fmt, ...) ; +extern void error (const char * fmt, ...) ; + +#endif /* error_h_ */ + diff --git a/wmmenu/events.c b/wmmenu/events.c new file mode 100644 index 0000000..8c44f55 --- /dev/null +++ b/wmmenu/events.c @@ -0,0 +1,251 @@ +/* +List of events catched: + +button bar window: + - button press and release => run a menu entry + - enter/leave => show/hide bar (if not -O click) and highlight (if set) + - pointer motion (if highlight set) => change highlight position + +menu icon: + - button press => show/hide bar + - enter/leave (if not -O click) => show/hide bar + - move/reparent => find WMFrame and bar coords, update frame events. + +WMFrame (if some): + - enter/leave (if not -O click) => show/hide bar + - move/destroy => find WMFrame and bar coords, update frame events. + +NB: Move is actually part of a larger "Configure" event; Configure, +Reparent and Destroy events are catched with StructureNotifyMask. + +*/ + +#include + +#include + +#include "types.h" +#include "events.h" +#include "buttonbar.h" +#include "options.h" +#include "menu.h" +#include "xobjects.h" +#include "pixmaps.h" + +static bool BarShown = false ; +static bool HideBarDelayed = false ; + +static void FindWMFrameAndBarPos (void) +{ + XWindowAttributes wa ; + Window tile, parent, root, *children ; + unsigned int nChildren ; + long evMask ; + + /* find window just under root, it is the wm frame icon */ + /* (or DAWindow itself if none) */ + root = 0 ; + tile = parent = DAWindow ; + while (parent != root) + { + tile = parent ; + XQueryTree (DADisplay, tile, + &root, &parent, &children, &nChildren) ; + if (children != NULL) XFree (children) ; + } + + /* container actually changed ? */ + if (WMFrame != tile) + { +#if 0 + /* + TODO: put this back once a solution has been found to avoid an X + error, when WMFrame has been destroyed while we were looking for our + new frame. Meanwhile, it seems acceptable to not unregister events + since in the normal case WMFrame is going to be destroyed ! + */ + /* remove events from old container (if this is not the first time) */ + if (WMFrame != 0 && WMFrame != DAWindow) + XSelectInput (DADisplay, WMFrame, 0) ; +#endif + + /* add events to new container */ + if (tile != DAWindow) + { + evMask = StructureNotifyMask ; /* move/destroy */ + if (! ClickOnly) + evMask |= EnterWindowMask | LeaveWindowMask ; + XSelectInput (DADisplay, tile, evMask) ; + } + + WMFrame = tile ; + } + + XGetWindowAttributes (DADisplay, WMFrame, & wa) ; + ButtonBar_SetPositionFromDockApp (wa.x, wa.y, wa.width, wa.height) ; +} + +static void EnterApp (void) +{ + if (Menu_HasChanged ()) + { + Menu_Reload () ; + + Pixmaps_LoadMenu () ; + Pixmaps_LoadTile () ; + + ButtonBar_Rebuild () ; + /* adjust position depending on possible new size */ + FindWMFrameAndBarPos () ; + } + + ButtonBar_Show () ; + BarShown = true ; + HideBarDelayed = false ; +} + +static void LeaveBar (void) +{ + ButtonBar_Hide () ; + BarShown = false ; + HideBarDelayed = false ; +} + +static void LeaveApp (void) +{ + if (BarShown) + { + ButtonBar_Unhighlight () ; + HideBarDelayed = ! ClickOnly ; + } +} + +static void InvokeBar (int x, int y) +{ + int h, w ; + h = Menu_GetNbRows () ; + w = Menu_GetNbColumns () ; + x /= TileXSize ; + y /= TileYSize ; + if (0 <= y && y < h && 0 <= x && x < w) + { + int entry ; + entry = y + h*x ; + + if (entry < Menu_GetNbEntries ()) + { + system (Menu_GetEntryCommand (entry)) ; + } + } + + LeaveBar () ; +} + +static void PressApp (int button, int state, int x, int y) +{ + if (BarShown) LeaveBar () ; + else EnterApp () ; +} + +extern void Events_SetCallbacks (void) +{ + DACallbacks events ; + XSetWindowAttributes ws ; + XWindowAttributes wa ; + + events.destroy = NULL ; + events.buttonPress = PressApp ; + events.buttonRelease = NULL ; + events.motion = NULL ; + events.enter = (ClickOnly ? NULL : EnterApp) ; + events.leave = (ClickOnly ? NULL : LeaveApp) ; + + DASetCallbacks (& events) ; + + /* update set of events we want to catch on the dock app */ + XGetWindowAttributes (DADisplay, DAWindow, & wa) ; + ws.event_mask = wa.your_event_mask + | StructureNotifyMask ; /* move/reparent */ + /* work around a bug in libdockapp: not selecting Enter/Leave events */ + if (! ClickOnly) + ws.event_mask |= EnterWindowMask | LeaveWindowMask ; + XChangeWindowAttributes (DADisplay, DAWindow, CWEventMask, & ws) ; +} + +extern void Events_Loop (void) +{ + XEvent ev ; + bool canShowBar = true ; + + while (true) + { + /* get some event to process */ + if (HideBarDelayed) + { + if (! DANextEventOrTimeout (& ev, HideTimeout)) + { + /* timeout ! */ + LeaveBar () ; + continue ; /* restart waiting for an event */ + } + } + else + { + XNextEvent (DADisplay, & ev) ; + } + /* event available, process it */ + + + if (ev.type == EnterNotify) /* catch entering any wmmenu window */ + { + if (canShowBar) EnterApp () ; + canShowBar = true ; + } + else + if (ev.type == LeaveNotify) /* catch leaving any wmmenu window */ + { + /* when cursor goes from icon to dock tile */ + /* take care to not show the bar back if it is already hidden */ + if (ev.xany.window == DAWindow) + canShowBar = BarShown ; + LeaveApp () ; + } + else + if (ev.xany.window == DAWindow) switch (ev.type) + { + case ReparentNotify : + case ConfigureNotify : + /* find new WMFrame and update bar position */ + FindWMFrameAndBarPos () ; + break ; + + default : + DAProcessEvent (& ev) ; + break ; + } + else + if (ev.xany.window == ButtonBarWindow) switch (ev.type) + { + case ButtonRelease : + InvokeBar (ev.xbutton.x, ev.xbutton.y) ; + break ; + + case MotionNotify : + if (HighlightImage != 0) /* try to avoid func call */ + { + ButtonBar_Highlight ( + ev.xmotion.x/TileXSize, ev.xmotion.y/TileYSize) ; + } + break ; + } + else + if (ev.xany.window == WMFrame && WMFrame != 0) switch (ev.type) + { + case DestroyNotify : + case ConfigureNotify : + /* find new WMFrame and update bar position */ + FindWMFrameAndBarPos () ; + break ; + } + } +} diff --git a/wmmenu/events.h b/wmmenu/events.h new file mode 100644 index 0000000..414609c --- /dev/null +++ b/wmmenu/events.h @@ -0,0 +1,7 @@ +#ifndef events_h_ +#define events_h_ + +extern void Events_SetCallbacks (void) ; +extern void Events_Loop () ; + +#endif /* events_h_ */ diff --git a/wmmenu/example/apps b/wmmenu/example/apps new file mode 100644 index 0000000..a8c7a23 --- /dev/null +++ b/wmmenu/example/apps @@ -0,0 +1,11 @@ +# example wmmenu menu file +# put it in ~/.wmmenu +# run with "wmmenu -m apps" + +"GNUstep.xpm" Menu title +"linuxterm.xpm" xterm -T Terminal -name terminal -geometry 80x50 & +"HomeNeighborOpen.xpm" xterm -T "Login terminal" -name loginxterm -e bin/rloginsession & +"FileManager.xpm" xterm -T "Midnight Commander" -name mc -geometry 100x50 -sl 1000 -e mc -c & +"mixer.xpm" gaumix & +"HP-16C-48.xpm" kcalc & + diff --git a/wmmenu/example/defaults b/wmmenu/example/defaults new file mode 100644 index 0000000..345a356 --- /dev/null +++ b/wmmenu/example/defaults @@ -0,0 +1,26 @@ +# wmmenu configuration file +# put it in ~/.wmmenu/ +# +# xpmpath PATH1:PATH2:... +# xpmpath PATH3 +# xpmpath PATH4 +# ... +# +# tile FILE.XPM +# or +# tile /SOME/PATH/TO/FILE.XPM +# or +# tile !SOME-COMMAND WITH ARG +# +# highlight FILE.XPM +# or +# highlight /SOME/PATH/TO/FILE.XPM +# +# highlight_behind ANYTHING_NOT_EMPTY +# +# hide_timeout 1 + +xpmpath /usr/local/share/WindowMaker/Icons +xpmpath /usr/local/share/pixmaps +tile tile2.xpm +tile !echo tile2.xpm diff --git a/wmmenu/example/extract_icon_back b/wmmenu/example/extract_icon_back new file mode 100755 index 0000000..463f8da --- /dev/null +++ b/wmmenu/example/extract_icon_back @@ -0,0 +1,61 @@ +#!/usr/bin/awk -f +# Usage: +# extract_icon_back [] +# Description: +# Uses WindowMaker's getstyle command to extract the icon pixmap from +# preferences, and print it. +# If the name returned by getstyle is not absolute, the right pixmap path +# is supposed to be declared in wmmenu's defaults file. +# If no pixmap is found in WindowMaker's preferences (f.e. in case of +# pixmap-less gradient), the string provided as command line argument is +# used instead (and is possibly empty or unspecified). +# NB: This script expects a POSIX / X/Open compatible AWK. Be aware that +# some GNU awk versions do not fulfill this requirement. + +BEGIN { + if (1 in ARGV) { + Name=ARGV[1] + delete ARGV[1] + } + ARGC=0 + + Command="getstyle" + IconBackLine="" + + # Search first line marked "IconBack" + while (Ok = ((Command | getline) == 1)) { + if ($1 == "IconBack") { + IconBackLine=$0 + break + } + } + ReturnDefaultIfNot(Ok) + + # Accumulate while not closed + while (IconBackLine !~ /\);$/) { + Ok = ((Command | getline) == 1) + if (! Ok) break + IconBackLine=IconBackLine $0 + } + ReturnDefaultIfNot(Ok) + + # finished + close(Command) + + # analyze what we have: split on '= (' and ', "' or ', ' + FS="(, ([\"]?))|(= \()" + $0=IconBackLine + TextureType=$2 + if(TextureType == "spixmap" || TextureType ~ /^t[hvd]gradient$/) { + Name=$3 + sub(/[""]$/,"",Name) + } + print Name +} + +function ReturnDefaultIfNot(ok) { + if (! ok) { + print Name + exit 0 + } +} diff --git a/wmmenu/menu.c b/wmmenu/menu.c new file mode 100644 index 0000000..10da3d1 --- /dev/null +++ b/wmmenu/menu.c @@ -0,0 +1,196 @@ +#define _POSIX_SOURCE + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "menu.h" +#include "utils.h" +#include "types.h" +#include "error.h" + +#define MAXENTRIES 50 + +#define BLANKS " \t\f\r\n" +#define SPACES " \t\f" +#define ENDLINE "\r\n" + +static int NbEntries = 0 ; +static int Rows = 1 ; +static const char * Pixmaps [MAXENTRIES] ; +static const char * Commands [MAXENTRIES] ; +static char * MenuFileText = NULL ; +static char MenuPath [FILENAME_MAX] = "" ; +static time_t MenuAge = 0 ; + +static void ParseMenu (void) +{ + char * p ; + + assert (MenuFileText != NULL) ; + p = MenuFileText ; + p += strspn (p, BLANKS) ; + NbEntries = 0 ; + Pixmaps[0] = NULL ; + Commands[0] = NULL ; + + while (NbEntries < MAXENTRIES && *p != EOS) switch (*p++) + { + case '#' : + p += strcspn (p, ENDLINE) ; + p += strspn (p, BLANKS) ; + break ; + + case '"' : + Pixmaps[NbEntries] = p ; + p += strcspn (p, "\"") ; + *p++ = EOS ; + p += strspn (p, SPACES) ; + break ; + + default : + if (Pixmaps[NbEntries] == NULL) + warn ("entry #%d has no pixmap", NbEntries) ; + else Commands[NbEntries++] = p-1 ; + + p += strcspn (p, ENDLINE) ; + *p++ = EOS ; + p += strspn (p, BLANKS) ; + + Commands[NbEntries] = NULL ; + Pixmaps[NbEntries] = NULL ; + break ; + } + + if (*p != EOS) + warn ("too many entries") ; +} + +extern void Menu_LoadFromFile (const char * name) +{ + char path [FILENAME_MAX] ; + const char * home ; + FILE * f ; + struct stat finfo ; + + assert (name != NULL) ; + + if (strchr (name, '/') == NULL && (home = getenv ("HOME")) != NULL && + home[0] != EOS) + sprintf (path, "%s/.wmmenu/%s", home, name) ; + else sprintf (path, "%s", name) ; + + if ((f = fopen (path, "r")) == NULL) + error ("can't open %s", path) ; + else + { + if (fstat (fileno (f), & finfo) == 0) + { + MenuAge = finfo.st_mtime ; + } + + sprintf (MenuPath, "%.*s", (int)(sizeof MenuPath)-1, path) ; + + if (MenuFileText != NULL) free (MenuFileText) ; + MenuFileText = File_ReadAll (f) ; + } + + fclose (f) ; + + ParseMenu () ; +} + +extern int Menu_GetNbRows(void) +{ + assert (Rows > 0) ; + return Rows ; +} + +extern void Menu_SetNbRows (const char *s) +{ + int h; + + h = atoi(s) ; + if (h > 0) Rows = h ; +} + +extern int Menu_GetNbColumns (void) +{ + assert (NbEntries > 1 && Rows > 0) ; + /* + Remove 1 entry used for header, then apply the formula: + UNITS = int (floor ((USED - 1) / PERUNIT)) + 1 + (USED is NbEntries - 1) + */ + return ((NbEntries - 2) / Rows) + 1 ; +} + +extern int Menu_GetNbEntries (void) +{ + assert (NbEntries > 1) ; + return NbEntries-1 ; +} + +extern const char * Menu_GetEntryPixmap (int i) +{ + assert (0 <= i && i < NbEntries-1) ; + return Pixmaps[i+1] ; +} + +extern const char * Menu_GetEntryCommand (int i) +{ + assert (0 <= i && i < NbEntries-1) ; + return Commands[i+1] ; +} + +extern const char * Menu_GetPixmap (void) +{ + assert (0 < NbEntries) ; + return Pixmaps[0] ; +} + +extern const char * Menu_GetTitle (void) +{ + assert (0 < NbEntries) ; + return Commands[0] ; +} + +extern int Menu_HasChanged (void) +{ + struct stat finfo ; + + if (stat (MenuPath, & finfo) == 0 && finfo.st_mtime > MenuAge) + { + return 1 ; /* should reload */ + } + else + { + return 0 ; /* don't try to reload */ + } +} + +extern void Menu_Reload (void) +{ + FILE * f ; + struct stat finfo ; + + if ((f = fopen (MenuPath, "r")) != NULL) + { + if (fstat (fileno (f), & finfo) == 0) + { + MenuAge = finfo.st_mtime ; + } + + if (MenuFileText != NULL) free (MenuFileText) ; + MenuFileText = File_ReadAll (f) ; + fclose (f) ; + + ParseMenu () ; + } +} diff --git a/wmmenu/menu.h b/wmmenu/menu.h new file mode 100644 index 0000000..e0d8680 --- /dev/null +++ b/wmmenu/menu.h @@ -0,0 +1,19 @@ +#ifndef menu_h_ +#define menu_h_ + +extern void Menu_LoadFromFile (const char * name) ; +extern int Menu_HasChanged (void) ; +extern void Menu_Reload (void) ; + +extern const char * Menu_GetPixmap (void) ; +extern const char * Menu_GetTitle (void) ; + +extern int Menu_GetNbEntries (void) ; +extern const char * Menu_GetEntryPixmap (int i) ; +extern const char * Menu_GetEntryCommand (int i) ; + +extern void Menu_SetNbRows (const char *s) ; +extern int Menu_GetNbRows (void) ; +extern int Menu_GetNbColumns (void) ; + +#endif /* menu_h_ */ diff --git a/wmmenu/options.c b/wmmenu/options.c new file mode 100644 index 0000000..228cbc7 --- /dev/null +++ b/wmmenu/options.c @@ -0,0 +1,305 @@ +/* ANSI */ +#include +#include +#include +#include +/* POSIX */ +#include + +#include "options.h" +#include "version.h" +#include "error.h" +#include "utils.h" +#include "types.h" +#include "menu.h" + +#define MAXOPTIONS (20) + +#ifndef ETCDIR +#define ETCDIR "/usr/local/etc" +#endif +#define DEFAULTPATH (ETCDIR ":.") + +#define BLANKS " \t\f\r\n" +#define SPACES " \t\f" +#define ENDLINE "\r\n" + +int TileXSize = 0 ; +int TileYSize = 0 ; + +char MenuName [40] = "" ; + +static char MyPixmapPath [1024] = "" ; +char * PixmapPath = MyPixmapPath ; + +static char MyTilePath [FILENAME_MAX] = "" ; +char * TilePath = MyTilePath ; + +static char MyHighlightPath [FILENAME_MAX] = "" ; +char * HighlightPath = MyHighlightPath ; + +bool ClickOnly = false ; +bool AutoScale = true ; +bool HighlightBehind = false ; +int HideTimeout = 1 ; + +int Options_Argc = 0 ; +char * Options_Argv [MAXOPTIONS] ; + +static void Usage (void) +{ + printf ( +"Usage: wmmenu [...][-- ...]\n" +"Normal options:\n" +"-m MENUNAME set the name of the menu file to load from ~/.wmmenu\n" +"-g WxH force width and height of tile\n" +"-l XPMFILE set the pixmap used to highlight icon under cursor\n" +"-t XPMFILE set the pixmap used as button bar background\n" +"-O click bar is only triggered by clicks on the tile, not moves\n" +"-O noautoscale disable automatic pixmap scaling to tile size\n" +"-O behind draw highlight pixmap behind icon, not above\n" +"-O hide=N set bar hiding timeout to N ms (default one)\n" +"-r ROWS set number of menu rows (default one)\n" +"-v print version information\n" +"-h print this help message\n" +"Note:\n" +" -t, -l and '-O behind' can also be specified with the defaults file.\n" +"" + ) ; +} + +static void SetGeometry (const char * val) +{ + if (sscanf (val, "%dx%d", &TileXSize, &TileYSize) != 2) + error ("bad tile geometry \"%s\"", val) ; + else + if (64 < TileXSize || TileXSize < 0) + error ("incorrect tile width %d", TileXSize) ; + else + if (64 < TileYSize || TileYSize < 0) + error ("incorrect tile height %d", TileYSize) ; +} + +static void SetTilePath (const char * value) +{ + char *ptrToFree = NULL ; + + if (value != NULL && value[0] == '!') + { + ptrToFree = File_ReadOutputFromCommand (value+1) ; + + if ((value = ptrToFree) == NULL) + value = "" ; + } + + sprintf (MyTilePath, "%.*s", (int)(sizeof MyTilePath)-1, value) ; + + if (ptrToFree != NULL) + free (ptrToFree) ; +} + +static void SetHighlightPath (const char * value) +{ + sprintf (MyHighlightPath, "%.*s", (int)(sizeof MyHighlightPath)-1, value) ; +} + +static void SetHideTimeout (const char * value) +{ + HideTimeout = atoi (value) ; + if (HideTimeout <= 0) + { + warn ("hide_timeout must be a strictly positive integer") ; + HideTimeout = 1 ; + } + /* no maximum -- for players */ +} + +static void AddPixmapPath (const char * value) +{ + int curLen ; + int szLeft ; + + curLen = strlen (MyPixmapPath) ; + szLeft = (sizeof MyPixmapPath) - curLen ; + + /* don't forget to count space for ':' and ending EOS */ + sprintf (MyPixmapPath+curLen, ":%.*s", szLeft-2, value) ; +} + +static void InitDefaults (void) +{ + char dftPixmapPath [FILENAME_MAX] ; + const char * home ; + + if ((home = getenv ("HOME")) != NULL && home[0] != EOS) + { + sprintf (dftPixmapPath, "%.*s/.wmmenu", + (int)(sizeof dftPixmapPath)-10, home) ; + } + else + { + strcpy (dftPixmapPath, ".") ; + } + + strcpy (MyPixmapPath, dftPixmapPath) ; +} + +static void ParseDefaults (char * text) +{ + char * p ; + const char * name ; + const char * value ; + + assert (text != NULL) ; + p = text ; + p += strspn (p, BLANKS) ; + + while (*p != EOS) switch (*p++) + { + case '#' : + p += strcspn (p, ENDLINE) ; + p += strspn (p, BLANKS) ; + break ; + + default : + name = p-1 ; + p += strcspn (p, SPACES) ; + *p++ = EOS ; + p += strspn (p, SPACES) ; + value = p ; + p += strcspn (p, ENDLINE) ; + *p++ = EOS ; + p += strspn (p, BLANKS) ; + + if (streq (name, "geometry")) SetGeometry (value) ; + else + if (streq (name, "xpmpath")) + { + AddPixmapPath (value) ; + } + else + if (streq (name, "tile")) + { + SetTilePath (value) ; + } + else + if (streq (name, "highlight")) + { + SetHighlightPath (value) ; + } + else + if (streq (name, "highlight_behind")) + { + HighlightBehind = true ; + } + else + if (streq (name, "hide_timeout")) + { + SetHideTimeout (value) ; + } + else error ("unknown setting \"%s\"", name) ; + + break ; + } +} + +extern void Options_ParseDefaults (void) +{ + char pathList [1000] ; + char path [FILENAME_MAX] ; + const char * home ; + FILE * f ; + + if ((home = getenv ("HOME")) != NULL && *home != EOS) + { + sprintf (pathList, "%s/.wmmenu:%s", home, DEFAULTPATH) ; + } + else + { + strcpy (pathList, DEFAULTPATH) ; + } + + if (File_FindInPath (path, sizeof path, pathList, "defaults") && + (f = fopen (path, "r")) != NULL) + { + char * text ; + + text = File_ReadAll (f) ; + fclose (f) ; + + InitDefaults () ; + ParseDefaults (text) ; + free (text) ; + } +} + +extern void Options_Parse (int argc, char ** argv) +{ + int opt ; + + assert (argv != NULL) ; + assert (argc > 0) ; + + Options_Argc = 0 ; + Options_Argv[Options_Argc++] = MenuName ; + + while ((opt = getopt (argc, argv, "hg:l:m:r:t:vO:")) != EOF) switch (opt) + { + case 'g' : + SetGeometry (optarg) ; + break ; + + case 'm' : + sprintf (MenuName, "%.*s", (int)(sizeof MenuName)-1, optarg) ; + break ; + + case 'r' : + Menu_SetNbRows (optarg) ; + break ; + + case 't' : + SetTilePath (optarg) ; + break ; + + case 'l' : + sprintf (MyHighlightPath, "%.*s", + (int)(sizeof MyHighlightPath)-1, optarg) ; + break ; + + case 'O' : + if (streq (optarg, "click")) ClickOnly = true ; + else if (streq (optarg, "noautoscale")) AutoScale = false ; + else if (streq (optarg, "behind")) HighlightBehind = true ; + else if (streql (optarg, "hide=", 5)) SetHideTimeout (optarg+5) ; + else printf ("ignoring unknown feature \"%s\"\n", optarg) ; + break ; + + case 'v' : + printf ("wmmenu (c) F.COUTANT v%s\n", VERSION) ; + exit (EXIT_SUCCESS) ; + break ; + + case 'h' : + Usage () ; + exit (EXIT_SUCCESS) ; + break ; + + case '?' : + Usage () ; + exit (EXIT_FAILURE) ; + break ; + } + + if (MenuName[0] == EOS) + error ("no menu file name specified") ; + if (MyTilePath[0] == EOS) + warn ("no tile pixmap specified, using internal default") ; + + while (optind < argc && Options_Argc < MAXOPTIONS) + Options_Argv[Options_Argc++] = argv[optind++] ; +} + +extern void Options_SetMenuName (const char * name) +{ + sprintf (MenuName, "%.*s", (int)(sizeof MenuName)-1, name) ; +} diff --git a/wmmenu/options.h b/wmmenu/options.h new file mode 100644 index 0000000..6d741c0 --- /dev/null +++ b/wmmenu/options.h @@ -0,0 +1,41 @@ +#ifndef options_h_ +#define options_h_ + +#include "types.h" + +/* defaults to "not set" */ +extern int TileXSize ; +extern int TileYSize ; + +/* defaults to "not set" */ +extern char MenuName [] ; + +/* empty by default; can be written to */ +extern char * PixmapPath ; + +/* empty by default; can be written to */ +extern char * TilePath ; + +/* empty by default; can be written to */ +extern char * HighlightPath ; + +/* defaults to false */ +extern bool ClickOnly ; + +/* defaults to true */ +extern bool AutoScale ; + +/* defaults to false */ +extern bool HighlightBehind ; + +/* defaults to 1ms */ +extern int HideTimeout ; + +extern int Options_Argc ; +extern char * Options_Argv [] ; + +extern void Options_ParseDefaults (void) ; +extern void Options_Parse (int argc, char ** argv) ; +extern void Options_SetMenuName (const char *) ; + +#endif /* options_h_ */ diff --git a/wmmenu/pixmaps.c b/wmmenu/pixmaps.c new file mode 100644 index 0000000..8799dbb --- /dev/null +++ b/wmmenu/pixmaps.c @@ -0,0 +1,238 @@ +#include +#include + +#ifdef WITH_GDKPIXBUF +#include +#endif +#include + +#include "pixmaps.h" +#include "xobjects.h" +#include "options.h" +#include "utils.h" +#include "error.h" +#include "menu.h" + +#include "defaultTile.xpm" +#include "defaultIcon.xpm" + +static char ** CurrentDefault = defaultIcon_xpm ; + +#ifdef WITH_GDKPIXBUF + +extern void Pixmaps_FindLoad (const char * name, + Pixmap * imageP, Pixmap * maskP, int * wP, int * hP) +{ + static int mustInitGdkPixbuf = 1 ; + char path [FILENAME_MAX] ; + GdkPixbuf * pix ; + int width, height ; + void (* problem) (const char *, ...) ; + + if (mustInitGdkPixbuf) + { + gdk_pixbuf_xlib_init (DADisplay, DefaultScreen (DADisplay)) ; + mustInitGdkPixbuf = 0 ; + } + + assert (name != NULL) ; + assert (imageP != NULL) ; + assert (maskP != NULL) ; + problem = (CurrentDefault == NULL ? error : warn) ; + +#define UseDefault() \ + if ((pix = gdk_pixbuf_new_from_xpm_data ( \ + (const char **)CurrentDefault)) == NULL) \ + error ("can't create internal default pixmap") + + if (name == NULL || name[0] == EOS) + { + if (CurrentDefault == NULL) + error ("missing image name specification") ; + + UseDefault () ; + } + else + if (! File_FindInPath (path, sizeof path, PixmapPath, name)) + { + problem ("can't find image \"%s\"", name) ; + UseDefault () ; + } + else + if ((pix = gdk_pixbuf_new_from_file (path)) == NULL) + { + problem ("can't load image \"%s\"", path) ; + UseDefault () ; + } + + /* get loaded geometry */ + width = gdk_pixbuf_get_width (pix) ; + height = gdk_pixbuf_get_height (pix) ; + + /* scale if allowed, possible, and useful */ + if (AutoScale && + TileXSize > 0 && TileYSize > 0 && + (width > TileXSize || height > TileYSize)) + { + GdkPixbuf * scaled ; + + /* + Compare width/TileXSize to height/TileYSize to determine a new + size that fits within TileXSize x TileYSize and keeps the same + aspect ratio as before. The biggest ratio wins. + */ + if (width*TileYSize >= height*TileXSize) + { + /* width directs re-scaling */ + height = (height * TileXSize) / width ; + width = TileXSize ; + } + else + { + /* height directs re-scaling */ + width = (width * TileYSize) / height ; + height = TileYSize ; + } + + scaled = gdk_pixbuf_scale_simple (pix, + width, height, GDK_INTERP_HYPER) ; + gdk_pixbuf_unref (pix) ; + pix = scaled ; + } + + if (wP != NULL) *wP = width ; + if (hP != NULL) *hP = height ; + gdk_pixbuf_xlib_render_pixmap_and_mask (pix, imageP, maskP, 128) ; + /* don't forget to free now we've done pixmaps */ + gdk_pixbuf_unref (pix) ; +} + +/* +We have to reimplement a few trivial gdk functions here to avoid linking with +it ! +*/ + +extern gint gdk_screen_width (void) +{ + return DisplayWidth (DADisplay, DefaultScreen (DADisplay)) ; +} + +extern gint gdk_screen_height (void) +{ + return DisplayHeight (DADisplay, DefaultScreen (DADisplay)) ; +} + +extern gboolean gdk_color_parse (const gchar * spec, GdkColor * color) +{ + XColor scr ; +#if 1 + + /* Lukasz Pankowski suggested this */ + if (! XParseColor (DADisplay, + DefaultColormap (DADisplay, DefaultScreen (DADisplay)), + spec, & scr)) +#else + XColor exact ; + + if (! XAllocNamedColor (DADisplay, + DefaultColormap (DADisplay, DefaultScreen (DADisplay)), + spec, & scr, & exact)) +#endif + { + return FALSE ; + } + else + { + color->pixel = scr.pixel ; + color->red = scr.red ; + color->green = scr.green ; + color->blue = scr.blue ; + return TRUE ; + } +} + +#else + +extern void Pixmaps_FindLoad (const char * name, + Pixmap * imageP, Pixmap * maskP, int * wP, int * hP) +{ + char path [FILENAME_MAX] ; + XpmAttributes attr ; + void (* problem) (const char *, ...) ; + + assert (name != NULL) ; + assert (imageP != NULL) ; + assert (maskP != NULL) ; + attr.valuemask = 0 ; + problem = (CurrentDefault == NULL ? error : warn) ; + +#define UseDefault() \ + if (XpmCreatePixmapFromData (DADisplay, DefaultRootWindow (DADisplay), \ + CurrentDefault, imageP, maskP, & attr) != XpmSuccess) \ + error ("can't create internal default pixmap") + + if (! File_FindInPath (path, sizeof path, PixmapPath, name)) + { + problem ("can't find file \"%s\"", name) ; + UseDefault () ; + } + else + if (XpmReadFileToPixmap (DADisplay, DefaultRootWindow (DADisplay), + path, imageP, maskP, & attr) != XpmSuccess) + { + problem ("can't load pixmap \"%s\"", path) ; + UseDefault () ; + } + + if (wP != NULL) *wP = attr.width ; + if (hP != NULL) *hP = attr.height ; +} + +#endif + +extern void Pixmaps_LoadMenu (void) +{ + Pixmap image, mask ; + bool saveAutoScale ; + saveAutoScale = AutoScale ; /* save old value */ + AutoScale = false ; /* set temporary value */ + Pixmaps_FindLoad (Menu_GetPixmap (), & image, & mask, NULL, NULL) ; + DASetShape (mask) ; + DASetPixmap (image) ; + AutoScale = saveAutoScale ; /* restore initial value */ +} + +extern void Pixmaps_LoadTile (void) +{ + int x, y ; + + if (TileImage != 0) XFreePixmap (DADisplay, TileImage) ; + if (TileMask != 0) XFreePixmap (DADisplay, TileMask) ; + + CurrentDefault = defaultTile_xpm ; + Pixmaps_FindLoad (TilePath, & TileImage, & TileMask, & x, & y) ; + CurrentDefault = defaultIcon_xpm ; + + if (TileXSize <= 0) TileXSize = x ; + if (TileYSize <= 0) TileYSize = y ; +} + +extern void Pixmaps_LoadHighlight (void) +{ + int x, y ; + + if (HighlightImage != 0) XFreePixmap (DADisplay, HighlightImage) ; + if (HighlightMask != 0) XFreePixmap (DADisplay, HighlightMask) ; + + if (HighlightPath[0] != EOS) + { + Pixmaps_FindLoad (HighlightPath, + & HighlightImage, & HighlightMask, & x, & y) ; + } + else + { + HighlightImage = 0 ; + HighlightMask = 0 ; + } +} + diff --git a/wmmenu/pixmaps.h b/wmmenu/pixmaps.h new file mode 100644 index 0000000..8885667 --- /dev/null +++ b/wmmenu/pixmaps.h @@ -0,0 +1,10 @@ +#ifndef pixmaps_h_ +#define pixmaps_h_ + +extern void Pixmaps_FindLoad (const char * name, + Pixmap * imageP, Pixmap * maskP, int * wP, int * hP) ; +extern void Pixmaps_LoadMenu (void) ; +extern void Pixmaps_LoadTile (void) ; +extern void Pixmaps_LoadHighlight (void) ; + +#endif /* pixmaps_h_ */ diff --git a/wmmenu/target-white.xpm b/wmmenu/target-white.xpm new file mode 100644 index 0000000..216ad3e --- /dev/null +++ b/wmmenu/target-white.xpm @@ -0,0 +1,69 @@ +/* XPM */ +static char * target_white_xpm[] = { +"64 64 2 1", +" c None", +". c white", +" ", +" ", +" .......... .......... ", +" .......... .......... ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .......... .......... ", +" .......... .......... ", +" ", +" "}; diff --git a/wmmenu/types.h b/wmmenu/types.h new file mode 100644 index 0000000..50e0ad9 --- /dev/null +++ b/wmmenu/types.h @@ -0,0 +1,16 @@ +#ifndef types_h_ +#define types_h_ + +typedef int bool ; +#ifndef false +#define false (0) +#endif +#ifndef true +#define true (1) +#endif + +#ifndef EOS +#define EOS '\0' +#endif + +#endif /* types_h_ */ diff --git a/wmmenu/utils.c b/wmmenu/utils.c new file mode 100644 index 0000000..cdb92e2 --- /dev/null +++ b/wmmenu/utils.c @@ -0,0 +1,183 @@ +#define _POSIX_SOURCE +#define _POSIX_C_SOURCE 199309L + +#include +#include +#include +#include +#include +/* POSIX */ +#include + +#include "utils.h" +#include "error.h" +#include "types.h" + +static char * ReadAll (FILE * f, int offset) +{ + char buf [10*1024] ; + int iRead, nRead ; + char * ret ; + + clearerr (f) ; + + iRead = 0 ; + nRead = 0 ; + while (iRead < sizeof buf) + { + nRead = fread (buf+iRead, 1, (sizeof buf)-iRead, f) ; + if (nRead <= 0) break ; + iRead += nRead ; + } + + if (nRead > 0) + { + assert (iRead == sizeof buf) ; + ret = ReadAll (f, offset+iRead) ; + } + else + if (ferror (f) != 0) + { + error ("read file: %s", strerror (errno)) ; + ret = NULL ; + } + else + { + ret = malloc (offset+iRead+1) ; + if (ret == NULL) error ("failed to allocate memory") ; + ret[offset+iRead] = EOS ; + } + memcpy (ret+offset, buf, iRead) ; + + return ret ; +} + +extern char * File_ReadAll (FILE * f) +{ + assert (f != NULL) ; + return ReadAll (f, 0) ; +} + +static const char * getHome (void) +{ + static char homeDir [80] = "" ; + static int initialized = 0 ; + if (! initialized) + { + const char * env ; + env = getenv ("HOME") ; + if (env != NULL && env[0] != EOS) + { + sprintf (homeDir, "%.*s", (int)(sizeof homeDir)-1, env) ; + } + initialized = 1 ; + } + return homeDir[0] != EOS ? homeDir : NULL ; +} + +extern bool File_FindInPath (char * out, int outSz, + const char * path, const char * basename) +{ + char name [FILENAME_MAX] ; + int len ; + + assert (path != NULL) ; + assert (basename != NULL) ; + assert (out != NULL) ; + + /* regular path */ + if (access (basename, F_OK) == 0) + { + sprintf (out, "%.*s", outSz-1, basename) ; + return true ; + } + else + /* relative to home directory */ + if (strncmp (basename, "~/", 2) == 0 && getHome () != NULL) + { + sprintf (name, "%s%s", getHome (), basename+1) ; + if (access (name, F_OK) == 0) + { + sprintf (out, "%.*s", outSz-1, name) ; + return true ; + } + else + { + return false ; + } + } + else + /* forbid relative to PATH just like shell */ + /* NB: absolute non-existent files also drop here */ + if (strchr (basename, '/') != NULL) + { + return false ; + } + else + { + while (*path != EOS) + { + len = strcspn (path, ":") ; + + if (strncmp (path, "~/", 2) == 0) + { + sprintf (name, "%s%.*s/%s", + getHome (), len-1, path+1, basename) ; + } + else + { + sprintf (name, "%.*s/%s", len, path, basename) ; + } + + if (access (name, F_OK) == 0) + { + sprintf (out, "%.*s", outSz-1, name) ; + return true ; + } + + path += len ; + while (*path == ':') path++ ; + } + + return false ; + } +} + +extern char * File_ReadOutputFromCommand (const char * cmd) +{ + FILE * out ; + char * ret ; + + if ((out = popen (cmd, "r")) == NULL) + { + error ("when calling command: %s, error: ", + cmd, strerror (errno)) ; + ret = NULL ; + } + else + { + ret = File_ReadAll (out) ; + pclose (out) ; + + /* if return value is correct, remove trailing whitespace */ + if (ret != NULL) + { + char *lastNotWhite, *cursor ; + char c ; + + cursor = lastNotWhite = ret ; + + while ((c = *cursor++) != EOS) + { + if (strchr (" \t\n", c) == NULL) + { + lastNotWhite = cursor ; + } + } + + *lastNotWhite = EOS ; + } + } + + return ret ; +} diff --git a/wmmenu/utils.h b/wmmenu/utils.h new file mode 100644 index 0000000..9394c4a --- /dev/null +++ b/wmmenu/utils.h @@ -0,0 +1,17 @@ +#ifndef utils_h_ +#define utils_h_ + +#include +#include +#include "types.h" + +extern char * File_ReadAll (FILE *) ; +extern bool File_FindInPath (char * out, int outSz, + const char * path, const char * basename) ; + +#define streq(S1,S2) (strcmp ((S1), (S2)) == 0) +#define streql(S1,S2,L) (strncmp ((S1), (S2), (L)) == 0) + +extern char * File_ReadOutputFromCommand (const char * cmd) ; + +#endif /* utils_h_ */ diff --git a/wmmenu/version.h b/wmmenu/version.h new file mode 100644 index 0000000..93bebea --- /dev/null +++ b/wmmenu/version.h @@ -0,0 +1,12 @@ +#ifndef version_h_ +#define version_h_ + +#ifdef WITH_GDKPIXBUF +#define ADDVER " (with gdk-pixbuf support)" +#else +#define ADDVER " (XPM only)" +#endif + +#define VERSION ("1.2" ADDVER) + +#endif /* version_h_ */ diff --git a/wmmenu/wmmenu.1 b/wmmenu/wmmenu.1 new file mode 100644 index 0000000..25a9671 --- /dev/null +++ b/wmmenu/wmmenu.1 @@ -0,0 +1,196 @@ +.TH "wmmenu" "1" "1.1" "Fabien COUTANT" "WMaker dockapp" +.SH "NAME" +.LP +wmmenu \- A WindowMaker dockapp to launch programs with a popup pixmap menu +.SH "SYNTAX" +.LP +wmmenu [\fI\fR] \fB\-m\fP \fI\fR +.br +wmmenu \fB\-v\fP +.br +wmmenu \fB\-h\fP +.SH "DESCRIPTION" +.LP +This is a "dock application" for Windowmaker, that provides a button bar to +launch applications from. +.LP +The bar opens automatically when either the mouse enters the button or you +click on it (this is configurable). +.LP +Multiple instances of the program can run at the same time: each one provides +a menu that it reads from a separate file, so you can have as many different +menus as you want (you can also display the same menu more than once if you +want; dunno what it's useful for...). +.LP +NOTE: options can take place before or after "\-m", as long as each option is +correctly paired with its corresponding argument (when it has one). +.SH "OPTIONS" +.LP +.TP +\fB\-h\fR +print a help message listing known options. +.TP +\fB\-v\fR +print version information +.TP +\fB\-g\fR \fIW\fP\fBx\fR\fIH\fP +force width and height of tile +.TP +\fB\-l\fR \fIXPMFILE\fP +set filename of the pixmap used to highlight icon under cursor +.TP +\fB\-t\fR \fIXPMFILE\fP +set filename of the pixmap used as button bar background. +XPMFILE may also be '!COMMAND' to execute COMMAND and get the pixmap name to use +from its output. +.TP +\fB\-O click\fR +bar is only triggered by clicks on the tile, not moves +.TP +\fB\-O noautoscale\fR +disable automatic pixmap scaling to tile size +.TP +\fB\-O behind\fR +draw highlight pixmap behind icon, not above +.TP +\fB\-O hide=\fIN\fR +set bar hiding timeout in ms. See hide_timeout description in Defaults. +.TP +\fB\-r\fR \fIROWS\fP +set number of menu rows (default one) +.LP +Please note, that \fB\-l\fR, \fB\-t\fR and \fB\-O behind\fR options +can also be specified with another syntax in the \fBdefaults\fR file +(described hereafter). +.SH "DEFAULTS FILE" +This is a configuration file that defines things common to all instances +of wmmenu. +It is located in "~/.wmmenu/defaults". + +.LP +The syntax is as follows: +.LP +# comment or empty lines are ignored +.LP +xpmpath PATH1:PATH2:... +.br +xpmpath PATH3 +.br +xpmpath PATH4 +.br +... +.br +# defines in which path to search for pixmaps +.LP +tile FILE.XPM +.br + or +.br +tile /SOME/PATH/TO/FILE.XPM +.br +# defines pixmap used as background tile in menu bar +.br + or +.br +tile !some_command with arguments +.br +# defines the command to call to get the pixmap name to be +# used: the name is read from its standard output. +# If the name read is empty, the internal default is used +# instead. +.LP +highlight FILE.XPM +.br + or +.br +highlight /SOME/PATH/TO/FILE.XPM +.br +# defines pixmap used to highlight item under cursor +.LP +highlight_behind[ ANYTHING_NOT_EMPTY] +.br +# (don't forget the separating space) +.br +# request to draw highlight pixmap BEHIND icon, +.br +# no more in front. +.br +# To be used if your pixmap is designed to cover most +.br +# of tile's surface +.LP +hide_timeout MS +.br +# set the delay, in ms, necessary for the bar to close +.br +# after the cursor has left wmmenu. 1 by default. +.SH "MENU FILES" +Those files each define a menu of their own. +Each menu file is located in "~/.wmmenu/\fI\fR"; +The name of the file determines the name you must use on command\-line +to call it. + +.LP +The syntax is the following: +.LP +# comment and blank lines are ignored +.TP +"MENUICON.XPM" menu title +There is exactly one such line in each menu file, +and is the first significant line encountered. +It describes the menu name, which may be used by your window manager, and +the pixmap that is shown to trigger the menu. +The pixmap is specified using the same rules as the next item (read on). +.TP +"ICON.XPM" command arguments & +\fIICON.XPM\fR is an image filename or path. +It can be an absolute path (begins with "/"), +a path relative to wmmenu's current directory (contains a "/" but not at the beginning), +a path relative to home directory (starts with "~/"), +or a simple file name (searched through all defined xpmpath elements). +If you compiled wmmenu with gdk\-pixbuf support, the image can be any format +supported by this library (GIF, PNG, TIFF, JPEG, etc...); +Otherwise only XPM is supported. +.br +\fIcommand\fR and \fIarguments\fR are run with the system(3) library call, +hence: +1/ you can use any shell tricks you want, and +2/ wmmenu waits for command completion, so for X11 programs you have to add +"\fB&\fR" at the end. +.SH "FILES" +.LP +\fI~/.wmmenu/\fP +.br +\fI~/.wmmenu/defaults\fP +.SH "ENVIRONMENT VARIABLES" +.LP +.TP +\fBHOME\fP +Specifies the home directory +.SH "EXAMPLES" +.LP +I personally use the following command line: +.LP +wmmenu \-m apps \-r 3 +.SH "BUGS" +.LP +If wmmenu was not compiled with gdk\-pixbuf support, +application icons larger than tile overlap over icons next to them. +With gdk\-pixbuf support turned on, images in this case are +automatically scaled down to fit to tile +(unless "\-O noautoscale" was specified). +.LP +There is some flicker when the mouse goes from the dockapp to the +menu bar. On fast displays this is not always apparent. +.LP +No editor is provided, to edit menu files. +However, editing by hand is not so difficult, and +menu files are automatically reloaded each time you save them. +You only have to restart wmmenu, if you change any setting in +the \fBdefaults\fR file. +.SH "AUTHORS" +.LP +Fabien COUTANT +.SH "SEE ALSO" +.LP +rox\-menu, wmaker diff --git a/wmmenu/wmmenu.c b/wmmenu/wmmenu.c new file mode 100644 index 0000000..1afb417 --- /dev/null +++ b/wmmenu/wmmenu.c @@ -0,0 +1,36 @@ +#include +#include + +#include + +#include "options.h" +#include "menu.h" +#include "version.h" +#include "pixmaps.h" +#include "buttonbar.h" +#include "events.h" + +extern int main (int argc, char ** argv) +{ + Options_ParseDefaults () ; + Options_Parse (argc, argv) ; + Menu_LoadFromFile (MenuName) ; + + DAParseArguments (Options_Argc, Options_Argv, NULL, 0, + "wmmenu", VERSION) ; + DAInitialize (NULL, (char*)Menu_GetTitle (), 48, 48, argc, argv) ; + + Pixmaps_LoadMenu () ; + Pixmaps_LoadTile () ; + /* needs tile to be loaded before to have autoscale work */ + Pixmaps_LoadHighlight () ; + /* bar build needs highlight mask and menu icons */ + ButtonBar_Build () ; + Events_SetCallbacks () ; + + DAShow () ; + Events_Loop () ; + + return EXIT_SUCCESS ; +} + diff --git a/wmmenu/xobjects.c b/wmmenu/xobjects.c new file mode 100644 index 0000000..76934ac --- /dev/null +++ b/wmmenu/xobjects.c @@ -0,0 +1,11 @@ +#include "xobjects.h" + +Pixmap TileImage = 0 ; +Pixmap TileMask = 0 ; +Pixmap HighlightImage = 0 ; +Pixmap HighlightMask = 0 ; +Pixmap HighlightBehindMask = 0 ; +Pixmap ButtonBarImage = 0 ; +Window ButtonBarWindow = 0 ; +Window WMFrame = 0 ; + diff --git a/wmmenu/xobjects.h b/wmmenu/xobjects.h new file mode 100644 index 0000000..2edfcc2 --- /dev/null +++ b/wmmenu/xobjects.h @@ -0,0 +1,13 @@ +#ifndef xobjects_h_ +#define xobjects_h_ + +#include + +extern Pixmap TileImage, TileMask ; +extern Pixmap HighlightImage, HighlightMask ; +extern Pixmap HighlightBehindMask ; +extern Pixmap ButtonBarImage ; +extern Window ButtonBarWindow ; +extern Window WMFrame ; + +#endif /* xobjects_h_ */