sync code with last improvements from OpenBSD

This commit is contained in:
purplerain 2023-08-28 05:57:34 +00:00
commit 88965415ff
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
26235 changed files with 29195616 additions and 0 deletions

View file

@ -0,0 +1,45 @@
These bugs are not fixed, if you think you can help, do so.
Known bugs as of FvwmButtons-200396b:
* Chuck says it doesn't redraw correctly on resizes on AIX; it requires
full expose to do this..? Could this be a problem with the X server?
Known bugs as of FvwmButtons-080396:
* Another problem with swallowing is when two FvwmButtons decides to swallow
the same window, only one succeeds. Morale: modify the titles of programs
you start to be swallowed... One simple way to try to see this error is
to fire up two copies of the same FvwmButtons at the same time.
There is a define on top of FvwmButtons.c you can uncomment to get some
debug on this; DEBUG_HANGON.
There has also been reported problems with buttons hanging forever after
being pressed, this might be related.
* When you make the buttonbox small enough (= very small, less than 1x1
pixel inside relief and padding) it exits. Should make it silently suffer
with grace instead. Update: actually this is a problem with the swallowed
windows, some crash when made 1x1. Otherwise the rest is fixed.
Known bugs as of FvwmButtons-070396:
* Action commands are supposed to work also on swallowed windows, but there
is a problem with X. After reparenting, XSelectInput is called with a mask
including ButtonPressMask|ButtonReleaseMask, but evidently no buttonpresses
are received, even though the program (like xload) doesn't use them for
itself. So where is the bottleneck? Send the solution if you got it.
OK, so I need to do SubstructureRedirectMask, and shuffle all the events
onwards... really? No better way? Mmm..
Known bugs as of FvwmButtons-040396:
* There are still some problems related to swallowed windows, but I haven't
found a reliable way to reproduce them. What probably happens is that a
window is created, FvwmButtons gets its name and desides to swallow it, it
is mapped, but before it gets swallowed it fails, thus the reparent code
does a BadWindow.
* When you kill many swallowed windows quickly, FvwmButtons crashes probably
because after gracefully removing one of it's children it tries to redraw
some other before handling more destroy_requests.

View file

@ -0,0 +1,392 @@
Changed since FvwmButtons-200396b
* 110198: Updated manpage
* 110198: Animated panel, button geometry and 'Left', 'Right', 'Center'
options have been added.
* 200396: Updated TODO file some.
* 210396: Fixed Desk buttons that didn't hang correctly.
* 280396: Chuck: Fixed some problems with macro definitions min,max and abs
on AIX
* 280396: Think I fixed the problem that made windows get huge on machines
with non-cleaning mallocs (AIXs) when no global Frame was specified.
* 280396: Somehow the string "*blabla" should have _2_ chars more allocated
than "blabla" or the parser would choke and die on some ELF linux system..
Thanks to Dirk Vangestel for this.
Changed since FvwmButtons-200396
* 200396: Hups, seems I introduced a little bug that made it reluctant to
swallow some windows, particularly shaped ones... Should be back to normal
now.
* 200396: Thanks to Romano again for saving my ass - I managed to remove
the initialization of b->flags, creating major disasters on startup.
Changed since FvwmButtons-130396
* 130396: Did lots and lots of things, actually had pixmaps for backgrounds
working, and had started a complete restructuring of the source (again)
Then the disk crashed. Good. Happy.
* 140396: Fixed real inheritance of swallow flags.
* 140396: Fixed bug which dumped core if Desk buttons were present.
* 140396: Check before redrawing background/padding if it's needed.
* 140396: Gave bitmaps the correct background color.
* 180396: On slow systems, when using the UseOld flag on several buttons,
it could spawn several copies of each program. Now only spawns after
_first_ M_END_WINDOWLIST, not every one.
Also made it honor inherited UseOld flags and not spawn on startup.
* 180396: Some editing... does every cpp understand '# ifdef A' ?
* 180396: Removed a couple of calls to buttonJustify in draw.c..
* 190396: Made the parser properly use tolower() when comparing, preparing for
i18n to LC_CTYPE...
* 200396: Updated somewhat to work with latest fvwmlib picture patch of mine.
* 200396: Again changed the resource name and class, now it is (in ICCCM
compliance) the invoking name and FvwmButtons, respectively.
* 200396: Now also does shaped bitmaps w/o xpm library. You won't notice
until the background pixmaps are done though. Also fixed a memory leak
where the temporary pixmap made for a bitmap was not deleted.
* 200396: Now uses the picture caching introduced with the fvwmlib patch
mentioned above. This patch btw also applies to fvwm menus, could save
major amounts of memory (say 50 equal 16x16 pixmaps - you save 49 times
512 bytes for just the pixmaps and the masks (assuming 8bit display),
plus some overhead. Not to mention it should start much faster!
* 200396: Now uses XTranslateCoordinates instead of XQueryTree to find
real coords when swallowing a window.
Changed since FvwmButtons-120396
* 120396: Now properly avoids modifying icons on monochrome displays. This
used to ruin xpm's mono settings. A patch for the Picture code in fvwmlib
is also needed, get my fvwm-picture-pl2.patch, and also fvwm-menus.patch
which will fix the same problem for fvwm menus.
* 130396: Fixed two typos on the man page, thanks to Brandon for noticing.
* 130396: Improved parser to ignore leading spaces in buttonrc files, and
to accept any amount of whitespace between *FvwmButtons and (...) in
.fvwm[2]rc. Thanks to Alan for pointing this weakness out.
* 130396: The main call to XCreateSimpleWindow would give random x,y coords
unless given a geometry, perhaps that is allowable when using a WM, but not
without. This is now fixed.
* 130396: Now uses XSetWMProperty instead of XmbSetWMProperty, to please
those stuck with X11R4. Thanks to Angiolini Giorgio for the information.
* 130396: Fixed parser to cope with Exec something, i.e. without the ""
empty hangon notifier. It used to garb this up, trying to do Exec mething.
Fixed man page to reflect the change.
Changed since FvwmButtons-110396b
* 120396: Added lots of debug information for swallow/unswallow. Finally did
it all properly when exiting, no more X Errors when restarting fvwm from
FvwmButtons :-) FvwmButtons grabs the server, and goes through the
pending eventlist to decide which windows have been destroyed by fvwm
already before deciding to kill,close or reparent. Or ignore. After all
children are handled, ther server is ungrabbed.
* 120396: Added some debugging output for events and fvwm communication.
Now uses only SendText instead of both SendInfo and SendText (duplicates).
* 120396: Fixed the position detection routine for buttonpresses, should now
be a little more accurate.
* 120396: Fixed stupid negated #ifdef that tried to use the XPM color loading
if you didn't have it, and not if you did.
* 120396: Finally! Removed the superfluous XFree that had made FvwmButtons
unusable to many people! Thanks, thanks and many more thanks to Romano
Giannetti for tracing down this stupid bug! I mean, the variable it freed
wan't even used! Romano is hereby awarded the title "Bugslayer" for this
outstanding feat. Applause!
* 120396: Added some more starting debug info that should be unneeded after
the above fix.
* 120396: Turned _off_ most debug options by default. Moved them to the
header file.
* 120396: Cleaned up a few unused variables. Added #include <ctype.h> to
parse.c, after advice from Romano.
Changed since FvwmButtons-110396
* 110396: Fixed bug where, if Respawn was specified by a container, and a
button had specifed NoRespawn, it would still respawn. Or the opposite
situation, Respawn locally and NoRespawn higher up, would cause NoRespawn.
* 110396: Fixed bug where x padding would be set equal to y padding if no
padding was specified for a button.
* 110396: Wrote a file INSTALL and a samplebuttonrc file.
* 110396: Fixed bug where containers would get padding and information from
parents on redraw, when they were not supposed to.
* 110396: Fixed bug where icons left of title would not be clipped properly
when the button was sized too small.
* 110396: Added error messages telling when a font could not be loaded.
* 110396: Turned on lots of starting info by default (turn it off by
commenting out the defines in FvwmButtons.c) which will hopefully help
people understand what is going on when it dumps core on them.
* 110396: Fixed bug where bitmaps would get drawn with current background
instead of the one given for the button.
* 110396: Fixed ShuffleButtons to reduce the number of rows if there are
too many of them. This should correctly handle single buttons without
giving rows or columns options.
* 110396: FvwmButtons will now not create windows less than 16x16 pixels,
in case you have not provided a geometry or any buttons from which
FvwmButtons can calculate a unit buttonsize.
Changed since FvwmButtons-080396
* 090396: Parser now accepts escaped quoting characters in quote. Only the
current quoting character is unescaped while parsing, i.e:
Action `Exec emacs \`xcb -p 1\` -title \"hello\"`
would give
Exec emacs `xcb -p 1` -title \"hello\"
Also, the string "\\"" would be read to \", as only the sequence \q will
be collapsed, where q is the quoting character.
Thanks to Emiel Witteman <ewittema@wi.leidenuniv.nl> for pointing out the
necessity of this improvement.
* 090396: Rewrote flag handling, now you can specify title flags and swallow
flags in the container part, like Container(Title(Left,Side)) and that will
count for all subbuttons. This also goes for all the swallowing flags, and
these negatives have been introduced: Kill, Hints, NoRespawn, NoOld,
NoTitle. All this is yet not fully tested.
There is no negative for Title(Side) because this is a Hack! (see README)
* 090396: Made a patch to fvwm-2.0.41 that allows any module to pop up a real
Popup menu! Just use it as a regular command - it's like a dream.
* 090396: Changed ResourceName to "FvwmButtons" and ResourceClass to
"FvwmModule", regardless of what name the module is given at runtime.
* 090396: Split up source some more, mostly to ease maintenance and get
faster recompiles.
* 090396: Took a shot at the exposure handler, relaxed the updating a little,
now there is _much_ less flashing when redrawing, and it only redraw parts
that are part of the expose.
* 090396: Moderated ending efforts to WM_DELETE_WINDOW instead of KillClient.
However some programs don't understand that, so remodeled Kill,NoKill flags
to decide if KillClient should be used. The old Kill,NoKill are now
Close,NoClose.
* 090396: Updated the man page somewhat on the flag changes.
* 090396: Rewrote icon handling to use fvwmlib's Picture routines, the same
that are used for fvwm's menus. Made a patch to fix bitmap searching for
this.
* 090396: Tidied away all the colorcloseness settings, it's the same level
as the other xpm stuff used so no extra checking needs be done.
* 090396: Fixed bitmap icons, which converted from 1 to X planes each time
they were drawn, bummer.
* 090396: Actually fixed most problems with resizing to a very small size.
Swallowed windows might still give you X Errors though, if they don't like
being 1x1.
* 110396: Added config option *FvwmButtonsFile string which will read the
config from the file "string" instead. Also, this can be given as an
argument starting with: FvwmButtons FvwmTesting string
This config file is the same as in .fvwm[2]rc, but you don't put
*FvwmButtons in front of all the lines.
The filename will have to be given with full path or be relative to the
dir you started fvwm in. No preprocessor is available, but it does '#'
comments and linecontinuation.
Changed since FvwmButtons-070396
* 080396: Now _really_ works with common PixmapPath and IconPath. I have even
tested it this time :-)
* 080396: Rewrote swallowing: If a window disappears between M_WINDOW_NAME etc
and M_MAP, it is assumed crashed, no further action. But if the window
simply has gotten another parent, we assume some other swallower got to it
before us, so we release our hold and give a new Send_Windowlist to find
another fitting window, and if that fails, spawns one ourself.
Still, best to avoid competition about windows to be swallowed, use
different titles. It still easily fails if it processes an out of date
windowlist.
* 080396: Put in some more debugging output, controlled by the defines in
the head of FvwmButtons.c.
* 080396: Now, when quitting FvwmButtons, it checks to see if a window still
exists before trying to kill it or unswallow it.
* 080396: Added Size w h command, assures a button get at least this large.
Great for buttonboxes with only swallowed windows.
* 080396: Man page: Added Size description, replaced some "frame"s with
"relief" (Maybe the option should be changed also?), added a subsection
on how initial buttonsizes are calculated, changed #908090 to rgb:90/80/90
to conform to X standards, and wrote a blurb saying so, and what to
consider when using the older # method.
* 080396: Fixed redrawing buttons - now the container padding is cleared
correctly also when resized to mismatching sizes.
* 080396: FvwmButtons now allocates only one graphic context instead of 3.
Shadow of buttons are now longer handled specially for monochrome screens.
* 080396: Hacked an option to the Title command, Title(Side) now stacks
Icon and Title side by side. It also left justifies the icon automatically.
Between the icon and title there is the horizontal padding space.
Added it to the man page.
Changed since FvwmButtons-060396
* 060396: Made if startable as "Module FvwmButtons SomeButtons", or even
"FvwmButtons SomeButtons", which will name it SomeButton and does away
with silly softlinks.
* 060396: Fixed the close color allocation via Xpm to work with xpm versions
back to 3.2b, which was released october 92. There was really no need of
using features from 3.4g.
* 060396: Rewrote font loading, for no particular reason.
* 070396: Did some work on individual color settings, now Fore and Back can
be set in buttons and in containers.
* 070396: Take back suggestion that ConfigureNotify is autofollowed by
Expose, not true when no subwindows. Now ConfigureNotify Resize does a
full redraw.
* 070396: Fixed Right option of strings, which was broken. For instance,
when used, title became left justified. Also it was a little confused
about which font to use where.
* 070396: Update man page to specify Back and Fore colors and mention
argument namechange. (I.e FvwmButtons AnotherName invocation.)
Changed since FvwmButtons-040396
* 060396: Removed a bug that would choke on buttons with "Desk xxxx" commands
on them. Thanks to Robert Tarrall <tarrall@plutus.colorado.edu>.
* 060396: Color-closeness behaviour has been disabled by default, as it
requires xpm-3.4g or newer. Several people had trouble with this. It now
avoids this code if your xpm include is too old.
* 060396: Removed bug that made it ignore an xpm when it was in the same
directory searched for bitmaps.
* 060396: Now sets Class and Resource to FvwmButtons (or bound name) instead
of NoClass, NoResource. Code copied from FvwmTalk.
* 060396: Parser no longer accepts '(' and ')' as quoting characters, those
are reserved for optional parameters. String quotation characters available
are "string", 'string' and `string`, the last one should be used if you
want preprocessors to get inside.
* 060396: Some general cleanup of unused variables and unclean typing. Got a
little shocked when I saw what good ol' -Wall came up with.
* 060396: Changed Action syntax, removed Mouse syntax. Mouse # command shall
now be given as Action(Mouse #) command. Future extensions of this will be
Action(Mouse # [Click|DoubleClick|Move [N|S|E|W]]) command and
Action(Key code [moderators]) command.
* 060396: Fixed line continuation in the man page, thanks to Romano Giannetti
<romano@iet.unipi.it> for pointing it out.
* 060396: Swallow changes! There is a new flag UseTitle, which must be used
if you want the button to get the window title as it's title. It will no
longer automatically overwrite. This is not backwards compatible though.
Also there is a change of syntax, all swallow flags must now be given with
the swallow command, like:
Swallow(NoHints, NoKill, Respawn, UseOld, UseTitle) Hangon Command
* 060396: When NoKill is set, windows are unswallowed to their original
geometry (x,y,width,height,borderwidth). Nice in conjunction with UseOld.
Note: If you experience _systematic_, _reproducable_ errors with NoKill,
UseOld, Respawn etc, do not hesitate to report! There are some dustdragons
around.
* 060396: Frame now accepts a negative parameter, this causes the frame to
be inverted for all purposes. Pushing an inverse button makes it stand out
etc. This duplicates the excellent Variable Relief patch by Gregory
Lauckhart <gregl@cs.washington.edu>
* 060396: Did some real updating of the manual page. Even wrote a section
on the arranging algorithm!
* 060396: Put in justification of titles, the syntax is now
"Title[(Left|Right|Center)] string". If the title is too long its tail is
cut off, unless it is Right justified - then its head goes.
Now only stacking order is missing before we have it emulate menus with
icons :-)
* 060396: Fixed code that stores geometry of a swallowed window, now it
really unswallows to same place. Hint: XQueryTree()....
* 060396: Finally got rid of the annoying problem that swallowed programs
sometimes managed put a border on themselves after being positioned.
ResizeRedirectMask to dead ears is like plucking the legs of an insect...
* 060396: Added option NoSize, which will make the initial size estimate
skip that button when calculating sizes. A very long title or an almost
right size icon could ruin you whole setup without it.
Changed since FvwmButtons-020396
* 030396: Fixed the positioning of large windows, which was thoroughly
unusable due to a "bug" in button_belongs_to(). Rewrite touched a little
on ShuffleButtons() too.
* 040396: Fixed bug that made FvwmButtons crash with BUG: Illegal iconwindow
if an icon failed to load for some reason.
* 040396: Added better error messages for GetXPMFile(), also told Xpm to use
whatever closest colors available if not able to allocate exact ones.
* 040396: Made it allocate colors through a call to XpmCreateImageFromData()
to gain from its color closeness algorithms, which gets close colors if no
space is left in the colormap. Better than crashing :-) Should put all the
calls together to make it in one go...
But what to do when not using Xpm?
* 040396: Fixed bug that messed up icon_w and icon_h when failing to load a
bitmap, which messed up buttonsizes and made a BadValue when creating the
main window.
* 040396: Fixed bug, when a font failed in a subcontainer, it would copy it's
parents personal font instead of it's public font, probably just a garbage
pointer. If any subbuttons had titles, it would foul up as above.
* 040396: Actually, it seems it was this: when a button with both icon and
title failed to load it's icon, icon_w and icon_h was never initialized,
but used to calculate button size.

View file

@ -0,0 +1,590 @@
.\" $OpenBSD: FvwmButtons.1,v 1.1.1.1 2006/11/26 10:53:44 matthieu Exp $
.\" t # I don't know this stuff, sorry. -Jarl
.\" @(#)FvwmButtons.1 1/28/94
.TH FvwmButtons 1 "Nov 1 1998"
.UC
.SH NAME
FvwmButtons \- the FVWM buttonbox module
.SH SYNOPSIS
FvwmButtons is spawned by fvwm, so no command line invocation will work.
.SH DESCRIPTION
The FvwmButtons module provides a window of buttons which sits on the X
terminal's root window. The user can press the buttons at any time,
and trigger invocation of a user-specified command by the window
manager. FvwmButtons only works when fvwm is used as the window manager.
The buttonbox can be of any configuration or geometry, and can have
monochrome or color icons to represent the actions which would be
invoked.
.SH INITIALIZATION
During initialization, \fIFvwmButtons\fP will search for a configuration
file which describes the buttonbox geometry, color, icons, and
actions. The format of
this files will be described later. The configuration file will be the
one which fvwm used during its initialization.
To use FvwmButtons with several different configurations, you can
invoke FvwmButtons with an optional parameter, which it will use
as its name instead (e.g "Module FvwmButtons SomeButtons").
SomeButtons will then read only the lines in the configuration file
starting with "*SomeButtons", and not the lines belonging to FvwmButtons.
You can also specify an optional configuration file to use instead of
the default fvwm configuration file, by giving a second argument which
is a filename. This will override the setting "*FvwmButtonsFile", see
below.
.SH INVOCATION
FvwmButtons can be invoked by inserting the line 'Module FvwmButtons' in
the .fvwmrc file. This should be placed in the InitFunction if FvwmButtons
is to be spawned during fvwm's initialization, or can be bound to a
menu or mouse button or keystroke to invoke it later. Fvwm will search
directory specified in the ModulePath configuration option to attempt
to locate FvwmButtons.
.SH CONFIGURATION OPTIONS
The following options int the .fvwmrc file are understood by FvwmButtons:
.IP "*FvwmButtonsBack \fIcolor\fP"
Specifies the background color for the buttons. A relief and a shadow color
will also be calculated from this.
.IP "*FvwmButtonsBoxSize \fIalgorithm\fP"
This option specifies how serious FvwmButtons takes the Rows and Colums
options (see below). It can be one of \fIdumb\fP, \fIfixed\fP or \fIsmart\fP.
If fixed is given and both Rows and Columns are specified and non-zero,
FvwmButtons will use exactly this numbers of rows and columns of button. If
the box is too small to accomodate all buttons the module will fail. Using
the smart option FvwmButtons is intelligent enough to enlarge the box so
all buttons have a chance to fit. The number of columns is increased to at
least the width of the widest button and new rows are added until all buttons
can be placed. For best tolerance of configuration of errors use the
smart option.
.IP "*FvwmButtonsColumns \fIcolumns\fP"
Specifies the number of columns of buttons to be created. If unspecified,
the number of columns will be set to the number of buttons requested,
divided by the number of rows. If both the rows and columns are
specified, but do not specify as many buttons as are defined, then the
users columns specification will be ignored unless the value \fIfixed\fP
was gived to the \fIBoxSize\fP option (see there).
.IP "*FvwmButtonsFile \fIfilename\fP"
Specifies that the configuration for this button is found in the file
\fIfilename\fP, which will have to be given with full pathname, or is
assumed to be in fvwm's startup directory. The configuration file is in
the same format as fvwm's configuration file, but each line is read as
if prefixed by "*FvwmButtons". Comments are given by starting a line with
"#", line continuation is done by ending a line with a "\\".
.IP "*FvwmButtonsFont \fIfont\fP"
Specifies the font to be used for labeling the buttons, or \fINone\fP.
.IP "*FvwmButtonsFore \fIcolor\fP"
Specifies the color used for button label text and monochrome icons.
.IP "*FvwmButtonsFrame \fIwidth\fP"
Specifies the width of the relief around each button. If this is given
as a negative number, the relief will at all times be the inverse of the
normal relief. In effect, you will get a sunken button, which is raised when
activated.
.IP "*FvwmButtonsGeometry \fIgeometry\fP"
Specifies the FvwmButtons window location. The size should not be specified,
as FvwmButtons automatically chooses a size which gracefully accomodates
all its buttons. The geometry is a standard X11 window geometry specification.
.IP "*FvwmButtonsPadding \fIwidth height\fP"
The amount of free space between the relief of the button and its contents
is normally 2 pixels to the sides and 4 pixels above and below, except for
swallowed windows and containers, which are not padded at all, unless
given specific orders. This setting
specifies the default horizontal padding to be \fIwidth\fP pixels, and the
vertical padding to be \fIheight\fP pixels.
.IP "*FvwmButtonsPanel \fItitle\fP"
Specifies the title of a panel. All following *FvwmButtons
configuration commands up to the next *FvwmButtonsPanel line
refer to the panel.
.IP "*FvwmButtonsPixmap \fIpixmapfile\fP"
Specifies a background pixmap to use. Specify "none" for a transparent
background.
.IP "*FvwmButtonsRows \fIrows\fP"
Specifies the number of rows of buttons to be created. If unspecified,
2 rows will be used.
.IP "*FvwmButtons(\fIoptions\fP) [\fItitle icon command\fP]"
Specifies the contents of a button in the buttonbox.
The following \fIoptions\fP, separated by commas or whitespace, can be
given a button:
.IP " \fIgeometry\fP"
Specifies the size and position of the button within the FvwmButtons window
or container. The button will be \fIwidth\fP times the normal button width
and \fIheight\fP times the normal button height. If values for \fIx\fP and
\fIy\fP are given, the button is placed x (y) button units from the left
(top) of the container if x (y) is positive and x (y) units from the right
(bottom) if x (y) is negative. The geometry is a standard X11 window geometry
specification. Buttons with position arguments (x and y) are placed before
thos without them. If two or more buttons are forced to overlap by this,
FvwmButton exits with an error message.
.IP " Action [(\fIoptions\fP)] \fIcommand\fP"
Specifies an fvwm command to be executed when the button is activated
by pressing return or a mouse button. The \fIcommand\fP needs to be
quoted if it contains a comma or a closing parenthesis. The current
options are:
Mouse \fIn\fP - this action is only executed for mouse button \fIn\fP.
One actions can be defined for each mouse button, in addition to the
general action.
.IP " Back \fIcolor\fP"
Specifies the background color to be used drawing this box. A relief color
and a shadow color will also be calculated from this.
.IP " Center"
The contents of the button is centered on the button. This is the default but
may be changed by \fILeft\fP or \fIRight\fP.
.IP " Container [(\fIoptions\fP)]"
Specifies that this button will contain a miniature buttonbox, more or less
equivalent to swallowing another FvwmButtons module. The options are the
same as can be given for a single button, but they affect all
the contained buttons. Options available for this use are \fIBack, Font,
Fore, Frame\fP and \fIPadding\fP. Flags for Title and Swallow options can
be set with \fITitle(flags)\fP and \fISwallow(flags)\fP.
You should also specify either "Columns \fIwidth\fP" or "Rows \fIheight\fP",
or "Rows 2" will be assumed for purpose of arranging the buttons inside
the container. For an example, see the \fISample configuration\fP section.
The container button itself (separate from the contents) can take format
options like
\fIFrame\fP and \fIPadding\fP, and commands can be bound to it. This means
you can make a sensitive relief around a container, like
*FvwmButtons(2x2, Frame 5, Padding 2 2, Action Beep,\\
Container(Frame 1))
Typically you will want to at least give the container a size setting
\fIwidth\fPx\fIheight\fP.
.IP " End"
Specifies that no more buttons are defined for the current container, and
further buttons will be put in the container's parent. This option should
be given on a line by itself, i.e
*FvwmButtons(End)
.IP " Font \fIfontname\fP"
Specifies that the font \fIfontname\fP is to be used for labeling this button.
.IP " Fore \fIcolor\fP"
Specifies a color of the title and monochrome icons in this button.
.IP " Frame \fIwidth\fP"
The relief of the button will be \fIwidth\fP pixels wide. If \fIwidth\fP
is given as a negative number, the
relief will at all times be the inverse of the normal relief.
In effect, you will get a sunken button, which is raised when activated.
.IP " Icon \fIfilename\fP"
The name of an X11 bitmap file or XPM color icon file, containing the
icon to display on the button. FvwmButtons will search through the path
specified in the fvwm IconPath or PixmapPath
configuration items to find the icon file.
.IP " Left"
The contents of the button will be aligned to the left. The default is to
center the contents on the button.
.IP " NoSize"
This option specifies that this button will not be considered at all when
making the initial calculations of buttonsizes. Useful for the odd button
that gets just a couple of pixels to large to keep in line, and therefor
blows up your whole buttonbox. "NoSize" is equivalent to "Size 0 0".
.IP " Padding \fIwidth height\fP"
The amount of free space between the relief of the button and its contents
is normally 2 pixels to the sides and 4 pixels above and below, except
for swallowed windows and containers, which are by default not padded at all.
This option sets the horizontal padding to \fIwidth\fP and the vertical
padding to \fIheight\fP.
.IP " Panel [ (\fIdirection\fP) ] \fIname\fP"
Pop up a panel in the specified \fIdirection\fP from the
invoking button. A position set with *FvwmButtonsGeometry is taken
as a relative offset to this position. \fIdirection\fP may be
"up" (the default), "left", "down" od "right". The panel is a
button bar itself. See \fIFvwmButtonsPanel\fP. To get the panel
at a specific place on the screen use "geometry" in place of the
direction. The *FvwmButtonsGeometry line will then be treated as
a normal X geometry specification.
.IP " Right"
The contents of the button will be aligned to the Right. The default is to
center the contents on the button.
.IP " Size \fIwidth height\fP"
Specifies that the contents of this button will require \fIwidth\fP by
\fIheight\fP pixels, regardless of what size FvwmButtons calculates from
the icon and the title. A buttonbar with only swallowed windows will
not get very large without this option specified, as FvwmButtons does not
consider sizes for swallowing buttons. Note that this option gives the
minimum space assured; other buttons might require the buttonbox to use
larger sizes.
.IP " Swallow [(\fIflags\fP)] \fIhangon\fP \fIcommand\fP"
Causes FvwmButtons to execute \fIcommand\fP, and when a window matching the
name \fIhangon\fP appears, it is captured and swallowed into this button.
An example:
*FvwmButtons(Swallow XClock 'Exec xclock &')
will take the first window whose name, class or resource is "XClock" and
display it in the button. Modules can be swallowed by specifying
the module instead of 'Exec whatever', like:
*FvwmButtons(Swallow "FvwmPager" "FvwmPager 0 0")
The flags that can be given to swallow are:
NoClose / Close -
Specifies whether the swallowed program in this button will be unswallowed
or closed when FvwmButtons exit cleanly. "NoClose" can be combined with
"UseOld" to have windows survive restart of windowmanager. The default
setting is "Close".
NoHints / Hints -
Specifies whether hints from the swallowed program in this
button will be ignored or not, useful in forcing a window to resize itself
to fit its button. The default value is "Hints".
NoKill / Kill -
Specifies whether the swallowed program will be closed by killing it or by
sending a message to it. This can be useful in ending programs that
doesn't accept window manager protocol. The default value is "NoKill".
This has no effect if "NoClose" is specified.
NoRespawn / Respawn -
Specifies whether the swallowed program is to be respawn if it dies.
If "Respawn" is specified, the program will be respawned using the original
\fIcommand\fP. Use this option with care, the program might have a very
legitimate reason to die.
NoOld / UseOld -
Specifies whether the button will try to swallow an existing window matching
the \fIhangon\fP name before spawning one itself with \fIcommand\fP.
The default value is "NoOld".
"UseOld" can be combined with "NoKill" to have windows survive restart of
windowmanager. If you want FvwmButtons to swallow an old window, and not
spawn one itself if failing, let the \fIcommand\fP be "Nop":
*FvwmButtons(Swallow (UseOld) "Console" Nop)
If you want to be able to start it yourself, combine it with an action:
*FvwmButtons(Swallow (UseOld) "Console" Nop, \\
Action `Exec "Console" console &`)
NoTitle / UseTitle -
Specifies whether the title of the button will be taken from the swallowed
window's title or not. If "UseTitle" is given, the title on the button will
change dynamically to reflect the window name. The default is "NoTitle".
.IP " Title [(\fIoptions\fP)] \fIname\fP"
Specifies the title which will be written on the button.
Whitespace can be included in the title by quoting it.
If a title at any time is to long for
its buttons, characters are chopped of one at a time until it fits.
If \fIjustify\fP is "Right", the head is removed, otherwise its tail is
removed.
These \fIoptions\fP can be given to Title:
Center - The title will be centered horizontally. This is the default.
Left - The title will be justified to the left side.
Right - The title will be justified to the right side.
Side - This will cause the title to appear on the right hand side of
any icon or swallowed window, instead of below it which is the default.
If you use small icons, and combine this with the "Left" option, you can
get a look similar to fvwm's menus.
.IP "Legacy fields [\fItitle icon command\fP]"
These fields are kept for compatibility with previous versions of
FvwmButtons, and their use is discouraged.
The \fItitle\fP field is similar to the option
Title \fIname\fP. If the title field is "-", no title will be displayed.
The \fIicon\fP field is similar to the option
Icon \fIfilename\fP. If the icon field is "-" no icon will be displayed.
The \fIcommand\fP field is similar to the option
Action \fIcommand\fP or alternatively Swallow "\fIhangon\fP" \fIcommand\fP.
.IP "The \fIcommand\fP"
Any fvwm command is recognized by FvwmButtons. See fvwm(1) for more info
on this. The Exec command has a small extension when used in Actions,
its syntax is here:
Exec ["hangon"] command
When FvwmButtons finds such an Exec command, the button will remain
pushed in until a window whose name or class matches the
qouted portion of the command is encountered. This is intended to
provide visual feedback to the user that the action he has requested
will be performed. If the qouted portion
contains no characters, then the button will pop out immediately.
Note that users can continue pressing the button, and re-executing the
command, even when it looks "pressed in."
.IP "Quoting"
Any string which contains whitespace must be quoted. Contrary to
earlier versions commands no longer need to be quoted. In this
case any quoting character will be passed on to the application
untouched. Only commas ',' and closing parentheses ')' have to
be quoted inside a command.
Quoting can be done with any of the three quotation characters;
single quote:
'This is a "quote"',
double quote:
"It's another `quote'",
and backquote:
`This is a strange quote`.
The backquoting is purposeful
if you use a preprocessor like FvwmCpp and want it to get into your
commands, like this:
#define BG gray60
*FvwmButtons(Swallow "xload" `Exec xload -bg BG &`)
Furthermore a single character can be quoted with a preceding
backslash '\'.
.SH ARRANGEMENT ALGORITHM
FvwmButtons tries to arrange its buttons as best it can, by using
recursively, on each container including the buttonbox itself,
the following algorithm.
.IP "Getting the size right"
First it calculates the number of button unit areas it will need, by adding
the width times the height in buttons of each button. Containers are
for the moment considered a normal button.
Then it considers the given \fIrows\fP and \fIcolumns\fP arguments.
If the number of rows is given, it will calculate how many columns are needed,
and stick to that, unless \fIcolumns\fP is larger, in which case you will
get some empty space at the bottom of the buttonbox.
If the number of columns is given, it calculates how many rows it needs
to fit all the buttons.
If neither is given, it assumes you want two rows, and finds the number of
columns from that.
If the BoxSize option is set to \fIsmart\fP at least the height/width of
the tallest/widest button is used while the \fIfixed\fP value prevents the
box from getting resized if both \fIrows\fP and \fIcolums\fP have been set
to non-zero.
.IP "Shuffling buttons"
Now it has a large enough area to place the buttons in, all that is left is
to place them right. There are two kinds ob buttons: fixed and floating
buttons. A fixed button is forced to a specific slot in the button box by
a x/y geometry argument. All other buttons are considered floating. Fixed
buttons are placed first. Should a fixed button overlap another one or shall
be place outside the buttons window, FvwmButtons exits with an error message.
After that the floating buttons are placed.
The algorithm tries to place the buttons in a left to right, top to bottom
western fashion. If a button fits at the suggested position it is placed
there, if not the current slot stays empty and the slot to the right will
be considered. After the button has been placed, the next button is tried
to be placed in the next slot and so on until all buttons are placed.
Additional rows are added below the bottom line of buttons until all buttons
are placed if necessary if the BoxSize option \fIsmart\fP is used.
.IP "Containers"
Containers are arranged by the same algorithm, in fact they are shuffled
recursively as the algorithm finds them.
.IP "Clarifying example"
An example might be useful here: Suppose you have 6 buttons, all unit sized
except number two, which is 2x2. This makes for 5 times 1 plus 1 times 4
equals 9 unit buttons total area. Assume you have requested 3 columns.
.nf
.sp
1) +---+---+---+ 2) +---+---+---+ 3) +---+---+---+
| 1 | | | 1 | | | 1 | |
+---+ + +---+ 2 + +---+ 2 +
| | | | | | 3 | |
+ + + +---+---+ +---+---+---+
| | | | | | | |
+-----------+ +---+-------+ +---+---+---+
4) +---+---+---+ 5) +---+-------+ 6) +---+-------+
| 1 | | | 1 | | | 1 | |
+---+ 2 + +---+ 2 | +---+ 2 |
| 3 | | | 3 | | | 3 | |
+---+---+---+ +---+---+---+ +---+-------+
| 4 | | | 4 | 5 | | | 4 | 5 | 6 |
+---+---+---+ +---+---+---+ +---+---+---+
.sp
.fi
.IP "What size will the buttons be?"
When FvwmButtons has read the icons and fonts that are required by its
configuration, it can find out which size is needed for every non-swallowing
button. The unit button size of a container is set to be large enough to
hold the largest button in it without squeezing it. Swallowed windows
are simply expected to be comfortable with the buttonsize they get
from this scheme. If a particular configuration requires more space
for a swallowed window, it can be set in that button's configuration line
using the option "Size \fIwidth height\fP". This will tell FvwmButtons
to give this button at least \fIwidth\fP by \fIheight\fP pixels inside
the relief and padding.
.SH SAMPLE CONFIGURATION
The following are excepts from a .fvwmrc file which describe FvwmButtons
initialization commands:
.nf
.sp
XCOMM#########################################################
XCOMM Load any modules which should be started during fvwm
XCOMM initialization
ModulePath /usr/lib/X11/fvwm:/usr/bin/X11
XCOMM Make sure FvwmButtons is always there.
AddToFunc InitFunction "I" Module FvwmButtons
AddToFunc RestartFunction "I" Module FvwmButtons
XCOMM Make it titlebar-less, sticky, and give it an icon
Style "FvwmButtons" Icon toolbox.xpm, NoTitle, Sticky
XCOMM Make the menu/panel look like CDE
Style "FvwmButtonsPanel" Title, NoHandles, BorderWidth 0
Style "FvwmButtonsPanel" NoButton 2, NoButton 4, Sticky
XCOMM#########################################################
*FvwmButtonsFore Black
*FvwmButtonsBack rgb:90/80/90
*FvwmButtonsGeometry -135-5
*FvwmButtonsRows 1
*FvwmButtonsBoxSize smart
*FvwmButtonsFont -*-helvetica-medium-r-*-*-12-*
*FvwmButtonsPadding 2 2
*FvwmButtons(Title WinOps,Panel WinOps)
*FvwmButtons(Title Tools ,Panel Tools)
*FvwmButtons(Title Resize,Icon resize.xpm ,Action Resize)
*FvwmButtons(Title Move ,Icon arrows2.xpm,Action Move )
*FvwmButtons(Title Lower ,Icon Down ,Action Lower )
*FvwmButtons(Title Raise ,Icon Up ,Action Raise )
*FvwmButtons(Title Kill ,Icon bomb.xpm ,Action Destroy)
*FvwmButtons(1x1,Container(Rows 3,Frame 1))
*FvwmButtons(Title Dopey ,Action \\
`Exec "big_win" xterm -T big_win -geometry 80x50 &`)
*FvwmButtons(Title Snoopy, Font fixed, Action \\
`Exec "small_win" xterm -T small_win &`)
*FvwmButtons(Title Smokin')
*FvwmButtons(End)
*FvwmButtons(Title Xcalc, Icon rcalc.xpm, \\
Action `Exec "Calculator" xcalc &`)
*FvwmButtons(Title XMag, Icon magnifying_glass2.xpm, \\
Action `Exec "xmag" xmag &`)
*FvwmButtons(Title Mail, Icon mail2.xpm, \\
Action `Exec "xmh" xmh &`)
*FvwmButtons(4x1, Swallow "FvwmPager" `FvwmPager 0 3` \\
Frame 3)
*FvwmButtons(Swallow(UseOld,NoKill) "xload15" `Exec xload \\
-title xload15 -nolabel -bg rgb:90/80/90 -update 15 &`)
.sp
.fi
The last lines are a little tricky - one spawns an FvwmPager module, and
captures it to display in a quadruple width button.
is used, the Pager will be as big as possible within the button's relief.
The final line is even more magic. Note the combination of \fIUseOld\fP
and \fINoKill\fP, which will try to swallow an existing window with the
name "xload15" when starting up (if failing: starting one with the
specified command), which is unswallowed when ending FvwmButtons.
The other panels are specified after the root panel:
.nf
.sp
XCOMM######### PANEL
*FvwmButtonsPanel WinOps
*FvwmButtonsBack bisque2
*FvwmButtonsGeometry -3-3
*FvwmButtonsColumns 1
*FvwmButtons(Title Resize,Icon resize.xpm ,Action Resize)
*FvwmButtons(Title Move ,Icon arrows2.xpm,Action Move )
*FvwmButtons(Title Lower ,Icon Down ,Action Lower )
*FvwmButtons(Title Raise ,Icon Up ,Action Raise )
XCOMM######### PANEL
*FvwmButtonsPanel Tools
*FvwmButtonsBack bisque2
*FvwmButtonsGeometry -1-1
*FvwmButtonsColumns 1
*FvwmButtons(Title Kill ,Icon bomb.xpm ,Action Destroy)
.sp
.fi
The color specification \fIrgb:90/80/90\fP is actually the most
correct way of specifying independent colors in X, and should be
used instead of the older \fI#908090\fP. If the latter specification
is used in your configuration file, you should be sure to escape
the hash in any of the \fIcommand\fPs which will be executed, or
fvwm will consider the rest of the line a comment.
Note that with the x/y geometry specs you can easily build button
windows with gaps. Here is another example. You can not accomplish
this without geometry specs for the buttons:
.nf
.sp
XCOMM#########################################################
XCOMM Make it titlebar-less, sticky, and give it an icon
Style "FvwmButtons" Icon toolbox.xpm, NoTitle, Sticky
*FvwmButtonsFont 5x7
*FvwmButtonsBack rgb:90/80/90
*FvwmButtonsFore black
*FvwmButtonsFrame 1
XCOMM 9x11 pixels per button, 4x4 pixels for the frame
*FvwmButtonsGeometry 580x59+0-0
*FvwmButtonsRows 5
*FvwmButtonsColumns 64
*FvwmButtonsBoxSize fixed
*FvwmButtonsPadding 1 1
XCOMM Menu Popups
*FvwmButtons(9x1+3+0, Padding 0, Title "Modules", \\
Action `Menu Modulepopup mouse c -8p Nop`)
XCOMM first row of buttons from left to right:
*FvwmButtons(3x2+0+1, Icon my_lock.xpm, Action `Exec xlock`)
*FvwmButtons(3x2+3+1, Icon my_recapture.xpm, Action Recapture)
*FvwmButtons(3x2+6+1, Icon my_resize.xpm, Action Resize)
*FvwmButtons(3x2+9+1, Icon my_move.xpm, Action Move)
*FvwmButtons(3x2+12+1, Icon my_fvwmconsole.xpm, \\
Action 'Module FvwmConsole')
XCOMM second row of buttons from left to right:
*FvwmButtons(3x2+0+3, Icon my_exit.xpm, Action QuitSave)
*FvwmButtons(3x2+3+3, Icon my_restart.xpm, Action Restart)
*FvwmButtons(3x2+6+3, Icon my_kill.xpm, Action Destroy)
*FvwmButtons(3x2+9+3, Icon my_shell.xpm, Action 'Exec rxvt')
XCOMM big items
*FvwmButtons(10x5, Swallow (NoKill, NoCLose) \\
"FvwmPager" 'FvwmPager * * -geometry 40x40-1024-1024')
*FvwmButtons(6x5, Swallow "FvwmXclock" `Exec xclock \\
-name FvwmXclock -geometry 40x40+0-0 -padding 1 \\
-analog -chime -bg rgb:90/80/90`)
*FvwmButtons(13x5, Left, Swallow (NoClose) \\
"FvwmIconMan" 'Module FvwmIconMan')
*FvwmButtons(20x5, Padding 0, Swallow "xosview" \\
`Exec /usr/X11R6/bin/xosview -cpu -int -page -net \\
-geometry 100x50+0-0 -font 5x7`)
.sp
.fi
.SH BUGS
The action part of the Swallow option must be quoted if it contains
any whitespace character.
.SH COPYRIGHTS
The FvwmButtons program, and the concept for interfacing this module to
the Window Manager, are all original work by Robert Nation
Copyright 1993, Robert Nation. No guarantees or warranties or anything
are provided or implied in any way whatsoever. Use this program at your
own risk. Permission to use this program for any purpose is given,
as long as the copyright is kept intact.
Further modifications and patching by Jarl Totland, copyright 1996.
The statement above still applies.
.SH AUTHOR
Robert Nation.
Somewhat enhanced by Jarl Totland, Jui-Hsuan Joshua Feng and Dominik Vogt.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,191 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
/* -------------------------------- DEBUG ---------------------------------- */
/* Uncomment some of these defines to get (lots of) debug output. If you can't
get it started, DEBUG_LOADDATA and DEBUG_INIT might be handy. The default
DEBUG only generates output on warnings, and adds the functions DumpButtons
and SaveButtons */
#if 0
#define DEBUG
#define DEBUG_LOADDATA /* Get updates on loading */
#define DEBUG_INIT /* Get startup progress */
#define DEBUG_HANGON /* Debug hangon, swallow and unswallow */
/* #define DEBUG_EVENTS */ /* Get much info on events */
#define DEBUG_FVWM /* Debug communciation with fvwm */
/* #define DEBUG_X */
#endif
/* ---------------------------- compatibility ------------------------------ */
#define OLD_EXPOSE /* Try this if resizing/exposes screw up */
/* -------------------------------- more ---------------------------------- */
#include "../../libs/fvwmlib.h"
/* ------------------------------- structs --------------------------------- */
/* flags for b->flags */
#define b_Container 0x00000001 /* Contains several buttons */
#define b_Font 0x00000002 /* Has personal font data */
#define b_Fore 0x00000004 /* Has personal text color */
#define b_Back 0x00000008 /* Has personal background color (or "none")*/
#define b_Padding 0x00000010 /* Has personal padding data */
#define b_Frame 0x00000020 /* Has personal framewidth */
#define b_Title 0x00000040 /* Contains title */
#define b_Icon 0x00000080 /* Contains icon */
#define b_Swallow 0x00000100 /* Contains swallowed window */
#define b_Action 0x00000200 /* Fvwm action when clicked on */
#define b_Hangon 0x00000400 /* Is waiting for a window before turning
* active */
#define b_Justify 0x00000800 /* Has justification info */
#define b_Size 0x00001000 /* Has a minimum size, don't guess */
#define b_IconBack 0x00002000 /* Has an icon as background */
#define b_IconParent 0x00004000 /* Parent button has an icon as background */
#define b_TransBack 0x00008000 /* Transparent background */
#define b_Left 0x00010000 /* Button is left-aligned */
#define b_Right 0x00020000 /* Button is right-aligned */
#define b_SizeFixed 0x00040000 /* User provided rows/columns may not be
* altered */
#define b_PosFixed 0x00080000 /* User provided button position */
#define b_SizeSmart 0x00100000 /* Improved button box sizing */
/* Flags for b->swallow */
#define b_Count 0x03 /* Init counter for swallowing */
#define b_NoHints 0x04 /* Ignore window hints from swallowed window */
#define b_NoClose 0x08 /* Don't close window when exiting, unswallow it */
#define b_Kill 0x10 /* Don't close window when exiting, kill it */
#define b_Respawn 0x20 /* Respawn if swallowed window dies */
#define b_UseOld 0x40 /* Try to capture old window, don't spawn it */
#define b_UseTitle 0x80 /* Allow window to write to b->title */
/* Flags for b->justify */
#define b_TitleHoriz 0x03 /* Mask for title x positioning info */
#define b_Horizontal 0x04 /* HACK: stack title and iconwin horizontally */
typedef struct panel_info_struct panel_info;
typedef struct button_info_struct button_info;
typedef struct container_info_struct container_info;
#define ushort unsigned int
#define byte unsigned char
/* This structure contains data that the parents give their children */
struct container_info_struct
{
button_info **buttons; /* Required fields */
int allocated_buttons;
int num_buttons;
int num_columns;
int num_rows;
int ButtonWidth;
int ButtonHeight;
int xpos,ypos;
unsigned long flags; /* Which data are set in this container? */
byte justify; /* b_Justify */
byte justify_mask; /* b_Justify */
byte swallow; /* b_Swallow */
byte swallow_mask; /* b_Swallow */
byte xpad,ypad; /* b_Padding */
signed char framew; /* b_Frame */
XFontStruct *font; /* b_Font */
char *font_string; /* b_Font */
char *back; /* b_Back && !b_IconBack */
char *back_file; /* b_Back && b_IconBack */
char *fore; /* b_Fore */
Pixel fc; /* b_Fore */
Pixel bc,hc,sc; /* b_Back && !b_IconBack */
FvwmPicture *backicon; /* b_Back && b_IconBack */
ushort minx,miny; /* b_Size */
};
struct button_info_struct
{
/* required fields */
unsigned long flags;
int BPosX,BPosY; /* position in button units from top left */
byte BWidth,BHeight; /* width and height in button units */
button_info *parent;
int n; /* number in parent */
/* conditional fields */ /* applicable if these flags are set */
XFontStruct *font; /* b_Font */
char *font_string; /* b_Font */
char *back; /* b_Back */
char *fore; /* b_Fore */
byte xpad,ypad; /* b_Padding */
signed char framew; /* b_Frame */
byte justify; /* b_Justify */
byte justify_mask; /* b_Justify */
container_info *c; /* b_Container */
char *title; /* b_Title */
char **action; /* b_Action */
char *icon_file; /* b_Icon */
char *hangon; /* b_Hangon || b_Swallow */
Window IconWin; /* b_Icon || b_Swallow */
Pixel fc; /* b_Fore */
Pixel bc,hc,sc; /* b_Back && !b_IconBack */
FvwmPicture *backicon; /* b_Back && b_IconBack */
ushort minx,miny; /* b_Size */
FvwmPicture *icon; /* b_Icon */
byte swallow; /* b_Swallow */
byte swallow_mask; /* b_Swallow */
int icon_w,icon_h; /* b_Swallow */
Window IconWinParent; /* b_Swallow */
XSizeHints *hints; /* b_Swallow && !b_NoHints */
char *spawn; /* b_Swallow */
int x,y; /* b_Swallow */
ushort w,h,bw; /* b_Swallow */
};
struct panel_info_struct
{ button_info *uber; /* panel */
panel_info *next;
};
#include "button.h"
/* -------------------------------- prototypes ----------------------------- */
void AddButtonAction(button_info*,int,char*);
void MakeContainer(button_info*);
#ifdef DEBUG
char *mymalloc(int);
#else
#define mymalloc(a) safemalloc(a)
#endif
/* ----------------------------- global variables -------------------------- */
extern Display *Dpy;
extern Window Root;
extern Window MyWindow;
extern char *MyName;
extern button_info *UberButton,*CurrentButton;
extern panel_info *MainPanel, *CurrentPanel;
extern char *iconPath;
extern char *pixmapPath;
extern int fd[];
extern int screen;
extern int d_depth;
extern int new_desk;
extern GC NormalGC;
extern int x,y,xneg,yneg,w,h; /* Dirty... */
/* ---------------------------------- misc --------------------------------- */

View file

@ -0,0 +1,23 @@
How to install FvwmButtons in the fvwm-2.0.41 tree.
NOTE: If you don't want to overwrite the old FvwmButtons, you should change
all "FvwmButtons" below to some other name like "NewButtons". You should also
edit the last line in the Imakefile to read "FvwmModuleTarget(NewButtons)".
1) Untar the distribution inside fvwm-2.0.41/modules/FvwmButtons
3) In that directory, type
xmkmf; make clean; make install
No need to recompile the whole thing :-) Unless of course you have applied
any of the related patches.
4) Fire up FvwmTalk and try: FvwmButtons SomeName /full/path/to/samplebuttonrc
(or NewButtons if that is what you called it)
This should produce a nice buttonbox on your screen. Try rescaling it a
little, maybe edit the file and experiment.
5) If this did not work, check the error output from fvwm, this might provide
some info on what's wrong. Send the complete output to me if you like.
You can make it produce lot of output by uncommenting some of the DEBUG
defines in FvwmButtons.h.

View file

@ -0,0 +1,12 @@
XCOMM $OpenBSD: Imakefile,v 1.1.1.1 2006/11/26 10:53:45 matthieu Exp $
FVWMTOP=../..
#include "../../Fvwm.tmpl"
SRCS= FvwmButtons.c button.c draw.c icons.c misc.c output.c parse.c
OBJS= FvwmButtons.o button.o draw.o icons.o misc.o output.o parse.o
DEPLIBS= $(FVWMLIB) $(DEPXPMLIB) $(DEPXLIB)
LOCAL_LIBRARIES= $(FVWMLIB) $(XPMLIB) $(XLIB)
FvwmComplexModuleTarget(FvwmButtons)

View file

@ -0,0 +1,14 @@
# $OpenBSD: Makefile,v 1.3 2007/04/09 18:59:57 matthieu Exp $
.include "../Makefile.inc"
.PATH: ${DIST}/modules/FvwmButtons
PROG= FvwmButtons
SRCS= FvwmButtons.c button.c draw.c icons.c misc.c output.c parse.c
LDADD+= -lXpm -lXext ${XLIB}
BINDIR= ${FVWMLIBDIR}
.include <bsd.prog.mk>
.include <bsd.xorg.mk>

View file

@ -0,0 +1,126 @@
FvwmButtons 2.0.41-plural-Z-alpha 28.03.96
-------------------------------------------------------------------------------
This is a much improved version of FvwmButtons, previously known as GoodStuff.
It provides full configuration for each button on colors, sizes, fonts etc,
more control over swallowed windows, support for popup menus and actions bound
to separate mouse buttons. See the home page for illustrative examples.
Check out the FvwmButtons home page:
http://www.fm.unit.no/~jatotal/fvwm.html
Thanks to the folks who tried it out, commented, reported bugs and stuff,
especially those I remembered to write down here at the time, namely:
Brandon M. Browning <brandon@powertie.org>
Rich Derr <rhd@interaccess.com>
Romano Giannetti <romano@iet.unipi.it> Bugslayer
Angiolini Giorgio <angiolin@ic8wd2.settimo.italtel.it>
Albrecht Kadlec <albrecht@auto.tuwien.ac.at>
Dugeon Olivier <dugeon@lannion.cnet.fr>
Olly Stephens <olly@dylan.zycad.com>
HenSiong Tan <tan@stat.psu.edu>
Chris Taylor <shaggy@ctron.com>
Dirk Vangestel <gesteld@sebb.bel.alcatel.be>
Alan Wild <arwild01@scic.intel.com>
Emiel Witteman <ewittema@wi.leidenuniv.nl>
Christopher Wolf <cwolf@micro.ti.com>
Thanks to Rob and Chuck for Fvwm!
Jarl Totland <jatotal@stud.unit.no> (Until summer 96)
<jarl.totland@errors.bbs.no> (Forever, but seldom read)
-------------------------------------------------------------------------------
HACK:
I have tried to keep the code as clean as possible, not introducing features
that would mess things up. There is however one feature which is a hack only,
and will be removed at a later stage when introducing a more general way in
which you can achieve the same effect. That is:
Title (options) garblebrook
The options (Left,Right,Center,Side) will probably all go, but "Side" is a
very lousy solution, not very expandable. But until I have time to think out
a nice and general way to handle real estate inside each button, it will
have to stay to provide the Menu Loop (tm). So there.
SYNTAX:
This is the syntax of the options part of the configuration file, written
out in approximate BNF:
options := option options
| option
option := UNSIGNED 'x' UNSIGNED
| 'Action' aoptions STRING
| 'Back' STRING
| 'Container' coptions
| 'End'
| 'Font' STRING
| 'Fore' STRING
| 'Frame' SIGNED
| 'NoSize'
| 'Panel' poption STRING
| 'Padding' UNSIGNED
| 'Padding' UNSIGNED UNSIGNED
| 'Size' UNSIGNED UNSIGNED
| 'Swallow' sflags STRING STRING
| 'Title' tflags STRING
aoptions := '(' aoptions2 ')'
| NULL
aoptions2 := aoption aoptions2
| aoption
aoption := 'Mouse' UNSIGNED
coptions := '(' coptions2 ')'
| NULL
coptions2 := coption coptions2
| coption
coption := 'Action' aoptions STRING
| 'Back' STRING
| 'Columns' UNSIGNED
| 'Font' STRING
| 'Fore' STRING
| 'Frame' SIGNED
| 'NoSize'
| 'Padding' UNSIGNED
| 'Padding' UNSIGNED UNSIGNED
| 'Size' UNSIGNED UNSIGNED
| 'Swallow' soptions
| 'Title' toptions
poption := '(up)'
| '(left)'
| '(down)'
| '(right)'
| NULL
sflags := '(' sflags2 ')'
| NULL
sflags2 := sflag sflags2
| sflag
sflag := 'Close'
| 'Hints'
| 'Kill'
| 'NoClose'
| 'NoHints'
| 'NoKill'
| 'NoOld'
| 'NoRespawn'
| 'NoTitle'
| 'Respawn'
| 'UseOld'
| 'UseTitle'
tflags := '(' tflags2 ')'
| NULL
tflags2 := tflag tflags2
| tflag
tflag := 'Center'
| 'Left'
| 'Right'
| 'Side'

View file

@ -0,0 +1,130 @@
Things that should be done for the next release:
* Work in progress: free setting of relief and shadow color, getting back
background pixmaps. Optional extra arguments to Frame.. Frame f1 f2 would
be for normal/depressed relief width... Frame f1 f2 f3 f4 could be
normal x/normal y/depressed x/depressed y relief widths...
AND
implement padding _between_ buttons... how? Hmmm.
-> Buttons geometry patch allows this.
* How about being able to put a pixmap to the background of FvwmButtons?
A marble surface would be nice. Shading for frames can be done with
interleaving black or white pixels. This should probably be done anyway...
This can also be used to emulate OpenStep toolbar...
Update: This was done but disappeared in a crash, will be redone when
I have time to do it properly.
Update (Dominik Vogt): at least background pixmaps seem to work (but not
with swallowed apps, only simple buttons.
* Should center icons even when out of space, not use NW gravity.
* Bugfixes? Bugfixes. Bugfixes!?
Things that will be done when I have lots of time:
* There really should be some interactive way to build the buttonbar :-)
Actually, I have it all worked out on paper, but it will not be done
until late april earliest.
Things that should be done to FvwmButtons some day:
* Get events from reparented windows to get actions on swallowed windows.
I tried to do this, but failed. See BUGS. Help me on this, someone!
Am I up to coding this now? Is there any need for it?
* Proper ICCCM compliance: check for WM_DELETE_WINDOW of children to decide
whether to kill or delete... more?
* Make it create hints that only allows it to be scaled to "proper" sizes,
i.e. with all buttons properly sized.
Today it only considers the number of buttons in the UberButton, so if you
make one container outside all your buttons, to give it a frame, it will
give you free resizing. (Only one button, eh?)
* Expand "Mouse" command to differentiate between Click, Move, DoubleClick
etc. Make "Key" command.
* Investigate transparent buttons.
* Make it possible to have buttons that hang until the window they caused
to appear is gone again.
Things that could be done to FvwmButtons:
* Make it possible to have it invisible (unmapped) until the mousepointer
enters a specified InputOnly window on the screen - then it pops up, until
the mousepointer leaves it.
* Allow for linefeeds in titles, maybe have them wordwrap themselves if out
of space. Make it an option: Wrap. Linefeeds could be "\n" inside a string.
Mmm, linefeeds are not really needed. Wordwrap would be nice.
Also: preforming clipping instead of chopping on titles. This would
facilitate handling low roofs too.
* Let containers have titles and icons. This would be awesome! Update: not
really needed, can be done by putting some extra buttons in there...
* Make option for using a limited colormap, say: use 16 colors max
*FvwmButtonsColorMax 16
This should be doable by preparing a dummy colormap to give to xpm.
* Try to find a way to activate Popup menus and Functions. This seems awfully
difficult, as fvwm keeps a tight lid on them. Not possible through the
protocol. Maybe we should cheat and load the config file ourselves?
Update: Popup menus now work courtesy of a simple hack at fvwm. Functions
are harder it seems... at least they didn't work with the same hack.
* Make commands for interactive swallow and unswallow, what about
*FvwmButtons(Title Swallow,Action Swallow)
which could popup a crosshair pointer. Selected window is swallowed.
* On the subject of swallow; is it possible to make it swallow iconified
windows? Could unswallow on deiconify - making FvwmButtons a new IconBox!
:-) But seriously, could be worthwhile. Should be keine problem, just do
whatever the IconBox does.
Swallow(AsIcon) ".." `....`
* Rewrite parser, somewhat lex/yacc style, let it eat the BNF.
There is really no need for this, actually the current parser is tight
and somewhat elegant... Update: Hmm, actually the parser code is huge...
I can't believe how huge it is? 17kb out of 75kb .o file (Solaris 2.2) is
made by the parser... Hmm.
* What about resizing icons on the fly? Buttons with Resize specified can
make icons fill it.
*FvwmButtons(Resize Icon gigantic.xpm)
Should Resize automatically imply NoSize (above)?
* Make it a substitute for xbiff? Let it change state (icons) changeable
on the fly, on the output on a command run? That could be difficult as
they're run through fvwm... What about
*FvwmButtons(Icons nomail.xpm mail.xpm \
Watch 10 "/usr/spool/mail/luser" \
Action "Exec "exmh" (exec exmh)))
with two new things, Icons which takes two icons, one for normal state
and one for excited. This can also be used for normal buttons, when they
hang on something or when they are pressed they could show another icon.
The other new command is Watch, which takes a timeout in seconds and a
filename. When the file grows the button changes state, changing the icon.
How can this be extended to other things than file watching? It can't.
It would be nice to have it run any (shell) command, and change state
according to it's return code or output. This command could ping a host,
check your connection is up, and return errorcodes to FvwmButtons which
gives visual feedback. Or it could work through a pipe, getting fed back
commands that can be actions forwarded to fvwm (Beep, Exec), and other
icons to be shown (Icon mail-from-fvwm-list.xpm).
Pros for having this kind of functionality in FvwmButtons: Do you know
anyone, using FvwmButtons, that doesn't run xbiff equivalents in it?
Cons: it would have to be as functional as most of those, or it wouldn't
be used.
* Add favourite hack here. Make it vt100 compatible, support emacs editing
commands, or able to import Quake .PAKs. Someone probably needs that too.

View file

@ -0,0 +1,727 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/Intrinsic.h>
#include "FvwmButtons.h"
extern char *MyName;
/**
*** buttonInfo()
*** Give lots of info for this button: XPos, YPos, XPad, YPad, Frame(signed)
**/
void buttonInfo(button_info *b,int *x,int *y,int *px,int *py,int *f)
{
ushort w=b_Padding|b_Frame;
*x=buttonXPos(b,b->n);
*y=buttonYPos(b,b->n);
*px=b->xpad;
*py=b->ypad;
*f=b->framew;
w&=~(b->flags&(b_Frame|b_Padding));
if(b->flags&b_Container && w&b_Frame)
{
*f=0;
w&=~b_Frame;
}
if((b->flags&b_Container || b->flags&b_Swallow) && w&b_Padding)
{
*px=*py=0;
w&=~b_Padding;
}
while(w && (b=b->parent))
{
if(w&b_Frame && b->c->flags&b_Frame)
{
*f=b->c->framew;
w&=~b_Frame;
}
if(w&b_Padding && b->c->flags&b_Padding)
{
*px=b->c->xpad;
*py=b->c->ypad;
w&=~b_Padding;
}
}
}
/**
*** GetInternalSize()
**/
void GetInternalSize(button_info *b,int *x,int *y,int *w,int *h)
{
int f;
int px,py;
buttonInfo(b,x,y,&px,&py,&f);
f=abs(f);
*w=buttonWidth(b)-2*(px+f);
*h=buttonHeight(b)-2*(py+f);
*x+=f+px;
*y+=f+py;
if(*w<=1 || *h<=1)
*w=*h=1;
}
/**
*** buttonFrameSigned()
*** Give the signed framewidth for this button.
**/
int buttonFrameSigned(button_info *b)
{
if(b->flags&b_Frame)
return b->framew;
if(b->flags&b_Container) /* Containers usually gets 0 relief */
return 0;
while((b=b->parent))
if(b->c->flags&b_Frame)
return b->c->framew;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No relief width definition?\n",MyName);
#endif
return 0;
}
/**
*** buttonXPad()
*** Give the x padding for this button
**/
int buttonXPad(button_info *b)
{
if(b->flags&b_Padding)
return b->xpad;
if(b->flags&(b_Container|b_Swallow)) /* Normally no padding for these */
return 0;
while((b=b->parent))
if(b->c->flags&b_Padding)
return b->c->xpad;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No padding definition?\n",MyName);
#endif
return 0;
}
/**
*** buttonYPad()
*** Give the y padding for this button
**/
int buttonYPad(button_info *b)
{
if(b->flags&b_Padding)
return b->ypad;
if(b->flags&(b_Container|b_Swallow)) /* Normally no padding for these */
return 0;
while((b=b->parent))
if(b->c->flags&b_Padding)
return b->c->ypad;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No padding definition?\n",MyName);
#endif
return 0;
}
/**
*** buttonFont()
*** Give the font pointer for this button
**/
XFontStruct *buttonFont(button_info *b)
{
if(b->flags&b_Font)
return b->font;
while((b=b->parent))
if(b->c->flags&b_Font)
return b->c->font;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No font definition?\n",MyName);
#endif
return None;
}
/**
*** buttonFore()
*** Give the foreground pixel of this button
**/
Pixel buttonFore(button_info *b)
{
if(b->flags&b_Fore)
return b->fc;
while((b=b->parent))
if(b->c->flags&b_Fore)
return b->c->fc;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No foreground definition?\n",MyName);
#endif
return None;
}
/**
*** buttonBack()
*** Give the background pixel of this button
**/
Pixel buttonBack(button_info *b)
{
if(b->flags&b_Back)
return b->bc;
while((b=b->parent))
if(b->c->flags&b_Back)
return b->c->bc;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No background definition?\n",MyName);
#endif
return None;
}
/**
*** buttonHilite()
*** Give the relief pixel of this button
**/
Pixel buttonHilite(button_info *b)
{
if(b->flags&b_Back)
return b->hc;
while((b=b->parent))
if(b->c->flags&b_Back)
return b->c->hc;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No background definition?\n",MyName);
#endif
return None;
}
/**
*** buttonShadow()
*** Give the shadow pixel of this button
**/
Pixel buttonShadow(button_info *b)
{
if(b->flags&b_Back)
return b->sc;
while((b=b->parent))
if(b->c->flags&b_Back)
return b->c->sc;
#ifdef DEBUG
fprintf(stderr,"%s: BUG: No background definition?\n",MyName);
#endif
return None;
}
/**
*** buttonSwallow()
*** Give the swallowing flags for this button
**/
byte buttonSwallow(button_info *b)
{
byte s=0,t=0;
if(b->flags&b_Swallow)
{
s=b->swallow;
t=b->swallow_mask;
}
while((b=b->parent))
if(b->c->flags&b_Swallow)
{
s&=~(b->c->swallow_mask&~t);
s|=(b->c->swallow&b->c->swallow_mask&~t);
t|=b->c->swallow_mask;
}
return s;
}
/**
*** buttonJustify()
*** Give the justify flags for this button
**/
byte buttonJustify(button_info *b)
{
byte j=1,i=0;
if(b->flags&b_Justify)
{
i=b->justify_mask;
j=b->justify;
}
while((b=b->parent))
if(b->c->flags&b_Justify)
{
j&=~(b->c->justify_mask&~i);
j|=(b->c->justify&b->c->justify_mask&~i);
i|=b->c->justify_mask;
}
return j;
}
/* ---------------------------- button creation ---------------------------- */
/**
*** alloc_buttonlist()
*** Makes sure the list of butten_info's is long enough, if not it reallocates
*** a longer one. This happens in steps of 32. Inital length is 0.
**/
void alloc_buttonlist(button_info *ub,int num)
{
button_info **bb;
int i,old;
if(num>=ub->c->allocated_buttons)
{
old=ub->c->allocated_buttons;
if(num<old || old+32<old)
{
fprintf(stderr,"%s: Too many buttons, integer overflow\n",MyName);
exit(1);
}
while(ub->c->allocated_buttons<=num)
ub->c->allocated_buttons+=32;
bb=(button_info**)
mymalloc(ub->c->allocated_buttons*sizeof(button_info*));
for(i=old;i<ub->c->allocated_buttons;i++)
bb[i]=NULL;
if(ub->c->buttons)
{
for(i=0;i<old;i++) bb[i]=ub->c->buttons[i];
free(ub->c->buttons);
}
ub->c->buttons=bb;
}
}
/**
*** alloc_button()
*** Allocates memory for a new button struct. Calles alloc_buttonlist to
*** assure enough space is present. Also initiates most elements of the struct.
**/
button_info *alloc_button(button_info *ub,int num)
{
button_info *b;
if(num>=ub->c->allocated_buttons)
alloc_buttonlist(ub,num);
if(ub->c->buttons[num])
{
fprintf(stderr,"%s: Allocated button twice, report bug twice\n",MyName);
exit(2);
}
b=(button_info*)mymalloc(sizeof(button_info));
ub->c->buttons[num]=b;
memset((void *)b, 0, sizeof(*b));
b->flags = 0;
b->swallow = 0;
b->BWidth = b->BHeight = 1;
b->BPosX = b->BPosY = 0;
b->parent = ub;
b->n = -1;
b->IconWin = 0;
b->framew = 1;
b->xpad = 2;
b->ypad = 4;
b->w=1;
b->h=1;
b->bw=1;
return(b);
}
/**
*** MakeContainer()
*** Allocs and sets the container-specific fields of a button.
**/
void MakeContainer(button_info *b)
{
b->c=(container_info*)mymalloc(sizeof(container_info));
b->flags|=b_Container;
b->c->buttons=NULL;
b->c->num_buttons=0;
b->c->num_rows=0;
b->c->num_columns=0;
b->c->allocated_buttons=0;
b->c->xpos=0;
b->c->ypos=0;
if(b->parent != NULL)
{
if (b->parent->c->flags&b_IconBack || b->parent->c->flags&b_IconParent)
b->c->flags=b_IconParent;
else
b->c->flags=0;
}
else /* This applies to the UberButton */
{
b->c->flags=b_Font|b_Padding|b_Frame|b_Back|b_Fore;
b->c->font_string=strdup("fixed");
b->c->xpad=2;
b->c->ypad=4;
b->c->back=strdup("#908090");
b->c->fore=strdup("black");
b->c->framew=2;
}
}
/* -------------------------- button administration ------------------------ */
/**
*** NumberButtons()
*** Prepare the n fields in each button
**/
void NumberButtons(button_info *b)
{
int i=-1;
while(++i<b->c->num_buttons)
if(b->c->buttons[i])
{
b->c->buttons[i]->n=i;
if(b->c->buttons[i]->flags&b_Container)
NumberButtons(b->c->buttons[i]);
}
}
/**
*** PlaceAndExpandButton()
*** Places a button in it's container and claims all needed slots.
**/
char PlaceAndExpandButton(int x, int y, button_info *b, button_info *ub)
{
int i,j,k;
container_info *c=ub->c;
i = x+y*c->num_columns;
if (x>=c->num_columns || x<0)
{
fprintf(stderr,"%s: Button out of horizontal range. Quitting.\n",MyName);
fprintf(stderr,"Button=%d num_columns=%d BPosX=%d\n",
i,c->num_columns,b->BPosX);
exit(1);
}
if (y>=c->num_rows || y<0)
{
if (b->flags&b_PosFixed || !(ub->c->flags&b_SizeSmart) || y<0)
{
fprintf(stderr,"%s: Button out of vertical range. Quitting.\n",
MyName);
fprintf(stderr,"Button=%d num_rows=%d BPosY=%d\n",
i,c->num_rows,b->BPosY);
exit(1);
}
c->num_rows=y+b->BHeight;
c->num_buttons=c->num_columns*c->num_rows;
alloc_buttonlist(ub,c->num_buttons);
}
if(x+b->BWidth>c->num_columns)
{
fprintf(stderr,"%s: Button too wide. giving up\n",MyName);
fprintf(stderr,"Button=%d num_columns=%d bwidth=%d w=%d\n",
i,c->num_columns,b->BWidth,x);
b->BWidth = c->num_columns-x;
}
if(y+b->BHeight>c->num_rows)
{
if (c->flags&b_SizeSmart)
{
c->num_rows=y+b->BHeight;
c->num_buttons=c->num_columns*c->num_rows;
alloc_buttonlist(ub,c->num_buttons);
}
else
{
fprintf(stderr,"%s: Button too tall. Giving up\n",MyName);
fprintf(stderr,"Button=%d num_rows=%d bheight=%d h=%d\n",
i,c->num_rows,b->BHeight,y);
b->BHeight = c->num_rows-y;
}
}
/* check if buttons are free */
for(k=0;k<b->BHeight;k++)
for(j=0;j<b->BWidth;j++)
if (c->buttons[i+j+k*c->num_columns])
return 1;
/* claim all buttons */
for(k=0;k<b->BHeight;k++)
for(j=0;j<b->BWidth;j++)
c->buttons[i+j+k*c->num_columns] = b;
b->BPosX = x;
b->BPosY = y;
return 0;
}
/**
*** ShrinkButton()
*** Frees all but the upper left slot a button uses in it's container.
**/
void ShrinkButton(button_info *b, container_info *c)
{
int i,j,k,l;
if (!b)
{
fprintf(stderr,"error: shrink1: button is empty but shouldn't\n");
exit(1);
}
i = b->BPosX+b->BPosY*c->num_columns;
/* free all buttons but the upper left corner */
for(k=0;k<b->BHeight;k++)
for(j=0;j<b->BWidth;j++)
if(j||k)
{
l = i+j+k*c->num_columns;
if (c->buttons[l] != b)
{
fprintf(stderr,"error: shrink2: button was stolen\n");
exit(1);
}
c->buttons[l] = NULL;
}
}
/**
*** ShuffleButtons()
*** Orders and sizes the buttons in the UberButton, corrects num_rows and
*** num_columns in containers.
**/
void ShuffleButtons(button_info *ub)
{
int i,actual_buttons_used;
int next_button_x, next_button_y, num_items;
button_info *b;
button_info **local_buttons;
container_info *c=ub->c;
/* make local copy of buttons in ub */
num_items = c->num_buttons;
local_buttons=(button_info**)mymalloc(sizeof(button_info)*num_items);
for(i=0;i<num_items;i++)
{
local_buttons[i] = c->buttons[i];
c->buttons[i] = NULL;
}
/* Allow for multi-width/height buttons */
actual_buttons_used = 0;
for(i=0;i<num_items;i++)
actual_buttons_used+=local_buttons[i]->BWidth*local_buttons[i]->BHeight;
if (!(c->flags&b_SizeFixed)||!(c->num_rows)||!(c->num_columns))
{
/* Size and create the window */
if(c->num_rows==0 && c->num_columns==0)
c->num_rows=2;
if(c->num_columns==0)
c->num_columns=1+(actual_buttons_used-1)/c->num_rows;
if(c->num_rows==0)
c->num_rows=1+(actual_buttons_used-1)/c->num_columns;
while(c->num_rows * c->num_columns < actual_buttons_used)
c->num_columns++;
if (!(c->flags&b_SizeFixed))
{
while(c->num_rows*c->num_columns >= actual_buttons_used + c->num_columns)
c->num_rows--;
}
}
if (c->flags&b_SizeSmart)
{
/* Set rows/columns to at least the height/width of largest button */
for(i=0;i<num_items;i++)
{
b=local_buttons[i];
if (c->num_rows<b->BHeight) c->num_rows=b->BHeight;
if (c->num_columns<b->BWidth) c->num_columns=b->BWidth;
if (b->flags&b_PosFixed && c->num_columns<b->BWidth+b->BPosX)
c->num_columns=b->BWidth+b->BPosX;
if (b->flags&b_PosFixed && c->num_columns<b->BWidth-b->BPosX)
c->num_columns=b->BWidth-b->BPosX;
if (b->flags&b_PosFixed && c->num_rows<b->BHeight+b->BPosY)
c->num_rows=b->BHeight+b->BPosY;
if (b->flags&b_PosFixed && c->num_rows<b->BHeight-b->BPosY)
c->num_rows=b->BHeight-b->BPosY;
}
}
/* this was buggy before */
c->num_buttons = c->num_rows*c->num_columns;
alloc_buttonlist(ub,c->num_buttons);
/* Shuffle subcontainers */
for(i=0;i<num_items;i++)
{
b=local_buttons[i];
/* Shuffle subcontainers recursively */
if(b && b->flags&b_Container)
ShuffleButtons(b);
}
/* Place fixed buttons as given in BPosX and BPosY */
for(i=0;i<num_items;i++)
{
b=local_buttons[i];
if (!(b->flags&b_PosFixed)) continue;
/* recalculate position for negative offsets */
if (b->BPosX<0) b->BPosX=b->BPosX+c->num_columns-b->BWidth+1;
if (b->BPosY<0) b->BPosY=b->BPosY+c->num_rows-b->BHeight+1;
/* Move button if position given by user */
if (PlaceAndExpandButton(b->BPosX,b->BPosY,b,ub))
{
fprintf(stderr, "%s: Overlapping fixed buttons. Quitting.\n",MyName);
fprintf(stderr, "Button=%d, x=%d, y=%d\n", i,b->BPosX,b->BPosY);
exit(1);
}
}
/* place floating buttons dynamically */
next_button_x = next_button_y = 0;
for(i=0;i<num_items;i++)
{
b=local_buttons[i];
if (b->flags&b_PosFixed) continue;
if (next_button_x+b->BWidth>c->num_columns)
{
next_button_y++;
next_button_x=0;
}
/* Search for next free position to accomodate button */
while (PlaceAndExpandButton(next_button_x,next_button_y,b,ub))
{
next_button_x++;
if (next_button_x+b->BWidth>c->num_columns)
{
next_button_y++;
next_button_x=0;
if (next_button_y>=c->num_rows)
{
/* could not place button */
fprintf(stderr,"%s: Button confusion! Quitting\n", MyName);
exit(1);
}
}
}
}
/* shrink buttons in Container */
for(i=0;i<num_items;i++)
ShrinkButton(local_buttons[i], c);
free(local_buttons);
}
/* ----------------------------- button iterator --------------------------- */
/**
*** NextButton()
*** Iterator to traverse buttontree. Start it with first argument a pointer
*** to the root UberButton, and the index int set to -1. Each subsequent call
*** gives the pointer to uberbutton, button and button index within uberbutton.
*** If all, also returns containers, apart from the UberButton.
**/
button_info *NextButton(button_info **ub,button_info **b,int *i,int all)
{
/* Get next button */
(*i)++;
/* Skip fake buttons */
while((*i)<(*ub)->c->num_buttons && !(*ub)->c->buttons[*i])
(*i)++;
/* End of contained buttons */
if((*i)>=(*ub)->c->num_buttons)
{
*b=*ub;
*ub=(*b)->parent;
/* End of the world as we know it */
if(!(*ub))
{
*b=NULL;
return *b;
}
*i=(*b)->n;
if((*i)>=(*ub)->c->num_buttons)
{
fprintf(stderr,"%s: BUG: Couldn't return to uberbutton\n",MyName);
exit(2);
}
NextButton(ub,b,i,all);
return *b;
}
*b=(*ub)->c->buttons[*i];
/* Found new container */
if((*b)->flags & b_Container)
{
*i=-1;
*ub=*b;
if(!all)
NextButton(ub,b,i,all);
return *b;
}
return *b;
}
/* --------------------------- button navigation --------------------------- */
/**
*** button_belongs_to()
*** Function that finds out which button a given position belongs to.
*** Returns -1 is not part of any, button if a proper button.
**/
int button_belongs_to(button_info *ub,int button)
{
int x,y,xx,yy;
button_info *b;
if(!ub || button<0 || button>ub->c->num_buttons)
return -1;
if(ub->c->buttons[button])
return button;
yy=button/ub->c->num_columns;
xx=button%ub->c->num_columns;
for(y=yy;y>=0;y--)
for(x=xx;x>=0;x--)
{
b=ub->c->buttons[x+y*ub->c->num_columns];
if(b && (x+b->BWidth > xx) && (y+b->BHeight > yy))
{
return x+y*ub->c->num_columns;
}
}
return -1;
}
/**
*** select_button()
*** Given (x,y) and uberbutton, returns pointer to referred button, or NULL
**/
button_info *select_button(button_info *ub,int x,int y)
{
int i;
button_info *b;
if(!(ub->flags&b_Container))
return ub;
x-=buttonXPad(ub)+buttonFrame(ub);
y-=buttonYPad(ub)+buttonFrame(ub);
if(x >= ub->c->ButtonWidth * ub->c->num_columns || x<0 ||
y >= ub->c->ButtonHeight * ub->c->num_rows || y<0)
return ub;
i=x/ub->c->ButtonWidth + (y/ub->c->ButtonHeight)*ub->c->num_columns;
i=button_belongs_to(ub,i);
if(i==-1)return ub;
b=ub->c->buttons[i];
return select_button(b,x-(i%ub->c->num_columns)*ub->c->ButtonWidth,
y-(i/ub->c->num_columns)*ub->c->ButtonHeight);
}

View file

@ -0,0 +1,64 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
/* --------------------------- button information -------------------------- */
#define buttonXPos(b,i) \
((b)->parent->c->xpos + \
((i)%(b)->parent->c->num_columns)*((b)->parent->c->ButtonWidth))
#define buttonYPos(b,i) \
((b)->parent->c->ypos + \
((i)/(b)->parent->c->num_columns)*((b)->parent->c->ButtonHeight))
#define buttonWidth(b) \
((b)->BWidth*(b)->parent->c->ButtonWidth)
#define buttonHeight(b) \
((b)->BHeight*(b)->parent->c->ButtonHeight)
#define buttonSwallowCount(b) \
(((b)->flags&b_Swallow)?((b)->swallow&b_Count):0)
void buttonInfo(button_info*,int *x,int *y,int *padx,int *pady,int *frame);
void GetInternalSize(button_info*,int*,int*,int*,int*);
#define buttonFrame(b) abs(buttonFrameSigned(b))
int buttonFrameSigned(button_info*);
int buttonXPad(button_info*);
int buttonYPad(button_info*);
XFontStruct *buttonFont(button_info*);
Pixel buttonFore(button_info*);
Pixel buttonBack(button_info*);
Pixel buttonHilite(button_info*);
Pixel buttonShadow(button_info*);
byte buttonSwallow(button_info*);
byte buttonJustify(button_info*);
#define buttonNum(b) ((b)->n)
/* ---------------------------- button creation ---------------------------- */
void alloc_buttonlist(button_info*,int);
button_info *alloc_button(button_info*,int);
void MakeContainer(button_info*);
/* ------------------------- button administration ------------------------- */
void NumberButtons(button_info*);
void ShuffleButtons(button_info*);
/* ---------------------------- button iterator ---------------------------- */
button_info *NextButton(button_info**,button_info**,int*,int);
/* --------------------------- button navigation --------------------------- */
int button_belongs_to(button_info*,int);
button_info *select_button(button_info*,int,int);

View file

@ -0,0 +1,340 @@
/*
Fvwmbuttons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
/* ------------------------------- includes -------------------------------- */
#include "config.h"
#ifdef HAVE_SYS_BSDTYPES_H
#include <sys/bsdtypes.h> /* Saul */
#endif
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include "FvwmButtons.h"
#include "misc.h" /* ConstrainSize() */
#include "icons.h" /* ConfigureIconWindow() */
#include "button.h"
#include "draw.h"
/* ---------------- Functions that design and draw buttons ----------------- */
/**
*** RelieveWindow()
*** Draws the relief pattern around a window.
**/
void RelieveWindow(Window wn,int width,int x,int y,int w,int h,Pixel relief,
Pixel shadow,int rev)
{
XSegment seg[4];
unsigned long gcm=0;
XGCValues gcv;
Pixel p;
int i,j;
if(!width)
return;
if(width<0)
{
width=-width;
p=relief;relief=shadow;shadow=p;
}
if(rev)
{
p=relief;relief=shadow;shadow=p;
}
gcm=GCForeground;
gcv.foreground=relief;
XChangeGC(Dpy,NormalGC,gcm,&gcv);
for(j=0;j<width && w>1 && h>1 ;j++,w-=2,h-=2,x+=1,y+=1)
{
i=0;
seg[i].x1 = x; seg[i].y1 = y;
seg[i].x2 = x+w-1; seg[i++].y2 = y;
seg[i].x1 = x; seg[i].y1 = y;
seg[i].x2 = x; seg[i++].y2 = y+h-1;
XDrawSegments(Dpy,wn,NormalGC,seg,i);
}
w+=width*2;h+=width*2;x-=width;y-=width;
gcm=GCForeground;
gcv.foreground=shadow;
XChangeGC(Dpy,NormalGC,gcm,&gcv);
for(j=0;j<width && w>1 && h>1 ;j++,w-=2,h-=2,x+=1,y+=1)
{
i=0;
seg[i].x1 = x+1; seg[i].y1 = y+h-1;
seg[i].x2 = x+w-1; seg[i++].y2 = y+h-1;
seg[i].x1 = x+w-1; seg[i].y1 = y+1;
seg[i].x2 = x+w-1; seg[i++].y2 = y+h-1;
XDrawSegments(Dpy,wn,NormalGC,seg,i);
}
}
/**
*** MakeButton()
*** To position subwindows in a button: icons and swallowed windows.
**/
void MakeButton(button_info *b)
{
/* This is resposible for drawing the contents of a button, placing the
icon and/or swallowed item in the correct position inside potential
padding or frame.
*/
int ih,iw,ix,iy;
XFontStruct *font;
if(!b)
{
fprintf(stderr,"%s: BUG: DrawButton called with NULL pointer\n",MyName);
exit(2);
}
if(b->flags&b_Container)
{
fprintf(stderr,"%s: BUG: DrawButton called with container\n",MyName);
exit(2);
}
if(!(b->flags&b_Icon) && (buttonSwallowCount(b)<3))
return;
/* Check if parent container has an icon as background */
if (b->parent->c->flags&b_IconBack || b->parent->c->flags&b_IconParent)
b->flags|=b_IconParent;
font = buttonFont(b);
GetInternalSize(b,&ix,&iy,&iw,&ih);
/* At this point iw,ih,ix and iy should be correct. Now all we have to do is
place title and iconwin in their proper positions */
/* For now, use the old routine in icons.h for buttons with icons */
if(b->flags&b_Icon)
ConfigureIconWindow(b);
/* For now, hardcoded window centered, title bottom centered, below window */
else if(buttonSwallowCount(b)==3)
{
long supplied;
if(!b->IconWin)
{
fprintf(stderr,"%s: BUG: Swallowed window has no IconWin\n",MyName);
exit(2);
}
if(b->flags&b_Title && font && !(buttonJustify(b)&b_Horizontal))
ih -= font->ascent+font->descent;
b->icon_w=iw;
b->icon_h=ih;
if(iw>0 && ih>0)
{
if(!(buttonSwallow(b)&b_NoHints))
{
if(!XGetWMNormalHints(Dpy,b->IconWin,b->hints,&supplied))
b->hints->flags=0;
ConstrainSize(b->hints,&b->icon_w,&b->icon_h);
}
if (b->flags & b_Right)
ix += iw-b->icon_w;
else if (!(b->flags & b_Left))
ix += (iw-b->icon_w)/2;
XMoveResizeWindow(Dpy,b->IconWin,ix,iy+(ih-b->icon_h)/2,
b->icon_w,b->icon_h);
}
else
XMoveWindow(Dpy,b->IconWin,2000,2000);
}
}
/**
*** RedrawButton()
*** Writes out title, if any, and displays the bevel right, by calling
*** RelieveWindow. If clean is nonzero, also clears background.
**/
void RedrawButton(button_info *b,int clean)
{
int i,j,k,BH,BW;
int f,x,y,px,py;
int ix,iy,iw,ih;
XFontStruct *font=buttonFont(b);
XGCValues gcv;
unsigned long gcm=0;
int rev=0;
BW = buttonWidth(b);
BH = buttonHeight(b);
buttonInfo(b,&x,&y,&px,&py,&f);
GetInternalSize(b,&ix,&iy,&iw,&ih);
/* This probably isn't the place for this, but it seems to work here and not
elsewhere, so... */
if((buttonSwallowCount(b)==3) && b->IconWin!=None)
XSetWindowBorderWidth(Dpy,b->IconWin,0);
/* ----------------------------------------------------------------------- */
if(b->flags&b_Hangon || b==CurrentButton) /* Hanging or held down by user */
rev=1;
if(b->flags&b_Action) /* If this is a Desk button that takes you to here.. */
{
int n=0;
while(n<4 && (!b->action[n] || strncasecmp(b->action[n],"Desk",4)))
n++;
if(n<4)
{
k=sscanf(&b->action[n][4],"%d%d",&i,&j);
if(k==2 && i==0 && j==new_desk)
rev=1;
}
}
RelieveWindow(MyWindow,f,x,y,BW,BH,buttonHilite(b),buttonShadow(b),rev);
/* ----------------------------------------------------------------------- */
f=abs(f);
if(clean && BW>2*f && BH>2*f)
{
gcm = GCForeground;
gcv.foreground=buttonBack(b);
XChangeGC(Dpy,NormalGC,gcm,&gcv);
if(b->flags&b_Container)
{
int x1=x+f,y1=y+f;
int w1=px,h1=py,w2=w1,h2=h1;
int w=BW-2*f,h=BH-2*f;
w2+=iw - b->c->num_columns*b->c->ButtonWidth;
h2+=ih - b->c->num_rows*b->c->ButtonHeight;
if(w1)XFillRectangle(Dpy,MyWindow,NormalGC,x1,y1,w1,h);
if(w2)XFillRectangle(Dpy,MyWindow,NormalGC,x1+w-w2,y1,w2,h);
if(h1)XFillRectangle(Dpy,MyWindow,NormalGC,x1,y1,w,h1);
if(h2)XFillRectangle(Dpy,MyWindow,NormalGC,x1,y1+h-h2,w,h2);
}
else if(!(b->flags&b_IconBack) && !(b->flags&b_IconParent) &&
!(b->flags&b_Swallow))
XFillRectangle(Dpy,MyWindow,NormalGC,x+f,y+f,BW-2*f,BH-2*f);
}
/* ----------------------------------------------------------------------- */
if(b->flags&b_Title && font)
{
gcm = GCForeground | GCFont;
gcv.foreground=buttonFore(b);
gcv.font = font->fid;
XChangeGC(Dpy,NormalGC,gcm,&gcv);
DrawTitle(b,MyWindow,NormalGC);
}
}
/**
*** DrawTitle()
*** Writes out title.
**/
void DrawTitle(button_info *b,Window win,GC gc)
{
int BH;
int ix,iy,iw,ih;
XFontStruct *font=buttonFont(b);
int justify=buttonJustify(b);
int l,i,xpos;
char *s;
int just=justify&b_TitleHoriz; /* Left, center, right */
BH = buttonHeight(b);
GetInternalSize(b,&ix,&iy,&iw,&ih);
/* ----------------------------------------------------------------------- */
if(!(b->flags&b_Title) || !font)
return;
/* If a title is to be shown, truncate it until it fits */
if(justify&b_Horizontal)
{
if(b->flags&b_Icon)
{
ix+=b->icon->width+buttonXPad(b);
iw-=b->icon->width+buttonXPad(b);
}
else if (buttonSwallowCount(b)==3)
{
ix+=b->icon_w+buttonXPad(b);
iw-=b->icon_w+buttonXPad(b);
}
}
s=b->title;
l=strlen(s);
i=XTextWidth(font,s,l);
if(i>iw)
{
if(just==2)
{
while(i>iw && *s)
i=XTextWidth(font,++s,--l);
}
else /* Left or center - cut off its tail */
{
while(i>iw && l>0)
i=XTextWidth(font,s,--l);
}
}
if(just==0) /* Left */
xpos=ix;
else if(just==2) /* Right */
xpos=max(ix,ix+iw-i);
else /* Centered, I guess */
xpos=ix+(iw-i)/2;
if(*s && l>0 && BH>=font->descent+font->ascent) /* Clip it somehow? */
{
/* If there is more than the title, put it at the bottom */
/* Unless stack flag is set, put it to the right of icon */
if((b->flags&b_Icon || (buttonSwallowCount(b)==3)) &&
!(justify&b_Horizontal))
{
XDrawString(Dpy,win,gc,xpos,
iy+ih-font->descent,s,l);
/* Shrink the space available for icon/window */
ih-=font->descent+font->ascent;
}
/* Or else center vertically */
else
{
XDrawString(Dpy,win,gc,xpos,
iy+(ih+font->ascent-font->descent)/2,s,l);
}
}
}

View file

@ -0,0 +1,19 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
void RelieveWindow(Window,int,int,int,int,int,Pixel,Pixel,int);
void MakeButton(button_info*);
void RedrawButton(button_info*,int);
void DrawTitle(button_info*,Window,GC);

View file

@ -0,0 +1,209 @@
/*
Fvwmbuttons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
/***********************************************************************
*
* Derived from fvwm icon code
*
***********************************************************************/
#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xproto.h>
#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "../../libs/fvwmlib.h"
#include "FvwmButtons.h"
#ifdef XPM
#include <X11/xpm.h>
#endif /* XPM */
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif /* SHAPE */
/****************************************************************************
*
* Creates an Icon Window
*
****************************************************************************/
void CreateIconWindow(button_info *b)
{
#ifndef NO_ICONS
unsigned long valuemask; /* mask for create windows */
XSetWindowAttributes attributes; /* attributes for create windows */
if(!(b->flags&b_Icon))
return;
if(b->IconWin != None)
{
fprintf(stderr,"%s: BUG: Iconwindow already created for 0x%lx!\n",
MyName,(unsigned long)b);
exit(2);
}
attributes.background_pixel = buttonBack(b);
attributes.event_mask = ExposureMask;
valuemask = CWEventMask | CWBackPixel;
if(b->icon->width<1 || b->icon->height<1)
{
fprintf(stderr,"%s: BUG: Illegal iconwindow tried created\n",MyName);
exit(2);
}
b->IconWin=XCreateWindow(Dpy,MyWindow,0,0,b->icon->width,b->icon->height,
0, CopyFromParent, CopyFromParent,CopyFromParent,
valuemask,&attributes);
#ifdef XPM
#ifdef SHAPE
if (b->icon->mask!=None)
XShapeCombineMask(Dpy,b->IconWin,ShapeBounding,0,0,
b->icon->mask,ShapeSet);
#endif
#endif
if(b->icon->depth==0)
{
XGCValues gcv;
unsigned long gcm=0;
Pixmap temp;
gcm = GCForeground | GCBackground;
gcv.background=buttonBack(b);
gcv.foreground=buttonFore(b);
XChangeGC(Dpy,NormalGC,gcm,&gcv);
#ifdef SHAPE
XShapeCombineMask(Dpy,b->IconWin,ShapeBounding,0,0,
b->icon->picture,ShapeSet);
#endif
temp = XCreatePixmap(Dpy,Root,b->icon->width,
b->icon->height,d_depth);
XCopyPlane(Dpy,b->icon->picture,temp,NormalGC,
0,0,b->icon->width,b->icon->height,0,0,1);
XSetWindowBackgroundPixmap(Dpy,b->IconWin,temp);
XFreePixmap(Dpy,temp);
/* We won't use the icon pixmap anymore... but we still need it for
width/height etc. so we can't destroy it. */
}
else
XSetWindowBackgroundPixmap(Dpy,b->IconWin,b->icon->picture);
return;
#endif
}
/****************************************************************************
*
* Combines icon shape masks after a resize
*
****************************************************************************/
void ConfigureIconWindow(button_info *b)
{
#ifndef NO_ICONS
int x,y,w,h;
int xoff,yoff;
int framew,xpad,ypad;
XFontStruct *font;
int BW,BH;
if(!b || !(b->flags&b_Icon))
return;
if(!b->IconWin)
{
fprintf(stderr,"%s: DEBUG: Tried to configure erroneous iconwindow\n",
MyName);
exit(2);
}
buttonInfo(b,&x,&y,&xpad,&ypad,&framew);
framew=abs(framew);
font = buttonFont(b);
w = b->icon->width;
h = b->icon->height;
BW = buttonWidth(b);
BH = buttonHeight(b);
w=min(w,BW-2*(xpad+framew));
if(b->flags&b_Title && font && !(buttonJustify(b)&b_Horizontal))
h=min(h,BH-2*(ypad+framew)-font->ascent-font->descent);
else
h=min(h,BH-2*(ypad+framew));
if(w < 1 || h < 1)
{
XMoveResizeWindow(Dpy, b->IconWin, 2000,2000,1,1);
return; /* No need drawing to this */
}
if(buttonJustify(b)&b_Horizontal)
xoff=0;
else
xoff=(BW-w)>>1;
if(b->flags&b_Title && font && !(buttonJustify(b)&b_Horizontal))
yoff=(BH-(h+font->ascent+font->descent))>>1;
else
yoff=(BH-h)>>1;
if(xoff < framew+xpad)
xoff = framew+xpad;
if(yoff < framew+ypad)
yoff = framew+ypad;
x += xoff;
y += yoff;
XMoveResizeWindow(Dpy, b->IconWin, x,y,w,h);
/* Doesn't this belong above?
#ifdef XPM
#ifdef SHAPE
if (b->icon->mask!=None)
{
XShapeCombineMask(Dpy,b->IconWin,ShapeBounding,0,0,
b->icon->mask,ShapeSet);
}
#endif
#endif
if(b->icon->depth==0)
{
PixmapFromBitmap(b);
}
XSetWindowBackgroundPixmap(Dpy,b->IconWin,b->icon->picture);
*/
#endif
}

View file

@ -0,0 +1,20 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
/* ------------------------------ prototypes ------------------------------- */
#if 0
void LoadIconFile(button_info*);
#endif
void CreateIconWindow(button_info*);
void ConfigureIconWindow(button_info*);

View file

@ -0,0 +1,161 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
#include "misc.h"
/**
*** ConstrainSize()
*** Adjust a given width and height to account for the constraints imposed by
*** size hints.
*** The general algorithm, especially the aspect ratio stuff, is borrowed from
*** uwm's CheckConsistency routine.
**/
void ConstrainSize (XSizeHints *hints, int *widthp, int *heightp)
{
#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
int baseWidth, baseHeight;
int dwidth = *widthp, dheight = *heightp;
if(hints->flags & PMinSize)
{
minWidth = hints->min_width;
minHeight = hints->min_height;
if(hints->flags & PBaseSize)
{
baseWidth = hints->base_width;
baseHeight = hints->base_height;
}
else
{
baseWidth = hints->min_width;
baseHeight = hints->min_height;
}
}
else if(hints->flags & PBaseSize)
{
minWidth = hints->base_width;
minHeight = hints->base_height;
baseWidth = hints->base_width;
baseHeight = hints->base_height;
}
else
{
minWidth = 1;
minHeight = 1;
baseWidth = 1;
baseHeight = 1;
}
if(hints->flags & PMaxSize)
{
maxWidth = hints->max_width;
maxHeight = hints->max_height;
}
else
{
maxWidth = 10000;
maxHeight = 10000;
}
if(hints->flags & PResizeInc)
{
xinc = hints->width_inc;
yinc = hints->height_inc;
}
else
{
xinc = 1;
yinc = 1;
}
/*
* First, clamp to min and max values
*/
if (dwidth < minWidth) dwidth = minWidth;
if (dheight < minHeight) dheight = minHeight;
if (dwidth > maxWidth) dwidth = maxWidth;
if (dheight > maxHeight) dheight = maxHeight;
/*
* Second, fit to base + N * inc
*/
dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
/*
* Third, adjust for aspect ratio
*/
#define maxAspectX hints->max_aspect.x
#define maxAspectY hints->max_aspect.y
#define minAspectX hints->min_aspect.x
#define minAspectY hints->min_aspect.y
/*
* The math looks like this:
*
* minAspectX dwidth maxAspectX
* ---------- <= ------- <= ----------
* minAspectY dheight maxAspectY
*
* If that is multiplied out, then the width and height are
* invalid in the following situations:
*
* minAspectX * dheight > minAspectY * dwidth
* maxAspectX * dheight < maxAspectY * dwidth
*
*/
if (hints->flags & PAspect)
{
if (minAspectX * dheight > minAspectY * dwidth)
{
delta = makemult(minAspectX * dheight / minAspectY - dwidth,
xinc);
if (dwidth + delta <= maxWidth)
dwidth += delta;
else
{
delta = makemult(dheight - dwidth*minAspectY/minAspectX,
yinc);
if (dheight - delta >= minHeight) dheight -= delta;
}
}
if (maxAspectX * dheight < maxAspectY * dwidth)
{
delta = makemult(dwidth * maxAspectY / maxAspectX - dheight,
yinc);
if (dheight + delta <= maxHeight)
dheight += delta;
else
{
delta = makemult(dwidth - maxAspectX*dheight/maxAspectY,
xinc);
if (dwidth - delta >= minWidth) dwidth -= delta;
}
}
}
*widthp = dwidth;
*heightp = dheight;
return;
#undef makemult
#undef maxAspectX
#undef maxAspectY
#undef minAspectX
#undef minAspectY
}

View file

@ -0,0 +1,18 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
void ConstrainSize (XSizeHints *hints, int *widthp, int *heightp);

View file

@ -0,0 +1,279 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/Intrinsic.h>
#include "FvwmButtons.h"
/**
*** DumpButtons()
*** Debug function. May only be called after ShuffleButtons has been called.
**/
void DumpButtons(button_info *b)
{
if(!b)
{
fprintf(stderr,"NULL\n");
return;
}
if(b!=UberButton)
{
int button=buttonNum(b);
fprintf(stderr,"0x%lx(%ix%i@(%i,%i),0x%04lx): ",
(unsigned long)b,b->BWidth,b->BHeight,
buttonXPos(b,button),buttonYPos(b,button),b->flags);
}
else
fprintf(stderr,"0x%lx(%ix%i@,0x%04lx): ",(unsigned long)b,
b->BWidth,b->BHeight,b->flags);
if(b->flags&b_Font)
fprintf(stderr,"Font(%s,0x%lx) ",b->font_string,(unsigned long)b->font);
if(b->flags&b_Padding)
fprintf(stderr,"Padding(%i,%i) ",b->xpad,b->ypad);
if(b->flags&b_Frame)
fprintf(stderr,"Framew(%i) ",b->framew);
if(b->flags&b_Title)
fprintf(stderr,"Title(%s) ",b->title);
if(b->flags&b_Icon)
fprintf(stderr,"Icon(%s,%i) ",b->icon_file,(int)b->IconWin);
if(b->flags&b_Action)
fprintf(stderr,"\n Action(%s,%s,%s,%s) ",
b->action[0]?b->action[0]:"",
b->action[1]?b->action[1]:"",
b->action[2]?b->action[2]:"",
b->action[3]?b->action[3]:"");
if(b->flags&b_Swallow)
{
fprintf(stderr,"Swallow(0x%02x) ",b->swallow);
if(b->swallow&b_Respawn)
fprintf(stderr,"\n Respawn(%s) ",b->spawn);
}
if(b->flags&b_Hangon)
fprintf(stderr,"Hangon(%s) ",b->hangon);
fprintf(stderr,"\n");
if(b->flags&b_Container)
{
int i=0;
fprintf(stderr," Container(%ix%i=%i buttons 0x%04lx (alloc %i), size %ix%i, pos %i,%i)\n{ ",
b->c->num_columns,b->c->num_rows,b->c->num_buttons,b->c->flags,
b->c->allocated_buttons,
b->c->ButtonWidth,b->c->ButtonHeight,b->c->xpos,b->c->ypos);
/*
fprintf(stderr," font(%s,%i) framew(%i) pad(%i,%i) { ",
b->c->font_string,(int)b->c->font,b->c->framew,b->c->xpad,
b->c->ypad);
*/
while(i<b->c->num_buttons)
fprintf(stderr,"0x%lx ",(unsigned long)b->c->buttons[i++]);
fprintf(stderr,"}\n");
i=0;
while(i<b->c->num_buttons)
DumpButtons(b->c->buttons[i++]);
return;
}
}
void SaveButtons(button_info *b)
{
int i;
if(!b)
return;
if(b->BWidth>1 || b->BHeight>1)
fprintf(stderr,"%ix%i ",b->BWidth,b->BHeight);
if(b->flags&b_Font)
fprintf(stderr,"Font %s ",b->font_string);
if(b->flags&b_Fore)
fprintf(stderr,"Fore %s ",b->fore);
if(b->flags&b_Back)
fprintf(stderr,"Back %s ",b->back);
if(b->flags&b_Frame)
fprintf(stderr,"Frame %i ",b->framew);
if(b->flags&b_Padding)
fprintf(stderr,"Padding %i %i ",b->xpad,b->ypad);
if(b->flags&b_Title)
{
fprintf(stderr,"Title ");
if(b->flags&b_Justify)
{
fprintf(stderr,"(");
switch(b->justify&b_TitleHoriz)
{
case 0:
fprintf(stderr,"Left");
break;
case 1:
fprintf(stderr,"Center");
break;
case 2:
fprintf(stderr,"Right");
break;
}
if(b->justify&b_Horizontal)
fprintf(stderr,", Side");
fprintf(stderr,") ");
}
fprintf(stderr,"\"%s\" ",b->title);
}
if(b->flags&b_Icon)
fprintf(stderr,"Icon \"%s\" ",b->icon_file);
if(b->flags&b_Swallow)
{
fprintf(stderr,"Swallow ");
if(b->swallow_mask)
{
fprintf(stderr,"(");
if(b->swallow_mask&b_NoHints) {
if(b->swallow&b_NoHints)
fprintf(stderr,"NoHints ");
else
fprintf(stderr,"Hints ");
}
if(b->swallow_mask&b_Kill) {
if(b->swallow&b_Kill)
fprintf(stderr,"Kill ");
else
fprintf(stderr,"NoKill ");
}
if(b->swallow_mask&b_NoClose) {
if(b->swallow&b_NoClose)
fprintf(stderr,"NoClose ");
else
fprintf(stderr,"Close ");
}
if(b->swallow_mask&b_Respawn) {
if(b->swallow&b_Respawn)
fprintf(stderr,"Respawn ");
else
fprintf(stderr,"NoRespawn ");
}
if(b->swallow_mask&b_UseOld) {
if(b->swallow&b_UseOld)
fprintf(stderr,"UseOld ");
else
fprintf(stderr,"NoOld ");
}
if(b->swallow_mask&b_UseTitle) {
if(b->swallow&b_UseTitle)
fprintf(stderr,"UseTitle ");
else
fprintf(stderr,"NoTitle ");
}
fprintf(stderr,") ");
}
fprintf(stderr,"\"%s\" \"%s\" ",b->hangon,b->spawn);
}
if(b->flags&b_Action)
{
if(b->action[0])
fprintf(stderr,"Action `%s` ",b->action[0]);
for(i=1;i<4;i++)
if(b->action[i])
fprintf(stderr,"Action (Mouse %i) `%s` ",i,b->action[i]);
}
if(b->flags&b_Container)
{
fprintf(stderr,"Container (Columns %i Rows %i ",b->c->num_columns,
b->c->num_rows);
if(b->c->flags)
{
if(b->c->flags&b_Font)
fprintf(stderr,"Font %s ",b->c->font_string);
if(b->c->flags&b_Fore)
fprintf(stderr,"Fore %s ",b->c->fore);
if(b->c->flags&b_Back)
fprintf(stderr,"Back %s ",b->c->back);
if(b->c->flags&b_Frame)
fprintf(stderr,"Frame %i ",b->c->framew);
if(b->c->flags&b_Padding)
fprintf(stderr,"Padding %i %i ",b->c->xpad,b->c->ypad);
if(b->c->flags&b_Justify)
{
fprintf(stderr,"Title (");
switch(b->c->justify&b_TitleHoriz)
{
case 0:
fprintf(stderr,"Left");
break;
case 1:
fprintf(stderr,"Center");
break;
case 2:
fprintf(stderr,"Right");
break;
}
if(b->c->justify&b_Horizontal)
fprintf(stderr,", Side");
fprintf(stderr,") ");
}
if(b->c->swallow_mask)
{
fprintf(stderr,"Swallow (");
if(b->c->swallow_mask&b_NoHints) {
if(b->c->swallow&b_NoHints)
fprintf(stderr,"NoHints ");
else
fprintf(stderr,"Hints ");
}
if(b->c->swallow_mask&b_Kill) {
if(b->c->swallow&b_Kill)
fprintf(stderr,"Kill ");
else
fprintf(stderr,"NoKill ");
}
if(b->c->swallow_mask&b_NoClose) {
if(b->c->swallow&b_NoClose)
fprintf(stderr,"NoClose ");
else
fprintf(stderr,"Close ");
}
if(b->c->swallow_mask&b_Respawn) {
if(b->c->swallow&b_Respawn)
fprintf(stderr,"Respawn ");
else
fprintf(stderr,"NoRespawn ");
}
if(b->c->swallow_mask&b_UseOld) {
if(b->c->swallow&b_UseOld)
fprintf(stderr,"UseOld ");
else
fprintf(stderr,"NoOld ");
}
if(b->c->swallow_mask&b_UseTitle) {
if(b->c->swallow&b_UseTitle)
fprintf(stderr,"UseTitle ");
else
fprintf(stderr,"NoTitle ");
}
fprintf(stderr,") ");
}
}
fprintf(stderr,")");
}
fprintf(stderr,"\n");
if(b->flags&b_Container)
{
i=0;
while(i<b->c->num_buttons)
SaveButtons(b->c->buttons[i++]);
fprintf(stderr,"End\n");
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
/*
FvwmButtons v2.0.41-plural-Z-alpha, copyright 1996, Jarl Totland
* This module, and the entire GoodStuff program, and the concept for
* interfacing this module to the Window Manager, are all original work
* by Robert Nation
*
* Copyright 1993, Robert Nation. No guarantees or warantees or anything
* are provided or implied in any way whatsoever. Use this program at your
* own risk. Permission to use this program for any purpose is given,
* as long as the copyright is kept intact.
*/
void ParseOptions(button_info*);

View file

@ -0,0 +1,18 @@
Back bisque3
(Frame 2 Padding 2 2 Container(Rows 2 Frame 1 Padding 10 0 Swallow(Respawn)))
(NoSize Title Close, Icon bomb.xpm, Action Close)
(Title Resize Back bisque4 Action Resize)
(Frame 2 Padding 2 2 NoSize Container(Back red Title(left,side) Fore yellow \
Columns 1 Padding 4 2 Frame 2 Font -*-helvetica-*-r-*-*-14-*))
(Icon jball.xpm Title Dump Action DumpButtons)
(Icon jball.xpm Title Save Action SaveButtons)
(End)
(3x1 Back darkolivegreen Fore white Frame 2 Padding 2 2 \
Container(Rows 1 Frame -2 Padding 1 1 Back darkolivegreen))
(Swallow(Respawn NoHints) xclock \
`Exec exec xclock -bg darkolivegreen -padding 0 -geometry +2000-0`)
(2x1 Title(Side,Right) Mail Fore white Swallow(NoClose,UseOld,NoRespawn,\
NoHints) xbiff `Exec exec xbiff -bg darkolivegreen -geometry +200+200`)
(Action Beep Title Beep Icon Down Fore yellow Frame 2 Back seagreen)
(End)
(End)