1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 20:10:29 +01:00

Initial revision

This commit is contained in:
scottc
1998-09-29 22:36:29 +00:00
commit 9d2e6ef9f1
527 changed files with 138651 additions and 0 deletions

177
AUTHORS Normal file
View File

@@ -0,0 +1,177 @@
Information about locale translators is at src/po/README and
Library/WindowMaker/README
Many thanks to the following people who have contributed
patches, bug fixes and other stuff for WindowMaker:
ABE Shige <sabe@ibm.net>
I18N support, diagonal and vertical gradient, cosmetic additions to
move/resize frames, window list menu, side swapping and other things for dock,
japanese local, icon arrangement fix, remember current workspace after
restart, dock bug fixes
Andrea Arcangeli <arcangeli@mbox.queen.it>
Fix for cascade window placement
Peter Bentley <peter.bentley@nomura.co.uk>
fixed WM_STATE handling bug, fixed some memory leaks, made application menus
be mapped near the windows for non-click-to-focus modes.
Ulf Betlehem <flu@iki.fi>
Window resize with Meta-Click3, fixed OpaqueMove to send only 1 synth.
ConfigureNotify
Olly Betts <olly@muscat.co.uk>
shaded window indication in window list
Rob Clark <rclark@turing.cs.hmc.edu>
Text input field, 15bpp support
Sylvain CORRE <sylvain.corre@wanadoo.fr>
bug fix for MkLinux/PPC, bug fix for cpixmap in wmsetbg
Frederic Devernay <devernay@istar.fr>
dock fix for openwindows, made asclock be friendlier with colorcell impaired
dpys, fixed wrlib to work with most visual/depth combinations, many
miscellaneous bug fixes
Adrian Drzewiecki <fsawd@aurora.alaska.edu>
opaque window move
Bjoern Giesler <giesler@ira.uka.de>
Dynamic reconfiguration, libPropList
Oliver Graf <ograf@fga.de>
more configure.in fixes
Chris Green <grapeape@uab.edu>
FAQ author/maintainer
Nicolai P Guba <nicolai@gnu.ai.mit.edu>
Documentation help, autoconf cleanup
Mark 'segfault' Guzman <root@lsd.pbx.org>
Various bugfixes
Ullrich Hafner <hafner@informatik.uni-wuerzburg.de>
Better detection of gfx libraries
Greg Hayes <sdc@choice.net>
Twisted miniaturization animation
HIDEKI Fujimoto <hideki70@osk2.threewebnet.or.jp>
FreeBSD portability, icon arrangement fixes, dock initialization bug fix,
some I18N related fixes
Robert A. Holak <panthar@tradeservices.com>
bug fix
IKARASHI Akira <ikarashi@itlb.te.noda.sut.ac.jp>
Workspace change bug fix
Sudish Joseph <sj@eng.mindspring.net>
Modifier binding fix and other bug fixes
Bradley M Keryan <keryan@andrew.cmu.edu>
EMACS/keypad like cursor movement for WINGs textfield
Jim Knoble <jmknoble@pobox.com>
made autoarrange icons a runtime option, SHADOW_RESIZEBAR c-time option,
no workspace switch to the same workspace, dashed icon selection,
misclellaneous bug fixes
Alfredo K. Kojima <kojima@inf.ufrgs.br>
Project maintainer
Jay Kominek <jkominek@xtn.net>
smart and random placement
Alexander Kourakos <awk@bnt.com>
Move/resize code fixes, button press/release fix
Ryan Land <rland@bc1.com>
workspace "layers"
Largo <largo@gnu.net>
wm.gnu.net maintainer, FAQ maintainer
Stuart Luppescu <s-luppescu@uchicago.edu>
Documentation help
Marcelo E. Magallon <mmagallo@efis.ucr.ac.cr>
CPP search path improvement, man pages
Tim Malone <mrgone@eskimo.com>
bug fix
MANOME Tomonori <manome@itlb.te.noda.sut.ac.jp>
I18N bug fixes and japanese locale
Brian Alexander Martin <brian@goober.wireless.ucsc.edu>
PIPE_MENU
Andrea Mistrali <andre@ulmo.aleph.it>
3D version of GNUstep icon.
Jeff Meininger <jeffm@boxybutgood.com>
Fix for unassociated alpha tiff
Dan Pascu <dan@services.iiruc.ro>
dock ghost (superfluous mode) fix, enhancement for scrollable menus,
clip, numerous other stuff, project maintainer
Kenneth W. Persinger Jr. <Kenn_Persinger@sector7.com>
tcl/tk dockit
Biagio Pippa <1993s017@educ.disi.unige.it>
fixed miniaturization with transient window
Anthony Quinn <Anthony.Quinn@usa.xerox.com>
Sound code.
Andreas Saudemont <saudemon@depinfo.u-bourgogne.fr>
Initial code for clip's collapse feature.
Ture Pelsson <ture@lysator.liu.se>
various portability fixes, replaced busy wait with select() in event
handling code, fixed problem with some misbehaved kids after a fork().
Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de>
SCO portability, german locale, autoconf enhancements
Christopher Seawood <cls@seawood.org>
REDUCE_APPICON/single-icon
Chong Shang Shan <chongsha@sps.nus.edu.sg>
flipping iconification animation
Phillip Smith <teknix@alloy.net>
FTP and WWW site provider/maintainer
Lauri Tarkkala <ltarkkal@cs.hut.fi>
SIGHUP unblock bug fix
Sam Varner <varner@nmr.physics.wm.edu>
many fixes and enhancements for move, resize and window placement code.
Marco van Hylckama Vlieg <fatal@global.uibk.ac.at>
house icon for WINGs file dialogs, defaullAppIcon and Clip xpm icon
David Wang <dwang@cisco.com>
edge resistance
Yoav Yerushalmi <yoav@mit.edu>
Fixed -visualid for screens that can do multiple depths. Another fix in
libproplist. Chooses best depth in screen.
FRBall <frb@umr.edu>
dgradient fix
"]d" <mhz@gpf.or.th>
Window list menu miniaturized/hidden hints
Trae Mc Combs <x@themes.org>
BlueWaves.jpeg background image in BlueWaves theme.
And a special thanks to Martin Eskildsen for giving me his
copy of NEXTSTEP :-)

71
BUGFORM Normal file
View File

@@ -0,0 +1,71 @@
WindowMaker Bug Report Form
---------------------------
If you find a bug please fill this form and send it to
developers@windowmaker.org
You can also report a bug in the WWW bug tracker at
http://windowmaker.org/cgi-bin/bugs
0. Before reporting this bug I already:
[ ] read the NEWS, README and INSTALL files
[ ] read the list of already known bugs in the BUGS file
[ ] downloaded and tried the latest version of WindowMaker
1. What happened:
[ ] could not compile
[ ] crashed
[ ] configuration option does not work
[ ] weird behaviour
[ ] cosmetic
[ ] some problem with WPrefs
[ ] others: ...................................
2. Detailed description of what happened:
3. How to reproduce the bug, if known:
4. Configure time options you specified:
[ ] --enable-kanji
[ ] --disable-shape
[ ] --disable-xpm
[ ] --disable-tiff
[ ] --disable-png
[ ] --enable-single-icon
[ ] Others: .......................
5. Changes to the src/wconfig.h file:
6. The error occured during:
[ ] configuration
[ ] compilation
[ ] startup
[ ] use
7. Changes made to the configuration files, if the error ocurred during use:
8. Error messages output:
9. Fix, if known:
10. Other Notes:
Your e-mail address: .................................................
Operating System (run "uname -a"): .................. Version: .......
Distribution (if applicable): ..................... Version:..........
X Server Vendor: ...................... Color Depth: .................
WindowMaker Version (run "wmaker -version"): .........................

10
BUGS Normal file
View File

@@ -0,0 +1,10 @@
- the app menu does not update after a style/theme change without restart.
- the animation of shade puts ImageMagick/display in a weird state
- during startup, transient windows should be miniaturized with their owners
not in their own icons
- shaped windows don't resize very well
- stacking code is buggy (or XFree is buggy)
- WINGs has problems in some platforms (SGI, Sun etc.) Anyone on these
systems want to fix it?
- save session doesnt work on some platforms (Alpha and Sparc)
- GNUSTEP_WM_ATTR in WINGs has problems on Alpha boxes

340
COPYING Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

1224
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

907
FAQ Normal file
View File

@@ -0,0 +1,907 @@
WindowMaker FAQ
====================================================================
the latest info can be found at
http://www.dpo.uab.edu/~grapeape/wmfaq.html or
http://wm.gnu.net/wmfaq/
--------------------------
Summary of Contents:
Introduction
- What is WindowMaker?
- Where can I get WindowMaker?
- Where are the mailing list archives?
- Where is there more documentation on configuring WindowMaker?
Installation
- Where can I get proplist.h?
- Why do no icons show up after installing WindowMaker 0.15.0 when I've
followed all the directions?
- How do I get libtiff to work?
- How do I get libjpeg to work?
- How do I get libpng to work?
- Does wmsound work with 0.1x.x?
- How do I switch CDE's windowmanager to use WindowMaker?
- Do I need to rerun wmaker.inst with every new version of WindowMaker?
Usage
- What is an appicon?
- How do I get new apps on the dock (The line of pixmaps on the right side
of the screen by default)
- What is the button in the middle of the Clip?
- What is the difference between the Exit and Exit Session Option?
- How do I "dock" Icons on the Clip?
- Why do none of my Key Bindings work in WindowMaker 0.1x.x
- How do I rename workspaces?
- How can I resize a window if the window is larger than my currect
desktop?
- When I run xyz (xyz usually = rxvt) from the dock and later quit, the
3 dots don't come back and I can't run it again.
Configuration
- What are those files inside my ~/GNUstep directory?
- How do I enable the normal X sloppy focus mode?
- How do I get my auto-arrange icons to work?
- How do I get my Meta-Tab to cycle through windows correctly?
- How can I define my own Icon for a program? (instead of the Icon the
Application Supplies?)
- How do I get a pixmap background for my appicons (those things in the
dock)?
- How do you dock <insert program here> that doesn't have an appicon in
the new version of WindowMaker?
- How do I get x11amp to not have a title bar? (or any other program for that
matter?)
- How do I set a pixmap background?
- Can I put pixmaps in my root menu and title bars?
- How do I get my Minimize Icon to look like the triangle I see in
screenshots?
- How do I get superfluous bells and whistles working?
- How do I get my oldstyle back?
Other Applications
- How do I assign gimp an appicon?
- How do I get an appicon for XEmacs 20.3+?
- Where do you get that clock program I always see on people's desktops?
- How do you dock asclock?
- How do you dock wmload?
- What other apps exist for the dock?
- How do I get an appicon for rxvt so I can dock it?
- How do I get different icons for rxvt's (or xterms) running different
programs?
- How do I allow Alt+# to work in an rxvt session? (with irc for example)
Programming
- How do I get a normal X application to produce an appicon?
- How do I get my tcl/tk application to produce an appicon?
Miscellaneous Questions
- Is there a pager for WindowMaker?
- Can I have folders like in AfterStep?
- What exactly are Themes?
- How do I install a Theme?
- How do I make a Theme?
========================================================================
-=-=-=-=-=-=-
Introduction:
-=-=-=-=-=-=-
What is WindowMaker?
----------------------------------
WindowMaker is an elegant X11 window manger that emulates the OpenStep
desktop with some noticeable enhancements. Look at
http://wm.gnu.net/screenshots.html for example screenshots.
Where can I get WindowMaker?
----------------------------------
The official site to get new developmental versions from is
ftp://ftp.windowmaker.org/pub/beta/srcs/.
NOTE: WindowMaker-0.16.1.tar.gz is the newest stable release, for some
reason it has not been moved into the release directory. You should
DEFINATELY go with 0.16.1 rather than 0.6.3.
WindowMaker-0.17.5 is the newest development release. This will be the last
release with new features until 1.0 is released. Work from now until 1.0 will
focus on bug fixes, so keep testing and report those bugs!
The development versions are usually very stable themselves, so if you want to
have all the newest features, you can rather safetly go with the development
versions. Just remember to save any unsaved data before you go playing
around with the config files. Also, remember they are developmental versions,
so your mileage may vary, don't get angry if they crash.
Where are the mailing list archives?
----------------------------------
UPDATE: Ed has moved to Utah to work for Caldera, so the list has moved.
The new address is http://www.caldera.com/linuxcenter/forums/wmaker.html
The archives should come online again when Ed gets all moved in and comfy in
about 2 weeks or so. (around mid-august or so) Please be patient until then.
Thanks!
Where is there more documentation on configuring WindowMaker?
----------------------------------
Besides the mailing list archives, there are nice documents in
ftp://ftp.windowmaker.org/pub/docs/
-=-=-=-=-=-=-
Installation:
-=-=-=-=-=-=-
Where can I get proplist.h?
----------------------------------
My first hint would be to look through the documentation a little more closely.
libPropList.tar.gz is located in the root of the WindowMaker distribution source
tree. Untar libproplist, compile and install it so that the it will be available to
compile WindowMaker.
Why do no icons show up after installing WindowMaker >= 0.15.x when
I've followed all the directions?
----------------------------------
According to Dan Pascu should not happen because WindowMaker should
detect if libtiff is going to be compiled in and then it will make the default theme
based around .xpm instead of .tif.
As of WindowMaker version 0.15.0, the default setup includes .tiff icons which
require you to have compiled WindowMaker with libtiff support. For some help
on compiling with libtiff, at the libtiff section of this FAQ.
How do I get libtiff to work?
----------------------------------
The whole key to getting libtiff working for me was to upgrade to >=
tiff-v3.4beta037-tar.gz availible at ftp.sgi.com.
Rerun ./configure and make and it should work. I had previously been using
tiff-v3.4-tar.gz instead so the library was there just not working. A note to keep in
mind, is that the tiff libs are versioned rather oddly, version tiff-v3.4beta037 is
actually newer than tiff-v3.4.
Make sure to rm config.cache and rerun ./configure before attempting to compile
again.
Also, make sure to use gnu-make for the WindowMaker compile.
How do I get libjpeg to work?
----------------------------------
The newest jpeg libs are availible at ftp://ftp.uu.net/graphics/jpeg/.
How many of you have seen that darned "lib reports 62 caller expects 61" type of
error?
Well, I have more than once, and here are some answers to possibly help you
out.
First things first. As always, make sure there are not older copies of libjpeg
floating around on your system. By default my Slackware distribution came with
an old libjpeg.so.1 in the /usr/X11R6/lib/ directory. This can simply be deleted. Or
if something complains after you delete it, recompile it if you can to look for the
new lib in the right place, or if that fails, as a last resort, you might add a symlink
to the new lib like so:
ln -s /usr/local/lib/libjpeg.so.6.0.2 libjpeg.so.1
Now on to the error.
This is basically caused by your application having been compiled to
dynamically use the libjpeg.so shared library. When you install a new lib and then
try to run your program again, it expects the lib it was compiled against, in this
case the older libjpeg.so.6.0.1 and instead finds libjpeg.so.6.0.2 and reports the
error.
The fix is actually rather simple. Along with adding a libjpeg.so.6 symlink like so
(just in case):
ln -s libjpeg.so.6.0.2 libjpeg.so.6
where you installed your new lib, you simply need to recompile your app to link it
against the new library. :)
Make sure to rm config.cache and rerun ./configure before attempting to compile
again.
Also, make sure to use gnu-make for the WindowMaker compile.
How do I get libpng to work?
----------------------------------
The newest png libs are availible at
http://www.cdrom.com/pub/png/pngcode.html.
You should also get the newest zlib libs from
http://www.cdrom.com/pub/infozip/zlib/.
I had a few problems with this lib as well, basically I had an old libz.so in my
/usr/X11R6/lib/ directory which configure was finding first, and which failed the test,
being an older lib.
Generally the same applies here as with libjpeg, make sure there are no older
versions of the necessary libs floating around on your system, then try and
configure and make again.
Make sure to rm config.cache and rerun ./configure before attempting to compile
again.
Also, make sure to use gnu-make for the WindowMaker compile.
Does wmsound work with 0.1x.x?
----------------------------------
As of WindowMaker 0.15.x, sound is now included by default but requires the
authors sound server. For more information, read the NEWS file in the
WindowMaker distribution.
The author Anthony Quinn has released a version that works with
WindowMaker >= 0.15.x. It is available from it's home page at
http://www.frontiernet.net/~southgat/wmsound/
or at
http://wm.gnu.net/files.html#wmsound
How do I switch CDE's window-manager to use WindowMaker?
----------------------------------
Method 1:
Peter Ilberg <peter.ilberg@natinst.com> gives us this answer:
Install WM wherever you want it, mine is in /opt/WindowMaker-0.16.0
(eg. use ./configure --prefix=/opt/WindowMaker-0.16.0).
Run the install script wmaker.inst in your home directory.
Add the following two lines to .dtprofile in your home directory:
SESSIONTYPE=xdm; export SESSIONTYPE
PATH=:/usr/contrib/bin/X11:$PATH:.; export PATH
This tells CDE to go looking for an .xinitrc/.xsession instead of using the default
environment.
Make your .xsession/.xinitrc executable (VERY IMPORTANT, wmaker.inst did NOT
do this automatically for me) using eg.
chmod ugo+x .xsession
Your .xsession/.xinitrc should look something like this:
#!/bin/sh
<some other init stuff that you want/need>
exec wmaker
Things to try if it doesn't work: (somewhat fuzzy and random)
This should do it although I did have problems sometimes initially which I fixed
by randomly trying absolute pathes for wmaker in .xsession/.xinitrc and/or making
the dtprofile/.xinitrc/etc executable. It helps logging in on the console (select from
CDE login screen) and start X manually using 'X'.
If it works that way it should work when logging into the CDE environment.
Remember to Check your paths!
If it doesn't work, you can also substitute some other window manager for
wmaker in the .xinitrc and see if that works. If it does you know at least that .xinitrc
is getting called/executed, so your WM path is wrong or not set.
Method 2:
Thomas Hanselman gave this alternative answer (via Peter Ilberg):
Build and install WM wherever you want, as described in Method 1. You can
install and run WM just fine from your home directory. That's what I'm doing,
since I don't have root access at work :(. Then, in your .Xdefaults file in your
home directory, add the following line:
Dtsession*wmStartupCommand: <path to WindowMaker executable>
Then, log out, and log back in, and, unless I've forgotten a step (or this is a
custom Nortel thing), you should be in WindowMaker heaven ;).
Difference between the methods: (according to Thomas)
I've been told that the difference between setting the resource and Peter's
method is that if you override the window manager with the resouce, you still get
the CDE resources read into the resource database (so you still have your color
settings & such from CDE), whereas with Peter's, the CDE resource don't get
read into the database. I don't know if this is true or not, however. Also, another
thing to note with WindowMaker and HP-UX 10.20 -- if you select "Exit Session"
from the WM root menu, WindowMaker and all of your applications are killed,
but you may not be logged out. Again, this might be an artifact from my work
environment, or the way I start WindowMaker.
Owen Stenseth <iplenergy.com> adds:
When using this method it is possible to exit WindowMaker cleanly by using the
dtaction command. I use the following in my WindowMaker menu:
"Exit Session" EXEC dtaction ExitSession
The only problem I have at the moment is I seem to get multiple copies of
asclock running when I log in again.
Do I need to rerun wmaker.inst with every new version of WindowMaker?
----------------------------------
Dan Pascu reveals the answer:
When the user will need to run wmaker.inst again in a new release of wmaker,
we will write that down in the NEWS file.
(as I've done in 0.15.0).
The way domain files are read beginning from 0.15.0 makes this redundant. The
user config files are merged with the global ones in
/usr/local/share/WindowMaker/Defaults.
So even if new options are added, they will reflect in the user configuration.
Only if user wishes to change the default behavior, he needs to add that option
to the config file.
-=-=-=-
Usage:
-=-=-=-
What is an appicon?
----------------------------------
An appicon is the icon (without the tiny titlebar a minimized application icon has)
produced by most applications that initially is in the bottom left corner of the
screen while an application is running. For an example, run xterm and notice the
icon in the corner. (Make sure that you use xterm and not a default older rxvt
because older versions of rxvt do not properly set their window attributes.)
How do I get new apps on the dock (The icon or line of icons on the right
side of the screen by default)
----------------------------------
Launch an application. If there is a little icon that pops up in the bottom corner of
the screen, drag it over to the dock icon(s). You should see a whiteish square
indicating when it is close enough to dock, and where it will be placed. To make
sure this application will be there next time you start up windowmaker, exit
windowmaker with the "exit session" option.
What is the button in the middle of the Clip?
----------------------------------
Dan Pascu gives this insightful answer:
"Well, it's the power on indicator. To be sure that Clip is working ;)"
In 0.15.x, the light now means that the Clip is in its expanded stateto show any
appicons attached to it. When collapsed, it expands when you drag an appicon
near it to dock.
What is the difference between the 'Exit' and 'Exit Session' Options?
----------------------------------
Another Answer from Dan Pascu:
"'Exit' exits wmaker, but leaves the other apps running, and if wmaker was not
the last app launched in the .xinitrc the X server is not closed, until the last app
started by .xinitrc is closed.
'Exit session' will exit wmaker, but also will close all running apps, thus the X
server will be closed."
How do I "dock" Icons on the Clip?
----------------------------------
Just drag icons near it like you would for the dock. If you are having a problem
docking icons, you should try moving the Clip away from the dock.
Why do none of my Key Bindings (ie: Alt+#) work in WindowMaker 0.1x.x
----------------------------------
If you are using XFree86, make sure scroll lock and numlock are off or no
bindings will work (XFree bug). You can try using the XFree86 Numlock Hack by
editing the line #undef NUMLOCK_HACK in $WindowMakerdir/src/wconfig.h and
changing it to #define NUMLOCK_HACK.
How do I rename workspaces?
----------------------------------
Right click on the "desktop" (root window) to show the menu (don't hold the
button down). Go to the workspaces menu and hold the Control key down and
click on the workspace you would like to rename and type the name.
How can I resize a window if the window is larger than my currect
desktop?
----------------------------------
David Reviejo <dreviejo@arrakis.es> best summed up this answer:
"Maybe you know:
Alt+Left click and drag
to move the window.
Try this:
Alt+Right click and drag
to resize (by moving the nearest window corner)
Another move/resize tip: while you are moving or resizing a window, you
can change the move/resize mode by pressing the SHIFT key."
When I run xyz (xyz usually = rxvt) from the dock and later quit, the
3 dots don't come back and I can't run it again.
----------------------------------
You docked xyz using dockit. Dockit does not generate correct application
icons most of the time. The only way to get around it is to edit
~/GNUstep/Defaults/WMState and set ForcedDock = YES; in the entry for xyz.
If you use rxvt, upgrade to rxvt 2.4.6 or newer.
-=-=-=-=-=-=-=-
Configuration:
-=-=-=-=-=-=-=-
What are those files inside my ~/GNUstep directory?
----------------------------------
~/GNUstep/WindowMaker/WindowMaker
The main config file. This file controls options such as keybindings, fonts,
pixmaps, and focus modes.
~/GNUstep/WindowMaker/WMWindowAttributes
The Controls "attributes" for individual applications and appicons. Options
such as what icon to use are set here. For the most part, this is now best
accessed via a right click on a title bar of an application and selecting
"Attributes"
~/GNUstep/Defaults/WMState
This is the file that is automatically generated and contains the current
dock settings. It is not recommended to edit this file by hand.
~/GNUstep/Defaults/WMRootMenu
This file specifies what file to use as the root menu.
~/GNUstep/Library/WindowMaker/menu
This is the file to edit to change your root menu.
How do I enable the normal X sloppy focus mode?
----------------------------------
In the ~/GNUstep/Defaults/WindowMaker, change the following:
FocusMode = sloppy;
How do I get my auto-arrange icons to work?
----------------------------------
In ~/GNUstep/Defaults/WindowMaker set AutoArrangeIcons=Yes; and the icons
should now auto-arrange.
How do I get my Meta-Tab to cycle through windows correctly?
----------------------------------
Make sure that these settings are true in your ~/GNUstep/Defaults/WindowMaker
file:
CirculateRaise = Yes;
RaiseDelay = 1;
How can I define my own Icon for a program? (instead of the Icon the
Application Supplies?)
----------------------------------
You can right click on the titlebar of the running app and choose the
"Attributes..." option, then click on the "Ignore client supplied icon" checkbox.
Click "Apply", "Save" and close the Attributes Editor.
Another method is to edit ~/GNUstep/Defaults/WMWindowAttributes by hand and
use the AlwaysUserIcon=YES; option for the app. For example:
xmcd = { Icon = "Radio.xpm";
AlwaysUserIcon=Yes;
};
How do I get a pixmap background for my appicons (those things in the
dock)?
----------------------------------
You need to change 1 line to your ~/GNUstep/Defaults/WindowMakerfile.
IconBack = (spixmap, tile.black.xpm, white);
or
IconBack = (tpixmap, tile.black.xpm, white);
spixmap will scale the pixmap to fit the tile, tpixmap will tile it as is.
As Random@efnet says, The last parameter is the color that fills in any
transparent parts of your icon.
How do you dock <insert program here> that doesn't have an appicon in
the new version of WindowMaker?
----------------------------------
Use the tcl script dockit which is included with WindowMaker 0.15.x. By default
you can run it by double clicking on the main dock icon. Note that dockit
can generate problematic appicons.
How do I get x11amp to not have a title bar? (or any other program for
that matter?)
----------------------------------
Right Click on the title bar and choose "Attributes". Click on Panel 2 and click
the the "Disable titlebar" and "Disable resizebar" options. Click "Save", "Apply"
and then close the Attributes panel.
By Default, to get back to the attributes menu once you've removed the titlebar,
hit the key F10 while the window is focused.
Here is an example entry in ~/GNUstep/WMWindowAttributes for x11amp.
x11amp={
Icon="x11amp.xpm";
NoTitlebar=Yes;
NoResizebar=Yes;
NoAppIcon=Yes;
};
How do I set a pixmap background?
----------------------------------
Here is the in depth explanation straight from the NEWS file:
wmsetbg now accepts the following options:
usage: wmsetbg [-options] image
options:
-d dither image
-m match colors
-t tile image
-s scale image (default)
-u update WindowMaker domain database
-D <domain> update <domain> database
-c <cpc> colors per channel to use
By default, it will try to guess if dithering is needed or not and proceed
accordingly.
Using -d or -m will force it to dither or match colors.
Dithering for more than 15bpp is generally not needed, and will only result in a
slower processing.
Don't use dithering except when needed, because it is slower. Else rely on
wmsetbg which will detect if dithering is needed and use it.
-u will update the WorkspaceBack in the default database domain
file in ~/GNUstep/Defaults/WindowMaker, and let WindowMaker
refresh the screen. Please note that this option only works under
WindowMaker, and will have no effect under other window
managers, since it rely on WindowMaker to update the image
after it reads the updated defaults database.
-D <domain> is same as above, but will update the domain
<domain> instead of the default WindowMaker domain.
-c <cpc> will set the color per channel to use. Only needed for
PseudoColor visuals. WindowMaker will automatically pass the
value read from the WindowMaker domain database.
The following line is straight from your WindowMaker-0.15.x
~/GNUstep/Library/WindowMaker/menu file and should all be on one line.
"Images" OPEN_MENU BACKGROUNDS_DIR
~/GNUstep/Library/WindowMaker/Backgrounds WITH wmsetbg -u -t
This should give you an idea on how to add other entries for different image
directories. See the help info at the top of the
~/GNUstep/Library/WindowMaker/menu file for more information.
If you for some reason would like to set your background image with XV, for
instance to use an image format not yet supported by wmsetbg or to use one of
XV's special modes, edit the file ~/GNUstep/Library/WindowMaker/autostart and
insert the line
xv -root -quit -maxpect ~/background.jpg
or
xv -root -quit -max ~/background.jpg
you can also try variations of this to get different tiling and other effects (where X
is a number 1-9 I believe):
'xv -root -quit -rmodeX ~/background.jpg'
If you would like xv functionality in your menu, heres a nice little tip from Alfredo:
Add the following line to your ~/GNUstep/Library/WindowMaker/menu file. (all on one
line)
"More Backgrounds" OPEN_MENU /home/whoever/backgrounds xv -root -maxpect -quit
Can I put pixmaps in my root menu and title bars?
----------------------------------
With the release of WindowMaker-0.14.1, you can now put pixmaps anywhere
you would have either a gradient or a color. This means now that
MenuTextBack=(tpixmap, foo.xpm, acolor);
in ~/GNUstep/Defaults/WindowMaker will put the correct pixmap tiled in your menu.
FTitleBack = (spixmap, foo.xpm, black);
Would have the effect of streching a pixmap to fit the titlebar of the active
window.
You can use png, tiff, jpeg and xpm images interchangeably in WindowMaker if
you have compiled in support for those formats.
How do I get my Minimize Icon to look like the triangle I see in
screenshots?
----------------------------------
This involves a minor source tweak. Instructions are available at
http://wm.gnu.net/tips.html#titlebar_icons.
Example screenshot can be seen at
http://wm.gnu.net/images/screenshots/Midnight3.jpg.
How do I get superfluous bells and whistles working?
----------------------------------
Add Superfluous=YES; to your ~/GNUstep/Defaults/Windowmaker file.
This option was added as a runtime option in WindowMaker >= 0.16.1.
How do I get the classic NeXT(tm)-like style back?
----------------------------------
Add NewStyle=NO; to your ~/GNUstep/Defaults/Windowmaker file.
This option was added as a runtime option in WindowMaker >= 0.16.1
-=-=-=-=-=-=-=-=-=-
Other Applications:
-=-=-=-=-=-=-=-=-=-
How do I assign gimp an appicon?
----------------------------------
WindowMaker now can assign Icons from within the windowmanager, to do so,
right click on the title bar of an app or hit F10 while the desired app is focused,
choose "Attributes...", click on the "4" Button, enter the icon file name (make
sure this is in your pixmap path, or you can type in the full path without using ~/
type path names), click "Update", "Apply", "Save" and then close the Attributes
Editor.
You can also enter the following line in
~/GNUstep/Library/WindowMaker/WMWindowAttributes:
gimp={Icon="gimp.xpm";};
How do I get an appicon for XEmacs 20.3+?
----------------------------------
Thanks to Michael Hafner <hayfi@rz.fh-augsburg.de> for this answer.
You don't need to patch the XEmacs code, just run
./configure --with-session=yes (in addition to any other options you use)
in your XEmacs 20.3+ sourcedir and rebuild it. Then XEmacs shows an
appicon when running and you can easily dock it.
Where do you get that clock program I always see on people's desktops?
----------------------------------
Its called asclock. It has been included with every version I've downloaded.
Currently it resides in ./WindowMaker-0.xx.x/misc/asclock.tgz and is prepatched to
be able to dock. Some other (older) versions you might find on the net don't
dock.
How do you dock asclock?
----------------------------------
asclock -shape -iconic -12 &
Drag it from the top right corner of the clock to the dock. Right click on the icon
and select autolaunch.
You have to drag the appicon by clicking on the edge of the icon, because the
actual pixmap belongs to the app itself, and any clicks on the pixmap are
interpreted by the app rather than X or the window manager. Therefor, you need
to click somewhere on the appicon where the background tile shows through
(usually the edges), and drag it that way.
How do you dock wmload?
----------------------------------
wmload -withdrawn -shape &
Then dock it similar to asclock.
What other apps exist for the dock?
----------------------------------
Several Nice applications are available:
wmmixer and wmcd and wmmount
http://www.geocities.com/SiliconValley/Vista/2471/linux.htm#xapps
ascd,WMRack,asmixer,asmodem, and others
ftp://ftp.windowmaker.org/pub/wmaker/contrib/srcs/apps/
wmavgload, wmmount, and wmload
ftp://ftp.windowmaker.org/pub/wmaker/contrib/srcs/utils/
wmppp-wmifs, wmtime, wmmon and other nifty apps
http://windowmaker.mezaway.org/
How do I get an appicon for rxvt so I can dock it?
----------------------------------
The default rxvt that comes with most distribtions is an outdated version of rxvt.
The newest development version of rxvt is availible from
ftp://ftp.math.fu-berlin.de/pub/rxvt/devel/. As of the time of this writing, the
version is 2.4.6 and it natively produces an appicon without a patch.
John Eikenberry has also created an rpm which is available from
ftp://ftp.coe.uga.edu/users/jae/windowmaker/
As of version 2.4.6, rxvt includes WindowMaker support as well as
John Eikenberry's NeXT scrollbar hack.
How do I get different icons for rxvt's (or xterms) running different
programs?
----------------------------------
The simplest way is to run each rxvt with a different -name parameter.
For example, I want to run an rxvt for irc and one for mail. This is an example of
what I'd do:
for the irc rxvt:
rxvt -name "irc" -e "irc"
for the mail rxvt:
rxvt -name "mail" -e "pine"
This would result in each rxvt now having the instance and class of irc.Xterm and
mail.Xterm respectively, so that WindowMaker can now set Attributes for them
individually.
How do I allow Alt+# to work in an rxvt session? (with irc for example)
----------------------------------
First, Launch a unique instance of rxvt or xterm.
This can be done using the -name option of rxvt.
For example:
rxvt -name foo -e irc
Then, go to the Attributes menu (right click on titlebar (or hit F10) and choose
'Attributes...')
Then choose 'Advanced Options' from the listbox and enable 'Don't Bind
Keyboard shortcuts'.
Click 'Save' and 'Apply' and you should be able to run your session without the
shortcuts.
-=-=-=-=-=-=-
Programming:
-=-=-=-=-=-=-
How do I get a normal X application to produce an appicon?
----------------------------------
Another insightful answer from who else but Dan Pascu.
"You must define the WM_CLASS (XSetClassHint()) and the CLIENT_LEADER
or XWMHints.window_group properties, which are automatically set by most
applications that use Xt (Motif, Athena ...), but if you use plain Xlib you must set
them by hand.
Also you must make a call to XSetCommand(dpy, leader, argv, argc);
Take a look at WindowMaker-0.1x.x/test/test.c that is an example for writing
such an app (which also have an app menu)."
How do I get my tcl/tk application to produce an appicon?
----------------------------------
Oliver Graf writes:
The main window (normally this is called '.' [dot] in tk) should use the following
lines:
wm command . [concat $argv0 $argv]
wm group . .
All child windows attached to the same app-icon should use:
toplevel .child
wm group .child .
where .child should be replaced by the actual window path.
Replace '.' with the actual main-window path and 'wm group .child .' should be
added for each 'toplevel .child' call.
-=-=-=-=-=-=-=-=-=-=-=-=-
Miscellaneous Questions:
-=-=-=-=-=-=-=-=-=-=-=-=-
Is there a pager for WindowMaker?
----------------------------------
Not at the moment because there is not a pressing need for a pager. The
concept of multiple desktops does exist and there are currently 3 ways to
switch between them.
First, the Alt+Number combination will switch between desktops. The
Workspaces menu will also let you switch workspaces. Lastly, the Clip will also
scroll one through workspaces.
For those that would like to send an application to a specific workspace, either
drag it to an edge of the desktop onto the next workspace or you can right click
on the titlebar, choose "Move to..." and choose the appropriate workspace.
Can I have folders like in AfterStep?
----------------------------------
No. WindowMaker does however support the collapsable Clip per desktop for a
similar functionality.
What exactly are themes?
----------------------------------
Themes are a great aspect of WindowMaker allowing a user to simply save the
entire 'look' of their desktop in a Archive to distribute freely among friends, fellow
users and/or the whole net in general. :)
See the topic "How do I make a Theme?" below for an in-depth walk-through on
making a Theme archive.
How do I install a Theme?
----------------------------------
This should be as simple as untarring the Theme.tar.gz into one of two places.
You can untar it to the global /usr/local/share/WindowMaker/* directory, and have it
be accessable to all users, or you can untar it to your own
~/GNUstep/Library/WindowMaker/ directory for your own personal use.
Use your favorite variation of the following:
gzip -dc "Theme.tar.gz" | tar xvf -
*(directory may differ on some systems)
How do I make a Theme?
----------------------------------
In this walk-through when I use WindowMaker/, it can refer to the global
/usr/local/share/WindowMaker/ directory or the users own
~/GNUstep/Library/WindowMaker/ directory.
To make a Theme.tar.gz, these are the steps I take:
1.Optionally create a README for your theme in WindowMaker/, call it
something like "ThemeName.txt"
2.Use the following command to add the Theme files to your .tar file.
tar cvf ThemeName.tar ThemeName.txt Themes/ThemeName
Backgrounds/ThemeNameBG.jpg Backgrounds/ThemeNameTile.xpm
You can add as many more images as you need from the appropriate
directories under WindowMaker/ following that general idea. You can even
optionally add an IconSets/ThemeName.iconset and it's associated icons to
your theme in the same manner. This should be stated in your README
if you decide to include these.
3.Then gzip your .tar file to make your ThemeName.tar.gz file with this
command:
gzip -9 ThemeName.tar
4.Now give it to your friends!

51
FAQ.I18N Normal file
View File

@@ -0,0 +1,51 @@
If I18N support does not work for you, check these:
- the LANG environment variable is set to your locale, and
the locale is supported by your OS's locale or X's locale
emulation. you can display all supported locales by
executing "locale -a" command if it available. and you
can check if your locale is supported by X's locale emulation.
See "/usr/X11R6/lib/X11/locale/locale.alias"
- if your OS doesn't support any locale or if your OS doesn't
support a locale for your language, you can use X Window System's
locale emulation feature instead of OS's locale. To use this
feature, add this option to the configure, "--with-x-locale".
if your OS is commercial one, such as Solaris,IRIX,AIX,...,
you perhaps don't have to use X's locale emulation.
But if your OS is Linux or NetBSD or .. , it's possible
your locale is not supported so far. then use "--with-x-locale".
Note: to use X's locale emulation, your Xlib has to be
compiled so that the locale emulation is enabled.
Linux RedHat5.0's default Xlib is not compiled
like that. (RH4.x are ok). Recompiled Xlib for
RH5.0 where you can use locale emulation is available
here:
ftp://ftp.linux.or.jp/pub/RPM/glibc
- if you'd like to display multibyte characters, wmaker have to
be compiled with multibyte character support. Add this option
to the configure, "--enable-kanji".
- the fonts you're using support your locale. if your font
setting on $HOME/GNUstep/Defaults/WindowMaker is like..
WindowTitleFont = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*";
MenuTitleFont = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*";
......................................................
then you can't display non iso8859-x charcters by helvetica.
so quick way to display various languages' font is to change
all the font settings into:
"-*-*-medium-r-normal-*-14-*-*-*-*-*-*-*"
and also you need to change font settings in style files in
the "$HOME/Library/WindowMaker/Style" directory.
- the LC_CTYPE environment variable is unset or it has the correct
value. If you don't know what is the correct value, unset it.

455
INSTALL Normal file
View File

@@ -0,0 +1,455 @@
Installation Instructions for WindowMaker
SUPPORTED PLATFORMS
===================
(ie: I've heard someone has compiled it on...)
- Intel/Linux RedHat 4.2 (primary platform)
- Intel/Linux other distributions
- Sparc/Linux RedHat 5.1
- PowerPC/MkLinux
- Alpha/Linux RedHat 5.1
- FreeBSD
- Solaris 2.5.1, 2.5.2
- Solaris 2.6.0
- Solaris 2.7beta
- SCO Unix
- SGI Irix
- OSF/1
- HP-UX
- AIX 4.1.4 / IBM PowerPC
- DEC Alpha/Digital UNIX 4.x
- XFree86 / OS/2
Patches to make it work on other platforms are welcome.
REQUIREMENTS:
=============
The following software is required to use WindowMaker
- X11R6.x
WindowMaker can be compiled in older versions of X, like X11R5
(Solaris) or X11R4 (OpenWindows) but it will not work 100% correctly.
In such servers there will not be application icons and you'll have
trouble using the dock.
If you will build WindowMaker, make sure you have gcc and the X header files
installed. Specially for newbie Linux users: you must install all X development
packages and the gcc suite. Otherwise you won't be able to build any X program,
including WindowMaker.
OPTIONAL:
=========
These libraries are not required to make WindowMaker work, but they
are supported in case you want to use them. Version numbers are those
that I have (and therefore, guraranteed to work), but other versions
might work too. Tell me if you made wmaker work with some library
with a version older than the stated here.
- libXPM 4.7
Older versions may not work!!!
Available at ftp://sunsite.unc.edu/pub/Linux/libs/X/
There is builtin support for XPM files, but it will not
load images in some uncommon encodings.
- libpng 0.96 or newer and zlib
For PNG image support.
- libtiff 3.4 or newer
For TIFF image support.
You can get it at ftp://ftp.sgi.com/graphics/tiff
- libjpeg 6.0.1
For JPEG image support
- libgif 2.2 or libungif
For GIF image support
- GNU xgettext
If you want to use translated messages, you will need GNU gettext.
Other versions of gettext are not compatible and will not work.
Get the GNU version from ftp://prep.ai.mit.edu
Most of these can be get from ftp.uu.net/pub/graphics
CONFIGURE OPTIONS:
==================
These options can be passed to the configure script to enable/disable
some WindowMaker features. Example:
./configure --enable-kanji
will configure WindowMaker with kanji characters support compiled in.
--disable-xpm disables use of the XPM library even if it is available on
your system.
--disable-png disables use of PNG library
--disable-tiff disable use of TIFF library
--disable-gif disable use of GIF library
--disable-jpeg disable use of JPEG library
--disable-shape disables shaped windows (for oclock, xeyes etc.)
--enable-debug adds extra debugging information. Do not use it
unless you're debugging WindowMaker.
--enable-kanji support to display Kanji characters, Korean, Chinese
and other languagues that require special characters.
--enable-single-icon enables the collapsing of all appicons of the
WM_CLASS+WM_INSTANCE into a single one. This feature is not
supported at all by the developers. If you have some trouble with it,
contact it's author: Christopher Seawood <cls@seawood.org>
PLATFORM SPECIFIC NOTES:
========================
- SCO Unix - run configure like
CFLAGS="-belf -DANSICPP" ./configure
- SunOS, Solaris
If you have gcc installed, after running configure, edit
src/config.h and change the #define CPP_PATH line to
#define CPP_PATH "gcc -E -x c"
Sun's cpp lacks some features needed by WindowMaker and it can
cause problems when parsing the config files.
- RedHat Linux
Make sure you don't have the LANG and LINGUAS environment variables
set to en_RN. Also, make sure you have /usr/local/bin in your
PATH environment variable, as for some mysterious reason the folks
at RedHat did not include it in the default configuration files
in RH 5.{0,1}.
- PowerPC MkLinux
You will need to have the latest version of Xpmac. Older versions
seem to have bugs that cause the system to hang.
- Debian Linux
If you want JPEG and TIFF support, make sure you have libtiff-dev
and libjpeg-dev installed.
- MetroX (unknown version)
MetroX has a bug that corrupts pixmaps that are set as window
backgrounds. If you use MetroX and has weird problems with
textures, do not use textures in titlebars. Or use a different
X server.
INSTALLATION:
=============
Unpack WindowMaker-data.tar.gz and move the pixmaps directory in it
to /usr/local/share/pixmaps
You can get the file at ftp://ftp.windowmaker.org. This file is not strictly
necessary, but contains some additional nice icons and other things.
autoconf and automake
---------------------
autoconf and automake are not required, but if you have them installed,
make sure you have autoconf 2.12 and automake 1.3 or newer. If you have
an older version, disable them by temporarily renaming them to something
else or uninstalling them from your system.
Build libPropList
-----------------
Note: You only need to build libPropList if you don't have it installed
in your system.
libPropList is included with the distribution, so you don't
need to download it anywhere (some people have asked me this...)
But if you already have libPropList installed on you system you
can skip this step, since configure will detect that and use the
installed version first if available.
To build libPropList, simply type the following at the shell prompt:
gunzip -c libPropList.tar.gz | tar xf -
cd libPropList
./configure
make
then, login as root and type:
make install
Build WindowMaker
-----------------
If this is the first time you're building WindowMaker, you can
simply type:
./configure
make
then, login as root and type:
make install
or if you want to strip the binaries from debugging symbols and make them
smaller, you can instead type:
make install-strip
This will build and install WindowMaker with default parameters.
If you want to customize some compile-time options, you can do the
following.
1. (optional) Look at the CONFIGURE OPTIONS section above for the
options available. Also run:
./configure --help
to get a complete listing of other options that are available.
Note that the WPrefs.app installation path is configured
in a different way. Look at WPrefs/README for information.
2. Run configure with the options you want. For example, if you
want to use the --enable-kanji option, type:
./configure --enable-kanji
3. (optional) Edit src/wconfig.h with your favorite text editor
and browse through it for some options you might want to change.
4. Compile WindowMaker. Just type:
make
5. Login as root (if you can't do that, read the "I don't have the
root password :-(" section) and install WindowMaker in your system.
Again, type:
su root
make install
User specific configuration
---------------------------
These instructions do not need to be followed when upgrading WindowMaker
from an older version, unless stated differently in the NEWS file.
Every user on your system that wishes to run WindowMaker must do the
following:
1. Install WindowMaker configuration files in your home directory.
Type:
wmaker.inst
wmaker.inst will install WindowMaker configuration files and will
setup X to automatically launch WindowMaker at startup.
That's it! The configuration file where you can edit your preferences
is $HOME/GNUstep/Defaults/WindowMaker.
The $HOME/GNUstep/Defaults/WMWindowAttributes file is where you assign
icons to applications and edit some other attributes for windows. This can
be also edited from the "Attributes Panel". To access it, click the titlebar
of the window with the Right mouse button and select "Attributes...".
The $HOME/GNUstep/Library/WindowMaker/menu file is the definition of
the root menu. Edit it according to the applications you have installed.
Read the User Guide for a more in depth explanation of WindowMaker.
The User Guide is avaiable at http://windowmaker.org
You might want to take a look at the FAQ too.
I don't have the root password :(
---------------------------------
If you can't get superuser privileges (can't be root) you can install
wmaker in your own home directory. For that, supply the --prefix option
when running configure in step 2 of building WindowMaker . Example:
./configure --prefix=/home/jshmoe
If you use national language support, you must also supply the --with-nlsdir
option, as:
./configure --prefix=/home/jshmoe --with-nlsdir=/home/jshmoe/lib/locale
Then make /home/jshmoe/bin be included in your search path and run
bin/wmaker.inst
UPGRADING
=========
If you are upgrading from an older version of WindowMaker:
1. Configure and build WindowMaker as always
2. Install WindowMaker (but do not run wmaker.inst)
3. Read the NEWS file and update your configuration files,
if necessary.
TROUBLESHOOTING
===============
When you have some trouble during configuration (while running configure),
like not being able to use a graphic format library you think you have
installed, look at the config.log file for clues of the problem.
== When I try to start X after installing wmaker, I get this:
exec: wmaker: not found
You probably are using a brain-damaged distribution. Add /usr/local/bin
into your path environment variable (editing .cshrc or .profile)
== Error during build of libPropList
make: *** No rule to make target `libPropList.a.c', needed by
`libPropList.a.o'. Stop.
Make sure the autoconf and automake versions you have installed are at
least:
autoconf 2.12
automake 1.3
If you are using the RPM's that come with RedHat 4.x, don't use them.
It is broken. Uninstall the RPM and reinstall a fresh package from
You can get them from ftp://prep.ai.mit.edu or any mirror.
== configure doesn't detect libtiff, or other graphic libraries.
Delete config.cache, then rerun configure adding the following options to
configure (among the other options you use):
--with-gfx-libs="-L/usr/local/lib"
--with-gfx-incs="-I/usr/local/include -I/usr/local/include/tiff"
Put the paths where your graphic libs and their corresponding header files are
located. You can put multiple paths in any of these options, as the example
of --with-gfx-incs shows. Just put a space between them.
== configure doesn't detect libXpm.
* Check if you have a symbolic link from libXpm.so.4.9 to libXpm.so
== Segmentation fault on startup
* Check if the version of libXPM you have is at least 4.7
* Check if you have an updated version of ~/GNUstep/Defaults/WindowMaker
If you're not sure, try renaming ~/GNUstep to ~/GNUtmp and then run wmaker.inst
== "...: your machine is misconfigured. gethostname() returned (none)"
* the hostname of your machine is set to something invalid, that starts
with a parenthesis. Do a man hostname for info about how to set it.
== The root menu contains only 2 entries. ("XTerm" and "Exit...")
* WindowMaker is not finding cpp (the C preprocessor). If your cpp is
not located in /lib/cpp, edit src/config.h and correct the path in
CPP_PATH.
LOCALES/INTERNATIONALIZATION
============================
WindowMaker has national language support.
To enable national language support, you must compile
WindowMaker with some additional parameters.
0 - You must have the GNU gettext package installed. It can be
obtained at ftp://prep.ai.mit.edu/pub/gnu/gettext-nnn.tar.gz
Steps 1 to 3 can be skipped if you use the Install script.
1 - You have to select the languages you want to support. Set the
LINGUAS to the list of locales you want. English is always
suported. Example:
setenv LINGUAS "pt ja de"
in csh
or
export LINGUAS;LINGUAS="pt ja de"
in sh
The list of supported locales can be found in po/README.
English is the default language.
Read po/README if you wish to translate and maintain locale files
for other languages.
2 - Additionally, if your language uses multi-byte characters, such
as Japanese or Korean, you must supply the --enable-kanji flag to configure.
3 - Configure, build and install WindowMaker normally.
4 - To select a particular locale at runtime you must set the LANG
environment variable to the locale you want. For example, if you want to set
the portuguese locale, you must run
setenv LANG pt
in csh or
export LANG; LANG=pt
in Bourne sh and similars
Note: If you have the LC_CTYPE environment variable set, you must
unset it before running wmaker.
For menu definition files, WindowMaker searches for them in the
following order (for brazilian portuguese, in this case):
menu.pt_BR
menu.pt
menu
5 - If you chose a language that uses multi-byte characters, you must
configure the fonts appropriately. Read the manual page for XCreateFontSet
to have more details about it. You must change the ~/G/D/WindowMaker file
for fonts used in titlebars, menus and other things. For fonts used in
dialog windows, change ~/G/D/WMGLOBAL. Note that at the moment you can only
supply a single font in WMGLOBAL. The %d in the font names must not be
removed.
For example, you can specify the following in ~/G/D/WindowMaker:
WindowTitleFont = "-*-helvetica-bold-r-normal-*-12-*,-*-*-medium-r-normal-*-14-*";
MenuTitleFont = "-*-helvetica-bold-r-normal-*-12-*,-*-*-medium-r-normal-*-14-*";
MenuTextFont = "-*-helvetica-medium-r-normal-*-12-*,-*-*-medium-r-normal-*-14-*";
IconTitleFont = "-*-helvetica-medium-r-normal-*-8-*,-*-*-medium-r-normal-*-12-*";
ClipTitleFont = "-*-helvetica-bold-r-normal-*-10-*,-*-*-medium-r-normal-*-12-*";
DisplayFont = "-*-helvetica-medium-r-normal-*-12-*,-*-*-medium-r-normal-*-12-*";
and in ~/G/D/WMGLOBAL:
SystemFont = "-*-*-medium-r-normal-*-%d-*-*-*-*-*-*-*";
BoldSystemFont = "-*-*-medium-r-normal-*-%d-*-*-*-*-*-*-*";

210
Install Executable file
View File

@@ -0,0 +1,210 @@
#!/bin/sh
#
# WindowMaker configuration and compilation script.
#
# Copyright (c) 1997, 1998 Alfredo K. Kojima
#
export LINGUAS;LINGUAS=""
if test "$NLSDIR" = ""; then
export NLSDIR;NLSDIR="/usr/lib/locale"
fi
OPTIONS=""
PREFIX="/usr/local"
perai() {
echo "Type <Return> to continue"
read nada
}
echo
echo "========================"
echo "WindowMaker Installation"
echo "========================"
echo
echo "NOTE: If the installation procedure fails, read the INSTALL file and do"
echo "the installation manually."
perai
if test "$USER" != "root"; then
echo "Warning: you must run this script as the root user."
perai
echo
echo "Be sure to specify an installation path where you have"
echo "write persmission."
echo
fi
echo
echo "Option Selection"
echo "================"
######################## Sound
echo
echo "Do you want sound support? Note that you need a module distributed"
echo "separately to make it work. You can get it at:"
echo "http://www.frontiernet.net/~southgat/wmsound"
echo -n "<y/n> [y] "
read SFX
if [ "x$SFX" = "x" -o "$SFX" = "y" -o "$SFX" = "Y" ]; then
OPTIONS="$OPTIONS --enable-sound"
fi
######################## NLS
echo
echo "Do you want National Language Support?"
echo -n "<y/n> [n] "
read NLS
if [ "$NLS" = "y" -o "$NLS" = "Y" ]; then
NLS="Y"
echo "The supported locales are:"
ling=` (cd po; /bin/ls *.po) `
ALL_LINGUAS=""
for l in $ling; do
lname=`(cd po; grep Language-Team $l|cut -f 2 -d: |cut -f 2 -d\ )`
lname=`echo $lname`
lcode=`basename $l .po`
ALL_LINGUAS="$ALL_LINGUAS $lcode"
echo "$lcode $lname"
done
echo "Type in the locales you want [$ALL_LINGUAS]"
read foo
if test "x$foo" = "x"; then
LINGUAS=$ALL_LINGUAS
else
LINGUAS="$foo"
fi
echo "Selected locales are: $LINGUAS"
MB=""
for i in $LINGUAS; do
ok=0
for b in $ALL_LINGUAS; do
if test "$b" = "$i"; then
ok=1
break
fi
done
if test "$ok" = "0"; then
echo
echo "$i is not a supported locale"
perai
continue
fi
if [ "$MB" = "" -a "$i" = "ja" -o "$i" = "kr" ]; then
echo
echo "A language you selected needs multi-byte character support"
echo "Do you want to enable it?"
echo -n "<y/n> [n] "
read MB
if [ "$MB" = "y" -o "$MB" = "Y" ]; then
OPTIONS="$OPTIONS --enable-kanji"
fi
fi
done
echo
echo "Where do you want to put the message files? [$NLSDIR]"
echo -n "? "
read foo
if test "x$foo" != "x"; then
NLSDIR=$foo
fi
fi
##################### Installation path
done=0
while [ $done = 0 ]; do
echo
echo "Where do you want to install WindowMaker? [$PREFIX]"
echo "Don't change it if you don't know what you're doing."
echo "(The default path will install WindowMaker in "
echo "$PREFIX/bin, $PREFIX/lib etc.)"
echo -n "? "
read foo
if test "x$foo" != "x"; then
if [ "$foo" = "y" -o "$foo" = "n" ]; then
echo
echo "Hmm... I don't think you really want to install WindowMaker into \"$foo\""
echo
else
done=1
PREFIX=$foo
fi
else
done=1
fi
echo
echo "$PREFIX/bin must be in the PATH environment variable of all users who use WindowMaker"
perai
done
OPTIONS="$OPTIONS --prefix=$PREFIX"
###################### Build libPropList
if [ ! -d libPropList ]; then
gzip -d -c libPropList.tar.gz | tar xf -
fi
echo "-----------------------"
echo "Building libPropList..."
echo "-----------------------"
cd libPropList
if [ ! -f config.status ]; then
./configure
fi
make
cd ..
if [ ! -f libPropList/libPropList.a ]; then
echo "Build of libPropList was not successfull. "
exit
fi
##################### Configure
echo "--------------------------"
echo "Configuring WindowMaker..."
echo "--------------------------"
if [ `uname -s` = "SCO_SV" ]; then
echo "CFLAGS=\"$CFLAGS -belf -DANSICPP\" ./configure $OPTIONS"
CFLAGS="$CFLAGS -belf -DANSICPP" ./configure $OPTIONS
else
echo "CFLAGS=\"$CFLAGS $GCCFLAGS\" ./configure $OPTIONS"
CFLAGS="$CFLAGS $GCCFLAGS" ./configure $OPTIONS
fi
#################### Compile
echo "------------------------"
echo "Compiling WindowMaker..."
echo "------------------------"
(cd src; make clean)
make
echo "-------------------------"
echo "Installing WindowMaker..."
echo "-------------------------"
make install
echo
echo "Installation Finished!"
echo
echo "Now, each user that wishes to use WindowMaker must run the wmaker.inst"
echo "script that was just installed."
if test "$NLS" = "Y"; then
echo "Don't forget to set the LANG environment variable to your locale"
fi

54
MIRRORS Normal file
View File

@@ -0,0 +1,54 @@
WindowMaker FTP Mirror Sites
============================
Official Site (USA):
--------------------
ftp://ftp.windowmaker.org/
Australia:
----------
ftp://ftp.goldweb.com.au/pub/WindowMaker/
Contact: Matthew Hawkins <matt@goldweb.com.au>
France:
-------
ftp://ftp.ensm-ales.fr/pub/mirrors/ftp.windowmaker.org
Contact: Laurent PELLISSIER <Laurent.Pellissier@ensm-ales.fr>
Germany:
--------
ftp://ftp.freenews.de/pub/windowmaker/
Contact: Jonas Luster <jonas@cabal.arnooo.de>
United States of America:
-------------------------
ftp://ftp.io.com/pub/mirror/windowmaker/
Contact: Bobby <bobby@mezaway.org>
http://jgo.local.net/cool_downloads/wm/
Contact: Joshua Go <joshuago@usa.net>
ftp://ftp.cybertrails.com/pub/windowmaker/
Contact: Adam Jacob <adam@cybertrails.com>
Third Party WindowMaker Distribution Packages
=============================================
RedHat/RPM
----------
Contact: Jim Knoble <jmknoble@pobox.com>
Sites:
ftp://ftp.windowmaker.org/pub/beta/compiled/linux/rpms/
ftp://ftp.redhat.com/pub/contrib/SRPMS/
ftp://ftp.redhat.com/pub/contrib/i386/

14
Makefile.am Normal file
View File

@@ -0,0 +1,14 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = wrlib WINGs src util po WindowMaker wmlib test WPrefs.app doc
EXTRA_DIST = TODO BUGS BUGFORM FAQ FAQ.I18N MIRRORS Install acconfig.h\
libPropList.tar.gz mkpatch
libPropList.tar.gz:
-(cd libPropList; $(MAKE) distclean)
-rm -f libPropList.tar.gz
tar cf libPropList.tar libPropList
gzip -9 libPropList.tar

322
Makefile.in Normal file
View File

@@ -0,0 +1,322 @@
# Makefile.in generated automatically by automake 1.3 from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLIBS = @GFXLIBS@
I18N = @I18N@
I18N_MB = @I18N_MB@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LIBPL_INC_PATH = @LIBPL_INC_PATH@
LIBPL_LIBS = @LIBPL_LIBS@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@
NLSDIR = @NLSDIR@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
REDUCE_APPICONS = @REDUCE_APPICONS@
SHAPE = @SHAPE@
SOUND = @SOUND@
VERSION = @VERSION@
WPMOFILES = @WPMOFILES@
XCFLAGS = @XCFLAGS@
XGETTEXT = @XGETTEXT@
XLFLAGS = @XLFLAGS@
XLIBS = @XLIBS@
XSHM = @XSHM@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LOCALE = @X_LOCALE@
pixmapdir = @pixmapdir@
wprefsdir = @wprefsdir@
SUBDIRS = wrlib WINGs src util po WindowMaker wmlib test WPrefs.app doc
EXTRA_DIST = TODO BUGS BUGFORM FAQ FAQ.I18N MIRRORS Install acconfig.h\
libPropList.tar.gz mkpatch
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ./src/config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
Makefile.in NEWS TODO aclocal.m4 config.guess config.sub configure \
configure.in install-sh missing mkinstalldirs
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
all: all-recursive all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
list='$(SUBDIRS)'; for subdir in $$list; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
done; \
for subdir in $$rev; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
(cd $$subdir && $(MAKE) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) \
&& $(MAKE) dvi \
&& $(MAKE) check \
&& $(MAKE) install \
&& $(MAKE) installcheck \
&& $(MAKE) dist
-rm -rf $(distdir)
@echo "========================"; \
echo "$(distdir).tar.gz is ready for distribution"; \
echo "========================"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
@for file in $(DISTFILES); do \
d=$(srcdir); \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file; \
done
for subdir in $(SUBDIRS); do \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
done
info: info-recursive
dvi: dvi-recursive
check: all-am
$(MAKE) check-recursive
installcheck: installcheck-recursive
all-am: Makefile
install-exec: install-exec-recursive
@$(NORMAL_INSTALL)
install-data: install-data-recursive
@$(NORMAL_INSTALL)
install: install-recursive
@:
uninstall: uninstall-recursive
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs: installdirs-recursive
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(DISTCLEANFILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean-am: mostlyclean-tags mostlyclean-generic
clean-am: clean-tags clean-generic mostlyclean-am
distclean-am: distclean-tags distclean-generic clean-am
maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
distclean-am
mostlyclean: mostlyclean-recursive mostlyclean-am
clean: clean-recursive clean-am
distclean: distclean-recursive distclean-am
-rm -f config.status
maintainer-clean: maintainer-clean-recursive maintainer-clean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
-rm -f config.status
.PHONY: install-data-recursive uninstall-data-recursive \
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
uninstalldirs-recursive all-recursive check-recursive \
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info dvi \
installcheck all-am install-exec install-data install uninstall all \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
libPropList.tar.gz:
-(cd libPropList; $(MAKE) distclean)
-rm -f libPropList.tar.gz
tar cf libPropList.tar libPropList
gzip -9 libPropList.tar
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

1385
NEWS Normal file

File diff suppressed because it is too large Load Diff

194
README Normal file
View File

@@ -0,0 +1,194 @@
WindowMaker X11 Window Manager
<http://windowmaker.org>
<ftp://ftp.windowmaker.org>
Alfredo K. Kojima
<kojima@windowmaker.org>
Dan Pascu
<dan@windowmaker.org>
Matthew Hawkins
<matt@windowmaker.org>
Description
===========
WindowMaker is a window manager designed to emulate the look and feel of
part of the NEXTSTEP(tm) GUI. It's supposed to be relatively fast and small,
feature rich, easy to configure and easy to use, with a simple and elegant
appearance borrowed from NEXTSTEP(tm).
User Guide
==========
The WindowMaker User's Guide can be downloaded from the official ftp
or web sites.
It can also be viewed in HTML format in:
http://people.delphi.com/crc3419/WMUserGuide/index.htm
Directories & Files
===================
o INSTALL contains installation instructions and some troubleshooting tips.
o Install is a script for configuring and compiling WindowMaker in a easy
way.
o ChangeLog contains the changes since the last version
o BUGS contains a list of the currently known bugs
o FAQ is a list of frequently asked questions. Read it. I won't answer
questions answered in it.
o NEWS is a list of user visible changes since the last version. Read it if
you are upgrading.
o wmlib/ contains the library necessary to write applications that use
WindowMaker specific features, like application defined menus. This library
will be merged into WINGs in the future.
o WINGs/ contain the WINGs (WINGs Is Not GNUstep) tiny widget library. It is
used by wmaker, but can be used by standalone programs as well.
o test/ contains a simple test program that shows some of the things that can
be done with WindowMaker and wmlib
o wrlib/ contains the library used to do image manipulation (loading,
dithering etc.) in WindowMaker. It can be used in other applications.
o util/ contains various utility programs.
o WPrefs/ contains the source code for the WindowMaker Preferences utility.
Read the WPrefs/README file before using it.
o Configuration options can be found in the ~/GNUstep/Defaults/* files
(after installation). The menus can be configured in
~/GNUstep/Library/WindowMaker/menu
o The default configuration files for the system are installed by default in
/usr/local/share/WindowMaker, along with some other data files.
o src/wconfig.h contains various compile time options you can change to
select some options/features and things like the path for configuration
directory.
o BUGFORM is a form you should fill to send a bugreport. Please use the
form. It makes things easier to me and ensures that you give me a reasonable
amount of information. This form should be sent to developers@windowmaker.org
Mailing List
============
There is a mailing list for discussing WindowMaker at
wmaker@linuxcenter.com To subscribe to it, send a message containing:
subscribe
in the subject and the body of the message to wmaker-request@linuxcenter.com
If you have some problem installing or using wmaker, it would be advisable
to ask in the mailing list, as the probability of at least one of the 500+
users there having the same problem as you (and solving it) is bigger than
the three of us. The developers are subscribed to the mailing list, so we
will read your post anyway (no need for cc:). For bug reports, fill
the BUGFORM and send it to developers@windowmaker.org You can also use
the bug tracker page at http://windowmaker.org/cgi-bin/bugs
Important note: when asking for help (in the mailing list or to the
developerts, directly) always send information about the system you are
using. You can use the system information section at the end of BUGFORM
as a guideline. Another thing: please don't send HTML mail. You will
be risking having your mail deleted before being read. Not everybody
uses a browser to read email, wich makes your message an annoyance.
There should be an option in your mail app to disable it.
Running multiple instances of WindowMaker
=========================================
It is not a good idea to run more than one instance of WindowMaker
from the same user (so that wmaker will use the same configuration
files) at the same time. You might get unexpected behaviour when WindowMaker
updates it's configuration files.
Sound support
=============
Sound is supported for Linux and FreeBSD systems with the use of a
separately distributed module. You can download it at:
http://www.frontiernet.net/~southgat/wmsound
Note that you must compile WindowMaker with the --enable-sound configure
flag and set the DisableSound option to NO.
Performance Tuning
==================
If you want to diminish WindowMaker's memory usage and improve performance,
while keeping a nice appearance and good functionality, follow the items
bellow:
- use solid textures for everything, mainly titlebars and menus. If you
want a nice looking desktop, use the Traditional style.
- turn NewStyle and Superfluous off
- turn on DisableAnimations
- do not bind many shortcuts in the menu and keep only the essential items
in the menu
- turn on DisableClip
- edit wconfig.h and disable the NUMLOCK_HACK and the features you
don't use anyway (keep in mind that some of the #defines might not
work, as they are not fully supported). Make sure to always keep
NumLock and ScrollLock turned off.
- strip down the default IconPath and PixmapPath entries to contain only
the paths that you really have in your system.
- do not use large images in the root background
- remove support for image formats you don't use
Copyrights
==========
WindowMaker is copyrighted by Alfredo K. Kojima and is licensed through the
GNU General Public License. Read the COPYING file for the complete license.
NeXT, OpenStep and NEXTSTEP are a trademarks of NeXT Computer, Inc.
Authors
=======
The AUTHORS file contains a list of the people who have contributed to the
project. The name of people who have helped with localization (translation)
can be found in po/README and WindowMaker/README
If you have any comments, fixes and bug reports (filled BUGFORMs) send them
to kojima@windowmaker.org
Musicware
=========
If you use WindowMaker and *really* like it, please consider making my day
by sending me a music CD (or a MiniDisc) of your favorite band, singer,
instrumentist, composer or whatever :^). I like listening to music and would
love to get new CDs, especially from other parts of the world. I like almost
any kind of music, from Ozzy Osbourne to Bach (mas n<>o pagode e sertanejo
pelamordideus :), so I will be happy to receive just about anything.
Snail mail address:
Alfredo Kengi Kojima
Rua Firmino O. Bimbi, 255/25B
Porto Alegre - RS
CEP 91751-330
Brazil

50
TODO Normal file
View File

@@ -0,0 +1,50 @@
Do ASAP:
========
- fix bestvisual selection code. Broken.
- add a dialog to let user choose if we should restart, restart twm or continue crashing on crash. Do not forget to check if wmaker is already fully running.
- fix stacking. buggy again
+ ICCCM compliant stuff: find what is missing
- WM_COLORMAP_NOTIFY clientmessage
- fix RemakeStackList() to account for transient windows
- change CommitStacking() on AddToStackingList() to more optimized thing
- differential update of appmenu
- make unhide app map windows in the same stacking order they were before
hiding
Need to do:
===========
- rewrite all redundant stuff to use WINGs
- resizebartexture option
- add function to directly make a thumbnail of an image, using the
functionality provided by the image libraries to load a minimal
amount of data.
- clickonclientarearaisewindow
- edge resistance (with timer)
- save client supplied icons in ~/GNUstep/.AppInfo/ClientIcons/ and
use them by default
- GNUstepWMAttributes update in propertynotify
+ investigate memory leaks
- make Docked apps with WM_CLIENT_MACHINE be launched from respective
machines (also put a marking showing it's remote launched)
- handle change of CLIENT_LEADER property
- rewrite defaults/wdefaults stuff to use WINGs UD stuff. Search list:
~/G/D/WindowMaker /u/l/s/W/D/WindowMaker built-in-defaults
- remake internal string processing to use wc?
- -statefile cmd arg to specify path for WMState file (multiple instance
support)
Maybe some day:
===============
- virtual desktop
- optimize for size
- make dithering in 8bpp better
Never: (so, dont even bother to ask)
======
- different themes for each workspace. Unless you give us a SGI/Power Onyx
with 2 CPUs ;). Different workspacebacks for each workspace is being
considered, but don't hold your breath.
- anything that requires the mouse pointer to be jumped by WindowMaker to
somewhere. This is *terrible* behaviour. And it's not just IMO.

96
WINGs/ChangeLog Normal file
View File

@@ -0,0 +1,96 @@
changes since wmaker 0.20.0:
............................
- changed WMGetFilePanelFile() with WMGetFilePanelFileName()
- made SavePanel
changes since wmaker 0.19.3:
............................
- added WMCreatePanelForWindow()
- added extra parent parameter for filepanel, alertpanel and inputpanel
- WMCloseWindow()
- WMChangePanelOwner()
- added WMAddInputHandler()
- change range related function arguments (WMTextField) to use WMRange
changes since wmaker 0.19.1:
............................
- added wstrappend()
- fixed bug when changing selected radio button by hand
changes since wmaker 0.18.1:
............................
- removed textHeight arg from W_PaintImageAndText
- added WMCreateWindowWithStyle()
- added WMSetWindowBaseSize() and ResizeIncrements()
- added WMSetWindowLeve()
- added WMSetWindowDocumentEdited()
- added WMSetScrollViewLineScroll(), WMSetScrollViewPageScroll()
- added WMSetWindowMiniwindowTitle()
- added WMSetWindowMiniwindowImage()
changes since wmaker 0.18.0:
............................
- added functions to get RGB components and "#rrggbb" string from WMColor.
- added function to create color from a name
- fixed bug that caused blocking until some new event arrives, even
when there already were events in the queue
(like having to move the pointer over window to force the window to be
painted)
changes since wmaker 0.17.5:
............................
I don't remember everything, but here it goes:
- fixed some bugs in text field
- added a incomplete implementation of split view (not yet usable)
- added a slider
- changed the filepanel stuff. Each application can have only 1 file panel.
The same panel will be reused every time you call for it, unless you free it.
- changed semantics of WMCreateFont() so that it returns NULL if the requested
font can't be loaded
- removed WMAddDestroyCallback()
- fixed bug in WMRemovePopUpButtonItem()
- added function for user specified item height in WMList
- added WMSetPopUpButtonText(). It will set the default text in the button
when no options are selected
- fixed bug in remove/add item in already mapped popupbuttons. Note: it is
not good practice to change the contents of a popup button when it's
already visible and the user has probably interacted with it.
- fixed behaviour of "radio buttons"
- WMInitializeApplication() must be the first function to be called in the
program
- removed applicationName, argc and argv arguments from the WMCreateScree...
functions
- WMReleaseColor(scr,color) changed to WMReleaseColor(color)
- WMPaintColorRectangle() changed to WMPaintColorSwatch()
- added various functions in font and color handling
- added WMSetButtonFont()
- changed WMCreateCommandButton() so that the buttons it creates will change
their label when pushed
- added WMGetSystemPixmap(WMScreen *scr, int image)
- added partial I18N support
- added libPropList requirement and some related utility functions
- added a interface to prooplist, so that it works as a user defaults db
- added WMWidthOfString() (removed WMFontWidthOfString())
- added WMDrawString()
- added WMSetTextFieldSecure(WMTextField *tPtr, Bool flag)
- WMGetListItem() will dup the returned string
- removed need for ProgName being defined
- rewrote hashtable stuff and made it available for outside use
- added notification functions, with view resize notification
- added WMSetWindowMinSize() and MaxSize()
- text editing notification
- added WMSetListPosition() etc.
- added WMInsertBrowserItem()
- the above 2 functions return WMListItem*, instead of Bool
- rewrote browser
- WMGetListItem() will return WMListItem*
- removed WMGetListItems() and WMSetListItems()
- fixed focus stuff for multi-window apps
- changed all WMList function names that contained index to row

90
WINGs/Makefile.am Normal file
View File

@@ -0,0 +1,90 @@
## automake input file for WINGs
AUTOMAKE_OPTIONS = no-dependencies
SUBDIRS = Resources
LIBLIST= -L$(top_builddir)/wrlib -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ \
-lm @LIBPL_LIBS@
lib_LIBRARIES = libWINGs.a
include_HEADERS = WINGs.h WUtil.h WINGsP.h
noinst_PROGRAMS = wtest wmquery wmfile fontl testmywidget
testmywidget_SOURCES = testmywidget.c mywidget.c mywidget.h
testmywidget_LDADD = -L. -lWINGs $(LIBLIST)
fontl_SOURCES = fontl.c
fontl_LDADD = -L. -lWINGs $(LIBLIST)
wtest_SOURCES = wtest.c
wtest_LDADD = -L. -lWINGs $(LIBLIST)
wtest_DEPENDENCIES = libWINGs.a
wmfile_SOURCES = wmfile.c
wmfile_LDADD = -L. -lWINGs $(LIBLIST)
wmquery_SOURCES = wmquery.c
wmquery_LDADD = -L. -lWINGs $(LIBLIST)
EXTRA_DIST = logo.xpm
# wbutton.c
libWINGs_a_SOURCES = \
WINGs.h \
WINGsP.h \
configuration.c \
international.c \
notification.c \
selection.c \
userdefaults.c \
wapplication.c \
wbrowser.c \
wbutton.c \
wcolor.c \
wcolorwell.c \
wevent.c \
wfilepanel.c \
wframe.c \
wfont.c \
wfontpanel.c \
widgets.c \
wlabel.c \
wlist.c \
wmisc.c \
wpanel.c \
wpixmap.c \
wpopupbutton.c \
wscroller.c \
wscrollview.c \
wslider.c \
wsplitview.c \
wtextfield.c \
wwindow.c \
wview.c \
error.c \
findfile.c \
hashtable.c \
memory.c \
usleep.c
##
## Find a better way than $(GFXFLAGS) to inform widgets.c wich of
## tiff or xpm images should be used
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src @XCFLAGS@ \
-DRESOURCE_PATH=\"$(datadir)/WINGs\" $(GFXFLAGS) -DDEBUG \
@LIBPL_INC_PATH@

513
WINGs/Makefile.in Normal file
View File

@@ -0,0 +1,513 @@
# Makefile.in generated automatically by automake 1.3 from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLIBS = @GFXLIBS@
I18N = @I18N@
I18N_MB = @I18N_MB@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LIBPL_INC_PATH = @LIBPL_INC_PATH@
LIBPL_LIBS = @LIBPL_LIBS@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@
NLSDIR = @NLSDIR@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
REDUCE_APPICONS = @REDUCE_APPICONS@
SHAPE = @SHAPE@
SOUND = @SOUND@
VERSION = @VERSION@
WPMOFILES = @WPMOFILES@
XCFLAGS = @XCFLAGS@
XGETTEXT = @XGETTEXT@
XLFLAGS = @XLFLAGS@
XLIBS = @XLIBS@
XSHM = @XSHM@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LOCALE = @X_LOCALE@
pixmapdir = @pixmapdir@
wprefsdir = @wprefsdir@
AUTOMAKE_OPTIONS = no-dependencies
SUBDIRS = Resources
LIBLIST= -L$(top_builddir)/wrlib -lwraster @XLFLAGS@ @GFXLIBS@ @XLIBS@ \
-lm @LIBPL_LIBS@
lib_LIBRARIES = libWINGs.a
include_HEADERS = WINGs.h WUtil.h WINGsP.h
noinst_PROGRAMS = wtest wmquery wmfile fontl testmywidget
testmywidget_SOURCES = testmywidget.c mywidget.c mywidget.h
testmywidget_LDADD = -L. -lWINGs $(LIBLIST)
fontl_SOURCES = fontl.c
fontl_LDADD = -L. -lWINGs $(LIBLIST)
wtest_SOURCES = wtest.c
wtest_LDADD = -L. -lWINGs $(LIBLIST)
wtest_DEPENDENCIES = libWINGs.a
wmfile_SOURCES = wmfile.c
wmfile_LDADD = -L. -lWINGs $(LIBLIST)
wmquery_SOURCES = wmquery.c
wmquery_LDADD = -L. -lWINGs $(LIBLIST)
EXTRA_DIST = logo.xpm
# wbutton.c
libWINGs_a_SOURCES = \
WINGs.h \
WINGsP.h \
configuration.c \
international.c \
notification.c \
selection.c \
userdefaults.c \
wapplication.c \
wbrowser.c \
wbutton.c \
wcolor.c \
wcolorwell.c \
wevent.c \
wfilepanel.c \
wframe.c \
wfont.c \
wfontpanel.c \
widgets.c \
wlabel.c \
wlist.c \
wmisc.c \
wpanel.c \
wpixmap.c \
wpopupbutton.c \
wscroller.c \
wscrollview.c \
wslider.c \
wsplitview.c \
wtextfield.c \
wwindow.c \
wview.c \
error.c \
findfile.c \
hashtable.c \
memory.c \
usleep.c
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src @XCFLAGS@ \
-DRESOURCE_PATH=\"$(datadir)/WINGs\" $(GFXFLAGS) -DDEBUG \
@LIBPL_INC_PATH@
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../src/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(lib_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir) -I../src
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
libWINGs_a_LIBADD =
libWINGs_a_OBJECTS = configuration.o international.o notification.o \
selection.o userdefaults.o wapplication.o wbrowser.o wbutton.o wcolor.o \
wcolorwell.o wevent.o wfilepanel.o wframe.o wfont.o wfontpanel.o \
widgets.o wlabel.o wlist.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o \
wscroller.o wscrollview.o wslider.o wsplitview.o wtextfield.o wwindow.o \
wview.o error.o findfile.o hashtable.o memory.o usleep.o
AR = ar
PROGRAMS = $(noinst_PROGRAMS)
wtest_OBJECTS = wtest.o
wtest_LDFLAGS =
wmquery_OBJECTS = wmquery.o
wmquery_DEPENDENCIES =
wmquery_LDFLAGS =
wmfile_OBJECTS = wmfile.o
wmfile_DEPENDENCIES =
wmfile_LDFLAGS =
fontl_OBJECTS = fontl.o
fontl_DEPENDENCIES =
fontl_LDFLAGS =
testmywidget_OBJECTS = testmywidget.o mywidget.o
testmywidget_DEPENDENCIES =
testmywidget_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
HEADERS = $(include_HEADERS)
DIST_COMMON = README ChangeLog Makefile.am Makefile.in TODO
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
SOURCES = $(libWINGs_a_SOURCES) $(wtest_SOURCES) $(wmquery_SOURCES) $(wmfile_SOURCES) $(fontl_SOURCES) $(testmywidget_SOURCES)
OBJECTS = $(libWINGs_a_OBJECTS) $(wtest_OBJECTS) $(wmquery_OBJECTS) $(wmfile_OBJECTS) $(fontl_OBJECTS) $(testmywidget_OBJECTS)
all: all-recursive all-am
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu WINGs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-libLIBRARIES:
clean-libLIBRARIES:
-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
distclean-libLIBRARIES:
maintainer-clean-libLIBRARIES:
install-libLIBRARIES: $(lib_LIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libdir)
list='$(lib_LIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
else :; fi; \
done
@$(POST_INSTALL)
@list='$(lib_LIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \
$(RANLIB) $(DESTDIR)$(libdir)/$$p; \
else :; fi; \
done
uninstall-libLIBRARIES:
@$(NORMAL_UNINSTALL)
list='$(lib_LIBRARIES)'; for p in $$list; do \
rm -f $(DESTDIR)$(libdir)/$$p; \
done
.c.o:
$(COMPILE) -c $<
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
libWINGs.a: $(libWINGs_a_OBJECTS) $(libWINGs_a_DEPENDENCIES)
-rm -f libWINGs.a
$(AR) cru libWINGs.a $(libWINGs_a_OBJECTS) $(libWINGs_a_LIBADD)
$(RANLIB) libWINGs.a
mostlyclean-noinstPROGRAMS:
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
distclean-noinstPROGRAMS:
maintainer-clean-noinstPROGRAMS:
wtest: $(wtest_OBJECTS) $(wtest_DEPENDENCIES)
@rm -f wtest
$(LINK) $(wtest_LDFLAGS) $(wtest_OBJECTS) $(wtest_LDADD) $(LIBS)
wmquery: $(wmquery_OBJECTS) $(wmquery_DEPENDENCIES)
@rm -f wmquery
$(LINK) $(wmquery_LDFLAGS) $(wmquery_OBJECTS) $(wmquery_LDADD) $(LIBS)
wmfile: $(wmfile_OBJECTS) $(wmfile_DEPENDENCIES)
@rm -f wmfile
$(LINK) $(wmfile_LDFLAGS) $(wmfile_OBJECTS) $(wmfile_LDADD) $(LIBS)
fontl: $(fontl_OBJECTS) $(fontl_DEPENDENCIES)
@rm -f fontl
$(LINK) $(fontl_LDFLAGS) $(fontl_OBJECTS) $(fontl_LDADD) $(LIBS)
testmywidget: $(testmywidget_OBJECTS) $(testmywidget_DEPENDENCIES)
@rm -f testmywidget
$(LINK) $(testmywidget_LDFLAGS) $(testmywidget_OBJECTS) $(testmywidget_LDADD) $(LIBS)
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(includedir)
@list='$(include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
$(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
list='$(include_HEADERS)'; for p in $$list; do \
rm -f $(DESTDIR)$(includedir)/$$p; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
list='$(SUBDIRS)'; for subdir in $$list; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
done; \
for subdir in $$rev; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
(cd $$subdir && $(MAKE) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = WINGs
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file; \
done
for subdir in $(SUBDIRS); do \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
done
info: info-recursive
dvi: dvi-recursive
check: all-am
$(MAKE) check-recursive
installcheck: installcheck-recursive
all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS)
install-exec-am: install-libLIBRARIES
install-data-am: install-includeHEADERS
uninstall-am: uninstall-libLIBRARIES uninstall-includeHEADERS
install-exec: install-exec-recursive install-exec-am
@$(NORMAL_INSTALL)
install-data: install-data-recursive install-data-am
@$(NORMAL_INSTALL)
install: install-recursive install-exec-am install-data-am
@:
uninstall: uninstall-recursive uninstall-am
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs: installdirs-recursive
$(mkinstalldirs) $(DATADIR)$(libdir) $(DATADIR)$(includedir)
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(DISTCLEANFILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean-am: mostlyclean-libLIBRARIES mostlyclean-compile \
mostlyclean-noinstPROGRAMS mostlyclean-tags \
mostlyclean-generic
clean-am: clean-libLIBRARIES clean-compile clean-noinstPROGRAMS \
clean-tags clean-generic mostlyclean-am
distclean-am: distclean-libLIBRARIES distclean-compile \
distclean-noinstPROGRAMS distclean-tags \
distclean-generic clean-am
maintainer-clean-am: maintainer-clean-libLIBRARIES \
maintainer-clean-compile \
maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
maintainer-clean-generic distclean-am
mostlyclean: mostlyclean-recursive mostlyclean-am
clean: clean-recursive clean-am
distclean: distclean-recursive distclean-am
-rm -f config.status
maintainer-clean: maintainer-clean-recursive maintainer-clean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
.PHONY: mostlyclean-libLIBRARIES distclean-libLIBRARIES \
clean-libLIBRARIES maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \
install-libLIBRARIES mostlyclean-compile distclean-compile \
clean-compile maintainer-clean-compile mostlyclean-noinstPROGRAMS \
distclean-noinstPROGRAMS clean-noinstPROGRAMS \
maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \
install-includeHEADERS install-data-recursive uninstall-data-recursive \
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
uninstalldirs-recursive all-recursive check-recursive \
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info dvi \
installcheck all-am install-exec-am install-data-am uninstall-am \
install-exec install-data install uninstall all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

102
WINGs/README Normal file
View File

@@ -0,0 +1,102 @@
WINGs - WINGs Is Not GNUstep
by
Alfredo Kengi Kojima
kojima@windowmaker.org
WINGs is a small widget set with the N*XTSTEP look and feel. It's API
is inspired in OpenStep and it's implementation borrows some ideas
from Tk. It has a reasonable set of widgets, sufficient for building
small applications (like a CDPlayer or hacking something like rxvt). It
also has other functions that are usefull for applications, like a
User Defaults like configuration manager and a notification system.
The library is limited and it's design is a little sloppy,
so it's not intended to build large or complex applications, like
anything more complex than a CDPlayer. GNUstep should be used for such
applications.
Since WINGs is written in C and is sort of low-level it is small
and faster than say, Motif or even Athena. Knowing Xlib will help you to
workaround some of it's limitations, although you'll probably be able to
write something like a trivial tic-tac-toe game without knowing much Xlib.
Some of it's functions are designed to support the WindowMaker window
manager (see http://windowmaker.org) In fact, it's primary role is to
support WindowMaker. All other uses of it are just an added bonus.
It will help you to understand the API if you read the ApplicationKit
reference manual, distributed as a PDF by Apple. The function names,
structs and most of the intrinsics are very close to OpenStep classes.
Internationalization:
---------------------
WINGs supports display of multibyte characters (kanji etc) without the
to specify any flags (ie: there is no way to disable i18n support).
Change ~/GNUstep/Defaults/WMGLOBAL to set the desired font set.
Widgets provided by WINGs:
--------------------------
- button (command button, radio, switch etc. - all buttons defined in OpenStep)
- label
- textfield
- frame
- window
- popup menu button
- scroller
- selection list
- browser
- slider
- scrollable view
- color well
- split view (only 2 subviews)
- input box
- file panel
- alert panel
Planned:
--------
- selection (pasteboard like)
- drag&drop
If you think you can code the following, please do. They are needed by
WPrefs.app, but the number of other things I have to do is huge.
- color panel
- font panel (the UI part is done. Might require a rewrite of the font list
retrievel code. Might also require a WMFontManager)
- input method support (XIM). I have no idea of how to code it. People who use
different characters than ASCII will have trouble editing menus without it...
Wish list: (I don't have the know-how or time to do them)
---------------------------------------------------------
- text (with support for RTF)
- matrix (like NSMatrix)
- splitviews with more than 2 subviews
- font manager (like NSFontManager)
- finish file panel, open/save
- finish other wigets
- optimize list scrolling (XCopyArea() the area that's already drawn)
- InterfaceMaker?
- use XSetWMName and XSetWMIconName for the window/icon title setting.
This requires transforming the received text to a text property with
the proper encoding.
Copyright
---------
WINGs is copyright (c) Alfredo K. Kojima and is licensed through the GNU
Library General Public License (LGPL).

BIN
WINGs/Resources/Images.tiff Normal file

Binary file not shown.

BIN
WINGs/Resources/Images.xcf Normal file

Binary file not shown.

236
WINGs/Resources/Images.xpm Normal file
View File

@@ -0,0 +1,236 @@
/* XPM */
static char * image_name[] = {
"128 128 105 2",
" c None",
". c #000000000000",
"X c #10400C301040",
"o c #410345144103",
"O c #DF7DE38DE79D",
"+ c #18611C712081",
"@ c #28A224922081",
"# c #69A65D756185",
"$ c #38E338E338E3",
"% c #618565956185",
"& c #CF3CD34CD75C",
"* c #C71BCB2BCF3C",
"= c #208120812081",
"- c #492455555965",
"; c #9E7975D671C6",
": c #492445144103",
"> c #28A220811861",
", c #8E3892489658",
"< c #D75CDB6CDF7D",
"1 c #BEFBCB2BCF3C",
"2 c #BEFBC30BC71B",
"3 c #186114511861",
"4 c #208124922081",
"5 c #38E32CB228A2",
"6 c #61855D755144",
"7 c #4924451438E3",
"8 c #410330C228A2",
"9 c #A699AAAAAEBA",
"0 c #69A669A66185",
"q c #41033CF338E3",
"w c #69A661855965",
"e c #618559655144",
"r c #38E334D330C2",
"t c #69A661856185",
"y c #96589A699E79",
"u c #082004100820",
"i c #596555555144",
"p c #618561855965",
"a c #514451444924",
"s c #96588E388E38",
"d c #86178A288E38",
"f c #8E388A288617",
"g c #965892489658",
"h c #B6DABAEABEFB",
"j c #69A669A669A6",
"k c #51443CF338E3",
"l c #71C671C669A6",
"z c #AEBAAAAAAEBA",
"x c #AEBAB2CAB6DA",
"c c #9E79A289A699",
"v c #861782078617",
"b c #71C679E779E7",
"n c #96589E79A699",
"m c #410341034103",
"M c #492449244924",
"N c #79E782078617",
"B c #965896589658",
"V c #104008200820",
"C c #9E799E799E79",
"Z c #30C230C228A2",
"A c #596559655965",
"S c #8E388E389658",
"D c #38E33CF34103",
"F c #8617820779E7",
"G c #AEBAA6999E79",
"H c #38E33CF338E3",
"J c #79E7820779E7",
"K c #8E388E388E38",
"L c #186118611861",
"P c #20811C711861",
"I c #A699A2899E79",
"U c #E79DEBADEFBE",
"Y c #861775D669A6",
"T c #EFBEF7DEF7DE",
"R c #BEFBBEFBBEFB",
"E c #9E799A699E79",
"W c #71C675D671C6",
"Q c #186114511040",
"! c #28A22CB228A2",
"~ c #49244D344924",
"^ c #69A66DB669A6",
"/ c #965892488E38",
"( c #79E77DF78617",
") c #A699A699A699",
"_ c #79E779E771C6",
"` c #CF3CCB2BCF3C",
"' c #8E388A288E38",
"] c #79E77DF779E7",
"[ c #4103410338E3",
"{ c #30C22CB228A2",
"} c #30C228A228A2",
"| c #514455555144",
" . c #71C659655144",
".. c #492434D330C2",
"X. c #596561856185",
"o. c #69A651444924",
"O. c #514449244103",
"+. c #59655D756185",
"@. c #A6998E388617",
"#. c #49243CF338E3",
"$. c #38E324922081",
"%. c #38E32CB22081",
"&. c #104014511040",
"*. c #30C228A22081",
"=. c #28A214511040",
" ",
" . ",
" . X o O + . ",
" @ # . . X $ % & & * = . ",
" - ; = : > , < 1 1 & 2 3 . ",
" 4 X . . 5 6 7 8 * < 1 2 & 2 2 9 X . ",
" = 0 q w 0 e r t < O < & & & & & < y u . ",
" i O r p a p s , , d f g g 9 9 h < & j u . ",
". k l z g h 2 * x & O & z h * c c v b n m . ",
". M N & m 1 B g 2 & 1 & V C O Z A < 1 S = u . ",
" D F & p * c G 2 < < < r 2 O H J < 2 K L . ",
" D q * P < B I 2 U U U Y & T r , U O R = . ",
" D E < 2 & & U y W Q u ! o ~ W ^ @ Q ~ / = . ",
" o O O O < < O d * h E B ( ) y J _ A h c ~ X . ",
"m ` d h m < ' 2 ' o P v V @ Z o ~ y b J ] W = . ",
". U W 2 M O g & B 0 Q ' Q [ { } r | = | > r 4 . ",
". T { x r O b & c Y .' Q = a > a % ..v | ~ = . ",
". U 9 2 y < c x c % N , 6 X.o.O., 9 ^ a +.^ = . ",
". ] ' h 9 * h x @.h 2 h N J c | ( 2 F a , y = . ",
". ! Z w p j #.} } > } = { W $.[ r r Z ~ m %.4 . ",
" . &.= 4 = { a A r *.> =.= *.{ { { r { { Z 4 . ",
" . . . . u X Q L = 4 4 4 = = = = = = = = L . ",
" . . . . . . . . . . . . . . . . . ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};

View File

@@ -0,0 +1,6 @@
resdatadir = $(datadir)/WINGs
resdata_DATA = Images.tiff Images.xpm defaultIcon.tiff defaultIcon.xpm
EXTRA_DIST = $(resdata_DATA) Images.xcf

210
WINGs/Resources/Makefile.in Normal file
View File

@@ -0,0 +1,210 @@
# Makefile.in generated automatically by automake 1.3 from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLIBS = @GFXLIBS@
I18N = @I18N@
I18N_MB = @I18N_MB@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LIBPL_INC_PATH = @LIBPL_INC_PATH@
LIBPL_LIBS = @LIBPL_LIBS@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@
NLSDIR = @NLSDIR@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
REDUCE_APPICONS = @REDUCE_APPICONS@
SHAPE = @SHAPE@
SOUND = @SOUND@
VERSION = @VERSION@
WPMOFILES = @WPMOFILES@
XCFLAGS = @XCFLAGS@
XGETTEXT = @XGETTEXT@
XLFLAGS = @XLFLAGS@
XLIBS = @XLIBS@
XSHM = @XSHM@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LOCALE = @X_LOCALE@
pixmapdir = @pixmapdir@
wprefsdir = @wprefsdir@
resdatadir = $(datadir)/WINGs
resdata_DATA = Images.tiff Images.xpm defaultIcon.tiff defaultIcon.xpm
EXTRA_DIST = $(resdata_DATA) Images.xcf
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../src/config.h
CONFIG_CLEAN_FILES =
DATA = $(resdata_DATA)
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
all: Makefile $(DATA)
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps WINGs/Resources/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
install-resdataDATA: $(resdata_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(resdatadir)
@list='$(resdata_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(resdatadir)/$$p"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(resdatadir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(resdatadir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(resdatadir)/$$p; \
fi; fi; \
done
uninstall-resdataDATA:
@$(NORMAL_UNINSTALL)
list='$(resdata_DATA)'; for p in $$list; do \
rm -f $(DESTDIR)$(resdatadir)/$$p; \
done
tags: TAGS
TAGS:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = WINGs/Resources
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file; \
done
info:
dvi:
check: all
$(MAKE)
installcheck:
install-exec:
@$(NORMAL_INSTALL)
install-data: install-resdataDATA
@$(NORMAL_INSTALL)
install: install-exec install-data all
@:
uninstall: uninstall-resdataDATA
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs:
$(mkinstalldirs) $(DATADIR)$(resdatadir)
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(DISTCLEANFILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean: mostlyclean-generic
clean: clean-generic mostlyclean
distclean: distclean-generic clean
-rm -f config.status
maintainer-clean: maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
.PHONY: uninstall-resdataDATA install-resdataDATA tags distdir info dvi \
installcheck install-exec install-data install uninstall all \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

Binary file not shown.

View File

@@ -0,0 +1,54 @@
/* XPM */
static char * defaultIcon_xpm[] = {
"48 48 3 1",
" c #000000000000",
". c None",
"X c #FFFFFFFFFFFF",
" ..",
" ..",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
" ",
" ",
".... ",
".... "};

5
WINGs/TODO Normal file
View File

@@ -0,0 +1,5 @@
- move paint to idle handlers
- optimize color allocation for repeated colors
- make it work in 8bpp
- optimize SystemFont allocation for repeated font sizes

1004
WINGs/WINGs.h Normal file

File diff suppressed because it is too large Load Diff

394
WINGs/WINGsP.h Normal file
View File

@@ -0,0 +1,394 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "WINGs.h"
#include "WUtil.h"
#if WINGS_H_VERSION < 980922
#error There_is_an_old_WINGs.h_file_somewhere_in_your_system._Please_remove_it.
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define DOUBLE_BUFFER
#define WC_UserWidget 128
#define SCROLLER_WIDTH 20
/* internal messages */
#define WM_UPDATE_COLORWELL 130
#define WM_USER_MESSAGE 1024
#define SETUP_INTERNAL_MESSAGE(event, scrPtr) \
event.xclient.type=ClientMessage;\
event.xclient.display=scrPtr->display;\
event.xclient.send_event=False;\
event.xclient.serial=0;\
event.xclient.format=32;\
event.xclient.message_type=scrPtr->internalMessage;
typedef struct W_Font {
struct W_Screen *screen;
union {
XFontSet set;
XFontStruct *normal;
} font;
short height;
short y;
short refCount;
unsigned int notFontSet:1;
} W_Font;
typedef struct W_Pixmap {
struct W_Screen *screen;
Pixmap pixmap;
Pixmap mask;
unsigned short width;
unsigned short height;
short depth;
short refCount;
} W_Pixmap;
typedef struct W_Color {
struct W_Screen *screen;
XColor color;
short refCount;
GC gc;
struct {
unsigned int exact:1;
} flags;
} W_Color;
typedef struct W_FocusInfo {
struct W_View *toplevel;
struct W_View *focused; /* view that has the focus in this toplevel */
struct W_FocusInfo *next;
} W_FocusInfo;
typedef struct W_Screen {
Display *display;
int screen;
int depth;
Colormap colormap;
Visual *visual;
Time lastEventTime;
Window rootWin;
struct W_View *rootView;
RContext *rcontext;
/* application related */
W_FocusInfo *focusInfo;
struct W_Pixmap *applicationIcon;
struct W_Window *windowList; /* list of windows in the app */
Window groupLeader; /* the leader of the application */
/* also used for other things */
struct W_SelectionHandlers *selectionHandlerList;
struct {
unsigned int hasAppIcon:1;
unsigned int simpleApplication:1;
} aflags;
WMOpenPanel *sharedOpenPanel;
WMSavePanel *sharedSavePanel;
struct W_FontPanel *sharedFontPanel;
struct W_ColorPanel *sharedColorPanel;
/* colors */
W_Color *white;
W_Color *black;
W_Color *gray;
W_Color *darkGray;
GC stippleGC;
GC copyGC;
GC clipGC;
GC monoGC; /* GC for 1bpp visuals */
GC xorGC;
GC ixorGC; /* IncludeInferiors XOR */
GC textFieldGC;
W_Font *normalFont;
W_Font *boldFont;
struct W_Pixmap *checkButtonImageOn;
struct W_Pixmap *checkButtonImageOff;
struct W_Pixmap *radioButtonImageOn;
struct W_Pixmap *radioButtonImageOff;
struct W_Pixmap *buttonArrow;
struct W_Pixmap *pushedButtonArrow;
struct W_Pixmap *scrollerDimple;
struct W_Pixmap *upArrow;
struct W_Pixmap *downArrow;
struct W_Pixmap *leftArrow;
struct W_Pixmap *rightArrow;
struct W_Pixmap *hiUpArrow;
struct W_Pixmap *hiDownArrow;
struct W_Pixmap *hiLeftArrow;
struct W_Pixmap *hiRightArrow;
struct W_Pixmap *pullDownIndicator;
struct W_Pixmap *popUpIndicator;
struct W_Pixmap *homeIcon;
struct W_Pixmap *defaultObjectIcon;
Cursor defaultCursor;
Cursor textCursor;
Atom internalMessage; /* for ClientMessage */
Atom attribsAtom; /* GNUstepWindowAttributes */
Atom deleteWindowAtom; /* WM_DELETE_WINDOW */
Atom protocolsAtom; /* _XA_WM_PROTOCOLS */
Atom clipboardAtom; /* CLIPBOARD */
/* stuff for detecting double-clicks */
Time lastClickTime; /* time of last mousedown event */
Window lastClickWindow; /* window of the last mousedown */
struct W_View *modalView;
unsigned modal:1;
unsigned ignoreNextDoubleClick:1;
} W_Screen;
typedef struct W_View {
struct W_Screen *screen;
WMWidget *self; /* must point to the widget the
* view belongs to */
Window window;
WMSize size;
WMPoint pos;
struct W_View *nextFocusChain; /* next/prev in focus chain */
struct W_View *prevFocusChain;
struct W_View *parent; /* parent WMView */
struct W_View *childrenList; /* first in list of child windows */
struct W_View *nextSister; /* next on parent's children list */
struct W_EventHandler *handlerList;/* list of event handlers for this window */
unsigned long attribFlags;
XSetWindowAttributes attribs;
void *hangedData; /* data holder for user program */
#if 0
struct W_DragSourceProcs *dragSourceProcs;
struct W_DragDestinationProcs *dragDestinationProcs;
#endif
int helpContext;
struct {
unsigned int realized:1;
unsigned int mapped:1;
unsigned int parentDying:1;
unsigned int dying:1; /* the view is being destroyed */
unsigned int topLevel:1; /* is a top level window */
unsigned int root:1; /* is the root window */
unsigned int mapWhenRealized:1;/* map the view when it's realized */
unsigned int alreadyDead:1; /* view was freed */
unsigned int dontCompressMotion:1; /* motion notify event compress */
unsigned int notifySizeChanged:1;
unsigned int dontCompressExpose:1; /* will compress all expose
events into one */
/* toplevel only */
unsigned int worksWhenModal:1;
unsigned int pendingRelease1:1;
unsigned int pendingRelease2:1;
unsigned int pendingRelease3:1;
unsigned int pendingRelease4:1;
unsigned int pendingRelease5:1;
} flags;
int refCount;
} W_View;
typedef struct W_EventHandler {
unsigned long eventMask;
WMEventProc *proc;
void *clientData;
struct W_EventHandler *nextHandler;
} W_EventHandler;
typedef struct W_ViewProcedureTable {
void (*setBackgroundColor)(WMWidget*, WMColor *color);
void (*resize)(WMWidget*, unsigned int, unsigned int);
void (*move)(WMWidget*, int, int);
} W_ViewProcedureTable;
typedef struct _WINGsConfiguration {
char *systemFont;
char *boldSystemFont;
unsigned doubleClickDelay;
} _WINGsConfiguration;
_WINGsConfiguration WINGsConfiguration;
#define CHECK_CLASS(widget, class) assert(W_CLASS(widget)==(class))
#define W_CLASS(widget) (((W_WidgetType*)(widget))->widgetClass)
#define W_VIEW(widget) (((W_WidgetType*)(widget))->view)
#define W_VIEW_REALIZED(view) (view)->flags.realized
#define W_VIEW_MAPPED(view) (view)->flags.mapped
#define W_PIXEL(c) (c)->color.pixel
#define W_GC(c) (c)->gc
#define W_FONTID(f) (f)->font->fid
#define W_DRAWABLE(scr) (scr)->rootWin
W_View *W_GetViewForXWindow(Display *display, Window window);
W_View *W_CreateView(W_View *parent);
W_View *W_CreateTopView(W_Screen *screen);
W_View *W_CreateRootView(W_Screen *screen);
void W_DestroyView(W_View *view);
void W_RealizeView(W_View *view);
void W_ReparentView(W_View *view, W_View *newParent);
void W_MapView(W_View *view);
void W_MapSubviews(W_View *view);
void W_UnmapSubviews(W_View *view);
W_View *W_TopLevelOfView(W_View *view);
void W_UnmapView(W_View *view);
void W_MoveView(W_View *view, int x, int y);
void W_ResizeView(W_View *view, unsigned int width, unsigned int height);
void W_SetViewBackgroundColor(W_View *view, WMColor *color);
void W_DrawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
unsigned int height, WMReliefType relief);
void W_CleanUpEvents(W_View *view);
void W_CallDestroyHandlers(W_View *view);
void W_PaintTextAndImage(W_View *view, int wrap, GC textGC, W_Font *font,
WMReliefType relief, char *text,
WMAlignment alignment, W_Pixmap *image,
WMImagePosition position, GC backGC, int ofs);
void W_PaintText(W_View *view, Drawable d, WMFont *font, int x, int y,
int width, WMAlignment alignment, GC gc,
int wrap, char *text, int length);
int W_GetTextHeight(WMFont *font, char *text, int width, int wrap);
int W_TextWidth(WMFont *font, char *text, int length);
void W_BroadcastMessage(W_View *targetParent, XEvent *event);
void W_DispatchMessage(W_View *target, XEvent *event);
Bool W_CheckInternalMessage(W_Screen *scr, XClientMessageEvent *cev, int event);
void W_SetFocusOfToplevel(W_View *toplevel, W_View *view);
W_View *W_FocusedViewOfToplevel(W_View *view);
void W_SetFocusOfTopLevel(W_View *toplevel, W_View *view);
void W_ReleaseView(WMView *view);
WMView *W_RetainView(WMView *view);
void W_InitApplication(WMScreen *scr);
void W_InitNotificationCenter(void);
W_Class W_RegisterUserWidget(W_ViewProcedureTable *procTable);
void W_RedisplayView(WMView *view);
Bool W_ApplicationInitialized(void);
char *W_GetTextSelection(WMScreen *scr, Atom selection);

227
WINGs/WUtil.h Normal file
View File

@@ -0,0 +1,227 @@
#ifndef _WUTIL_H_
#define _WUTIL_H_
#include <X11/Xlib.h>
#include <sys/types.h>
/*
* Warning: proplist.h #defines BOOL which will clash with the
* typedef BOOL in Xmd.h
* proplist.h should use Bool (which is a #define in Xlib.h) instead.
*
*/
#include <proplist.h>
#ifndef WMAX
# define WMAX(a,b) ((a)>(b) ? (a) : (b))
#endif
#ifndef WMIN
# define WMIN(a,b) ((a)<(b) ? (a) : (b))
#endif
typedef enum {
WMPostWhenIdle = 1,
WMPostASAP = 2,
WMPostNow = 3
} WMPostingStyle;
typedef enum {
WNCNone = 0,
WNCOnName = 1,
WNCOnSender = 2
} WMNotificationCoalescing;
typedef struct W_HashTable WMHashTable;
typedef struct W_UserDefaults WMUserDefaults;
typedef struct W_Notification WMNotification;
typedef struct W_NotificationQueue WMNotificationQueue;
/* DO NOT ACCESS THE CONTENTS OF THIS STRUCT */
typedef struct {
void *table;
void *nextItem;
int index;
} WMHashEnumerator;
typedef struct {
/* NULL is pointer hash */
unsigned (*hash)(const void *);
/* NULL is pointer compare */
Bool (*keyIsEqual)(const void *, const void *);
/* NULL does nothing */
void* (*retainKey)(const void *);
/* NULL does nothing */
void (*releaseKey)(const void *);
} WMHashTableCallbacks;
typedef void WMNotificationObserverAction(void *observerData,
WMNotification *notification);
/*......................................................................*/
void wfatal(const char *msg, ...);
void wwarning(const char *msg, ...);
void wsyserror(const char *msg, ...);
char *wfindfile(char *paths, char *file);
char *wfindfileinlist(char **path_list, char *file);
char *wexpandpath(char *path);
/* don't free the returned string */
char *wgethomedir();
void *wmalloc(size_t size);
void *wrealloc(void *ptr, size_t newsize);
void wrelease(void *ptr);
void *wretain(void *ptr);
char *wstrdup(char *str);
char *wstrappend(char *dst, char *src);
char *wusergnusteppath();
char *wdefaultspathfordomain(char *domain);
void wusleep(unsigned int microsec);
/*......................................................................*/
WMHashTable *WMCreateHashTable(WMHashTableCallbacks callbacks);
void WMFreeHashTable(WMHashTable *table);
void WMResetHashTable(WMHashTable *table);
void *WMHashGet(WMHashTable *table, const void *key);
/* put data in table, replacing already existing data and returning
* the old value */
void *WMHashInsert(WMHashTable *table, void *key, void *data);
void WMHashRemove(WMHashTable *table, const void *key);
/* warning: do not manipulate the table while using these functions */
WMHashEnumerator WMEnumerateHashTable(WMHashTable *table);
void *WMNextHashEnumeratorItem(WMHashEnumerator *enumerator);
unsigned WMCountHashTable(WMHashTable *table);
/* some predefined callback sets */
extern const WMHashTableCallbacks WMIntHashCallbacks;
/* sizeof(keys) are <= sizeof(void*) */
extern const WMHashTableCallbacks WMStringHashCallbacks;
/* keys are strings. Strings will be copied with wstrdup()
* and freed with free() */
extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
/* keys are strings, bug they are not copied */
/*......................................................................*/
WMNotification *WMCreateNotification(char *name, void *object, void *clientData);
void WMReleaseNotification(WMNotification *notification);
WMNotification *WMRetainNotification(WMNotification *notification);
void *WMGetNotificationClientData(WMNotification *notification);
void *WMGetNotificationObject(WMNotification *notification);
char *WMGetNotificationName(WMNotification *notification);
void WMAddNotificationObserver(WMNotificationObserverAction *observerAction,
void *observer, char *name, void *object);
void WMPostNotification(WMNotification *notification);
void WMRemoveNotificationObserver(void *observer);
void WMRemoveNotificationObserverWithName(void *observer, char *name,
void *object);
void WMPostNotificationName(char *name, void *object, void *clientData);
WMNotificationQueue *WMGetDefaultNotificationQueue(void);
WMNotificationQueue *WMCreateNotificationQueue(void);
void WMDequeueNotificationMatching(WMNotificationQueue *queue, unsigned mask);
void WMEnqueueNotification(WMNotificationQueue *queue, WMNotification *notification,
WMPostingStyle postingStyle);
void WMEnqueueCoalesceNotification(WMNotificationQueue *queue,
WMNotification *notification,
WMPostingStyle postingStyle,
unsigned coalesceMask);
/*......................................................................*/
WMUserDefaults *WMGetStandardUserDefaults(void);
proplist_t WMGetUDObjectForKey(WMUserDefaults *database, char *defaultName);
void WMSetUDObjectForKey(WMUserDefaults *database, proplist_t object,
char *defaultName);
void WMRemoveUDObjectForKey(WMUserDefaults *database, char *defaultName);
/* you can free the returned string */
char *WMGetUDStringForKey(WMUserDefaults *database, char *defaultName);
int WMGetUDIntegerForKey(WMUserDefaults *database, char *defaultName);
int WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName);
Bool WMGetUDBoolForKey(WMUserDefaults *database, char *defaultName);
void WMSetUDStringForKey(WMUserDefaults *database, char *value,
char *defaultName);
void WMSetUDIntegerForKey(WMUserDefaults *database, int value,
char *defaultName);
void WMSetUDFloatForKey(WMUserDefaults *database, float value,
char *defaultName);
void WMSetUDBoolForKey(WMUserDefaults *database, Bool value,
char *defaultName);
proplist_t WMGetUDSearchList(WMUserDefaults *database);
void WMSetUDSearchList(WMUserDefaults *database, proplist_t list);
#endif

49
WINGs/configuration.c Normal file
View File

@@ -0,0 +1,49 @@
#include "WINGsP.h"
#include <proplist.h>
_WINGsConfiguration WINGsConfiguration;
#define SYSTEM_FONT "-*-helvetica-medium-r-normal-*-%d-*-*-*-*-*-*-*"
#define BOLD_SYSTEM_FONT "-*-helvetica-bold-r-normal-*-%d-*-*-*-*-*-*-*"
void
W_ReadConfigurations(void)
{
WMUserDefaults *defaults;
memset(&WINGsConfiguration, 0, sizeof(_WINGsConfiguration));
defaults = WMGetStandardUserDefaults();
if (defaults) {
WINGsConfiguration.systemFont =
WMGetUDStringForKey(defaults, "SystemFont");
WINGsConfiguration.boldSystemFont =
WMGetUDStringForKey(defaults, "BoldSystemFont");
WINGsConfiguration.doubleClickDelay =
WMGetUDIntegerForKey(defaults, "DoubleClickTime");
}
if (!WINGsConfiguration.systemFont) {
WINGsConfiguration.systemFont = SYSTEM_FONT;
}
if (!WINGsConfiguration.boldSystemFont) {
WINGsConfiguration.boldSystemFont = BOLD_SYSTEM_FONT;
}
if (WINGsConfiguration.doubleClickDelay == 0) {
WINGsConfiguration.doubleClickDelay = 250;
}
}

118
WINGs/error.c Normal file
View File

@@ -0,0 +1,118 @@
/*
* WindowMaker miscelaneous function library
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "../src/config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
extern char *_WINGS_progname;
#define MAXLINE 1024
/**************************************************************************
* Prints a fatal error message with variable arguments and terminates
*
* msg - message to print with optional formatting
* ... - arguments to use on formatting
**************************************************************************/
void
wfatal(const char *msg, ...)
{
va_list args;
char buf[MAXLINE];
va_start(args, msg);
vsprintf(buf, msg, args);
strcat(buf,"\n");
fflush(stdout);
fputs(_WINGS_progname, stderr);
fputs(" fatal error: ",stderr);
fputs(buf, stderr);
fflush(NULL);
va_end(args);
}
/*********************************************************************
* Prints a warning message with variable arguments
*
* msg - message to print with optional formatting
* ... - arguments to use on formatting
*********************************************************************/
void
wwarning(const char *msg, ...)
{
va_list args;
char buf[MAXLINE];
va_start(args, msg);
vsprintf(buf, msg, args);
strcat(buf,"\n");
fflush(stdout);
fputs(_WINGS_progname, stderr);
fputs(" warning: ",stderr);
fputs(buf, stderr);
fflush(NULL);
va_end(args);
}
/*********************************************************************
* Prints a system error message with variable arguments
*
* msg - message to print with optional formatting
* ... - arguments to use on formatting
*********************************************************************/
void
wsyserror(const char *msg, ...)
{
va_list args;
char buf[MAXLINE];
#ifdef HAVE_STRERROR
int error=errno;
#endif
va_start(args, msg);
vsprintf(buf, msg, args);
fflush(stdout);
fputs(_WINGS_progname, stderr);
fputs(" error: ", stderr);
strcat(buf, ": ");
#ifdef HAVE_STRERROR
strcat(buf, strerror(error));
strcat(buf,"\n");
fputs(buf, stderr);
fflush(NULL);
#else
perror(buf);
#endif
va_end(args);
}

285
WINGs/findfile.c Normal file
View File

@@ -0,0 +1,285 @@
/*
* WindowMaker miscelaneous function library
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "../src/config.h"
#include "WUtil.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
char*
wgethomedir()
{
char *home = getenv("HOME");
struct passwd *user;
if (home)
return home;
user = getpwuid(getuid());
if (!user) {
wsyserror("could not get password entry for UID %i", getuid());
return "/";
}
if (!user->pw_dir) {
return "/";
} else {
return user->pw_dir;
}
}
static char*
getuserhomedir(char *username)
{
struct passwd *user;
user = getpwnam(username);
if (!user) {
wsyserror("could not get password entry for user %s", username);
return NULL;
}
if (!user->pw_dir) {
return "/";
} else {
return user->pw_dir;
}
}
char*
wexpandpath(char *path)
{
char buffer2[PATH_MAX+2];
char buffer[PATH_MAX+2];
int i;
memset(buffer, 0, PATH_MAX+2);
if (*path=='~') {
char *home;
path++;
if (*path=='/' || *path==0) {
home = wgethomedir();
strcat(buffer, home);
} else {
int j;
j = 0;
while (*path!=0 && *path!='/') {
buffer2[j++] = *path;
buffer2[j] = 0;
path++;
}
home = getuserhomedir(buffer2);
if (!home)
return NULL;
strcat(buffer, home);
}
}
i = strlen(buffer);
while (*path!=0) {
char *tmp;
if (*path=='$') {
int j = 0;
path++;
/* expand $(HOME) or $HOME style environment variables */
if (*path=='(') {
path++;
while (*path!=0 && *path!=')') {
buffer2[j++] = *(path++);
buffer2[j] = 0;
}
if (*path==')')
path++;
tmp = getenv(buffer2);
if (!tmp) {
buffer[i] = 0;
strcat(buffer, "$(");
strcat(buffer, buffer2);
strcat(buffer, ")");
i += strlen(buffer2)+3;
} else {
strcat(buffer, tmp);
i += strlen(tmp);
}
} else {
while (*path!=0 && *path!='/') {
buffer2[j++] = *(path++);
buffer2[j] = 0;
}
tmp = getenv(buffer2);
if (!tmp) {
strcat(buffer, "$");
strcat(buffer, buffer2);
i += strlen(buffer2)+1;
} else {
strcat(buffer, tmp);
i += strlen(tmp);
}
}
} else {
buffer[i++] = *path;
path++;
}
}
return wstrdup(buffer);
}
/*
*----------------------------------------------------------------------
* findfile--
* Finds a file in a : separated list of paths. ~ expansion is also
* done.
*
* Returns:
* The complete path for the file (in a newly allocated string) or
* NULL if the file was not found.
*
* Side effects:
* A new string is allocated. It must be freed later.
*
*----------------------------------------------------------------------
*/
char*
wfindfile(char *paths, char *file)
{
char *path;
char *tmp;
int done;
int len, flen;
char *fullpath;
if (!file)
return NULL;
if (*file=='/' || *file=='~' || *file=='$' || !paths) {
if (access(file, R_OK)<0) {
fullpath = wexpandpath(file);
if (!fullpath)
return NULL;
if (access(fullpath, R_OK)<0) {
free(fullpath);
return NULL;
} else {
return fullpath;
}
} else {
return wstrdup(file);
}
}
flen = strlen(file);
tmp = paths;
done = 0;
while (!done) {
len = strcspn(tmp, ":");
if (len==0) done=1;
path = wmalloc(len+flen+2);
path = memcpy(path, tmp, len);
path[len]=0;
strcat(path, "/");
strcat(path, file);
fullpath = wexpandpath(path);
free(path);
if (fullpath) {
if (access(fullpath, R_OK)==0) {
return fullpath;
}
free(fullpath);
}
tmp=&(tmp[len+1]);
if (*tmp==0) break;
}
return NULL;
}
char*
wfindfileinlist(char **path_list, char *file)
{
int i;
char *path;
int len, flen;
char *fullpath;
if (!file)
return NULL;
if (*file=='/' || *file=='~' || !path_list) {
if (access(file, R_OK)<0) {
fullpath = wexpandpath(file);
if (!fullpath)
return NULL;
if (access(fullpath, R_OK)<0) {
free(fullpath);
return NULL;
} else {
return fullpath;
}
} else {
return wstrdup(file);
}
}
flen = strlen(file);
for (i=0; path_list[i]!=NULL; i++) {
len = strlen(path_list[i]);
path = wmalloc(len+flen+2);
path = memcpy(path, path_list[i], len);
path[len]=0;
strcat(path, "/");
strcat(path, file);
/* expand tilde */
fullpath = wexpandpath(path);
free(path);
if (fullpath) {
/* check if file is readable */
if (access(fullpath, R_OK)==0) {
return fullpath;
}
free(fullpath);
}
}
return NULL;
}

104
WINGs/fontl.c Normal file
View File

@@ -0,0 +1,104 @@
/*
* WINGs demo: font lister
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include "WINGs.h"
#include "WUtil.h"
void
wAbort()
{
exit(0);
}
void show(WMWidget *self, void *data)
{
char buf[60];
void *d;
WMLabel *l = (WMLabel*)data;
d = WMGetHangedData(self);
sprintf(buf, "%i - 0x%x - 0%o", (int)d, (int)d, (int)d);
WMSetLabelText(l, buf);
}
void quit(WMWidget *self, void *data)
{
exit(0);
}
int
main(int argc, char **argv)
{
Display *dpy;
WMWindow *win;
WMScreen *scr;
WMButton *lab, *l0=NULL;
WMLabel *pos;
int x, y, c;
char buf[20];
WMInitializeApplication("FontView", &argc, argv);
dpy = XOpenDisplay("");
if (!dpy) {
wfatal("cant open display");
exit(0);
}
scr = WMCreateSimpleApplicationScreen(dpy);
win = WMCreateWindow(scr, "main");
WMResizeWidget(win, 20*33, 20+20*9);
WMSetWindowTitle(win, "Font Chars");
WMSetWindowCloseAction(win, quit, NULL);
pos = WMCreateLabel(win);
WMResizeWidget(pos, 20*33, 20);
WMMoveWidget(pos, 10, 5);
c = 0;
for (y=0; y<8; y++) {
for (x=0; x<32; x++, c++) {
lab = WMCreateCustomButton(win, WBBStateLightMask);
WMResizeWidget(lab, 20, 20);
WMMoveWidget(lab, 10+x*20, 30+y*20);
sprintf(buf, "%c", c);
WMSetButtonText(lab, buf);
WMSetButtonAction(lab, show, pos);
WMHangData(lab, (void*)c);
if (c>0) {
WMGroupButtons(l0, lab);
} else {
l0 = lab;
}
}
}
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
WMScreenMainLoop(scr);
return 0;
}

406
WINGs/hashtable.c Normal file
View File

@@ -0,0 +1,406 @@
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "WUtil.h"
#define INITIAL_CAPACITY 23
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define INLINE inline
#else
# define INLINE
#endif
typedef struct HashItem {
void *key;
void *data;
struct HashItem *next; /* collided item list */
} HashItem;
typedef struct W_HashTable {
WMHashTableCallbacks callbacks;
unsigned itemCount;
unsigned size; /* table size */
HashItem **table;
} HashTable;
#define HASH(table, key) (((table)->callbacks.hash ? \
(*(table)->callbacks.hash)(key) : hashPtr(key)) % (table)->size)
#define DUPKEY(table, key) ((table)->callbacks.retainKey ? \
(*(table)->callbacks.retainKey)(key) : (key))
#define RELKEY(table, key) if ((table)->callbacks.releaseKey) \
(*(table)->callbacks.releaseKey)(key)
static INLINE unsigned
hashString(const char *key)
{
unsigned ret = 0;
unsigned ctr = 0;
while (*key) {
ret ^= *(char*)key++ << ctr;
ctr = (ctr + 1) % sizeof (char *);
}
return ret;
}
static INLINE unsigned
hashPtr(const void *key)
{
return ((size_t)key / sizeof(char*));
}
static void
rellocateItem(WMHashTable *table, HashItem *item)
{
unsigned h;
h = HASH(table, item->key);
item->next = table->table[h];
table->table[h] = item;
}
static void
rebuildTable(WMHashTable *table)
{
HashItem *next;
HashItem **oldArray;
int i;
int oldSize;
int newSize;
oldArray = table->table;
oldSize = table->size;
newSize = table->size*2;
table->table = wmalloc(sizeof(char*)*newSize);
memset(table->table, 0, sizeof(char*)*newSize);
table->size = newSize;
for (i = 0; i < oldSize; i++) {
while (oldArray[i]!=NULL) {
next = oldArray[i]->next;
rellocateItem(table, oldArray[i]);
oldArray[i] = next;
}
}
free(oldArray);
}
WMHashTable*
WMCreateHashTable(WMHashTableCallbacks callbacks)
{
HashTable *table;
table = wmalloc(sizeof(HashTable));
memset(table, 0, sizeof(HashTable));
table->callbacks = callbacks;
table->size = INITIAL_CAPACITY;
table->table = wmalloc(sizeof(HashItem*)*table->size);
memset(table->table, 0, sizeof(HashItem*)*table->size);
return table;
}
void
WMResetHashTable(WMHashTable *table)
{
HashItem *item, *tmp;
int i;
for (i = 0; i < table->size; i++) {
item = table->table[i];
while (item) {
tmp = item->next;
RELKEY(table, item);
free(item);
item = tmp;
}
}
table->itemCount = 0;
if (table->size > INITIAL_CAPACITY) {
free(table->table);
table->size = INITIAL_CAPACITY;
table->table = wmalloc(sizeof(HashItem*)*table->size);
}
memset(table->table, 0, sizeof(HashItem*)*table->size);
}
void
WMFreeHashTable(WMHashTable *table)
{
HashItem *item, *tmp;
int i;
for (i = 0; i < table->size; i++) {
item = table->table[i];
while (item) {
tmp = item->next;
RELKEY(table, item);
free(item);
item = tmp;
}
}
free(table->table);
free(table);
}
void*
WMHashGet(WMHashTable *table, const void *key)
{
unsigned h;
HashItem *item;
h = HASH(table, key);
item = table->table[h];
if (table->callbacks.keyIsEqual) {
while (item) {
if ((*table->callbacks.keyIsEqual)(key, item->key)) {
break;
}
item = item->next;
}
} else {
while (item) {
if (key == item->key) {
break;
}
item = item->next;
}
}
if (item)
return item->data;
else
return NULL;
}
void*
WMHashInsert(WMHashTable *table, void *key, void *data)
{
unsigned h;
HashItem *item;
int replacing = 0;
h = HASH(table, key);
/* look for the entry */
item = table->table[h];
if (table->callbacks.keyIsEqual) {
while (item) {
if ((*table->callbacks.keyIsEqual)(key, item->key)) {
replacing = 1;
break;
}
item = item->next;
}
} else {
while (item) {
if (key == item->key) {
replacing = 1;
break;
}
item = item->next;
}
}
if (replacing) {
void *old;
old = item->data;
item->data = data;
RELKEY(table, item->key);
item->key = DUPKEY(table, key);
return old;
} else {
HashItem *nitem;
nitem = wmalloc(sizeof(HashItem));
nitem->key = DUPKEY(table, key);
nitem->data = data;
nitem->next = table->table[h];
table->table[h] = nitem;
table->itemCount++;
}
/* OPTIMIZE: put this in an idle handler.*/
if (table->itemCount > table->size) {
#ifdef DEBUG0
printf("rebuilding hash table...\n");
#endif
rebuildTable(table);
#ifdef DEBUG0
printf("finished rebuild.\n");
#endif
}
return NULL;
}
static HashItem*
deleteFromList(HashTable *table, HashItem *item, const void *key)
{
HashItem *next;
if (item==NULL)
return NULL;
if ((table->callbacks.keyIsEqual
&& (*table->callbacks.keyIsEqual)(key, item->key))
|| (!table->callbacks.keyIsEqual && key==item->key)) {
next = item->next;
RELKEY(table, item->key);
free(item);
table->itemCount--;
return next;
}
item->next = deleteFromList(table, item->next, key);
return item;
}
void
WMHashRemove(WMHashTable *table, const void *key)
{
unsigned h;
h = HASH(table, key);
table->table[h] = deleteFromList(table, table->table[h], key);
}
WMHashEnumerator
WMEnumerateHashTable(WMHashTable *table)
{
WMHashEnumerator enumerator;
enumerator.table = table;
enumerator.index = 0;
enumerator.nextItem = table->table[0];
return enumerator;
}
void*
WMNextHashEnumeratorItem(WMHashEnumerator *enumerator)
{
void *data = NULL;
/* this assumes the table doesn't change between
* WMEnumerateHashTable() and WMNextHashEnumeratorItem() calls */
if (enumerator->nextItem==NULL) {
HashTable *table = enumerator->table;
while (++enumerator->index < table->size) {
if (table->table[enumerator->index]!=NULL) {
enumerator->nextItem = table->table[enumerator->index];
break;
}
}
}
if (enumerator->nextItem) {
data = ((HashItem*)enumerator->nextItem)->data;
enumerator->nextItem = ((HashItem*)enumerator->nextItem)->next;
}
return data;
}
unsigned
WMCountHashTable(WMHashTable *table)
{
return table->itemCount;
}
static Bool
compareStrings(const char *key1, const char *key2)
{
return strcmp(key1, key2)==0;
}
typedef unsigned (*hashFunc)(const void*);
typedef Bool (*isEqualFunc)(const void*, const void*);
typedef void* (*retainFunc)(const void*);
typedef void (*releaseFunc)(const void*);
const WMHashTableCallbacks WMIntHashCallbacks = {
NULL,
NULL,
NULL,
NULL
};
const WMHashTableCallbacks WMStringHashCallbacks = {
(hashFunc)hashString,
(isEqualFunc)compareStrings,
(retainFunc)wstrdup,
(releaseFunc)free
};
const WMHashTableCallbacks WMStringPointerHashCallbacks = {
(hashFunc)hashString,
(isEqualFunc)compareStrings,
NULL,
NULL
};

12
WINGs/international.c Normal file
View File

@@ -0,0 +1,12 @@
#include <X11/Xlib.h>
#include "WINGsP.h"
void
InitI18n(Display *dpy)
{
}

56
WINGs/logo.xpm Normal file
View File

@@ -0,0 +1,56 @@
/* XPM */
static char * GNUSTEP_XPM[] = {
"45 45 8 1",
" c None",
". c #666666666666",
"X c #777777777777",
"o c #596559656185",
"O c #000000000000",
"+ c #3CF33CF33CF3",
"@ c #CF3CCF3CCF3C",
"# c #FFFFFFFFFFFF",
" ",
" .Xooooooooo. ",
" ..ooOOOOOOOOOOOOOo. ",
" .XoOOOOOOOOOOOOOOOOOO+ ",
" .oOOOOOOOOOOOOOOOOOOOOOO+ ",
" XOOOOOOOOOOOOOOOOOOOOOOOOOOo ",
" oOOOOOOOOOOOOOOOOOOOOOOOOOOOO+ ",
" oOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO+ooooooo",
" +OOOOOOOOOOOOOOOOOOOOOOOOoXXXXX.XOOOOOOO",
" XOOOOOOOOOOOOOOOOOOOOOOOOOX#######.OOOOOO",
" XOOOOOOOOOOOOOOOOOOOOOOOOOOX########oOOOOO",
" OOOOOOOOOOOOOOOOOOOOOOOOOOOX#########oOOOO",
" oOOOOOOOOOOOOOOOOOOOOOOOOOOOX#########@OOOO",
" OOOOOOOOOOOOOOOOOOOOOOOOOOOOX##########oOOO",
" oOOOOOOOOOOOOOOOOOOOOOOOOOOOOX##########@OOO",
" OOOOOOOOOOOOOOOOOOOOOOOOOOOOOX###########+OO",
" OOOOOOOOOOOOOOOOOOOOOOOOOOOOOX###########oOO",
"oOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX###########@OO",
"+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOX###########@OO",
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX############XO",
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX############XO",
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX############XO",
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX############XO",
"OOOOOOOOOOOOOOOoX.X.X.X.XX.XXX@############XO",
"OOOOOOOOOOOOOOOX###########################XO",
"OOOOOOOOOOOOOOOX###########################XO",
"OOOOOOOOOOOOOOOX###########################XO",
"+OOOOOOOOOOOOOOX###########################OO",
"oOOOOOOOOOOOOOOX###########################OO",
" OOOOOOOOOOOOOOX##########################XOO",
" OOOOOOOOOOOOOOX##########################oOO",
" oOOOOOOOOOOOOOX#########################@OOO",
" OOOOOOOOOOOOOX#########################+OOO",
" oOOOOOOOOOOOOX########################@OOOO",
" OOOOOOOOOOOOX########################oOOOO",
" OOOOOOOOOOOX#######################oOOOOO",
" OOOOOOOOOOX######################XOOOOOO",
"OOOOOOOXXXXXXXX@#####################@OOOOOOO",
"OOOOOOOo############################@OOOOOOOO",
"OOOOOOOOO@#########################oOOOOOOOOO",
"OOOOOOOOOOX######################@oOOOOOOOOOO",
"OOOOOOOOOOOOX###################XOOOOOOOOOOOO",
"OOOOOOOOOOOOOOX@#############@XOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOOOXXX#####XXXOOOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"};

169
WINGs/memory.c Normal file
View File

@@ -0,0 +1,169 @@
/*
* WindowMaker miscelaneous function library
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "../src/config.h"
#include "WUtil.h"
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifndef False
# define False 0
#endif
#ifndef True
# define True 1
#endif
extern void wAbort(int);
static int Aborting=0; /* if we're in the middle of an emergency exit */
static WMHashTable *table = NULL;
void *wmalloc(size_t size)
{
void *tmp;
tmp = malloc(size);
if (tmp == NULL) {
wwarning("malloc() failed. Retrying after 2s.");
sleep(2);
tmp = malloc(size);
if (tmp == NULL) {
if (Aborting) {
puts("Real Bad Error: recursive malloc() failure.");
exit(-1);
} else {
wfatal("virtual memory exhausted");
Aborting=1;
wAbort(False);
}
}
}
return tmp;
}
void *wrealloc(void *ptr, size_t newsize)
{
void *nptr;
if (!ptr) {
nptr = malloc(newsize);
} else {
nptr=realloc(ptr, newsize);
}
if (nptr==NULL) {
printf("Could not do realloc");
return NULL;
}
return nptr;
}
void*
wretain(void *ptr)
{
int *refcount;
if (!table) {
table = WMCreateHashTable(WMIntHashCallbacks);
}
refcount = WMHashGet(table, ptr);
if (!refcount) {
refcount = wmalloc(sizeof(int));
*refcount = 1;
WMHashInsert(table, ptr, refcount);
#ifdef VERBOSE
printf("== %i (%p)\n", *refcount, ptr);
#endif
} else {
(*refcount)++;
#ifdef VERBOSE
printf("+ %i (%p)\n", *refcount, ptr);
#endif
}
return ptr;
}
void
wrelease(void *ptr)
{
int *refcount;
refcount = WMHashGet(table, ptr);
if (!refcount) {
wwarning("trying to release unexisting data %p", ptr);
} else {
(*refcount)--;
if (*refcount < 1) {
#ifdef VERBOSE
printf("RELEASING %p\n", ptr);
#endif
WMHashRemove(table, ptr);
free(refcount);
free(ptr);
}
#ifdef VERBOSE
else {
printf("- %i (%p)\n", *refcount, ptr);
}
#endif
}
}
char*
wstrdup(char *str)
{
assert(str!=NULL);
return strcpy(wmalloc(strlen(str)+1), str);
}
char*
wstrappend(char *dst, char *src)
{
char *str;
if (!dst)
return wstrdup(src);
else if (!src)
return wstrdup(dst);
str = wmalloc(strlen(dst)+strlen(src)+1);
strcpy(str, dst);
strcat(str, src);
return str;
}

221
WINGs/mywidget.c Normal file
View File

@@ -0,0 +1,221 @@
/*
* Demo user widget for WINGs.
*
*
* Copyright (c) 1998 Alfredo K. Kojima
*/
/*
*
* Include the WINGs private data header.
*
*
*/
#include "WINGsP.h"
/*
* Our public header.
*/
#include "mywidget.h"
/*
* Define the widget "class"
*/
typedef struct W_MyWidget {
/* these two fields must be present in all your widgets in this
* exact position */
W_Class widgetClass;
WMView *view;
/* put your stuff here */
char *text;
} _MyWidget;
/* some forward declarations */
static void destroyMyWidget(_MyWidget *mPtr);
static void paintMyWidget(_MyWidget *mPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
/*
* Some procedures you might want to override. Don't forget to call
* the equivalent view procedure after (or before) doing your stuff.
* See the source for the other widgets to see how to use.
* You won't need to use this most of the time.
*/
static W_ViewProcedureTable _MyWidgetViewProcedures = {
NULL,
NULL,
NULL
};
/* our widget class ID */
static W_Class myWidgetClass = 0;
/*
* Initializer for our widget. Must be called before creating any
* instances of the widget.
*/
W_Class
InitMyWidget(WMScreen *scr)
{
/* register our widget with WINGs and get our widget class ID */
if (!myWidgetClass) {
myWidgetClass = W_RegisterUserWidget(&_MyWidgetViewProcedures);
}
return myWidgetClass;
}
/*
* Our widget fabrication plant.
*/
MyWidget*
CreateMyWidget(WMWidget *parent)
{
MyWidget *mPtr;
/* allocate some storage for our new widget instance */
mPtr = wmalloc(sizeof(MyWidget));
/* initialize it */
memset(mPtr, 0, sizeof(MyWidget));
/* set the class ID */
mPtr->widgetClass = myWidgetClass;
/*
* Create the view for our widget.
* Note: the Window for the view is only created after the view is
* realized with W_RealizeView()
*
* Consider the returned view as read-only.
*/
mPtr->view = W_CreateView(W_VIEW(parent));
if (!mPtr->view) {
free(mPtr);
return NULL;
}
/* always do this */
mPtr->view->self = mPtr;
/*
* Intercept some events for our widget, so that we can handle them.
*/
WMCreateEventHandler(mPtr->view, ExposureMask /* this allows us to know when we should paint */
|StructureNotifyMask, /* this allows us to know things like when we are destroyed */
handleEvents, mPtr);
/*
* Intercept some other events. This could be merged with the above
* call, but we separate for more organization.
*/
WMCreateEventHandler(mPtr->view, ButtonPressMask,handleActionEvents, mPtr);
return mPtr;
}
/*
* Paint our widget contents.
*/
static void
paintMyWidget(_MyWidget *mPtr)
{
W_Screen *scr = mPtr->view->screen;
WMColor *color;
if (mPtr->text) {
color = WMWhiteColor(scr);
W_PaintText(mPtr->view, mPtr->view->window, scr->normalFont, 0, 0,
mPtr->view->size.width, WACenter, W_GC(color),
False, mPtr->text, strlen(mPtr->text));
WMReleaseColor(color);
}
}
static void
handleEvents(XEvent *event, void *data)
{
_MyWidget *mPtr = (_MyWidget*)data;
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintMyWidget(mPtr);
break;
case DestroyNotify:
destroyMyWidget(mPtr);
break;
}
}
static void
handleActionEvents(XEvent *event, void *data)
{
_MyWidget *mPtr = (_MyWidget*)data;
switch (event->type) {
case ButtonPress:
XBell(mPtr->view->screen->display, 100);
XBell(mPtr->view->screen->display, 100);
break;
}
}
void
SetMyWidgetText(MyWidget *mPtr, char *text)
{
CHECK_CLASS(mPtr, myWidgetClass);
if (mPtr->text)
free(mPtr->text);
mPtr->text = wstrdup(text);
if (W_VIEW_MAPPED(mPtr->view)) {
paintMyWidget(mPtr);
}
}
static void
destroyMyWidget(_MyWidget *mPtr)
{
/*
* Free all data we allocated for our widget.
*/
if (mPtr->text)
free(mPtr->text);
free(mPtr);
}

15
WINGs/mywidget.h Normal file
View File

@@ -0,0 +1,15 @@
/*
* Header foy demo widget.
*
*/
typedef struct W_MyWidget MyWidget;
MyWidget *CreateMyWidget(WMWidget *parent);
void SetMyWidgetText(MyWidget *mPtr, char *text);
W_Class InitMyWidget(WMScreen *scr);

414
WINGs/notification.c Normal file
View File

@@ -0,0 +1,414 @@
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "WUtil.h"
typedef struct W_Notification {
char *name;
void *object;
void *clientData;
int refCount;
} Notification;
char*
WMGetNotificationName(WMNotification *notification)
{
return notification->name;
}
void*
WMGetNotificationObject(WMNotification *notification)
{
return notification->object;
}
void*
WMGetNotificationClientData(WMNotification *notification)
{
return notification->clientData;
}
WMNotification*
WMCreateNotification(char *name, void *object, void *clientData)
{
Notification *nPtr;
nPtr = wmalloc(sizeof(Notification));
nPtr->name = name;
nPtr->object = object;
nPtr->clientData = clientData;
nPtr->refCount = 1;
return nPtr;
}
void
WMReleaseNotification(WMNotification *notification)
{
notification->refCount--;
if (notification->refCount < 1) {
free(notification);
}
}
WMNotification*
WMRetainNotification(WMNotification *notification)
{
notification->refCount++;
return notification;
}
/***************** Notification Center *****************/
typedef struct NotificationObserver {
WMNotificationObserverAction *observerAction;
void *observer;
char *name;
void *object;
struct NotificationObserver *prev; /* for tables */
struct NotificationObserver *next;
struct NotificationObserver *nextAction; /* for observerTable */
} NotificationObserver;
typedef struct W_NotificationCenter {
WMHashTable *nameTable; /* names -> observer lists */
WMHashTable *objectTable; /* object -> observer lists */
NotificationObserver *nilList; /* obervers that catch everything */
WMHashTable *observerTable; /* observer -> NotificationObserver */
} NotificationCenter;
/* default (and only) center */
static NotificationCenter *notificationCenter = NULL;
void
W_InitNotificationCenter(void)
{
notificationCenter = wmalloc(sizeof(NotificationCenter));
notificationCenter->nameTable = WMCreateHashTable(WMStringPointerHashCallbacks);
notificationCenter->objectTable = WMCreateHashTable(WMIntHashCallbacks);
notificationCenter->nilList = NULL;
notificationCenter->observerTable = WMCreateHashTable(WMIntHashCallbacks);
}
void
WMAddNotificationObserver(WMNotificationObserverAction *observerAction,
void *observer, char *name, void *object)
{
NotificationObserver *oRec, *rec;
oRec = wmalloc(sizeof(NotificationObserver));
oRec->observerAction = observerAction;
oRec->observer = observer;
oRec->name = name;
oRec->object = object;
oRec->next = NULL;
oRec->prev = NULL;
/* put this action in the list of actions for this observer */
rec = WMHashInsert(notificationCenter->observerTable, observer, oRec);
if (rec) {
/* if this is not the first action for the observer */
oRec->nextAction = rec;
} else {
oRec->nextAction = NULL;
}
if (!name && !object) {
/* catch-all */
oRec->next = notificationCenter->nilList;
if (notificationCenter->nilList) {
notificationCenter->nilList->prev = oRec;
}
notificationCenter->nilList = oRec;
} else if (!name) {
/* any message coming from object */
rec = WMHashInsert(notificationCenter->objectTable, object, oRec);
oRec->next = rec;
if (rec) {
rec->prev = oRec;
}
} else {
/* name && (object || !object) */
rec = WMHashInsert(notificationCenter->nameTable, name, oRec);
oRec->next = rec;
if (rec) {
rec->prev = oRec;
}
}
}
void
WMPostNotification(WMNotification *notification)
{
NotificationObserver *orec, *tmp;
WMRetainNotification(notification);
/* tell the observers that want to know about a particular message */
orec = WMHashGet(notificationCenter->nameTable, notification->name);
while (orec) {
tmp = orec->next;
if (!orec->object || orec->object == notification->object) {
/* tell the observer */
if (orec->observerAction) {
(*orec->observerAction)(orec->observer, notification);
}
}
orec = tmp;
}
/* tell the observers that want to know about an object */
orec = WMHashGet(notificationCenter->objectTable, notification->object);
while (orec) {
tmp = orec->next;
/* tell the observer */
if (orec->observerAction) {
(*orec->observerAction)(orec->observer, notification);
}
orec = tmp;
}
/* tell the catch all observers */
orec = notificationCenter->nilList;
while (orec) {
tmp = orec->next;
/* tell the observer */
if (orec->observerAction) {
(*orec->observerAction)(orec->observer, notification);
}
orec = tmp;
}
WMReleaseNotification(notification);
}
void
WMRemoveNotificationObserver(void *observer)
{
NotificationObserver *orec, *tmp, *rec;
/* get the list of actions the observer is doing */
orec = WMHashGet(notificationCenter->observerTable, observer);
/*
* FOREACH orec IN actionlist for observer
* DO
* remove from respective lists/tables
* free
* END
*/
while (orec) {
tmp = orec->nextAction;
if (!orec->name && !orec->object) {
/* catch-all */
if (notificationCenter->nilList==orec)
notificationCenter->nilList = orec->next;
} else if (!orec->name) {
/* any message coming from object */
rec = WMHashGet(notificationCenter->objectTable, orec->object);
if (rec==orec) {
/* replace table entry */
if (orec->next) {
WMHashInsert(notificationCenter->objectTable, orec->object,
orec->next);
} else {
WMHashRemove(notificationCenter->objectTable, orec->object);
}
}
} else {
/* name && (object || !object) */
rec = WMHashGet(notificationCenter->nameTable, orec->name);
if (rec==orec) {
/* replace table entry */
if (orec->next) {
WMHashInsert(notificationCenter->nameTable, orec->name,
orec->next);
} else {
WMHashRemove(notificationCenter->nameTable, orec->name);
}
}
}
if (orec->prev)
orec->prev->next = orec->next;
if (orec->next)
orec->next->prev = orec->prev;
free(orec);
orec = tmp;
}
WMHashRemove(notificationCenter->observerTable, observer);
}
void
WMRemoveNotificationObserverWithName(void *observer, char *name, void *object)
{
NotificationObserver *orec, *tmp, *rec;
/* get the list of actions the observer is doing */
orec = WMHashGet(notificationCenter->observerTable, observer);
while (orec) {
tmp = orec->nextAction;
if (orec->name == name && orec->object == object) {
if (!name && !object) {
if (notificationCenter->nilList == orec)
notificationCenter->nilList = orec->next;
} else if (!name) {
rec = WMHashGet(notificationCenter->objectTable, orec->object);
if (rec==orec) {
assert(rec->prev==NULL);
/* replace table entry */
if (orec->next) {
WMHashInsert(notificationCenter->objectTable, orec->object,
orec->next);
} else {
WMHashRemove(notificationCenter->objectTable,
orec->object);
}
}
} else {
rec = WMHashGet(notificationCenter->nameTable, orec->name);
if (rec==orec) {
assert(rec->prev==NULL);
/* replace table entry */
if (orec->next) {
WMHashInsert(notificationCenter->nameTable, orec->name,
orec->next);
} else {
WMHashRemove(notificationCenter->nameTable, orec->name);
}
}
}
/* update the action list for the observer */
rec = WMHashGet(notificationCenter->observerTable, observer);
if (rec == orec) {
if (orec->nextAction) {
WMHashInsert(notificationCenter->nameTable, observer,
orec->nextAction);
} else {
WMHashRemove(notificationCenter->nameTable, observer);
}
}
if (orec->prev)
orec->prev->next = orec->next;
if (orec->next)
orec->next->prev = orec->prev;
free(orec);
}
orec = tmp;
}
}
void
WMPostNotificationName(char *name, void *object, void *clientData)
{
WMNotification *notification;
notification = WMCreateNotification(name, object, clientData);
WMPostNotification(notification);
WMReleaseNotification(notification);
}
/**************** Notification Queues ****************/
typedef struct W_NotificationQueue {
NotificationCenter *center;
void *asapQueue;
void *idleQueue;
} NotificationQueue;
/* default queue */
static WMNotificationQueue *notificationQueue = NULL;
WMNotificationQueue*
WMGetDefaultNotificationQueue(void)
{
return notificationQueue;
}
WMNotificationQueue*
WMCreateNotificationQueue(void)
{
return NULL;
}
void
WMDequeueNotificationMatching(WMNotificationQueue *queue, unsigned mask)
{
}
void
WMEnqueueNotification(WMNotificationQueue *queue, WMNotification *notification,
WMPostingStyle postingStyle)
{
}
void
WMEnqueueCoalesceNotification(WMNotificationQueue *queue,
WMNotification *notification,
WMPostingStyle postingStyle,
unsigned coalesceMask)
{
}

293
WINGs/selection.c Normal file
View File

@@ -0,0 +1,293 @@
#include <stdlib.h>
#include <X11/Xatom.h>
#include "WINGsP.h"
#if 0
typedef struct W_SelectionHandler {
WMWidget *widget;
Atom selection;
void *clientData;
WMSelectionProc *proc;
WMHandlerID timerID;
W_SelectionHandler *next;
W_SelectionHandler *prev;
} W_SelectionHandler;
#endif
#define SELECTION_TIMEOUT 2000
#define MAX_PROPERTY_SIZE 10*1024
#if 0
void
WMWriteSelectionToClipboard(WMSelection *selection)
{
}
WMSelection*
WMCreateSelectionWithData(WMData *data, Atom type)
{
}
#endif
#if 0
#define MAX_PROPERTY_SIZE 100*1024
static void
handleSelectionEvent(XEvent *event, void *data)
{
W_SelectionHandler *handler = (W_SelectionHandler*)data;
char *data = NULL;
Atom type;
int format, result;
unsigned long numItems, bytesAfter;
WMScreen *scr = WMWidgetScreen(handler->widget);
WMDeleteTimerHandler(handler->timerID);
if (handler->next)
handler->next->prev = handler->prev;
if (handler->prev)
handler->prev->next = handler->next;
if (handler == WMWidgetScreen(handler->widget)->selectionHandlerList)
WMWidgetScreen(handler->widget)->selectionHandlerList = handler->next;
if (event->xselection.property == None) {
char *name = XGetAtomName(event->xselection.display,
handler->selection);
char *form = XGetAtomName(event->xselection.display, handler->type);
wwarning("error retrieving selection %s with form %s\n", name, form);
if (name)
XFree(name);
if (form)
XFree(form);
free(handler);
return;
}
if (XGetWindowProperty(event->xselection.display,
event->xselection.requestor, handler->property,
0, MAX_PROPERTY_SIZE, False, AnyPropertyType,
&type, &format, &numItems, &bytesAfter,
&data) != Success || type == None) {
if (data)
XFree(data);
free(handler);
return;
}
if (bytesAfter!=0) {
wwarning("data in selection is too large");
if (data)
XFree(data);
free(handler);
return;
}
if (type == XA_STRING || type == scr->compoundTextAtom) {
if (format!=8) {
wwarning("string in selection has format %i, which is invalid",
format);
if (data)
XFree(data);
free(handler);
return;
}
(*handler->proc)();
}
}
static void
timeoutHandler(void *data)
{
W_SelectionHandler *handler = (W_SelectionHandler*)data;
wwarning("selection timed out");
WMDeleteEventHandler(WMWidgetView(handler->widget), SelectionNotifyMask,
handleSelectionEvent, data);
if (handler->next)
handler->next->prev = handler->prev;
if (handler->prev)
handler->prev->next = handler->next;
if (handler == WMWidgetScreen(handler->widget)->selectionHandlerList)
WMWidgetScreen(handler->widget)->selectionHandlerList = handler->next;
}
void
WMGetSelection(WMWidget *widget, Atom selection, Atom type, Atom property,
WMSelectionProc *proc, void *clientData, Time time)
{
WMScreen *scr = WMWidgetScreen(widget);
void *data;
Atom rtype;
int bits;
unsigned long len, bytes;
unsigned char *data;
int buffer = -1;
switch (selection) {
case XA_CUT_BUFFER0:
buffer = 0;
break;
case XA_CUT_BUFFER1:
buffer = 1;
break;
case XA_CUT_BUFFER2:
buffer = 2;
break;
case XA_CUT_BUFFER3:
buffer = 3;
break;
case XA_CUT_BUFFER4:
buffer = 4;
break;
case XA_CUT_BUFFER5:
buffer = 5;
break;
case XA_CUT_BUFFER6:
buffer = 6;
break;
case XA_CUT_BUFFER7:
buffer = 7;
break;
}
if (buffer >= 0) {
char *data;
int size;
data = XFetchBuffer(scr->display, &size, buffer);
} else {
W_SelectionHandler *handler;
XDeleteProperty(scr->display, WMWidgetXID(widget), selection);
XConvertSelection(scr->display, selection, type, property,
WMWidgetXID(widget), time);
handler = wmalloc(sizeof(W_SelectionHandler));
handler->widget = widget;
handler->selection = selection;
handler->type = type;
handler->property = property;
handler->clientData = clientData;
handler->proc = proc;
handler->timerID = WMAddTimerHandler(SELECTION_TIMEOUT,
timeoutHandler, handler);
handler->next = scr->selectionHandlerList;
handler->prev = NULL;
if (scr->selectionHandlerList)
scr->selectionHandlerList->prev = handler;
scr->selectionHandlerList = handler;
WMCreateEventHandler(WMWidgetView(widget), SelectionNotifyMask,
handleSelectionEvent, handler);
}
}
#endif
static void
timeoutHandler(void *data)
{
*(int*)data = 1;
}
char*
W_GetTextSelection(WMScreen *scr, Atom selection)
{
int buffer = -1;
switch (selection) {
case XA_CUT_BUFFER0:
buffer = 0;
break;
case XA_CUT_BUFFER1:
buffer = 1;
break;
case XA_CUT_BUFFER2:
buffer = 2;
break;
case XA_CUT_BUFFER3:
buffer = 3;
break;
case XA_CUT_BUFFER4:
buffer = 4;
break;
case XA_CUT_BUFFER5:
buffer = 5;
break;
case XA_CUT_BUFFER6:
buffer = 6;
break;
case XA_CUT_BUFFER7:
buffer = 7;
break;
}
if (buffer >= 0) {
char *data;
int size;
data = XFetchBuffer(scr->display, &size, buffer);
return data;
} else {
unsigned char *data;
int bits;
Atom rtype;
unsigned long len, bytes;
WMHandlerID timer;
int timeout = 0;
XEvent ev;
XDeleteProperty(scr->display, scr->groupLeader, scr->clipboardAtom);
XConvertSelection(scr->display, selection, XA_STRING,
scr->clipboardAtom, scr->groupLeader,
scr->lastEventTime);
timer = WMAddTimerHandler(1000, timeoutHandler, &timeout);
while (!XCheckTypedWindowEvent(scr->display, scr->groupLeader,
SelectionNotify, &ev) && !timeout);
if (!timeout) {
WMDeleteTimerHandler(timer);
} else {
wwarning("selection retrieval timed out");
return NULL;
}
/* nobody owns the selection */
if (ev.xselection.property == None) {
return NULL;
}
if (XGetWindowProperty(scr->display, scr->groupLeader,
scr->clipboardAtom, 0, MAX_PROPERTY_SIZE,
False, XA_STRING, &rtype, &bits, &len,
&bytes, &data)!=Success) {
return NULL;
}
if (rtype!=XA_STRING || bits!=8) {
wwarning("invalid data in text selection");
if (data)
XFree(data);
return NULL;
}
return data;
}
}

51
WINGs/testmywidget.c Normal file
View File

@@ -0,0 +1,51 @@
#include <WINGs.h>
#include <WUtil.h>
#include "mywidget.h"
void
wAbort()
{
exit(1);
}
int main(int argc, char **argv)
{
Display *dpy = XOpenDisplay("");
WMScreen *scr;
WMWindow *win;
MyWidget *thing;
WMInitializeApplication("Test", &argc, argv);
if (!dpy) {
wfatal("could not open display");
exit(1);
}
scr = WMCreateSimpleApplicationScreen(dpy);
/* init our widget */
InitMyWidget(scr);
win = WMCreateWindow(scr, "test");
WMResizeWidget(win, 150, 50);
thing = CreateMyWidget(win);
SetMyWidgetText(thing, "The Test");
WMResizeWidget(thing, 100, 20);
WMMoveWidget(thing, 10, 10);
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
WMScreenMainLoop(scr);
return 0;
}

420
WINGs/userdefaults.c Normal file
View File

@@ -0,0 +1,420 @@
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <assert.h>
#include "WUtil.h"
#include <proplist.h>
typedef struct W_UserDefaults {
proplist_t defaults;
proplist_t appDomain;
proplist_t searchListArray;
proplist_t *searchList; /* cache for searchListArray */
char dirty;
} UserDefaults;
static UserDefaults *sharedUserDefaults = NULL;
extern char *WMGetApplicationName();
#define DEFAULTS_DIR "/Defaults"
char*
wusergnusteppath()
{
char *path;
char *gspath;
int pathlen;
gspath = getenv("GNUSTEP_USER_ROOT");
if (gspath) {
gspath = wexpandpath(gspath);
pathlen = strlen(gspath) + 4;
path = wmalloc(pathlen);
strcpy(path, gspath);
free(gspath);
} else {
pathlen = strlen(wgethomedir()) + 10;
path = wmalloc(pathlen);
strcpy(path, wgethomedir());
strcat(path, "/GNUstep");
}
return path;
}
char*
wdefaultspathfordomain(char *domain)
{
char *path;
char *gspath;
gspath = wusergnusteppath();
path = wmalloc(strlen(gspath)+strlen(DEFAULTS_DIR)+strlen(domain)+4);
strcpy(path, gspath);
free(gspath);
strcat(path, DEFAULTS_DIR);
strcat(path, "/");
strcat(path, domain);
return path;
}
static void
saveDefaultsChanges(void)
{
if (sharedUserDefaults && sharedUserDefaults->dirty) {
PLSave(sharedUserDefaults->appDomain, YES);
}
}
WMUserDefaults*
WMGetStandardUserDefaults(void)
{
if (!sharedUserDefaults) {
WMUserDefaults *defaults;
proplist_t domain;
proplist_t key;
char *path;
int i;
defaults = wmalloc(sizeof(WMUserDefaults));
memset(defaults, 0, sizeof(WMUserDefaults));
defaults->defaults = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
defaults->searchList = wmalloc(sizeof(proplist_t)*3);
/* application domain */
key = PLMakeString(WMGetApplicationName());
defaults->searchList[0] = key;
/* temporary kluge */
if (strcmp(WMGetApplicationName(), "WindowMaker")==0) {
domain = NULL;
path = NULL;
} else {
path = wdefaultspathfordomain(PLGetString(key));
domain = PLGetProplistWithPath(path);
}
if (!domain) {
proplist_t p;
domain = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
if (path) {
p = PLMakeString(path);
PLSetFilename(domain, p);
PLRelease(p);
}
}
if (path)
free(path);
defaults->appDomain = domain;
if (domain)
PLInsertDictionaryEntry(defaults->defaults, key, domain);
PLRelease(key);
/* global domain */
key = PLMakeString("WMGLOBAL");
defaults->searchList[1] = key;
path = wdefaultspathfordomain(PLGetString(key));
domain = PLGetProplistWithPath(path);
free(path);
if (!domain)
domain = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
if (domain)
PLInsertDictionaryEntry(defaults->defaults, key, domain);
PLRelease(key);
/* terminate list */
defaults->searchList[2] = NULL;
defaults->searchListArray=PLMakeArrayFromElements(NULL,NULL);
i = 0;
while (defaults->searchList[i]) {
PLAppendArrayElement(defaults->searchListArray,
defaults->searchList[i]);
i++;
}
sharedUserDefaults = defaults;
/* set to save changes in defaults when program is exited */
atexit(saveDefaultsChanges);
}
return sharedUserDefaults;
}
proplist_t
WMGetUDObjectForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t domainName, domain;
proplist_t object = NULL;
proplist_t key = PLMakeString(defaultName);
int i = 0;
while (database->searchList[i] && !object) {
domainName = database->searchList[i];
domain = PLGetDictionaryEntry(database->defaults, domainName);
if (domain) {
object = PLGetDictionaryEntry(domain, key);
}
i++;
}
PLRelease(key);
return object;
}
void
WMSetUDObjectForKey(WMUserDefaults *database, proplist_t object,
char *defaultName)
{
proplist_t key = PLMakeString(defaultName);
database->dirty = 1;
PLInsertDictionaryEntry(database->appDomain, key, object);
PLRelease(key);
}
void
WMRemoveUDObjectForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t key = PLMakeString(defaultName);
database->dirty = 1;
PLRemoveDictionaryEntry(database->appDomain, key);
PLRelease(key);
}
char*
WMGetUDStringForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t val;
val = WMGetUDObjectForKey(database, defaultName);
if (!val)
return NULL;
if (!PLIsString(val))
return NULL;
return wstrdup(PLGetString(val));
}
int
WMGetUDIntegerForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t val;
char *str;
int value;
val = WMGetUDObjectForKey(database, defaultName);
if (!val)
return 0;
if (!PLIsString(val))
return 0;
str = PLGetString(val);
if (!str)
return 0;
if (sscanf(str, "%i", &value)!=1)
return 0;
return value;
}
int
WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t val;
char *str;
float value;
val = WMGetUDObjectForKey(database, defaultName);
if (!val)
return 0.0;
if (!PLIsString(val))
return 0.0;
str = PLGetString(val);
if (!str)
return 0.0;
if (sscanf(str, "%f", &value)!=1)
return 0.0;
return value;
}
Bool
WMGetUDBoolForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t val;
int value;
char *str;
val = WMGetUDObjectForKey(database, defaultName);
if (!val)
return False;
if (!PLIsString(val))
return False;
str = PLGetString(val);
if (!str)
return False;
if (sscanf(str, "%i", &value)==1 && value!=0)
return True;
if (strcasecmp(str, "YES")==0)
return True;
if (strcasecmp(str, "Y")==0)
return True;
return False;
}
void
WMSetUDIntegerForKey(WMUserDefaults *database, int value, char *defaultName)
{
proplist_t object;
char buffer[128];
sprintf(buffer, "%i", value);
object = PLMakeString(buffer);
WMSetUDObjectForKey(database, object, defaultName);
PLRelease(object);
}
void
WMSetUDStringForKey(WMUserDefaults *database, char *value, char *defaultName)
{
proplist_t object;
object = PLMakeString(value);
WMSetUDObjectForKey(database, object, defaultName);
PLRelease(object);
}
void
WMSetUDFloatForKey(WMUserDefaults *database, float value, char *defaultName)
{
proplist_t object;
char buffer[128];
sprintf(buffer, "%f", value);
object = PLMakeString(buffer);
WMSetUDObjectForKey(database, object, defaultName);
PLRelease(object);
}
void
WMSetUDBoolForKey(WMUserDefaults *database, Bool value, char *defaultName)
{
static proplist_t yes = NULL, no = NULL;
if (!yes) {
yes = PLMakeString("YES");
no = PLMakeString("NO");
}
WMSetUDObjectForKey(database, value ? yes : no, defaultName);
}
proplist_t
WMGetUDSearchList(WMUserDefaults *database)
{
return database->searchListArray;
}
void
WMSetUDSearchList(WMUserDefaults *database, proplist_t list)
{
int i, c;
if (database->searchList) {
i = 0;
while (database->searchList[i]) {
PLRelease(database->searchList[i]);
i++;
}
free(database->searchList);
}
if (database->searchListArray) {
PLRelease(database->searchListArray);
}
c = PLGetNumberOfElements(list);
database->searchList = wmalloc(sizeof(proplist_t)*(c+1));
for (i=0; i<c; i++) {
database->searchList[i] = PLGetArrayElement(list, i);
}
database->searchListArray = PLDeepCopy(list);
}

50
WINGs/usleep.c Normal file
View File

@@ -0,0 +1,50 @@
#include "../src/config.h"
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef _AIX
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if defined(HAVE_SELECT)
void
wusleep(unsigned int microsecs)
{
struct timeval tv;
fd_set rd, wr, ex;
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&ex);
tv.tv_sec = microsecs / 1000000u;
tv.tv_usec = microsecs % 1000000u;
select(1, &rd, &wr, &ex, &tv);
}
#else /* not HAVE_SELECT */
# ifdef HAVE_POLL
void
wusleep(unsigned int microsecs)
{
poll((struct poll *) 0, (size_t) 0, microsecs/1000);
}
# else /* ! HAVE_POLL */
oops!
# endif /* !HAVE_POLL */
#endif /* !HAVE_SELECT */

301
WINGs/wapplication.c Normal file
View File

@@ -0,0 +1,301 @@
#include <unistd.h>
#include "WINGsP.h"
#include <X11/Xutil.h>
/* Xmd.h which is indirectly included by GNUstep.h defines BOOL,
* but libPropList also defines it. So we do this kluge to get rid of BOOL
* temporarily */
#ifdef BOOL
# define WINGS_BOOL
# undef BOOL
#endif
#include "GNUstep.h"
#ifdef WINGS_BOOL
# define BOOL
# undef WINGS_BOOL
#endif
extern void W_ReadConfigurations(void);
extern void W_InitNotificationCenter(void);
typedef struct W_Application {
char *applicationName;
int argc;
char **argv;
char *resourcePath;
} W_Application;
struct W_Application WMApplication;
char *_WINGS_progname = NULL;
Bool
W_ApplicationInitialized(void)
{
return _WINGS_progname!=NULL;
}
void
WMInitializeApplication(char *applicationName, int *argc, char **argv)
{
int i;
assert(argc!=NULL);
assert(argv!=NULL);
assert(applicationName!=NULL);
_WINGS_progname = argv[0];
WMApplication.applicationName = wstrdup(applicationName);
WMApplication.argc = *argc;
WMApplication.argv = wmalloc((*argc+1)*sizeof(char*));
for (i=0; i<*argc; i++) {
WMApplication.argv[i] = wstrdup(argv[i]);
}
WMApplication.argv[i] = NULL;
/* initialize notification center */
W_InitNotificationCenter();
/* read general configuration data for WINGs */
W_ReadConfigurations();
}
void
WMSetResourcePath(char *path)
{
if (WMApplication.resourcePath)
free(WMApplication.resourcePath);
WMApplication.resourcePath = wstrdup(path);
}
char*
WMGetApplicationName()
{
return WMApplication.applicationName;
}
static char*
checkFile(char *path, char *folder, char *ext, char *resource)
{
char *ret;
int extralen;
extralen = (ext ? strlen(ext) : 0) + (folder ? strlen(folder) : 0) + 4;
ret = wmalloc(strlen(path)+strlen(resource)+extralen+8);
strcpy(ret, path);
if (folder) {
strcat(ret, "/");
strcat(ret, folder);
}
if (ext) {
strcat(ret, "/");
strcat(ret, ext);
}
strcat(ret, "/");
strcat(ret, resource);
if (access(ret, F_OK)!=0) {
free(ret);
ret = NULL;
}
return ret;
}
char*
WMPathForResourceOfType(char *resource, char *ext)
{
char *path = NULL;
char *tmp, *appdir;
int i;
/*
* Paths are searched in this order:
* - resourcePath/ext
* - argv[0]/ext
* - GNUSTEP_USER_ROOT/Apps/ApplicationName.app/ext
* - ~/GNUstep/Apps/ApplicationName.app/ext
* - GNUSTEP_LOCAL_ROOT/Apps/ApplicationName.app/ext
* - /usr/local/GNUstep/Apps/ApplicationName.app/ext
* - GNUSTEP_SYSTEM_ROOT/Apps/ApplicationName.app/ext
* - /usr/GNUstep/Apps/ApplicationName.app/ext
*/
if (WMApplication.resourcePath) {
path = checkFile(WMApplication.resourcePath, NULL, ext, resource);
if (path)
return path;
}
if (WMApplication.argv[0]) {
tmp = wstrdup(WMApplication.argv[0]);
i = strlen(tmp);
while (i > 0 && tmp[i]!='/')
i--;
tmp[i] = 0;
if (i>0) {
path = checkFile(tmp, NULL, ext, resource);
} else {
path = NULL;
}
free(tmp);
if (path)
return path;
}
appdir = wmalloc(strlen(WMApplication.applicationName)+8);
sprintf(appdir, "Apps/%s.app", WMApplication.applicationName);
if (getenv("GNUSTEP_USER_ROOT")) {
path = checkFile(getenv("GNUSTEP_USER_ROOT"), appdir, ext, resource);
if (path) {
free(appdir);
return path;
}
}
tmp = wusergnusteppath();
if (tmp) {
path = checkFile(tmp, appdir, ext, resource);
free(tmp);
if (path) {
free(appdir);
return path;
}
}
if (getenv("GNUSTEP_LOCAL_ROOT")) {
path = checkFile(getenv("GNUSTEP_LOCAL_ROOT"), appdir, ext, resource);
if (path) {
free(appdir);
return path;
}
}
path = checkFile("/usr/local/GNUstep", appdir, ext, resource);
if (path) {
free(appdir);
return path;
}
if (getenv("GNUSTEP_SYSTEM_ROOT")) {
path = checkFile(getenv("GNUSTEP_SYSTEM_ROOT"), appdir, ext, resource);
if (path) {
free(appdir);
return path;
}
}
path = checkFile("/usr/GNUstep", appdir, ext, resource);
if (path) {
free(appdir);
return path;
}
return NULL;
}
/********************* WMScreen related stuff ********************/
void
WMSetApplicationIconImage(WMScreen *scr, WMPixmap *icon)
{
if (scr->applicationIcon)
WMReleasePixmap(scr->applicationIcon);
scr->applicationIcon = WMRetainPixmap(icon);
if (scr->groupLeader) {
XWMHints *hints;
hints = XGetWMHints(scr->display, scr->groupLeader);
hints->flags |= IconPixmapHint|IconMaskHint;
hints->icon_pixmap = icon->pixmap;
hints->icon_mask = icon->mask;
XSetWMHints(scr->display, scr->groupLeader, hints);
XFree(hints);
}
}
WMPixmap*
WMGetApplicationIconImage(WMScreen *scr)
{
return scr->applicationIcon;
}
void
WMSetApplicationHasAppIcon(WMScreen *scr, Bool flag)
{
scr->aflags.hasAppIcon = flag;
}
void
W_InitApplication(WMScreen *scr)
{
Window leader;
XClassHint *classHint;
XWMHints *hints;
leader = XCreateSimpleWindow(scr->display, scr->rootWin, -1, -1,
1, 1, 0, 0, 0);
if (!scr->aflags.simpleApplication) {
classHint = XAllocClassHint();
classHint->res_name = "groupLeader";
classHint->res_class = WMApplication.applicationName;
XSetClassHint(scr->display, leader, classHint);
XFree(classHint);
XSetCommand(scr->display, leader, WMApplication.argv,
WMApplication.argc);
hints = XAllocWMHints();
hints->flags = WindowGroupHint;
hints->window_group = leader;
if (scr->applicationIcon) {
hints->flags |= IconPixmapHint;
hints->icon_pixmap = scr->applicationIcon->pixmap;
if (scr->applicationIcon->mask) {
hints->flags |= IconMaskHint;
hints->icon_mask = scr->applicationIcon->mask;
}
}
XSetWMHints(scr->display, leader, hints);
XFree(hints);
}
scr->groupLeader = leader;
}

911
WINGs/wbrowser.c Normal file
View File

@@ -0,0 +1,911 @@
#include "WINGsP.h"
char *WMBrowserDidScrollNotification = "WMBrowserDidScrollNotification";
typedef struct W_Browser {
W_Class widgetClass;
W_View *view;
char **titles;
WMList **columns;
short columnCount;
short usedColumnCount; /* columns actually being used */
short minColumnWidth;
short maxVisibleColumns;
short firstVisibleColumn;
short titleHeight;
short selectedColumn;
WMSize columnSize;
void *clientData;
WMAction *action;
void *doubleClientData;
WMAction *doubleAction;
WMBrowserFillColumnProc *fillColumn;
WMScroller *scroller;
char *pathSeparator;
struct {
unsigned int isTitled:1;
unsigned int allowMultipleSelection:1;
unsigned int hasScroller:1;
/* */
unsigned int loaded:1;
unsigned int loadingColumn:1;
} flags;
} Browser;
#define COLUMN_SPACING 4
#define TITLE_SPACING 2
#define DEFAULT_WIDTH 305
#define DEFAULT_HEIGHT 200
#define DEFAULT_HAS_SCROLLER True
#define DEFAULT_SEPARATOR "/"
#define COLUMN_IS_VISIBLE(b, c) ((c) >= (b)->firstVisibleColumn \
&& (c) < (b)->firstVisibleColumn + (b)->maxVisibleColumns)
static void handleEvents(XEvent *event, void *data);
static void destroyBrowser(WMBrowser *bPtr);
static void setupScroller(WMBrowser *bPtr);
static void scrollToColumn(WMBrowser *bPtr, int column);
static void paintItem(WMList *lPtr, Drawable d, char *text, int state,
WMRect *rect);
static void loadColumn(WMBrowser *bPtr, int column);
static void resizeBrowser(WMWidget*, unsigned int, unsigned int);
W_ViewProcedureTable _BrowserViewProcedures = {
NULL,
resizeBrowser,
NULL
};
WMBrowser*
WMCreateBrowser(WMWidget *parent)
{
WMBrowser *bPtr;
int i;
bPtr = wmalloc(sizeof(WMBrowser));
memset(bPtr, 0, sizeof(WMBrowser));
bPtr->widgetClass = WC_Browser;
bPtr->view = W_CreateView(W_VIEW(parent));
if (!bPtr->view) {
free(bPtr);
return NULL;
}
bPtr->view->self = bPtr;
WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, bPtr);
/* default configuration */
bPtr->flags.hasScroller = DEFAULT_HAS_SCROLLER;
bPtr->titleHeight = 20;
bPtr->flags.isTitled = 1;
bPtr->maxVisibleColumns = 2;
resizeBrowser(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
bPtr->pathSeparator = wstrdup(DEFAULT_SEPARATOR);
if (bPtr->flags.hasScroller)
setupScroller(bPtr);
for (i=0; i<bPtr->maxVisibleColumns; i++) {
WMAddBrowserColumn(bPtr);
}
bPtr->usedColumnCount = 0;
bPtr->selectedColumn = -1;
return bPtr;
}
int
WMGetBrowserNumberOfColumns(WMBrowser *bPtr)
{
return bPtr->usedColumnCount;
}
void
WMSetBrowserPathSeparator(WMBrowser *bPtr, char *separator)
{
if (bPtr->pathSeparator)
free(bPtr->pathSeparator);
bPtr->pathSeparator = wstrdup(separator);
}
static void
drawTitleOfColumn(WMBrowser *bPtr, int column)
{
WMScreen *scr = bPtr->view->screen;
int x;
x=(column-bPtr->firstVisibleColumn)*(bPtr->columnSize.width+COLUMN_SPACING);
XFillRectangle(scr->display, bPtr->view->window, W_GC(scr->darkGray), x, 0,
bPtr->columnSize.width, bPtr->titleHeight);
W_DrawRelief(scr, bPtr->view->window, x, 0,
bPtr->columnSize.width, bPtr->titleHeight, WRSunken);
if (column < bPtr->usedColumnCount && bPtr->titles[column])
W_PaintText(bPtr->view, bPtr->view->window, scr->boldFont, x,
(bPtr->titleHeight-scr->boldFont->height)/2,
bPtr->columnSize.width, WACenter, W_GC(scr->white),
False, bPtr->titles[column], strlen(bPtr->titles[column]));
}
void
WMSetBrowserColumnTitle(WMBrowser *bPtr, int column, char *title)
{
assert(column >= 0);
assert(column < bPtr->usedColumnCount);
if (bPtr->titles[column])
free(bPtr->titles[column]);
bPtr->titles[column] = wstrdup(title);
if (COLUMN_IS_VISIBLE(bPtr, column) && bPtr->flags.isTitled) {
drawTitleOfColumn(bPtr, column);
}
}
WMList*
WMGetBrowserListInColumn(WMBrowser *bPtr, int column)
{
if (column < 0 || column >= bPtr->usedColumnCount)
return NULL;
return bPtr->columns[column];
}
void
WMSetBrowserFillColumnProc(WMBrowser *bPtr, WMBrowserFillColumnProc *proc)
{
bPtr->fillColumn = proc;
}
int
WMGetBrowserFirstVisibleColumn(WMBrowser *bPtr)
{
return bPtr->firstVisibleColumn;
}
static void
removeColumn(WMBrowser *bPtr, int column)
{
int i;
WMList **clist;
char **tlist;
if (column >= bPtr->usedColumnCount)
return;
if (column < bPtr->maxVisibleColumns) {
int tmp;
for (i=column; i < bPtr->maxVisibleColumns; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMClearList(bPtr->columns[i]);
bPtr->usedColumnCount--;
}
tmp = bPtr->columnCount;
for (i=bPtr->maxVisibleColumns; i < tmp; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMDestroyWidget(bPtr->columns[i]);
bPtr->columns[i] = NULL;
bPtr->columnCount--;
bPtr->usedColumnCount--;
}
} else {
int tmp = bPtr->columnCount;
for (i=column; i < tmp; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMDestroyWidget(bPtr->columns[i]);
bPtr->columns[i] = NULL;
bPtr->columnCount--;
bPtr->usedColumnCount--;
}
}
clist = wmalloc(sizeof(WMList*)*bPtr->columnCount);
tlist = wmalloc(sizeof(char*)*bPtr->columnCount);
memcpy(clist, bPtr->columns, sizeof(WMList*)*bPtr->columnCount);
memcpy(tlist, bPtr->titles, sizeof(char*)*bPtr->columnCount);
free(bPtr->titles);
free(bPtr->columns);
bPtr->titles = tlist;
bPtr->columns = clist;
}
WMListItem*
WMGetBrowserSelectedItemInColumn(WMBrowser *bPtr, int column)
{
if ((column < 0) || (column > bPtr->columnCount))
return NULL;
return WMGetListSelectedItem(bPtr->columns[column]);
}
int
WMGetBrowserSelectedColumn(WMBrowser *bPtr)
{
return bPtr->selectedColumn;
}
int
WMGetBrowserSelectedRowInColumn(WMBrowser *bPtr, int column)
{
if (column >= 0 && column < bPtr->columnCount) {
return WMGetListSelectedItemRow(bPtr->columns[column]);
} else {
return -1;
}
}
void
WMSetBrowserTitled(WMBrowser *bPtr, Bool flag)
{
int i;
int columnX, columnY;
if (bPtr->flags.isTitled == flag)
return;
columnX = 0;
if (!bPtr->flags.isTitled) {
columnY = TITLE_SPACING + bPtr->titleHeight;
bPtr->columnSize.height -= columnY;
for (i=0; i<bPtr->columnCount; i++) {
WMResizeWidget(bPtr->columns[i], bPtr->columnSize.width,
bPtr->columnSize.height);
columnX = WMWidgetView(bPtr->columns[i])->pos.x;
WMMoveWidget(bPtr->columns[i], columnX, columnY);
}
} else {
bPtr->columnSize.height += TITLE_SPACING + bPtr->titleHeight;
for (i=0; i<bPtr->columnCount; i++) {
WMResizeWidget(bPtr->columns[i], bPtr->columnSize.width,
bPtr->columnSize.height);
columnX = WMWidgetView(bPtr->columns[i])->pos.x;
WMMoveWidget(bPtr->columns[i], columnX, 0);
}
}
bPtr->flags.isTitled = flag;
}
WMListItem*
WMAddSortedBrowserItem(WMBrowser *bPtr, int column, char *text, Bool isBranch)
{
WMListItem *item;
if (column < 0 || column >= bPtr->columnCount)
return NULL;
item = WMAddSortedListItem(bPtr->columns[column], text);
item->isBranch = isBranch;
return item;
}
WMListItem*
WMInsertBrowserItem(WMBrowser *bPtr, int column, int row, char *text,
Bool isBranch)
{
WMListItem *item;
if (column < 0 || column >= bPtr->columnCount)
return NULL;
item = WMInsertListItem(bPtr->columns[column], row, text);
item->isBranch = isBranch;
return item;
}
static void
resizeBrowser(WMWidget *w, unsigned int width, unsigned int height)
{
WMBrowser *bPtr = (WMBrowser*)w;
int cols = bPtr->maxVisibleColumns;
int colX, colY;
int i;
assert(width > 0);
assert(height > 0);
bPtr->columnSize.width = (width-(cols-1)*COLUMN_SPACING) / cols;
bPtr->columnSize.height = height;
if (bPtr->flags.isTitled) {
bPtr->columnSize.height -= TITLE_SPACING + bPtr->titleHeight;
colY = TITLE_SPACING + bPtr->titleHeight;
} else {
colY = 0;
}
if (bPtr->flags.hasScroller) {
bPtr->columnSize.height -= SCROLLER_WIDTH + 4;
if (bPtr->scroller) {
WMResizeWidget(bPtr->scroller, width-2, 1);
WMMoveWidget(bPtr->scroller, 1, height-SCROLLER_WIDTH-1);
}
}
colX = 0;
for (i = 0; i < bPtr->columnCount; i++) {
WMResizeWidget(bPtr->columns[i], bPtr->columnSize.width,
bPtr->columnSize.height);
WMMoveWidget(bPtr->columns[i], colX, colY);
if (COLUMN_IS_VISIBLE(bPtr, i)) {
colX += bPtr->columnSize.width+COLUMN_SPACING;
}
}
W_ResizeView(bPtr->view, width, height);
}
static void
paintItem(WMList *lPtr, Drawable d, char *text, int state, WMRect *rect)
{
WMView *view = W_VIEW(lPtr);
W_Screen *scr = view->screen;
int width, height, x, y;
width = rect->size.width;
height = rect->size.height;
x = rect->pos.x;
y = rect->pos.y;
if (state & WLDSSelected)
XFillRectangle(scr->display, d, W_GC(scr->white), x, y,
width, height);
else
XClearArea(scr->display, d, x, y, width, height, False);
W_PaintText(view, d, scr->normalFont, x+4, y, width,
WALeft, W_GC(scr->black), False, text, strlen(text));
if (state & WLDSIsBranch) {
XDrawLine(scr->display, d, W_GC(scr->darkGray), x+width-11, y+3,
x+width-6, y+height/2);
if (state & WLDSSelected)
XDrawLine(scr->display, d,W_GC(scr->gray), x+width-11, y+height-5,
x+width-6, y+height/2);
else
XDrawLine(scr->display, d,W_GC(scr->white), x+width-11, y+height-5,
x+width-6, y+height/2);
XDrawLine(scr->display, d, W_GC(scr->black), x+width-12, y+3,
x+width-12, y+height-5);
}
}
static void
scrollCallback(WMWidget *scroller, void *self)
{
WMBrowser *bPtr = (WMBrowser*)self;
WMScroller *sPtr = (WMScroller*)scroller;
int newFirst;
#define LAST_VISIBLE_COLUMN bPtr->firstVisibleColumn+bPtr->maxVisibleColumns
switch (WMGetScrollerHitPart(sPtr)) {
case WSDecrementLine:
if (bPtr->firstVisibleColumn > 0) {
scrollToColumn(bPtr, bPtr->firstVisibleColumn-1);
}
break;
case WSDecrementPage:
if (bPtr->firstVisibleColumn > 0) {
newFirst = bPtr->firstVisibleColumn - bPtr->maxVisibleColumns;
scrollToColumn(bPtr, newFirst);
}
break;
case WSIncrementLine:
if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
scrollToColumn(bPtr, bPtr->firstVisibleColumn+1);
}
break;
case WSIncrementPage:
if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
newFirst = bPtr->firstVisibleColumn + bPtr->maxVisibleColumns;
if (newFirst+bPtr->maxVisibleColumns >= bPtr->columnCount)
newFirst = bPtr->columnCount - bPtr->maxVisibleColumns;
scrollToColumn(bPtr, newFirst);
}
break;
case WSKnob:
{
float floatValue;
float value = bPtr->columnCount - bPtr->maxVisibleColumns;
floatValue = WMGetScrollerValue(bPtr->scroller);
floatValue = (floatValue*value)/value;
newFirst = floatValue*(float)(bPtr->columnCount - bPtr->maxVisibleColumns);
if (bPtr->firstVisibleColumn != newFirst)
scrollToColumn(bPtr, newFirst);
else
WMSetScrollerParameters(bPtr->scroller, floatValue,
bPtr->maxVisibleColumns/(float)bPtr->columnCount);
}
break;
case WSKnobSlot:
case WSNoPart:
/* do nothing */
break;
}
#undef LAST_VISIBLE_COLUMN
}
static void
setupScroller(WMBrowser *bPtr)
{
WMScroller *sPtr;
int y;
y = bPtr->view->size.height - SCROLLER_WIDTH - 1;
sPtr = WMCreateScroller(bPtr);
WMSetScrollerAction(sPtr, scrollCallback, bPtr);
WMMoveWidget(sPtr, 1, y);
WMResizeWidget(sPtr, bPtr->view->size.width-2, SCROLLER_WIDTH);
bPtr->scroller = sPtr;
WMMapWidget(sPtr);
}
void
WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData)
{
bPtr->action = action;
bPtr->clientData = clientData;
}
void
WMSetBrowserHasScroller(WMBrowser *bPtr, int hasScroller)
{
bPtr->flags.hasScroller = hasScroller;
}
Bool
WMSetBrowserPath(WMBrowser *bPtr, char *path)
{
int i;
char *str = wstrdup(path);
char *tmp;
int item;
Bool ok = True;
WMListItem *listItem;
removeColumn(bPtr, 1);
i = 0;
tmp = strtok(str, bPtr->pathSeparator);
while (tmp) {
/* select it in the column */
item = WMFindRowOfListItemWithTitle(bPtr->columns[i], tmp);
if (item<0) {
ok = False;
break;
}
WMSelectListItem(bPtr->columns[i], item);
WMSetListPosition(bPtr->columns[i], item);
listItem = WMGetListItem(bPtr->columns[i], item);
if (!listItem || !listItem->isBranch) {
break;
}
/* load next column */
WMAddBrowserColumn(bPtr);
loadColumn(bPtr, i+1);
tmp = strtok(NULL, bPtr->pathSeparator);
i++;
}
free(str);
bPtr->selectedColumn = bPtr->usedColumnCount - 1;
scrollToColumn(bPtr, bPtr->columnCount-bPtr->maxVisibleColumns);
return ok;
}
char*
WMGetBrowserPath(WMBrowser *bPtr)
{
return WMGetBrowserPathToColumn(bPtr, bPtr->columnCount);
}
char*
WMGetBrowserPathToColumn(WMBrowser *bPtr, int column)
{
int i, size;
char *path;
WMListItem *item;
if (column >= bPtr->usedColumnCount)
column = bPtr->usedColumnCount-1;
/* calculate size of buffer */
size = 0;
for (i = 0; i <= column; i++) {
item = WMGetListSelectedItem(bPtr->columns[i]);
if (!item)
break;
size += strlen(item->text);
}
/* get the path */
path = wmalloc(size+(column+1)*strlen(bPtr->pathSeparator)+1);
/* ignore first / */
*path = 0;
for (i = 0; i <= column; i++) {
strcat(path, bPtr->pathSeparator);
item = WMGetListSelectedItem(bPtr->columns[i]);
if (!item)
break;
strcat(path, item->text);
}
return path;
}
static void
loadColumn(WMBrowser *bPtr, int column)
{
assert(bPtr->fillColumn);
bPtr->flags.loadingColumn = 1;
(*bPtr->fillColumn)(bPtr, column);
bPtr->flags.loadingColumn = 0;
}
static void
paintBrowser(WMBrowser *bPtr)
{
int i;
if (!bPtr->view->flags.mapped)
return;
W_DrawRelief(bPtr->view->screen, bPtr->view->window, 0,
bPtr->view->size.height-SCROLLER_WIDTH-2,
bPtr->view->size.width, 22, WRSunken);
if (bPtr->flags.isTitled) {
for (i=0; i<bPtr->maxVisibleColumns; i++) {
drawTitleOfColumn(bPtr, i+bPtr->firstVisibleColumn);
}
}
}
static void
handleEvents(XEvent *event, void *data)
{
WMBrowser *bPtr = (WMBrowser*)data;
CHECK_CLASS(data, WC_Browser);
switch (event->type) {
case Expose:
paintBrowser(bPtr);
break;
case DestroyNotify:
destroyBrowser(bPtr);
break;
}
}
static void
scrollToColumn(WMBrowser *bPtr, int column)
{
int i;
int x;
int notify = 0;
if (column != bPtr->firstVisibleColumn)
notify = 1;
if (column < 0)
column = 0;
x = 0;
bPtr->firstVisibleColumn = column;
for (i = 0; i < bPtr->usedColumnCount; i++) {
if (COLUMN_IS_VISIBLE(bPtr, i)) {
WMMoveWidget(bPtr->columns[i], x,
WMWidgetView(bPtr->columns[i])->pos.y);
if (!WMWidgetView(bPtr->columns[i])->flags.realized)
WMRealizeWidget(bPtr->columns[i]);
WMMapWidget(bPtr->columns[i]);
x += bPtr->columnSize.width+COLUMN_SPACING;
} else {
WMUnmapWidget(bPtr->columns[i]);
}
}
/* update the scroller */
if (bPtr->columnCount > bPtr->maxVisibleColumns) {
float value, proportion;
value = bPtr->firstVisibleColumn
/(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
WMSetScrollerParameters(bPtr->scroller, value, proportion);
} else {
WMSetScrollerParameters(bPtr->scroller, 0, 1);
}
if (bPtr->view->flags.mapped)
paintBrowser(bPtr);
if (notify)
WMPostNotificationName(WMBrowserDidScrollNotification, bPtr, NULL);
}
static void
listCallback(void *self, void *clientData)
{
WMBrowser *bPtr = (WMBrowser*)clientData;
WMList *lPtr = (WMList*)self;
WMListItem *item;
int i;
item = WMGetListSelectedItem(lPtr);
if (!item)
return;
for (i=0; i<bPtr->columnCount; i++) {
if (lPtr == bPtr->columns[i])
break;
}
assert(i<bPtr->columnCount);
bPtr->selectedColumn = i;
/* columns at right must be cleared */
removeColumn(bPtr, i+1);
/* open directory */
if (item->isBranch) {
WMAddBrowserColumn(bPtr);
loadColumn(bPtr, bPtr->usedColumnCount-1);
}
if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
i = 0;
else
i = bPtr->usedColumnCount-bPtr->maxVisibleColumns;
scrollToColumn(bPtr, i);
/* call callback for click */
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
}
void
WMLoadBrowserColumnZero(WMBrowser *bPtr)
{
if (!bPtr->flags.loaded) {
/* create column 0 */
WMAddBrowserColumn(bPtr);
loadColumn(bPtr, 0);
/* make column 0 visible */
scrollToColumn(bPtr, 0);
bPtr->flags.loaded = 1;
}
}
void
WMRemoveBrowserItem(WMBrowser *bPtr, int column, int row)
{
WMList *list;
if (column < 0 || column >= bPtr->usedColumnCount)
return;
list = WMGetBrowserListInColumn(bPtr, column);
if (row < 0 || row >= WMGetListNumberOfRows(list))
return;
removeColumn(bPtr, column+1);
if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
scrollToColumn(bPtr, 0);
else
scrollToColumn(bPtr, bPtr->usedColumnCount-bPtr->maxVisibleColumns);
WMRemoveListItem(list, row);
}
int
WMAddBrowserColumn(WMBrowser *bPtr)
{
WMList *list;
WMList **clist;
char **tlist;
int colY;
int index;
if (bPtr->usedColumnCount < bPtr->columnCount) {
return bPtr->usedColumnCount++;
}
bPtr->usedColumnCount++;
if (bPtr->flags.isTitled) {
colY = TITLE_SPACING + bPtr->titleHeight;
} else {
colY = 0;
}
index = bPtr->columnCount;
bPtr->columnCount++;
clist = wmalloc(sizeof(WMList*)*bPtr->columnCount);
tlist = wmalloc(sizeof(char*)*bPtr->columnCount);
memcpy(clist, bPtr->columns, sizeof(WMList*)*(bPtr->columnCount-1));
memcpy(tlist, bPtr->titles, sizeof(char*)*(bPtr->columnCount-1));
if (bPtr->columns)
free(bPtr->columns);
if (bPtr->titles)
free(bPtr->titles);
bPtr->columns = clist;
bPtr->titles = tlist;
bPtr->titles[index] = NULL;
list = WMCreateList(bPtr);
WMSetListAction(list, listCallback, bPtr);
WMSetListUserDrawProc(list, paintItem);
bPtr->columns[index] = list;
WMResizeWidget(list, bPtr->columnSize.width, bPtr->columnSize.height);
WMMoveWidget(list, (bPtr->columnSize.width+COLUMN_SPACING)*index, colY);
if (COLUMN_IS_VISIBLE(bPtr, index))
WMMapWidget(list);
/* update the scroller */
if (bPtr->columnCount > bPtr->maxVisibleColumns) {
float value, proportion;
value = bPtr->firstVisibleColumn
/(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
WMSetScrollerParameters(bPtr->scroller, value, proportion);
}
return index;
}
static void
destroyBrowser(WMBrowser *bPtr)
{
int i;
for (i=0; i<bPtr->columnCount; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
}
free(bPtr->titles);
free(bPtr->pathSeparator);
free(bPtr);
}

714
WINGs/wbutton.c Normal file
View File

@@ -0,0 +1,714 @@
#include "WINGsP.h"
typedef struct W_Button {
W_Class widgetClass;
WMView *view;
char *caption;
char *altCaption;
WMFont *font;
W_Pixmap *image;
W_Pixmap *altImage;
void *clientData;
WMAction *action;
int tag;
int groupIndex;
float periodicDelay;
float periodicInterval;
WMHandlerID *timer; /* for continuous mode */
struct {
WMButtonType type:4;
WMImagePosition imagePosition:4;
WMAlignment alignment:2;
unsigned int selected:1;
unsigned int enabled:1;
unsigned int bordered:1;
unsigned int springLoaded:1;
unsigned int pushIn:1; /* change relief while pushed */
unsigned int pushLight:1; /* highlight while pushed */
unsigned int pushChange:1; /* change caption while pushed */
unsigned int stateLight:1; /* state indicated by highlight */
unsigned int stateChange:1; /* state indicated by caption change */
unsigned int statePush:1; /* state indicated by relief */
unsigned int continuous:1; /* continually perform action */
/* */
unsigned int prevSelected:1;
unsigned int pushed:1;
unsigned int wasPushed:1;
unsigned int redrawPending:1;
unsigned int addedObserver:1;
} flags;
} Button;
#define DEFAULT_BUTTON_WIDTH 60
#define DEFAULT_BUTTON_HEIGHT 24
#define DEFAULT_BUTTON_ALIGNMENT WACenter
#define DEFAULT_BUTTON_IS_BORDERED True
#define DEFAULT_RADIO_WIDTH 100
#define DEFAULT_RADIO_HEIGHT 20
#define DEFAULT_RADIO_ALIGNMENT WALeft
#define DEFAULT_RADIO_IMAGE_POSITION WIPLeft
#define DEFAULT_RADIO_TEXT "Radio"
#define DEFAULT_SWITCH_WIDTH 100
#define DEFAULT_SWITCH_HEIGHT 20
#define DEFAULT_SWITCH_ALIGNMENT WALeft
#define DEFAULT_SWITCH_IMAGE_POSITION WIPLeft
#define DEFAULT_SWITCH_TEXT "Switch"
static void destroyButton(Button *bPtr);
static void paintButton(Button *bPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
W_ViewProcedureTable _ButtonViewProcedures = {
NULL,
NULL,
NULL
};
static char *WMPushedRadioNotification="WMPushedRadioNotification";
#define NFONT(b) (b)->view->screen->normalFont
WMButton*
WMCreateCustomButton(WMWidget *parent, int behaviourMask)
{
Button *bPtr;
bPtr = wmalloc(sizeof(Button));
memset(bPtr, 0, sizeof(Button));
bPtr->widgetClass = WC_Button;
bPtr->view = W_CreateView(W_VIEW(parent));
if (!bPtr->view) {
free(bPtr);
return NULL;
}
bPtr->view->self = bPtr;
bPtr->flags.type = 0;
bPtr->flags.springLoaded = (behaviourMask & WBBSpringLoadedMask)!=0;
bPtr->flags.pushIn = (behaviourMask & WBBPushInMask)!=0;
bPtr->flags.pushChange = (behaviourMask & WBBPushChangeMask)!=0;
bPtr->flags.pushLight = (behaviourMask & WBBPushLightMask)!=0;
bPtr->flags.stateLight = (behaviourMask & WBBStateLightMask)!=0;
bPtr->flags.stateChange = (behaviourMask & WBBStateChangeMask)!=0;
bPtr->flags.statePush = (behaviourMask & WBBStatePushMask)!=0;
W_ResizeView(bPtr->view, DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
bPtr->flags.alignment = DEFAULT_BUTTON_ALIGNMENT;
bPtr->flags.bordered = DEFAULT_BUTTON_IS_BORDERED;
bPtr->flags.enabled = 1;
WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask,
handleEvents, bPtr);
WMCreateEventHandler(bPtr->view, ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask,
handleActionEvents, bPtr);
W_ResizeView(bPtr->view, DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
bPtr->flags.alignment = DEFAULT_BUTTON_ALIGNMENT;
bPtr->flags.bordered = DEFAULT_BUTTON_IS_BORDERED;
return bPtr;
}
WMButton*
WMCreateButton(WMWidget *parent, WMButtonType type)
{
W_Screen *scrPtr = W_VIEW(parent)->screen;
Button *bPtr;
switch (type) {
case WBTMomentaryPush:
bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask
|WBBPushInMask|WBBPushLightMask);
break;
case WBTMomentaryChange:
bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask
|WBBPushChangeMask);
break;
case WBTPushOnPushOff:
bPtr = WMCreateCustomButton(parent, WBBPushInMask|WBBStatePushMask
|WBBStateLightMask);
break;
case WBTToggle:
bPtr = WMCreateCustomButton(parent, WBBPushInMask|WBBStateChangeMask
|WBBStatePushMask);
break;
case WBTOnOff:
bPtr = WMCreateCustomButton(parent, WBBStateLightMask);
break;
case WBTSwitch:
bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
bPtr->flags.bordered = 0;
bPtr->image = WMRetainPixmap(scrPtr->checkButtonImageOff);
bPtr->altImage = WMRetainPixmap(scrPtr->checkButtonImageOn);
break;
case WBTRadio:
bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
bPtr->flags.bordered = 0;
bPtr->image = WMRetainPixmap(scrPtr->radioButtonImageOff);
bPtr->altImage = WMRetainPixmap(scrPtr->radioButtonImageOn);
break;
default:
case WBTMomentaryLight:
bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask
|WBBPushLightMask);
bPtr->flags.bordered = 1;
break;
}
bPtr->flags.type = type;
if (type==WBTRadio) {
W_ResizeView(bPtr->view, DEFAULT_RADIO_WIDTH, DEFAULT_RADIO_HEIGHT);
WMSetButtonText(bPtr, DEFAULT_RADIO_TEXT);
bPtr->flags.alignment = DEFAULT_RADIO_ALIGNMENT;
bPtr->flags.imagePosition = DEFAULT_RADIO_IMAGE_POSITION;
} else if (type==WBTSwitch) {
W_ResizeView(bPtr->view, DEFAULT_SWITCH_WIDTH, DEFAULT_SWITCH_HEIGHT);
WMSetButtonText(bPtr, DEFAULT_SWITCH_TEXT);
bPtr->flags.alignment = DEFAULT_SWITCH_ALIGNMENT;
bPtr->flags.imagePosition = DEFAULT_SWITCH_IMAGE_POSITION;
}
return bPtr;
}
void
WMSetButtonImage(WMButton *bPtr, WMPixmap *image)
{
if (bPtr->image!=NULL)
WMReleasePixmap(bPtr->image);
bPtr->image = WMRetainPixmap(image);
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonAltImage(WMButton *bPtr, WMPixmap *image)
{
if (bPtr->altImage!=NULL)
WMReleasePixmap(bPtr->altImage);
bPtr->altImage = WMRetainPixmap(image);
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonImagePosition(WMButton *bPtr, WMImagePosition position)
{
bPtr->flags.imagePosition = position;
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonTextAlignment(WMButton *bPtr, WMAlignment alignment)
{
bPtr->flags.alignment = alignment;
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonText(WMButton *bPtr, char *text)
{
if (bPtr->caption)
free(bPtr->caption);
if (text!=NULL) {
bPtr->caption = wstrdup(text);
} else {
bPtr->caption = NULL;
}
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonAltText(WMButton *bPtr, char *text)
{
if (bPtr->altCaption)
free(bPtr->altCaption);
if (text!=NULL) {
bPtr->altCaption = wstrdup(text);
} else {
bPtr->altCaption = NULL;
}
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonSelected(WMButton *bPtr, int isSelected)
{
bPtr->flags.selected = isSelected;
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
int
WMGetButtonSelected(WMButton *bPtr)
{
CHECK_CLASS(bPtr, WC_Button);
return bPtr->flags.selected;
}
void
WMSetButtonBordered(WMButton *bPtr, int isBordered)
{
bPtr->flags.bordered = isBordered;
if (bPtr->view->flags.realized) {
paintButton(bPtr);
}
}
void
WMSetButtonFont(WMButton *bPtr, WMFont *font)
{
if (bPtr->font)
WMReleaseFont(bPtr->font);
bPtr->font = WMRetainFont(font);
}
void
WMSetButtonEnabled(WMButton *bPtr, Bool flag)
{
bPtr->flags.enabled = flag;
if (bPtr->view->flags.mapped) {
paintButton(bPtr);
}
}
void
WMSetButtonTag(WMButton *bPtr, int tag)
{
bPtr->tag = tag;
}
void
WMPerformButtonClick(WMButton *bPtr)
{
CHECK_CLASS(bPtr, WC_Button);
if (!bPtr->flags.enabled)
return;
bPtr->flags.pushed = 1;
bPtr->flags.selected = 1;
if (bPtr->view->flags.mapped) {
paintButton(bPtr);
XFlush(WMScreenDisplay(WMWidgetScreen(bPtr)));
wusleep(20000);
}
if (bPtr->groupIndex>0) {
WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
}
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
bPtr->flags.pushed = 0;
if (bPtr->view->flags.mapped)
paintButton(bPtr);
}
void
WMSetButtonAction(WMButton *bPtr, WMAction *action, void *clientData)
{
CHECK_CLASS(bPtr, WC_Button);
bPtr->action = action;
bPtr->clientData = clientData;
}
static void
radioPushObserver(void *observerData, WMNotification *notification)
{
WMButton *bPtr = (WMButton*)observerData;
WMButton *pushedButton = (WMButton*)WMGetNotificationObject(notification);
if (bPtr!=pushedButton && pushedButton->groupIndex == bPtr->groupIndex
&& bPtr->groupIndex!=0) {
if (bPtr->flags.selected) {
bPtr->flags.selected = 0;
paintButton(bPtr);
}
}
}
void
WMGroupButtons(WMButton *bPtr, WMButton *newMember)
{
static int tagIndex = 0;
CHECK_CLASS(bPtr, WC_Button);
CHECK_CLASS(newMember, WC_Button);
if (!bPtr->flags.addedObserver) {
WMAddNotificationObserver(radioPushObserver, bPtr,
WMPushedRadioNotification, NULL);
bPtr->flags.addedObserver = 1;
}
if (!newMember->flags.addedObserver) {
WMAddNotificationObserver(radioPushObserver, newMember,
WMPushedRadioNotification, NULL);
newMember->flags.addedObserver = 1;
}
if (bPtr->groupIndex==0) {
bPtr->groupIndex = ++tagIndex;
}
newMember->groupIndex = bPtr->groupIndex;
}
void
WMSetButtonContinuous(WMButton *bPtr, Bool flag)
{
bPtr->flags.continuous = flag;
if (bPtr->timer) {
WMDeleteTimerHandler(bPtr->timer);
bPtr->timer = NULL;
}
}
void
WMSetButtonPeriodicDelay(WMButton *bPtr, float delay, float interval)
{
bPtr->periodicInterval = interval;
bPtr->periodicDelay = delay;
}
static void
paintButton(Button *bPtr)
{
W_Screen *scrPtr = bPtr->view->screen;
GC gc;
WMReliefType relief;
int offset;
char *caption;
WMPixmap *image;
GC textGC;
gc = NULL;
caption = bPtr->caption;
image = bPtr->image;
offset = 0;
if (bPtr->flags.bordered)
relief = WRRaised;
else
relief = WRFlat;
if (bPtr->flags.selected) {
if (bPtr->flags.stateLight)
gc = W_GC(scrPtr->white);
if (bPtr->flags.stateChange) {
if (bPtr->altCaption) {
caption = bPtr->altCaption;
}
if (bPtr->altImage)
image = bPtr->altImage;
}
if (bPtr->flags.statePush && bPtr->flags.bordered) {
relief = WRSunken;
offset = 1;
}
}
if (bPtr->flags.pushed) {
if (bPtr->flags.pushIn) {
relief = WRPushed;
offset = 1;
}
if (bPtr->flags.pushLight)
gc = W_GC(scrPtr->white);
if (bPtr->flags.pushChange) {
if (bPtr->altCaption) {
caption = bPtr->altCaption;
}
if (bPtr->altImage)
image = bPtr->altImage;
}
}
if (bPtr->flags.enabled)
textGC = W_GC(scrPtr->black);
else
textGC = W_GC(scrPtr->darkGray);
W_PaintTextAndImage(bPtr->view, True, textGC,
(bPtr->font!=NULL ? bPtr->font : scrPtr->normalFont),
relief, caption, bPtr->flags.alignment, image,
bPtr->flags.imagePosition, gc, offset);
}
static void
handleEvents(XEvent *event, void *data)
{
Button *bPtr = (Button*)data;
CHECK_CLASS(data, WC_Button);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintButton(bPtr);
break;
case DestroyNotify:
destroyButton(bPtr);
break;
}
}
static void
autoRepeat(void *data)
{
Button *bPtr = (Button*)data;
if (bPtr->action && bPtr->flags.pushed)
(*bPtr->action)(bPtr, bPtr->clientData);
bPtr->timer = WMAddTimerHandler((int)(bPtr->periodicInterval*1000),
autoRepeat, bPtr);
}
static void
handleActionEvents(XEvent *event, void *data)
{
Button *bPtr = (Button*)data;
int doclick = 0, dopaint=0;
CHECK_CLASS(data, WC_Button);
if (!bPtr->flags.enabled)
return;
switch (event->type) {
case EnterNotify:
if (bPtr->groupIndex == 0) {
bPtr->flags.pushed = bPtr->flags.wasPushed;
if (bPtr->flags.pushed) {
bPtr->flags.selected = !bPtr->flags.prevSelected;
dopaint = 1;
}
}
break;
case LeaveNotify:
if (bPtr->groupIndex == 0) {
bPtr->flags.wasPushed = bPtr->flags.pushed;
if (bPtr->flags.pushed) {
bPtr->flags.selected = bPtr->flags.prevSelected;
dopaint = 1;
}
bPtr->flags.pushed = 0;
}
break;
case ButtonPress:
if (event->xbutton.button == Button1) {
if (bPtr->groupIndex>0) {
if (!bPtr->flags.selected)
doclick = 1;
bPtr->flags.pushed = 1;
bPtr->flags.selected = 1;
dopaint = 1;
break;
}
bPtr->flags.wasPushed = 0;
bPtr->flags.pushed = 1;
bPtr->flags.prevSelected = bPtr->flags.selected;
bPtr->flags.selected = !bPtr->flags.selected;
dopaint = 1;
if (bPtr->flags.continuous && !bPtr->timer) {
bPtr->timer = WMAddTimerHandler((int)(bPtr->periodicDelay*1000),
autoRepeat, bPtr);
}
}
break;
case ButtonRelease:
if (event->xbutton.button == Button1) {
if (bPtr->flags.pushed) {
if (bPtr->groupIndex==0)
doclick = 1;
dopaint = 1;
if (bPtr->flags.springLoaded) {
bPtr->flags.selected = bPtr->flags.prevSelected;
}
}
bPtr->flags.pushed = 0;
}
if (bPtr->timer) {
WMDeleteTimerHandler(bPtr->timer);
bPtr->timer = NULL;
}
break;
}
if (dopaint)
paintButton(bPtr);
if (doclick) {
if (bPtr->flags.selected && bPtr->groupIndex>0) {
WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
}
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
}
}
static void
destroyButton(Button *bPtr)
{
if (bPtr->flags.addedObserver) {
WMRemoveNotificationObserver(bPtr);
}
if (bPtr->timer)
WMDeleteTimerHandler(bPtr->timer);
if (bPtr->font)
WMReleaseFont(bPtr->font);
if (bPtr->caption)
free(bPtr->caption);
if (bPtr->altCaption)
free(bPtr->altCaption);
if (bPtr->image)
WMReleasePixmap(bPtr->image);
if (bPtr->altImage)
WMReleasePixmap(bPtr->altImage);
free(bPtr);
}

325
WINGs/wcolor.c Normal file
View File

@@ -0,0 +1,325 @@
#include "WINGsP.h"
#include <wraster.h>
#define LIGHT_STIPPLE_WIDTH 4
#define LIGHT_STIPPLE_HEIGHT 4
static unsigned char LIGHT_STIPPLE_BITS[] = {
0x05, 0x0a, 0x05, 0x0a};
#define DARK_STIPPLE_WIDTH 4
#define DARK_STIPPLE_HEIGHT 4
static unsigned char DARK_STIPPLE_BITS[] = {
0x0a, 0x04, 0x0a, 0x01};
static WMColor *createRGBColor(WMScreen *scr, unsigned short red,
unsigned short green, unsigned short blue);
/*
* TODO: make the color creation code return the same WMColor for the
* same colors.
* make findCloseColor() find the closest color in the RContext pallette
* or in the other colors allocated by WINGs.
*/
static WMColor*
findCloseColor(WMScreen *scr, unsigned short red, unsigned short green,
unsigned short blue)
{
WMColor *color;
XColor xcolor;
RColor rcolor;
XGCValues gcv;
rcolor.red = red>>8;
rcolor.green = green>>8;
rcolor.blue = blue>>8;
if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor))
return NULL;
if (!XAllocColor(scr->display, scr->colormap, &xcolor))
return NULL;
color = wmalloc(sizeof(WMColor));
color->screen = scr;
color->refCount = 1;
color->color = xcolor;
color->flags.exact = 1;
gcv.foreground = color->color.pixel;
gcv.graphics_exposures = False;
color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
GCForeground|GCGraphicsExposures, &gcv);
return color;
}
static WMColor*
createRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
unsigned short blue)
{
WMColor *color;
XGCValues gcv;
XColor xcolor;
xcolor.red = red;
xcolor.green = green;
xcolor.blue = blue;
xcolor.flags = DoRed|DoGreen|DoBlue;
if (!XAllocColor(scr->display, scr->colormap, &xcolor))
return NULL;
color = wmalloc(sizeof(WMColor));
color->screen = scr;
color->refCount = 1;
color->color = xcolor;
color->flags.exact = 1;
gcv.foreground = color->color.pixel;
gcv.graphics_exposures = False;
color->gc = XCreateGC(scr->display, scr->rcontext->drawable,
GCForeground|GCGraphicsExposures, &gcv);
return color;
}
WMColor*
WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green,
unsigned short blue, Bool exact)
{
WMColor *color = NULL;
if (!exact || !(color=createRGBColor(scr, red, green, blue))) {
color = findCloseColor(scr, red, green, blue);
}
if (!color)
color = WMBlackColor(scr);
return color;
}
WMColor*
WMCreateNamedColor(WMScreen *scr, char *name, Bool exact)
{
WMColor *color;
XColor xcolor;
if (!XParseColor(scr->display, scr->colormap, name, &xcolor))
return NULL;
if (!exact || !(color=createRGBColor(scr, xcolor.red, xcolor.green,
xcolor.blue))) {
color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue);
}
return color;
}
WMColor*
WMRetainColor(WMColor *color)
{
assert(color!=NULL);
color->refCount++;
return color;
}
void
WMReleaseColor(WMColor *color)
{
color->refCount--;
if (color->refCount < 1) {
XFreeColors(color->screen->display, color->screen->colormap,
&(color->color.pixel), 1, 0);
XFreeGC(color->screen->display, color->gc);
free(color);
}
}
void
WMPaintColorSwatch(WMColor *color, Drawable d, int x, int y,
unsigned int width, unsigned int height)
{
XFillRectangle(color->screen->display, d, color->gc, x, y, width, height);
}
WMPixel
WMColorPixel(WMColor *color)
{
return color->color.pixel;
}
GC
WMColorGC(WMColor *color)
{
return color->gc;
}
void
WMSetColorInGC(WMColor *color, GC gc)
{
XSetForeground(color->screen->display, gc, color->color.pixel);
}
/* "system" colors */
WMColor*
WMWhiteColor(WMScreen *scr)
{
if (!scr->white) {
scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True);
if (!scr->white->flags.exact)
wwarning("could not allocate %s color", "white");
}
return WMRetainColor(scr->white);
}
WMColor*
WMBlackColor(WMScreen *scr)
{
if (!scr->black) {
scr->black = WMCreateRGBColor(scr, 0, 0, 0, True);
if (!scr->black->flags.exact)
wwarning("could not allocate %s color", "black");
}
return WMRetainColor(scr->black);
}
WMColor*
WMGrayColor(WMScreen *scr)
{
if (!scr->gray) {
WMColor *color;
if (scr->depth == 1) {
Pixmap stipple;
WMColor *white = WMWhiteColor(scr);
WMColor *black = WMBlackColor(scr);
XGCValues gcv;
stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH,
LIGHT_STIPPLE_HEIGHT);
color = createRGBColor(scr, 0xffff, 0xffff, 0xffff);
XFreeGC(scr->display, color->gc);
gcv.foreground = white->color.pixel;
gcv.background = black->color.pixel;
gcv.fill_style = FillStippled;
gcv.stipple = stipple;
color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
|GCBackground|GCStipple|GCFillStyle
|GCGraphicsExposures, &gcv);
XFreePixmap(scr->display, stipple);
WMReleaseColor(white);
WMReleaseColor(black);
} else {
color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True);
if (!color->flags.exact)
wwarning("could not allocate %s color", "gray");
}
scr->gray = color;
}
return WMRetainColor(scr->gray);
}
WMColor*
WMDarkGrayColor(WMScreen *scr)
{
if (!scr->darkGray) {
WMColor *color;
if (scr->depth == 1) {
Pixmap stipple;
WMColor *white = WMWhiteColor(scr);
WMColor *black = WMBlackColor(scr);
XGCValues gcv;
stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr),
DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH,
DARK_STIPPLE_HEIGHT);
color = createRGBColor(scr, 0, 0, 0);
XFreeGC(scr->display, color->gc);
gcv.foreground = white->color.pixel;
gcv.background = black->color.pixel;
gcv.fill_style = FillStippled;
gcv.stipple = stipple;
color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground
|GCBackground|GCStipple|GCFillStyle
|GCGraphicsExposures, &gcv);
XFreePixmap(scr->display, stipple);
WMReleaseColor(white);
WMReleaseColor(black);
} else {
color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True);
if (!color->flags.exact)
wwarning("could not allocate %s color", "dark gray");
}
scr->darkGray = color;
}
return WMRetainColor(scr->darkGray);
}
unsigned short
WMRedComponentOfColor(WMColor *color)
{
return color->color.red;
}
unsigned short
WMGreenComponentOfColor(WMColor *color)
{
return color->color.green;
}
unsigned short
WMBlueComponentOfColor(WMColor *color)
{
return color->color.blue;
}
char*
WMGetColorRGBDescription(WMColor *color)
{
char *str = wmalloc(32);
sprintf(str, "rgb:%4x/%4x/%4x", color->color.red, color->color.green,
color->color.blue);
return str;
}

257
WINGs/wcolorwell.c Normal file
View File

@@ -0,0 +1,257 @@
#include "WINGsP.h"
typedef struct W_ColorWell {
W_Class widgetClass;
WMView *view;
WMView *colorView;
WMColor *color;
WMAction *action;
void *clientData;
WMPoint ipoint;
struct {
unsigned int active:1;
unsigned int bordered:1;
} flags;
} ColorWell;
static void destroyColorWell(ColorWell *cPtr);
static void paintColorWell(ColorWell *cPtr);
static void handleEvents(XEvent *event, void *data);
#if 0
static void handleDragEvents(XEvent *event, void *data);
#endif
static void handleActionEvents(XEvent *event, void *data);
static void resizeColorWell();
W_ViewProcedureTable _ColorWellViewProcedures = {
NULL,
resizeColorWell,
NULL
};
#if 0
static WMDragSourceProcs dragProcs = {
};
#endif
#define DEFAULT_WIDTH 60
#define DEFAULT_HEIGHT 30
#define DEFAULT_BORDER_WIDTH 6
#define MIN_WIDTH 16
#define MIN_HEIGHT 8
WMColorWell*
WMCreateColorWell(WMWidget *parent)
{
ColorWell *cPtr;
cPtr = wmalloc(sizeof(ColorWell));
memset(cPtr, 0, sizeof(ColorWell));
cPtr->widgetClass = WC_ColorWell;
cPtr->view = W_CreateView(W_VIEW(parent));
if (!cPtr->view) {
free(cPtr);
return NULL;
}
cPtr->colorView = W_CreateView(cPtr->view);
if (!cPtr->colorView) {
W_DestroyView(cPtr->view);
free(cPtr);
return NULL;
}
WMCreateEventHandler(cPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, cPtr);
WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
#if 0
WMCreateEventHandler(cPtr->colorView, ButtonPressMask|Button1MotionMask,
handleDragEvents, cPtr);
#endif
WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents,
cPtr);
cPtr->colorView->flags.mapWhenRealized = 1;
resizeColorWell(cPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
return cPtr;
}
void
WMSetColorWellColor(WMColorWell *cPtr, WMColor *color)
{
if (cPtr->color)
WMReleaseColor(cPtr->color);
cPtr->color = WMRetainColor(color);
if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
paintColorWell(cPtr);
}
WMColor*
WMGetColorWellColor(WMColorWell *cPtr)
{
return cPtr->color;
}
#define MIN(a,b) ((a) > (b) ? (b) : (a))
static void
resizeColorWell(WMColorWell *cPtr, unsigned int width, unsigned int height)
{
int bw;
if (width < MIN_WIDTH)
width = MIN_WIDTH;
if (height < MIN_HEIGHT)
height = MIN_HEIGHT;
bw = (int)((float)MIN(width, height)*0.24);
W_ResizeView(cPtr->view, width, height);
W_ResizeView(cPtr->colorView, width-2*bw, height-2*bw);
if (cPtr->colorView->pos.x!=bw || cPtr->colorView->pos.y!=bw)
W_MoveView(cPtr->colorView, bw, bw);
}
static void
paintColorWell(ColorWell *cPtr)
{
W_Screen *scr = cPtr->view->screen;
W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width,
cPtr->view->size.height, WRRaised);
W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
cPtr->colorView->size.width, cPtr->colorView->size.height,
WRSunken);
if (cPtr->color)
WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
2, 2, cPtr->colorView->size.width-4,
cPtr->colorView->size.height-4);
}
static void
handleEvents(XEvent *event, void *data)
{
ColorWell *cPtr = (ColorWell*)data;
CHECK_CLASS(data, WC_ColorWell);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintColorWell(cPtr);
break;
case DestroyNotify:
destroyColorWell(cPtr);
break;
}
}
#if 0
static WMPixmap*
makeDragPixmap(WMColorWell *cPtr)
{
WMScreen *scr = cPtr->view->screen;
Pixmap pix;
pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
}
static void
handleDragEvents(XEvent *event, void *data)
{
WMColorWell *cPtr = (ColorWell*)data;
switch (event->type) {
case ButtonPress:
if (event->xbutton.button == Button1) {
cPtr->ipoint.x = event->xbutton.x;
cPtr->ipoint.y = event->xbutton.y;
}
break;
case MotionNotify:
if (event->xmotion.state & Button1Mask) {
if (abs(cPtr->ipoint.x - event->xmotion.x) > 4
|| abs(cPtr->ipoint.y - event->xmotion.y) > 4) {
WMSize offs;
WMPixmap *pixmap;
offs.width = 2;
offs.height = 2;
pixmap = makeDragPixmap(cPtr);
WMDragImageFromView(cPtr->view, pixmap, cPtr->view->pos,
offs, event, True);
WMReleasePixmap(pixmap);
}
}
break;
}
}
#endif
static void
handleActionEvents(XEvent *event, void *data)
{
/* WMColorWell *cPtr = (ColorWell*)data;*/
}
static void
destroyColorWell(ColorWell *cPtr)
{
if (cPtr->color)
WMReleaseColor(cPtr->color);
free(cPtr);
}

918
WINGs/wevent.c Normal file
View File

@@ -0,0 +1,918 @@
/*
* This event handling stuff was based on Tk.
*/
#include "WINGsP.h"
#include "../src/config.h"
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef HAVE_GETTIMEOFDAY
# include <sys/time.h>
# ifdef TIME_WITH_SYS_TIME
# include <time.h>
# endif
#else /* ! HAVE_GETTIMEOFDAY */
# include <time.h>
#endif /* ! HAVE_GETTIMEOFDAY */
extern _WINGsConfiguration WINGsConfiguration;
typedef struct TimerHandler {
WMCallback *callback; /* procedure to call */
unsigned long msec; /* when to call the callback */
void *clientData;
struct TimerHandler *next;
} TimerHandler;
typedef struct IdleHandler {
WMCallback *callback;
void *clientData;
struct IdleHandler *next;
} IdleHandler;
typedef struct InputHandler {
WMInputProc *callback;
void *clientData;
int fd;
int mask;
struct InputHandler *next;
} InputHandler;
/* table to map event types to event masks */
static unsigned long eventMasks[] = {
0,
0,
KeyPressMask, /* KeyPress */
KeyReleaseMask, /* KeyRelease */
ButtonPressMask, /* ButtonPress */
ButtonReleaseMask, /* ButtonRelease */
PointerMotionMask|PointerMotionHintMask|ButtonMotionMask
|Button1MotionMask|Button2MotionMask|Button3MotionMask
|Button4MotionMask|Button5MotionMask,
/* MotionNotify */
EnterWindowMask, /* EnterNotify */
LeaveWindowMask, /* LeaveNotify */
FocusChangeMask, /* FocusIn */
FocusChangeMask, /* FocusOut */
KeymapStateMask, /* KeymapNotify */
ExposureMask, /* Expose */
ExposureMask, /* GraphicsExpose */
ExposureMask, /* NoExpose */
VisibilityChangeMask, /* VisibilityNotify */
SubstructureNotifyMask, /* CreateNotify */
StructureNotifyMask, /* DestroyNotify */
StructureNotifyMask, /* UnmapNotify */
StructureNotifyMask, /* MapNotify */
SubstructureRedirectMask, /* MapRequest */
StructureNotifyMask, /* ReparentNotify */
StructureNotifyMask, /* ConfigureNotify */
SubstructureRedirectMask, /* ConfigureRequest */
StructureNotifyMask, /* GravityNotify */
ResizeRedirectMask, /* ResizeRequest */
StructureNotifyMask, /* CirculateNotify */
SubstructureRedirectMask, /* CirculateRequest */
PropertyChangeMask, /* PropertyNotify */
0, /* SelectionClear */
0, /* SelectionRequest */
0, /* SelectionNotify */
ColormapChangeMask, /* ColormapNotify */
ClientMessageMask, /* ClientMessage */
0, /* Mapping Notify */
};
/* queue of timer event handlers */
static TimerHandler *timerHandler=NULL;
static IdleHandler *idleHandler=NULL;
static InputHandler *inputHandler=NULL;
/* hook for other toolkits or wmaker process their events */
static WMEventHook *extraEventHandler=NULL;
#define timerPending() (timerHandler)
#define idlePending() (idleHandler)
/* return current time in milliseconds */
#ifdef HAVE_GETTIMEOFDAY
static unsigned long
rightNow(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return 1000L*(unsigned long)tv.tv_sec + (unsigned long)tv.tv_usec/1000L;
}
#else /* !HAVE_GETTIMEOFDAY */
# define rightNow() (1000*(unsigned long)time(NULL))
#endif /* !HAVE_GETTIMEOFDAY */
WMHandlerID
WMAddTimerHandler(int milliseconds, WMCallback *callback, void *cdata)
{
TimerHandler *handler, *tmp;
handler = malloc(sizeof(TimerHandler));
if (!handler)
return NULL;
handler->msec = rightNow()+milliseconds;
handler->callback = callback;
handler->clientData = cdata;
/* insert callback in queue, sorted by time left */
if (!timerHandler || timerHandler->msec >= handler->msec) {
/* first in the queue */
handler->next = timerHandler;
timerHandler = handler;
} else {
tmp = timerHandler;
while (tmp->next && tmp->next->msec < handler->msec) {
tmp = tmp->next;
}
handler->next = tmp->next;
tmp->next = handler;
}
return handler;
}
void
WMDeleteTimerWithClientData(void *cdata)
{
TimerHandler *handler, *tmp;
if (!cdata || !timerHandler)
return;
tmp = timerHandler;
if (tmp->clientData==cdata) {
timerHandler = tmp->next;
free(tmp);
} else {
while (tmp->next) {
if (tmp->next->clientData==cdata) {
handler = tmp->next;
tmp->next = handler->next;
free(handler);
break;
}
tmp = tmp->next;
}
}
}
void
WMDeleteTimerHandler(WMHandlerID handlerID)
{
TimerHandler *tmp, *handler=(TimerHandler*)handlerID;
if (!handler || !timerHandler)
return;
tmp = timerHandler;
if (tmp==handler) {
timerHandler = handler->next;
free(handler);
} else {
while (tmp->next) {
if (tmp->next==handler) {
tmp->next=handler->next;
free(handler);
break;
}
tmp = tmp->next;
}
}
}
WMHandlerID
WMAddIdleHandler(WMCallback *callback, void *cdata)
{
IdleHandler *handler, *tmp;
handler = malloc(sizeof(IdleHandler));
if (!handler)
return NULL;
handler->callback = callback;
handler->clientData = cdata;
handler->next = NULL;
/* add callback at end of queue */
if (!idleHandler) {
idleHandler = handler;
} else {
tmp = idleHandler;
while (tmp->next) {
tmp = tmp->next;
}
tmp->next = handler;
}
return handler;
}
void
WMDeleteIdleHandler(WMHandlerID handlerID)
{
IdleHandler *tmp, *handler = (IdleHandler*)handlerID;
if (!handler || !idleHandler)
return;
tmp = idleHandler;
if (tmp == handler) {
idleHandler = handler->next;
free(handler);
} else {
while (tmp->next) {
if (tmp->next == handler) {
tmp->next = handler->next;
free(handler);
break;
}
tmp = tmp->next;
}
}
}
WMHandlerID
WMAddInputHandler(int fd, int condition, WMInputProc *proc, void *clientData)
{
InputHandler *handler;
handler = wmalloc(sizeof(InputHandler));
handler->fd = fd;
handler->mask = condition;
handler->callback = proc;
handler->clientData = clientData;
handler->next = inputHandler;
inputHandler = handler;
return handler;
}
void
WMDeleteInputHandler(WMHandlerID handlerID)
{
InputHandler *tmp, *handler = (InputHandler*)handlerID;
if (!handler || !inputHandler)
return;
tmp = inputHandler;
if (tmp == handler) {
inputHandler = handler->next;
free(handler);
} else {
while (tmp->next) {
if (tmp->next == handler) {
tmp->next = handler->next;
free(handler);
break;
}
tmp = tmp->next;
}
}
}
static void
checkIdleHandlers()
{
IdleHandler *handler, *tmp;
if (!idleHandler)
return;
handler = idleHandler;
/* we will process all idleHandlers so, empty the handler list */
idleHandler = NULL;
while (handler) {
tmp = handler->next;
(*handler->callback)(handler->clientData);
/* remove the handler */
free(handler);
handler = tmp;
}
}
static void
checkTimerHandlers()
{
TimerHandler *handler;
unsigned long now = rightNow();
if (!timerHandler || (timerHandler->msec > now))
return;
while (timerHandler && timerHandler->msec <= now) {
handler = timerHandler;
timerHandler = timerHandler->next;
handler->next = NULL;
(*handler->callback)(handler->clientData);
free(handler);
}
}
static unsigned long
msToNextTimerEvent()
{
unsigned long now;
if (!timerHandler) {
/* The return value of this function is only valid if there _are_
timers active. */
return 0;
}
now = rightNow();
if (timerHandler->msec < now) {
return 0;
} else {
return timerHandler->msec - now;
}
}
/*
* WMCreateEventHandler--
* Create an event handler and put it in the event handler list for the
* view. If the same callback and clientdata are already used in another
* handler, the masks are swapped.
*
*/
void
WMCreateEventHandler(WMView *view, unsigned long mask, WMEventProc *eventProc,
void *clientData)
{
W_EventHandler *handler;
W_EventHandler *ptr = view->handlerList;
unsigned long eventMask;
if (ptr==NULL) {
handler = wmalloc(sizeof(W_EventHandler));
handler->nextHandler = NULL;
view->handlerList = handler;
eventMask = mask;
} else {
handler = NULL;
eventMask = mask;
while (ptr != NULL) {
if (ptr->clientData == clientData && ptr->proc == eventProc) {
handler = ptr;
}
eventMask |= ptr->eventMask;
ptr = ptr->nextHandler;
}
if (!handler) {
handler = wmalloc(sizeof(W_EventHandler));
handler->nextHandler = view->handlerList;
view->handlerList = handler;
}
}
/* select events for window */
handler->eventMask = mask;
handler->proc = eventProc;
handler->clientData = clientData;
}
/*
* WMDeleteEventHandler--
* Delete event handler matching arguments from windows
* event handler list.
*
*/
void
WMDeleteEventHandler(WMView *view, unsigned long mask, WMEventProc *eventProc,
void *clientData)
{
W_EventHandler *handler, *ptr, *pptr;
ptr = view->handlerList;
handler = NULL;
pptr = NULL;
while (ptr!=NULL) {
if (ptr->eventMask == mask && ptr->proc == eventProc
&& ptr->clientData == clientData) {
handler = ptr;
break;
}
pptr = ptr;
ptr = ptr->nextHandler;
}
if (!handler)
return;
if (!pptr) {
view->handlerList = handler->nextHandler;
} else {
pptr->nextHandler = handler->nextHandler;
}
free(handler);
}
void
W_CleanUpEvents(WMView *view)
{
W_EventHandler *ptr, *nptr;
ptr = view->handlerList;
while (ptr!=NULL) {
nptr = ptr->nextHandler;
free(ptr);
ptr = nptr;
}
}
static Time
getEventTime(WMScreen *screen, XEvent *event)
{
switch (event->type) {
case ButtonPress:
case ButtonRelease:
return event->xbutton.time;
case KeyPress:
case KeyRelease:
return event->xkey.time;
case MotionNotify:
return event->xmotion.time;
case EnterNotify:
case LeaveNotify:
return event->xcrossing.time;
case PropertyNotify:
return event->xproperty.time;
case SelectionClear:
return event->xselectionclear.time;
case SelectionRequest:
return event->xselectionrequest.time;
case SelectionNotify:
return event->xselection.time;
default:
return screen->lastEventTime;
}
}
void
W_CallDestroyHandlers(W_View *view)
{
XEvent event;
W_EventHandler *hPtr;
event.type = DestroyNotify;
event.xdestroywindow.window = view->window;
event.xdestroywindow.event = view->window;
hPtr = view->handlerList;
while (hPtr!=NULL) {
if (hPtr->eventMask & StructureNotifyMask) {
(*hPtr->proc)(&event, hPtr->clientData);
}
hPtr = hPtr->nextHandler;
}
}
int
WMHandleEvent(XEvent *event)
{
W_EventHandler *hPtr;
W_View *view, *vPtr, *toplevel;
unsigned long mask;
Window window;
if (event->type == MappingNotify) {
XRefreshKeyboardMapping(&event->xmapping);
return True;
}
mask = eventMasks[event->xany.type];
window = event->xany.window;
/* diferentiate SubstructureNotify with StructureNotify */
if (mask == StructureNotifyMask) {
if (event->xmap.event != event->xmap.window) {
mask = SubstructureNotifyMask;
window = event->xmap.event;
}
}
view = W_GetViewForXWindow(event->xany.display, window);
if (!view) {
if (extraEventHandler)
(extraEventHandler)(event);
return False;
}
view->screen->lastEventTime = getEventTime(view->screen, event);
toplevel = W_TopLevelOfView(view);
/* if it's a key event, redispatch it to the focused control */
if (mask & (KeyPressMask|KeyReleaseMask)) {
W_View *focused = W_FocusedViewOfToplevel(toplevel);
if (focused) {
view = focused;
}
}
/* compress Motion events */
if (event->type == MotionNotify && !view->flags.dontCompressMotion) {
while (XPending(event->xmotion.display)) {
XEvent ev;
XPeekEvent(event->xmotion.display, &ev);
if (ev.type == MotionNotify
&& event->xmotion.window == ev.xmotion.window
&& event->xmotion.subwindow == ev.xmotion.subwindow) {
/* replace events */
XNextEvent(event->xmotion.display, event);
} else break;
}
}
/* compress expose events */
if (event->type == Expose && !view->flags.dontCompressExpose) {
while (XCheckTypedWindowEvent(event->xexpose.display, view->window,
Expose, event));
}
if (view->screen->modal && toplevel!=view->screen->modalView
&& !toplevel->flags.worksWhenModal) {
if (event->type == KeyPress || event->type == KeyRelease
|| event->type == MotionNotify || event->type == ButtonPress
|| event->type == ButtonRelease
|| event->type == FocusIn || event->type == FocusOut) {
return True;
}
}
/* This is a hack. It will make the panel be secure while
* the event handlers are handled, as some event handler
* might destroy the widget. */
W_RetainView(toplevel);
hPtr = view->handlerList;
while (hPtr!=NULL) {
W_EventHandler *tmp;
tmp = hPtr->nextHandler;
if ((hPtr->eventMask & mask)) {
(*hPtr->proc)(event, hPtr->clientData);
}
hPtr = tmp;
}
/* pass the event to the top level window of the widget */
if (view->parent!=NULL) {
vPtr = view;
while (vPtr->parent!=NULL)
vPtr = vPtr->parent;
hPtr = vPtr->handlerList;
while (hPtr!=NULL) {
if (hPtr->eventMask & mask) {
(*hPtr->proc)(event, hPtr->clientData);
}
hPtr = hPtr->nextHandler;
}
}
/* save button click info to track double-clicks */
if (view->screen->ignoreNextDoubleClick) {
view->screen->ignoreNextDoubleClick = 0;
} else {
if (event->type == ButtonPress) {
view->screen->lastClickWindow = event->xbutton.window;
view->screen->lastClickTime = event->xbutton.time;
}
}
W_ReleaseView(toplevel);
return True;
}
int
WMIsDoubleClick(XEvent *event)
{
W_View *view;
if (event->type != ButtonPress)
return False;
view = W_GetViewForXWindow(event->xany.display, event->xbutton.window);
if (!view)
return False;
if (view->screen->lastClickWindow != event->xbutton.window)
return False;
if (event->xbutton.time - view->screen->lastClickTime
< WINGsConfiguration.doubleClickDelay) {
view->screen->lastClickTime = 0;
view->screen->lastClickWindow = None;
view->screen->ignoreNextDoubleClick = 1;
return True;
} else
return False;
}
Bool
W_WaitForEvent(Display *dpy, unsigned long xeventmask)
{
#ifndef HAVE_SELECT
#error This_system_does_not_have_select(2)_and_is_not_supported
#endif
unsigned long milliseconds;
struct timeval timeout;
struct timeval *timeoutPtr;
fd_set rset, wset, eset;
int maxfd;
int count;
InputHandler *handler = inputHandler;
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);
FD_SET(ConnectionNumber(dpy), &rset);
maxfd = ConnectionNumber(dpy);
while (handler) {
if (handler->mask & WIReadMask)
FD_SET(handler->fd, &rset);
if (handler->mask & WIWriteMask)
FD_SET(handler->fd, &wset);
if (handler->mask & WIExceptMask)
FD_SET(handler->fd, &eset);
if (maxfd < handler->fd)
maxfd = handler->fd;
handler = handler->next;
}
/*
* Setup the select() timeout to the estimated time until the
* next timer expires.
*/
if (timerPending()) {
milliseconds = msToNextTimerEvent();
timeout.tv_sec = milliseconds / 1000;
timeout.tv_usec = (milliseconds % 1000) * 1000;
timeoutPtr = &timeout;
} else {
timeoutPtr = (struct timeval*)0;
}
XSync(dpy, False);
if (xeventmask==0) {
if (XPending(dpy))
return True;
} else {
XEvent ev;
if (XCheckMaskEvent(dpy, xeventmask, &ev)) {
XPutBackEvent(dpy, &ev);
return True;
}
}
/* TODO: port to poll() */
count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr);
if (count > 0) {
handler = inputHandler;
while (handler) {
int mask;
mask = 0;
if (FD_ISSET(handler->fd, &rset))
mask |= WIReadMask;
if (FD_ISSET(handler->fd, &wset))
mask |= WIWriteMask;
if (FD_ISSET(handler->fd, &eset))
mask |= WIExceptMask;
if (mask!=0 && handler->callback) {
(*handler->callback)(handler->fd, mask,
handler->clientData);
}
handler = handler->next;
}
}
return FD_ISSET(ConnectionNumber(dpy), &rset);
}
void
WMNextEvent(Display *dpy, XEvent *event)
{
/* Check any expired timers */
if (timerPending()) {
checkTimerHandlers();
}
while (XPending(dpy) == 0) {
/* Do idle stuff */
/* Do idle and timer stuff while there are no timer or X events */
while (!XPending(dpy) && idlePending()) {
if (idlePending())
checkIdleHandlers();
/* dispatch timer events */
if (timerPending())
checkTimerHandlers();
}
/*
* Make sure that new events did not arrive while we were doing
* timer/idle stuff. Or we might block forever waiting for
* an event that already arrived.
*/
/* wait to something happen */
W_WaitForEvent(dpy, 0);
/* Check any expired timers */
if (timerPending()) {
checkTimerHandlers();
}
}
XNextEvent(dpy, event);
}
#if 0
void
WMMaskEvent(Display *dpy, long mask, XEvent *event)
{
unsigned long milliseconds;
struct timeval timeout;
struct timeval *timeoutOrInfty;
fd_set readset;
while (!XCheckMaskEvent(dpy, mask, event)) {
/* Do idle stuff while there are no timer or X events */
while (idlePending()) {
checkIdleHandlers();
if (XCheckMaskEvent(dpy, mask, event))
return;
}
/*
* Setup the select() timeout to the estimated time until the
* next timer expires.
*/
if (timerPending()) {
milliseconds = msToNextTimerEvent();
timeout.tv_sec = milliseconds / 1000;
timeout.tv_usec = (milliseconds % 1000) * 1000;
timeoutOrInfty = &timeout;
} else {
timeoutOrInfty = (struct timeval*)0;
}
if (XCheckMaskEvent(dpy, mask, event))
return;
/* Wait for input on the X connection socket */
FD_ZERO(&readset);
FD_SET(ConnectionNumber(dpy), &readset);
select(1 + ConnectionNumber(dpy), &readset, (fd_set*)0, (fd_set*)0,
timeoutOrInfty);
/* Check any expired timers */
if (timerPending()) {
checkTimerHandlers();
}
}
}
#endif
#if 1
/*
* Cant use this because XPending() will make W_WaitForEvent
* return even if the event in the queue is not what we want,
* and if we block until some new event arrives from the
* server, other events already in the queue (like Expose)
* will be deferred.
*/
void
WMMaskEvent(Display *dpy, long mask, XEvent *event)
{
while (!XCheckMaskEvent(dpy, mask, event)) {
/* Do idle stuff while there are no timer or X events */
while (idlePending()) {
checkIdleHandlers();
if (XCheckMaskEvent(dpy, mask, event))
return;
}
/* Wait for input on the X connection socket */
W_WaitForEvent(dpy, mask);
/* Check any expired timers */
if (timerPending()) {
checkTimerHandlers();
}
}
}
#endif
Bool
WMScreenPending(WMScreen *scr)
{
if (XPending(scr->display))
return True;
else
return False;
}
WMEventHook*
WMHookEventHandler(WMEventHook *handler)
{
WMEventHook *oldHandler = extraEventHandler;
extraEventHandler = handler;
return oldHandler;
}

559
WINGs/wfilepanel.c Normal file
View File

@@ -0,0 +1,559 @@
#include "WINGsP.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
typedef struct W_FilePanel {
WMWindow *win;
WMLabel *iconLabel;
WMLabel *titleLabel;
WMFrame *line;
WMLabel *nameLabel;
WMBrowser *browser;
WMButton *okButton;
WMButton *cancelButton;
WMButton *homeButton;
WMTextField *fileField;
char **fileTypes;
struct {
unsigned int canExit:1;
unsigned int canceled:1; /* clicked on cancel */
unsigned int done:1;
unsigned int filtered:1;
unsigned int canChooseFiles:1;
unsigned int canChooseDirectories:1;
unsigned int showAllFiles:1;
unsigned int canFreeFileTypes:1;
unsigned int fileMustExist:1;
} flags;
} W_FilePanel;
#define PWIDTH 320
#define PHEIGHT 360
static void listDirectoryOnColumn(WMFilePanel *panel, int column, char *path);
static void browserClick();
static void fillColumn(WMBrowser *bPtr, int column);
static void goHome();
static void buttonClick();
static char *getCurrentFileName(WMFilePanel *panel);
static int
closestListItem(WMList *list, char *text)
{
WMListItem *item = WMGetListItem(list, 0);
int i = 0;
int len = strlen(text);
if (len==0)
return -1;
while (item) {
if (strlen(item->text) >= len && strncmp(item->text, text, len)==0) {
return i;
}
item = item->nextPtr;
i++;
}
return -1;
}
static void
textChangedObserver(void *observerData, WMNotification *notification)
{
W_FilePanel *panel = (W_FilePanel*)observerData;
char *text;
WMList *list;
int col = WMGetBrowserNumberOfColumns(panel->browser) - 1;
int i;
list = WMGetBrowserListInColumn(panel->browser, col);
if (!list)
return;
text = WMGetTextFieldText(panel->fileField);
i = closestListItem(list, text);
WMSelectListItem(list, i);
if (i>=0)
WMSetListPosition(list, i);
free(text);
}
static void
textEditedObserver(void *observerData, WMNotification *notification)
{
W_FilePanel *panel = (W_FilePanel*)observerData;
if ((int)WMGetNotificationClientData(notification)==WMReturnTextMovement) {
WMPerformButtonClick(panel->okButton);
}
}
static WMFilePanel*
makeFilePanel(WMScreen *scrPtr, char *name, char *title)
{
WMFilePanel *fPtr;
WMFont *largeFont;
fPtr = wmalloc(sizeof(WMFilePanel));
memset(fPtr, 0, sizeof(WMFilePanel));
fPtr->win = WMCreateWindowWithStyle(scrPtr, name, WMTitledWindowMask
|WMResizableWindowMask);
WMResizeWidget(fPtr->win, PWIDTH, PHEIGHT);
WMSetWindowTitle(fPtr->win, "");
fPtr->iconLabel = WMCreateLabel(fPtr->win);
WMResizeWidget(fPtr->iconLabel, 64, 64);
WMMoveWidget(fPtr->iconLabel, 0, 0);
WMSetLabelImagePosition(fPtr->iconLabel, WIPImageOnly);
WMSetLabelImage(fPtr->iconLabel, scrPtr->applicationIcon);
fPtr->titleLabel = WMCreateLabel(fPtr->win);
WMResizeWidget(fPtr->titleLabel, PWIDTH-64, 64);
WMMoveWidget(fPtr->titleLabel, 64, 0);
largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
WMSetLabelFont(fPtr->titleLabel, largeFont);
WMReleaseFont(largeFont);
WMSetLabelText(fPtr->titleLabel, title);
fPtr->line = WMCreateFrame(fPtr->win);
WMMoveWidget(fPtr->line, 0, 64);
WMResizeWidget(fPtr->line, PWIDTH, 2);
WMSetFrameRelief(fPtr->line, WRGroove);
fPtr->browser = WMCreateBrowser(fPtr->win);
WMSetBrowserFillColumnProc(fPtr->browser, fillColumn);
WMSetBrowserAction(fPtr->browser, browserClick, fPtr);
WMMoveWidget(fPtr->browser, 7, 72);
WMHangData(fPtr->browser, fPtr);
fPtr->nameLabel = WMCreateLabel(fPtr->win);
WMMoveWidget(fPtr->nameLabel, 7, 282);
WMResizeWidget(fPtr->nameLabel, 55, 14);
WMSetLabelText(fPtr->nameLabel, "Name:");
fPtr->fileField = WMCreateTextField(fPtr->win);
WMMoveWidget(fPtr->fileField, 60, 278);
WMResizeWidget(fPtr->fileField, PWIDTH-60-10, 24);
WMAddNotificationObserver(textEditedObserver, fPtr,
WMTextDidEndEditingNotification,
fPtr->fileField);
WMAddNotificationObserver(textChangedObserver, fPtr,
WMTextDidChangeNotification,
fPtr->fileField);
fPtr->okButton = WMCreateCommandButton(fPtr->win);
WMMoveWidget(fPtr->okButton, 230, 325);
WMResizeWidget(fPtr->okButton, 80, 28);
WMSetButtonText(fPtr->okButton, "OK");
WMSetButtonImage(fPtr->okButton, scrPtr->buttonArrow);
WMSetButtonAltImage(fPtr->okButton, scrPtr->pushedButtonArrow);
WMSetButtonImagePosition(fPtr->okButton, WIPRight);
WMSetButtonAction(fPtr->okButton, buttonClick, fPtr);
fPtr->cancelButton = WMCreateCommandButton(fPtr->win);
WMMoveWidget(fPtr->cancelButton, 140, 325);
WMResizeWidget(fPtr->cancelButton, 80, 28);
WMSetButtonText(fPtr->cancelButton, "Cancel");
WMSetButtonAction(fPtr->cancelButton, buttonClick, fPtr);
fPtr->homeButton = WMCreateCommandButton(fPtr->win);
WMMoveWidget(fPtr->homeButton, 55, 325);
WMResizeWidget(fPtr->homeButton, 28, 28);
WMSetButtonImagePosition(fPtr->homeButton, WIPImageOnly);
WMSetButtonImage(fPtr->homeButton, scrPtr->homeIcon);
WMSetButtonAction(fPtr->homeButton, goHome, fPtr);
WMRealizeWidget(fPtr->win);
WMMapSubwidgets(fPtr->win);
WMLoadBrowserColumnZero(fPtr->browser);
fPtr->flags.canChooseFiles = 1;
fPtr->flags.canChooseDirectories = 1;
return fPtr;
}
WMOpenPanel*
WMGetOpenPanel(WMScreen *scrPtr)
{
WMFilePanel *panel;
if (scrPtr->sharedOpenPanel)
return scrPtr->sharedOpenPanel;
panel = makeFilePanel(scrPtr, "openFilePanel", "Open");
panel->flags.fileMustExist = 1;
scrPtr->sharedOpenPanel = panel;
return panel;
}
WMSavePanel*
WMGetSavePanel(WMScreen *scrPtr)
{
WMFilePanel *panel;
if (scrPtr->sharedSavePanel)
return scrPtr->sharedSavePanel;
panel = makeFilePanel(scrPtr, "saveFilePanel", "Save");
panel->flags.fileMustExist = 0;
scrPtr->sharedSavePanel = panel;
return panel;
}
void
WMFreeFilePanel(WMFilePanel *panel)
{
if (panel == WMWidgetScreen(panel->win)->sharedOpenPanel) {
WMWidgetScreen(panel->win)->sharedOpenPanel = NULL;
}
WMRemoveNotificationObserver(panel);
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
free(panel);
}
int
WMRunModalSavePanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name)
{
WMScreen *scr = WMWidgetScreen(panel->win);
XEvent event;
WMChangePanelOwner(panel->win, owner);
WMSetFilePanelDirectory(panel, path);
panel->flags.done = 0;
panel->fileTypes = NULL;
panel->flags.filtered = 0;
WMMapWidget(panel->win);
while (!panel->flags.done) {
WMNextEvent(scr->display, &event);
WMHandleEvent(&event);
}
WMCloseWindow(panel->win);
return (panel->flags.canceled ? False : True);
}
int
WMRunModalOpenPanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name, char **fileTypes)
{
WMScreen *scr = WMWidgetScreen(panel->win);
XEvent event;
WMChangePanelOwner(panel->win, owner);
WMSetFilePanelDirectory(panel, path);
panel->flags.done = 0;
if (fileTypes)
panel->flags.filtered = 1;
panel->fileTypes = fileTypes;
WMMapWidget(panel->win);
while (!panel->flags.done) {
WMNextEvent(scr->display, &event);
WMHandleEvent(&event);
}
WMCloseWindow(panel->win);
return (panel->flags.canceled ? False : True);
}
void
WMSetFilePanelDirectory(WMFilePanel *panel, char *path)
{
WMList *list;
WMListItem *item;
int col;
WMSetBrowserPath(panel->browser, path);
col = WMGetBrowserNumberOfColumns(panel->browser) - 1;
list = WMGetBrowserListInColumn(panel->browser, col);
if (list && (item = WMGetListSelectedItem(list))) {
if (item->isBranch) {
WMSetTextFieldText(panel->fileField, NULL);
} else {
WMSetTextFieldText(panel->fileField, item->text);
}
} else {
WMSetTextFieldText(panel->fileField, path);
}
}
void
WMSetFilePanelCanChooseDirectories(WMFilePanel *panel, int flag)
{
panel->flags.canChooseDirectories = flag;
}
void
WMSetFilePanelCanChooseFiles(WMFilePanel *panel, int flag)
{
panel->flags.canChooseFiles = flag;
}
char*
WMGetFilePanelFileName(WMFilePanel *panel)
{
return getCurrentFileName(panel);
}
static char*
get_name_from_path(char *path)
{
int size;
assert(path!=NULL);
size = strlen(path);
/* remove trailing / */
while (size > 0 && path[size-1]=='/')
size--;
/* directory was root */
if (size == 0)
return wstrdup("/");
while (size > 0 && path[size-1] != '/')
size--;
return wstrdup(&(path[size]));
}
static int
filterFileName(WMFilePanel *panel, char *file, Bool isDirectory)
{
return True;
}
static void
listDirectoryOnColumn(WMFilePanel *panel, int column, char *path)
{
WMBrowser *bPtr = panel->browser;
struct dirent *dentry;
DIR *dir;
struct stat stat_buf;
char pbuf[PATH_MAX+16];
assert(column >= 0);
assert(path != NULL);
/* put directory name in the title */
WMSetBrowserColumnTitle(bPtr, column, get_name_from_path(path));
dir = opendir(path);
if (!dir) {
#ifdef VERBOSE
printf("WINGs: could not open directory %s\n", path);
#endif
return;
}
/* list contents in the column */
while ((dentry = readdir(dir))) {
if (strcmp(dentry->d_name, ".")==0 ||
strcmp(dentry->d_name, "..")==0)
continue;
strcpy(pbuf, path);
if (strcmp(path, "/")!=0)
strcat(pbuf, "/");
strcat(pbuf, dentry->d_name);
if (stat(pbuf, &stat_buf)!=0) {
#ifdef VERBOSE
printf("WINGs: could not stat %s\n", pbuf);
#endif
continue;
} else {
int isDirectory;
isDirectory = S_ISDIR(stat_buf.st_mode);
if (filterFileName(panel, dentry->d_name, isDirectory))
WMAddSortedBrowserItem(bPtr, column, dentry->d_name,
isDirectory);
}
}
closedir(dir);
}
static void
fillColumn(WMBrowser *bPtr, int column)
{
char *path;
WMFilePanel *panel;
if (column > 0) {
path = WMGetBrowserPathToColumn(bPtr, column-1);
} else {
path = wstrdup("/");
}
panel = WMGetHangedData(bPtr);
listDirectoryOnColumn(panel, column, path);
free(path);
}
static void
browserClick(WMBrowser *bPtr, WMFilePanel *panel)
{
int col = WMGetBrowserSelectedColumn(bPtr);
WMListItem *item = WMGetBrowserSelectedItemInColumn(bPtr, col);
if (!item || item->isBranch)
WMSetTextFieldText(panel->fileField, NULL);
else {
WMSetTextFieldText(panel->fileField, item->text);
}
}
static void
goHome(WMButton *bPtr, WMFilePanel *panel)
{
char *home;
/* home is statically allocated. Don't free it! */
home = wgethomedir();
if (!home)
return;
WMSetFilePanelDirectory(panel, home);
}
static char*
getCurrentFileName(WMFilePanel *panel)
{
char *path;
char *file;
char *tmp;
int len;
path = WMGetBrowserPath(panel->browser);
len = strlen(path);
if (path[len-1]=='/') {
file = WMGetTextFieldText(panel->fileField);
tmp = wmalloc(strlen(path)+strlen(file)+8);
strcpy(tmp, path);
strcat(tmp, file);
free(file);
free(path);
return tmp;
} else {
return path;
}
}
static Bool
validOpenFile(WMFilePanel *panel)
{
WMListItem *item;
int col;
col = WMGetBrowserSelectedColumn(panel->browser);
item = WMGetBrowserSelectedItemInColumn(panel->browser, col);
if (item) {
if (item->isBranch && !panel->flags.canChooseDirectories)
return False;
else if (!item->isBranch && !panel->flags.canChooseFiles)
return False;
}
return True;
}
static void
buttonClick(WMButton *bPtr, WMFilePanel *panel)
{
if (bPtr == panel->okButton) {
if (panel->flags.fileMustExist) {
char *file;
if (!validOpenFile(panel))
return;
file = getCurrentFileName(panel);
if (access(file, F_OK)!=0) {
WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
"Error", "File does not exist.",
"Ok", NULL, NULL);
free(file);
return;
}
free(file);
}
panel->flags.canceled = 0;
} else
panel->flags.canceled = 1;
panel->flags.done = 1;
}

272
WINGs/wfont.c Normal file
View File

@@ -0,0 +1,272 @@
#include "WINGsP.h"
#include <wraster.h>
#include <assert.h>
static char *makeFontSetOfSize(char *fontset, int size);
WMFont*
WMCreateFont(WMScreen *scrPtr, char *fontName)
{
WMFont *font;
Display *display = scrPtr->display;
char **missing;
int nmissing = 0;
char *defaultString;
XFontSetExtents *extents;
font = malloc(sizeof(WMFont));
if (!font)
return NULL;
font->notFontSet = 0;
font->screen = scrPtr;
font->font.set = XCreateFontSet(display, fontName, &missing, &nmissing,
&defaultString);
if (nmissing > 0 && font->font.set) {
int i;
wwarning("the following character sets are missing in %s:",
fontName);
for (i = 0; i < nmissing; i++) {
wwarning(missing[i]);
}
XFreeStringList(missing);
if (defaultString)
wwarning("the string \"%s\" will be used in place of any characters from those sets.",
defaultString);
}
if (!font->font.set) {
free(font);
return NULL;
}
extents = XExtentsOfFontSet(font->font.set);
font->height = extents->max_logical_extent.height;
font->y = font->height - (font->height + extents->max_logical_extent.y);
font->refCount = 1;
return font;
}
WMFont*
WMCreateFontInDefaultEncoding(WMScreen *scrPtr, char *fontName)
{
WMFont *font;
Display *display = scrPtr->display;
font = malloc(sizeof(WMFont));
if (!font)
return NULL;
font->notFontSet = 1;
font->screen = scrPtr;
font->font.normal = XLoadQueryFont(display, fontName);
if (!font->font.normal) {
free(font);
return NULL;
}
font->height = font->font.normal->ascent+font->font.normal->descent;
font->y = font->font.normal->ascent;
font->refCount = 1;
return font;
}
WMFont*
WMRetainFont(WMFont *font)
{
assert(font!=NULL);
font->refCount++;
return font;
}
void
WMReleaseFont(WMFont *font)
{
assert(font!=NULL);
font->refCount--;
if (font->refCount < 1) {
if (font->notFontSet)
XFreeFont(font->screen->display, font->font.normal);
else
XFreeFontSet(font->screen->display, font->font.set);
free(font);
}
}
unsigned int
WMFontHeight(WMFont *font)
{
assert(font!=NULL);
return font->height;
}
WMFont*
WMSystemFontOfSize(WMScreen *scrPtr, int size)
{
WMFont *font;
char *fontSpec;
fontSpec = makeFontSetOfSize(WINGsConfiguration.systemFont, size);
font = WMCreateFont(scrPtr, fontSpec);
if (!font) {
wwarning("could not load font set %s. Trying fixed.", fontSpec);
font = WMCreateFont(scrPtr, "fixed");
if (!font) {
wwarning("could not load fixed font!");
free(fontSpec);
return NULL;
}
}
free(fontSpec);
return font;
}
WMFont*
WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
{
WMFont *font;
char *fontSpec;
fontSpec = makeFontSetOfSize(WINGsConfiguration.boldSystemFont, size);
font = WMCreateFont(scrPtr, fontSpec);
if (!font) {
wwarning("could not load font set %s. Trying fixed.", fontSpec);
font = WMCreateFont(scrPtr, "fixed");
if (!font) {
wwarning("could not load fixed font!");
free(fontSpec);
return NULL;
}
}
free(fontSpec);
return font;
}
XFontSet
WMGetFontFontSet(WMFont *font)
{
if (font->notFontSet)
return NULL;
else
return font->font.set;
}
int
WMWidthOfString(WMFont *font, char *text, int length)
{
assert(font!=NULL);
assert(text!=NULL);
if (font->notFontSet)
return XTextWidth(font->font.normal, text, length);
else {
XRectangle rect;
XRectangle AIXsucks;
XmbTextExtents(font->font.set, text, length, &AIXsucks, &rect);
return rect.width;
}
}
void
WMDrawString(WMScreen *scr, Drawable d, GC gc, WMFont *font, int x, int y,
char *text, int length)
{
if (font->notFontSet) {
XSetFont(scr->display, gc, font->font.normal->fid);
XDrawString(scr->display, d, gc, x, y + font->y, text, length);
} else {
XmbDrawString(scr->display, d, font->font.set, gc, x, y + font->y,
text, length);
}
}
void
WMDrawImageString(WMScreen *scr, Drawable d, GC gc, WMFont *font, int x, int y,
char *text, int length)
{
if (font->notFontSet) {
XSetFont(scr->display, gc, font->font.normal->fid);
XDrawImageString(scr->display, d, gc, x, y + font->y, text, length);
} else {
XmbDrawImageString(scr->display, d, font->font.set, gc, x, y + font->y,
text, length);
}
}
static char*
makeFontSetOfSize(char *fontset, int size)
{
char font[300];
char *newfs = NULL;
char *ptr;
char *tmp;
do {
int hold = ' ';
ptr = strchr(fontset, ',');
if (ptr) {
hold = *(ptr+1);
*(ptr+1) = 0;
}
if (strlen(fontset)>255) {
wwarning("font description %s is too large.", fontset);
} else {
sprintf(font, fontset, size);
tmp = wstrappend(newfs, font);
if (newfs)
free(newfs);
newfs = tmp;
}
if (ptr) {
*(ptr+1) = hold;
}
fontset = ptr+1;
} while (ptr!=NULL);
return newfs;
}

654
WINGs/wfontpanel.c Normal file
View File

@@ -0,0 +1,654 @@
#include "WINGsP.h"
#include <strings.h>
typedef struct W_FontPanel {
WMWindow *win;
WMFrame *upperF;
WMLabel *sampleL;
WMSplitView *split;
WMFrame *lowerF;
WMLabel *famL;
WMList *famLs;
WMLabel *typL;
WMList *typLs;
WMLabel *sizL;
WMTextField *sizT;
WMList *sizLs;
WMFrame *xlfdF;
WMTextField *xlfdT;
WMFrame *encF;
WMPopUpButton *encP;
WMButton *revertB;
WMButton *previewB;
WMButton *setB;
proplist_t fdb;
} FontPanel;
#define MIN_UPPER_HEIGHT 20
#define MIN_LOWER_HEIGHT 140
#define MAX_FONTS_TO_RETRIEVE 2000
#define MIN_WIDTH 250
#define MIN_HEIGHT MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+70
/*
static char *scalableFontSizes[] = {
"8",
"10",
"11",
"12",
"14",
"16",
"18",
"20",
"24",
"36",
"48",
"64"
};
*/
static void arrangeLowerFrame(FontPanel *panel);
static proplist_t createFontDatabase(WMScreen *scr);
static void listFamilies(proplist_t fdb, WMList *list);
static void
splitViewConstrainCallback(WMSplitView *sPtr, int divIndex, int *min, int *max)
{
*min = MIN_UPPER_HEIGHT;
*max = WMWidgetHeight(sPtr)-WMGetSplitViewDividerThickness(sPtr)-MIN_LOWER_HEIGHT;
}
static void
notificationObserver(void *self, WMNotification *notif)
{
WMFontPanel *panel = (WMFontPanel*)self;
void *object = WMGetNotificationObject(notif);
if (WMGetNotificationName(notif) == WMViewSizeDidChangeNotification) {
if (object == WMWidgetView(panel->win)) {
int h = WMWidgetHeight(panel->win);
int w = WMWidgetWidth(panel->win);
WMResizeWidget(panel->split, w, h-40);
WMMoveWidget(panel->setB, w-80, h-35);
WMMoveWidget(panel->previewB, w-160, h-35);
WMMoveWidget(panel->revertB, w-240, h-35);
} else if (object == WMWidgetView(panel->upperF)) {
WMResizeWidget(panel->sampleL, WMWidgetWidth(panel->upperF)-20,
WMWidgetHeight(panel->upperF)-10);
} else if (object == WMWidgetView(panel->lowerF)) {
if (WMWidgetHeight(panel->lowerF) < MIN_LOWER_HEIGHT) {
int h;
h = WMWidgetHeight(panel->split)-MIN_LOWER_HEIGHT
- WMGetSplitViewDividerThickness(panel->split);
WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF), h);
WMMoveWidget(panel->lowerF, 0, WMWidgetHeight(panel->upperF)
+ WMGetSplitViewDividerThickness(panel->split));
WMResizeWidget(panel->lowerF, WMWidgetWidth(panel->lowerF),
MIN_LOWER_HEIGHT);
} else {
arrangeLowerFrame(panel);
}
}
}
}
/*
static void
familyClick(WMWidget *w, void *data)
{
WMList *lPtr = (WMList*)w;
FontPanel *panel = (FontPanel*)data;
}
*/
WMFontPanel*
WMGetFontPanel(WMScreen *scr)
{
FontPanel *panel;
WMColor *dark, *white;
WMFont *font;
int divThickness;
if (scr->sharedFontPanel)
return scr->sharedFontPanel;
panel = wmalloc(sizeof(FontPanel));
memset(panel, 0, sizeof(FontPanel));
panel->win = WMCreateWindow(scr, "fontPanel");
WMResizeWidget(panel->win, 320, 370);
WMSetWindowMinSize(panel->win, MIN_WIDTH, MIN_HEIGHT);
WMSetViewNotifySizeChanges(WMWidgetView(panel->win), True);
panel->split = WMCreateSplitView(panel->win);
WMResizeWidget(panel->split, 320, 330);
WMSetSplitViewConstrainProc(panel->split, splitViewConstrainCallback);
divThickness = WMGetSplitViewDividerThickness(panel->split);
panel->upperF = WMCreateFrame(panel->win);
WMSetFrameRelief(panel->upperF, WRFlat);
WMSetViewNotifySizeChanges(WMWidgetView(panel->upperF), True);
panel->lowerF = WMCreateFrame(panel->win);
WMSetFrameRelief(panel->lowerF, WRFlat);
WMSetViewNotifySizeChanges(WMWidgetView(panel->lowerF), True);
WMAddSplitViewSubview(panel->split, W_VIEW(panel->upperF));
WMAddSplitViewSubview(panel->split, W_VIEW(panel->lowerF));
WMResizeWidget(panel->upperF, 320, 60);
WMResizeWidget(panel->lowerF, 320, 330-60-divThickness);
WMMoveWidget(panel->lowerF, 0, 60+divThickness);
white = WMWhiteColor(scr);
dark = WMDarkGrayColor(scr);
panel->sampleL = WMCreateLabel(panel->upperF);
WMResizeWidget(panel->sampleL, 300, 50);
WMMoveWidget(panel->sampleL, 10, 10);
WMSetWidgetBackgroundColor(panel->sampleL, white);
WMSetLabelRelief(panel->sampleL, WRSunken);
WMSetLabelText(panel->sampleL, "It is not yet completed!!!");
font = WMBoldSystemFontOfSize(scr, 12);
panel->famL = WMCreateLabel(panel->lowerF);
WMSetWidgetBackgroundColor(panel->famL, dark);
WMSetLabelText(panel->famL, "Family");
WMSetLabelFont(panel->famL, font);
WMSetLabelTextColor(panel->famL, white);
WMSetLabelRelief(panel->famL, WRSunken);
WMSetLabelTextAlignment(panel->famL, WACenter);
panel->famLs = WMCreateList(panel->lowerF);
panel->typL = WMCreateLabel(panel->lowerF);
WMSetWidgetBackgroundColor(panel->typL, dark);
WMSetLabelText(panel->typL, "Typeface");
WMSetLabelFont(panel->typL, font);
WMSetLabelTextColor(panel->typL, white);
WMSetLabelRelief(panel->typL, WRSunken);
WMSetLabelTextAlignment(panel->typL, WACenter);
panel->typLs = WMCreateList(panel->lowerF);
panel->sizL = WMCreateLabel(panel->lowerF);
WMSetWidgetBackgroundColor(panel->sizL, dark);
WMSetLabelText(panel->sizL, "Size");
WMSetLabelFont(panel->sizL, font);
WMSetLabelTextColor(panel->sizL, white);
WMSetLabelRelief(panel->sizL, WRSunken);
WMSetLabelTextAlignment(panel->sizL, WACenter);
panel->sizT = WMCreateTextField(panel->lowerF);
panel->sizLs = WMCreateList(panel->lowerF);
WMReleaseFont(font);
WMReleaseColor(white);
WMReleaseColor(dark);
panel->encF = WMCreateFrame(panel->lowerF);
WMSetFrameTitle(panel->encF, "Encoding");
WMResizeWidget(panel->encF, 130, 50);
panel->encP = WMCreatePopUpButton(panel->encF);
WMMoveWidget(panel->encP, 10, 20);
WMResizeWidget(panel->encP, 112, 20);
WMMapSubwidgets(panel->encF);
panel->xlfdF = WMCreateFrame(panel->lowerF);
WMSetFrameTitle(panel->xlfdF, "Xtra Long Font Description");
panel->xlfdT = WMCreateTextField(panel->xlfdF);
WMMoveWidget(panel->xlfdT, 10, 20);
WMMapSubwidgets(panel->xlfdF);
arrangeLowerFrame(panel);
panel->setB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->setB, 70, 24);
WMMoveWidget(panel->setB, 240, 335);
WMSetButtonText(panel->setB, "Set");
panel->previewB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->previewB, 70, 24);
WMMoveWidget(panel->previewB, 160, 335);
WMSetButtonText(panel->previewB, "Preview");
panel->revertB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->revertB, 70, 24);
WMMoveWidget(panel->revertB, 80, 335);
WMSetButtonText(panel->revertB, "Revert");
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->upperF);
WMMapSubwidgets(panel->lowerF);
WMMapSubwidgets(panel->split);
WMMapSubwidgets(panel->win);
scr->sharedFontPanel = panel;
/* register notification observers */
WMAddNotificationObserver(notificationObserver, panel,
WMViewSizeDidChangeNotification,
WMWidgetView(panel->win));
WMAddNotificationObserver(notificationObserver, panel,
WMViewSizeDidChangeNotification,
WMWidgetView(panel->upperF));
WMAddNotificationObserver(notificationObserver, panel,
WMViewSizeDidChangeNotification,
WMWidgetView(panel->lowerF));
panel->fdb = createFontDatabase(scr);
listFamilies(panel->fdb, panel->famLs);
return panel;
}
void
WMFreeFontPanel(WMFontPanel *panel)
{
if (panel == WMWidgetScreen(panel->win)->sharedFontPanel) {
WMWidgetScreen(panel->win)->sharedFontPanel = NULL;
}
WMRemoveNotificationObserver(panel);
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
free(panel);
}
void
WMShowFontPanel(WMFontPanel *panel)
{
WMMapWidget(panel->win);
}
void
WMHideFontPanel(WMFontPanel *panel)
{
WMUnmapWidget(panel->win);
}
void
WMSetFontPanelFont(WMFontPanel *panel, WMFont *font)
{
}
WMFont*
WMGetFontPanelFont(WMFontPanel *panel)
{
return NULL;
}
char*
WMGetFontPanelFontName(WMFontPanel *panel)
{
return NULL;
}
static void
arrangeLowerFrame(FontPanel *panel)
{
int width = WMWidgetWidth(panel->lowerF) - 55 - 30;
int height = WMWidgetHeight(panel->lowerF);
int oheight = 330-60-WMGetSplitViewDividerThickness(panel->split);
int fw, tw, sw;
int h;
height -= 20 + 3 + 10 + 50;
oheight -= 20 + 3 + 10 + 50;
fw = (125*width) / 235;
tw = (110*width) / 235;
sw = 55;
h = (174*height) / oheight;
WMMoveWidget(panel->famL, 10, 0);
WMResizeWidget(panel->famL, fw, 20);
WMMoveWidget(panel->famLs, 10, 23);
WMResizeWidget(panel->famLs, fw, h);
WMMoveWidget(panel->typL, 10+fw+3, 0);
WMResizeWidget(panel->typL, tw, 20);
WMMoveWidget(panel->typLs, 10+fw+3, 23);
WMResizeWidget(panel->typLs, tw, h);
WMMoveWidget(panel->sizL, 10+fw+3+tw+3, 0);
WMResizeWidget(panel->sizL, sw+4, 20);
WMMoveWidget(panel->sizT, 10+fw+3+tw+3, 23);
WMResizeWidget(panel->sizT, sw+4, 20);
WMMoveWidget(panel->sizLs, 10+fw+3+tw+3, 46);
WMResizeWidget(panel->sizLs, sw+4, h-22);
WMMoveWidget(panel->encF, 10, WMWidgetHeight(panel->lowerF)-55);
WMMoveWidget(panel->xlfdF, 145, WMWidgetHeight(panel->lowerF)-55);
WMResizeWidget(panel->xlfdF, WMWidgetWidth(panel->lowerF)-155, 50);
WMResizeWidget(panel->xlfdT, WMWidgetWidth(panel->lowerF)-155-20, 20);
}
#define ALL_FONTS_MASK "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
#define FOUNDRY 0
#define FAMILY 1
#define WEIGHT 2
#define SLANT 3
#define SETWIDTH 4
#define ADD_STYLE 5
#define PIXEL_SIZE 6
#define POINT_SIZE 7
#define RES_X 8
#define RES_Y 9
#define SPACING 10
#define AV_WIDTH 11
#define REGISTRY 12
#define ENCODING 13
#define NUM_FIELDS 14
static Bool
parseFont(char *font, char **values)
{
char *ptr;
int part;
char buffer[256], *bptr;
part = FOUNDRY;
ptr = font;
ptr++; /* skip first - */
bptr = buffer;
while (*ptr) {
if (*ptr == '-') {
*bptr = 0;
values[part]=wstrdup(buffer);
bptr = buffer;
part++;
} else {
*bptr++ = *ptr;
}
ptr++;
}
*bptr = 0;
values[part]=wstrdup(buffer);
return True;
}
static int
isXLFD(char *font, int *length_ret)
{
int c = 0;
*length_ret = 0;
while (*font) {
(*length_ret)++;
if (*font++ == '-')
c++;
}
return c==NUM_FIELDS;
}
static proplist_t foundryKey = NULL;
static proplist_t typeKey = NULL;
static proplist_t sizeKey, encKey, xlfdKey;
static void
addSizeToEnc(proplist_t enc, char **fields)
{
proplist_t sizel;
sizel = PLGetDictionaryEntry(enc, sizeKey);
if (!sizel) {
sizel = PLMakeArrayFromElements(PLMakeString(fields[PIXEL_SIZE]),NULL);
PLInsertDictionaryEntry(enc, sizeKey, sizel);
} else {
PLAppendArrayElement(sizel, PLMakeString(fields[PIXEL_SIZE]));
}
}
static proplist_t
addTypefaceToFont(proplist_t font, char **fields)
{
proplist_t face, encod, facedic, encodic;
char buffer[256];
strcpy(buffer, fields[WEIGHT]);
if (strcasecmp(fields[SLANT], "R")==0)
strcat(buffer, " Roman ");
else if (strcasecmp(fields[SLANT], "I")==0)
strcat(buffer, " Italic ");
else if (strcasecmp(fields[SLANT], "O")==0)
strcat(buffer, " Oblique ");
else if (strcasecmp(fields[SLANT], "RI")==0)
strcat(buffer, " Reverse Italic ");
else if (strcasecmp(fields[SLANT], "RO")==0)
strcat(buffer, " Reverse Oblique ");
else if (strcasecmp(fields[SLANT], "OT")==0)
strcat(buffer, " ? ");
/* else
* polymorphic fonts
*/
strcat(buffer, fields[SETWIDTH]);
strcat(buffer, " ");
strcat(buffer, fields[ADD_STYLE]);
face = PLMakeString(buffer);
facedic = PLGetDictionaryEntry(font, face);
if (!facedic) {
facedic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
PLInsertDictionaryEntry(font, face, facedic);
PLRelease(facedic);
}
PLRelease(face);
strcpy(buffer, fields[REGISTRY]);
strcat(buffer, "-");
strcat(buffer, fields[ENCODING]);
encod = PLMakeString(buffer);
encodic = PLGetDictionaryEntry(facedic, encod);
if (!encodic) {
proplist_t tmp;
sprintf(buffer, "-%s-%s-%s-%s-%s-%s-%%d-0-%s-%s-%s-%s-%s-%s",
fields[FOUNDRY], fields[FAMILY], fields[WEIGHT],
fields[SLANT], fields[SETWIDTH], fields[ADD_STYLE],
fields[RES_X], fields[RES_Y], fields[SPACING],
fields[AV_WIDTH], fields[REGISTRY], fields[ENCODING]);
tmp = PLMakeString(buffer);
encodic = PLMakeDictionaryFromEntries(xlfdKey, tmp, NULL);
PLRelease(tmp);
PLInsertDictionaryEntry(facedic, encod, encodic);
PLRelease(encodic);
}
addSizeToEnc(encodic, fields);
return font;
}
static proplist_t
makeFontEntry(char **fields)
{
proplist_t font;
proplist_t value;
proplist_t tmp;
value = PLMakeString(fields[FOUNDRY]);
tmp = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
font = PLMakeDictionaryFromEntries(foundryKey, value,
typeKey, tmp,
NULL);
PLRelease(value);
PLRelease(tmp);
addTypefaceToFont(font, fields);
return font;
}
static proplist_t
createFontDatabase(WMScreen *scr)
{
char **fontList;
int count;
char *fields[NUM_FIELDS];
int font_name_length;
char buffer[256];
int i;
proplist_t fdb;
proplist_t font;
proplist_t family;
proplist_t foundry;
proplist_t tmp;
if (!foundryKey) {
foundryKey = PLMakeString("Foundry");
typeKey = PLMakeString("Typeface");
encKey = PLMakeString("Encoding");
sizeKey = PLMakeString("Sizes");
xlfdKey = PLMakeString("XLFD");
}
/* retrieve a complete listing of the available fonts */
fontList = XListFonts(scr->display, ALL_FONTS_MASK, MAX_FONTS_TO_RETRIEVE,
&count);
if (!fontList) {
wwarning("could not retrieve font list");
return NULL;
}
fdb = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
for (i=0; i<count; i++) {
if (!isXLFD(fontList[i], &font_name_length)) {
continue;
}
/* the XLFD specs limit the size of a font description in 255 chars */
assert(font_name_length < 256);
if (parseFont(fontList[i], fields)) {
family = PLMakeString(fields[FAMILY]);
font = PLGetDictionaryEntry(fdb, family);
if (font) {
foundry = PLGetDictionaryEntry(font, foundryKey);
if (strcmp(PLGetString(foundry), fields[FOUNDRY])==0) {
/* already a font with the same family */
addTypefaceToFont(font, fields);
} else {
/* same font family by different foundries */
sprintf(buffer, "%s (%s)", fields[FAMILY],
fields[FOUNDRY]);
PLRelease(family);
family = PLMakeString(buffer);
font = PLGetDictionaryEntry(fdb, family);
if (font) {
/* already a font with the same family */
addTypefaceToFont(font, fields);
} else {
tmp = makeFontEntry(fields);
PLInsertDictionaryEntry(fdb, family, tmp);
PLRelease(tmp);
}
}
} else {
tmp = makeFontEntry(fields);
PLInsertDictionaryEntry(fdb, family, tmp);
PLRelease(tmp);
}
PLRelease(family);
}
}
XFreeFontNames(fontList);
return fdb;
}
static void
listFamilies(proplist_t fdb, WMList *list)
{
proplist_t arr;
proplist_t fam;
int i;
arr = PLGetAllDictionaryKeys(fdb);
for (i = 0; i<PLGetNumberOfElements(arr); i++) {
fam = PLGetArrayElement(arr, i);
WMAddSortedListItem(list, PLGetString(fam));
}
}

223
WINGs/wframe.c Normal file
View File

@@ -0,0 +1,223 @@
#include "WINGsP.h"
typedef struct W_Frame {
W_Class widgetClass;
W_View *view;
char *caption;
struct {
WMReliefType relief:3;
WMTitlePosition titlePosition:3;
} flags;
} Frame;
struct W_ViewProcedureTable _FrameViewProcedures = {
NULL,
NULL,
NULL
};
#define DEFAULT_RELIEF WRGroove
#define DEFAULT_TITLE_POSITION WTPAtTop
#define DEFAULT_WIDTH 40
#define DEFAULT_HEIGHT 40
static void destroyFrame(Frame *fPtr);
static void paintFrame(Frame *fPtr);
void
WMSetFrameTitlePosition(WMFrame *fPtr, WMTitlePosition position)
{
fPtr->flags.titlePosition = position;
if (fPtr->view->flags.realized) {
paintFrame(fPtr);
}
}
void
WMSetFrameRelief(WMFrame *fPtr, WMReliefType relief)
{
fPtr->flags.relief = relief;
if (fPtr->view->flags.realized) {
paintFrame(fPtr);
}
}
void
WMSetFrameTitle(WMFrame *fPtr, char *title)
{
if (fPtr->caption)
free(fPtr->caption);
if (title)
fPtr->caption = wstrdup(title);
else
fPtr->caption = NULL;
if (fPtr->view->flags.realized) {
paintFrame(fPtr);
}
}
static void
paintFrame(Frame *fPtr)
{
W_View *view = fPtr->view;
W_Screen *scrPtr = view->screen;
int tx, ty, tw, th;
int fy, fh;
if (fPtr->caption!=NULL)
th = scrPtr->normalFont->height;
else {
th = 0;
}
fh = view->size.height;
fy = 0;
switch (fPtr->flags.titlePosition) {
case WTPAboveTop:
ty = 0;
fy = th + 4;
fh = view->size.height - fy;
break;
case WTPAtTop:
ty = 0;
fy = th/2;
fh = view->size.height - fy;
break;
case WTPBelowTop:
ty = 4;
fy = 0;
fh = view->size.height;
break;
case WTPAboveBottom:
ty = view->size.height - th - 4;
fy = 0;
fh = view->size.height;
break;
case WTPAtBottom:
ty = view->size.height - th;
fy = 0;
fh = view->size.height - th/2;
break;
case WTPBelowBottom:
ty = view->size.height - th;
fy = 0;
fh = view->size.height - th - 4;
break;
default:
ty = 0;
fy = 0;
fh = view->size.height;
}
/*
XClearArea(scrPtr->display, view->window, fy+2, 2, fh-4, view->size.width-4,
False);
*/
XClearWindow(scrPtr->display, view->window);
W_DrawRelief(scrPtr, view->window, 0, fy, view->size.width, fh,
fPtr->flags.relief);
if (fPtr->caption!=NULL && fPtr->flags.titlePosition!=WTPNoTitle) {
tw = WMWidthOfString(scrPtr->normalFont, fPtr->caption,
strlen(fPtr->caption));
tx = (view->size.width - tw) / 2;
XFillRectangle(scrPtr->display, view->window, W_GC(scrPtr->gray),
tx, ty, tw, th);
WMDrawString(scrPtr, view->window, W_GC(scrPtr->black),
scrPtr->normalFont, tx, ty, fPtr->caption,
strlen(fPtr->caption));
}
}
static void
handleEvents(XEvent *event, void *data)
{
Frame *fPtr = (Frame*)data;
CHECK_CLASS(data, WC_Frame);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintFrame(fPtr);
break;
case DestroyNotify:
destroyFrame(fPtr);
break;
}
}
WMFrame*
WMCreateFrame(WMWidget *parent)
{
Frame *fPtr;
fPtr = wmalloc(sizeof(Frame));
memset(fPtr, 0, sizeof(Frame));
fPtr->widgetClass = WC_Frame;
fPtr->view = W_CreateView(W_VIEW(parent));
if (!fPtr->view) {
free(fPtr);
return NULL;
}
fPtr->view->self = fPtr;
WMCreateEventHandler(fPtr->view, ExposureMask|StructureNotifyMask,
handleEvents, fPtr);
fPtr->flags.relief = DEFAULT_RELIEF;
fPtr->flags.titlePosition = DEFAULT_TITLE_POSITION;
WMResizeWidget(fPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
return fPtr;
}
static void
destroyFrame(Frame *fPtr)
{
if (fPtr->caption)
free(fPtr->caption);
free(fPtr);
}

894
WINGs/widgets.c Normal file
View File

@@ -0,0 +1,894 @@
#include "WINGsP.h"
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
/********** data ************/
#define CHECK_BUTTON_ON_WIDTH 16
#define CHECK_BUTTON_ON_HEIGHT 16
static char *CHECK_BUTTON_ON[] = {
" %",
" .............%#",
" ........... .%#",
" .......... #.%#",
" ......... #%.%#",
" ........ #%..%#",
" ... #.. #%...%#",
" ... #% #%....%#",
" ... % #%.....%#",
" ... #%......%#",
" ... #%.......%#",
" ...#%........%#",
" .............%#",
" .............%#",
" %%%%%%%%%%%%%%#",
"%###############"};
#define CHECK_BUTTON_OFF_WIDTH 16
#define CHECK_BUTTON_OFF_HEIGHT 16
static char *CHECK_BUTTON_OFF[] = {
" %",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" .............%#",
" %%%%%%%%%%%%%%#",
"%###############"};
#define RADIO_BUTTON_ON_WIDTH 15
#define RADIO_BUTTON_ON_HEIGHT 15
static char *RADIO_BUTTON_ON[] = {
".....%%%%%.....",
"...%%#####%%...",
"..%##.....%.%..",
".%#%.. .....",
".%#. ...",
"%#.. .. ",
"%#. . ",
"%#. . ",
"%#. . ",
"%#. . ",
".%%. . .",
".%.. . .",
"..%... .. ..",
".... ..... ...",
"..... .....",
};
#define RADIO_BUTTON_OFF_WIDTH 15
#define RADIO_BUTTON_OFF_HEIGHT 15
static char *RADIO_BUTTON_OFF[] = {
".....%%%%%.....",
"...%%#####%%...",
"..%##.......%..",
".%#%...........",
".%#............",
"%#............ ",
"%#............ ",
"%#............ ",
"%#............ ",
"%#............ ",
".%%.......... .",
".%........... .",
"..%......... ..",
".... ..... ...",
"..... .....",
};
static char *BUTTON_ARROW[] = {
"..................",
"....##....#### ...",
"...#.%....#... ...",
"..#..%#####... ...",
".#............ ...",
"#............. ...",
".#............ ...",
"..#.. ...",
"...#. ............",
"....# ............"
};
#define BUTTON_ARROW_WIDTH 18
#define BUTTON_ARROW_HEIGHT 10
static char *BUTTON_ARROW2[] = {
" ",
" ## ####. ",
" # % # . ",
" # %##### . ",
" # . ",
"# . ",
" # . ",
" # .......... ",
" # . ",
" #. "
};
#define BUTTON_ARROW2_WIDTH 18
#define BUTTON_ARROW2_HEIGHT 10
static char *SCROLLER_DIMPLE[] = {
".%###.",
"%#%%%%",
"#%%...",
"#%.. ",
"#%. ",
".%. ."
};
#define SCROLLER_DIMPLE_WIDTH 6
#define SCROLLER_DIMPLE_HEIGHT 6
static char *SCROLLER_ARROW_UP[] = {
"....%....",
"....#....",
"...%#%...",
"...###...",
"..%###%..",
"..#####..",
".%#####%.",
".#######.",
"%#######%"
};
static char *HI_SCROLLER_ARROW_UP[] = {
" % ",
" % ",
" %%% ",
" %%% ",
" %%%%% ",
" %%%%% ",
" %%%%%%% ",
" %%%%%%% ",
"%%%%%%%%%"
};
#define SCROLLER_ARROW_UP_WIDTH 9
#define SCROLLER_ARROW_UP_HEIGHT 9
static char *SCROLLER_ARROW_DOWN[] = {
"%#######%",
".#######.",
".%#####%.",
"..#####..",
"..%###%..",
"...###...",
"...%#%...",
"....#....",
"....%...."
};
static char *HI_SCROLLER_ARROW_DOWN[] = {
"%%%%%%%%%",
" %%%%%%% ",
" %%%%%%% ",
" %%%%% ",
" %%%%% ",
" %%% ",
" %%% ",
" % ",
" % "
};
#define SCROLLER_ARROW_DOWN_WIDTH 9
#define SCROLLER_ARROW_DOWN_HEIGHT 9
static char *SCROLLER_ARROW_LEFT[] = {
"........%",
"......%##",
"....%####",
"..%######",
"%########",
"..%######",
"....%####",
"......%##",
"........%"
};
static char *HI_SCROLLER_ARROW_LEFT[] = {
" %",
" %%%",
" %%%%%",
" %%%%%%%",
"%%%%%%%%%",
" %%%%%%%",
" %%%%%",
" %%%",
" %"
};
#define SCROLLER_ARROW_LEFT_WIDTH 9
#define SCROLLER_ARROW_LEFT_HEIGHT 9
static char *SCROLLER_ARROW_RIGHT[] = {
"%........",
"##%......",
"####%....",
"######%..",
"########%",
"######%..",
"####%....",
"##%......",
"%........"
};
static char *HI_SCROLLER_ARROW_RIGHT[] = {
"% ",
"%%% ",
"%%%%% ",
"%%%%%%% ",
"%%%%%%%%%",
"%%%%%%% ",
"%%%%% ",
"%%% ",
"% "
};
#define SCROLLER_ARROW_RIGHT_WIDTH 9
#define SCROLLER_ARROW_RIGHT_HEIGHT 9
static char *POPUP_INDICATOR[] = {
" #==",
" ......%#==",
" ......%#%%",
" ......%#%%",
" %%%%%%%#%%",
"#########%%",
"==%%%%%%%%%",
"==%%%%%%%%%"
};
#define POPUP_INDICATOR_WIDTH 11
#define POPUP_INDICATOR_HEIGHT 8
static char *PULLDOWN_INDICATOR[] = {
"=#######=",
"=%===== =",
"==%=== ==",
"==%=== ==",
"===%= ===",
"===%= ===",
"====%===="
};
#define PULLDOWN_INDICATOR_WIDTH 9
#define PULLDOWN_INDICATOR_HEIGHT 7
#define STIPPLE_WIDTH 8
#define STIPPLE_HEIGHT 8
static unsigned char STIPPLE_BITS[] = {
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa};
extern W_ViewProcedureTable _WindowViewProcedures;
extern W_ViewProcedureTable _FrameViewProcedures;
extern W_ViewProcedureTable _LabelViewProcedures;
extern W_ViewProcedureTable _ButtonViewProcedures;
extern W_ViewProcedureTable _TextFieldViewProcedures;
extern W_ViewProcedureTable _ScrollerViewProcedures;
extern W_ViewProcedureTable _ScrollViewProcedures;
extern W_ViewProcedureTable _ListViewProcedures;
extern W_ViewProcedureTable _BrowserViewProcedures;
extern W_ViewProcedureTable _PopUpButtonViewProcedures;
extern W_ViewProcedureTable _ColorWellViewProcedures;
extern W_ViewProcedureTable _ScrollViewViewProcedures;
extern W_ViewProcedureTable _SliderViewProcedures;
extern W_ViewProcedureTable _SplitViewViewProcedures;
/*
* All widget classes defined must have an entry here.
*/
static W_ViewProcedureTable *procedureTables[16];
static W_ViewProcedureTable **userProcedureTable = NULL;
static int userWidgetCount=0;
/***** end data ******/
static void
initProcedureTable()
{
procedureTables[WC_Window] = &_WindowViewProcedures;
procedureTables[WC_Frame] = &_FrameViewProcedures;
procedureTables[WC_Label] = &_LabelViewProcedures;
procedureTables[WC_Button] = &_ButtonViewProcedures;
procedureTables[WC_TextField] = &_TextFieldViewProcedures;
procedureTables[WC_Scroller] = &_ScrollerViewProcedures;
procedureTables[WC_List] = &_ListViewProcedures;
procedureTables[WC_Browser] = &_BrowserViewProcedures;
procedureTables[WC_PopUpButton] = &_PopUpButtonViewProcedures;
procedureTables[WC_ColorWell] = &_ColorWellViewProcedures;
procedureTables[WC_ScrollView] = &_ScrollViewViewProcedures;
procedureTables[WC_Slider] = &_SliderViewProcedures;
procedureTables[WC_SplitView] = &_SplitViewViewProcedures;
}
static void
renderPixmap(W_Screen *screen, Pixmap d, Pixmap mask, char **data,
int width, int height)
{
int x, y;
GC whiteGC = W_GC(screen->white);
GC blackGC = W_GC(screen->black);
GC lightGC = W_GC(screen->gray);
GC darkGC = W_GC(screen->darkGray);
if (mask)
XSetForeground(screen->display, screen->monoGC,
W_PIXEL(screen->black));
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
switch (data[y][x]) {
case ' ':
case 'w':
XDrawPoint(screen->display, d, whiteGC, x, y);
break;
case '=':
if (mask)
XDrawPoint(screen->display, mask, screen->monoGC, x, y);
case '.':
case 'l':
XDrawPoint(screen->display, d, lightGC, x, y);
break;
case '%':
case 'd':
XDrawPoint(screen->display, d, darkGC, x, y);
break;
case '#':
case 'b':
default:
XDrawPoint(screen->display, d, blackGC, x, y);
break;
}
}
}
}
static WMPixmap*
makePixmap(W_Screen *sPtr, char **data, int width, int height, int masked)
{
Pixmap pixmap, mask = None;
pixmap = XCreatePixmap(sPtr->display, W_DRAWABLE(sPtr), width, height,
sPtr->depth);
if (masked) {
mask = XCreatePixmap(sPtr->display, W_DRAWABLE(sPtr), width, height, 1);
XSetForeground(sPtr->display, sPtr->monoGC, W_PIXEL(sPtr->white));
XFillRectangle(sPtr->display, mask, sPtr->monoGC, 0, 0, width, height);
}
renderPixmap(sPtr, pixmap, mask, data, width, height);
return WMCreatePixmapFromXPixmaps(sPtr, pixmap, mask, width, height,
sPtr->depth);
}
#ifdef USE_TIFF
#define WINGS_IMAGES_FILE RESOURCE_PATH"/Images.tiff"
#define DEFAULT_OBJECT_ICON_FILE RESOURCE_PATH"/defaultIcon.tiff"
#else
#define WINGS_IMAGES_FILE RESOURCE_PATH"/Images.xpm"
#define DEFAULT_OBJECT_ICON_FILE RESOURCE_PATH"/defaultIcon.xpm"
#endif
static Bool
loadPixmaps(WMScreen *scr)
{
RImage *image, *tmp;
Pixmap pixmap;
RColor gray;
image = RLoadImage(scr->rcontext, WINGS_IMAGES_FILE, 0);
if (!image) {
wwarning("WINGs: could not load widget images file: %s", RErrorString);
return False;
}
/* make it have a gray background */
gray.red = 0xae;
gray.green = 0xaa;
gray.blue = 0xae;
RCombineImageWithColor(image, &gray);
tmp = RGetSubImage(image, 0, 0, 24, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->homeIcon = NULL;
} else {
scr->homeIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 24, 24,
scr->depth);
}
RDestroyImage(tmp);
RDestroyImage(image);
#if 0
scr->defaultObjectIcon =
WMCreatePixmapFromFile(scr, DEFAULT_OBJECT_ICON_FILE);
if (!scr->defaultObjectIcon) {
wwarning("WINGs: could not load default icon file");
return False;
}
#endif
return True;
}
WMScreen*
WMCreateSimpleApplicationScreen(Display *display)
{
WMScreen *scr;
scr = WMCreateScreen(display, DefaultScreen(display));
scr->aflags.hasAppIcon = 0;
scr->aflags.simpleApplication = 1;
return scr;
}
WMScreen*
WMCreateScreen(Display *display, int screen)
{
return WMCreateScreenWithRContext(display, screen,
RCreateContext(display, screen, NULL));
}
WMScreen*
WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
{
W_Screen *scrPtr;
XGCValues gcv;
Pixmap stipple;
static int initialized = 0;
if (!initialized) {
initialized = 1;
initProcedureTable();
assert(W_ApplicationInitialized());
}
scrPtr = malloc(sizeof(W_Screen));
if (!scrPtr)
return NULL;
memset(scrPtr, 0, sizeof(W_Screen));
scrPtr->aflags.hasAppIcon = 1;
scrPtr->display = display;
scrPtr->screen = screen;
scrPtr->rcontext = context;
scrPtr->depth = context->depth;
scrPtr->visual = context->visual;
scrPtr->lastEventTime = 0;
scrPtr->colormap = context->cmap;
scrPtr->rootWin = RootWindow(display, screen);
/* initially allocate some colors */
WMWhiteColor(scrPtr);
WMBlackColor(scrPtr);
WMGrayColor(scrPtr);
WMDarkGrayColor(scrPtr);
gcv.graphics_exposures = False;
gcv.function = GXxor;
gcv.foreground = W_PIXEL(scrPtr->white);
scrPtr->xorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction
|GCGraphicsExposures|GCForeground, &gcv);
gcv.function = GXxor;
gcv.foreground = W_PIXEL(scrPtr->gray);
gcv.subwindow_mode = IncludeInferiors;
scrPtr->ixorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction
|GCGraphicsExposures|GCForeground
|GCSubwindowMode, &gcv);
gcv.function = GXcopy;
scrPtr->copyGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction
|GCGraphicsExposures, &gcv);
scrPtr->clipGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction
|GCGraphicsExposures, &gcv);
stipple = XCreateBitmapFromData(display, W_DRAWABLE(scrPtr),
STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT);
gcv.foreground = W_PIXEL(scrPtr->darkGray);
gcv.background = W_PIXEL(scrPtr->gray);
gcv.fill_style = FillStippled;
gcv.stipple = stipple;
scrPtr->stippleGC = XCreateGC(display, W_DRAWABLE(scrPtr),
GCForeground|GCBackground|GCStipple
|GCFillStyle|GCGraphicsExposures, &gcv);
gcv.foreground = W_PIXEL(scrPtr->black);
gcv.background = W_PIXEL(scrPtr->white);
scrPtr->textFieldGC = XCreateGC(display, W_DRAWABLE(scrPtr),
GCForeground|GCBackground, &gcv);
/* we need a 1bpp drawable for the monoGC, so borrow this one */
scrPtr->monoGC = XCreateGC(display, stipple, 0, NULL);
XFreePixmap(display, stipple);
scrPtr->normalFont = WMSystemFontOfSize(scrPtr, 12);
scrPtr->boldFont = WMBoldSystemFontOfSize(scrPtr, 12);
scrPtr->checkButtonImageOn = makePixmap(scrPtr, CHECK_BUTTON_ON,
CHECK_BUTTON_ON_WIDTH,
CHECK_BUTTON_ON_HEIGHT, False);
scrPtr->checkButtonImageOff = makePixmap(scrPtr, CHECK_BUTTON_OFF,
CHECK_BUTTON_OFF_WIDTH,
CHECK_BUTTON_OFF_HEIGHT, False);
scrPtr->radioButtonImageOn = makePixmap(scrPtr, RADIO_BUTTON_ON,
RADIO_BUTTON_ON_WIDTH,
RADIO_BUTTON_ON_HEIGHT, False);
scrPtr->radioButtonImageOff = makePixmap(scrPtr, RADIO_BUTTON_OFF,
RADIO_BUTTON_OFF_WIDTH,
RADIO_BUTTON_OFF_HEIGHT, False);
scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW,
BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT,
False);
scrPtr->pushedButtonArrow = makePixmap(scrPtr, BUTTON_ARROW2,
BUTTON_ARROW2_WIDTH, BUTTON_ARROW2_HEIGHT,
False);
scrPtr->scrollerDimple = makePixmap(scrPtr, SCROLLER_DIMPLE,
SCROLLER_DIMPLE_WIDTH,
SCROLLER_DIMPLE_HEIGHT, False);
scrPtr->upArrow = makePixmap(scrPtr, SCROLLER_ARROW_UP,
SCROLLER_ARROW_UP_WIDTH,
SCROLLER_ARROW_UP_HEIGHT, True);
scrPtr->downArrow = makePixmap(scrPtr, SCROLLER_ARROW_DOWN,
SCROLLER_ARROW_DOWN_WIDTH,
SCROLLER_ARROW_DOWN_HEIGHT, True);
scrPtr->leftArrow = makePixmap(scrPtr, SCROLLER_ARROW_LEFT,
SCROLLER_ARROW_LEFT_WIDTH,
SCROLLER_ARROW_LEFT_HEIGHT, True);
scrPtr->rightArrow = makePixmap(scrPtr, SCROLLER_ARROW_RIGHT,
SCROLLER_ARROW_RIGHT_WIDTH,
SCROLLER_ARROW_RIGHT_HEIGHT, True);
scrPtr->hiUpArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_UP,
SCROLLER_ARROW_UP_WIDTH,
SCROLLER_ARROW_UP_HEIGHT, True);
scrPtr->hiDownArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_DOWN,
SCROLLER_ARROW_DOWN_WIDTH,
SCROLLER_ARROW_DOWN_HEIGHT, True);
scrPtr->hiLeftArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_LEFT,
SCROLLER_ARROW_LEFT_WIDTH,
SCROLLER_ARROW_LEFT_HEIGHT, True);
scrPtr->hiRightArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_RIGHT,
SCROLLER_ARROW_RIGHT_WIDTH,
SCROLLER_ARROW_RIGHT_HEIGHT, True);
scrPtr->popUpIndicator = makePixmap(scrPtr, POPUP_INDICATOR,
POPUP_INDICATOR_WIDTH,
POPUP_INDICATOR_HEIGHT, True);
scrPtr->pullDownIndicator = makePixmap(scrPtr, PULLDOWN_INDICATOR,
PULLDOWN_INDICATOR_WIDTH,
PULLDOWN_INDICATOR_HEIGHT, True);
loadPixmaps(scrPtr);
scrPtr->defaultCursor = XCreateFontCursor(display, XC_left_ptr);
scrPtr->textCursor = XCreateFontCursor(display, XC_xterm);
scrPtr->internalMessage = XInternAtom(display, "_WINGS_MESSAGE", False);
scrPtr->attribsAtom = XInternAtom(display, "_GNUSTEP_WM_ATTR", False);
scrPtr->deleteWindowAtom = XInternAtom(display, "WM_DELETE_WINDOW", False);
scrPtr->protocolsAtom = XInternAtom(display, "WM_PROTOCOLS", False);
scrPtr->clipboardAtom = XInternAtom(display, "CLIPBOARD", False);
scrPtr->rootView = W_CreateRootView(scrPtr);
return scrPtr;
}
void
WMHangData(WMWidget *widget, void *data)
{
W_VIEW(widget)->hangedData = data;
}
void*
WMGetHangedData(WMWidget *widget)
{
return W_VIEW(widget)->hangedData;
}
void
WMDestroyWidget(WMWidget *widget)
{
W_DestroyView(W_VIEW(widget));
}
void
WMSetFocusToWidget(WMWidget *widget)
{
W_SetFocusOfTopLevel(W_TopLevelOfView(W_VIEW(widget)), W_VIEW(widget));
}
/*
* WMRealizeWidget-
* Realizes the widget and all it's children.
*
*/
void
WMRealizeWidget(WMWidget *w)
{
W_RealizeView(W_VIEW(w));
}
void
WMMapWidget(WMWidget *w)
{
W_MapView(W_VIEW(w));
}
static void
makeChildrenAutomap(W_View *view, int flag)
{
view = view->childrenList;
while (view) {
view->flags.mapWhenRealized = flag;
makeChildrenAutomap(view, flag);
view = view->nextSister;
}
}
void
WMMapSubwidgets(WMWidget *w)
{
/* make sure that subwidgets created after the parent was realized
* are mapped too */
if (!W_VIEW(w)->flags.realized) {
makeChildrenAutomap(W_VIEW(w), True);
} else {
W_MapSubviews(W_VIEW(w));
}
}
void
WMUnmapSubwidgets(WMWidget *w)
{
if (!W_VIEW(w)->flags.realized) {
makeChildrenAutomap(W_VIEW(w), False);
} else {
W_UnmapSubviews(W_VIEW(w));
}
}
void
WMUnmapWidget(WMWidget *w)
{
W_UnmapView(W_VIEW(w));
}
void
WMSetWidgetBackgroundColor(WMWidget *w, WMColor *color)
{
if (W_CLASS(w) < WC_UserWidget
&& procedureTables[W_CLASS(w)]->setBackgroundColor) {
(*procedureTables[W_CLASS(w)]->setBackgroundColor)(w, color);
} else if (W_CLASS(w) >= WC_UserWidget
&& userProcedureTable[W_CLASS(w)-WC_UserWidget]->setBackgroundColor) {
(*userProcedureTable[W_CLASS(w)-WC_UserWidget]->setBackgroundColor)(w, color);
} else {
W_SetViewBackgroundColor(W_VIEW(w), color);
}
}
void
WMMoveWidget(WMWidget *w, int x, int y)
{
if (W_CLASS(w) < WC_UserWidget
&& procedureTables[W_CLASS(w)]->move) {
(*procedureTables[W_CLASS(w)]->move)(w, x, y);
} else if (W_CLASS(w) >= WC_UserWidget
&& userProcedureTable[W_CLASS(w)-WC_UserWidget]->move) {
(*userProcedureTable[W_CLASS(w)-WC_UserWidget]->move)(w, x, y);
} else {
W_MoveView(W_VIEW(w), x, y);
}
}
void
WMResizeWidget(WMWidget *w, unsigned int width, unsigned int height)
{
if (W_CLASS(w) < WC_UserWidget
&& procedureTables[W_CLASS(w)]->resize) {
(*procedureTables[W_CLASS(w)]->resize)(w, width, height);
} else if (W_CLASS(w) >= WC_UserWidget
&& userProcedureTable[W_CLASS(w)-WC_UserWidget]->resize) {
(*userProcedureTable[W_CLASS(w)-WC_UserWidget]->resize)(w, width, height);
} else {
W_ResizeView(W_VIEW(w), width, height);
}
}
W_Class
W_RegisterUserWidget(W_ViewProcedureTable *procTable)
{
W_ViewProcedureTable **newTable;
userWidgetCount++;
newTable = wmalloc(sizeof(W_ViewProcedureTable*)*userWidgetCount);
memcpy(newTable, userProcedureTable,
sizeof(W_ViewProcedureTable*)*(userWidgetCount-1));
newTable[userWidgetCount-1] = procTable;
free(userProcedureTable);
userProcedureTable = newTable;
return userWidgetCount + WC_UserWidget - 1;
}
RContext*
WMScreenRContext(WMScreen *scr)
{
return scr->rcontext;
}
unsigned int
WMWidgetWidth(WMWidget *w)
{
return W_VIEW(w)->size.width;
}
unsigned int
WMWidgetHeight(WMWidget *w)
{
return W_VIEW(w)->size.height;
}
Window
WMWidgetXID(WMWidget *w)
{
return W_VIEW(w)->window;
}
WMScreen*
WMWidgetScreen(WMWidget *w)
{
return W_VIEW(w)->screen;
}
void
WMScreenMainLoop(WMScreen *scr)
{
XEvent event;
while (1) {
WMNextEvent(scr->display, &event);
WMHandleEvent(&event);
}
}
Display*
WMScreenDisplay(WMScreen *scr)
{
return scr->display;
}
void
WMRedisplayWidget(WMWidget *w)
{
W_RedisplayView(W_VIEW(w));
}

243
WINGs/wlabel.c Normal file
View File

@@ -0,0 +1,243 @@
#include "WINGsP.h"
typedef struct W_Label {
W_Class widgetClass;
W_View *view;
char *caption;
WMColor *textColor;
WMFont *font; /* if NULL, use default */
W_Pixmap *image;
struct {
WMReliefType relief:3;
WMImagePosition imagePosition:4;
WMAlignment alignment:2;
unsigned int noWrap:1;
unsigned int redrawPending:1;
} flags;
} Label;
W_ViewProcedureTable _LabelViewProcedures = {
NULL,
NULL,
NULL
};
#define DEFAULT_WIDTH 60
#define DEFAULT_HEIGHT 14
#define DEFAULT_ALIGNMENT WALeft
#define DEFAULT_RELIEF WRFlat
#define DEFAULT_IMAGE_POSITION WIPNoImage
static void destroyLabel(Label *lPtr);
static void paintLabel(Label *lPtr);
static void handleEvents(XEvent *event, void *data);
WMLabel*
WMCreateLabel(WMWidget *parent)
{
Label *lPtr;
lPtr = wmalloc(sizeof(Label));
memset(lPtr, 0, sizeof(Label));
lPtr->widgetClass = WC_Label;
lPtr->view = W_CreateView(W_VIEW(parent));
if (!lPtr->view) {
free(lPtr);
return NULL;
}
lPtr->view->self = lPtr;
lPtr->textColor = WMRetainColor(lPtr->view->screen->black);
WMCreateEventHandler(lPtr->view, ExposureMask|StructureNotifyMask,
handleEvents, lPtr);
W_ResizeView(lPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
lPtr->flags.alignment = DEFAULT_ALIGNMENT;
lPtr->flags.relief = DEFAULT_RELIEF;
lPtr->flags.imagePosition = DEFAULT_IMAGE_POSITION;
return lPtr;
}
void
WMSetLabelImage(WMLabel *lPtr, WMPixmap *image)
{
if (lPtr->image!=NULL)
WMReleasePixmap(lPtr->image);
if (image)
lPtr->image = WMRetainPixmap(image);
else
lPtr->image = NULL;
if (lPtr->view->flags.realized) {
paintLabel(lPtr);
}
}
void
WMSetLabelImagePosition(WMLabel *lPtr, WMImagePosition position)
{
lPtr->flags.imagePosition = position;
if (lPtr->view->flags.realized) {
paintLabel(lPtr);
}
}
void
WMSetLabelTextAlignment(WMLabel *lPtr, WMAlignment alignment)
{
lPtr->flags.alignment = alignment;
if (lPtr->view->flags.realized) {
paintLabel(lPtr);
}
}
void
WMSetLabelRelief(WMLabel *lPtr, WMReliefType relief)
{
lPtr->flags.relief = relief;
if (lPtr->view->flags.realized) {
paintLabel(lPtr);
}
}
void
WMSetLabelText(WMLabel *lPtr, char *text)
{
if (lPtr->caption)
free(lPtr->caption);
if (text!=NULL) {
lPtr->caption = wstrdup(text);
} else {
lPtr->caption = NULL;
}
if (lPtr->view->flags.realized) {
paintLabel(lPtr);
}
}
void
WMSetLabelFont(WMLabel *lPtr, WMFont *font)
{
if (lPtr->font!=NULL)
WMReleaseFont(lPtr->font);
if (font)
lPtr->font = WMRetainFont(font);
else
lPtr->font = NULL;
if (lPtr->view->flags.realized) {
paintLabel(lPtr);
}
}
void
WMSetLabelTextColor(WMLabel *lPtr, WMColor *color)
{
if (lPtr->textColor)
WMReleaseColor(lPtr->textColor);
lPtr->textColor = WMRetainColor(color);
}
void
WMSetLabelWraps(WMLabel *lPtr, Bool flag)
{
if (lPtr->flags.noWrap != !flag) {
lPtr->flags.noWrap = !flag;
if (lPtr->view->flags.realized)
paintLabel(lPtr);
}
}
static void
paintLabel(Label *lPtr)
{
W_Screen *scrPtr = lPtr->view->screen;
GC gc;
if (lPtr->textColor)
gc = W_GC(lPtr->textColor);
else
gc = W_GC(scrPtr->black);
W_PaintTextAndImage(lPtr->view, !lPtr->flags.noWrap, gc,
(lPtr->font!=NULL ? lPtr->font : scrPtr->normalFont),
lPtr->flags.relief, lPtr->caption,
lPtr->flags.alignment, lPtr->image,
lPtr->flags.imagePosition, NULL, 0);
}
static void
handleEvents(XEvent *event, void *data)
{
Label *lPtr = (Label*)data;
CHECK_CLASS(data, WC_Label);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintLabel(lPtr);
break;
case DestroyNotify:
destroyLabel(lPtr);
break;
}
}
static void
destroyLabel(Label *lPtr)
{
if (lPtr->textColor)
WMReleaseColor(lPtr->textColor);
if (lPtr->caption)
free(lPtr->caption);
if (lPtr->font)
WMReleaseFont(lPtr->font);
if (lPtr->image)
WMReleasePixmap(lPtr->image);
free(lPtr);
}

797
WINGs/wlist.c Normal file
View File

@@ -0,0 +1,797 @@
#include "WINGsP.h"
typedef struct W_List {
W_Class widgetClass;
W_View *view;
WMListItem *items; /* array of items */
short itemCount;
short selectedItem;
short itemHeight;
short topItem; /* index of first visible item */
short fullFitLines; /* no of lines that fit entirely */
void *clientData;
WMAction *action;
void *doubleClientData;
WMAction *doubleAction;
WMListDrawProc *draw;
WMHandlerID *idleID; /* for updating the scroller after
* adding elements */
WMScroller *vScroller;
/*
WMScroller *hScroller;
*/
struct {
unsigned int allowMultipleSelection:1;
unsigned int userDrawn:1;
unsigned int userItemHeight:1;
/* */
unsigned int dontFitAll:1; /* 1 = last item won't be fully visible */
unsigned int redrawPending:1;
unsigned int buttonPressed:1;
unsigned int buttonWasPressed:1;
} flags;
} List;
#define DEFAULT_WIDTH 150
#define DEFAULT_HEIGHT 150
static void destroyList(List *lPtr);
static void paintList(List *lPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
static void updateScroller(List *lPtr);
static void vScrollCallBack(WMWidget *scroller, void *self);
static void resizeList();
W_ViewProcedureTable _ListViewProcedures = {
NULL,
resizeList,
NULL
};
WMList*
WMCreateList(WMWidget *parent)
{
List *lPtr;
W_Screen *scrPtr = W_VIEW(parent)->screen;
lPtr = wmalloc(sizeof(List));
memset(lPtr, 0, sizeof(List));
lPtr->widgetClass = WC_List;
lPtr->view = W_CreateView(W_VIEW(parent));
if (!lPtr->view) {
free(lPtr);
return NULL;
}
lPtr->view->self = lPtr;
WMCreateEventHandler(lPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, lPtr);
WMCreateEventHandler(lPtr->view, ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask|ButtonMotionMask,
handleActionEvents, lPtr);
lPtr->itemHeight = scrPtr->normalFont->height + 1;
/* create the vertical scroller */
lPtr->vScroller = WMCreateScroller(lPtr);
WMMoveWidget(lPtr->vScroller, 1, 1);
WMSetScrollerArrowsPosition(lPtr->vScroller, WSAMaxEnd);
WMSetScrollerAction(lPtr->vScroller, vScrollCallBack, lPtr);
/* make the scroller map itself when it's realized */
WMMapWidget(lPtr->vScroller);
resizeList(lPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
lPtr->selectedItem = -1;
return lPtr;
}
WMListItem*
WMAddSortedListItem(WMList *lPtr, char *text)
{
WMListItem *item;
WMListItem *tmp;
int index;
item = wmalloc(sizeof(WMListItem));
memset(item, 0, sizeof(WMListItem));
item->text = wstrdup(text);
if (!lPtr->items) {
lPtr->items = item;
index = 0;
} else if (strcmp(lPtr->items->text, text) > 0) {
item->nextPtr = lPtr->items;
lPtr->items = item;
index = 1;
} else {
int added = 0;
index = 0;
tmp = lPtr->items;
while (tmp->nextPtr) {
if (strcmp(tmp->nextPtr->text, text) >= 0) {
item->nextPtr = tmp->nextPtr;
tmp->nextPtr = item;
added = 1;
break;
}
index++;
tmp = tmp->nextPtr;
}
if (!added) {
tmp->nextPtr = item;
}
}
lPtr->itemCount++;
if (lPtr->selectedItem >= index)
lPtr->selectedItem++;
/* update the scroller when idle, so that we don't waste time
* updating it when another item is going to be added later */
if (!lPtr->idleID) {
lPtr->idleID = WMAddIdleHandler((WMCallback*)updateScroller, lPtr);
}
return item;
}
WMListItem*
WMInsertListItem(WMList *lPtr, int row, char *text)
{
WMListItem *item;
WMListItem *tmp = lPtr->items;
CHECK_CLASS(lPtr, WC_List);
item = wmalloc(sizeof(WMListItem));
memset(item, 0, sizeof(WMListItem));
item->text = wstrdup(text);
if (lPtr->selectedItem >= row && lPtr->selectedItem >= 0)
lPtr->selectedItem++;
if (lPtr->items==NULL) {
lPtr->items = item;
} else if (row == 0) {
item->nextPtr = lPtr->items;
lPtr->items = item;
} else if (row < 0) {
while (tmp->nextPtr)
tmp = tmp->nextPtr;
tmp->nextPtr = item;
row = lPtr->itemCount;
} else {
while (--row > 0)
tmp = tmp->nextPtr;
item->nextPtr = tmp->nextPtr;
tmp->nextPtr = item;
}
lPtr->itemCount++;
/* update the scroller when idle, so that we don't waste time
* updating it when another item is going to be added later */
if (!lPtr->idleID) {
lPtr->idleID = WMAddIdleHandler((WMCallback*)updateScroller, lPtr);
}
return item;
}
void
WMRemoveListItem(WMList *lPtr, int row)
{
WMListItem *llist;
WMListItem *tmp;
CHECK_CLASS(lPtr, WC_List);
if (row < 0 || row >= lPtr->itemCount)
return;
if (lPtr->selectedItem == row)
lPtr->selectedItem = -1;
else if (lPtr->selectedItem > row)
lPtr->selectedItem--;
if (row <= lPtr->topItem+lPtr->fullFitLines+lPtr->flags.dontFitAll)
lPtr->topItem--;
if (lPtr->topItem < 0)
lPtr->topItem = 0;
if (row == 0) {
if (lPtr->items->text)
free(lPtr->items->text);
tmp = lPtr->items->nextPtr;
free(lPtr->items);
lPtr->items = tmp;
} else {
llist = lPtr->items;
while (--row > 0)
llist = llist->nextPtr;
tmp = llist->nextPtr;
llist->nextPtr = llist->nextPtr->nextPtr;
if (tmp->text)
free(tmp->text);
free(tmp);
}
lPtr->itemCount--;
if (!lPtr->idleID) {
lPtr->idleID = WMAddIdleHandler((WMCallback*)updateScroller, lPtr);
}
}
WMListItem*
WMGetListItem(WMList *lPtr, int row)
{
WMListItem *listPtr;
listPtr = lPtr->items;
while (row-- > 0)
listPtr = listPtr->nextPtr;
return listPtr;
}
void
WMSetListUserDrawProc(WMList *lPtr, WMListDrawProc *proc)
{
lPtr->flags.userDrawn = 1;
lPtr->draw = proc;
}
void
WMSetListUserDrawItemHeight(WMList *lPtr, unsigned short height)
{
assert(height > 0);
lPtr->flags.userItemHeight = 1;
lPtr->itemHeight = height;
}
void
WMClearList(WMList *lPtr)
{
WMListItem *item, *tmp;
item = lPtr->items;
while (item) {
free(item->text);
tmp = item->nextPtr;
free(item);
item = tmp;
}
lPtr->items = NULL;
lPtr->itemCount = 0;
lPtr->topItem = 0;
lPtr->selectedItem = -1;
if (!lPtr->idleID) {
WMDeleteIdleHandler(lPtr->idleID);
lPtr->idleID = NULL;
}
if (lPtr->view->flags.realized) {
updateScroller(lPtr);
}
}
void
WMSetListAction(WMList *lPtr, WMAction *action, void *clientData)
{
lPtr->action = action;
lPtr->clientData = clientData;
}
void
WMSetListDoubleAction(WMList *lPtr, WMAction *action, void *clientData)
{
lPtr->doubleAction = action;
lPtr->doubleClientData = clientData;
}
WMListItem*
WMGetListSelectedItem(WMList *lPtr)
{
int i = lPtr->selectedItem;
WMListItem *item;
if (lPtr->selectedItem < 0)
return NULL;
item = lPtr->items;
while (i-- > 0) {
item = item->nextPtr;
}
return item;
}
int
WMGetListSelectedItemRow(WMList *lPtr)
{
return lPtr->selectedItem;
}
void
WMSetListPosition(WMList *lPtr, int row)
{
lPtr->topItem = row;
if (lPtr->topItem + lPtr->fullFitLines > lPtr->itemCount)
lPtr->topItem = lPtr->itemCount - lPtr->fullFitLines;
if (lPtr->topItem < 0)
lPtr->topItem = 0;
if (lPtr->view->flags.realized)
updateScroller(lPtr);
}
void
WMSetListBottomPosition(WMList *lPtr, int row)
{
if (lPtr->itemCount > lPtr->fullFitLines) {
lPtr->topItem = row - lPtr->fullFitLines;
if (lPtr->topItem < 0)
lPtr->topItem = 0;
if (lPtr->view->flags.realized)
updateScroller(lPtr);
}
}
int
WMGetListNumberOfRows(WMList *lPtr)
{
return lPtr->itemCount;
}
int
WMGetListPosition(WMList *lPtr)
{
return lPtr->topItem;
}
static void
vScrollCallBack(WMWidget *scroller, void *self)
{
WMList *lPtr = (WMList*)self;
WMScroller *sPtr = (WMScroller*)scroller;
int height;
height = lPtr->view->size.height - 4;
switch (WMGetScrollerHitPart(sPtr)) {
case WSDecrementLine:
if (lPtr->topItem > 0) {
lPtr->topItem--;
updateScroller(lPtr);
}
break;
case WSDecrementPage:
if (lPtr->topItem > 0) {
lPtr->topItem -= lPtr->fullFitLines-(1-lPtr->flags.dontFitAll)-1;
if (lPtr->topItem < 0)
lPtr->topItem = 0;
updateScroller(lPtr);
}
break;
case WSIncrementLine:
if (lPtr->topItem + lPtr->fullFitLines < lPtr->itemCount) {
lPtr->topItem++;
updateScroller(lPtr);
}
break;
case WSIncrementPage:
if (lPtr->topItem + lPtr->fullFitLines < lPtr->itemCount) {
lPtr->topItem += lPtr->fullFitLines-(1-lPtr->flags.dontFitAll)-1;
if (lPtr->topItem + lPtr->fullFitLines > lPtr->itemCount)
lPtr->topItem = lPtr->itemCount - lPtr->fullFitLines;
updateScroller(lPtr);
}
break;
case WSKnob:
{
int oldTopItem = lPtr->topItem;
lPtr->topItem = WMGetScrollerValue(lPtr->vScroller) *
(float)(lPtr->itemCount - lPtr->fullFitLines);
if (oldTopItem != lPtr->topItem)
paintList(lPtr);
}
break;
case WSKnobSlot:
case WSNoPart:
/* do nothing */
break;
}
}
static void
paintItem(List *lPtr, int index)
{
WMView *view = lPtr->view;
W_Screen *scr = view->screen;
int width, height, x, y;
WMListItem *itemPtr;
int i;
i = index;
itemPtr = lPtr->items;
while (i-- > 0)
itemPtr = itemPtr->nextPtr;
width = lPtr->view->size.width - 2 - 19;
height = lPtr->itemHeight;
x = 19;
y = 2 + (index-lPtr->topItem) * lPtr->itemHeight + 1;
if (lPtr->flags.userDrawn) {
WMRect rect;
int flags;
rect.size.width = width;
rect.size.height = height;
rect.pos.x = x;
rect.pos.y = y;
flags = itemPtr->uflags;
if (itemPtr->disabled)
flags |= WLDSDisabled;
if (itemPtr->selected)
flags |= WLDSSelected;
if (itemPtr->isBranch)
flags |= WLDSIsBranch;
if (lPtr->draw)
(*lPtr->draw)(lPtr, view->window, itemPtr->text, flags, &rect);
} else {
if (itemPtr->selected)
XFillRectangle(scr->display, view->window, W_GC(scr->white), x, y,
width, height);
else
XClearArea(scr->display, view->window, x, y, width, height, False);
W_PaintText(view, view->window, scr->normalFont, x+4, y, width,
WALeft, W_GC(scr->black), False,
itemPtr->text, strlen(itemPtr->text));
}
}
static void
paintList(List *lPtr)
{
W_Screen *scrPtr = lPtr->view->screen;
int i, lim;
if (!lPtr->view->flags.mapped)
return;
if (lPtr->itemCount>0) {
if (lPtr->topItem+lPtr->fullFitLines+lPtr->flags.dontFitAll > lPtr->itemCount) {
lim = lPtr->itemCount - lPtr->topItem;
XClearArea(scrPtr->display, lPtr->view->window, 19,
2+lim*lPtr->itemHeight, lPtr->view->size.width-21,
lPtr->view->size.height-lim*lPtr->itemHeight-3, False);
} else {
lim = lPtr->fullFitLines + lPtr->flags.dontFitAll;
}
for (i = lPtr->topItem; i < lPtr->topItem + lim; i++) {
paintItem(lPtr, i);
}
} else {
XClearWindow(scrPtr->display, lPtr->view->window);
}
W_DrawRelief(scrPtr, lPtr->view->window, 0, 0, lPtr->view->size.width,
lPtr->view->size.height, WRSunken);
}
#if 0
static void
scrollTo(List *lPtr, int newTop)
{
}
#endif
static void
updateScroller(List *lPtr)
{
float knobProportion, floatValue, tmp;
if (lPtr->idleID)
WMDeleteIdleHandler(lPtr->idleID);
lPtr->idleID = NULL;
paintList(lPtr);
if (lPtr->itemCount == 0 || lPtr->itemCount <= lPtr->fullFitLines)
WMSetScrollerParameters(lPtr->vScroller, 0, 1);
else {
tmp = lPtr->fullFitLines;
knobProportion = tmp/(float)lPtr->itemCount;
floatValue = (float)lPtr->topItem/(float)(lPtr->itemCount - lPtr->fullFitLines);
WMSetScrollerParameters(lPtr->vScroller, floatValue, knobProportion);
}
}
static void
handleEvents(XEvent *event, void *data)
{
List *lPtr = (List*)data;
CHECK_CLASS(data, WC_List);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintList(lPtr);
break;
case DestroyNotify:
destroyList(lPtr);
break;
}
}
int
WMFindRowOfListItemWithTitle(WMList *lPtr, char *title)
{
WMListItem *item;
int i;
int ok = 0;
for (i=0, item=lPtr->items; item!=NULL; item=item->nextPtr, i++) {
if (strcmp(item->text, title)==0) {
ok = 1;
break;
}
}
return ok ? i : -1;
}
void
WMSelectListItem(WMList *lPtr, int row)
{
WMListItem *itemPtr;
int i;
if (row >= lPtr->itemCount)
return;
if (!lPtr->flags.allowMultipleSelection) {
/* unselect previous selected item */
if (lPtr->selectedItem >= 0) {
itemPtr = lPtr->items;
for (i=0; i<lPtr->selectedItem; i++)
itemPtr = itemPtr->nextPtr;
if (itemPtr->selected) {
itemPtr->selected = 0;
if (lPtr->view->flags.mapped && i>=lPtr->topItem
&& i<=lPtr->topItem+lPtr->fullFitLines)
paintItem(lPtr, i);
}
}
}
if (row < 0) {
if (!lPtr->flags.allowMultipleSelection)
lPtr->selectedItem = -1;
return;
}
/* select item */
itemPtr = lPtr->items;
for (i=0; i<row; i++)
itemPtr = itemPtr->nextPtr;
if (lPtr->flags.allowMultipleSelection)
itemPtr->selected = !itemPtr->selected;
else
itemPtr->selected = 1;
if (lPtr->view->flags.mapped) {
paintItem(lPtr, row);
if ((row-lPtr->topItem+lPtr->fullFitLines)*lPtr->itemHeight
> lPtr->view->size.height-2)
W_DrawRelief(lPtr->view->screen, lPtr->view->window, 0, 0,
lPtr->view->size.width, lPtr->view->size.height,
WRSunken);
}
lPtr->selectedItem = row;
}
static int
getItemIndexAt(List *lPtr, int clickY)
{
int index;
index = (clickY - 2) / lPtr->itemHeight + lPtr->topItem;
if (index < 0 || index >= lPtr->itemCount)
return -1;
return index;
}
static void
handleActionEvents(XEvent *event, void *data)
{
List *lPtr = (List*)data;
int tmp;
CHECK_CLASS(data, WC_List);
switch (event->type) {
case ButtonRelease:
lPtr->flags.buttonPressed = 0;
tmp = getItemIndexAt(lPtr, event->xbutton.y);
if (tmp == lPtr->selectedItem && tmp >= 0) {
if (WMIsDoubleClick(event)) {
if (lPtr->doubleAction)
(*lPtr->doubleAction)(lPtr, lPtr->doubleClientData);
} else {
if (lPtr->action)
(*lPtr->action)(lPtr, lPtr->clientData);
}
}
break;
case EnterNotify:
lPtr->flags.buttonPressed = lPtr->flags.buttonWasPressed;
lPtr->flags.buttonWasPressed = 0;
break;
case LeaveNotify:
lPtr->flags.buttonWasPressed = lPtr->flags.buttonPressed;
lPtr->flags.buttonPressed = 0;
break;
case ButtonPress:
if (event->xbutton.x > WMWidgetWidth(lPtr->vScroller)) {
tmp = getItemIndexAt(lPtr, event->xbutton.y);
if (tmp>=0) {
WMSelectListItem(lPtr, tmp);
lPtr->selectedItem = tmp;
}
lPtr->flags.buttonPressed = 1;
}
break;
case MotionNotify:
if (lPtr->flags.buttonPressed) {
tmp = getItemIndexAt(lPtr, event->xmotion.y);
if (tmp>=0 && tmp != lPtr->selectedItem) {
WMSelectListItem(lPtr, tmp);
lPtr->selectedItem = tmp;
}
}
break;
}
}
static void
resizeList(WMList *lPtr, unsigned int width, unsigned int height)
{
W_ResizeView(lPtr->view, width, height);
WMResizeWidget(lPtr->vScroller, 1, height-2);
lPtr->fullFitLines = (height - 4) / lPtr->itemHeight;
if (lPtr->fullFitLines * lPtr->itemHeight < height-4) {
lPtr->flags.dontFitAll = 1;
} else {
lPtr->flags.dontFitAll = 0;
}
}
static void
destroyList(List *lPtr)
{
WMListItem *itemPtr;
if (lPtr->idleID)
WMDeleteIdleHandler(lPtr->idleID);
lPtr->idleID = NULL;
while (lPtr->items!=NULL) {
itemPtr = lPtr->items;
if (itemPtr->text)
free(itemPtr->text);
lPtr->items = itemPtr->nextPtr;
free(itemPtr);
}
free(lPtr);
}

97
WINGs/wmfile.c Normal file
View File

@@ -0,0 +1,97 @@
/*
* Author: Len Trigg <trigg@cs.waikato.ac.nz>
*/
#include "WINGs.h"
#include <unistd.h>
#include <stdio.h>
#include "logo.xpm"
void
wAbort()
{
exit(1);
}
char *ProgName;
void usage(void)
{
fprintf(stderr,
"usage:\n"
"\t%s [-options]\n"
"\n"
"options:\n"
" -i <str>\tInitial directory (default /)\n"
" -t <str>\tQuery window title (default none)\n"
"\n"
"information:\n"
"\t%s pops up a WindowMaker style file selection panel.\n"
"\n"
"version:\n"
"\t%s\n"
,ProgName,ProgName,__DATE__
);
exit(0);
}
int main(int argc, char **argv)
{
Display *dpy = XOpenDisplay("");
WMScreen *scr;
WMPixmap *pixmap;
WMOpenPanel *panel;
/* RImage *image;*/
char *title = NULL;
char *initial = "/";
int ch;
extern char *optarg;
extern int optind;
WMInitializeApplication("WMFile", &argc, argv);
ProgName = argv[0];
if (!dpy) {
puts("could not open display");
exit(1);
}
while((ch = getopt(argc, argv, "i:ht:")) != -1)
switch(ch)
{
case 'i':
initial = optarg;
break;
case 't':
title = optarg;
break;
default:
usage();
}
for(; optind <argc; optind++)
usage();
scr = WMCreateSimpleApplicationScreen(dpy);
pixmap = WMCreatePixmapFromXPMData(scr, GNUSTEP_XPM);
WMSetApplicationIconImage(scr, pixmap); WMReleasePixmap(pixmap);
panel = WMGetOpenPanel(scr);
/* The 3rd argument for this function is the initial name of the file,
* not the name of the window, although it's not implemented yet */
if (WMRunModalOpenPanelForDirectory(panel, NULL, initial, /*title*/ NULL, NULL) == True)
printf("%s\n", WMGetFilePanelFileName(panel));
else
printf("\n");
return 0;
}

297
WINGs/wmisc.c Normal file
View File

@@ -0,0 +1,297 @@
#include "WINGsP.h"
#include <wraster.h>
#include <ctype.h>
void
W_DrawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
unsigned int height, WMReliefType relief)
{
Display *dpy = scr->display;
GC bgc;
GC wgc;
GC lgc;
GC dgc;
switch (relief) {
case WRSimple:
XDrawRectangle(dpy, d, W_GC(scr->black), x, y, width-1, height-1);
return;
break;
case WRRaised:
bgc = W_GC(scr->black);
dgc = W_GC(scr->darkGray);
wgc = W_GC(scr->white);
lgc = W_GC(scr->gray);
break;
case WRSunken:
wgc = W_GC(scr->darkGray);
lgc = W_GC(scr->black);
bgc = W_GC(scr->white);
dgc = W_GC(scr->gray);
break;
case WRPushed:
lgc = wgc = W_GC(scr->black);
dgc = bgc = W_GC(scr->white);
break;
case WRRidge:
lgc = bgc = W_GC(scr->darkGray);
dgc = wgc = W_GC(scr->white);
break;
case WRGroove:
wgc = dgc = W_GC(scr->darkGray);
lgc = bgc = W_GC(scr->white);
break;
default:
return;
}
/* top left */
XDrawLine(dpy, d, wgc, x, y, x+width-1, y);
if (width > 2 && relief != WRRaised && relief!=WRPushed) {
XDrawLine(dpy, d, lgc, x+1, y+1, x+width-3, y+1);
}
XDrawLine(dpy, d, wgc, x, y, x, y+height-1);
if (height > 2 && relief != WRRaised && relief!=WRPushed) {
XDrawLine(dpy, d, lgc, x+1, y+1, x+1, y+height-3);
}
/* bottom right */
XDrawLine(dpy, d, bgc, x, y+height-1, x+width-1, y+height-1);
if (width > 2 && relief!=WRPushed) {
XDrawLine(dpy, d, dgc, x+1, y+height-2, x+width-2, y+height-2);
}
XDrawLine(dpy, d, bgc, x+width-1, y, x+width-1, y+height-1);
if (height > 2 && relief!=WRPushed) {
XDrawLine(dpy, d, dgc, x+width-2, y+2, x+width-2, y+height-3);
}
}
static int
fitText(char *text, WMFont *font, int width, int wrap)
{
int i, j;
int w;
if (text[0]==0)
return 0;
i = 0;
if (wrap) {
do {
i++;
w = WMWidthOfString(font, text, i);
} while (w < width && text[i]!='\n' && text[i]!=0);
/* keep words complete */
if (!isspace(text[i])) {
j = i;
while (j>1 && !isspace(text[j]) && text[j]!=0)
j--;
if (j>1)
i = j;
}
} else {
while (text[i]!='\n' && text[i]!=0)
i++;
}
return i;
}
int
W_GetTextHeight(WMFont *font, char *text, int width, int wrap)
{
char *ptr = text;
int count;
int length = strlen(text);
int h;
h = 0;
while (length > 0) {
count = fitText(ptr, font, width, wrap);
h += font->height;
if (isspace(ptr[count]))
count++;
ptr += count;
length -= count;
}
return h;
}
void
W_PaintText(W_View *view, Drawable d, WMFont *font, int x, int y,
int width, WMAlignment alignment, GC gc,
int wrap, char *text, int length)
{
char *ptr = text;
int line_width;
int line_x;
int count;
while (length > 0) {
count = fitText(ptr, font, width, wrap);
line_width = WMWidthOfString(font, ptr, count);
if (alignment==WALeft)
line_x = x;
else if (alignment==WARight)
line_x = x + width - line_width;
else
line_x = x + (width - line_width) / 2;
WMDrawString(view->screen, d, gc, font, line_x, y, ptr, count);
y += font->height;
if (isspace(ptr[count]))
count++;
ptr += count;
length -= count;
}
}
void
W_PaintTextAndImage(W_View *view, int wrap, GC textGC, W_Font *font,
WMReliefType relief, char *text,
WMAlignment alignment, W_Pixmap *image,
WMImagePosition position, GC backGC, int ofs)
{
W_Screen *screen = view->screen;
int ix, iy;
int x, y, w, h;
Drawable d = view->window;
#ifdef DOUBLE_BUFFER
d = XCreatePixmap(screen->display, view->window,
view->size.width, view->size.height, screen->depth);
#endif
/* background */
#ifndef DOUBLE_BUFFER
if (backGC) {
XFillRectangle(screen->display, d, backGC,
0, 0, view->size.width, view->size.height);
} else {
XClearWindow(screen->display, d);
}
#else
if (backGC)
XFillRectangle(screen->display, d, backGC, 0, 0,
view->size.width, view->size.height);
else {
XSetForeground(screen->display, screen->copyGC,
view->attribs.background_pixel);
XFillRectangle(screen->display, d, screen->copyGC, 0, 0,
view->size.width, view->size.height);
}
#endif
if (relief == WRFlat) {
x = 0;
y = 0;
w = view->size.width;
h = view->size.height;
} else {
x = 2;
y = 2;
w = view->size.width - 4;
h = view->size.height - 4;
}
/* calc. image alignment */
if (position!=WIPNoImage && image!=NULL) {
switch (position) {
case WIPOverlaps:
case WIPImageOnly:
ix = (view->size.width - image->width) / 2;
iy = (view->size.height - image->height) / 2;
/*
x = 2;
y = 0;
*/
break;
case WIPLeft:
ix = x;
iy = y + (h - image->height) / 2;
x = x + image->width + 5;
y = 0;
w -= image->width + 5;
break;
case WIPRight:
ix = view->size.width - image->width - x;
iy = y + (h - image->height) / 2;
w -= image->width + 5;
break;
case WIPBelow:
ix = (view->size.width - image->width) / 2;
iy = h - image->height;
y = 0;
h -= image->height;
break;
default:
case WIPAbove:
ix = (view->size.width - image->width) / 2;
iy = y;
y = image->height;
h -= image->height;
break;
}
ix += ofs;
iy += ofs;
XSetClipOrigin(screen->display, screen->clipGC, ix, iy);
XSetClipMask(screen->display, screen->clipGC, image->mask);
if (image->depth==1)
XCopyPlane(screen->display, image->pixmap, d, screen->clipGC,
0, 0, image->width, image->height, ix, iy, 1);
else
XCopyArea(screen->display, image->pixmap, d, screen->clipGC,
0, 0, image->width, image->height, ix, iy);
}
/* draw text */
if (position != WIPImageOnly && text!=NULL) {
int textHeight;
textHeight = W_GetTextHeight(font, text, w-8, wrap);
W_PaintText(view, d, font, x+ofs+4, y+ofs + (h-textHeight)/2, w-8,
alignment, textGC, wrap, text, strlen(text));
}
/* draw relief */
W_DrawRelief(screen, d, 0, 0, view->size.width, view->size.height, relief);
#ifdef DOUBLE_BUFFER
XCopyArea(screen->display, d, view->window, screen->copyGC, 0, 0,
view->size.width, view->size.height, 0, 0);
XFreePixmap(screen->display, d);
#endif
}

99
WINGs/wmquery.c Normal file
View File

@@ -0,0 +1,99 @@
/*
* Author: Len Trigg <trigg@cs.waikato.ac.nz>
*/
#include "WINGs.h"
#include <unistd.h>
#include <stdio.h>
#include "logo.xpm"
void
wAbort()
{
exit(1);
}
char *ProgName;
void usage(void)
{
fprintf(stderr,
"usage:\n"
"\t%s [-options]\n"
"\n"
"options:\n"
" -i <str>\tInitial entry contents (default none)\n"
" -p <str>\tPrompt message (default none)\n"
" -t <str>\tQuery window title (default none)\n"
"\n"
"information:\n"
"\t%s pops up a WindowMaker style input panel.\n"
"\n"
"version:\n"
"\t%s\n"
,ProgName,ProgName,__DATE__
);
exit(0);
}
int main(int argc, char **argv)
{
Display *dpy = XOpenDisplay("");
WMScreen *scr;
WMPixmap *pixmap;
char *title = NULL;
char *prompt = NULL;
char *initial = NULL;
char *result = NULL;
int ch;
extern char *optarg;
extern int optind;
WMInitializeApplication("WMQuery", &argc, argv);
ProgName = argv[0];
if (!dpy) {
puts("could not open display");
exit(1);
}
while((ch = getopt(argc, argv, "i:hp:t:")) != -1)
switch(ch)
{
case 'i':
initial = optarg;
break;
case 'p':
prompt = optarg;
break;
case 't':
title = optarg;
break;
default:
usage();
}
for(; optind <argc; optind++)
usage();
scr = WMCreateSimpleApplicationScreen(dpy);
pixmap = WMCreatePixmapFromXPMData(scr, GNUSTEP_XPM);
WMSetApplicationIconImage(scr, pixmap); WMReleasePixmap(pixmap);
if ((result = WMRunInputPanel(scr, NULL, title, prompt, initial, "OK", "Cancel")) != NULL)
printf("%s\n", result);
else
printf("\n");
return 0;
}

399
WINGs/wpanel.c Normal file
View File

@@ -0,0 +1,399 @@
#include "WINGsP.h"
#include <X11/keysym.h>
static void
alertPanelOnClick(WMWidget *self, void *clientData)
{
WMAlertPanel *panel = clientData;
panel->done = 1;
if (self == panel->defBtn) {
panel->result = WAPRDefault;
} else if (self == panel->othBtn) {
panel->result = WAPROther;
} else if (self == panel->altBtn) {
panel->result = WAPRAlternate;
}
}
static void
handleKeyPress(XEvent *event, void *clientData)
{
WMAlertPanel *panel = (WMAlertPanel*)clientData;
if (event->xkey.keycode == panel->retKey) {
WMPerformButtonClick(panel->defBtn);
}
}
int
WMRunAlertPanel(WMScreen *scrPtr, WMWindow *owner,
char *title, char *msg, char *defaultButton,
char *alternateButton, char *otherButton)
{
WMAlertPanel *panel;
int tmp;
panel = WMCreateAlertPanel(scrPtr, owner, title, msg, defaultButton,
alternateButton, otherButton);
scrPtr->modalView = W_VIEW(panel->win);
WMMapWidget(panel->win);
scrPtr->modal = 1;
while (!panel->done || WMScreenPending(scrPtr)) {
XEvent event;
WMNextEvent(scrPtr->display, &event);
WMHandleEvent(&event);
}
scrPtr->modal = 0;
tmp = panel->result;
WMDestroyAlertPanel(panel);
return tmp;
}
void
WMDestroyAlertPanel(WMAlertPanel *panel)
{
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
free(panel);
}
WMAlertPanel*
WMCreateAlertPanel(WMScreen *scrPtr, WMWindow *owner,
char *title, char *msg, char *defaultButton,
char *alternateButton, char *otherButton)
{
WMAlertPanel *panel;
int x, dw=0, aw=0, ow=0, w;
panel = wmalloc(sizeof(WMAlertPanel));
memset(panel, 0, sizeof(WMAlertPanel));
panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
if (owner)
panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel",
WMTitledWindowMask);
else
panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel",
WMTitledWindowMask);
WMSetWindowTitle(panel->win, "");
if (scrPtr->applicationIcon) {
panel->iLbl = WMCreateLabel(panel->win);
WMResizeWidget(panel->iLbl, scrPtr->applicationIcon->width,
scrPtr->applicationIcon->height);
WMMoveWidget(panel->iLbl, 8 + (64 - scrPtr->applicationIcon->width)/2,
(75 - scrPtr->applicationIcon->height)/2);
WMSetLabelImage(panel->iLbl, scrPtr->applicationIcon);
WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
}
if (title) {
WMFont *largeFont;
largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
panel->tLbl = WMCreateLabel(panel->win);
WMMoveWidget(panel->tLbl, 80, (80 - largeFont->height)/2);
WMResizeWidget(panel->tLbl, 400 - 70, largeFont->height+4);
WMSetLabelText(panel->tLbl, title);
WMSetLabelTextAlignment(panel->tLbl, WALeft);
WMSetLabelFont(panel->tLbl, largeFont);
WMReleaseFont(largeFont);
}
if (msg) {
panel->mLbl = WMCreateLabel(panel->win);
WMMoveWidget(panel->mLbl, 10, 83);
WMResizeWidget(panel->mLbl, 380, scrPtr->normalFont->height*4);
WMSetLabelText(panel->mLbl, msg);
WMSetLabelTextAlignment(panel->mLbl, WACenter);
}
/* create divider line */
panel->line = WMCreateFrame(panel->win);
WMMoveWidget(panel->line, 0, 80);
WMResizeWidget(panel->line, 400, 2);
WMSetFrameRelief(panel->line, WRGroove);
/* create buttons */
if (otherButton)
ow = WMWidthOfString(scrPtr->normalFont, otherButton,
strlen(otherButton));
if (alternateButton)
aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
strlen(alternateButton));
if (defaultButton)
dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
strlen(defaultButton));
w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
if (aw > w)
w = aw;
if (ow > w)
w = ow;
w += 30;
x = 400;
if (defaultButton) {
x -= w + 10;
panel->defBtn = WMCreateCommandButton(panel->win);
WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
WMMoveWidget(panel->defBtn, x, 144);
WMResizeWidget(panel->defBtn, w, 24);
WMSetButtonText(panel->defBtn, defaultButton);
WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
WMSetButtonImagePosition(panel->defBtn, WIPRight);
}
if (alternateButton) {
x -= w + 10;
panel->altBtn = WMCreateCommandButton(panel->win);
WMMoveWidget(panel->altBtn, x, 144);
WMResizeWidget(panel->altBtn, w, 24);
WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
WMSetButtonText(panel->altBtn, alternateButton);
}
if (otherButton) {
x -= w + 10;
panel->othBtn = WMCreateCommandButton(panel->win);
WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
WMMoveWidget(panel->othBtn, x, 144);
WMResizeWidget(panel->othBtn, w, 24);
WMSetButtonText(panel->othBtn, otherButton);
}
panel->done = 0;
WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
handleKeyPress, panel);
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->win);
return panel;
}
static void
inputBoxOnClick(WMWidget *self, void *clientData)
{
WMInputPanel *panel = clientData;
panel->done = 1;
if (self == panel->defBtn) {
panel->result = WAPRDefault;
} else if (self == panel->altBtn) {
panel->result = WAPRAlternate;
}
}
static void
handleKeyPress2(XEvent *event, void *clientData)
{
WMInputPanel *panel = (WMInputPanel*)clientData;
if (event->xkey.keycode == panel->retKey) {
WMPerformButtonClick(panel->defBtn);
}
}
char*
WMRunInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title,
char *msg, char *defaultText,
char *okButton, char *cancelButton)
{
WMInputPanel *panel;
char *tmp;
panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText,
okButton, cancelButton);
WMMapWidget(panel->win);
while (!panel->done || WMScreenPending(scrPtr)) {
XEvent event;
WMNextEvent(scrPtr->display, &event);
WMHandleEvent(&event);
}
if (panel->result == WAPRDefault)
tmp = WMGetTextFieldText(panel->text);
else
tmp = NULL;
WMDestroyInputPanel(panel);
return tmp;
}
void
WMDestroyInputPanel(WMInputPanel *panel)
{
WMRemoveNotificationObserver(panel);
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
free(panel);
}
static void
endedEditingObserver(void *observerData, WMNotification *notification)
{
WMInputPanel *panel = (WMInputPanel*)observerData;
if ((int)WMGetNotificationClientData(notification) == WMReturnTextMovement) {
WMPerformButtonClick(panel->defBtn);
}
}
WMInputPanel*
WMCreateInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title, char *msg,
char *defaultText, char *okButton, char *cancelButton)
{
WMInputPanel *panel;
int x, dw=0, aw=0, w;
panel = wmalloc(sizeof(WMInputPanel));
memset(panel, 0, sizeof(WMInputPanel));
panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
if (owner)
panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel",
WMTitledWindowMask);
else
panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel",
WMTitledWindowMask);
WMSetWindowTitle(panel->win, "");
WMResizeWidget(panel->win, 320, 160);
if (title) {
WMFont *largeFont;
largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
panel->tLbl = WMCreateLabel(panel->win);
WMMoveWidget(panel->tLbl, 20, 16);
WMResizeWidget(panel->tLbl, 320 - 40, largeFont->height+4);
WMSetLabelText(panel->tLbl, title);
WMSetLabelTextAlignment(panel->tLbl, WALeft);
WMSetLabelFont(panel->tLbl, largeFont);
WMReleaseFont(largeFont);
}
if (msg) {
panel->mLbl = WMCreateLabel(panel->win);
WMMoveWidget(panel->mLbl, 20, 50);
WMResizeWidget(panel->mLbl, 320 - 40,scrPtr->normalFont->height*2);
WMSetLabelText(panel->mLbl, msg);
WMSetLabelTextAlignment(panel->mLbl, WALeft);
}
panel->text = WMCreateTextField(panel->win);
WMMoveWidget(panel->text, 20, 85);
WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
WMSetTextFieldText(panel->text, defaultText);
WMAddNotificationObserver(endedEditingObserver, panel,
WMTextDidEndEditingNotification, panel->text);
/* create buttons */
if (cancelButton)
aw = WMWidthOfString(scrPtr->normalFont, cancelButton,
strlen(cancelButton));
if (okButton)
dw = WMWidthOfString(scrPtr->normalFont, okButton,
strlen(okButton));
w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
if (aw > w)
w = aw;
w += 30;
x = 310;
if (okButton) {
x -= w + 10;
panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
|WBBPushChangeMask
|WBBPushLightMask);
WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
WMMoveWidget(panel->defBtn, x, 124);
WMResizeWidget(panel->defBtn, w, 24);
WMSetButtonText(panel->defBtn, okButton);
WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
WMSetButtonImagePosition(panel->defBtn, WIPRight);
}
if (cancelButton) {
x -= w + 10;
panel->altBtn = WMCreateCommandButton(panel->win);
WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
WMMoveWidget(panel->altBtn, x, 124);
WMResizeWidget(panel->altBtn, w, 24);
WMSetButtonText(panel->altBtn, cancelButton);
}
panel->done = 0;
WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
handleKeyPress2, panel);
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->win);
WMSetFocusToWidget(panel->text);
return panel;
}

205
WINGs/wpixmap.c Normal file
View File

@@ -0,0 +1,205 @@
#include "WINGsP.h"
#include <wraster.h>
WMPixmap*
WMRetainPixmap(WMPixmap *pixmap)
{
if (pixmap)
pixmap->refCount++;
return pixmap;
}
void
WMReleasePixmap(WMPixmap *pixmap)
{
pixmap->refCount--;
if (pixmap->refCount<1) {
XFreePixmap(pixmap->screen->display, pixmap->pixmap);
if (pixmap->mask)
XFreePixmap(pixmap->screen->display, pixmap->mask);
free(pixmap);
}
}
WMPixmap*
WMCreatePixmapFromXPixmaps(WMScreen *scrPtr, Pixmap pixmap, Pixmap mask,
int width, int height, int depth)
{
WMPixmap *pixPtr;
pixPtr = malloc(sizeof(WMPixmap));
if (!pixPtr) {
return NULL;
}
pixPtr->screen = scrPtr;
pixPtr->pixmap = pixmap;
pixPtr->mask = mask;
pixPtr->width = width;
pixPtr->height = height;
pixPtr->depth = depth;
pixPtr->refCount = 1;
return pixPtr;
}
WMPixmap*
WMCreatePixmapFromFile(WMScreen *scrPtr, char *fileName)
{
WMPixmap *pixPtr;
RImage *image;
image = RLoadImage(scrPtr->rcontext, fileName, 0);
if (!image)
return NULL;
pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 127);
RDestroyImage(image);
return pixPtr;
}
WMPixmap*
WMCreatePixmapFromRImage(WMScreen *scrPtr, RImage *image, int threshold)
{
WMPixmap *pixPtr;
Pixmap pixmap, mask;
if (!RConvertImageMask(scrPtr->rcontext, image, &pixmap, &mask,
threshold)) {
return NULL;
}
pixPtr = malloc(sizeof(WMPixmap));
if (!pixPtr) {
return NULL;
}
pixPtr->screen = scrPtr;
pixPtr->pixmap = pixmap;
pixPtr->mask = mask;
pixPtr->width = image->width;
pixPtr->height = image->height;
pixPtr->depth = scrPtr->depth;
pixPtr->refCount = 1;
return pixPtr;
}
WMPixmap*
WMCreateBlendedPixmapFromFile(WMScreen *scrPtr, char *fileName, RColor *color)
{
WMPixmap *pixPtr;
RImage *image;
image = RLoadImage(scrPtr->rcontext, fileName, 0);
if (!image)
return NULL;
RCombineImageWithColor(image, color);
pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 0);
RDestroyImage(image);
return pixPtr;
}
WMPixmap*
WMCreatePixmapFromXPMData(WMScreen *scrPtr, char **data)
{
WMPixmap *pixPtr;
RImage *image;
image = RGetImageFromXPMData(scrPtr->rcontext, data);
if (!image)
return NULL;
pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 127);
RDestroyImage(image);
return pixPtr;
}
Pixmap
WMGetPixmapXID(WMPixmap *pixmap)
{
return pixmap->pixmap;
}
Pixmap
WMGetPixmapMaskXID(WMPixmap *pixmap)
{
return pixmap->mask;
}
WMSize
WMGetPixmapSize(WMPixmap *pixmap)
{
WMSize size;
size.width = pixmap->width;
size.height = pixmap->height;
return size;
}
WMPixmap*
WMGetSystemPixmap(WMScreen *scr, int image)
{
switch (image) {
case WSIReturnArrow:
return WMRetainPixmap(scr->buttonArrow);
case WSIHighlightedReturnArrow:
return WMRetainPixmap(scr->pushedButtonArrow);
case WSIScrollerDimple:
return WMRetainPixmap(scr->scrollerDimple);
case WSIArrowLeft:
return WMRetainPixmap(scr->leftArrow);
case WSIHighlightedArrowLeft:
return WMRetainPixmap(scr->hiLeftArrow);
case WSIArrowRight:
return WMRetainPixmap(scr->rightArrow);
case WSIHighlightedArrowRight:
return WMRetainPixmap(scr->hiRightArrow);
case WSIArrowUp:
return WMRetainPixmap(scr->upArrow);
case WSIHighlightedArrowUp:
return WMRetainPixmap(scr->hiUpArrow);
case WSIArrowDown:
return WMRetainPixmap(scr->downArrow);
case WSIHighlightedArrowDown:
return WMRetainPixmap(scr->hiDownArrow);
default:
return NULL;
}
}

709
WINGs/wpopupbutton.c Normal file
View File

@@ -0,0 +1,709 @@
#include "WINGsP.h"
typedef struct ItemList {
char *text;
struct ItemList *nextPtr;
unsigned int disabled:1;
} ItemList;
typedef struct W_PopUpButton {
W_Class widgetClass;
WMView *view;
void *clientData;
WMAction *action;
char *caption;
ItemList *items;
short itemCount;
short selectedItemIndex;
short highlightedItem;
ItemList *selectedItem; /* selected item if it is a menu btn */
WMView *menuView; /* override redirect popup menu */
struct {
unsigned int pullsDown:1;
unsigned int configured:1;
unsigned int insideMenu:1;
} flags;
} PopUpButton;
#define MENU_BLINK_DELAY 60000
#define MENU_BLINK_COUNT 2
W_ViewProcedureTable _PopUpButtonViewProcedures = {
NULL,
NULL,
NULL
};
#define DEFAULT_WIDTH 60
#define DEFAULT_HEIGHT 20
#define DEFAULT_CAPTION ""
static void destroyPopUpButton(PopUpButton *bPtr);
static void paintPopUpButton(PopUpButton *bPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
static void resizeMenu(PopUpButton *bPtr);
WMPopUpButton*
WMCreatePopUpButton(WMWidget *parent)
{
PopUpButton *bPtr;
W_Screen *scr = W_VIEW(parent)->screen;
bPtr = wmalloc(sizeof(PopUpButton));
memset(bPtr, 0, sizeof(PopUpButton));
bPtr->widgetClass = WC_PopUpButton;
bPtr->view = W_CreateView(W_VIEW(parent));
if (!bPtr->view) {
free(bPtr);
return NULL;
}
bPtr->view->self = bPtr;
WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, bPtr);
W_ResizeView(bPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
bPtr->caption = wstrdup(DEFAULT_CAPTION);
WMCreateEventHandler(bPtr->view, ButtonPressMask|ButtonReleaseMask,
handleActionEvents, bPtr);
bPtr->menuView = W_CreateTopView(scr);
bPtr->menuView->attribs.override_redirect = True;
bPtr->menuView->attribFlags |= CWOverrideRedirect;
W_ResizeView(bPtr->menuView, bPtr->view->size.width, 1);
WMCreateEventHandler(bPtr->menuView, ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask|ButtonMotionMask,
handleActionEvents, bPtr);
return bPtr;
}
void
WMSetPopUpButtonAction(WMPopUpButton *bPtr, WMAction *action, void *clientData)
{
CHECK_CLASS(bPtr, WC_PopUpButton);
bPtr->action = action;
bPtr->clientData = clientData;
}
void
WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title)
{
ItemList *itemPtr, *tmp;
CHECK_CLASS(bPtr, WC_PopUpButton);
itemPtr = wmalloc(sizeof(ItemList));
memset(itemPtr, 0, sizeof(ItemList));
itemPtr->text = wstrdup(title);
/* append item to list */
tmp = bPtr->items;
if (!tmp)
bPtr->items = itemPtr;
else {
while (tmp->nextPtr!=NULL)
tmp = tmp->nextPtr;
tmp->nextPtr = itemPtr;
}
bPtr->itemCount++;
if (bPtr->menuView && bPtr->menuView->flags.realized)
resizeMenu(bPtr);
}
void
WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, char *title)
{
ItemList *itemPtr;
CHECK_CLASS(bPtr, WC_PopUpButton);
if (index < 0)
index = 0;
if (index >= bPtr->itemCount) {
WMAddPopUpButtonItem(bPtr, title);
return;
}
itemPtr = wmalloc(sizeof(ItemList));
memset(itemPtr, 0, sizeof(ItemList));
itemPtr->text = wstrdup(title);
if (index == 0) {
itemPtr->nextPtr = bPtr->items;
bPtr->items = itemPtr;
} else {
ItemList *tmp;
int i = index;
tmp = bPtr->items;
/* insert item in list */
while (--i > 0) {
tmp = tmp->nextPtr;
}
bPtr->items->nextPtr = tmp->nextPtr;
tmp->nextPtr = bPtr->items;
}
bPtr->itemCount++;
/* if there is an selected item, update it's index to match the new
* position */
if (index < bPtr->selectedItemIndex)
bPtr->selectedItemIndex++;
if (bPtr->menuView && bPtr->menuView->flags.realized)
resizeMenu(bPtr);
}
void
WMRemovePopUpButtonItem(WMPopUpButton *bPtr, int index)
{
ItemList *tmp;
CHECK_CLASS(bPtr, WC_PopUpButton);
if (index < 0 || index >= bPtr->itemCount)
return;
if (index == 0) {
free(bPtr->items->text);
tmp = bPtr->items->nextPtr;
free(bPtr->items);
bPtr->items = tmp;
} else {
ItemList *next;
int i = index;
tmp = bPtr->items;
while (--i > 0)
tmp = tmp->nextPtr;
next = tmp->nextPtr->nextPtr;
free(tmp->nextPtr->text);
free(tmp->nextPtr);
tmp->nextPtr = next;
}
bPtr->itemCount--;
if (bPtr->selectedItem!=NULL && !bPtr->flags.pullsDown) {
if (index < bPtr->selectedItemIndex)
bPtr->selectedItemIndex--;
else if (index == bPtr->selectedItemIndex) {
/* reselect first item if the removed item is the
* selected one */
bPtr->selectedItem = bPtr->items;
bPtr->selectedItemIndex = 0;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
}
if (bPtr->menuView && bPtr->menuView->flags.realized)
resizeMenu(bPtr);
}
void
WMSetPopUpButtonSelectedItem(WMPopUpButton *bPtr, int index)
{
ItemList *itemPtr = bPtr->items;
int i = index;
if (index < 0) {
bPtr->selectedItem = NULL;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
return;
}
while (i-- > 0) {
itemPtr = itemPtr->nextPtr;
}
bPtr->selectedItem = itemPtr;
bPtr->selectedItemIndex = index;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
int
WMGetPopUpButtonSelectedItem(WMPopUpButton *bPtr)
{
if (!bPtr->flags.pullsDown && bPtr->selectedItem==NULL)
return -1;
else
return bPtr->selectedItemIndex;
}
void
WMSetPopUpButtonText(WMPopUpButton *bPtr, char *text)
{
if (bPtr->caption)
free(bPtr->caption);
if (text)
bPtr->caption = wstrdup(text);
else
bPtr->caption = NULL;
if (bPtr->view->flags.realized) {
if (bPtr->flags.pullsDown || bPtr->selectedItemIndex < 0) {
paintPopUpButton(bPtr);
}
}
}
void
WMSetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index, Bool flag)
{
int i;
ItemList *item = bPtr->items;
if (index < 0 || index >= bPtr->itemCount)
return;
for (i = 0; i<index; i++)
item=item->nextPtr;
item->disabled = !flag;
}
void
WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag)
{
bPtr->flags.pullsDown = flag;
if (!flag) {
bPtr->selectedItem = bPtr->items;
if (bPtr->selectedItem)
bPtr->selectedItemIndex = 0;
else
bPtr->selectedItemIndex = -1;
} else
bPtr->selectedItemIndex = -1;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
int
WMGetPopUpButtonNumberOfItems(WMPopUpButton *bPtr)
{
return bPtr->itemCount;
}
char*
WMGetPopUpButtonItem(WMPopUpButton *bPtr, int index)
{
ItemList *itemPtr = bPtr->items;
if ((index < 0) || (index >= bPtr->itemCount))
return NULL;
while (index-->0)
itemPtr = itemPtr->nextPtr;
return itemPtr->text;
}
static void
paintPopUpButton(PopUpButton *bPtr)
{
W_Screen *scr = bPtr->view->screen;
char *caption;
Pixmap pixmap;
if (bPtr->flags.pullsDown) {
caption = bPtr->caption;
} else {
if (bPtr->selectedItem == NULL) {
/* if no item selected, show the caption */
caption = bPtr->caption;
} else {
caption = bPtr->selectedItem->text;
}
}
pixmap = XCreatePixmap(scr->display, bPtr->view->window,
bPtr->view->size.width, bPtr->view->size.height,
scr->depth);
XFillRectangle(scr->display, pixmap, W_GC(scr->gray), 0, 0,
bPtr->view->size.width, bPtr->view->size.height);
W_DrawRelief(scr, pixmap, 0, 0, bPtr->view->size.width,
bPtr->view->size.height, WRRaised);
if (caption) {
W_PaintText(bPtr->view, pixmap, scr->normalFont,
6, (bPtr->view->size.height-scr->normalFont->height)/2,
bPtr->view->size.width, WALeft, W_GC(scr->black), False,
caption, strlen(caption));
}
if (bPtr->flags.pullsDown) {
XCopyArea(scr->display, scr->pullDownIndicator->pixmap,
pixmap, scr->copyGC, 0, 0, scr->pullDownIndicator->width,
scr->pullDownIndicator->height,
bPtr->view->size.width-scr->pullDownIndicator->width-4,
(bPtr->view->size.height-scr->pullDownIndicator->height)/2);
} else {
int x, y;
x = bPtr->view->size.width - scr->popUpIndicator->width - 4;
y = (bPtr->view->size.height-scr->popUpIndicator->height)/2;
XSetClipOrigin(scr->display, scr->clipGC, x, y);
XSetClipMask(scr->display, scr->clipGC, scr->popUpIndicator->mask);
XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap,
scr->clipGC, 0, 0, scr->popUpIndicator->width,
scr->popUpIndicator->height, x, y);
}
XCopyArea(scr->display, pixmap, bPtr->view->window, scr->copyGC, 0, 0,
bPtr->view->size.width, bPtr->view->size.height, 0, 0);
XFreePixmap(scr->display, pixmap);
}
static void
handleEvents(XEvent *event, void *data)
{
PopUpButton *bPtr = (PopUpButton*)data;
CHECK_CLASS(data, WC_PopUpButton);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintPopUpButton(bPtr);
break;
case DestroyNotify:
destroyPopUpButton(bPtr);
break;
}
}
static void
paintMenuEntry(PopUpButton *bPtr, int index, int highlight)
{
W_Screen *scr = bPtr->view->screen;
int i;
int yo;
ItemList *itemPtr;
int width, height, itemHeight;
itemHeight = bPtr->view->size.height;
width = bPtr->view->size.width;
height = itemHeight * bPtr->itemCount;
yo = (itemHeight - scr->normalFont->height)/2;
if (!highlight) {
XClearArea(scr->display, bPtr->menuView->window, 0, index*itemHeight,
width, itemHeight, False);
return;
} else if (index < 0 && bPtr->flags.pullsDown) {
return;
}
XFillRectangle(scr->display, bPtr->menuView->window, W_GC(scr->white),
1, index*itemHeight+1, width-3, itemHeight-3);
itemPtr = bPtr->items;
for (i = 0; i < index; i++)
itemPtr = itemPtr->nextPtr;
W_DrawRelief(scr, bPtr->menuView->window, 0, index*itemHeight,
width, itemHeight, WRRaised);
W_PaintText(bPtr->menuView, bPtr->menuView->window, scr->normalFont, 6,
index*itemHeight + yo, width, WALeft, W_GC(scr->black), False,
itemPtr->text, strlen(itemPtr->text));
if (!bPtr->flags.pullsDown && index == bPtr->selectedItemIndex) {
XCopyArea(scr->display, scr->popUpIndicator->pixmap,
bPtr->menuView->window, scr->copyGC, 0, 0,
scr->popUpIndicator->width, scr->popUpIndicator->height,
width-scr->popUpIndicator->width-4,
i*itemHeight+(itemHeight-scr->popUpIndicator->height)/2);
}
}
Pixmap
makeMenuPixmap(PopUpButton *bPtr)
{
Pixmap pixmap;
W_Screen *scr = bPtr->view->screen;
int i;
int yo;
ItemList *itemPtr;
int width, height, itemHeight;
itemHeight = bPtr->view->size.height;
width = bPtr->view->size.width;
height = itemHeight * bPtr->itemCount;
yo = (itemHeight - scr->normalFont->height)/2;
pixmap = XCreatePixmap(scr->display, bPtr->view->window, width, height,
scr->depth);
XFillRectangle(scr->display, pixmap, W_GC(scr->gray), 0, 0, width, height);
itemPtr = bPtr->items;
for (i = 0; i < bPtr->itemCount; i++) {
GC gc;
W_DrawRelief(scr, pixmap, 0, i*itemHeight, width, itemHeight,
WRRaised);
if (itemPtr->disabled)
gc = W_GC(scr->darkGray);
else
gc = W_GC(scr->black);
W_PaintText(bPtr->menuView, pixmap, scr->normalFont, 6,
i*itemHeight + yo, width, WALeft, gc, False,
itemPtr->text, strlen(itemPtr->text));
if (!bPtr->flags.pullsDown && i == bPtr->selectedItemIndex) {
XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap,
scr->copyGC, 0, 0, scr->popUpIndicator->width,
scr->popUpIndicator->height,
width-scr->popUpIndicator->width-4,
i*itemHeight+(itemHeight-scr->popUpIndicator->height)/2);
}
itemPtr = itemPtr->nextPtr;
}
return pixmap;
}
static void
resizeMenu(PopUpButton *bPtr)
{
int height;
height = bPtr->itemCount * bPtr->view->size.height;
W_ResizeView(bPtr->menuView, bPtr->view->size.width, height);
}
static void
popUpMenu(PopUpButton *bPtr)
{
W_Screen *scr = bPtr->view->screen;
Window dummyW;
int x, y;
if (!bPtr->menuView->flags.realized) {
W_RealizeView(bPtr->menuView);
resizeMenu(bPtr);
}
if (bPtr->itemCount < 1)
return;
XTranslateCoordinates(scr->display, bPtr->view->window, scr->rootWin,
0, 0, &x, &y, &dummyW);
if (bPtr->flags.pullsDown) {
y += bPtr->view->size.height;
} else {
y -= bPtr->view->size.height*bPtr->selectedItemIndex;
}
W_MoveView(bPtr->menuView, x, y);
XSetWindowBackgroundPixmap(scr->display, bPtr->menuView->window,
makeMenuPixmap(bPtr));
XClearWindow(scr->display, bPtr->menuView->window);
W_MapView(bPtr->menuView);
bPtr->highlightedItem = 0;
if (!bPtr->flags.pullsDown && bPtr->selectedItem != NULL)
paintMenuEntry(bPtr, bPtr->selectedItemIndex, True);
}
static void
popDownMenu(PopUpButton *bPtr)
{
W_UnmapView(bPtr->menuView);
/* free the background pixmap used to draw the menu contents */
XSetWindowBackgroundPixmap(bPtr->view->screen->display,
bPtr->menuView->window, None);
}
static int
itemIsEnabled(PopUpButton *bPtr, int index)
{
ItemList *item = bPtr->items;
while (index-- > 0)
item = item->nextPtr;
return !item->disabled;
}
static void
handleActionEvents(XEvent *event, void *data)
{
PopUpButton *bPtr = (PopUpButton*)data;
int oldItem;
CHECK_CLASS(data, WC_PopUpButton);
if (bPtr->itemCount < 1)
return;
switch (event->type) {
/* called for menuView */
case LeaveNotify:
bPtr->flags.insideMenu = 0;
if (bPtr->menuView->flags.mapped)
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
bPtr->highlightedItem = -1;
break;
case EnterNotify:
bPtr->flags.insideMenu = 1;
break;
case MotionNotify:
if (bPtr->flags.insideMenu) {
oldItem = bPtr->highlightedItem;
bPtr->highlightedItem = event->xmotion.y / bPtr->view->size.height;
if (oldItem!=bPtr->highlightedItem) {
paintMenuEntry(bPtr, oldItem, False);
paintMenuEntry(bPtr, bPtr->highlightedItem,
itemIsEnabled(bPtr, bPtr->highlightedItem));
}
}
break;
/* called for bPtr->view */
case ButtonPress:
popUpMenu(bPtr);
if (!bPtr->flags.pullsDown) {
bPtr->highlightedItem = bPtr->selectedItemIndex;
bPtr->flags.insideMenu = 1;
} else {
bPtr->highlightedItem = -1;
bPtr->flags.insideMenu = 0;
}
XGrabPointer(bPtr->view->screen->display, bPtr->menuView->window,
False, ButtonReleaseMask|ButtonMotionMask|EnterWindowMask
|LeaveWindowMask, GrabModeAsync, GrabModeAsync,
None, None, CurrentTime);
break;
case ButtonRelease:
XUngrabPointer(bPtr->view->screen->display, event->xbutton.time);
if (!bPtr->flags.pullsDown)
popDownMenu(bPtr);
if (bPtr->flags.insideMenu && bPtr->highlightedItem>=0) {
if (itemIsEnabled(bPtr, bPtr->highlightedItem)) {
int i;
WMSetPopUpButtonSelectedItem(bPtr, bPtr->highlightedItem);
if (bPtr->flags.pullsDown) {
for (i=0; i<MENU_BLINK_COUNT; i++) {
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
XSync(bPtr->view->screen->display, 0);
wusleep(MENU_BLINK_DELAY);
paintMenuEntry(bPtr, bPtr->highlightedItem, True);
XSync(bPtr->view->screen->display, 0);
wusleep(MENU_BLINK_DELAY);
}
}
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
popDownMenu(bPtr);
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
}
}
if (bPtr->menuView->flags.mapped)
popDownMenu(bPtr);
break;
}
}
static void
destroyPopUpButton(PopUpButton *bPtr)
{
ItemList *itemPtr, *tmp;
itemPtr = bPtr->items;
while (itemPtr!=NULL) {
free(itemPtr->text);
tmp = itemPtr->nextPtr;
free(itemPtr);
itemPtr = tmp;
}
if (bPtr->caption)
free(bPtr->caption);
/* have to destroy explicitly because the popup is a toplevel */
W_DestroyView(bPtr->menuView);
free(bPtr);
}

863
WINGs/wscroller.c Normal file
View File

@@ -0,0 +1,863 @@
#include "WINGsP.h"
/* undefine will disable the autoadjusting of the knob dimple to be
* directly below the cursor
* DOES NOT WORK */
#undef STRICT_NEXT_BEHAVIOUR
#define AUTOSCROLL_INITIAL_DELAY 200
#define AUTOSCROLL_DELAY 40
typedef struct W_Scroller {
W_Class widgetClass;
W_View *view;
void *clientData;
WMAction *action;
float knobProportion;
float floatValue;
WMHandlerID timerID; /* for continuous scrolling mode */
#ifndef STRICT_NEXT_BEHAVIOUR
int dragPoint; /* point where the knob is being
* dragged */
#endif
struct {
WMScrollArrowPosition arrowsPosition:3;
unsigned int horizontal:1;
WMScrollerPart hitPart:3;
/* */
unsigned int documentFullyVisible:1; /* document is fully visible */
unsigned int prevSelected:1;
unsigned int pushed:1;
unsigned int incrDown:1; /* whether increment button is down */
unsigned int decrDown:1;
unsigned int draggingKnob:1;
unsigned int configured:1;
unsigned int redrawPending:1;
} flags;
} Scroller;
#define DEFAULT_HEIGHT 60
#define DEFAULT_WIDTH SCROLLER_WIDTH
#define DEFAULT_ARROWS_POSITION WSAMinEnd
static void destroyScroller(Scroller *sPtr);
static void paintScroller(Scroller *sPtr);
static void resizeScroller();
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
static void handleMotion(Scroller *sPtr, int mouseX, int mouseY);
W_ViewProcedureTable _ScrollerViewProcedures = {
NULL,
resizeScroller,
NULL
};
WMScroller*
WMCreateScroller(WMWidget *parent)
{
Scroller *sPtr;
sPtr = wmalloc(sizeof(Scroller));
memset(sPtr, 0, sizeof(Scroller));
sPtr->widgetClass = WC_Scroller;
sPtr->view = W_CreateView(W_VIEW(parent));
if (!sPtr->view) {
free(sPtr);
return NULL;
}
sPtr->view->self = sPtr;
sPtr->flags.documentFullyVisible = 1;
WMCreateEventHandler(sPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, sPtr);
resizeScroller(sPtr, DEFAULT_WIDTH, DEFAULT_WIDTH);
sPtr->flags.arrowsPosition = DEFAULT_ARROWS_POSITION;
WMCreateEventHandler(sPtr->view, ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask|ButtonMotionMask,
handleActionEvents, sPtr);
sPtr->flags.hitPart = WSNoPart;
return sPtr;
}
void
WMSetScrollerArrowsPosition(WMScroller *sPtr, WMScrollArrowPosition position)
{
sPtr->flags.arrowsPosition = position;
if (sPtr->view->flags.realized) {
paintScroller(sPtr);
}
}
static void
resizeScroller(WMScroller *sPtr, unsigned int width, unsigned int height)
{
if (width > height) {
sPtr->flags.horizontal = 1;
W_ResizeView(sPtr->view, width, SCROLLER_WIDTH);
} else {
sPtr->flags.horizontal = 0;
W_ResizeView(sPtr->view, SCROLLER_WIDTH, height);
}
if (sPtr->view->flags.realized) {
paintScroller(sPtr);
}
}
void
WMSetScrollerAction(WMScroller *sPtr, WMAction *action, void *clientData)
{
CHECK_CLASS(sPtr, WC_Scroller);
sPtr->action = action;
sPtr->clientData = clientData;
}
void
WMSetScrollerParameters(WMScroller *sPtr, float floatValue,
float knobProportion)
{
CHECK_CLASS(sPtr, WC_Scroller);
if (floatValue < 0.0)
sPtr->floatValue = 0.0;
else if (floatValue > 1.0)
sPtr->floatValue = 1.0;
else
sPtr->floatValue = floatValue;
if (knobProportion <= 0.0) {
sPtr->knobProportion = 0.0;
sPtr->flags.documentFullyVisible = 0;
} else if (knobProportion >= 1.0) {
sPtr->knobProportion = 1.0;
sPtr->flags.documentFullyVisible = 1;
} else {
sPtr->knobProportion = knobProportion;
sPtr->flags.documentFullyVisible = 0;
}
if (sPtr->view->flags.realized)
paintScroller(sPtr);
}
float
WMGetScrollerKnobProportion(WMScroller *sPtr)
{
CHECK_CLASS(sPtr, WC_Scroller);
return sPtr->knobProportion;
}
float
WMGetScrollerValue(WMScroller *sPtr)
{
CHECK_CLASS(sPtr, WC_Scroller);
return sPtr->floatValue;
}
WMScrollerPart
WMGetScrollerHitPart(WMScroller *sPtr)
{
CHECK_CLASS(sPtr, WC_Scroller);
return sPtr->flags.hitPart;
}
static void
paintArrow(WMScroller *sPtr, Drawable d, int part)
/*
* part- 0 paints the decrement arrow, 1 the increment arrow
*/
{
WMView *view = sPtr->view;
WMScreen *scr = view->screen;
int ofs, bsize;
W_Pixmap *arrow;
#ifndef DOUBLE_BUFFER
GC gc = scr->lightGC;
#endif
bsize = SCROLLER_WIDTH - 4;
if (part == 0) { /* decrement button */
if (sPtr->flags.horizontal) {
if (sPtr->flags.arrowsPosition == WSAMaxEnd) {
ofs = view->size.width - 2*(bsize+1) - 1;
} else {
ofs = 2;
}
if (sPtr->flags.decrDown)
arrow = scr->hiLeftArrow;
else
arrow = scr->leftArrow;
} else {
if (sPtr->flags.arrowsPosition == WSAMaxEnd) {
ofs = view->size.height - 2*(bsize+1) - 1;
} else {
ofs = 2;
}
if (sPtr->flags.decrDown)
arrow = scr->hiUpArrow;
else
arrow = scr->upArrow;
}
#ifndef DOUBLE_BUFFER
if (sPtr->flags.decrDown)
gc = W_GC(scr->white);
#endif
} else { /* increment button */
if (sPtr->flags.horizontal) {
if (sPtr->flags.arrowsPosition == WSAMaxEnd) {
ofs = view->size.width - bsize+1 - 3;
} else {
ofs = 2 + bsize+1;
}
if (sPtr->flags.incrDown)
arrow = scr->hiRightArrow;
else
arrow = scr->rightArrow;
} else {
if (sPtr->flags.arrowsPosition == WSAMaxEnd) {
ofs = view->size.height - bsize+1 - 3;
} else {
ofs = 2 + bsize+1;
}
if (sPtr->flags.incrDown)
arrow = scr->hiDownArrow;
else
arrow = scr->downArrow;
}
#ifndef DOUBLE_BUFFER
if (sPtr->flags.incrDown)
gc = scr->whiteGC;
#endif
}
if (sPtr->flags.horizontal) {
/* paint button */
#ifndef DOUBLE_BUFFER
XFillRectangle(scr->display, d, gc,
ofs+1, 2+1, bsize+1-3, bsize-3);
#else
if ((!part&&sPtr->flags.decrDown) || (part&&sPtr->flags.incrDown))
XFillRectangle(scr->display, d, W_GC(scr->white),
ofs+1, 2+1, bsize+1-3, bsize-3);
#endif /* DOUBLE_BUFFER */
W_DrawRelief(scr, d, ofs, 2, bsize, bsize, WRRaised);
/* paint arrow */
XSetClipMask(scr->display, scr->clipGC, arrow->mask);
XSetClipOrigin(scr->display, scr->clipGC,
ofs + (bsize - arrow->width) / 2,
2 + (bsize - arrow->height) / 2);
XCopyArea(scr->display, arrow->pixmap, d, scr->clipGC,
0, 0, arrow->width, arrow->height,
ofs + (bsize - arrow->width) / 2,
2 + (bsize - arrow->height) / 2);
} else { /* vertical */
/* paint button */
#ifndef DOUBLE_BUFFER
XFillRectangle(scr->display, d, gc,
2+1, ofs+1, bsize-3, bsize+1-3);
#else
if ((!part&&sPtr->flags.decrDown) || (part&&sPtr->flags.incrDown))
XFillRectangle(scr->display, d, W_GC(scr->white),
2+1, ofs+1, bsize-3, bsize+1-3);
#endif /* DOUBLE_BUFFER */
W_DrawRelief(scr, d, 2, ofs, bsize, bsize, WRRaised);
/* paint arrow */
XSetClipMask(scr->display, scr->clipGC, arrow->mask);
XSetClipOrigin(scr->display, scr->clipGC,
2 + (bsize - arrow->width) / 2,
ofs + (bsize - arrow->height) / 2);
XCopyArea(scr->display, arrow->pixmap, d, scr->clipGC,
0, 0, arrow->width, arrow->height,
2 + (bsize - arrow->width) / 2,
ofs + (bsize - arrow->height) / 2);
}
}
static int
knobLength(Scroller *sPtr)
{
int tmp, length;
if (sPtr->flags.horizontal)
length = sPtr->view->size.width - 4;
else
length = sPtr->view->size.height - 4;
if (sPtr->flags.arrowsPosition == WSAMaxEnd) {
length -= (SCROLLER_WIDTH - 4 + 1)*2;
} else if (sPtr->flags.arrowsPosition == WSAMinEnd) {
length -= (SCROLLER_WIDTH - 4 + 1)*2;
}
tmp = (int)((float)length * sPtr->knobProportion + 0.5);
/* keep minimum size */
if (tmp < SCROLLER_WIDTH-4)
tmp = SCROLLER_WIDTH-4;
return tmp;
}
static void
paintScroller(Scroller *sPtr)
{
WMView *view = sPtr->view;
WMScreen *scr = view->screen;
#ifdef DOUBLE_BUFFER
Pixmap d;
#else
Drawable d = view->window;
#endif
int length, ofs;
float knobP, knobL;
#ifdef DOUBLE_BUFFER
d = XCreatePixmap(scr->display, view->window, view->size.width,
view->size.height, scr->depth);
XFillRectangle(scr->display, d, W_GC(scr->gray), 0, 0,
view->size.width, view->size.height);
#endif
XDrawRectangle(scr->display, d, W_GC(scr->black), 0, 0,
view->size.width-1, view->size.height-1);
#ifndef DOUBLE_BUFFER
XDrawRectangle(scr->display, d, W_GC(scr->gray), 1, 1,
view->size.width-3, view->size.height-3);
#endif
if (sPtr->flags.horizontal)
length = view->size.width - 4;
else
length = view->size.height - 4;
if (sPtr->flags.documentFullyVisible) {
XFillRectangle(scr->display, d, scr->stippleGC, 2, 2,
view->size.width-4, view->size.height-4);
} else {
if (sPtr->flags.arrowsPosition==WSAMaxEnd) {
ofs = 0;
length -= (SCROLLER_WIDTH - 4 + 1)*2;
} else if (sPtr->flags.arrowsPosition==WSAMinEnd) {
ofs = (SCROLLER_WIDTH - 4 + 1)*2;
length -= (SCROLLER_WIDTH - 4 + 1)*2;
} else {
ofs = 0;
}
knobL = (float)knobLength(sPtr);
knobP = sPtr->floatValue * ((float)length - knobL);
if (sPtr->flags.horizontal) {
/* before */
XFillRectangle(scr->display, d, scr->stippleGC,
ofs+2, 2, (int)knobP, view->size.height-4);
/* knob */
#ifndef DOUBLE_BUFFER
XFillRectangle(scr->display, d, scr->lightGC,
ofs+2+(int)knobP+2, 2+2, (int)knobL-4,
view->size.height-4-4);
#endif
W_DrawRelief(scr, d, ofs+2+(int)knobP, 2, (int)knobL,
view->size.height-4, WRRaised);
XCopyArea(scr->display, scr->scrollerDimple->pixmap, d,
scr->copyGC, 0, 0,
scr->scrollerDimple->width, scr->scrollerDimple->height,
ofs+2+(int)knobP+((int)knobL-scr->scrollerDimple->width-1)/2,
(view->size.height-scr->scrollerDimple->height-1)/2);
/* after */
if ((int)(knobP+knobL) < length)
XFillRectangle(scr->display, d, scr->stippleGC,
ofs+2+(int)(knobP+knobL), 2,
length-(int)(knobP+knobL),
view->size.height-4);
} else {
/* before */
if (knobP>0.0)
XFillRectangle(scr->display, d, scr->stippleGC,
2, ofs+2, view->size.width-4, (int)knobP);
/* knob */
#ifndef DOUBLE_BUFFER
XFillRectangle(scr->display, d, scr->lightGC,
2+2, ofs+2+(int)knobP+2,
view->size.width-4-4, (int)knobL-4);
#endif
XCopyArea(scr->display, scr->scrollerDimple->pixmap, d,
scr->copyGC, 0, 0,
scr->scrollerDimple->width, scr->scrollerDimple->height,
(view->size.width-scr->scrollerDimple->width-1)/2,
ofs+2+(int)knobP+((int)knobL-scr->scrollerDimple->height-1)/2);
W_DrawRelief(scr, d, 2, ofs+2+(int)knobP,
view->size.width-4, (int)knobL, WRRaised);
/* after */
if ((int)(knobP+knobL) < length)
XFillRectangle(scr->display, d, scr->stippleGC,
2, ofs+2+(int)(knobP+knobL),
view->size.width-4,
length-(int)(knobP+knobL));
}
if (sPtr->flags.arrowsPosition != WSANone) {
paintArrow(sPtr, d, 0);
paintArrow(sPtr, d, 1);
}
}
#ifdef DOUBLE_BUFFER
XCopyArea(scr->display, d, view->window, scr->copyGC, 0, 0,
view->size.width, view->size.height, 0, 0);
XFreePixmap(scr->display, d);
#endif
}
static void
handleEvents(XEvent *event, void *data)
{
Scroller *sPtr = (Scroller*)data;
CHECK_CLASS(data, WC_Scroller);
switch (event->type) {
case Expose:
if (event->xexpose.count==0)
paintScroller(sPtr);
break;
case DestroyNotify:
destroyScroller(sPtr);
break;
}
}
/*
* locatePointInScroller-
* Return the part of the scroller where the point is located.
*/
static WMScrollerPart
locatePointInScroller(Scroller *sPtr, int x, int y, int alternate)
{
int width = sPtr->view->size.width;
int height = sPtr->view->size.height;
int c, p1, p2, p3, p4, p5, p6;
int knobL, slotL;
/* if there is no knob... */
if (sPtr->flags.documentFullyVisible)
return WSKnobSlot;
if (sPtr->flags.horizontal)
c = x;
else
c = y;
/* p1 p2 p3 p4 p5 p6
* | | |###########| |#####| | |
* | < | > |###########| O |#####| < | > |
* | | |###########| |#####| | |
*/
if (sPtr->flags.arrowsPosition == WSAMinEnd) {
p1 = 18;
p2 = 36;
if (sPtr->flags.horizontal) {
slotL = width - 36;
p5 = width;
} else {
slotL = height - 36;
p5 = height;
}
p6 = p5;
} else if (sPtr->flags.arrowsPosition == WSAMaxEnd) {
if (sPtr->flags.horizontal) {
slotL = width - 36;
p6 = width - 18;
} else {
slotL = height - 36;
p6 = height - 18;
}
p5 = p6 - 18;
p1 = p2 = 0;
} else {
/* no arrows */
p1 = p2 = 0;
if (sPtr->flags.horizontal) {
slotL = p5 = p6 = width;
} else {
slotL = p5 = p6 = height;
}
}
knobL = knobLength(sPtr);
p3 = p2 + (int)((float)(slotL-knobL) * sPtr->floatValue);
p4 = p3 + knobL;
/* uses a mix of the NS and Win ways of doing scroll page */
if (c <= p1)
return alternate ? WSDecrementPage : WSDecrementLine;
else if (c <= p2)
return alternate ? WSIncrementPage : WSIncrementLine;
else if (c <= p3)
return WSDecrementPage;
else if (c <= p4)
return WSKnob;
else if (c <= p5)
return WSIncrementPage;
else if (c <= p6)
return alternate ? WSDecrementPage : WSDecrementLine;
else
return alternate ? WSIncrementPage : WSIncrementLine;
}
static void
handlePush(Scroller *sPtr, int pushX, int pushY, int alternate)
{
WMScrollerPart part;
int doAction = 0;
part = locatePointInScroller(sPtr, pushX, pushY, alternate);
sPtr->flags.hitPart = part;
switch (part) {
case WSIncrementLine:
sPtr->flags.incrDown = 1;
doAction = 1;
break;
case WSIncrementPage:
doAction = 1;
break;
case WSDecrementLine:
sPtr->flags.decrDown = 1;
doAction = 1;
break;
case WSDecrementPage:
doAction = 1;
break;
case WSKnob:
sPtr->flags.draggingKnob = 1;
#ifndef STRICT_NEXT_BEHAVIOUR
if (sPtr->flags.horizontal)
sPtr->dragPoint = pushX;
else
sPtr->dragPoint = pushY;
{
int noButtons = (sPtr->flags.arrowsPosition == WSANone);
int length, knobP;
if (sPtr->flags.horizontal)
length = sPtr->view->size.width - 4;
else
length = sPtr->view->size.height - 4;
if (!noButtons)
length -= 36;
knobP = (int)(sPtr->floatValue * (float)(length-knobLength(sPtr)));
if (sPtr->flags.arrowsPosition == WSAMinEnd)
sPtr->dragPoint -= 2 + (noButtons ? 0 : 36) + knobP;
else
sPtr->dragPoint -= 2 + knobP;
}
#endif /* STRICT_NEXT_BEHAVIOUR */
handleMotion(sPtr, pushX, pushY);
break;
case WSKnobSlot:
case WSNoPart:
/* dummy */
break;
}
if (doAction && sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
}
static float
floatValueForPoint(int slotOfs, int slotLength, int knobLength, int point)
{
float floatValue = 0;
float position;
#ifdef STRICT_NEXT_BEHAVIOUR
if (point < slotOfs + knobLength/2)
position = (float)(slotOfs + knobLength/2);
else if (point > slotOfs + slotLength - knobLength/2)
position = (float)(slotOfs + slotLength - knobLength/2);
else
position = (float)point;
floatValue = (position-(float)(slotOfs+slotLength/2))
/(float)(slotLength-knobLength);
#else
/* Adjust the last point to lie inside the knob slot */
if (point < slotOfs)
position = (float)slotOfs;
else if (point > slotOfs + slotLength)
position = (float)(slotOfs + slotLength);
else
position = (float)point;
/* Compute the float value */
floatValue = (position-(float)slotOfs) / (float)(slotLength-knobLength);
#endif
return floatValue;
}
static void
handleMotion(Scroller *sPtr, int mouseX, int mouseY)
{
int slotOffset;
int slotLength;
int noButtons = (sPtr->flags.arrowsPosition == WSANone);
if (sPtr->flags.arrowsPosition == WSAMinEnd)
slotOffset = 2 + (noButtons ? 0 : 36);
else
slotOffset = 2;
if (sPtr->flags.draggingKnob) {
float newFloatValue;
#ifdef STRICT_NEXT_BEHAVIOUR
if (sPtr->flags.horizontal) {
slotLength = sPtr->view->size.width-4-(noButtons ? 0 : 36);
newFloatValue = floatValueForPoint(slotOffset, slotLength,
(int)(slotLength*sPtr->knobProportion),
mouseX);
} else {
slotLength = sPtr->view->size.height-4-(noButtons ? 0 : 36);
newFloatValue = floatValueForPoint(slotOffset, slotLength,
(int)(slotLength*sPtr->knobProportion),
mouseY);
}
#else
if (sPtr->flags.horizontal) {
slotLength = sPtr->view->size.width-4-(noButtons ? 0 : 36);
newFloatValue = floatValueForPoint(slotOffset, slotLength,
(int)(slotLength*sPtr->knobProportion),
mouseX-sPtr->dragPoint);
} else {
slotLength = sPtr->view->size.height-4-(noButtons ? 0 : 36);
newFloatValue = floatValueForPoint(slotOffset, slotLength,
(int)(slotLength*sPtr->knobProportion),
mouseY-sPtr->dragPoint);
}
#endif /* !STRICT_NEXT_BEHAVIOUR */
WMSetScrollerParameters(sPtr, newFloatValue, sPtr->knobProportion);
if (sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
} else {
int part;
part = locatePointInScroller(sPtr, mouseX, mouseY, False);
sPtr->flags.hitPart = part;
if (part == WSIncrementLine && sPtr->flags.decrDown) {
sPtr->flags.decrDown = 0;
sPtr->flags.incrDown = 1;
} else if (part == WSDecrementLine && sPtr->flags.incrDown) {
sPtr->flags.incrDown = 0;
sPtr->flags.decrDown = 1;
} else if (part != WSIncrementLine && part != WSDecrementLine) {
sPtr->flags.incrDown = 0;
sPtr->flags.decrDown = 0;
}
}
}
static void
autoScroll(void *clientData)
{
Scroller *sPtr = (Scroller*)clientData;
if (sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
sPtr->timerID= WMAddTimerHandler(AUTOSCROLL_DELAY, autoScroll, clientData);
}
static void
handleActionEvents(XEvent *event, void *data)
{
Scroller *sPtr = (Scroller*)data;
int id, dd;
/* check if we're really dealing with a scroller, as something
* might have gone wrong in the event dispatching stuff */
CHECK_CLASS(sPtr, WC_Scroller);
id = sPtr->flags.incrDown;
dd = sPtr->flags.decrDown;
switch (event->type) {
case EnterNotify:
break;
case LeaveNotify:
if (sPtr->timerID) {
WMDeleteTimerHandler(sPtr->timerID);
sPtr->timerID = NULL;
}
sPtr->flags.incrDown = 0;
sPtr->flags.decrDown = 0;
break;
case ButtonPress:
/* FIXME: change Mod1Mask with something else */
handlePush(sPtr, event->xbutton.x, event->xbutton.y,
(event->xbutton.state & Mod1Mask)
||event->xbutton.button==Button2);
/* continue scrolling if pushed on the buttons */
if (sPtr->flags.hitPart == WSIncrementLine
|| sPtr->flags.hitPart == WSDecrementLine) {
sPtr->timerID = WMAddTimerHandler(AUTOSCROLL_INITIAL_DELAY,
autoScroll, sPtr);
}
break;
case ButtonRelease:
if (sPtr->flags.draggingKnob) {
if (sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
}
if (sPtr->timerID) {
WMDeleteTimerHandler(sPtr->timerID);
sPtr->timerID = NULL;
}
sPtr->flags.incrDown = 0;
sPtr->flags.decrDown = 0;
sPtr->flags.draggingKnob = 0;
break;
case MotionNotify:
handleMotion(sPtr, event->xbutton.x, event->xbutton.y);
if (sPtr->timerID && sPtr->flags.hitPart != WSIncrementLine
&& sPtr->flags.hitPart != WSDecrementLine) {
WMDeleteTimerHandler(sPtr->timerID);
sPtr->timerID = NULL;
}
break;
}
if (id != sPtr->flags.incrDown || dd != sPtr->flags.decrDown)
paintScroller(sPtr);
}
static void
destroyScroller(Scroller *sPtr)
{
/* we don't want autoscroll try to scroll a freed widget */
if (sPtr->timerID) {
WMDeleteTimerHandler(sPtr->timerID);
}
free(sPtr);
}

501
WINGs/wscrollview.c Normal file
View File

@@ -0,0 +1,501 @@
#include "WINGsP.h"
typedef struct W_ScrollView {
W_Class widgetClass;
WMView *view;
WMView *contentView;
WMView *viewport;
WMScroller *vScroller;
WMScroller *hScroller;
short lineScroll;
short pageScroll;
struct {
WMReliefType relief:3;
unsigned int hasVScroller:1;
unsigned int hasHScroller:1;
} flags;
} ScrollView;
static void destroyScrollView(ScrollView *sPtr);
static void paintScrollView(ScrollView *sPtr);
static void handleEvents(XEvent *event, void *data);
static void handleViewportEvents(XEvent *event, void *data);
static void resizeScrollView();
W_ViewProcedureTable _ScrollViewViewProcedures = {
NULL,
resizeScrollView,
NULL
};
WMScrollView*
WMCreateScrollView(WMWidget *parent)
{
ScrollView *sPtr;
sPtr = wmalloc(sizeof(ScrollView));
memset(sPtr, 0, sizeof(ScrollView));
sPtr->widgetClass = WC_ScrollView;
sPtr->view = W_CreateView(W_VIEW(parent));
if (!sPtr->view) {
free(sPtr);
return NULL;
}
sPtr->viewport = W_CreateView(sPtr->view);
if (!sPtr->view) {
W_DestroyView(sPtr->view);
free(sPtr);
return NULL;
}
sPtr->viewport->flags.mapWhenRealized = 1;
WMCreateEventHandler(sPtr->view, StructureNotifyMask|ExposureMask,
handleEvents, sPtr);
WMCreateEventHandler(sPtr->viewport, SubstructureNotifyMask,
handleViewportEvents, sPtr);
sPtr->lineScroll = 4;
sPtr->pageScroll = 0;
return sPtr;
}
static void
reorganizeInterior(WMScrollView *sPtr)
{
int hx, hy, hw;
int vx, vy, vh;
int cx, cy, cw, ch;
cw = hw = sPtr->view->size.width;
vh = ch = sPtr->view->size.height;
if (sPtr->flags.relief == WRSimple) {
cw -= 2;
ch -= 2;
cx = 1;
cy = 1;
} else if (sPtr->flags.relief != WRFlat) {
cw -= 3;
ch -= 3;
cx = 2;
cy = 2;
} else {
cx = 0;
cy = 0;
}
if (sPtr->flags.hasHScroller) {
int h = W_VIEW(sPtr->hScroller)->size.height;
ch -= h;
if (sPtr->flags.relief == WRSimple) {
hx = 0;
hy = sPtr->view->size.height - h;
} else if (sPtr->flags.relief != WRFlat) {
hx = 1;
hy = sPtr->view->size.height - h - 1;
hw -= 2;
} else {
hx = 0;
hy = sPtr->view->size.height - h;
}
} else {
/* make compiler shutup */
hx = 0;
hy = 0;
}
if (sPtr->flags.hasVScroller) {
int w = W_VIEW(sPtr->vScroller)->size.width;
cw -= w;
cx += w;
hx += w - 1;
hw -= w - 1;
if (sPtr->flags.relief == WRSimple) {
vx = 0;
vy = 0;
} else if (sPtr->flags.relief != WRFlat) {
vx = 1;
vy = 1;
vh -= 2;
} else {
vx = 0;
vy = 0;
}
} else {
/* make compiler shutup */
vx = 0;
vy = 0;
}
W_ResizeView(sPtr->viewport, cw, ch);
W_MoveView(sPtr->viewport, cx, cy);
if (sPtr->flags.hasHScroller) {
WMResizeWidget(sPtr->hScroller, hw, 20);
WMMoveWidget(sPtr->hScroller, hx, hy);
}
if (sPtr->flags.hasVScroller) {
WMResizeWidget(sPtr->vScroller, 20, vh);
WMMoveWidget(sPtr->vScroller, vx, vy);
}
}
static void
resizeScrollView(WMScrollView *sPtr, unsigned int width, unsigned int height)
{
W_ResizeView(sPtr->view, width, height);
reorganizeInterior(sPtr);
}
void
WMResizeScrollViewContent(WMScrollView *sPtr, unsigned int width,
unsigned int height)
{
int w, h, x;
w = width;
h = height;
x = 0;
if (sPtr->flags.relief == WRSimple) {
w += 2;
h += 2;
} else if (sPtr->flags.relief != WRFlat) {
w += 4;
h += 4;
x = 1;
}
if (sPtr->flags.hasVScroller) {
w -= W_VIEW(sPtr->hScroller)->size.width;
WMResizeWidget(sPtr->vScroller, 20, h);
}
if (sPtr->flags.hasHScroller) {
h -= W_VIEW(sPtr->hScroller)->size.height;
WMResizeWidget(sPtr->hScroller, w, 20);
WMMoveWidget(sPtr->hScroller, x, h);
}
W_ResizeView(sPtr->view, w, h);
W_ResizeView(sPtr->viewport, width, height);
}
void
WMSetScrollViewLineScroll(WMScrollView *sPtr, int amount)
{
assert(amount > 0);
sPtr->lineScroll = amount;
}
void
WMSetScrollViewPageScroll(WMScrollView *sPtr, int amount)
{
assert(amount >= 0);
sPtr->pageScroll = amount;
}
static void
doScrolling(WMWidget *self, void *data)
{
ScrollView *sPtr = (ScrollView*)data;
float value;
int pos;
int vpsize;
float size;
if (sPtr->hScroller == self) {
pos = -sPtr->contentView->pos.x;
size = sPtr->contentView->size.width-sPtr->viewport->size.width;
vpsize = sPtr->viewport->size.width - sPtr->pageScroll;
} else {
pos = -sPtr->contentView->pos.y;
size = sPtr->contentView->size.height-sPtr->viewport->size.height;
vpsize = sPtr->viewport->size.height - sPtr->pageScroll;
}
if (vpsize <= 0)
vpsize = 1;
switch (WMGetScrollerHitPart(self)) {
case WSDecrementLine:
if (pos > 0) {
pos-=sPtr->lineScroll;
if (pos < 0)
pos = 0;
value = (float)pos / size;
WMSetScrollerParameters(self, value,
WMGetScrollerKnobProportion(self));
}
break;
case WSIncrementLine:
if (pos < size) {
pos+=sPtr->lineScroll;
if (pos > size)
pos = size;
value = (float)pos / size;
WMSetScrollerParameters(self, value,
WMGetScrollerKnobProportion(self));
}
break;
case WSKnob:
value = WMGetScrollerValue(self);
pos = value*size;
break;
case WSDecrementPage:
if (pos > 0) {
pos -= vpsize;
if (pos < 0)
pos = 0;
value = (float)pos / size;
WMSetScrollerParameters(self, value,
WMGetScrollerKnobProportion(self));
}
break;
case WSIncrementPage:
if (pos < size) {
pos += vpsize;
if (pos > size)
pos = size;
value = (float)pos / size;
WMSetScrollerParameters(self, value,
WMGetScrollerKnobProportion(self));
}
break;
case WSNoPart:
case WSKnobSlot:
break;
}
if (sPtr->hScroller == self) {
W_MoveView(sPtr->contentView, -pos, sPtr->contentView->pos.y);
} else {
W_MoveView(sPtr->contentView, sPtr->contentView->pos.x, -pos);
}
}
WMScroller*
WMGetScrollViewHorizontalScroller(WMScrollView *sPtr)
{
return sPtr->hScroller;
}
WMScroller*
WMGetScrollViewVerticalScroller(WMScrollView *sPtr)
{
return sPtr->vScroller;
}
void
WMSetScrollViewHasHorizontalScroller(WMScrollView *sPtr, Bool flag)
{
if (flag) {
if (sPtr->flags.hasHScroller)
return;
sPtr->flags.hasHScroller = 1;
sPtr->hScroller = WMCreateScroller(sPtr);
WMSetScrollerAction(sPtr->hScroller, doScrolling, sPtr);
/* make it a horiz. scroller */
WMResizeWidget(sPtr->hScroller, 2, 1);
reorganizeInterior(sPtr);
WMMapWidget(sPtr->hScroller);
} else {
if (!sPtr->flags.hasHScroller)
return;
WMUnmapWidget(sPtr->hScroller);
WMDestroyWidget(sPtr->hScroller);
sPtr->hScroller = NULL;
sPtr->flags.hasHScroller = 0;
reorganizeInterior(sPtr);
}
}
void
WMSetScrollViewHasVerticalScroller(WMScrollView *sPtr, Bool flag)
{
if (flag) {
if (sPtr->flags.hasVScroller)
return;
sPtr->flags.hasVScroller = 1;
sPtr->vScroller = WMCreateScroller(sPtr);
WMSetScrollerAction(sPtr->vScroller, doScrolling, sPtr);
WMSetScrollerArrowsPosition(sPtr->vScroller, WSAMaxEnd);
/* make it a vert. scroller */
WMResizeWidget(sPtr->vScroller, 1, 2);
reorganizeInterior(sPtr);
WMMapWidget(sPtr->vScroller);
} else {
if (!sPtr->flags.hasVScroller)
return;
sPtr->flags.hasVScroller = 0;
WMUnmapWidget(sPtr->vScroller);
WMDestroyWidget(sPtr->vScroller);
sPtr->vScroller = NULL;
reorganizeInterior(sPtr);
}
}
void
WMSetScrollViewContentView(WMScrollView *sPtr, WMView *view)
{
assert(sPtr->contentView == NULL);
sPtr->contentView = view;
W_ReparentView(sPtr->contentView, sPtr->viewport);
if (sPtr->flags.hasHScroller) {
float prop;
prop = (float)sPtr->viewport->size.width/sPtr->contentView->size.width;
WMSetScrollerParameters(sPtr->hScroller, 0, prop);
}
if (sPtr->flags.hasVScroller) {
float prop;
prop = (float)sPtr->viewport->size.height/sPtr->contentView->size.height;
WMSetScrollerParameters(sPtr->vScroller, 0, prop);
}
}
void
WMSetScrollViewRelief(WMScrollView *sPtr, WMReliefType type)
{
sPtr->flags.relief = type;
if (sPtr->view->flags.mapped)
paintScrollView(sPtr);
}
static void
paintScrollView(ScrollView *sPtr)
{
W_DrawRelief(sPtr->view->screen, sPtr->view->window, 0, 0,
sPtr->view->size.width, sPtr->view->size.height,
sPtr->flags.relief);
}
static void
updateScrollerProportion(ScrollView *sPtr)
{
float prop, value;
if (sPtr->flags.hasHScroller) {
prop = (float)sPtr->viewport->size.width/sPtr->contentView->size.width;
value = WMGetScrollerValue(sPtr->hScroller);
WMSetScrollerParameters(sPtr->hScroller, value, prop);
}
if (sPtr->flags.hasVScroller) {
prop = (float)sPtr->viewport->size.height/sPtr->contentView->size.height;
value = WMGetScrollerValue(sPtr->vScroller);
WMSetScrollerParameters(sPtr->vScroller, value, prop);
}
}
static void
handleViewportEvents(XEvent *event, void *data)
{
ScrollView *sPtr = (ScrollView*)data;
if (sPtr->contentView
&& event->xconfigure.window == sPtr->contentView->window)
updateScrollerProportion(sPtr);
}
static void
handleEvents(XEvent *event, void *data)
{
ScrollView *sPtr = (ScrollView*)data;
CHECK_CLASS(data, WC_ScrollView);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintScrollView(sPtr);
break;
case DestroyNotify:
destroyScrollView(sPtr);
break;
}
}
static void
destroyScrollView(ScrollView *sPtr)
{
free(sPtr);
}

482
WINGs/wslider.c Normal file
View File

@@ -0,0 +1,482 @@
#include "WINGsP.h"
#undef STRICT_NEXT_BEHAVIOUR
typedef struct W_Slider {
W_Class widgetClass;
WMView *view;
int minValue;
int maxValue;
int value;
Pixmap knobPixmap;
WMAction *action;
void *clientData;
struct {
unsigned int continuous:1;
unsigned int vertical:1;
unsigned int dragging:1;
} flags;
} Slider;
#define SLIDER_LENGTH 20
static void resizeSlider();
W_ViewProcedureTable _SliderViewProcedures = {
NULL,
resizeSlider,
NULL
};
static void destroySlider(Slider *sPtr);
static void paintSlider(Slider *sPtr);
static void realizeSlider(Slider *sPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
static void
realizeObserver(void *self, WMNotification *not)
{
realizeSlider(self);
}
WMSlider*
WMCreateSlider(WMWidget *parent)
{
Slider *sPtr;
sPtr = wmalloc(sizeof(Slider));
memset(sPtr, 0, sizeof(Slider));
sPtr->widgetClass = WC_Slider;
sPtr->view = W_CreateView(W_VIEW(parent));
if (!sPtr->view) {
free(sPtr);
return NULL;
}
sPtr->view->self = sPtr;
WMCreateEventHandler(sPtr->view, ExposureMask|StructureNotifyMask,
handleEvents, sPtr);
WMCreateEventHandler(sPtr->view, ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask|ButtonMotionMask,
handleActionEvents, sPtr);
W_ResizeView(sPtr->view, 100, 16);
sPtr->flags.vertical = 0;
sPtr->minValue = 0;
sPtr->maxValue = 100;
sPtr->value = 50;
sPtr->flags.continuous = 1;
WMAddNotificationObserver(realizeObserver, sPtr,
WMViewRealizedNotification, sPtr->view);
return sPtr;
}
int
WMGetSliderMinValue(WMSlider *slider)
{
CHECK_CLASS(slider, WC_Slider);
return slider->minValue;
}
int
WMGetSliderMaxValue(WMSlider *slider)
{
CHECK_CLASS(slider, WC_Slider);
return slider->maxValue;
}
int
WMGetSliderValue(WMSlider *slider)
{
CHECK_CLASS(slider, WC_Slider);
return slider->value;
}
void
WMSetSliderMinValue(WMSlider *slider, int value)
{
CHECK_CLASS(slider, WC_Slider);
slider->minValue = value;
if (slider->value < value) {
slider->value = value;
if (slider->view->flags.mapped)
paintSlider(slider);
}
}
void
WMSetSliderMaxValue(WMSlider *slider, int value)
{
CHECK_CLASS(slider, WC_Slider);
slider->maxValue = value;
if (slider->value > value) {
slider->value = value;
if (slider->view->flags.mapped)
paintSlider(slider);
}
}
void
WMSetSliderValue(WMSlider *slider, int value)
{
CHECK_CLASS(slider, WC_Slider);
if (value < slider->minValue)
slider->value = slider->minValue;
else if (value > slider->maxValue)
slider->value = slider->maxValue;
else
slider->value = value;
if (slider->view->flags.mapped)
paintSlider(slider);
}
void
WMSetSliderContinuous(WMSlider *slider, Bool flag)
{
CHECK_CLASS(slider, WC_Slider);
slider->flags.continuous = flag;
}
void
WMSetSliderAction(WMSlider *slider, WMAction *action, void *data)
{
CHECK_CLASS(slider, WC_Slider);
slider->action = action;
slider->clientData = data;
}
static void
makeKnobPixmap(Slider *sPtr)
{
Pixmap pix;
WMScreen *scr = sPtr->view->screen;
int w, h;
if (sPtr->flags.vertical) {
w = sPtr->view->size.width-2;
h = SLIDER_LENGTH;
} else {
w = SLIDER_LENGTH;
h = sPtr->view->size.height-2;
}
pix = XCreatePixmap(scr->display, sPtr->view->window, w, h, scr->depth);
XFillRectangle(scr->display, pix, W_GC(scr->gray), 0, 0, w, h);
if (sPtr->flags.vertical) {
XDrawLine(scr->display, pix, W_GC(scr->white), 0, 0, 0, h-3);
XDrawLine(scr->display, pix, W_GC(scr->white), 1, 0, 1, h-3);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), w-2, 1, w-2, h/2-2);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), w-2, h/2, w-2, h-2);
XDrawLine(scr->display, pix, W_GC(scr->white), 0, 0, w-2, 0);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), 1, h/2-2, w-3, h/2-2);
XDrawLine(scr->display, pix, W_GC(scr->white), 0, h/2-1, w-3, h/2-1);
XDrawLine(scr->display, pix, W_GC(scr->black), w-1, 0, w-1, h-2);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), 0, h-3, w-2, h-3);
XDrawLine(scr->display, pix, W_GC(scr->black), 0, h-2, w-1, h-2);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), 0, h-1, w-1,h-1);
} else {
XDrawLine(scr->display, pix, W_GC(scr->white), 0, 0, w-3, 0);
XDrawLine(scr->display, pix, W_GC(scr->white), 0, 0, 0, h-2);
XDrawLine(scr->display, pix, W_GC(scr->white), 1, 0, 1, h-3);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), w/2-2, 1, w/2-2, h-3);
XDrawLine(scr->display, pix, W_GC(scr->white), w/2-1, 0, w/2-1, h-3);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), w-3, 0, w-3, h-2);
XDrawLine(scr->display, pix, W_GC(scr->black), w-2, 0, w-2, h-2);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), w-1, 0, w-1, h-1);
XDrawLine(scr->display, pix, W_GC(scr->black), 1, h-1, w/2+1, h-1);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), 1, h-2, w/2-2, h-2);
XDrawLine(scr->display, pix, W_GC(scr->darkGray), w/2, h-2, w-3,h-2);
XDrawLine(scr->display, pix, W_GC(scr->black), 0, h-1, w-2, h-1);
}
if (sPtr->knobPixmap)
XFreePixmap(scr->display, sPtr->knobPixmap);
sPtr->knobPixmap = pix;
}
static void
realizeSlider(Slider *sPtr)
{
W_RealizeView(sPtr->view);
makeKnobPixmap(sPtr);
}
static void
resizeSlider(Slider *sPtr, unsigned int width, unsigned int height)
{
assert(width > 0);
assert(height > 0);
W_ResizeView(sPtr->view, width, height);
if (width > height) {
if (sPtr->flags.vertical) {
sPtr->flags.vertical = 0;
if (sPtr->view->flags.realized)
makeKnobPixmap(sPtr);
}
} else {
if (!sPtr->flags.vertical) {
sPtr->flags.vertical = 1;
if (sPtr->view->flags.realized)
makeKnobPixmap(sPtr);
}
}
}
static void
paintSlider(Slider *sPtr)
{
W_Screen *scr = sPtr->view->screen;
GC bgc;
GC wgc;
GC lgc;
WMSize size = sPtr->view->size;
int pos;
Pixmap buffer;
#define MINV sPtr->minValue
#define MAXV sPtr->maxValue
#define POSV sPtr->value
bgc = W_GC(scr->black);
wgc = W_GC(scr->white);
lgc = W_GC(scr->gray);
buffer = XCreatePixmap(scr->display, sPtr->view->window,
size.width, size.height, scr->depth);
XFillRectangle(scr->display, buffer, lgc, 0, 0, size.width, size.height);
XFillRectangle(scr->display, buffer, scr->stippleGC, 0, 0, size.width,
size.height);
if (sPtr->flags.vertical) {
pos = (size.height-2-SLIDER_LENGTH)*(POSV-MINV)/(MAXV-MINV)+1;
/* draw knob */
XCopyArea(scr->display, sPtr->knobPixmap, buffer,
scr->copyGC, 0, 0, size.width-2, SLIDER_LENGTH, 1, pos);
} else {
pos = (size.width-2-SLIDER_LENGTH)*(POSV-MINV)/(MAXV-MINV)+1;
/* draw knob */
XCopyArea(scr->display, sPtr->knobPixmap, buffer,
scr->copyGC, 0, 0, SLIDER_LENGTH, size.height, pos, 1);
}
XDrawLine(scr->display, buffer, bgc, 0, 0, 0, size.height-1);
XDrawLine(scr->display, buffer, bgc, 0, 0, size.width, 0);
XDrawLine(scr->display, buffer, wgc, size.width-1, 0,
size.width-1, size.height-1);
XDrawLine(scr->display, buffer, wgc, 0, size.height-1,
size.width-1, size.height-1);
XCopyArea(scr->display, buffer, sPtr->view->window, scr->copyGC, 0, 0,
size.width, size.height, 0, 0);
XFreePixmap(scr->display, buffer);
}
static void
handleEvents(XEvent *event, void *data)
{
Slider *sPtr = (Slider*)data;
CHECK_CLASS(data, WC_Slider);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintSlider(sPtr);
break;
case DestroyNotify:
destroySlider(sPtr);
break;
}
}
#define DECR_PART 1
#define KNOB_PART 2
#define INCR_PART 3
static int
getSliderPart(Slider *sPtr, int x, int y)
{
int p;
int pos;
WMSize size = sPtr->view->size;
if (sPtr->flags.vertical) {
p = y;
pos = (size.height-2-SLIDER_LENGTH)*(POSV-MINV)/(MAXV-MINV);
if (p < pos)
return INCR_PART;
if (p > pos + SLIDER_LENGTH)
return DECR_PART;
return KNOB_PART;
} else {
p = x;
pos = (size.width-2-SLIDER_LENGTH)*(POSV-MINV)/(MAXV-MINV);
if (p < pos)
return DECR_PART;
if (p > pos + SLIDER_LENGTH)
return INCR_PART;
return KNOB_PART;
}
}
static int
valueForMousePoint(Slider *sPtr, int x, int y)
{
WMSize size = sPtr->view->size;
int f;
if (sPtr->flags.vertical) {
f = (y-SLIDER_LENGTH/2)*(MAXV-MINV)/((int)size.height-2-SLIDER_LENGTH);
} else {
f = (x-SLIDER_LENGTH/2)*(MAXV-MINV)/((int)size.width-2-SLIDER_LENGTH);
}
f += sPtr->minValue;
if (f < sPtr->minValue)
f = sPtr->minValue;
else if (f > sPtr->maxValue)
f = sPtr->maxValue;
return f;
}
static void
handleActionEvents(XEvent *event, void *data)
{
WMSlider *sPtr = (Slider*)data;
CHECK_CLASS(data, WC_Slider);
switch (event->type) {
case ButtonPress:
if (getSliderPart(sPtr, event->xbutton.x, event->xbutton.y)==KNOB_PART)
sPtr->flags.dragging = 1;
else {
#ifdef STRICT_NEXT_BEHAVIOUR
sPtr->flags.dragging = 1;
sPtr->value = valueForMousePoint(sPtr, event->xmotion.x,
event->xmotion.y);
paintSlider(sPtr);
#else
int tmp;
tmp = valueForMousePoint(sPtr, event->xmotion.x, event->xmotion.y);
if (tmp < sPtr->value)
tmp = sPtr->value-1;
else
tmp = sPtr->value+1;
WMSetSliderValue(sPtr, tmp);
#endif
if (sPtr->flags.continuous && sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
}
break;
case ButtonRelease:
if (!sPtr->flags.continuous && sPtr->flags.dragging && sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
sPtr->flags.dragging = 0;
break;
case MotionNotify:
if (sPtr->flags.dragging) {
sPtr->value = valueForMousePoint(sPtr, event->xmotion.x,
event->xmotion.y);
paintSlider(sPtr);
if (sPtr->flags.continuous && sPtr->action) {
(*sPtr->action)(sPtr, sPtr->clientData);
}
}
break;
}
}
static void
destroySlider(Slider *sPtr)
{
if (sPtr->knobPixmap)
XFreePixmap(sPtr->view->screen->display, sPtr->knobPixmap);
free(sPtr);
}

402
WINGs/wsplitview.c Normal file
View File

@@ -0,0 +1,402 @@
#include "WINGsP.h"
typedef struct W_SplitView {
W_Class widgetClass;
W_View *view;
/* WMSplitViewResizeSubviewsProc *resizeSubviewsProc;
*/
WMSplitViewConstrainProc *constrainProc;
struct {
unsigned int splitViewIsFull:1; /* already added 2 subviews */
} flags;
} SplitView;
#define DIVIDER_THICKNESS 8
static void destroySplitView(SplitView *sPtr);
static void paintSplitView(SplitView *sPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
W_ViewProcedureTable _SplitViewViewProcedures = {
NULL,
NULL,
NULL
};
static int
subviewCount(SplitView *sPtr)
{
int count = 0;
WMView *view;
for (view=sPtr->view->childrenList; view != NULL; view=view->nextSister)
count++;
return count;
}
static void
handleViewResized(void *self, WMNotification *notification)
{
SplitView *sPtr = (SplitView*)self;
int oldHeight;
WMView *view = sPtr->view;
int newWidth = view->size.width;
WMView *upper, *lower;
if (!view->childrenList)
return;
if (view->childrenList->nextSister==NULL) {
if (view->self)
WMResizeWidget(view->childrenList->self, newWidth, view->size.height);
else
W_ResizeView(view->childrenList, newWidth, view->size.height);
} else {
upper = view->childrenList;
lower = upper->nextSister;
oldHeight = upper->size.height+DIVIDER_THICKNESS+lower->size.height;
if (oldHeight > view->size.height
&& upper->size.height+DIVIDER_THICKNESS >= view->size.height) {
WMAdjustSplitViewSubviews(sPtr);
} else {
if (upper->self) {
WMResizeWidget(upper->self, newWidth, upper->size.height);
} else {
W_ResizeView(upper, newWidth, upper->size.height);
}
if (lower->self) {
WMResizeWidget(lower->self, newWidth,
view->size.height-lower->pos.y);
} else {
W_ResizeView(lower, newWidth, view->size.height-lower->pos.y);
}
}
}
}
WMSplitView*
WMCreateSplitView(WMWidget *parent)
{
SplitView *sPtr;
sPtr = wmalloc(sizeof(SplitView));
memset(sPtr, 0, sizeof(SplitView));
sPtr->widgetClass = WC_SplitView;
sPtr->view = W_CreateView(W_VIEW(parent));
if (!sPtr->view) {
free(sPtr);
return NULL;
}
sPtr->view->self = sPtr;
WMSetViewNotifySizeChanges(sPtr->view, True);
WMCreateEventHandler(sPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, sPtr);
WMCreateEventHandler(sPtr->view, ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask,
handleActionEvents, sPtr);
WMAddNotificationObserver(handleViewResized, sPtr,
WMViewSizeDidChangeNotification, sPtr->view);
return sPtr;
}
void
WMAddSplitViewSubview(WMSplitView *sPtr, WMView *subview)
{
int wasMapped;
assert(!sPtr->flags.splitViewIsFull);
wasMapped = subview->flags.mapped;
if (wasMapped) {
W_UnmapView(subview);
}
W_ReparentView(subview, sPtr->view);
#if 0
if (sPtr->resizeSubviewsProc && subviewCount(sPtr)>1) {
(*sPtr->resizeSubviewsProc)(sPtr, sPtr->view->size.width,
sPtr->view->size.height);
/* check if there is free space for the new subview and
* put the subview in it */
} else {
}
#endif
WMAdjustSplitViewSubviews(sPtr);
if (subviewCount(sPtr)==2)
sPtr->flags.splitViewIsFull = 1;
if (wasMapped) {
W_MapView(subview);
}
}
void
WMSetSplitViewConstrainProc(WMSplitView *sPtr, WMSplitViewConstrainProc *proc)
{
sPtr->constrainProc = proc;
}
void
WMAdjustSplitViewSubviews(WMSplitView *sPtr)
{
int theight = sPtr->view->size.height;
int width = sPtr->view->size.width;
int height;
int y, count;
W_View *view;
count = subviewCount(sPtr);
height = (theight - (count-1)*DIVIDER_THICKNESS)/count;
view = sPtr->view->childrenList;
if (view->self) {
WMMoveWidget(view->self, 0, 0);
WMResizeWidget(view->self, width, height);
} else {
W_MoveView(view, 0, 0);
W_ResizeView(view, width, height);
}
y = height + DIVIDER_THICKNESS;
for (view = view->nextSister; view != NULL; view = view->nextSister) {
if (view->self) {
WMMoveWidget(view->self, 0, y);
WMResizeWidget(view->self, width, height);
} else {
W_MoveView(view, 0, y);
W_ResizeView(view, width, height);
}
y += height + DIVIDER_THICKNESS;
}
}
#if 0
void
WMSetSplitViewResizeSubviewsProc(WMSplitView *sPtr,
WMSplitViewResizeSubviewsProc *proc)
{
sPtr->resizeSubviewsProc = proc;
}
#endif
int
WMGetSplitViewDividerThickness(WMSplitView *sPtr)
{
return DIVIDER_THICKNESS;
}
static void
paintSplitView(SplitView *sPtr)
{
W_Screen *scr = sPtr->view->screen;
int y, x;
W_View *ptr;
WMPixmap *dimple = scr->scrollerDimple;
XClearWindow(scr->display, sPtr->view->window);
x = (sPtr->view->size.width - dimple->width)/2;
ptr = sPtr->view->childrenList;
y = ptr->size.height;
XSetClipMask(scr->display, scr->clipGC, dimple->mask);
while (ptr->nextSister) {
y += (DIVIDER_THICKNESS - dimple->width)/2;
XSetClipOrigin(scr->display, scr->clipGC, x, y);
XCopyArea(scr->display, dimple->pixmap, sPtr->view->window,
scr->clipGC, 0, 0, dimple->width, dimple->height, x, y);
y += ptr->size.height;
ptr = ptr->nextSister;
}
}
static void
handleEvents(XEvent *event, void *data)
{
SplitView *sPtr = (SplitView*)data;
CHECK_CLASS(data, WC_SplitView);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintSplitView(sPtr);
break;
case DestroyNotify:
destroySplitView(sPtr);
break;
}
}
static void
dragDivider(SplitView *sPtr, int clickY)
{
int divider;
WMView *view, *view1=NULL, *view2=NULL;
int y;
int ofsY;
int done;
int dragging;
int minCoord;
int maxCoord;
XEvent ev;
WMScreen *scr = sPtr->view->screen;
view = sPtr->view->childrenList;
divider = 0;
ofsY = 0;
y = 0;
done = 0;
while (view) {
y += view->size.height+DIVIDER_THICKNESS;
if (clickY < y) {
/* offset from point where use clicked and the top of the
* divider */
ofsY = clickY - y + DIVIDER_THICKNESS;
view1 = view;
view2 = view->nextSister;
/* can't be NULL. It would mean the divider is at the bottom */
assert(view2!=NULL);
done = 1;
break;
}
view = view->nextSister;
divider++;
}
assert(done);
minCoord = view1->pos.y;
maxCoord = view2->pos.y+view2->size.height-DIVIDER_THICKNESS;
if (sPtr->constrainProc)
(*sPtr->constrainProc)(sPtr, divider, &minCoord, &maxCoord);
done = 0;
dragging = 0;
while (!done) {
WMMaskEvent(scr->display, ButtonMotionMask|ButtonReleaseMask
|ExposureMask, &ev);
switch (ev.type) {
case ButtonRelease:
done = 1;
if (dragging) {
XFillRectangle(scr->display, sPtr->view->window, scr->ixorGC,
0, y, sPtr->view->size.width,DIVIDER_THICKNESS);
}
break;
case MotionNotify:
if (dragging) {
XFillRectangle(scr->display, sPtr->view->window, scr->ixorGC,
0, y, sPtr->view->size.width,DIVIDER_THICKNESS);
}
if (ev.xmotion.y-ofsY < minCoord)
y = minCoord;
else if (ev.xmotion.y-ofsY > maxCoord)
y = maxCoord;
else
y = ev.xmotion.y-ofsY;
XFillRectangle(scr->display, sPtr->view->window, scr->ixorGC,
0, y, sPtr->view->size.width, DIVIDER_THICKNESS);
dragging = 1;
break;
default:
WMHandleEvent(&ev);
break;
}
}
if (dragging) {
int theight;
theight = view1->size.height + view2->size.height + DIVIDER_THICKNESS;
WMResizeWidget(view1->self, sPtr->view->size.width, y - view1->pos.y);
WMResizeWidget(view2->self, sPtr->view->size.width,
theight - view1->size.height - DIVIDER_THICKNESS);
WMMoveWidget(view2->self, 0,
view1->pos.y+view1->size.height+DIVIDER_THICKNESS);
}
}
static void
handleActionEvents(XEvent *event, void *data)
{
CHECK_CLASS(data, WC_SplitView);
switch (event->type) {
case ButtonPress:
if (event->xbutton.button == Button1)
dragDivider(data, event->xbutton.y);
break;
}
}
static void
destroySplitView(SplitView *sPtr)
{
WMRemoveNotificationObserver(sPtr);
free(sPtr);
}

445
WINGs/wtest.c Normal file
View File

@@ -0,0 +1,445 @@
/*
* WINGs test application
*/
#include "WINGs.h"
#include <stdio.h>
/*
* You need to define this function to link any program to WINGs.
* This will be called when the application will be terminated because
* on a fatal error.
*/
void
wAbort()
{
exit(1);
}
Display *dpy;
int windowCount = 0;
void
closeAction(WMWidget *self, void *data)
{
WMDestroyWidget(self);
windowCount--;
if (windowCount < 1)
exit(0);
}
void
testOpenFilePanel(WMScreen *scr)
{
WMOpenPanel *panel;
windowCount++;
/* get the shared Open File panel */
panel = WMGetOpenPanel(scr);
WMRunModalOpenPanelForDirectory(panel, NULL, "/usr/local", NULL, NULL);
/* free the panel to save some memory. Not needed otherwise. */
WMFreeFilePanel(panel);
}
void
testFontPanel(WMScreen *scr)
{
WMFontPanel *panel;
windowCount++;
panel = WMGetFontPanel(scr);
WMShowFontPanel(panel);
/* WMFreeFontPanel(panel);*/
}
void
testList(WMScreen *scr)
{
WMWindow *win;
WMList *list;
char text[100];
int i;
windowCount++;
win = WMCreateWindow(scr, "testList");
WMSetWindowTitle(win, "List");
WMSetWindowCloseAction(win, closeAction, NULL);
list = WMCreateList(win);
for (i=0; i<50; i++) {
sprintf(text, "Item %i", i);
WMAddListItem(list, text);
}
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
void
testGradientButtons(WMScreen *scr)
{
WMWindow *win;
WMButton *btn;
WMPixmap *pix1, *pix2;
RImage *back;
RColor light, dark;
WMColor *color;
windowCount++;
/* creates the top-level window */
win = WMCreateWindow(scr, "testGradientButtons");
WMSetWindowTitle(win, "Gradiented Button Demo");
WMResizeWidget(win, 300, 200);
light.red = 0x90;
light.green = 0x85;
light.blue = 0x90;
dark.red = 0x35;
dark.green = 0x30;
dark.blue = 0x35;
color = WMCreateRGBColor(scr, 0x5900, 0x5100, 0x5900, True);
WMSetWidgetBackgroundColor(win, color);
WMReleaseColor(color);
back = RRenderGradient(60, 24, &dark, &light, RGRD_DIAGONAL);
RBevelImage(back, RBEV_RAISED2);
pix1 = WMCreatePixmapFromRImage(scr, back, 0);
RDestroyImage(back);
back = RRenderGradient(60, 24, &dark, &light, RGRD_DIAGONAL);
RBevelImage(back, RBEV_SUNKEN);
pix2 = WMCreatePixmapFromRImage(scr, back, 0);
RDestroyImage(back);
btn = WMCreateButton(win, WBTMomentaryChange);
WMResizeWidget(btn, 60, 24);
WMMoveWidget(btn, 20, 100);
WMSetButtonBordered(btn, False);
WMSetButtonImagePosition(btn, WIPOverlaps);
WMSetButtonImage(btn, pix1);
WMSetButtonAltImage(btn, pix2);
WMSetButtonText(btn, "Cool");
btn = WMCreateButton(win, WBTMomentaryChange);
WMResizeWidget(btn, 60, 24);
WMMoveWidget(btn, 90, 100);
WMSetButtonBordered(btn, False);
WMSetButtonImagePosition(btn, WIPOverlaps);
WMSetButtonImage(btn, pix1);
WMSetButtonAltImage(btn, pix2);
WMSetButtonText(btn, "Button");
btn = WMCreateButton(win, WBTMomentaryChange);
WMResizeWidget(btn, 60, 24);
WMMoveWidget(btn, 160, 100);
WMSetButtonBordered(btn, False);
WMSetButtonImagePosition(btn, WIPOverlaps);
WMSetButtonImage(btn, pix1);
WMSetButtonAltImage(btn, pix2);
WMSetButtonText(btn, "Test");
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
void
testScrollView(WMScreen *scr)
{
WMWindow *win;
WMScrollView *sview;
WMFrame *f;
WMLabel *l;
char buffer[128];
int i;
windowCount++;
/* creates the top-level window */
win = WMCreateWindow(scr, "testScroll");
WMSetWindowTitle(win, "Scrollable View");
WMSetWindowCloseAction(win, closeAction, NULL);
/* set the window size */
WMResizeWidget(win, 300, 300);
/* creates a scrollable view inside the top-level window */
sview = WMCreateScrollView(win);
WMResizeWidget(sview, 200, 200);
WMMoveWidget(sview, 30, 30);
WMSetScrollViewRelief(sview, WRSunken);
WMSetScrollViewHasVerticalScroller(sview, True);
WMSetScrollViewHasHorizontalScroller(sview, True);
/* create a frame with a bunch of labels */
f = WMCreateFrame(win);
WMResizeWidget(f, 400, 400);
WMSetFrameRelief(f, WRFlat);
for (i=0; i<20; i++) {
l = WMCreateLabel(f);
WMResizeWidget(l, 50, 18);
WMMoveWidget(l, 10, 20*i);
sprintf(buffer, "Label %i", i);
WMSetLabelText(l, buffer);
WMSetLabelRelief(l, WRSimple);
}
WMMapSubwidgets(f);
WMMapWidget(f);
WMSetScrollViewContentView(sview, WMWidgetView(f));
/* make the windows of the widgets be actually created */
WMRealizeWidget(win);
/* Map all child widgets of the top-level be mapped.
* You must call this for each container widget (like frames),
* even if they are childs of the top-level window.
*/
WMMapSubwidgets(win);
/* map the top-level window */
WMMapWidget(win);
}
void
testColorWell(WMScreen *scr)
{
WMWindow *win;
WMColorWell *well1, *well2;
windowCount++;
win = WMCreateWindow(scr, "testColor");
WMResizeWidget(win, 300, 300);
WMSetWindowCloseAction(win, closeAction, NULL);
well1 = WMCreateColorWell(win);
WMResizeWidget(well1, 60, 40);
WMMoveWidget(well1, 100, 100);
WMSetColorWellColor(well1, WMCreateRGBColor(scr, 0x8888, 0, 0x1111, True));
well2 = WMCreateColorWell(win);
WMResizeWidget(well2, 60, 40);
WMMoveWidget(well2, 200, 100);
WMSetColorWellColor(well2, WMCreateRGBColor(scr, 0, 0, 0x8888, True));
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
void
testSlider(WMScreen *scr)
{
WMWindow *win;
WMSlider *s;
windowCount++;
win = WMCreateWindow(scr, "testSlider");
WMResizeWidget(win, 300, 300);
WMSetWindowTitle(win, "Sliders");
WMSetWindowCloseAction(win, closeAction, NULL);
s = WMCreateSlider(win);
WMResizeWidget(s, 16, 100);
WMMoveWidget(s, 100, 100);
s = WMCreateSlider(win);
WMResizeWidget(s, 100, 16);
WMMoveWidget(s, 100, 10);
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
#if 0
void
testText(WMScreen *scr)
{
WMWindow *win;
WMSimpleText *text;
windowCount++;
win = WMCreateWindow(scr, "testText");
WMResizeWidget(win, 300, 300);
WMSetWindowTitle(win, "Text");
WMSetWindowCloseAction(win, closeAction, NULL);
text = WMCreateSimpleText(win);
WMResizeWidget(text, 280, 280);
WMMoveWidget(text, 10, 10);
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
#endif
void
testTextField(WMScreen *scr)
{
WMWindow *win;
WMTextField *field, *field2;
windowCount++;
win = WMCreateWindow(scr, "testText");
WMResizeWidget(win, 400, 300);
WMSetWindowCloseAction(win, closeAction, NULL);
field = WMCreateTextField(win);
WMResizeWidget(field, 200, 20);
WMMoveWidget(field, 20, 20);
field2 = WMCreateTextField(win);
WMResizeWidget(field2, 200, 20);
WMMoveWidget(field2, 20, 50);
WMSetTextFieldAlignment(field2, WARight);
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
void
testPullDown(WMScreen *scr)
{
WMWindow *win;
WMPopUpButton *pop, *pop2;
windowCount++;
win = WMCreateWindow(scr, "pullDown");
WMResizeWidget(win, 400, 300);
WMSetWindowCloseAction(win, closeAction, NULL);
pop = WMCreatePopUpButton(win);
WMResizeWidget(pop, 100, 20);
WMMoveWidget(pop, 50, 60);
WMSetPopUpButtonPullsDown(pop, True);
WMSetPopUpButtonText(pop, "Commands");
WMAddPopUpButtonItem(pop, "Add");
WMAddPopUpButtonItem(pop, "Remove");
WMAddPopUpButtonItem(pop, "Check");
WMAddPopUpButtonItem(pop, "Eat");
pop2 = WMCreatePopUpButton(win);
WMResizeWidget(pop2, 100, 20);
WMMoveWidget(pop2, 200, 60);
WMSetPopUpButtonText(pop2, "Select");
WMAddPopUpButtonItem(pop2, "Apples");
WMAddPopUpButtonItem(pop2, "Bananas");
WMAddPopUpButtonItem(pop2, "Strawberries");
WMAddPopUpButtonItem(pop2, "Blueberries");
WMRealizeWidget(win);
WMMapSubwidgets(win);
WMMapWidget(win);
}
#include "WUtil.h"
int main(int argc, char **argv)
{
WMScreen *scr;
WMPixmap *pixmap;
/* Initialize the application */
WMInitializeApplication("Test", &argc, argv);
/*
* Open connection to the X display.
*/
dpy = XOpenDisplay("");
if (!dpy) {
puts("could not open display");
exit(1);
}
/* This is used to disable buffering of X protocol requests.
* Do NOT use it unless when debugging. It will cause a major
* slowdown in your application
*/
#ifdef DEBUG
XSynchronize(dpy, True);
#endif
/*
* Create screen descriptor.
*/
scr = WMCreateScreen(dpy, DefaultScreen(dpy));
/*
* Loads the logo of the application.
*/
pixmap = WMCreatePixmapFromFile(scr, "logo.xpm");
/*
* Makes the logo be used in standard dialog panels.
*/
WMSetApplicationIconImage(scr, pixmap); WMReleasePixmap(pixmap);
/*
* Do some test stuff.
*
* Put the testSomething() function you want to test here.
*/
#if 0
testOpenFilePanel(scr);
testFontPanel(scr);
testList(scr);
testGradientButtons(scr);
testScrollView(scr);
testColorWell(scr);
testSlider(scr);
testTextField(scr);
testPullDown(scr);
#endif
/*
* The main event loop.
*
*/
WMScreenMainLoop(scr);
return 0;
}

880
WINGs/wtextfield.c Normal file
View File

@@ -0,0 +1,880 @@
#include "WINGsP.h"
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <ctype.h>
#define CURSOR_BLINK_ON_DELAY 600
#define CURSOR_BLINK_OFF_DELAY 300
char *WMTextDidChangeNotification = "WMTextDidChangeNotification";
char *WMTextDidBeginEditingNotification = "WMTextDidBeginEditingNotification";
char *WMTextDidEndEditingNotification = "WMTextDidEndEditingNotification";
typedef struct W_TextField {
W_Class widgetClass;
W_View *view;
struct W_TextField *nextField; /* next textfield in the chain */
struct W_TextField *prevField;
char *text;
int textLen; /* size of text */
int bufferSize; /* memory allocated for text */
int viewPosition; /* position of text being shown */
int cursorPosition; /* position of the insertion cursor */
short usableWidth;
short offsetWidth; /* offset of text from border */
#if 0
WMHandlerID timerID; /* for cursor blinking */
#endif
struct {
WMAlignment alignment:2;
unsigned int bordered:1;
unsigned int enabled:1;
unsigned int focused:1;
unsigned int cursorOn:1;
unsigned int secure:1; /* password entry style */
/**/
unsigned int notIllegalMovement:1;
} flags;
} TextField;
#define MIN_TEXT_BUFFER 2
#define TEXT_BUFFER_INCR 8
#define WM_EMACSKEYMASK ControlMask
#define WM_EMACSKEY_LEFT XK_b
#define WM_EMACSKEY_RIGHT XK_f
#define WM_EMACSKEY_HOME XK_a
#define WM_EMACSKEY_END XK_e
#define WM_EMACSKEY_BS XK_h
#define WM_EMACSKEY_DEL XK_d
#define DEFAULT_WIDTH 60
#define DEFAULT_HEIGHT 20
#define DEFAULT_BORDERED True
#define DEFAULT_ALIGNMENT WALeft
static void destroyTextField(TextField *tPtr);
static void paintTextField(TextField *tPtr);
static void handleEvents(XEvent *event, void *data);
static void handleTextFieldActionEvents(XEvent *event, void *data);
static void resizeTextField();
struct W_ViewProcedureTable _TextFieldViewProcedures = {
NULL,
resizeTextField,
NULL
};
#define TEXT_WIDTH(tPtr, start) (WMWidthOfString((tPtr)->view->screen->normalFont, \
&((tPtr)->text[(start)]), (tPtr)->textLen - (start) + 1))
#define TEXT_WIDTH2(tPtr, start, end) (WMWidthOfString((tPtr)->view->screen->normalFont, \
&((tPtr)->text[(start)]), (end) - (start) + 1))
static void
memmv(char *dest, char *src, int size)
{
int i;
if (dest > src) {
for (i=size-1; i>=0; i--) {
dest[i] = src[i];
}
} else if (dest < src) {
for (i=0; i<size; i++) {
dest[i] = src[i];
}
}
}
static int
incrToFit(TextField *tPtr)
{
int vp = tPtr->viewPosition;
while (TEXT_WIDTH(tPtr, tPtr->viewPosition) > tPtr->usableWidth) {
tPtr->viewPosition++;
}
return vp!=tPtr->viewPosition;
}
static int
incrToFit2(TextField *tPtr)
{
int vp = tPtr->viewPosition;
while (TEXT_WIDTH2(tPtr, tPtr->viewPosition, tPtr->cursorPosition)
>= tPtr->usableWidth)
tPtr->viewPosition++;
return vp!=tPtr->viewPosition;
}
static void
decrToFit(TextField *tPtr)
{
while (TEXT_WIDTH(tPtr, tPtr->viewPosition-1) < tPtr->usableWidth
&& tPtr->viewPosition>0)
tPtr->viewPosition--;
}
#undef TEXT_WIDTH
#undef TEXT_WIDTH2
WMTextField*
WMCreateTextField(WMWidget *parent)
{
TextField *tPtr;
tPtr = wmalloc(sizeof(TextField));
memset(tPtr, 0, sizeof(TextField));
tPtr->widgetClass = WC_TextField;
tPtr->view = W_CreateView(W_VIEW(parent));
if (!tPtr->view) {
free(tPtr);
return NULL;
}
tPtr->view->self = tPtr;
tPtr->view->attribFlags |= CWCursor;
tPtr->view->attribs.cursor = tPtr->view->screen->textCursor;
W_SetViewBackgroundColor(tPtr->view, tPtr->view->screen->white);
tPtr->text = wmalloc(MIN_TEXT_BUFFER);
tPtr->text[0] = 0;
tPtr->textLen = 0;
tPtr->bufferSize = MIN_TEXT_BUFFER;
tPtr->flags.enabled = 1;
WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
|FocusChangeMask, handleEvents, tPtr);
W_ResizeView(tPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
WMSetTextFieldBordered(tPtr, DEFAULT_BORDERED);
tPtr->flags.alignment = DEFAULT_ALIGNMENT;
tPtr->offsetWidth = (tPtr->view->size.height
- tPtr->view->screen->normalFont->height)/2;
WMCreateEventHandler(tPtr->view, EnterWindowMask|LeaveWindowMask
|ButtonPressMask|KeyPressMask|Button1MotionMask,
handleTextFieldActionEvents, tPtr);
tPtr->flags.cursorOn = 1;
return tPtr;
}
void
WMInsertTextFieldText(WMTextField *tPtr, char *text, int position)
{
int len;
CHECK_CLASS(tPtr, WC_TextField);
if (!text)
return;
len = strlen(text);
/* check if buffer will hold the text */
if (len + tPtr->textLen >= tPtr->bufferSize) {
tPtr->bufferSize = tPtr->textLen + len + TEXT_BUFFER_INCR;
tPtr->text = realloc(tPtr->text, tPtr->bufferSize);
}
if (position < 0 || position >= tPtr->textLen) {
/* append the text at the end */
strcat(tPtr->text, text);
incrToFit(tPtr);
tPtr->textLen += len;
tPtr->cursorPosition += len;
} else {
/* insert text at position */
memmv(&(tPtr->text[position+len]), &(tPtr->text[position]),
tPtr->textLen-position+1);
memcpy(&(tPtr->text[position]), text, len);
tPtr->textLen += len;
if (position >= tPtr->cursorPosition) {
tPtr->cursorPosition += len;
incrToFit2(tPtr);
} else {
incrToFit(tPtr);
}
}
paintTextField(tPtr);
}
void
WMDeleteTextFieldRange(WMTextField *tPtr, WMRange range)
{
CHECK_CLASS(tPtr, WC_TextField);
if (range.position >= tPtr->textLen)
return;
if (range.count < 1) {
if (range.position < 0)
range.position = 0;
tPtr->text[range.position] = 0;
tPtr->textLen = range.position;
tPtr->cursorPosition = 0;
tPtr->viewPosition = 0;
} else {
if (range.position + range.count > tPtr->textLen)
range.count = tPtr->textLen - range.position;
memmv(&(tPtr->text[range.position]), &(tPtr->text[range.position+range.count]),
tPtr->textLen - (range.position+range.count) + 1);
tPtr->textLen -= range.count;
if (tPtr->cursorPosition > range.position)
tPtr->cursorPosition -= range.count;
decrToFit(tPtr);
}
paintTextField(tPtr);
}
char*
WMGetTextFieldText(WMTextField *tPtr)
{
CHECK_CLASS(tPtr, WC_TextField);
return wstrdup(tPtr->text);
}
void
WMSetTextFieldText(WMTextField *tPtr, char *text)
{
if (text==NULL) {
tPtr->text[0] = 0;
tPtr->textLen = 0;
} else {
tPtr->textLen = strlen(text);
if (tPtr->textLen >= tPtr->bufferSize) {
tPtr->bufferSize = tPtr->textLen + TEXT_BUFFER_INCR;
tPtr->text = realloc(tPtr->text, tPtr->bufferSize);
}
strcpy(tPtr->text, text);
}
if (tPtr->textLen < tPtr->cursorPosition)
tPtr->cursorPosition = tPtr->textLen;
if (tPtr->view->flags.realized)
paintTextField(tPtr);
}
void
WMSetTextFieldAlignment(WMTextField *tPtr, WMAlignment alignment)
{
tPtr->flags.alignment = alignment;
if (alignment!=WALeft) {
wwarning("only left alignment is supported in textfields");
return;
}
if (tPtr->view->flags.realized) {
paintTextField(tPtr);
}
}
void
WMSetTextFieldBordered(WMTextField *tPtr, Bool bordered)
{
tPtr->flags.bordered = bordered;
if (tPtr->view->flags.realized) {
paintTextField(tPtr);
}
}
void
WMSetTextFieldSecure(WMTextField *tPtr, Bool flag)
{
tPtr->flags.secure = flag;
if (tPtr->view->flags.realized) {
paintTextField(tPtr);
}
}
void
WMSetTextFieldEnabled(WMTextField *tPtr, Bool flag)
{
tPtr->flags.enabled = flag;
if (tPtr->view->flags.realized) {
paintTextField(tPtr);
}
}
static void
resizeTextField(WMTextField *tPtr, unsigned int width, unsigned int height)
{
W_ResizeView(tPtr->view, width, height);
tPtr->offsetWidth = (tPtr->view->size.height
- tPtr->view->screen->normalFont->height)/2;
tPtr->usableWidth = tPtr->view->size.width - 2*tPtr->offsetWidth;
}
static void
paintCursor(TextField *tPtr)
{
int cx;
WMScreen *screen = tPtr->view->screen;
int textWidth;
cx = WMWidthOfString(screen->normalFont,
&(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition);
switch (tPtr->flags.alignment) {
case WARight:
textWidth = WMWidthOfString(screen->normalFont, tPtr->text,
tPtr->textLen);
if (textWidth < tPtr->usableWidth)
cx += tPtr->offsetWidth + tPtr->usableWidth - textWidth;
else
cx += tPtr->offsetWidth;
break;
case WALeft:
cx += tPtr->offsetWidth;
break;
case WACenter:
textWidth = WMWidthOfString(screen->normalFont, tPtr->text,
tPtr->textLen);
if (textWidth < tPtr->usableWidth)
cx += tPtr->offsetWidth + (tPtr->usableWidth-textWidth)/2;
else
cx += tPtr->offsetWidth;
break;
}
/*
XDrawRectangle(screen->display, tPtr->view->window, screen->xorGC,
cx, tPtr->offsetWidth, 1,
tPtr->view->size.height - 2*tPtr->offsetWidth - 1);
*/
XDrawLine(screen->display, tPtr->view->window, screen->xorGC,
cx, tPtr->offsetWidth, cx,
tPtr->view->size.height - tPtr->offsetWidth - 1);
}
static void
drawRelief(WMView *view)
{
WMScreen *scr = view->screen;
Display *dpy = scr->display;
GC wgc;
GC lgc;
GC dgc;
int width = view->size.width;
int height = view->size.height;
wgc = W_GC(scr->white);
dgc = W_GC(scr->darkGray);
lgc = W_GC(scr->gray);
/* top left */
XDrawLine(dpy, view->window, dgc, 0, 0, width-1, 0);
XDrawLine(dpy, view->window, dgc, 0, 1, width-2, 1);
XDrawLine(dpy, view->window, dgc, 0, 0, 0, height-2);
XDrawLine(dpy, view->window, dgc, 1, 0, 1, height-3);
/* bottom right */
XDrawLine(dpy, view->window, wgc, 0, height-1, width-1, height-1);
XDrawLine(dpy, view->window, lgc, 1, height-2, width-2, height-2);
XDrawLine(dpy, view->window, wgc, width-1, 0, width-1, height-1);
XDrawLine(dpy, view->window, lgc, width-2, 1, width-2, height-3);
}
static void
paintTextField(TextField *tPtr)
{
W_Screen *screen = tPtr->view->screen;
W_View *view = tPtr->view;
int tx, ty, tw, th;
int bd;
int totalWidth;
if (!view->flags.realized || !view->flags.mapped)
return;
if (!tPtr->flags.bordered) {
bd = 0;
} else {
bd = 2;
}
totalWidth = tPtr->view->size.width - 2*bd;
if (tPtr->textLen > 0) {
tw = WMWidthOfString(screen->normalFont,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen - tPtr->viewPosition);
th = screen->normalFont->height;
ty = tPtr->offsetWidth;
switch (tPtr->flags.alignment) {
case WALeft:
tx = tPtr->offsetWidth;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd+tw, bd,
totalWidth-tw, view->size.height-2*bd,
False);
break;
case WACenter:
tx = tPtr->offsetWidth + (tPtr->usableWidth - tw) / 2;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd, bd,
totalWidth, view->size.height-2*bd, False);
break;
default:
case WARight:
tx = tPtr->offsetWidth + tPtr->usableWidth - tw;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd, bd,
totalWidth-tw, view->size.height-2*bd, False);
break;
}
if (!tPtr->flags.secure) {
if (!tPtr->flags.enabled)
WMSetColorInGC(screen->darkGray, screen->textFieldGC);
WMDrawImageString(screen, view->window, screen->textFieldGC,
screen->normalFont, tx, ty,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen - tPtr->viewPosition);
if (!tPtr->flags.enabled)
WMSetColorInGC(screen->black, screen->textFieldGC);
}
} else {
XClearArea(screen->display, view->window, bd, bd, totalWidth,
view->size.height - 2*bd, False);
}
/* draw cursor */
if (tPtr->flags.focused && tPtr->flags.enabled && tPtr->flags.cursorOn) {
paintCursor(tPtr);
}
/* draw relief */
if (tPtr->flags.bordered) {
drawRelief(view);
}
}
#if 0
static void
blinkCursor(void *data)
{
TextField *tPtr = (TextField*)data;
if (tPtr->flags.cursorOn) {
tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_OFF_DELAY, blinkCursor,
data);
} else {
tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY, blinkCursor,
data);
}
paintCursor(tPtr);
tPtr->flags.cursorOn = !tPtr->flags.cursorOn;
}
#endif
static void
handleEvents(XEvent *event, void *data)
{
TextField *tPtr = (TextField*)data;
CHECK_CLASS(data, WC_TextField);
switch (event->type) {
case FocusIn:
if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view))!=tPtr->view)
return;
tPtr->flags.focused = 1;
#if 0
if (!tPtr->timerID) {
tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY,
blinkCursor, tPtr);
}
#endif
paintTextField(tPtr);
WMPostNotificationName(WMTextDidBeginEditingNotification, tPtr, NULL);
tPtr->flags.notIllegalMovement = 0;
break;
case FocusOut:
tPtr->flags.focused = 0;
#if 0
if (tPtr->timerID)
WMDeleteTimerHandler(tPtr->timerID);
tPtr->timerID = NULL;
#endif
paintTextField(tPtr);
if (!tPtr->flags.notIllegalMovement) {
WMPostNotificationName(WMTextDidEndEditingNotification, tPtr,
WMIllegalTextMovement);
}
break;
case Expose:
if (event->xexpose.count!=0)
break;
paintTextField(tPtr);
break;
case DestroyNotify:
destroyTextField(tPtr);
break;
}
}
static void
handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
{
char buffer[64];
KeySym ksym;
int count, refresh = 0;
int control_pressed = 0;
int changed;
WMNotification *notif;
WMScreen *scr = tPtr->view->screen;
changed = 0;
if (((XKeyEvent *) event)->state & WM_EMACSKEYMASK) {
control_pressed = 1;
}
count = XLookupString(&event->xkey, buffer, 63, &ksym, NULL);
buffer[count] = '\0';
switch (ksym) {
case XK_Tab:
if (event->xkey.state & ShiftMask) {
notif = WMCreateNotification(WMTextDidEndEditingNotification,
tPtr, (void*)WMBacktabTextMovement);
if (tPtr->view->prevFocusChain) {
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
tPtr->view->prevFocusChain);
tPtr->flags.notIllegalMovement = 1;
}
} else {
notif = WMCreateNotification(WMTextDidEndEditingNotification,
tPtr, (void*)WMTabTextMovement);
if (tPtr->view->nextFocusChain) {
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
tPtr->view->nextFocusChain);
tPtr->flags.notIllegalMovement = 1;
}
}
WMPostNotification(notif);
WMReleaseNotification(notif);
break;
case XK_Return:
WMPostNotificationName(WMTextDidEndEditingNotification, tPtr,
(void*)WMReturnTextMovement);
break;
case WM_EMACSKEY_LEFT:
if (!control_pressed) {
goto normal_key;
}
case XK_KP_Left:
case XK_Left:
if (tPtr->cursorPosition > 0) {
paintCursor(tPtr);
tPtr->cursorPosition--;
if (tPtr->cursorPosition < tPtr->viewPosition) {
tPtr->viewPosition = tPtr->cursorPosition;
refresh = 1;
} else {
paintCursor(tPtr);
}
}
break;
case WM_EMACSKEY_RIGHT:
if (!control_pressed) {
goto normal_key;
}
case XK_KP_Right:
case XK_Right:
if (tPtr->cursorPosition < tPtr->textLen) {
paintCursor(tPtr);
tPtr->cursorPosition++;
while (WMWidthOfString(scr->normalFont,
&(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition)
> tPtr->usableWidth) {
tPtr->viewPosition++;
refresh = 1;
}
if (!refresh)
paintCursor(tPtr);
}
break;
case WM_EMACSKEY_HOME:
if (!control_pressed) {
goto normal_key;
}
case XK_KP_Home:
case XK_Home:
if (tPtr->cursorPosition > 0) {
paintCursor(tPtr);
tPtr->cursorPosition = 0;
if (tPtr->viewPosition > 0) {
tPtr->viewPosition = 0;
refresh = 1;
} else {
paintCursor(tPtr);
}
}
break;
case WM_EMACSKEY_END:
if (!control_pressed) {
goto normal_key;
}
case XK_KP_End:
case XK_End:
if (tPtr->cursorPosition < tPtr->textLen) {
paintCursor(tPtr);
tPtr->cursorPosition = tPtr->textLen;
tPtr->viewPosition = 0;
while (WMWidthOfString(scr->normalFont,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition)
>= tPtr->usableWidth) {
tPtr->viewPosition++;
refresh = 1;
}
if (!refresh)
paintCursor(tPtr);
}
break;
case WM_EMACSKEY_BS:
if (!control_pressed) {
goto normal_key;
}
case XK_BackSpace:
if (tPtr->cursorPosition > 0) {
WMRange range;
changed = 1;
range.position = tPtr->cursorPosition-1;
range.count = 1;
WMDeleteTextFieldRange(tPtr, range);
}
break;
case WM_EMACSKEY_DEL:
if (!control_pressed) {
goto normal_key;
}
case XK_KP_Delete:
case XK_Delete:
if (tPtr->cursorPosition < tPtr->textLen) {
WMRange range;
changed = 1;
range.position = tPtr->cursorPosition;
range.count = 1;
WMDeleteTextFieldRange(tPtr, range);
}
break;
normal_key:
default:
if (count > 0 && !iscntrl(buffer[0])) {
changed = 1;
WMInsertTextFieldText(tPtr, buffer, tPtr->cursorPosition);
}
}
if (refresh) {
paintTextField(tPtr);
}
if (changed) {
WMPostNotificationName(WMTextDidChangeNotification, tPtr, NULL);
}
}
static int
pointToCursorPosition(TextField *tPtr, int x)
{
WMFont *font = tPtr->view->screen->normalFont;
int a, b, mid;
int tw;
if (tPtr->flags.bordered)
x -= 2;
a = tPtr->viewPosition;
b = tPtr->viewPosition + tPtr->textLen;
if (WMWidthOfString(font, &(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition) < x)
return tPtr->textLen;
while (a < b && b-a>1) {
mid = (a+b)/2;
tw = WMWidthOfString(font, &(tPtr->text[tPtr->viewPosition]),
mid - tPtr->viewPosition);
if (tw > x)
b = mid;
else if (tw < x)
a = mid;
else
return mid;
}
return (a+b)/2;
}
static void
handleTextFieldActionEvents(XEvent *event, void *data)
{
TextField *tPtr = (TextField*)data;
CHECK_CLASS(data, WC_TextField);
switch (event->type) {
case KeyPress:
if (tPtr->flags.enabled)
handleTextFieldKeyPress(tPtr, event);
break;
case MotionNotify:
if (tPtr->flags.enabled && (event->xmotion.state & Button1Mask)) {
tPtr->cursorPosition = pointToCursorPosition(tPtr,
event->xmotion.x);
paintTextField(tPtr);
}
break;
case ButtonPress:
if (tPtr->flags.enabled && !tPtr->flags.focused) {
WMSetFocusToWidget(tPtr);
tPtr->cursorPosition = pointToCursorPosition(tPtr,
event->xbutton.x);
paintTextField(tPtr);
} else if (tPtr->flags.focused) {
tPtr->cursorPosition = pointToCursorPosition(tPtr,
event->xbutton.x);
paintTextField(tPtr);
}
if (event->xbutton.button == Button2) {
char *text;
text = W_GetTextSelection(tPtr->view->screen, XA_PRIMARY);
if (!text) {
text = W_GetTextSelection(tPtr->view->screen, XA_CUT_BUFFER0);
}
if (text) {
WMInsertTextFieldText(tPtr, text, tPtr->cursorPosition);
XFree(text);
WMPostNotificationName(WMTextDidChangeNotification, tPtr,
NULL);
}
}
break;
case ButtonRelease:
break;
}
}
static void
destroyTextField(TextField *tPtr)
{
#if 0
if (tPtr->timerID)
WMDeleteTimerHandler(tPtr->timerID);
#endif
if (tPtr->text)
free(tPtr->text);
free(tPtr);
}

663
WINGs/wview.c Normal file
View File

@@ -0,0 +1,663 @@
#include "WINGsP.h"
#include <X11/Xresource.h>
/* the notifications about views */
char *WMViewSizeDidChangeNotification = "WMViewSizeDidChangeNotification";
char *WMViewFocusDidChangeNotification = "WMViewFocusDidChangeNotification";
char *WMViewRealizedNotification = "WMViewRealizedNotification";
#define EVENT_MASK \
KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \
EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \
VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|\
SubstructureNotifyMask|SubstructureRedirectMask
static XSetWindowAttributes defAtts= {
None, /* background_pixmap */
0, /* background_pixel */
CopyFromParent, /* border_pixmap */
0, /* border_pixel */
ForgetGravity, /* bit_gravity */
ForgetGravity, /* win_gravity */
NotUseful, /* backing_store */
(unsigned) ~0, /* backing_planes */
0, /* backing_pixel */
False, /* save_under */
EVENT_MASK, /* event_mask */
0, /* do_not_propagate_mask */
False, /* override_redirect */
None, /* colormap */
None /* cursor */
};
static XContext ViewContext=0; /* context for views */
W_View*
W_GetViewForXWindow(Display *display, Window window)
{
W_View *view;
if (XFindContext(display, window, ViewContext, (XPointer*)&view)==0) {
return view;
}
return NULL;
}
static void
unparentView(W_View *view)
{
/* remove from parent's children list */
if (view->parent!=NULL) {
W_View *ptr;
ptr = view->parent->childrenList;
if (ptr == view) {
view->parent->childrenList = view->nextSister;
} else {
while (ptr!=NULL) {
if (ptr->nextSister == view) {
ptr->nextSister = view->nextSister;
break;
}
ptr = ptr->nextSister;
}
}
}
view->parent = NULL;
}
static void
adoptChildView(W_View *view, W_View *child)
{
child->nextSister = NULL;
/* add to end of children list of parent */
if (view->childrenList == NULL) {
view->childrenList = child;
} else {
W_View *ptr;
ptr = view->childrenList;
while (ptr->nextSister!=NULL)
ptr = ptr->nextSister;
ptr->nextSister = child;
}
child->parent = view;
}
static void
handleEvents(XEvent *event, void *data)
{
W_View *view = (W_View*)data;
if (event->type == ConfigureNotify) {
if (event->xconfigure.width != view->size.width
|| event->xconfigure.height != view->size.height) {
if (view->flags.notifySizeChanged) {
view->size.width = event->xconfigure.width;
view->size.height = event->xconfigure.height;
WMPostNotificationName(WMViewSizeDidChangeNotification,
view, NULL);
}
}
}
}
static W_View*
createView(W_Screen *screen, W_View *parent)
{
W_View *view;
if (ViewContext==0)
ViewContext = XUniqueContext();
view = wmalloc(sizeof(W_View));
memset(view, 0, sizeof(W_View));
view->refCount = 1;
view->screen = screen;
if (parent!=NULL) {
/* attributes are not valid for root window */
view->attribFlags = CWEventMask|CWBitGravity;
view->attribs = defAtts;
view->attribFlags |= CWBackPixel|CWColormap;
view->attribs.background_pixel = W_PIXEL(screen->gray);
view->attribs.colormap = screen->colormap;
adoptChildView(parent, view);
}
return view;
}
W_View*
W_CreateView(W_View *parent)
{
return createView(parent->screen, parent);
}
W_View*
W_CreateRootView(W_Screen *screen)
{
W_View *view;
view = createView(screen, NULL);
view->window = screen->rootWin;
view->flags.realized = 1;
view->flags.mapped = 1;
view->flags.root = 1;
view->size.width =
WidthOfScreen(ScreenOfDisplay(screen->display, screen->screen));
view->size.height =
HeightOfScreen(ScreenOfDisplay(screen->display, screen->screen));
return view;
}
W_View*
W_CreateTopView(W_Screen *screen)
{
W_View *view;
view = createView(screen, screen->rootView);
if (!view)
return NULL;
view->flags.topLevel = 1;
view->attribs.event_mask |= StructureNotifyMask;
/* catch changes in the toplevel window (resize from user etc.) */
WMCreateEventHandler(view, StructureNotifyMask, handleEvents, view);
return view;
}
void
W_RealizeView(W_View *view)
{
Window parentWID;
Display *dpy = view->screen->display;
W_View *ptr;
assert(view->size.width > 0);
assert(view->size.height > 0);
if (view->parent && !view->parent->flags.realized) {
wwarning("trying to realize widget of unrealized parent");
return;
}
if (!view->flags.realized) {
parentWID = view->parent->window;
view->window = XCreateWindow(dpy, parentWID, view->pos.x, view->pos.y,
view->size.width, view->size.height, 0,
view->screen->depth, InputOutput,
view->screen->visual, view->attribFlags,
&view->attribs);
XSaveContext(dpy, view->window, ViewContext, (XPointer)view);
view->flags.realized = 1;
if (view->flags.mapWhenRealized) {
W_MapView(view);
view->flags.mapWhenRealized = 0;
}
WMPostNotificationName(WMViewRealizedNotification, view, NULL);
}
/* realize children */
ptr = view->childrenList;
while (ptr!=NULL) {
W_RealizeView(ptr);
ptr = ptr->nextSister;
}
}
Bool
W_CheckInternalMessage(W_Screen *scr, XClientMessageEvent *cev, int event)
{
if (cev->message_type == scr->internalMessage
&& cev->format == 32 && cev->data.l[1] == event)
return True;
else
return False;
}
void
W_ReparentView(W_View *view, W_View *newParent)
{
int wasMapped;
Display *dpy = view->screen->display;
assert(!view->flags.topLevel);
wasMapped = view->flags.mapped;
if (wasMapped)
W_UnmapView(view);
unparentView(view);
adoptChildView(newParent, view);
if (view->flags.realized) {
if (newParent->flags.realized) {
XReparentWindow(dpy, view->window, newParent->window, 0, 0);
} else {
wwarning("trying to reparent realized view to unrealized parent");
return;
}
}
view->pos.x = 0;
view->pos.y = 0;
if (wasMapped)
W_MapView(view);
}
void
W_MapView(W_View *view)
{
if (!view->flags.mapped) {
if (view->flags.realized) {
XMapRaised(view->screen->display, view->window);
XFlush(view->screen->display);
view->flags.mapped = 1;
} else {
view->flags.mapWhenRealized = 1;
}
}
}
/*
* W_MapSubviews-
* maps all children of the current view that where already realized.
*/
void
W_MapSubviews(W_View *view)
{
XMapSubwindows(view->screen->display, view->window);
XFlush(view->screen->display);
view = view->childrenList;
while (view) {
view->flags.mapped = 1;
view->flags.mapWhenRealized = 0;
view = view->nextSister;
}
}
void
W_UnmapSubviews(W_View *view)
{
XUnmapSubwindows(view->screen->display, view->window);
XFlush(view->screen->display);
view = view->childrenList;
while (view) {
view->flags.mapped = 0;
view->flags.mapWhenRealized = 0;
view = view->nextSister;
}
}
void
W_UnmapView(W_View *view)
{
view->flags.mapWhenRealized = 0;
if (!view->flags.mapped)
return;
XUnmapWindow(view->screen->display, view->window);
XFlush(view->screen->display);
view->flags.mapped = 0;
}
W_View*
W_TopLevelOfView(W_View *view)
{
W_View *toplevel;
for (toplevel=view; !toplevel->flags.topLevel; toplevel=toplevel->parent);
return toplevel;
}
static void
destroyView(W_View *view)
{
W_View *ptr;
if (view->flags.alreadyDead)
return;
view->flags.alreadyDead = 1;
/* Do not leave focus in a inexisting control */
if (W_FocusedViewOfToplevel(W_TopLevelOfView(view))==view)
W_SetFocusOfTopLevel(W_TopLevelOfView(view), NULL);
if (view->flags.topLevel) {
W_FocusInfo *info = view->screen->focusInfo;
/* remove focus information associated to this toplevel */
if (info) {
if (info->toplevel==view) {
view->screen->focusInfo = info->next;
free(info);
} else {
while (info->next) {
if (info->next->toplevel == view)
break;
info = info->next;
}
if (info->next) {
W_FocusInfo *next = info->next->next;
free(info->next);
info->next = next;
}
/* else the toplevel did not have any focused subview */
}
}
}
/* destroy children recursively */
while (view->childrenList!=NULL) {
ptr = view->childrenList;
ptr->flags.parentDying = 1;
W_DestroyView(ptr);
if (ptr == view->childrenList) {
view->childrenList = ptr->nextSister;
ptr->parent = NULL;
}
}
W_CallDestroyHandlers(view);
if (view->flags.realized) {
XDeleteContext(view->screen->display, view->window, ViewContext);
/* if parent is being destroyed, it will die naturaly */
if (!view->flags.parentDying || view->flags.topLevel)
XDestroyWindow(view->screen->display, view->window);
}
/* remove self from parent's children list */
unparentView(view);
W_CleanUpEvents(view);
#if 0
if (view->dragSourceProcs)
free(view->dragSourceProcs);
if (view->dragDestinationProcs)
free(view->dragDestinationProcs);
#endif
free(view);
}
void
W_DestroyView(W_View *view)
{
W_ReleaseView(view);
}
void
W_MoveView(W_View *view, int x, int y)
{
assert(view->flags.root==0);
if (view->pos.x == x && view->pos.y == y)
return;
if (view->flags.realized) {
XMoveWindow(view->screen->display, view->window, x, y);
}
view->pos.x = x;
view->pos.y = y;
}
void
W_ResizeView(W_View *view, unsigned int width, unsigned int height)
{
int shrinked;
assert(width > 0);
assert(height > 0);
if (view->size.width == width && view->size.height == height)
return;
shrinked = width < view->size.width || height < view->size.height;
if (view->flags.realized) {
XResizeWindow(view->screen->display, view->window, width, height);
}
view->size.width = width;
view->size.height = height;
if (view->flags.notifySizeChanged)
WMPostNotificationName(WMViewSizeDidChangeNotification, view, NULL);
}
void
W_RedisplayView(W_View *view)
{
XExposeEvent ev;
if (!view->flags.mapped)
return;
ev.type = Expose;
ev.display = view->screen->display;
ev.window = view->window;
ev.count = 0;
WMHandleEvent((XEvent*)&ev);
}
void
W_SetViewBackgroundColor(W_View *view, WMColor *color)
{
view->attribFlags |= CWBackPixel;
view->attribs.background_pixel = color->color.pixel;
if (view->flags.realized) {
XSetWindowBackground(view->screen->display, view->window,
color->color.pixel);
XClearWindow(view->screen->display, view->window);
}
}
W_View*
W_FocusedViewOfToplevel(W_View *view)
{
WMScreen *scr = view->screen;
W_FocusInfo *info;
for (info = scr->focusInfo; info!=NULL; info = info->next)
if (view == info->toplevel)
break;
if (!info)
return NULL;
return info->focused;
}
void
W_SetFocusOfTopLevel(W_View *toplevel, W_View *view)
{
WMScreen *scr = toplevel->screen;
XEvent event;
W_FocusInfo *info;
for (info = scr->focusInfo; info!=NULL; info = info->next)
if (toplevel == info->toplevel)
break;
if (!info) {
info = wmalloc(sizeof(W_FocusInfo));
info->toplevel = toplevel;
info->focused = view;
info->next = scr->focusInfo;
scr->focusInfo = info;
} else {
event.xfocus.mode = NotifyNormal;
event.xfocus.detail = NotifyDetailNone;
if (info->focused) {
/* simulate FocusOut event */
event.xfocus.type = FocusOut;
W_DispatchMessage(info->focused, &event);
}
info->focused = view;
}
if (view) {
/* simulate FocusIn event */
event.xfocus.type = FocusIn;
W_DispatchMessage(view, &event);
}
}
void
W_BroadcastMessage(W_View *targetParent, XEvent *event)
{
W_View *target;
target = targetParent->childrenList;
while (target!=NULL) {
W_DispatchMessage(target, event);
target = target->nextSister;
}
}
void
W_DispatchMessage(W_View *target, XEvent *event)
{
if (target->window==None)
return;
event->xclient.window = target->window;
event->xclient.display = target->screen->display;
WMHandleEvent(event);
/*
XSendEvent(target->screen->display, target->window, False,
SubstructureNotifyMask, event);
*/
}
WMView*
W_RetainView(WMView *view)
{
view->refCount++;
return view;
}
void
W_ReleaseView(WMView *view)
{
view->refCount--;
if (view->refCount < 1) {
destroyView(view);
}
}
WMWidget*
WMWidgetOfView(WMView *view)
{
return view->self;
}
WMSize
WMGetViewSize(WMView *view)
{
return view->size;
}
WMPoint
WMGetViewPosition(WMView *view)
{
return view->pos;
}
void
WMSetViewNotifySizeChanges(WMView *view, Bool flag)
{
view->flags.notifySizeChanged = flag;
}
Window
WMViewXID(WMView *view)
{
return view->window;
}

646
WINGs/wwindow.c Normal file
View File

@@ -0,0 +1,646 @@
#include <X11/Xmd.h>
#include "WINGsP.h"
#include <X11/Xatom.h>
typedef struct W_Window {
W_Class widgetClass;
W_View *view;
struct W_Window *nextPtr; /* next in the window list */
struct W_Window *owner;
char *title;
WMPixmap *miniImage; /* miniwindow */
char *miniTitle;
char *wname;
WMSize resizeIncrement;
WMSize baseSize;
WMSize minSize;
WMSize maxSize;
WMAction *closeAction;
void *closeData;
int level;
struct {
unsigned style:4;
unsigned configured:1;
unsigned documentEdited:1;
unsigned moved:1;
} flags;
} _Window;
typedef struct {
CARD32 flags;
CARD32 window_style;
CARD32 window_level;
CARD32 reserved;
Pixmap miniaturize_pixmap; /* pixmap for miniaturize button */
Pixmap close_pixmap; /* pixmap for close button */
Pixmap miniaturize_mask; /* miniaturize pixmap mask */
Pixmap close_mask; /* close pixmap mask */
CARD32 extra_flags;
} GNUstepWMAttributes;
#define GSWindowStyleAttr (1<<0)
#define GSWindowLevelAttr (1<<1)
#define GSMiniaturizePixmapAttr (1<<3)
#define GSClosePixmapAttr (1<<4)
#define GSMiniaturizeMaskAttr (1<<5)
#define GSCloseMaskAttr (1<<6)
#define GSExtraFlagsAttr (1<<7)
/* extra flags */
#define GSDocumentEditedFlag (1<<0)
#define GSNoApplicationIconFlag (1<<5)
#define WMFHideOtherApplications 10
#define WMFHideApplication 12
static void resizeWindow(WMWidget *, unsigned, unsigned);
static void moveWindow(WMWidget *, int, int);
struct W_ViewProcedureTable _WindowViewProcedures = {
NULL,
resizeWindow,
moveWindow
};
#define DEFAULT_WIDTH 400
#define DEFAULT_HEIGHT 180
#define DEFAULT_TITLE ""
static void destroyWindow(_Window *win);
static void handleEvents();
static void realizeWindow();
static void
realizeObserver(void *self, WMNotification *not)
{
realizeWindow(self);
}
WMWindow*
WMCreatePanelWithStyleForWindow(WMWindow *owner, char *name, int style)
{
WMWindow *win;
win = WMCreateWindowWithStyle(owner->view->screen, name, style);
win->owner = owner;
return win;
}
WMWindow*
WMCreatePanelForWindow(WMWindow *owner, char *name)
{
return WMCreatePanelWithStyleForWindow(owner, name,
WMTitledWindowMask
|WMClosableWindowMask
|WMResizableWindowMask);
}
void
WMChangePanelOwner(WMWindow *win, WMWindow *newOwner)
{
win->owner = newOwner;
if (win->view->flags.realized && newOwner) {
XSetTransientForHint(win->view->screen->display, win->view->window,
newOwner->view->window);
}
}
WMWindow*
WMCreateWindow(WMScreen *screen, char *name)
{
return WMCreateWindowWithStyle(screen, name, WMTitledWindowMask
|WMClosableWindowMask
|WMMiniaturizableWindowMask
|WMResizableWindowMask);
}
WMWindow*
WMCreateWindowWithStyle(WMScreen *screen, char *name, int style)
{
_Window *win;
static int initedApp = 0;
win = wmalloc(sizeof(_Window));
memset(win, 0, sizeof(_Window));
win->widgetClass = WC_Window;
win->view = W_CreateTopView(screen);
if (!win->view) {
free(win);
return NULL;
}
win->view->self = win;
win->wname = wstrdup(name);
/* add to the window list of the screen (application) */
win->nextPtr = screen->windowList;
screen->windowList = win;
WMCreateEventHandler(win->view, ExposureMask|StructureNotifyMask
|ClientMessageMask|FocusChangeMask, handleEvents,
win);
W_ResizeView(win->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
if (!initedApp) {
W_InitApplication(screen);
initedApp = 1;
}
WMAddNotificationObserver(realizeObserver, win,
WMViewRealizedNotification, win->view);
win->flags.style = style;
win->level = WMNormalWindowLevel;
/* kluge. Find a better solution */
W_SetFocusOfTopLevel(win->view, win->view);
return win;
}
void
WMSetWindowTitle(WMWindow *win, char *title)
{
if (win->title!=NULL)
free(win->title);
if (title!=NULL)
win->title = wstrdup(title);
else
win->title = NULL;
if (win->view->flags.realized) {
XStoreName(win->view->screen->display, win->view->window, title);
}
}
void
WMSetWindowCloseAction(WMWindow *win, WMAction *action, void *clientData)
{
Atom *atoms = NULL;
Atom *newAtoms;
int count;
WMScreen *scr = win->view->screen;
if (win->view->flags.realized) {
if (action && !win->closeAction) {
if (!XGetWMProtocols(scr->display, win->view->window, &atoms,
&count)) {
count = 0;
}
newAtoms = wmalloc((count+1)*sizeof(Atom));
if (count > 0)
memcpy(newAtoms, atoms, count*sizeof(Atom));
newAtoms[count++] = scr->deleteWindowAtom;
XSetWMProtocols(scr->display, win->view->window, newAtoms, count);
if (atoms)
XFree(atoms);
free(newAtoms);
} else if (!action && win->closeAction) {
int i, ncount;
if (XGetWMProtocols(scr->display, win->view->window, &atoms,
&count) && count>0) {
newAtoms = wmalloc((count-1)*sizeof(Atom));
ncount = 0;
for (i=0; i < count; i++) {
if (atoms[i]!=scr->deleteWindowAtom) {
newAtoms[i] = atoms[i];
ncount++;
}
}
XSetWMProtocols(scr->display, win->view->window, newAtoms,
ncount);
if (atoms)
XFree(atoms);
free(newAtoms);
}
}
}
win->closeAction = action;
win->closeData = clientData;
}
static void
moveWindow(WMWidget *w, int x, int y)
{
((WMWindow*)w)->flags.moved = 1;
W_MoveView(W_VIEW(w), x, y);
}
static void
resizeWindow(WMWidget *w, unsigned width, unsigned height)
{
WMWindow *win = (WMWindow*)w;
if (win->minSize.width > 0 && win->minSize.height > 0) {
if (width < win->minSize.width)
width = win->minSize.width;
if (height < win->minSize.height)
height = win->minSize.height;
}
if (win->maxSize.width > 0 && win->maxSize.height > 0) {
if (width > win->maxSize.width)
width = win->maxSize.width;
if (height > win->maxSize.height)
height = win->maxSize.height;
}
W_ResizeView(win->view, width, height);
}
static void
setSizeHints(WMWindow *win)
{
XSizeHints *hints;
hints = XAllocSizeHints();
if (!hints) {
wwarning("could not allocate memory for window size hints");
return;
}
hints->flags = 0;
if (win->minSize.width>0 && win->minSize.height>0) {
hints->flags |= PMinSize;
hints->min_width = win->minSize.width;
hints->min_height = win->minSize.height;
}
if (win->maxSize.width>0 && win->maxSize.height>0) {
hints->flags |= PMaxSize;
hints->max_width = win->maxSize.width;
hints->max_height = win->maxSize.height;
}
if (win->baseSize.width>0 && win->baseSize.height>0) {
hints->flags |= PBaseSize;
hints->base_width = win->baseSize.width;
hints->base_height = win->baseSize.height;
}
if (win->resizeIncrement.width>0 && win->resizeIncrement.height>0) {
hints->flags |= PResizeInc;
hints->width_inc = win->resizeIncrement.width;
hints->height_inc = win->resizeIncrement.height;
}
if (hints->flags) {
XSetWMNormalHints(win->view->screen->display, win->view->window, hints);
}
XFree(hints);
}
static void
writeGNUstepWMAttr(WMScreen *scr, Window window, GNUstepWMAttributes *attr)
{
CARD32 data[9];
/* handle idiot compilers where array of CARD32 != struct of CARD32 */
data[0] = attr->flags;
data[1] = attr->window_style;
data[2] = attr->window_level;
data[3] = 0; /* reserved */
/* The X protocol says XIDs are 32bit */
data[4] = attr->miniaturize_pixmap;
data[5] = attr->close_pixmap;
data[6] = attr->miniaturize_mask;
data[7] = attr->close_mask;
data[8] = attr->extra_flags;
XChangeProperty(scr->display, window, scr->attribsAtom, scr->attribsAtom,
32, PropModeReplace, (unsigned char *)data, 9);
}
static void
setWindowMakerHints(WMWindow *win)
{
GNUstepWMAttributes attribs;
WMScreen *scr = WMWidgetScreen(win);
memset(&attribs, 0, sizeof(GNUstepWMAttributes));
attribs.flags = GSWindowStyleAttr|GSWindowLevelAttr|GSExtraFlagsAttr;
attribs.window_style = win->flags.style;
attribs.window_level = win->level;
if (win->flags.documentEdited)
attribs.extra_flags = GSDocumentEditedFlag;
else
attribs.extra_flags = 0;
writeGNUstepWMAttr(scr, win->view->window, &attribs);
}
static void
realizeWindow(WMWindow *win)
{
XWMHints *hints;
XClassHint *classHint;
WMScreen *scr = win->view->screen;
Atom atoms[4];
int count;
if (!win->flags.moved && win->owner!=NULL) {
W_MoveView(win->view,
(scr->rootView->size.width-win->view->size.width)/2,
(scr->rootView->size.height-win->view->size.height)/2);
}
classHint = XAllocClassHint();
classHint->res_name = win->wname;
classHint->res_class = WMGetApplicationName();
XSetClassHint(scr->display, win->view->window, classHint);
XFree(classHint);
hints = XAllocWMHints();
hints->flags = 0;
if (!scr->aflags.simpleApplication) {
hints->flags |= WindowGroupHint;
hints->window_group = scr->groupLeader;
}
if (win->miniImage) {
hints->flags |= IconPixmapHint;
hints->icon_pixmap = WMGetPixmapXID(win->miniImage);
hints->icon_mask = WMGetPixmapMaskXID(win->miniImage);
if (hints->icon_mask != None) {
hints->flags |= IconMaskHint;
}
}
if (hints->flags != 0)
XSetWMHints(scr->display, win->view->window, hints);
XFree(hints);
count = 0;
if (win->closeAction) {
atoms[count++] = scr->deleteWindowAtom;
}
if (count>0)
XSetWMProtocols(scr->display, win->view->window, atoms, count);
if (win->title)
XStoreName(scr->display, win->view->window, win->title);
if (win->miniTitle)
XSetIconName(scr->display, win->view->window, win->miniTitle);
setWindowMakerHints(win);
setSizeHints(win);
if (win->owner) {
XSetTransientForHint(scr->display, win->view->window,
win->owner->view->window);
}
}
void
WMHideWindow(WMWindow *win)
{
WMUnmapWidget(win);
XWithdrawWindow(win->view->screen->display, win->view->window,
win->view->screen->screen);
}
void
WMSetWindowMinSize(WMWindow *win, unsigned width, unsigned height)
{
win->minSize.width = width;
win->minSize.height = height;
if (win->view->flags.realized)
setSizeHints(win);
}
void
WMSetWindowMaxSize(WMWindow *win, unsigned width, unsigned height)
{
win->maxSize.width = width;
win->maxSize.height = height;
if (win->view->flags.realized)
setSizeHints(win);
}
void
WMSetWindowBaseSize(WMWindow *win, unsigned width, unsigned height)
{
/* TODO: validate sizes */
win->baseSize.width = width;
win->baseSize.height = height;
if (win->view->flags.realized)
setSizeHints(win);
}
void
WMSetWindowResizeIncrements(WMWindow *win, unsigned wIncr, unsigned hIncr)
{
win->resizeIncrement.width = wIncr;
win->resizeIncrement.height = hIncr;
if (win->view->flags.realized)
setSizeHints(win);
}
void
WMSetWindowLevel(WMWindow *win, int level)
{
win->level = level;
if (win->view->flags.realized)
setWindowMakerHints(win);
}
void
WMSetWindowDocumentEdited(WMWindow *win, Bool flag)
{
if (win->flags.documentEdited != flag) {
win->flags.documentEdited = flag;
if (win->view->flags.realized)
setWindowMakerHints(win);
}
}
void
WMSetWindowMiniwindowImage(WMWindow *win, WMPixmap *pixmap)
{
if ((win->miniImage && !pixmap) || (!win->miniImage && pixmap)) {
if (win->miniImage)
WMReleasePixmap(win->miniImage);
if (pixmap)
win->miniImage = WMRetainPixmap(pixmap);
else
win->miniImage = NULL;
if (win->view->flags.realized) {
XWMHints *hints;
hints = XGetWMHints(win->view->screen->display, win->view->window);
if (!hints) {
hints = XAllocWMHints();
if (!hints) {
wwarning("could not allocate memory for WM hints");
return;
}
hints->flags = 0;
}
if (pixmap) {
hints->flags |= IconPixmapHint;
hints->icon_pixmap = WMGetPixmapXID(pixmap);
hints->icon_mask = WMGetPixmapMaskXID(pixmap);
if (hints->icon_mask != None) {
hints->flags |= IconMaskHint;
}
}
XSetWMHints(win->view->screen->display, win->view->window, hints);
XFree(hints);
}
}
}
void
WMSetWindowMiniwindowTitle(WMWindow *win, char *title)
{
if ((win->miniTitle && !title) || (!win->miniTitle && title)
|| (title && win->miniTitle && strcoll(title, win->miniTitle)!=0)) {
if (win->miniTitle)
free(win->miniTitle);
if (title)
win->miniTitle = wstrdup(title);
else
win->miniTitle = NULL;
if (win->view->flags.realized) {
XSetIconName(win->view->screen->display, win->view->window, title);
}
}
}
void
WMCloseWindow(WMWindow *win)
{
/* withdraw the window */
if (win->view->flags.realized)
XWithdrawWindow(win->view->screen->display, win->view->window,
win->view->screen->screen);
}
static void
handleEvents(XEvent *event, void *clientData)
{
_Window *win = (_Window*)clientData;
switch (event->type) {
case ClientMessage:
if (event->xclient.message_type == win->view->screen->protocolsAtom
&& event->xclient.format == 32
&& event->xclient.data.l[0]==win->view->screen->deleteWindowAtom) {
if (win->closeAction) {
(*win->closeAction)(win, win->closeData);
}
}
break;
case DestroyNotify:
destroyWindow(win);
break;
}
}
static void
destroyWindow(_Window *win)
{
WMScreen *scr = win->view->screen;
WMRemoveNotificationObserver(win);
if (scr->windowList == win) {
scr->windowList = scr->windowList->nextPtr;
} else {
WMWindow *ptr;
ptr = scr->windowList;
while (ptr->nextPtr) {
if (ptr->nextPtr==win) {
ptr->nextPtr = ptr->nextPtr->nextPtr;
break;
}
ptr = ptr->nextPtr;
}
}
if (win->title) {
free(win->title);
}
if (win->miniTitle) {
free(win->miniTitle);
}
if (win->miniImage) {
WMReleasePixmap(win->miniImage);
}
if (win->wname)
free(win->wname);
free(win);
}

458
WPrefs.app/Configurations.c Normal file
View File

@@ -0,0 +1,458 @@
/* Configurations.c- misc. configurations
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *icoF;
WMButton *icoB[5];
WMFrame *shaF;
WMButton *shaB[5];
WMFrame *titlF;
WMButton *oldsB;
WMButton *newsB;
WMFrame *animF;
WMButton *animB;
WMButton *supB;
WMButton *sfxB;
WMLabel *noteL;
WMFrame *dithF;
WMButton *dithB;
WMSlider *dithS;
WMLabel *dithL;
WMLabel *dith1L;
WMLabel *dith2L;
int cmapSize;
} _Panel;
#define ICON_FILE "configs"
#define OLDS_IMAGE "oldstyle"
#define NEWS_IMAGE "newstyle"
#define ANIM_IMAGE "animations"
#define SUPERF_IMAGE "moreanim"
#define SOUND_IMAGE "sound"
#define SPEED_IMAGE "speed%i"
#define SPEED_IMAGE_S "speed%is"
#define ARQUIVO_XIS "xis"
static void updateLabel(WMWidget *self, void *data);
static void
showData(_Panel *panel)
{
WMPerformButtonClick(panel->icoB[GetSpeedForKey("IconSlideSpeed")]);
WMPerformButtonClick(panel->shaB[GetSpeedForKey("ShadeSpeed")]);
if (GetBoolForKey("NewStyle")) {
WMPerformButtonClick(panel->newsB);
} else {
WMPerformButtonClick(panel->oldsB);
}
WMSetButtonSelected(panel->animB, !GetBoolForKey("DisableAnimations"));
WMSetButtonSelected(panel->supB, GetBoolForKey("Superfluous"));
WMSetButtonSelected(panel->sfxB, !GetBoolForKey("DisableSound"));
WMSetButtonSelected(panel->dithB, GetBoolForKey("DisableDithering"));
WMSetSliderValue(panel->dithS, GetIntegerForKey("ColormapSize"));
updateLabel(panel->dithS, panel);
}
static void
updateLabel(WMWidget *self, void *data)
{
WMSlider *sPtr = (WMSlider*)self;
_Panel *panel = (_Panel*)data;
char buffer[64];
float fl;
fl = WMGetSliderValue(sPtr);
panel->cmapSize = (int)fl;
sprintf(buffer, "%i", panel->cmapSize*panel->cmapSize*panel->cmapSize);
WMSetLabelText(panel->dithL, buffer);
}
static void
createImages(WMScreen *scr, RContext *rc, RImage *xis, char *file,
WMPixmap **icon1, WMPixmap **icon2)
{
RImage *icon;
char *path;
*icon1 = NULL;
*icon2 = NULL;
path = LocateImage(file);
if (!path) {
return;
}
*icon1 = WMCreatePixmapFromFile(scr, path);
if (!*icon1) {
wwarning(_("could not load icon %s"), path);
free(path);
return;
}
icon = RLoadImage(rc, path, 0);
if (!icon) {
wwarning(_("could not load icon %s"), path);
free(path);
return;
}
if (xis) {
RCombineImages(icon, xis);
if (!(*icon2 = WMCreatePixmapFromRImage(scr, icon, 127)))
wwarning(_("could not process icon %s:"), file, RErrorString);
}
RDestroyImage(icon);
free(path);
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
char *buf1, *buf2;
WMPixmap *icon, *altIcon;
RImage *xis = NULL;
int i;
RContext *rc = WMScreenRContext(scr);
WMFont *font = WMSystemFontOfSize(scr, 10);
char *path;
path = LocateImage(ARQUIVO_XIS);
if (path) {
xis = RLoadImage(rc, path, 0);
if (!xis) {
wwarning(_("could not load image file %s"), path);
}
free(path);
}
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/*********** Icon Slide Speed **********/
panel->icoF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->icoF, 230, 55);
WMMoveWidget(panel->icoF, 15, 10);
WMSetFrameTitle(panel->icoF, _("Icon Slide Speed"));
/*********** Shade Animation Speed **********/
panel->shaF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->shaF, 230, 55);
WMMoveWidget(panel->shaF, 15, 70);
WMSetFrameTitle(panel->shaF, _("Shade Animation Speed"));
buf1 = wmalloc(strlen(SPEED_IMAGE)+1);
buf2 = wmalloc(strlen(SPEED_IMAGE_S)+1);
for (i = 0; i < 5; i++) {
panel->icoB[i] = WMCreateCustomButton(panel->icoF, WBBStateChangeMask);
panel->shaB[i] = WMCreateCustomButton(panel->shaF, WBBStateChangeMask);
WMResizeWidget(panel->icoB[i], 40, 35);
WMMoveWidget(panel->icoB[i], 10+(40*i), 15);
WMResizeWidget(panel->shaB[i], 40, 35);
WMMoveWidget(panel->shaB[i], 10+(40*i), 15);
WMSetButtonBordered(panel->icoB[i], False);
WMSetButtonImagePosition(panel->icoB[i], WIPImageOnly);
if (i > 0) {
WMGroupButtons(panel->icoB[0], panel->icoB[i]);
}
WMSetButtonBordered(panel->shaB[i], False);
WMSetButtonImagePosition(panel->shaB[i], WIPImageOnly);
if (i > 0) {
WMGroupButtons(panel->shaB[0], panel->shaB[i]);
}
sprintf(buf1, SPEED_IMAGE, i);
sprintf(buf2, SPEED_IMAGE_S, i);
path = LocateImage(buf1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->icoB[i], icon);
WMSetButtonImage(panel->shaB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
path = LocateImage(buf2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonAltImage(panel->icoB[i], icon);
WMSetButtonAltImage(panel->shaB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
}
free(buf1);
free(buf2);
WMMapSubwidgets(panel->icoF);
WMMapSubwidgets(panel->shaF);
/***************** Titlebar Style Size ****************/
panel->titlF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->titlF, 230, 95);
WMMoveWidget(panel->titlF, 15, 130);
WMSetFrameTitle(panel->titlF, _("Titlebar Style"));
panel->newsB = WMCreateButton(panel->titlF, WBTOnOff);
WMResizeWidget(panel->newsB, 90, 60);
WMMoveWidget(panel->newsB, 25, 20);
WMSetButtonImagePosition(panel->newsB, WIPImageOnly);
path = LocateImage(NEWS_IMAGE);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->newsB, icon);
WMReleasePixmap(icon);
}
}
panel->oldsB = WMCreateButton(panel->titlF, WBTOnOff);
WMResizeWidget(panel->oldsB, 90, 60);
WMMoveWidget(panel->oldsB, 115, 20);
WMSetButtonImagePosition(panel->oldsB, WIPImageOnly);
path = LocateImage(OLDS_IMAGE);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->oldsB, icon);
WMReleasePixmap(icon);
}
}
WMGroupButtons(panel->newsB, panel->oldsB);
WMMapSubwidgets(panel->titlF);
/**************** Features ******************/
panel->animF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->animF, 255, 115);
WMMoveWidget(panel->animF, 255, 10);
WMSetFrameTitle(panel->animF, _("Animations and Sound"));
panel->animB = WMCreateButton(panel->animF, WBTToggle);
WMResizeWidget(panel->animB, 64, 64);
WMMoveWidget(panel->animB, 15, 20);
WMSetButtonFont(panel->animB, font);
WMSetButtonText(panel->animB, _("Animations"));
WMSetButtonImagePosition(panel->animB, WIPAbove);
createImages(scr, rc, xis, ANIM_IMAGE, &altIcon, &icon);
if (icon) {
WMSetButtonImage(panel->animB, icon);
WMReleasePixmap(icon);
}
if (altIcon) {
WMSetButtonAltImage(panel->animB, altIcon);
WMReleasePixmap(altIcon);
}
panel->supB = WMCreateButton(panel->animF, WBTToggle);
WMResizeWidget(panel->supB, 64, 64);
WMMoveWidget(panel->supB, 95, 20);
WMSetButtonFont(panel->supB, font);
WMSetButtonText(panel->supB, _("Superfluous"));
WMSetButtonImagePosition(panel->supB, WIPAbove);
createImages(scr, rc, xis, SUPERF_IMAGE, &altIcon, &icon);
if (icon) {
WMSetButtonImage(panel->supB, icon);
WMReleasePixmap(icon);
}
if (altIcon) {
WMSetButtonAltImage(panel->supB, altIcon);
WMReleasePixmap(altIcon);
}
panel->sfxB = WMCreateButton(panel->animF, WBTToggle);
WMResizeWidget(panel->sfxB, 64, 64);
WMMoveWidget(panel->sfxB, 175, 20);
WMSetButtonFont(panel->sfxB, font);
WMSetButtonText(panel->sfxB, _("Sounds"));
WMSetButtonImagePosition(panel->sfxB, WIPAbove);
createImages(scr, rc, xis, SOUND_IMAGE, &altIcon, &icon);
if (icon) {
WMSetButtonImage(panel->sfxB, icon);
WMReleasePixmap(icon);
}
if (altIcon) {
WMSetButtonAltImage(panel->sfxB, altIcon);
WMReleasePixmap(altIcon);
}
panel->noteL = WMCreateLabel(panel->animF);
WMResizeWidget(panel->noteL, 235, 28);
WMMoveWidget(panel->noteL, 10, 85);
WMSetLabelFont(panel->noteL, font);
WMSetLabelText(panel->noteL, _("Note: sound requires a module distributed separately"));
WMMapSubwidgets(panel->animF);
/*********** Dithering **********/
panel->cmapSize = 4;
panel->dithF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->dithF, 255, 95);
WMMoveWidget(panel->dithF, 255, 130);
WMSetFrameTitle(panel->dithF, _("Dithering colormap for 8bpp"));
panel->dithB = WMCreateSwitchButton(panel->dithF);
WMResizeWidget(panel->dithB, 235, 32);
WMMoveWidget(panel->dithB, 15, 15);
WMSetButtonText(panel->dithB, _("Disable dithering in any visual/depth"));
panel->dithL = WMCreateLabel(panel->dithF);
WMResizeWidget(panel->dithL, 75, 16);
WMMoveWidget(panel->dithL, 90, 50);
WMSetLabelTextAlignment(panel->dithL, WACenter);
WMSetLabelText(panel->dithL, "64");
panel->dithS = WMCreateSlider(panel->dithF);
WMResizeWidget(panel->dithS, 95, 16);
WMMoveWidget(panel->dithS, 80, 65);
WMSetSliderMinValue(panel->dithS, 2);
WMSetSliderMaxValue(panel->dithS, 6);
WMSetSliderContinuous(panel->dithS, True);
WMSetSliderAction(panel->dithS, updateLabel, panel);
panel->dith1L = WMCreateLabel(panel->dithF);
WMResizeWidget(panel->dith1L, 70, 35);
WMMoveWidget(panel->dith1L, 5, 50);
WMSetLabelTextAlignment(panel->dith1L, WACenter);
WMSetLabelFont(panel->dith1L, font);
WMSetLabelText(panel->dith1L, _("More colors for applications"));
panel->dith2L = WMCreateLabel(panel->dithF);
WMResizeWidget(panel->dith2L, 70, 35);
WMMoveWidget(panel->dith2L, 180, 50);
WMSetLabelTextAlignment(panel->dith2L, WACenter);
WMSetLabelFont(panel->dith2L, font);
WMSetLabelText(panel->dith2L, _("More colors for WindowMaker"));
WMMapSubwidgets(panel->dithF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
if (xis)
RDestroyImage(xis);
WMReleaseFont(font);
showData(panel);
}
static void
storeData(_Panel *panel)
{
int i;
for (i=0; i<5; i++) {
if (WMGetButtonSelected(panel->icoB[i]))
break;
}
SetSpeedForKey(i, "IconSlideSpeed");
for (i=0; i<5; i++) {
if (WMGetButtonSelected(panel->shaB[i]))
break;
}
SetSpeedForKey(i, "ShadeSpeed");
SetBoolForKey(WMGetButtonSelected(panel->newsB), "NewStyle");
SetBoolForKey(!WMGetButtonSelected(panel->animB), "DisableAnimations");
SetBoolForKey(WMGetButtonSelected(panel->supB), "Superfluous");
SetBoolForKey(!WMGetButtonSelected(panel->sfxB), "DisableSound");
SetBoolForKey(WMGetButtonSelected(panel->dithB), "DisableDithering");
SetIntegerForKey(WMGetSliderValue(panel->dithS), "ColormapSize");
}
Panel*
InitConfigurations(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Other Configurations");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

113
WPrefs.app/Expert.c Normal file
View File

@@ -0,0 +1,113 @@
/* Expert.c- expert user options
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMButton *swi[4];
} _Panel;
#define ICON_FILE "expert"
static void
showData(_Panel *panel)
{
WMUserDefaults *udb = WMGetStandardUserDefaults();
WMSetButtonSelected(panel->swi[0], WMGetUDBoolForKey(udb, "NoXSetStuff"));
WMSetButtonSelected(panel->swi[1], GetBoolForKey("SaveSessionOnExit"));
WMSetButtonSelected(panel->swi[2], GetBoolForKey("UseSaveUnders"));
WMSetButtonSelected(panel->swi[3], GetBoolForKey("DisableBlinking"));
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
int i;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
for (i=0; i<4; i++) {
panel->swi[i] = WMCreateSwitchButton(panel->frame);
WMResizeWidget(panel->swi[i], FRAME_WIDTH-40, 25);
WMMoveWidget(panel->swi[i], 20, 20+i*25);
}
WMSetButtonText(panel->swi[0], _("Do not set non-WindowMaker specific parameters (do not use xset)"));
WMSetButtonText(panel->swi[1], _("Automatically save session when exiting WindowMaker"));
WMSetButtonText(panel->swi[2], _("Use SaveUnder in window frames, icons, menus and other objects"));
WMSetButtonText(panel->swi[3], _("Disable cycling color highlighting of icons."));
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
static void
storeDefaults(_Panel *panel)
{
WMUserDefaults *udb = WMGetStandardUserDefaults();
WMSetUDBoolForKey(udb, WMGetButtonSelected(panel->swi[0]), "NoXSetStuff");
SetBoolForKey(WMGetButtonSelected(panel->swi[1]), "SaveSessionOnExit");
SetBoolForKey(WMGetButtonSelected(panel->swi[2]), "UseSaveUnders");
SetBoolForKey(WMGetButtonSelected(panel->swi[3]), "DisableBlinking");
}
Panel*
InitExpert(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Expert User Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeDefaults;
AddSection(panel, ICON_FILE);
return panel;
}

395
WPrefs.app/Focus.c Normal file
View File

@@ -0,0 +1,395 @@
/* Focus.c- input and colormap focus stuff
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *kfocF;
WMPopUpButton *kfocP;
WMLabel *kfocL;
WMFrame *cfocF;
WMButton *autB;
WMButton *manB;
WMFrame *raisF;
WMButton *raisB[5];
WMTextField *raisT;
WMLabel *raisL;
WMFrame *optF;
WMButton *ignB;
WMButton *newB;
char raiseDelaySelected;
} _Panel;
#define ICON_FILE "windowfocus"
#define DELAY_ICON "timer%i"
#define DELAY_ICON_S "timer%is"
static void changeFocusMode(WMWidget *w, void *data);
static void
showData(_Panel *panel)
{
char *str;
int i;
char buffer[32];
str = GetStringForKey("FocusMode");
if (strcasecmp(str, "manual")==0 || strcasecmp(str, "clicktofocus")==0)
WMSetPopUpButtonSelectedItem(panel->kfocP, 0);
else if (strcasecmp(str, "auto")==0 || strcasecmp(str, "focusfollowsmouse")==0)
WMSetPopUpButtonSelectedItem(panel->kfocP, 1);
else if (strcasecmp(str, "semiauto")==0 || strcasecmp(str, "sloppy")==0)
WMSetPopUpButtonSelectedItem(panel->kfocP, 2);
else {
wwarning(_("bad option value %s for option FocusMode. Using default Manual"),
str);
WMSetPopUpButtonSelectedItem(panel->kfocP, 0);
}
changeFocusMode(panel->kfocP, panel);
/**/
str = GetStringForKey("ColormapMode");
if (strcasecmp(str, "manual")==0 || strcasecmp(str, "clicktofocus")==0) {
WMPerformButtonClick(panel->manB);
} else if (strcasecmp(str, "auto")==0 || strcasecmp(str, "focusfollowsmouse")==0) {
WMPerformButtonClick(panel->autB);
} else {
wwarning(_("bad option value %s for option ColormapMode. Using default Manual"),
str);
WMPerformButtonClick(panel->manB);
}
/**/
i = GetIntegerForKey("RaiseDelay");
sprintf(buffer, "%i", i);
WMSetTextFieldText(panel->raisT, buffer);
switch (i) {
case 0:
WMPerformButtonClick(panel->raisB[0]);
break;
case 10:
WMPerformButtonClick(panel->raisB[1]);
break;
case 100:
WMPerformButtonClick(panel->raisB[2]);
break;
case 350:
WMPerformButtonClick(panel->raisB[3]);
break;
case 800:
WMPerformButtonClick(panel->raisB[4]);
break;
}
/**/
WMSetButtonSelected(panel->ignB, GetBoolForKey("IgnoreFocusClick"));
WMSetButtonSelected(panel->newB, GetBoolForKey("AutoFocus"));
}
static void
storeData(_Panel *panel)
{
char *str;
int i;
switch (WMGetPopUpButtonSelectedItem(panel->kfocP)) {
case 1:
str = "auto";
break;
case 2:
str = "sloppy";
break;
default:
str = "manual";
break;
}
SetStringForKey(str, "FocusMode");
if (WMGetButtonSelected(panel->manB)) {
SetStringForKey("manual", "ColormapMode");
} else {
SetStringForKey("auto", "ColormapMode");
}
str = WMGetTextFieldText(panel->raisT);
if (sscanf(str, "%i", &i)!=1)
i = 0;
SetIntegerForKey(i, "RaiseDelay");
SetBoolForKey(WMGetButtonSelected(panel->ignB), "IgnoreFocusClick");
SetBoolForKey(WMGetButtonSelected(panel->newB), "AutoFocus");
}
static void
pushDelayButton(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
panel->raiseDelaySelected = 1;
if (w == panel->raisB[0]) {
WMSetTextFieldText(panel->raisT, "OFF");
} else if (w == panel->raisB[1]) {
WMSetTextFieldText(panel->raisT, "10");
} else if (w == panel->raisB[2]) {
WMSetTextFieldText(panel->raisT, "100");
} else if (w == panel->raisB[3]) {
WMSetTextFieldText(panel->raisT, "350");
} else if (w == panel->raisB[4]) {
WMSetTextFieldText(panel->raisT, "800");
}
}
static void
changeFocusMode(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
switch (WMGetPopUpButtonSelectedItem(w)) {
case 0:
WMSetLabelText(panel->kfocL, _("Click on the window to set\n"\
"keyboard input focus."));
break;
case 1:
WMSetLabelText(panel->kfocL, _("Set keyboard input focus to\n"\
"the window under the mouse pointer,\n"\
"including the root window."));
break;
case 2:
WMSetLabelText(panel->kfocL, _("Set keyboard input focus to\n"\
"the window under the mouse pointer,\n"\
"except the root window."));
break;
}
}
static void
raiseTextChanged(void *observerData, WMNotification *notification)
{
_Panel *panel = (_Panel*)observerData;
int i;
if (panel->raiseDelaySelected) {
for (i=0; i<5; i++) {
WMSetButtonSelected(panel->raisB[i], False);
}
panel->raiseDelaySelected = 0;
}
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
int i;
char *buf1, *buf2;
WMPixmap *icon;
WMColor *color;
WMFont *font;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/***************** Input Focus Mode *****************/
panel->kfocF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->kfocF, 240, 130);
WMMoveWidget(panel->kfocF, 15, 15);
WMSetFrameTitle(panel->kfocF, _("Input Focus Mode"));
panel->kfocP = WMCreatePopUpButton(panel->kfocF);
WMResizeWidget(panel->kfocP, 210, 20);
WMMoveWidget(panel->kfocP, 15, 30);
WMAddPopUpButtonItem(panel->kfocP, _("Click window to focus"));
WMAddPopUpButtonItem(panel->kfocP, _("Focus follows mouse"));
WMAddPopUpButtonItem(panel->kfocP, _("\"Sloppy\" focus"));
WMSetPopUpButtonAction(panel->kfocP, changeFocusMode, panel);
panel->kfocL = WMCreateLabel(panel->kfocF);
WMResizeWidget(panel->kfocL, 211, 68);
WMMoveWidget(panel->kfocL, 15, 55);
WMSetLabelTextAlignment(panel->kfocL, WACenter);
WMMapSubwidgets(panel->kfocF);
/***************** Colormap Installation Mode ****************/
panel->cfocF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->cfocF, 240, 70);
WMMoveWidget(panel->cfocF, 15, 150);
WMSetFrameTitle(panel->cfocF, _("Install colormap in the window..."));
panel->manB = WMCreateRadioButton(panel->cfocF);
WMResizeWidget(panel->manB, 220, 20);
WMMoveWidget(panel->manB, 15, 18);
WMSetButtonText(panel->manB, _("...that has the input focus."));
panel->autB = WMCreateRadioButton(panel->cfocF);
WMResizeWidget(panel->autB, 220, 20);
WMMoveWidget(panel->autB, 15, 40);
WMSetButtonText(panel->autB, _("...that is under the mouse pointer."));
WMGroupButtons(panel->manB, panel->autB);
WMMapSubwidgets(panel->cfocF);
/***************** Automatic window raise delay *****************/
panel->raisF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->raisF, 245, 70);
WMMoveWidget(panel->raisF, 265, 15);
WMSetFrameTitle(panel->raisF, _("Automatic Window Raise Delay"));
buf1 = wmalloc(strlen(DELAY_ICON)+1);
buf2 = wmalloc(strlen(DELAY_ICON_S)+1);
for (i = 0; i < 5; i++) {
char *path;
panel->raisB[i] = WMCreateCustomButton(panel->raisF,
WBBStateChangeMask);
WMResizeWidget(panel->raisB[i], 25, 25);
WMMoveWidget(panel->raisB[i], 10+(30*i), 25);
WMSetButtonBordered(panel->raisB[i], False);
WMSetButtonImagePosition(panel->raisB[i], WIPImageOnly);
WMSetButtonAction(panel->raisB[i], pushDelayButton, panel);
if (i>0)
WMGroupButtons(panel->raisB[0], panel->raisB[i]);
sprintf(buf1, DELAY_ICON, i);
sprintf(buf2, DELAY_ICON_S, i);
path = LocateImage(buf1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->raisB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
path = LocateImage(buf2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonAltImage(panel->raisB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
}
free(buf1);
free(buf2);
panel->raisT = WMCreateTextField(panel->raisF);
WMResizeWidget(panel->raisT, 36, 20);
WMMoveWidget(panel->raisT, 165, 30);
WMAddNotificationObserver(raiseTextChanged, panel,
WMTextDidChangeNotification, panel->raisT);
color = WMDarkGrayColor(scr);
font = WMSystemFontOfSize(scr, 10);
panel->raisL = WMCreateLabel(panel->raisF);
WMResizeWidget(panel->raisL, 36, 16);
WMMoveWidget(panel->raisL, 205, 35);
WMSetLabelText(panel->raisL, _("msec"));
WMSetLabelTextColor(panel->raisL, color);
WMSetLabelFont(panel->raisL, font);
WMReleaseColor(color);
WMReleaseFont(font);
WMMapSubwidgets(panel->raisF);
/***************** Options ****************/
panel->optF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->optF, 245, 125);
WMMoveWidget(panel->optF, 265, 95);
panel->ignB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->ignB, 210, 50);
WMMoveWidget(panel->ignB, 15, 10);
WMSetButtonText(panel->ignB, _("Do not let aplications receive the "\
"click used to focus windows."));
panel->newB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->newB, 210, 35);
WMMoveWidget(panel->newB, 15, 70);
WMSetButtonText(panel->newB, _("Automatically focus new windows."));
WMMapSubwidgets(panel->optF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
Panel*
InitFocus(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Window Focus Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

318
WPrefs.app/Icons.c Normal file
View File

@@ -0,0 +1,318 @@
/* Icons.c- icon preferences
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *posF;
WMFrame *posVF;
WMFrame *posV;
WMButton *nwB;
WMButton *neB;
WMButton *swB;
WMButton *seB;
WMButton *verB;
WMButton *horB;
WMFrame *optF;
WMButton *arrB;
WMButton *omnB;
WMFrame *sizeF;
WMPopUpButton *sizeP;
} _Panel;
#define ICON_FILE "iconprefs"
static void
showIconLayout(WMWidget *widget, void *data)
{
_Panel *panel = (_Panel*)data;
int w, h;
if (WMGetButtonSelected(panel->horB)) {
w = 32;
h = 8;
} else {
w = 8;
h = 32;
}
WMResizeWidget(panel->posV, w, h);
if (WMGetButtonSelected(panel->nwB)) {
WMMoveWidget(panel->posV, 2, 2);
} else if (WMGetButtonSelected(panel->neB)) {
WMMoveWidget(panel->posV, 95-2-w, 2);
} else if (WMGetButtonSelected(panel->swB)) {
WMMoveWidget(panel->posV, 2, 70-2-h);
} else {
WMMoveWidget(panel->posV, 95-2-w, 70-2-h);
}
}
#define MIN(a,b) ((a) < (b) ? (a) : (b))
static void
showData(_Panel *panel)
{
int i;
char *str;
char *def = "blh";
WMSetButtonSelected(panel->arrB, GetBoolForKey("AutoArrangeIcons"));
WMSetButtonSelected(panel->omnB, GetBoolForKey("StickyIcons"));
str = GetStringForKey("IconPosition");
if (!str)
str = def;
if (strlen(str)!=3) {
wwarning("bad value %s for option IconPosition. Using default blh",
str);
str = def;
}
if (str[0]=='t' || str[0]=='T') {
if (str[1]=='r' || str[1]=='R') {
WMPerformButtonClick(panel->neB);
} else {
WMPerformButtonClick(panel->nwB);
}
} else {
if (str[1]=='r' || str[1]=='R') {
WMPerformButtonClick(panel->seB);
} else {
WMPerformButtonClick(panel->swB);
}
}
if (str[2]=='v' || str[2]=='V') {
WMPerformButtonClick(panel->verB);
} else {
WMPerformButtonClick(panel->horB);
}
i = GetIntegerForKey("IconSize");
i = (i-24)/8;
if (i<0)
i = 0;
else if (i>9)
i = 9;
WMSetPopUpButtonSelectedItem(panel->sizeP, i);
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMColor *color;
int i;
char buf[16];
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/***************** Positioning of Icons *****************/
panel->posF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->posF, 475, 135);
WMMoveWidget(panel->posF, 25, 10);
WMSetFrameTitle(panel->posF, _("Icon Positioning"));
panel->nwB = WMCreateRadioButton(panel->posF);
WMResizeWidget(panel->nwB, 110, 20);
WMMoveWidget(panel->nwB, 15, 25);
WMSetButtonImagePosition(panel->nwB, WIPRight);
WMSetButtonTextAlignment(panel->nwB, WARight);
WMSetButtonText(panel->nwB, "Top left");
WMSetButtonAction(panel->nwB, showIconLayout, panel);
panel->neB = WMCreateRadioButton(panel->posF);
WMResizeWidget(panel->neB, 110, 20);
WMMoveWidget(panel->neB, 230, 25);
WMSetButtonImagePosition(panel->neB, WIPLeft);
WMSetButtonTextAlignment(panel->neB, WALeft);
WMSetButtonText(panel->neB, "Top right");
WMSetButtonAction(panel->neB, showIconLayout, panel);
panel->swB = WMCreateRadioButton(panel->posF);
WMResizeWidget(panel->swB, 110, 20);
WMMoveWidget(panel->swB, 15, 95);
WMSetButtonText(panel->swB, "Bottom left");
WMSetButtonTextAlignment(panel->swB, WARight);
WMSetButtonImagePosition(panel->swB, WIPRight);
WMSetButtonAction(panel->swB, showIconLayout, panel);
panel->seB = WMCreateRadioButton(panel->posF);
WMResizeWidget(panel->seB, 110, 20);
WMMoveWidget(panel->seB, 230, 95);
WMSetButtonText(panel->seB, "Bottom right");
WMSetButtonAction(panel->seB, showIconLayout, panel);
WMGroupButtons(panel->nwB, panel->neB);
WMGroupButtons(panel->nwB, panel->seB);
WMGroupButtons(panel->nwB, panel->swB);
color = WMCreateRGBColor(WMWidgetScreen(panel->win), 0x5100, 0x5100,
0x7100, True);
panel->posVF = WMCreateFrame(panel->posF);
WMResizeWidget(panel->posVF, 95, 70);
WMMoveWidget(panel->posVF, 130, 35);
WMSetFrameRelief(panel->posVF, WRSunken);
WMSetWidgetBackgroundColor(panel->posVF, color);
WMReleaseColor(color);
panel->posV = WMCreateFrame(panel->posVF);
WMSetFrameRelief(panel->posV, WRSimple);
panel->verB = WMCreateRadioButton(panel->posF);
WMResizeWidget(panel->verB, 120, 20);
WMMoveWidget(panel->verB, 345, 45);
WMSetButtonText(panel->verB, "Vertical");
WMSetButtonAction(panel->verB, showIconLayout, panel);
panel->horB = WMCreateRadioButton(panel->posF);
WMResizeWidget(panel->horB, 120, 20);
WMMoveWidget(panel->horB, 345, 80);
WMSetButtonText(panel->horB, "Horizontal");
WMSetButtonAction(panel->horB, showIconLayout, panel);
WMGroupButtons(panel->horB, panel->verB);
WMMapSubwidgets(panel->posF);
/***************** Options ****************/
panel->optF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->optF, 260, 65);
WMMoveWidget(panel->optF, 25, 155);
panel->arrB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->arrB, 235, 20);
WMMoveWidget(panel->arrB, 15, 10);
WMSetButtonText(panel->arrB, _("Auto-arrange icons"));
panel->omnB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->omnB, 235, 20);
WMMoveWidget(panel->omnB, 15, 35);
WMSetButtonText(panel->omnB, _("Omnipresent miniwindows"));
WMMapSubwidgets(panel->optF);
/***************** Icon Size ****************/
panel->sizeF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->sizeF, 205, 70);
WMMoveWidget(panel->sizeF, 295, 150);
WMSetFrameTitle(panel->sizeF, _("Icon Size"));
panel->sizeP = WMCreatePopUpButton(panel->sizeF);
WMResizeWidget(panel->sizeP, 156, 20);
WMMoveWidget(panel->sizeP, 25, 30);
for (i=24; i<=96; i+=8) {
sprintf(buf, "%ix%i", i, i);
WMAddPopUpButtonItem(panel->sizeP, buf);
}
WMMapSubwidgets(panel->sizeF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
static void
storeData(_Panel *panel)
{
char buf[8];
SetBoolForKey(WMGetButtonSelected(panel->arrB), "AutoArrangeIcons");
SetBoolForKey(WMGetButtonSelected(panel->omnB), "StickyIcons");
SetIntegerForKey(WMGetPopUpButtonSelectedItem(panel->sizeP)*8+24,
"IconSize");
buf[3] = 0;
if (WMGetButtonSelected(panel->nwB)) {
buf[0] = 't';
buf[1] = 'l';
} else if (WMGetButtonSelected(panel->neB)) {
buf[0] = 't';
buf[1] = 'r';
} else if (WMGetButtonSelected(panel->swB)) {
buf[0] = 'b';
buf[1] = 'l';
} else {
buf[0] = 'b';
buf[1] = 'r';
}
if (WMGetButtonSelected(panel->horB)) {
buf[2] = 'h';
} else {
buf[2] = 'v';
}
SetStringForKey(buf, "IconPosition");
}
Panel*
InitIcons(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Icon Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

View File

@@ -0,0 +1,181 @@
/* KeyboardSettings.c- keyboard options (equivalent to xset)
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *delaF;
WMButton *delaB[4];
WMLabel *dmsL;
WMTextField *dmsT;
WMFrame *rateF;
WMButton *rateB[4];
WMLabel *rmsL;
WMTextField *rmsT;
WMTextField *testT;
} _Panel;
#define ICON_FILE "keyboard"
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
int i;
WMColor *color;
WMFont *font;
color = WMDarkGrayColor(scr);
font = WMSystemFontOfSize(scr, 10);
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/**************** Initial Key Repeat ***************/
panel->delaF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->delaF, 495, 60);
WMMoveWidget(panel->delaF, 15, 10);
WMSetFrameTitle(panel->delaF, _("Initial Key Repeat"));
for (i = 0; i < 4; i++) {
panel->delaB[i] = WMCreateButton(panel->delaF, WBTOnOff);
WMResizeWidget(panel->delaB[i], 60, 20);
WMMoveWidget(panel->delaB[i], 70+i*60, 25);
if (i>0)
WMGroupButtons(panel->delaB[0], panel->delaB[i]);
switch (i) {
case 0:
WMSetButtonText(panel->delaB[i], "....a");
break;
case 1:
WMSetButtonText(panel->delaB[i], "...a");
break;
case 2:
WMSetButtonText(panel->delaB[i], "..a");
break;
case 3:
WMSetButtonText(panel->delaB[i], ".a");
break;
}
}
panel->dmsT = WMCreateTextField(panel->delaF);
WMResizeWidget(panel->dmsT, 50, 20);
WMMoveWidget(panel->dmsT, 345, 25);
/* WMSetTextFieldAlignment(panel->dmsT, WARight);*/
panel->dmsL = WMCreateLabel(panel->delaF);
WMResizeWidget(panel->dmsL, 30, 16);
WMMoveWidget(panel->dmsL, 400, 30);
WMSetLabelTextColor(panel->dmsL, color);
WMSetLabelFont(panel->dmsL, font);
WMSetLabelText(panel->dmsL, "msec");
WMMapSubwidgets(panel->delaF);
/**************** Key Repeat Rate ***************/
panel->rateF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->rateF, 495, 60);
WMMoveWidget(panel->rateF, 15, 95);
WMSetFrameTitle(panel->rateF, _("Key Repeat Rate"));
for (i = 0; i < 4; i++) {
panel->rateB[i] = WMCreateButton(panel->rateF, WBTOnOff);
WMResizeWidget(panel->rateB[i], 60, 20);
WMMoveWidget(panel->rateB[i], 70+i*60, 25);
if (i>0)
WMGroupButtons(panel->rateB[0], panel->rateB[i]);
switch (i) {
case 0:
WMSetButtonText(panel->rateB[i], "a....a");
break;
case 1:
WMSetButtonText(panel->rateB[i], "a...a");
break;
case 2:
WMSetButtonText(panel->rateB[i], "a..a");
break;
case 3:
WMSetButtonText(panel->rateB[i], "a.a");
break;
}
}
panel->rmsT = WMCreateTextField(panel->rateF);
WMResizeWidget(panel->rmsT, 50, 20);
WMMoveWidget(panel->rmsT, 345, 25);
/* WMSetTextFieldAlignment(panel->rmsT, WARight);*/
panel->rmsL = WMCreateLabel(panel->rateF);
WMResizeWidget(panel->rmsL, 30, 16);
WMMoveWidget(panel->rmsL, 400, 30);
WMSetLabelTextColor(panel->rmsL, color);
WMSetLabelFont(panel->rmsL, font);
WMSetLabelText(panel->rmsL, "msec");
WMMapSubwidgets(panel->rateF);
panel->testT = WMCreateTextField(panel->frame);
WMResizeWidget(panel->testT, 480, 20);
WMMoveWidget(panel->testT, 20, 180);
WMSetTextFieldText(panel->testT, _("Type here to test"));
WMReleaseColor(color);
WMReleaseFont(font);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
}
Panel*
InitKeyboardSettings(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Keyboard Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
AddSection(panel, ICON_FILE);
return panel;
}

View File

@@ -0,0 +1,439 @@
/* KeyboardShortcuts.c- keyboard shortcut bindings
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
#include <ctype.h>
#include <X11/keysym.h>
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMLabel *actL;
WMList *actLs;
WMFrame *shoF;
WMTextField *shoT;
WMButton *cleB;
WMButton *defB;
WMLabel *instructionsL;
/**/
char capturing;
char **shortcuts;
int actionCount;
} _Panel;
#define ICON_FILE "keyshortcuts"
/* must be in the same order as the corresponding items in actions list */
static char *keyOptions[] = {
"RootMenuKey",
"WindowListKey",
"WindowMenuKey",
"HideKey",
"MiniaturizeKey",
"CloseKey",
"MaximizeKey",
"VMaximizeKey",
"RaiseKey",
"LowerKey",
"RaiseLowerKey",
"ShadeKey",
"SelectKey",
"FocusNextKey",
"FocusPrevKey",
"NextWorkspaceKey",
"PrevWorkspaceKey",
"NextWorkspaceLayerKey",
"PrevWorkspaceLayerKey",
"Workspace1Key",
"Workspace2Key",
"Workspace3Key",
"Workspace4Key",
"Workspace5Key",
"Workspace6Key",
"Workspace7Key",
"Workspace8Key",
"Workspace9Key",
"Workspace10Key",
"ClipRaiseKey",
"ClipLowerKey",
"ClipRaiseLowerKey"
};
static char*
captureShortcut(Display *dpy, _Panel *panel)
{
XEvent ev;
KeySym ksym;
char buffer[64];
char *key = NULL;
while (panel->capturing) {
XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
WMNextEvent(dpy, &ev);
if (ev.type==KeyPress && ev.xkey.keycode!=0) {
ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
if (!IsModifierKey(ksym)) {
key=XKeysymToString(ksym);
panel->capturing = 0;
break;
}
}
WMHandleEvent(&ev);
}
if (!key)
return NULL;
buffer[0] = 0;
if (ev.xkey.state & ControlMask) {
strcat(buffer, "Control+");
}
if (ev.xkey.state & ShiftMask) {
strcat(buffer, "Shift+");
}
if (ev.xkey.state & Mod1Mask) {
strcat(buffer, "Mod1+");
}
if (ev.xkey.state & Mod2Mask) {
strcat(buffer, "Mod2+");
}
if (ev.xkey.state & Mod3Mask) {
strcat(buffer, "Mod3+");
}
if (ev.xkey.state & Mod4Mask) {
strcat(buffer, "Mod4+");
}
if (ev.xkey.state & Mod5Mask) {
strcat(buffer, "Mod5+");
}
strcat(buffer, key);
return wstrdup(buffer);
}
static void
captureClick(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
char *shortcut;
if (!panel->capturing) {
panel->capturing = 1;
WMSetButtonText(w, _("Cancel"));
WMSetLabelText(panel->instructionsL, _("Press the desired shortcut key(s) or click Cancel to stop capturing."));
XGrabKeyboard(dpy, WMWidgetXID(panel->win), True, GrabModeAsync,
GrabModeAsync, CurrentTime);
shortcut = captureShortcut(dpy, panel);
if (shortcut) {
int row = WMGetListSelectedItemRow(panel->actLs);
WMSetTextFieldText(panel->shoT, shortcut);
if (row>=0) {
if (panel->shortcuts[row])
free(panel->shortcuts[row]);
panel->shortcuts[row] = shortcut;
} else {
free(shortcut);
}
}
}
panel->capturing = 0;
WMSetButtonText(w, _("Capture"));
WMSetLabelText(panel->instructionsL, _("Click Capture to interactively define the shortcut key."));
XUngrabKeyboard(dpy, CurrentTime);
}
static void
clearShortcut(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int row = WMGetListSelectedItemRow(panel->actLs);
WMSetTextFieldText(panel->shoT, NULL);
if (row>=0) {
if (panel->shortcuts[row])
free(panel->shortcuts[row]);
panel->shortcuts[row]=NULL;
}
}
static void
typedKeys(void *observerData, WMNotification *notification)
{
_Panel *panel = (_Panel*)observerData;
int row = WMGetListSelectedItemRow(panel->actLs);
if (row<0)
return;
if (panel->shortcuts[row])
free(panel->shortcuts[row]);
panel->shortcuts[row] = WMGetTextFieldText(panel->shoT);
if (strlen(panel->shortcuts[row])==0) {
free(panel->shortcuts[row]);
panel->shortcuts[row] = NULL;
}
}
static void
listClick(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int row = WMGetListSelectedItemRow(w);
WMSetTextFieldText(panel->shoT, panel->shortcuts[row]);
}
static char*
trimstr(char *str)
{
char *p = str;
int i;
while (isspace(*p)) p++;
p = wstrdup(p);
i = strlen(p);
while (isspace(p[i]) && i>0) {
p[i]=0;
i--;
}
return p;
}
static void
showData(_Panel *panel)
{
char *str;
int i;
for (i=0; i<panel->actionCount; i++) {
str = GetStringForKey(keyOptions[i]);
if (panel->shortcuts[i])
free(panel->shortcuts[i]);
if (str)
panel->shortcuts[i] = trimstr(str);
else
panel->shortcuts[i] = NULL;
if (panel->shortcuts[i] &&
(strcasecmp(panel->shortcuts[i], "none")==0
|| strlen(panel->shortcuts[i])==0)) {
free(panel->shortcuts[i]);
panel->shortcuts[i] = NULL;
}
}
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
WMColor *color;
WMFont *boldFont;
panel->capturing = 0;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
boldFont = WMBoldSystemFontOfSize(scr, 12);
/* **************** Actions **************** */
panel->actL = WMCreateLabel(panel->frame);
WMResizeWidget(panel->actL, 280, 20);
WMMoveWidget(panel->actL, 20, 10);
WMSetLabelFont(panel->actL, boldFont);
WMSetLabelText(panel->actL, _("Actions"));
WMSetLabelRelief(panel->actL, WRSunken);
WMSetLabelTextAlignment(panel->actL, WACenter);
color = WMDarkGrayColor(scr);
WMSetWidgetBackgroundColor(panel->actL, color);
WMReleaseColor(color);
color = WMWhiteColor(scr);
WMSetLabelTextColor(panel->actL, color);
WMReleaseColor(color);
panel->actLs = WMCreateList(panel->frame);
WMResizeWidget(panel->actLs, 280, 190);
WMMoveWidget(panel->actLs, 20, 32);
WMAddListItem(panel->actLs, _("Open applications menu"));
WMAddListItem(panel->actLs, _("Open window list menu"));
WMAddListItem(panel->actLs, _("Open window commands menu"));
WMAddListItem(panel->actLs, _("Hide active application"));
WMAddListItem(panel->actLs, _("Miniaturize active window"));
WMAddListItem(panel->actLs, _("Close active window"));
WMAddListItem(panel->actLs, _("Maximize active window"));
WMAddListItem(panel->actLs, _("Maximize active window vertically"));
WMAddListItem(panel->actLs, _("Raise active window"));
WMAddListItem(panel->actLs, _("Lower active window"));
WMAddListItem(panel->actLs, _("Raise/Lower window under mouse pointer"));
WMAddListItem(panel->actLs, _("Shade active window"));
WMAddListItem(panel->actLs, _("Select active window"));
WMAddListItem(panel->actLs, _("Focus next window"));
WMAddListItem(panel->actLs, _("Focus previous window"));
WMAddListItem(panel->actLs, _("Switch to next workspace"));
WMAddListItem(panel->actLs, _("Switch to previous workspace"));
WMAddListItem(panel->actLs, _("Switch to next ten workspaces"));
WMAddListItem(panel->actLs, _("Switch to previous ten workspaces"));
WMAddListItem(panel->actLs, _("Switch to workspace 1"));
WMAddListItem(panel->actLs, _("Switch to workspace 2"));
WMAddListItem(panel->actLs, _("Switch to workspace 3"));
WMAddListItem(panel->actLs, _("Switch to workspace 4"));
WMAddListItem(panel->actLs, _("Switch to workspace 5"));
WMAddListItem(panel->actLs, _("Switch to workspace 6"));
WMAddListItem(panel->actLs, _("Switch to workspace 7"));
WMAddListItem(panel->actLs, _("Switch to workspace 8"));
WMAddListItem(panel->actLs, _("Switch to workspace 9"));
WMAddListItem(panel->actLs, _("Switch to workspace 10"));
WMAddListItem(panel->actLs, _("Raise Clip"));
WMAddListItem(panel->actLs, _("Lower Clip"));
WMAddListItem(panel->actLs, _("Raise/Lower Clip"));
WMSetListAction(panel->actLs, listClick, panel);
panel->actionCount = WMGetListNumberOfRows(panel->actLs);
panel->shortcuts = wmalloc(sizeof(char*)*panel->actionCount);
memset(panel->shortcuts, 0, sizeof(char*)*panel->actionCount);
/***************** Shortcut ****************/
panel->shoF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->shoF, 190, 210);
WMMoveWidget(panel->shoF, 315, 10);
WMSetFrameTitle(panel->shoF, _("Shortcut"));
panel->shoT = WMCreateTextField(panel->shoF);
WMResizeWidget(panel->shoT, 160, 20);
WMMoveWidget(panel->shoT, 15, 65);
WMAddNotificationObserver(typedKeys, panel,
WMTextDidChangeNotification, panel->shoT);
panel->cleB = WMCreateCommandButton(panel->shoF);
WMResizeWidget(panel->cleB, 75, 24);
WMMoveWidget(panel->cleB, 15, 95);
WMSetButtonText(panel->cleB, _("Clear"));
WMSetButtonAction(panel->cleB, clearShortcut, panel);
panel->defB = WMCreateCommandButton(panel->shoF);
WMResizeWidget(panel->defB, 75, 24);
WMMoveWidget(panel->defB, 100, 95);
WMSetButtonText(panel->defB, _("Capture"));
WMSetButtonAction(panel->defB, captureClick, panel);
panel->instructionsL = WMCreateLabel(panel->shoF);
WMResizeWidget(panel->instructionsL, 160, 55);
WMMoveWidget(panel->instructionsL, 15, 140);
WMSetLabelTextAlignment(panel->instructionsL, WACenter);
WMSetLabelText(panel->instructionsL, _("Click Capture to interactively define the shortcut key."));
WMMapSubwidgets(panel->shoF);
WMReleaseFont(boldFont);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
static void
storeData(_Panel *panel)
{
int i;
char *str;
for (i=0; i<panel->actionCount; i++) {
str = NULL;
if (panel->shortcuts[i]) {
str = trimstr(panel->shortcuts[i]);
if (strlen(str)==0) {
free(str);
str = NULL;
}
}
if (str) {
SetStringForKey(str, keyOptions[i]);
free(str);
} else {
SetStringForKey("None", keyOptions[i]);
}
}
}
Panel*
InitKeyboardShortcuts(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Keyboard Shortcut Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

64
WPrefs.app/Makefile.am Normal file
View File

@@ -0,0 +1,64 @@
SUBDIRS = xpm tiff po
nlsdir = @NLSDIR@
AUTOMAKE_OPTIONS = no-dependencies
wpexecbindir = @wprefsdir@
wpexecbin_PROGRAMS = WPrefs
wpdatadir = @wprefsdir@
wpdata_DATA = WPrefs.tiff WPrefs.xpm
EXTRA_DIST = $(wpdata_DATA)
WPrefs_SOURCES = \
main.c \
WPrefs.c \
WPrefs.h \
Configurations.c \
Expert.c \
Focus.c \
Icons.c \
KeyboardSettings.c \
KeyboardShortcuts.c \
Menu.c \
MenuPreferences.c \
MouseSettings.c \
Paths.c \
Preferences.c \
Text.c \
TextureAndColor.c \
WindowHandling.c \
Workspace.c \
double.c \
double.h \
MenuGuru.c \
xmodifier.c
CPPFLAGS = \
@CPPFLAGS@ \
@SHAPE@ @I18N@ @X_LOCALE@ \
-DNLSDIR="\"$(nlsdir)\""
INCLUDES = \
-I$(top_srcdir)/wrlib \
-I$(top_srcdir)/WINGs \
@XCFLAGS@ \
@LIBPL_INC_PATH@
WPrefs_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a
WPrefs_LDADD = \
-L$(top_builddir)/WINGs -lWINGs\
-L$(top_builddir)/wrlib -lwraster \
@LIBPL_LIBS@ \
@XLFLAGS@ \
@GFXLIBS@ \
@XLIBS@ \
@X_EXTRA_LIBS@ \
@INTLIBS@ \
-lm

439
WPrefs.app/Makefile.in Normal file
View File

@@ -0,0 +1,439 @@
# Makefile.in generated automatically by automake 1.3 from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLIBS = @GFXLIBS@
I18N = @I18N@
I18N_MB = @I18N_MB@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LIBPL_INC_PATH = @LIBPL_INC_PATH@
LIBPL_LIBS = @LIBPL_LIBS@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@
NLSDIR = @NLSDIR@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
REDUCE_APPICONS = @REDUCE_APPICONS@
SHAPE = @SHAPE@
SOUND = @SOUND@
VERSION = @VERSION@
WPMOFILES = @WPMOFILES@
XCFLAGS = @XCFLAGS@
XGETTEXT = @XGETTEXT@
XLFLAGS = @XLFLAGS@
XLIBS = @XLIBS@
XSHM = @XSHM@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LOCALE = @X_LOCALE@
pixmapdir = @pixmapdir@
wprefsdir = @wprefsdir@
SUBDIRS = xpm tiff po
nlsdir = @NLSDIR@
AUTOMAKE_OPTIONS = no-dependencies
wpexecbindir = @wprefsdir@
wpexecbin_PROGRAMS = WPrefs
wpdatadir = @wprefsdir@
wpdata_DATA = WPrefs.tiff WPrefs.xpm
EXTRA_DIST = $(wpdata_DATA)
WPrefs_SOURCES = \
main.c \
WPrefs.c \
WPrefs.h \
Configurations.c \
Expert.c \
Focus.c \
Icons.c \
KeyboardSettings.c \
KeyboardShortcuts.c \
Menu.c \
MenuPreferences.c \
MouseSettings.c \
Paths.c \
Preferences.c \
Text.c \
TextureAndColor.c \
WindowHandling.c \
Workspace.c \
double.c \
double.h \
MenuGuru.c \
xmodifier.c
CPPFLAGS = \
@CPPFLAGS@ \
@SHAPE@ @I18N@ @X_LOCALE@ \
-DNLSDIR="\"$(nlsdir)\""
INCLUDES = \
-I$(top_srcdir)/wrlib \
-I$(top_srcdir)/WINGs \
@XCFLAGS@ \
@LIBPL_INC_PATH@
WPrefs_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a
WPrefs_LDADD = \
-L$(top_builddir)/WINGs -lWINGs\
-L$(top_builddir)/wrlib -lwraster \
@LIBPL_LIBS@ \
@XLFLAGS@ \
@GFXLIBS@ \
@XLIBS@ \
@X_EXTRA_LIBS@ \
@INTLIBS@ \
-lm
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../src/config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(wpexecbin_PROGRAMS)
DEFS = @DEFS@ -I. -I$(srcdir) -I../src
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
WPrefs_OBJECTS = main.o WPrefs.o Configurations.o Expert.o Focus.o \
Icons.o KeyboardSettings.o KeyboardShortcuts.o Menu.o MenuPreferences.o \
MouseSettings.o Paths.o Preferences.o Text.o TextureAndColor.o \
WindowHandling.o Workspace.o double.o MenuGuru.o xmodifier.o
WPrefs_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
DATA = $(wpdata_DATA)
DIST_COMMON = README Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
SOURCES = $(WPrefs_SOURCES)
OBJECTS = $(WPrefs_OBJECTS)
all: all-recursive all-am
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu WPrefs.app/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-wpexecbinPROGRAMS:
clean-wpexecbinPROGRAMS:
-test -z "$(wpexecbin_PROGRAMS)" || rm -f $(wpexecbin_PROGRAMS)
distclean-wpexecbinPROGRAMS:
maintainer-clean-wpexecbinPROGRAMS:
install-wpexecbinPROGRAMS: $(wpexecbin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(wpexecbindir)
@list='$(wpexecbin_PROGRAMS)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(wpexecbindir)/`echo $$p|sed '$(transform)'`"; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(wpexecbindir)/`echo $$p|sed '$(transform)'`; \
else :; fi; \
done
uninstall-wpexecbinPROGRAMS:
@$(NORMAL_UNINSTALL)
list='$(wpexecbin_PROGRAMS)'; for p in $$list; do \
rm -f $(DESTDIR)$(wpexecbindir)/`echo $$p|sed '$(transform)'`; \
done
.c.o:
$(COMPILE) -c $<
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
WPrefs: $(WPrefs_OBJECTS) $(WPrefs_DEPENDENCIES)
@rm -f WPrefs
$(LINK) $(WPrefs_LDFLAGS) $(WPrefs_OBJECTS) $(WPrefs_LDADD) $(LIBS)
install-wpdataDATA: $(wpdata_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(wpdatadir)
@list='$(wpdata_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(wpdatadir)/$$p"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(wpdatadir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(wpdatadir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(wpdatadir)/$$p; \
fi; fi; \
done
uninstall-wpdataDATA:
@$(NORMAL_UNINSTALL)
list='$(wpdata_DATA)'; for p in $$list; do \
rm -f $(DESTDIR)$(wpdatadir)/$$p; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
list='$(SUBDIRS)'; for subdir in $$list; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
done; \
for subdir in $$rev; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
(cd $$subdir && $(MAKE) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = WPrefs.app
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file; \
done
for subdir in $(SUBDIRS); do \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
done
info: info-recursive
dvi: dvi-recursive
check: all-am
$(MAKE) check-recursive
installcheck: installcheck-recursive
all-am: Makefile $(PROGRAMS) $(DATA)
install-exec-am: install-wpexecbinPROGRAMS
install-data-am: install-wpdataDATA
uninstall-am: uninstall-wpexecbinPROGRAMS uninstall-wpdataDATA
install-exec: install-exec-recursive install-exec-am
@$(NORMAL_INSTALL)
install-data: install-data-recursive install-data-am
@$(NORMAL_INSTALL)
install: install-recursive install-exec-am install-data-am
@:
uninstall: uninstall-recursive uninstall-am
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs: installdirs-recursive
$(mkinstalldirs) $(DATADIR)$(wpexecbindir) $(DATADIR)$(wpdatadir)
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(DISTCLEANFILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean-am: mostlyclean-wpexecbinPROGRAMS mostlyclean-compile \
mostlyclean-tags mostlyclean-generic
clean-am: clean-wpexecbinPROGRAMS clean-compile clean-tags \
clean-generic mostlyclean-am
distclean-am: distclean-wpexecbinPROGRAMS distclean-compile \
distclean-tags distclean-generic clean-am
maintainer-clean-am: maintainer-clean-wpexecbinPROGRAMS \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean-am
mostlyclean: mostlyclean-recursive mostlyclean-am
clean: clean-recursive clean-am
distclean: distclean-recursive distclean-am
-rm -f config.status
maintainer-clean: maintainer-clean-recursive maintainer-clean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
.PHONY: mostlyclean-wpexecbinPROGRAMS distclean-wpexecbinPROGRAMS \
clean-wpexecbinPROGRAMS maintainer-clean-wpexecbinPROGRAMS \
uninstall-wpexecbinPROGRAMS install-wpexecbinPROGRAMS \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile uninstall-wpdataDATA install-wpdataDATA \
install-data-recursive uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
all-recursive check-recursive installcheck-recursive info-recursive \
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info dvi \
installcheck all-am install-exec-am install-data-am uninstall-am \
install-exec install-data install uninstall all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

1366
WPrefs.app/Menu.c Normal file

File diff suppressed because it is too large Load Diff

502
WPrefs.app/MenuGuru.c Normal file
View File

@@ -0,0 +1,502 @@
/* MenuGuru.c- OPEN_MENU definition "guru" assistant
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
#include <assert.h>
#include <ctype.h>
typedef struct _MenuGuru {
WMWindow *win;
WMButton *nextB;
WMButton *backB;
WMButton *cancelB;
WMLabel *typetopL;
WMButton *typefB;
WMButton *typepB;
WMButton *typedB;
WMLabel *pathtopL;
WMTextField *pathT;
WMButton *pathB;
WMLabel *pathbotL;
WMLabel *pipetopL;
WMTextField *pipeT;
WMLabel *pipebotL;
WMLabel *dirtopL;
WMTextField *dirT;
WMLabel *dirbotL;
WMLabel *progtopL;
WMTextField *progT;
WMLabel *progbotL;
char ok;
char end;
int section;
} MenuGuru;
enum {
GSelectType,
GSelectFile,
GSelectPaths,
GSelectPipe,
GSelectProgram,
GDone
};
static char*
trimstr(char *str)
{
char *p = str;
int i;
while (isspace(*p)) p++;
p = wstrdup(p);
i = strlen(p);
while (isspace(p[i]) && i>0) {
p[i] = 0;
i--;
}
return p;
}
static void
showPart(MenuGuru *panel, int part)
{
WMUnmapSubwidgets(panel->win);
WMMapWidget(panel->nextB);
WMMapWidget(panel->backB);
WMMapWidget(panel->cancelB);
WMSetButtonEnabled(panel->backB, part!=GSelectType);
switch (part) {
case GSelectType:
WMSetWindowTitle(panel->win, _("Menu Guru - Select Type"));
WMMapWidget(panel->typetopL);
WMMapWidget(panel->typedB);
WMMapWidget(panel->typepB);
WMMapWidget(panel->typefB);
WMSetButtonText(panel->nextB, _("Next"));
break;
case GSelectFile:
WMSetWindowTitle(panel->win, _("Menu Guru - Select Menu File"));
WMMapWidget(panel->pathtopL);
WMMapWidget(panel->pathT);
/* WMMapWidget(panel->pathB);*/
WMMapWidget(panel->pathbotL);
WMSetButtonText(panel->nextB, _("OK"));
break;
case GSelectPipe:
WMSetWindowTitle(panel->win, _("Menu Guru - Select Pipe Command"));
WMMapWidget(panel->pipetopL);
WMMapWidget(panel->pipeT);
WMMapWidget(panel->pipebotL);
WMSetButtonText(panel->nextB, _("OK"));
break;
case GSelectPaths:
WMSetWindowTitle(panel->win, _("Menu Guru - Select Directories"));
WMMapWidget(panel->dirtopL);
WMMapWidget(panel->dirT);
WMMapWidget(panel->dirbotL);
WMSetButtonText(panel->nextB, _("Next"));
break;
case GSelectProgram:
WMSetWindowTitle(panel->win, _("Menu Guru - Select Command"));
WMMapWidget(panel->progtopL);
WMMapWidget(panel->progT);
WMMapWidget(panel->progbotL);
WMSetButtonText(panel->nextB, _("OK"));
break;
}
panel->section = part;
}
static void
clickNext(WMWidget *w, void *data)
{
MenuGuru *panel = (MenuGuru*)data;
char *tmp, *p;
switch (panel->section) {
case GSelectType:
if (WMGetButtonSelected(panel->typefB)) {
showPart(panel, GSelectFile);
} else if (WMGetButtonSelected(panel->typepB)) {
showPart(panel, GSelectPipe);
} else {
showPart(panel, GSelectPaths);
}
break;
case GSelectFile:
tmp = WMGetTextFieldText(panel->pathT);
p = trimstr(tmp); free(tmp);
if (strlen(p)==0) {
free(p);
return;
}
free(p);
panel->ok = 1;
panel->end = 1;
break;
case GSelectPaths:
tmp = WMGetTextFieldText(panel->dirT);
p = trimstr(tmp); free(tmp);
if (strlen(p)==0) {
free(p);
return;
}
free(p);
showPart(panel, GSelectProgram);
break;
case GSelectPipe:
tmp = WMGetTextFieldText(panel->pipeT);
p = trimstr(tmp); free(tmp);
if (strlen(p)==0) {
free(p);
return;
}
free(p);
panel->ok = 1;
panel->end = 1;
break;
case GSelectProgram:
panel->ok = 1;
panel->end = 1;
break;
default:
panel->end = 1;
}
}
static void
clickBack(WMWidget *w, void *data)
{
MenuGuru *panel = (MenuGuru*)data;
int newSection;
switch (panel->section) {
case GSelectFile:
newSection = GSelectType;
break;
case GSelectPipe:
newSection = GSelectType;
break;
case GSelectPaths:
newSection = GSelectType;
break;
case GSelectProgram:
newSection = GSelectPaths;
break;
default:
newSection = panel->section;
}
showPart(panel, newSection);
}
static void
closeWindow(WMWidget *w, void *data)
{
MenuGuru *panel = (MenuGuru*)data;
panel->end = 1;
}
static void
createPanel(WMWindow *mainWindow, MenuGuru *panel)
{
panel->win = WMCreatePanelForWindow(mainWindow, "menuGuru");
WMResizeWidget(panel->win, 370, 220);
panel->nextB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->nextB, 80, 24);
WMMoveWidget(panel->nextB, 280, 185);
WMSetButtonText(panel->nextB, _("Next"));
WMSetButtonAction(panel->nextB, clickNext, panel);
panel->backB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->backB, 80, 24);
WMMoveWidget(panel->backB, 195, 185);
WMSetButtonText(panel->backB, _("Back"));
WMSetButtonAction(panel->backB, clickBack, panel);
panel->cancelB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->cancelB, 80, 24);
WMMoveWidget(panel->cancelB, 110, 185);
WMSetButtonText(panel->cancelB, _("Cancel"));
WMSetButtonAction(panel->cancelB, closeWindow, panel);
/**/
panel->typetopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->typetopL, 350, 45);
WMMoveWidget(panel->typetopL, 10, 10);
WMSetLabelText(panel->typetopL, _("This process will help you create a "
"submenu which definition is located in another file "
"or is created dynamically.\nWhat do you want to use as the "
"contents of the submenu?"));
panel->typefB = WMCreateRadioButton(panel->win);
WMResizeWidget(panel->typefB, 330, 35);
WMMoveWidget(panel->typefB, 20, 65);
WMSetButtonText(panel->typefB, _("A file containing the menu definition "
"in the plain text (non-property list) menu format."));
panel->typepB = WMCreateRadioButton(panel->win);
WMResizeWidget(panel->typepB, 330, 35);
WMMoveWidget(panel->typepB, 20, 105);
WMSetButtonText(panel->typepB, _("The menu definition generated by a "
"script/program read through a pipe."));
panel->typedB = WMCreateRadioButton(panel->win);
WMResizeWidget(panel->typedB, 330, 35);
WMMoveWidget(panel->typedB, 20, 140);
WMSetButtonText(panel->typedB, _("The files in one or more directories."));
WMGroupButtons(panel->typefB, panel->typepB);
WMGroupButtons(panel->typefB, panel->typedB);
WMPerformButtonClick(panel->typefB);
/**/
panel->pathtopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->pathtopL, 330, 20);
WMMoveWidget(panel->pathtopL, 20, 25);
WMSetLabelText(panel->pathtopL, _("Type the path for the menu file:"));
panel->pathT = WMCreateTextField(panel->win);
WMResizeWidget(panel->pathT, 330, 20);
WMMoveWidget(panel->pathT, 20, 50);
/*
panel->pathB = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->pathB, 70, 24);
WMMoveWidget(panel->pathB, 275, 75);
WMSetButtonText(panel->pathB, _("Browse"));
*/
panel->pathbotL = WMCreateLabel(panel->win);
WMResizeWidget(panel->pathbotL, 330, 80);
WMMoveWidget(panel->pathbotL, 20, 100);
WMSetLabelText(panel->pathbotL, _("The menu file must contain a menu "
"in the plain text menu file format. This format is "
"described in the menu files included with WindowMaker, "
"probably at ~/GNUstep/Library/WindowMaker/menu"));
/**/
panel->pipetopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->pipetopL, 330, 32);
WMMoveWidget(panel->pipetopL, 20, 20);
WMSetLabelText(panel->pipetopL, _("Type the command that will generate "
"the menu definition:"));
panel->pipeT = WMCreateTextField(panel->win);
WMResizeWidget(panel->pipeT, 330, 20);
WMMoveWidget(panel->pipeT, 20, 55);
panel->pipebotL = WMCreateLabel(panel->win);
WMResizeWidget(panel->pipebotL, 330, 80);
WMMoveWidget(panel->pipebotL, 20, 85);
WMSetLabelText(panel->pipebotL, _("The command supplied must generate and "
"output a valid menu definition to stdout. This definition "
"should be in the plain text menu file format, described "
"in the menu files included with WindowMaker, usually "
"at ~/GNUstep/Library/WindowMaker/menu"));
/**/
panel->dirtopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirtopL, 330, 32);
WMMoveWidget(panel->dirtopL, 20, 20);
WMSetLabelText(panel->dirtopL, _("Type the path for the directory. You "
"can type more than one path by separating them with "
"spaces."));
panel->dirT = WMCreateTextField(panel->win);
WMResizeWidget(panel->dirT, 330, 20);
WMMoveWidget(panel->dirT, 20, 55);
panel->dirbotL = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirbotL, 330, 80);
WMMoveWidget(panel->dirbotL, 20, 85);
WMSetLabelText(panel->dirbotL, _("The menu generated will have an item "
"for each file in the directory. The directories can "
"contain program executables or data files (such as "
"jpeg images)."));
/**/
panel->dirtopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirtopL, 330, 32);
WMMoveWidget(panel->dirtopL, 20, 20);
WMSetLabelText(panel->dirtopL, _("Type the path for the directory. You "
"can type more than one path by separating them with "
"spaces."));
panel->dirT = WMCreateTextField(panel->win);
WMResizeWidget(panel->dirT, 330, 20);
WMMoveWidget(panel->dirT, 20, 55);
panel->dirbotL = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirbotL, 330, 80);
WMMoveWidget(panel->dirbotL, 20, 85);
WMSetLabelText(panel->dirbotL, _("The menu generated will have an item "
"for each file in the directory. The directories can "
"contain program executables or data files (such as "
"jpeg images)."));
/**/
panel->dirtopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirtopL, 330, 32);
WMMoveWidget(panel->dirtopL, 20, 20);
WMSetLabelText(panel->dirtopL, _("Type the path for the directory. You "
"can type more than one path by separating them with "
"spaces."));
panel->dirT = WMCreateTextField(panel->win);
WMResizeWidget(panel->dirT, 330, 20);
WMMoveWidget(panel->dirT, 20, 60);
panel->dirbotL = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirbotL, 330, 80);
WMMoveWidget(panel->dirbotL, 20, 85);
WMSetLabelText(panel->dirbotL, _("The menu generated will have an item "
"for each file in the directory. The directories can "
"contain program executables or data files (such as "
"jpeg images)."));
/**/
panel->progtopL = WMCreateLabel(panel->win);
WMResizeWidget(panel->progtopL, 330, 48);
WMMoveWidget(panel->progtopL, 20, 10);
WMSetLabelText(panel->progtopL, _("If the directory contain data files, "
"type the command used to open these files. Otherwise, "
"leave it in blank."));
panel->progT = WMCreateTextField(panel->win);
WMResizeWidget(panel->progT, 330, 20);
WMMoveWidget(panel->progT, 20, 60);
panel->progbotL = WMCreateLabel(panel->win);
WMResizeWidget(panel->progbotL, 330, 72);
WMMoveWidget(panel->progbotL, 20, 90);
WMSetLabelText(panel->progbotL, _("Each file in the directory will have "
"an item and they will be opened with the supplied command."
"For example, if the directory contains image files and "
"the command is \"xv -root\", each file in the directory "
"will have a menu item like \"xv -root imagefile\"."));
WMRealizeWidget(panel->win);
}
char*
OpenMenuGuru(WMWindow *mainWindow)
{
WMScreen *scr = WMWidgetScreen(mainWindow);
MenuGuru panel;
char *text, *p, *dirs;
createPanel(mainWindow, &panel);
WMSetWindowCloseAction(panel.win, closeWindow, &panel);
showPart(&panel, GSelectType);
WMMapWidget(panel.win);
panel.ok = 0;
panel.end = 0;
while (!panel.end) {
XEvent ev;
WMNextEvent(WMScreenDisplay(scr), &ev);
WMHandleEvent(&ev);
}
text = NULL;
if (panel.ok) {
switch (panel.section) {
case GSelectFile:
text = WMGetTextFieldText(panel.pathT);
break;
case GSelectPipe:
text = WMGetTextFieldText(panel.pipeT);
p = trimstr(text); free(text);
if (p[0]!='|') {
text = wmalloc(strlen(p)+4);
strcpy(text, "| ");
strcat(text, p);
free(p);
} else {
text = p;
}
break;
case GSelectProgram:
dirs = WMGetTextFieldText(panel.dirT);
text = WMGetTextFieldText(panel.progT);
p = trimstr(text); free(text);
if (strlen(p)==0) {
free(p);
text = dirs;
} else {
text = wmalloc(strlen(dirs)+16+strlen(p));
sprintf(text, "%s WITH %s", dirs, p);
free(dirs);
free(p);
}
break;
}
}
WMDestroyWidget(panel.win);
return text;
}

View File

@@ -0,0 +1,239 @@
/* MenuPreferences.c- menu related preferences
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *scrF;
WMButton *scrB[5];
WMFrame *aliF;
WMButton *aliyB;
WMButton *alinB;
WMFrame *optF;
WMButton *autoB;
WMButton *wrapB;
} _Panel;
#define ICON_FILE "menuprefs"
#define SPEED_IMAGE "speed%i"
#define SPEED_IMAGE_S "speed%is"
#define MENU_ALIGN1 "menualign1"
#define MENU_ALIGN2 "menualign2"
static void
showData(_Panel *panel)
{
WMPerformButtonClick(panel->scrB[GetSpeedForKey("MenuScrollSpeed")]);
if (GetBoolForKey("AlignSubmenus"))
WMPerformButtonClick(panel->aliyB);
else
WMPerformButtonClick(panel->alinB);
WMSetButtonSelected(panel->wrapB, GetBoolForKey("WrapMenus"));
WMSetButtonSelected(panel->autoB, GetBoolForKey("ScrollableMenus"));
}
static void
storeData(_Panel *panel)
{
int i;
for (i=0; i<5; i++) {
if (WMGetButtonSelected(panel->scrB[i]))
break;
}
SetSpeedForKey(i, "MenuScrollSpeed");
SetBoolForKey(WMGetButtonSelected(panel->aliyB), "AlignSubmenus");
SetBoolForKey(WMGetButtonSelected(panel->wrapB), "WrapMenus");
SetBoolForKey(WMGetButtonSelected(panel->autoB), "ScrollableMenus");
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
WMPixmap *icon;
int i;
char *buf1, *buf2;
char *path;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/***************** Menu Scroll Speed ****************/
panel->scrF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->scrF, 235, 90);
WMMoveWidget(panel->scrF, 25, 20);
WMSetFrameTitle(panel->scrF, _("Menu Scrolling Speed"));
buf1 = wmalloc(strlen(SPEED_IMAGE)+1);
buf2 = wmalloc(strlen(SPEED_IMAGE_S)+1);
for (i = 0; i < 5; i++) {
panel->scrB[i] = WMCreateCustomButton(panel->scrF, WBBStateChangeMask);
WMResizeWidget(panel->scrB[i], 40, 40);
WMMoveWidget(panel->scrB[i], 15+(40*i), 30);
WMSetButtonBordered(panel->scrB[i], False);
WMSetButtonImagePosition(panel->scrB[i], WIPImageOnly);
if (i > 0) {
WMGroupButtons(panel->scrB[0], panel->scrB[i]);
}
sprintf(buf1, SPEED_IMAGE, i);
sprintf(buf2, SPEED_IMAGE_S, i);
path = LocateImage(buf1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->scrB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
path = LocateImage(buf2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonAltImage(panel->scrB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
}
free(buf1);
free(buf2);
WMMapSubwidgets(panel->scrF);
/***************** Submenu Alignment ****************/
panel->aliF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->aliF, 220, 90);
WMMoveWidget(panel->aliF, 280, 20);
WMSetFrameTitle(panel->aliF, _("Submenu Alignment"));
panel->alinB = WMCreateButton(panel->aliF, WBTOnOff);
WMResizeWidget(panel->alinB, 48, 48);
WMMoveWidget(panel->alinB, 56, 25);
WMSetButtonImagePosition(panel->alinB, WIPImageOnly);
path = LocateImage(MENU_ALIGN1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->alinB, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
panel->aliyB = WMCreateButton(panel->aliF, WBTOnOff);
WMResizeWidget(panel->aliyB, 48, 48);
WMMoveWidget(panel->aliyB, 120, 25);
WMSetButtonImagePosition(panel->aliyB, WIPImageOnly);
path = LocateImage(MENU_ALIGN2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->aliyB, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
}
WMGroupButtons(panel->alinB, panel->aliyB);
WMMapSubwidgets(panel->aliF);
/***************** Options ****************/
panel->optF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->optF, 475, 80);
WMMoveWidget(panel->optF, 25, 130);
panel->wrapB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->wrapB, 440, 32);
WMMoveWidget(panel->wrapB, 25, 8);
WMSetButtonText(panel->wrapB, _("Always open submenus inside the screen, instead of scrolling.\nNote: this can be an annoyance at some circumstances."));
panel->autoB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->autoB, 440, 20);
WMMoveWidget(panel->autoB, 25, 45);
WMSetButtonText(panel->autoB, _("Scroll off-screen menus when pointer is moved over them."));
WMMapSubwidgets(panel->optF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
Panel*
InitMenuPreferences(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Menu Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

906
WPrefs.app/MouseSettings.c Normal file
View File

@@ -0,0 +1,906 @@
/* MouseSettings.c- mouse options (some are equivalent to xset)
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
#include <X11/Xutil.h>
#include <math.h>
/* double-click tester */
#include "double.h"
#define XSET "xset"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *speedF;
WMLabel *speedL;
WMButton *speedB[5];
WMLabel *acceL;
WMLabel *threL;
WMTextField *threT;
WMFrame *ddelaF;
WMButton *ddelaB[5];
DoubleTest *tester;
WMFrame *menuF;
WMLabel *listL;
WMLabel *appL;
WMLabel *selL;
WMLabel *mblL;
WMLabel *mbmL;
WMLabel *mbrL;
WMButton *lmb[3];
WMButton *amb[3];
WMButton *smb[3];
WMButton *disaB;
WMFrame *grabF;
WMPopUpButton *grabP;
/**/
WMButton *lastClickedSpeed;
int maxThreshold;
float acceleration;
} _Panel;
#define ICON_FILE "mousesettings"
#define SPEED_ICON_FILE "mousespeed"
#define SPEED_IMAGE "speed%i"
#define SPEED_IMAGE_S "speed%is"
#define DELAY_ICON "timer%i"
#define DELAY_ICON_S "timer%is"
#define MOUSEB_L "minimouseleft"
#define MOUSEB_M "minimousemiddle"
#define MOUSEB_R "minimouseright"
/* need access to the double click variables */
#include "WINGsP.h"
static char *modifierNames[] = {
"Shift",
"Lock",
"Control",
"Mod1",
"Mod2",
"Mod3",
"Mod4",
"Mod5"
};
#define DELAY(i) ((i)*75+170)
int ModifierFromKey(Display *dpy, char *key);
static void
setMouseAccel(WMScreen *scr, float accel, int threshold)
{
int n, d;
d = 10;
n = accel*d;
XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
}
static void
speedClick(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int i;
char buffer[64];
int threshold;
char *tmp;
for (i=0; i<5; i++) {
if (panel->speedB[i]==w)
break;
}
panel->lastClickedSpeed = panel->speedB[i];
panel->acceleration = 0.5+(i*0.5);
sprintf(buffer, "Accel.: %.2f", 0.5+(i*0.5));
WMSetLabelText(panel->acceL, buffer);
tmp = WMGetTextFieldText(panel->threT);
if (sscanf(tmp, "%i", &threshold)!=1 || threshold < 0
|| threshold > panel->maxThreshold) {
WMRunAlertPanel(WMWidgetScreen(w), GetWindow(panel), _("Error"),
_("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
_("OK"), NULL, NULL);
} else {
setMouseAccel(WMWidgetScreen(w), 0.5+(i*0.5), threshold);
}
free(tmp);
}
static void
returnPressed(void *observerData, WMNotification *notification)
{
_Panel *panel = (_Panel*)observerData;
speedClick(panel->lastClickedSpeed, panel);
}
static void
doubleClick(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int i;
extern _WINGsConfiguration WINGsConfiguration;
for (i=0; i<5; i++) {
if (panel->ddelaB[i]==w)
break;
}
WINGsConfiguration.doubleClickDelay = DELAY(i);
}
int
getbutton(char *str)
{
if (!str)
return -2;
if (strcasecmp(str, "left")==0)
return 0;
else if (strcasecmp(str, "middle")==0)
return 1;
else if (strcasecmp(str, "right")==0)
return 2;
else if (strcasecmp(str, "button1")==0)
return 0;
else if (strcasecmp(str, "button2")==0)
return 1;
else if (strcasecmp(str, "button3")==0)
return 2;
else if (strcasecmp(str, "button4")==0
|| strcasecmp(str, "button5")==0) {
wwarning(_("mouse button %s not supported by WPrefs."), str);
return -2;
} else {
return -1;
}
}
static void
getMouseParameters(Display *dpy, float *accel, int *thre)
{
int n, d;
XGetPointerControl(dpy, &n, &d, thre);
*accel = (float)n/(float)d;
}
static void
showData(_Panel *panel)
{
char *str;
int i;
int a=-1, b=-1, c=-1;
float accel;
char buffer[32];
Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
str = GetStringForKey("SelectWindowsMouseButton");
i = getbutton(str);
if (i==-1) {
a = 0;
wwarning(_("bad value %s for option %s"),str, "SelectWindowsMouseButton");
WMPerformButtonClick(panel->smb[0]);
} else if (i>=0) {
a = i;
WMPerformButtonClick(panel->smb[i]);
}
str = GetStringForKey("WindowListMouseButton");
i = getbutton(str);
if (i==-1) {
b = 0;
wwarning(_("bad value %s for option %s"), str, "WindowListMouseButton");
WMPerformButtonClick(panel->lmb[1]);
} else if (i>=0) {
b = i;
WMPerformButtonClick(panel->lmb[i]);
}
str = GetStringForKey("ApplicationMenuMouseButton");
i = getbutton(str);
if (i==-1) {
c = 0;
wwarning(_("bad value %s for option %s"), str, "ApplicationMenuMouseButton");
WMPerformButtonClick(panel->amb[2]);
} else if (i>=0) {
c = i;
WMPerformButtonClick(panel->amb[i]);
}
WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
/**/
getMouseParameters(dpy, &accel, &a);
panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
if (a > panel->maxThreshold) {
panel->maxThreshold = a;
}
sprintf(buffer, "%i", a);
WMSetTextFieldText(panel->threT, buffer);
/* find best match */
a = 0;
for (i=0; i<5; i++) {
if (fabs((0.5+((float)i*0.5))-accel) < fabs((0.5+((float)a*0.5))-accel))
a = i;
}
WMPerformButtonClick(panel->speedB[a]);
panel->lastClickedSpeed = panel->speedB[a];
panel->acceleration = accel;
speedClick(panel->lastClickedSpeed, panel);
/**/
b = GetIntegerForKey("DoubleClickTime");
/* find best match */
a = 0;
for (i=0; i<5; i++) {
if (abs(b - DELAY(i)) < abs(b - DELAY(a)))
a = i;
}
WMPerformButtonClick(panel->ddelaB[a]);
/**/
str = GetStringForKey("ModifierKey");
a = ModifierFromKey(dpy, str);
if (a != -1) {
str = modifierNames[a];
a = 0;
for (i=0; i<WMGetPopUpButtonNumberOfItems(panel->grabP); i++) {
if (strstr(WMGetPopUpButtonItem(panel->grabP, i), str)) {
WMSetPopUpButtonSelectedItem(panel->grabP, i);
a = 1;
break;
}
}
}
if (a < 1) {
sscanf(WMGetPopUpButtonItem(panel->grabP, 0), "%s", buffer);
WMSetPopUpButtonSelectedItem(panel->grabP, 0);
wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
str, buffer);
}
}
static void
fillModifierPopUp(WMPopUpButton *pop)
{
XModifierKeymap *mapping;
Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
int i, j;
char *str;
char buffer[64];
mapping = XGetModifierMapping(dpy);
if (!mapping || mapping->max_keypermod==0) {
WMAddPopUpButtonItem(pop, "Mod1");
WMAddPopUpButtonItem(pop, "Mod2");
WMAddPopUpButtonItem(pop, "Mod3");
WMAddPopUpButtonItem(pop, "Mod4");
WMAddPopUpButtonItem(pop, "Mod5");
wwarning(_("could not retrieve keyboard modifier mapping"));
return;
}
for (j=0; j<8; j++) {
int idx;
char *array[8];
int a;
KeySym ksym;
int k;
char *ptr;
char *tmp;
a = 0;
memset(array, 0, sizeof(char*)*8);
for (i=0; i < mapping->max_keypermod; i++) {
idx = i+j*mapping->max_keypermod;
if (mapping->modifiermap[idx]!=0) {
int l;
for (l=0; l<4; l++) {
ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
if (ksym!=NoSymbol)
break;
}
if (ksym!=NoSymbol)
str = XKeysymToString(ksym);
else
str = NULL;
if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
&& !strstr(str, "Control")) {
array[a++] = wstrdup(str);
}
}
}
for (k=0; k<a; k++) {
if (array[k]==NULL)
continue;
tmp = wstrdup(array[k]);
ptr = strstr(tmp, "_L");
if (ptr)
*ptr = 0;
ptr = strstr(tmp, "_R");
if (ptr)
*ptr = 0;
sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
WMAddPopUpButtonItem(pop, buffer);
for (i=k+1; i<a; i++) {
if (strstr(array[i], tmp)) {
free(array[i]);
array[i]=NULL;
break;
}
}
free(tmp);
}
while (--a>0) {
if (array[a])
free(array[a]);
}
}
if (mapping)
XFreeModifiermap(mapping);
}
static void
mouseButtonClickA(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int i;
for (i=0; i<3; i++) {
if (panel->amb[i]==w)
break;
}
if (i==3)
return;
if (WMGetButtonSelected(panel->lmb[i]))
WMSetButtonSelected(panel->lmb[i], False);
if (WMGetButtonSelected(panel->smb[i]))
WMSetButtonSelected(panel->smb[i], False);
}
static void
mouseButtonClickL(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int i;
for (i=0; i<3; i++) {
if (panel->lmb[i]==w)
break;
}
if (i==3)
return;
if (WMGetButtonSelected(panel->smb[i]))
WMSetButtonSelected(panel->smb[i], False);
if (WMGetButtonSelected(panel->amb[i]))
WMSetButtonSelected(panel->amb[i], False);
}
static void
mouseButtonClickS(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int i;
for (i=0; i<3; i++) {
if (panel->smb[i]==w)
break;
}
if (i==3)
return;
if (WMGetButtonSelected(panel->lmb[i]))
WMSetButtonSelected(panel->lmb[i], False);
if (WMGetButtonSelected(panel->amb[i]))
WMSetButtonSelected(panel->amb[i], False);
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
WMPixmap *icon;
char *buf1, *buf2;
int i;
RColor color;
char *path;
color.red = 0xaa;
color.green = 0xae;
color.blue = 0xaa;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/**************** Mouse Speed ****************/
panel->speedF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->speedF, 245, 100);
WMMoveWidget(panel->speedF, 15, 15);
WMSetFrameTitle(panel->speedF, _("Mouse Speed"));
panel->speedL = WMCreateLabel(panel->speedF);
WMResizeWidget(panel->speedL, 40, 46);
WMMoveWidget(panel->speedL, 15, 14);
WMSetLabelImagePosition(panel->speedL, WIPImageOnly);
path = LocateImage(SPEED_ICON_FILE);
if (path) {
icon = WMCreateBlendedPixmapFromFile(scr, path, &color);
if (icon) {
WMSetLabelImage(panel->speedL, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon %s"), path);
}
free(path);
}
buf1 = wmalloc(strlen(SPEED_IMAGE)+1);
buf2 = wmalloc(strlen(SPEED_IMAGE_S)+1);
for (i = 0; i < 5; i++) {
panel->speedB[i] = WMCreateCustomButton(panel->speedF,
WBBStateChangeMask);
WMResizeWidget(panel->speedB[i], 26, 26);
WMMoveWidget(panel->speedB[i], 60+(35*i), 25);
WMSetButtonBordered(panel->speedB[i], False);
WMSetButtonImagePosition(panel->speedB[i], WIPImageOnly);
WMSetButtonAction(panel->speedB[i], speedClick, panel);
if (i > 0) {
WMGroupButtons(panel->speedB[0], panel->speedB[i]);
}
sprintf(buf1, SPEED_IMAGE, i);
sprintf(buf2, SPEED_IMAGE_S, i);
path = LocateImage(buf1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->speedB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
path = LocateImage(buf2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonAltImage(panel->speedB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
}
}
free(buf1);
free(buf2);
panel->acceL = WMCreateLabel(panel->speedF);
WMResizeWidget(panel->acceL, 100, 16);
WMMoveWidget(panel->acceL, 10, 67);
panel->threL = WMCreateLabel(panel->speedF);
WMResizeWidget(panel->threL, 80, 16);
WMMoveWidget(panel->threL, 120, 67);
WMSetLabelText(panel->threL, _("Threshold:"));
panel->threT = WMCreateTextField(panel->speedF);
WMResizeWidget(panel->threT, 40, 20);
WMMoveWidget(panel->threT, 190, 65);
WMAddNotificationObserver(returnPressed, panel,
WMTextDidEndEditingNotification, panel->threT);
WMMapSubwidgets(panel->speedF);
/***************** Doubleclick Delay ****************/
panel->ddelaF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->ddelaF, 245, 95);
WMMoveWidget(panel->ddelaF, 15, 125);
WMSetFrameTitle(panel->ddelaF, _("Double-Click Delay"));
buf1 = wmalloc(strlen(DELAY_ICON)+1);
buf2 = wmalloc(strlen(DELAY_ICON_S)+1);
for (i = 0; i < 5; i++) {
panel->ddelaB[i] = WMCreateCustomButton(panel->ddelaF,
WBBStateChangeMask);
WMResizeWidget(panel->ddelaB[i], 25, 25);
WMMoveWidget(panel->ddelaB[i], 30+(40*i), 20);
WMSetButtonBordered(panel->ddelaB[i], False);
WMSetButtonImagePosition(panel->ddelaB[i], WIPImageOnly);
WMSetButtonAction(panel->ddelaB[i], doubleClick, panel);
if (i>0) {
WMGroupButtons(panel->ddelaB[0], panel->ddelaB[i]);
}
sprintf(buf1, DELAY_ICON, i+1);
sprintf(buf2, DELAY_ICON_S, i+1);
path = LocateImage(buf1);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonImage(panel->ddelaB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
path = LocateImage(buf2);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetButtonAltImage(panel->ddelaB[i], icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
}
free(buf1);
free(buf2);
panel->tester = CreateDoubleTest(panel->ddelaF, _("Test"));
WMResizeWidget(panel->tester, 84, 29);
WMMoveWidget(panel->tester, 85, 55);
WMMapSubwidgets(panel->ddelaF);
/* ************** Workspace Action Buttons **************** */
panel->menuF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->menuF, 240, 145);
WMMoveWidget(panel->menuF, 270, 15);
WMSetFrameTitle(panel->menuF, _("Workspace Mouse Actions"));
panel->disaB = WMCreateSwitchButton(panel->menuF);
WMResizeWidget(panel->disaB, 185, 19);
WMMoveWidget(panel->disaB, 20, 20);
WMSetButtonText(panel->disaB, _("Disable mouse actions"));
panel->mblL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->mblL, 16, 22);
WMMoveWidget(panel->mblL, 135, 40);
WMSetLabelImagePosition(panel->mblL, WIPImageOnly);
path = LocateImage(MOUSEB_L);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetLabelImage(panel->mblL, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
panel->mbmL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->mbmL, 16, 22);
WMMoveWidget(panel->mbmL, 170, 40);
WMSetLabelImagePosition(panel->mbmL, WIPImageOnly);
path = LocateImage(MOUSEB_M);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetLabelImage(panel->mbmL, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
panel->mbrL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->mbrL, 16, 22);
WMMoveWidget(panel->mbrL, 205, 40);
WMSetLabelImagePosition(panel->mbrL, WIPImageOnly);
path = LocateImage(MOUSEB_R);
if (path) {
icon = WMCreatePixmapFromFile(scr, path);
if (icon) {
WMSetLabelImage(panel->mbrL, icon);
WMReleasePixmap(icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
free(path);
}
panel->appL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->appL, 125, 16);
WMMoveWidget(panel->appL, 5, 65);
WMSetLabelTextAlignment(panel->appL, WARight);
WMSetLabelText(panel->appL, _("Applications menu"));
panel->listL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->listL, 125, 16);
WMMoveWidget(panel->listL, 5, 90);
WMSetLabelTextAlignment(panel->listL, WARight);
WMSetLabelText(panel->listL, _("Window list menu"));
panel->selL = WMCreateLabel(panel->menuF);
WMResizeWidget(panel->selL, 125, 16);
WMMoveWidget(panel->selL, 5, 115);
WMSetLabelTextAlignment(panel->selL, WARight);
WMSetLabelText(panel->selL, _("Select windows"));
for (i=0; i<3; i++) {
panel->amb[i] = WMCreateRadioButton(panel->menuF);
WMResizeWidget(panel->amb[i], 24, 24);
WMMoveWidget(panel->amb[i], 135+35*i, 65);
WMSetButtonText(panel->amb[i], NULL);
WMSetButtonAction(panel->amb[i], mouseButtonClickA, panel);
panel->lmb[i] = WMCreateRadioButton(panel->menuF);
WMResizeWidget(panel->lmb[i], 24, 24);
WMMoveWidget(panel->lmb[i], 135+35*i, 90);
WMSetButtonText(panel->lmb[i], NULL);
WMSetButtonAction(panel->lmb[i], mouseButtonClickL, panel);
panel->smb[i] = WMCreateRadioButton(panel->menuF);
WMResizeWidget(panel->smb[i], 24, 24);
WMMoveWidget(panel->smb[i], 135+35*i, 115);
WMSetButtonText(panel->smb[i], NULL);
WMSetButtonAction(panel->smb[i], mouseButtonClickS, panel);
if (i>0) {
WMGroupButtons(panel->lmb[0], panel->lmb[i]);
WMGroupButtons(panel->amb[0], panel->amb[i]);
WMGroupButtons(panel->smb[0], panel->smb[i]);
}
}
WMMapSubwidgets(panel->menuF);
/* ************** Grab Modifier **************** */
panel->grabF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->grabF, 240, 55);
WMMoveWidget(panel->grabF, 270, 165);
WMSetFrameTitle(panel->grabF, _("Mouse Grab Modifier"));
panel->grabP = WMCreatePopUpButton(panel->grabF);
WMResizeWidget(panel->grabP, 120, 20);
WMMoveWidget(panel->grabP, 60, 25);
fillModifierPopUp(panel->grabP);
WMMapSubwidgets(panel->grabF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
static void
storeCommandInScript(char *cmd, char *line)
{
char *path;
char *p;
FILE *f;
char buffer[128];
p = wusergnusteppath();
path = wmalloc(strlen(p)+64);
sprintf(path, "%s/Library/WindowMaker/autostart", p);
f = fopen(path, "r");
if (!f) {
f = fopen(path, "w");
if (!f) {
wsyserror(_("could not create %s"), path);
goto end;
}
fprintf(f, "#!/bin/sh\n");
fputs(line, f);
fputs("\n", f);
} else {
int len = strlen(cmd);
int ok = 0;
char *tmppath;
FILE *fo;
tmppath = wmalloc(strlen(p)+64);
sprintf(tmppath, "%s/Library/WindowMaker/autostart.tmp", p);
fo = fopen(tmppath, "w");
if (!fo) {
wsyserror(_("could not create temporary file %s"), tmppath);
goto end;
}
while (!feof(f)) {
if (!fgets(buffer, 127, f)) {
break;
}
if (strncmp(buffer, cmd, len)==0) {
if (!ok) {
fputs(line, fo);
fputs("\n", fo);
ok = 1;
}
} else {
fputs(buffer, fo);
}
}
if (!ok) {
fputs(line, fo);
fputs("\n", fo);
}
fclose(fo);
if (rename(tmppath, path)!=0) {
wsyserror(_("could not rename file %s to %s\n"), tmppath, path);
}
free(tmppath);
}
sprintf(buffer, "chmod u+x %s", path);
system(buffer);
end:
free(p);
free(path);
if (f)
fclose(f);
}
static void
storeData(_Panel *panel)
{
char buffer[64];
int i;
char *tmp, *p;
static char *button[3] = {"left", "middle", "right"};
tmp = WMGetTextFieldText(panel->threT);
if (strlen(tmp)==0) {
free(tmp);
tmp = wstrdup("0");
}
sprintf(buffer, XSET" m %i/%i %s\n", (int)(panel->acceleration*10),10, tmp);
storeCommandInScript(XSET" m", buffer);
free(tmp);
for (i=0; i<5; i++) {
if (WMGetButtonSelected(panel->ddelaB[i]))
break;
}
SetIntegerForKey(DELAY(i), "DoubleClickTime");
SetBoolForKey(WMGetButtonSelected(panel->disaB), "DisableWSMouseActions");
for (i=0; i<3; i++) {
if (WMGetButtonSelected(panel->amb[i]))
break;
}
if (i<3)
SetStringForKey(button[i], "ApplicationMenuMouseButton");
for (i=0; i<3; i++) {
if (WMGetButtonSelected(panel->lmb[i]))
break;
}
if (i<3)
SetStringForKey(button[i], "WindowListMouseButton");
for (i=0; i<3; i++) {
if (WMGetButtonSelected(panel->smb[i]))
break;
}
if (i<3)
SetStringForKey(button[i], "SelectWindowsMouseButton");
tmp = WMGetPopUpButtonItem(panel->grabP,
WMGetPopUpButtonSelectedItem(panel->grabP));
tmp = wstrdup(tmp);
p = strchr(tmp, ' ');
*p = 0;
SetStringForKey(tmp, "ModifierKey");
free(tmp);
}
Panel*
InitMouseSettings(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Mouse Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

395
WPrefs.app/Paths.c Normal file
View File

@@ -0,0 +1,395 @@
/* Paths.c- pixmap/icon paths
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
#include <unistd.h>
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *pixF;
WMList *pixL;
WMButton *pixaB;
WMButton *pixrB;
WMTextField *pixT;
WMFrame *icoF;
WMList *icoL;
WMButton *icoaB;
WMButton *icorB;
WMTextField *icoT;
WMColor *red;
WMColor *black;
WMColor *white;
WMFont *font;
} _Panel;
#define ICON_FILE "paths"
static void
addPathToList(WMList *list, int index, char *path)
{
char *fpath = wexpandpath(path);
WMListItem *item;
item = WMInsertListItem(list, index, path);
if (access(fpath, X_OK)!=0) {
item->uflags = 1;
}
free(fpath);
}
static void
showData(_Panel *panel)
{
proplist_t array, val;
int i;
array = GetObjectForKey("IconPath");
if (!array || !PLIsArray(array)) {
if (array)
wwarning(_("bad value in option IconPath. Using default path list"));
addPathToList(panel->icoL, -1, "~/pixmaps");
addPathToList(panel->icoL, -1, "~/GNUstep/Library/Icons");
addPathToList(panel->icoL, -1, "/usr/include/X11/pixmaps");
addPathToList(panel->icoL, -1, "/usr/local/share/WindowMaker/Icons");
addPathToList(panel->icoL, -1, "/usr/local/share/WindowMaker/Pixmaps");
addPathToList(panel->icoL, -1, "/usr/share/WindowMaker/Icons");
} else {
for (i=0; i<PLGetNumberOfElements(array); i++) {
val = PLGetArrayElement(array, i);
addPathToList(panel->icoL, -1, PLGetString(val));
}
}
array = GetObjectForKey("PixmapPath");
if (!array || !PLIsArray(array)) {
if (array)
wwarning(_("bad value in option PixmapPath. Using default path list"));
addPathToList(panel->pixL, -1, "~/pixmaps");
addPathToList(panel->pixL, -1, "~/GNUstep/Library/WindowMaker/Pixmaps");
addPathToList(panel->pixL, -1, "/usr/local/share/WindowMaker/Pixmaps");
} else {
for (i=0; i<PLGetNumberOfElements(array); i++) {
val = PLGetArrayElement(array, i);
addPathToList(panel->pixL, -1, PLGetString(val));
}
}
}
static void
pushButton(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int i;
/* icon paths */
if (w == panel->icoaB) {
char *text = WMGetTextFieldText(panel->icoT);
if (text && strlen(text) > 0) {
i = WMGetListSelectedItemRow(panel->icoL);
if (i >= 0) i++;
addPathToList(panel->icoL, i, text);
WMSetListBottomPosition(panel->icoL,
WMGetListNumberOfRows(panel->icoL));
}
if (text)
free(text);
WMSetTextFieldText(panel->icoT, NULL);
} else if (w == panel->icorB) {
i = WMGetListSelectedItemRow(panel->icoL);
if (i>=0)
WMRemoveListItem(panel->icoL, i);
}
/* pixmap paths */
if (w == panel->pixaB) {
char *text = WMGetTextFieldText(panel->pixT);
if (text && strlen(text) > 0) {
i = WMGetListSelectedItemRow(panel->pixL);
if (i >= 0) i++;
addPathToList(panel->pixL, i, text);
WMSetListBottomPosition(panel->pixL,
WMGetListNumberOfRows(panel->pixL));
}
if (text)
free(text);
WMSetTextFieldText(panel->pixT, NULL);
} else if (w == panel->pixrB) {
i = WMGetListSelectedItemRow(panel->pixL);
if (i>=0)
WMRemoveListItem(panel->pixL, i);
}
}
static void
textEditedObserver(void *observerData, WMNotification *notification)
{
_Panel *panel = (_Panel*)observerData;
switch ((int)WMGetNotificationClientData(notification)) {
case WMReturnTextMovement:
if (WMGetNotificationObject(notification) == panel->icoT)
WMPerformButtonClick(panel->icoaB);
else
WMPerformButtonClick(panel->pixaB);
break;
case WMIllegalTextMovement:
if (WMGetNotificationObject(notification) == panel->icoT) {
WMSetButtonImage(panel->icoaB, NULL);
WMSetButtonImage(panel->icoaB, NULL);
} else {
WMSetButtonImage(panel->pixaB, NULL);
WMSetButtonImage(panel->pixaB, NULL);
}
break;
}
}
static void
textBeginObserver(void *observerData, WMNotification *notification)
{
_Panel *panel = (_Panel*)observerData;
WMScreen *scr = WMWidgetScreen(panel->win);
WMPixmap *arrow1 = WMGetSystemPixmap(scr, WSIReturnArrow);
WMPixmap *arrow2 = WMGetSystemPixmap(scr, WSIHighlightedReturnArrow);
if (WMGetNotificationObject(notification)==panel->icoT) {
WMSetButtonImage(panel->icoaB, arrow1);
WMSetButtonAltImage(panel->icoaB, arrow2);
} else {
WMSetButtonImage(panel->pixaB, arrow1);
WMSetButtonAltImage(panel->pixaB, arrow2);
}
}
static void
listClick(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
char *t;
if (w == panel->icoL) {
t = WMGetListSelectedItem(panel->icoL)->text;
WMSetTextFieldText(panel->icoT, t);
} else {
t = WMGetListSelectedItem(panel->pixL)->text;
WMSetTextFieldText(panel->pixT, t);
}
}
static void
paintItem(WMList *lPtr, Drawable d, char *text, int state, WMRect *rect)
{
int width, height, x, y;
_Panel *panel = (_Panel*)WMGetHangedData(lPtr);
WMScreen *scr = WMWidgetScreen(lPtr);
Display *dpy = WMScreenDisplay(scr);
width = rect->size.width;
height = rect->size.height;
x = rect->pos.x;
y = rect->pos.y;
if (state & WLDSSelected)
XFillRectangle(dpy, d, WMColorGC(panel->white), x, y, width,
height);
else
XClearArea(dpy, d, x, y, width, height, False);
if (state & 1) {
WMDrawString(scr, d, WMColorGC(panel->red), panel->font, x+4, y,
text, strlen(text));
} else {
WMDrawString(scr, d, WMColorGC(panel->black), panel->font, x+4, y,
text, strlen(text));
}
}
static void
storeData(_Panel *panel)
{
proplist_t list;
proplist_t tmp;
int i;
char *p;
list = PLMakeArrayFromElements(NULL, NULL);
for (i=0; i<WMGetListNumberOfRows(panel->icoL); i++) {
p = WMGetListItem(panel->icoL, i)->text;
tmp = PLMakeString(p);
PLAppendArrayElement(list, tmp);
}
SetObjectForKey(list, "IconPath");
list = PLMakeArrayFromElements(NULL, NULL);
for (i=0; i<WMGetListNumberOfRows(panel->pixL); i++) {
p = WMGetListItem(panel->pixL, i)->text;
tmp = PLMakeString(p);
PLAppendArrayElement(list, tmp);
}
SetObjectForKey(list, "PixmapPath");
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
panel->white = WMWhiteColor(scr);
panel->black = WMBlackColor(scr);
panel->red = WMCreateRGBColor(scr, 0xffff, 0, 0, True);
panel->font = WMSystemFontOfSize(scr, 12);
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/* icon path */
panel->icoF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->icoF, 230, 210);
WMMoveWidget(panel->icoF, 25, 10);
WMSetFrameTitle(panel->icoF, _("Icon Search Paths"));
panel->icoL = WMCreateList(panel->icoF);
WMResizeWidget(panel->icoL, 200, 120);
WMMoveWidget(panel->icoL, 15, 20);
WMSetListAction(panel->icoL, listClick, panel);
WMSetListUserDrawProc(panel->icoL, paintItem);
WMHangData(panel->icoL, panel);
panel->icoaB = WMCreateCommandButton(panel->icoF);
WMResizeWidget(panel->icoaB, 90, 24);
WMMoveWidget(panel->icoaB, 125, 145);
WMSetButtonText(panel->icoaB, _("Add"));
WMSetButtonAction(panel->icoaB, pushButton, panel);
WMSetButtonImagePosition(panel->icoaB, WIPRight);
panel->icorB = WMCreateCommandButton(panel->icoF);
WMResizeWidget(panel->icorB, 90, 24);
WMMoveWidget(panel->icorB, 15, 145);
WMSetButtonText(panel->icorB, _("Remove"));
WMSetButtonAction(panel->icorB, pushButton, panel);
panel->icoT = WMCreateTextField(panel->icoF);
WMResizeWidget(panel->icoT, 200, 20);
WMMoveWidget(panel->icoT, 15, 175);
WMAddNotificationObserver(textEditedObserver, panel,
WMTextDidEndEditingNotification, panel->icoT);
WMAddNotificationObserver(textBeginObserver, panel,
WMTextDidBeginEditingNotification, panel->icoT);
WMMapSubwidgets(panel->icoF);
/* pixmap path */
panel->pixF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->pixF, 230, 210);
WMMoveWidget(panel->pixF, 270, 10);
WMSetFrameTitle(panel->pixF, _("Pixmap Search Paths"));
panel->pixL = WMCreateList(panel->pixF);
WMResizeWidget(panel->pixL, 200, 120);
WMMoveWidget(panel->pixL, 15, 20);
WMSetListAction(panel->pixL, listClick, panel);
WMSetListUserDrawProc(panel->pixL, paintItem);
WMHangData(panel->pixL, panel);
panel->pixaB = WMCreateCommandButton(panel->pixF);
WMResizeWidget(panel->pixaB, 90, 24);
WMMoveWidget(panel->pixaB, 125, 145);
WMSetButtonText(panel->pixaB, _("Add"));
WMSetButtonAction(panel->pixaB, pushButton, panel);
WMSetButtonImagePosition(panel->pixaB, WIPRight);
panel->pixrB = WMCreateCommandButton(panel->pixF);
WMResizeWidget(panel->pixrB, 90, 24);
WMMoveWidget(panel->pixrB, 15, 145);
WMSetButtonText(panel->pixrB, _("Remove"));
WMSetButtonAction(panel->pixrB, pushButton, panel);
panel->pixT= WMCreateTextField(panel->pixF);
WMResizeWidget(panel->pixT, 200, 20);
WMMoveWidget(panel->pixT, 15, 175);
WMAddNotificationObserver(textEditedObserver, panel,
WMTextDidEndEditingNotification, panel->pixT);
WMAddNotificationObserver(textBeginObserver, panel,
WMTextDidBeginEditingNotification, panel->pixT);
WMMapSubwidgets(panel->pixF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
Panel*
InitPaths(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Search Path Configuration");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

225
WPrefs.app/Preferences.c Normal file
View File

@@ -0,0 +1,225 @@
/* Preferences.c- misc personal preferences
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *sizeF;
WMPopUpButton *sizeP;
WMFrame *posiF;
WMPopUpButton *posiP;
WMFrame *ballF;
WMButton *ballB[4];
WMFrame *optF;
WMButton *raisB;
} _Panel;
#define ICON_FILE "ergonomic"
static void
showData(_Panel *panel)
{
char *str;
str = GetStringForKey("ResizeDisplay");
if (strcasecmp(str, "corner")==0)
WMSetPopUpButtonSelectedItem(panel->sizeP, 0);
else if (strcasecmp(str, "center")==0)
WMSetPopUpButtonSelectedItem(panel->sizeP, 1);
else if (strcasecmp(str, "floating")==0)
WMSetPopUpButtonSelectedItem(panel->sizeP, 2);
else if (strcasecmp(str, "line")==0)
WMSetPopUpButtonSelectedItem(panel->sizeP, 3);
str = GetStringForKey("MoveDisplay");
if (strcasecmp(str, "corner")==0)
WMSetPopUpButtonSelectedItem(panel->posiP, 0);
else if (strcasecmp(str, "center")==0)
WMSetPopUpButtonSelectedItem(panel->posiP, 1);
else if (strcasecmp(str, "floating")==0)
WMSetPopUpButtonSelectedItem(panel->posiP, 2);
WMSetButtonSelected(panel->raisB, GetBoolForKey("CirculateRaise"));
WMSetButtonSelected(panel->ballB[0], GetBoolForKey("WindowTitleBalloons"));
WMSetButtonSelected(panel->ballB[1], GetBoolForKey("MiniwindowTitleBalloons"));
WMSetButtonSelected(panel->ballB[2], GetBoolForKey("AppIconBalloons"));
}
static void
storeData(_Panel *panel)
{
char *str;
switch (WMGetPopUpButtonSelectedItem(panel->sizeP)) {
case 0:
str = "corner";
break;
case 1:
str = "center";
break;
case 2:
str = "floating";
break;
default:
str = "line";
break;
}
SetStringForKey(str, "ResizeDisplay");
switch (WMGetPopUpButtonSelectedItem(panel->posiP)) {
case 0:
str = "corner";
break;
case 1:
str = "center";
break;
default:
str = "floating";
break;
}
SetStringForKey(str, "MoveDisplay");
SetBoolForKey(WMGetButtonSelected(panel->raisB), "CirculateRaise");
SetBoolForKey(WMGetButtonSelected(panel->ballB[0]), "WindowTitleBalloons");
SetBoolForKey(WMGetButtonSelected(panel->ballB[1]), "MiniwindowTitleBalloons");
SetBoolForKey(WMGetButtonSelected(panel->ballB[2]), "AppIconBalloons");
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
int i;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/***************** Size Display ****************/
panel->sizeF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->sizeF, 240, 60);
WMMoveWidget(panel->sizeF, 20, 10);
WMSetFrameTitle(panel->sizeF, _("Size Display"));
panel->sizeP = WMCreatePopUpButton(panel->sizeF);
WMResizeWidget(panel->sizeP, 180, 20);
WMMoveWidget(panel->sizeP, 32, 24);
WMAddPopUpButtonItem(panel->sizeP, _("Corner of screen"));
WMAddPopUpButtonItem(panel->sizeP, _("Center of screen"));
WMAddPopUpButtonItem(panel->sizeP, _("Center of resized window"));
WMAddPopUpButtonItem(panel->sizeP, _("Technical drawing-like"));
WMMapSubwidgets(panel->sizeF);
/***************** Position Display ****************/
panel->posiF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->posiF, 240, 60);
WMMoveWidget(panel->posiF, 20, 75);
WMSetFrameTitle(panel->posiF, _("Position Display"));
panel->posiP = WMCreatePopUpButton(panel->posiF);
WMResizeWidget(panel->posiP, 180, 20);
WMMoveWidget(panel->posiP, 32, 24);
WMAddPopUpButtonItem(panel->posiP, _("Corner of screen"));
WMAddPopUpButtonItem(panel->posiP, _("Center of screen"));
WMAddPopUpButtonItem(panel->posiP, _("Center of resized window"));
WMMapSubwidgets(panel->posiF);
/***************** Balloon Text ****************/
panel->ballF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->ballF, 235, 125);
WMMoveWidget(panel->ballF, 270, 10);
WMSetFrameTitle(panel->ballF, _("Show balloon text for..."));
for (i=0; i<3; i++) {
panel->ballB[i] = WMCreateSwitchButton(panel->ballF);
WMResizeWidget(panel->ballB[i], 205, 20);
WMMoveWidget(panel->ballB[i], 15, 25+i*30);
}
WMSetButtonText(panel->ballB[0], _("incomplete window titles"));
WMSetButtonText(panel->ballB[1], _("miniwindow titles"));
WMSetButtonText(panel->ballB[2], _("application/dock icons"));
/* WMSetButtonText(panel->ballB[3], "help");*/
WMMapSubwidgets(panel->ballF);
/***************** Options ****************/
panel->optF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->optF, 485, 75);
WMMoveWidget(panel->optF, 20, 145);
panel->raisB = WMCreateSwitchButton(panel->optF);
WMResizeWidget(panel->raisB, 440, 20);
WMMoveWidget(panel->raisB, 20, 25);
WMSetButtonText(panel->raisB, _("Raise window when switching focus with keyboard."));
WMMapSubwidgets(panel->optF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
Panel*
InitPreferences(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Miscellaneous Ergonomic Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

111
WPrefs.app/README Normal file
View File

@@ -0,0 +1,111 @@
WPrefs.app
==========
The WindowMaker Prerefences Application
WPrefs.app is the preferences "editor" for the WindowMaker window
manager. It can be used to set most of the preference options of WindowMaker
and define it's applications menu. It also can change some settings
that do not belong to WindowMaker.
Although WPrefs.app is designed to be easy to use, you should read the
user guide to be fully aware of all available options and other features
of WindowMaker that are not related to configuration.
To run WPrefs, do not put it in your search path. Instead, run it
with the full path, like /usr/local/GNUstep/Apps/WPrefs.app/WPrefs
Then, dock it's application icon. The dock will automatically detect it's
icon and use it.
If you change configuration often, you might want to leave WPrefs
always running, leaving it hidden while not in use. You can also make it
be automatically started with WindowMaker and toggle the Start Hidden
option in the attributes panel for the WPrefs window. Of course, it will
use some memory, but by leaving it hidden it'll probably be swapped out and
stay there until you unhide it.
WPrefs is still under development. Some of the configuration options are
not yet configurable from WPrefs, notably the appearance related options.
It might contain bugs that can corrupt your configuration files, so backup
the contents of the ~/GNUstep/Defaults directory before using it.
Notes
-----
The mouse speed configuration is saved as a call for xset in
~/G/D/L/W/autostart. WindowMaker calls this file when it is started.
If you don't want or can't use the menu definition section, do not
open it's section (or if you do open it, do not Save), or WPrefs will
overwrite your ~/G/D/WMRootMenu file.
Only options that have different values than what is found in the
system-wide configuration file is saved.
WPrefs only supports property list menus. If you have a plain text file
menu, it will not be read by WPrefs. You can either recreate the menu from
scratch or not use WPrefs for menu definition. The old menu will not be
overwritten if you recreate it.
Build
-----
WPrefs will be built automatically and installed with the rest of WindowMaker.
Customized Installation
-----------------------
By default, WPrefs.app will be installed in the GNUstep applications
directory, which is /usr/local/GNUstep/Apps. If you want to install it
somewhere else, like in /some_weird_path/Apps, set the GNUSTEP_LOCAL_ROOT
environment variable to some_weird_path before running configure for
WindowMaker. Leave this variable always set (make it be set from your
.profile or .tcshrc or whatever), or WPrefs.app will not find it's resource
files (like icons).
If you change your mind after installing, you can move the .app directory
to one of the following GNUstep/Apps directories:
/usr/GNUstep/Apps
OR
/usr/local/GNUstep/Apps
OR
~/GNUstep/Apps
Credits
-------
User interface design, programming and a few icons:
Alfredo K. Kojima <kojima@windowmaker.org>
Icon and image artwork:
Marco van Hylckama Vlieg <fatal@global.uibk.ac.at>
WindowMaker
-----------
If for some weird reason you end up with this preferences program and
don't have WindowMaker yet, you can get more information about it at
http://windowmaker.org and download it at ftp://ftp.windowmaker.org
Contact
-------
Send comments and bug reports to kojima@windowmaker.org
Use the WindowMaker BUGFORM to report bugs.

335
WPrefs.app/Text.c Normal file
View File

@@ -0,0 +1,335 @@
/* Text.c- text/font settings
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMPopUpButton *secP;
WMButton *setB;
WMTextField *nameT;
WMLabel *sampleL;
WMFrame *alignF;
WMButton *leftB;
WMButton *centerB;
WMButton *rightB;
/**/
WMFont *windowF;
char *windowFont;
WMFont *menuF;
char *menuFont;
WMFont *itemF;
char *itemFont;
WMFont *clipF;
char *clipFont;
WMFont *iconF;
char *iconFont;
WMFont *geoF;
char *geoFont;
} _Panel;
#define ICON_FILE "fonts"
static void
changePage(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int sect;
sect = WMGetPopUpButtonSelectedItem(w);
if (sect == 0) {
WMMapWidget(panel->alignF);
} else {
WMUnmapWidget(panel->alignF);
}
switch (sect) {
case 0:
WMSetTextFieldText(panel->nameT, panel->windowFont);
WMSetLabelFont(panel->sampleL, panel->windowF);
break;
case 1:
WMSetTextFieldText(panel->nameT, panel->menuFont);
WMSetLabelFont(panel->sampleL, panel->menuF);
break;
case 2:
WMSetTextFieldText(panel->nameT, panel->itemFont);
WMSetLabelFont(panel->sampleL, panel->itemF);
break;
case 3:
WMSetTextFieldText(panel->nameT, panel->iconFont);
WMSetLabelFont(panel->sampleL, panel->iconF);
break;
case 4:
WMSetTextFieldText(panel->nameT, panel->clipFont);
WMSetLabelFont(panel->sampleL, panel->clipF);
break;
case 5:
WMSetTextFieldText(panel->nameT, panel->geoFont);
WMSetLabelFont(panel->sampleL, panel->geoF);
break;
}
}
static void
showData(_Panel *panel)
{
WMScreen *scr = WMWidgetScreen(panel->win);
char *str;
str = GetStringForKey("WindowTitleFont");
if (!str)
str = "-*-helvetica-bold-r-normal-*-12-*";
panel->windowF = WMCreateFont(scr, str);
panel->windowFont = wstrdup(str);
str = GetStringForKey("MenuTitleFont");
if (!str)
str = "-*-helvetica-bold-r-normal-*-12-*";
panel->menuF = WMCreateFont(scr, str);
panel->menuFont = wstrdup(str);
str = GetStringForKey("MenuTextFont");
if (!str)
str = "-*-helvetica-medium-r-normal-*-12-*";
panel->itemF = WMCreateFont(scr, str);
panel->itemFont = wstrdup(str);
str = GetStringForKey("IconTitleFont");
if (!str)
str = "-*-helvetica-medium-r-normal-*-8-*";
panel->iconF = WMCreateFont(scr, str);
panel->iconFont = wstrdup(str);
str = GetStringForKey("ClipTitleFont");
if (!str)
str = "-*-helvetica-medium-r-normal-*-10-*";
panel->clipF = WMCreateFont(scr, str);
panel->clipFont = wstrdup(str);
str = GetStringForKey("DisplayFont");
if (!str)
str = "-*-helvetica-medium-r-normal-*-12-*";
panel->geoF = WMCreateFont(scr, str);
panel->geoFont = wstrdup(str);
str = GetStringForKey("TitleJustify");
if (strcasecmp(str,"left")==0)
WMPerformButtonClick(panel->leftB);
else if (strcasecmp(str,"center")==0)
WMPerformButtonClick(panel->centerB);
else if (strcasecmp(str,"right")==0)
WMPerformButtonClick(panel->rightB);
changePage(panel->secP, panel);
}
static void
editedName(void *data, WMNotification *notification)
{
_Panel *panel = (_Panel*)data;
if ((int)WMGetNotificationClientData(notification)==WMReturnTextMovement) {
char *name;
WMFont *font;
char buffer[256];
name = WMGetTextFieldText(panel->nameT);
font = WMCreateFont(WMWidgetScreen(panel->win), name);
if (!font) {
sprintf(buffer, _("Invalid font %s."), name);
WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
_("Error"), buffer, _("OK"), NULL, NULL);
free(name);
} else {
int sect;
sect = WMGetPopUpButtonSelectedItem(panel->secP);
switch (sect) {
case 0:
if (panel->windowFont)
free(panel->windowFont);
panel->windowFont = name;
if (panel->windowF)
WMReleaseFont(panel->windowF);
panel->windowF = font;
break;
case 1:
if (panel->menuFont)
free(panel->menuFont);
panel->menuFont = name;
if (panel->menuF)
WMReleaseFont(panel->menuF);
panel->menuF = font;
break;
case 2:
if (panel->itemFont)
free(panel->itemFont);
panel->itemFont = name;
if (panel->itemF)
WMReleaseFont(panel->itemF);
panel->itemF = font;
break;
case 3:
if (panel->iconFont)
free(panel->iconFont);
panel->iconFont = name;
if (panel->iconF)
WMReleaseFont(panel->iconF);
panel->iconF = font;
break;
case 4:
if (panel->clipFont)
free(panel->clipFont);
panel->clipFont = name;
if (panel->clipF)
WMReleaseFont(panel->clipF);
panel->clipF = font;
break;
case 5:
if (panel->geoFont)
free(panel->geoFont);
panel->geoFont = name;
if (panel->geoF)
WMReleaseFont(panel->geoF);
panel->geoF = font;
break;
}
changePage(panel->secP, panel);
}
}
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
panel->setB = WMCreateCommandButton(panel->frame);
WMResizeWidget(panel->setB, 145, 20);
WMMoveWidget(panel->setB, 50, 25);
WMSetButtonText(panel->setB, _("Set Font..."));
panel->secP = WMCreatePopUpButton(panel->frame);
WMResizeWidget(panel->secP, 260, 20);
WMMoveWidget(panel->secP, 205, 25);
WMSetPopUpButtonAction(panel->secP, changePage, panel);
WMAddPopUpButtonItem(panel->secP, _("Window Title Font"));
WMAddPopUpButtonItem(panel->secP, _("Menu Title Font"));
WMAddPopUpButtonItem(panel->secP, _("Menu Item Font"));
WMAddPopUpButtonItem(panel->secP, _("Icon Title Font"));
WMAddPopUpButtonItem(panel->secP, _("Clip Title Font"));
WMAddPopUpButtonItem(panel->secP, _("Geometry Display Font"));
WMSetPopUpButtonSelectedItem(panel->secP, 0);
panel->nameT = WMCreateTextField(panel->frame);
WMResizeWidget(panel->nameT, 285, 24);
WMMoveWidget(panel->nameT, 50, 80);
WMAddNotificationObserver(editedName, panel,
WMTextDidEndEditingNotification, panel->nameT);
panel->sampleL = WMCreateLabel(panel->frame);
WMResizeWidget(panel->sampleL, 285, 85);
WMMoveWidget(panel->sampleL, 50, 135);
WMSetLabelRelief(panel->sampleL, WRSunken);
WMSetLabelText(panel->sampleL, _("Sample Text\nabcdefghijklmnopqrstuvxywz\nABCDEFGHIJKLMNOPQRSTUVXYWZ\n0123456789"));
panel->alignF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->alignF, 120, 160);
WMMoveWidget(panel->alignF, 345, 60);
WMSetFrameTitle(panel->alignF, _("Alignment"));
panel->leftB = WMCreateButton(panel->alignF, WBTOnOff);
WMResizeWidget(panel->leftB, 100, 24);
WMMoveWidget(panel->leftB, 10, 25);
WMSetButtonText(panel->leftB, _("Left"));
WMSetButtonTextAlignment(panel->leftB, WALeft);
panel->centerB = WMCreateButton(panel->alignF, WBTOnOff);
WMResizeWidget(panel->centerB, 100, 24);
WMMoveWidget(panel->centerB, 10, 70);
WMSetButtonText(panel->centerB, _("Center"));
WMSetButtonTextAlignment(panel->centerB, WACenter);
WMGroupButtons(panel->leftB, panel->centerB);
panel->rightB = WMCreateButton(panel->alignF, WBTOnOff);
WMResizeWidget(panel->rightB, 100, 24);
WMMoveWidget(panel->rightB, 10, 115);
WMSetButtonText(panel->rightB, _("Right"));
WMSetButtonTextAlignment(panel->rightB, WARight);
WMGroupButtons(panel->leftB, panel->rightB);
WMMapSubwidgets(panel->alignF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
Panel*
InitText(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Text Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
AddSection(panel, ICON_FILE);
return panel;
}

View File

@@ -0,0 +1,641 @@
/* TextureAndColor.c- color/texture for titlebar etc.
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMPopUpButton *secP;
WMLabel *prevL;
/* window titlebar */
WMFrame *focF;
WMColorWell *focC;
WMLabel *focL;
WMTextField *focT;
WMLabel *foc2L;
WMButton *focB;
WMFrame *unfF;
WMColorWell *unfC;
WMLabel *unfL;
WMTextField *unfT;
WMLabel *unf2L;
WMButton *unfB;
WMFrame *ownF;
WMColorWell *ownC;
WMLabel *ownL;
WMTextField *ownT;
WMLabel *own2L;
WMButton *ownB;
/* menu title */
WMFrame *backF;
WMTextField *backT;
WMButton *backB;
WMFrame *textF;
WMColorWell *textC;
/* menu items */
WMFrame *unsF;
WMTextField *unsT;
WMButton *unsB;
WMLabel *unsL;
WMColorWell *unsnC;
WMLabel *unsnL;
WMColorWell *unsdC;
WMLabel *unsdL;
WMFrame *selF;
WMColorWell *seltC;
WMLabel *seltL;
WMColorWell *selbC;
WMLabel *selbL;
/* workspace/clip */
WMFrame *workF;
WMTextField *workT;
WMButton *workB;
WMFrame *clipF;
WMColorWell *clipnC;
WMColorWell *clipcC;
WMLabel *clipnL;
WMLabel *clipcL;
/* icon */
WMFrame *iconF;
WMTextField *iconT;
WMButton *iconB;
Pixmap ftitle;
Pixmap utitle;
Pixmap otitle;
Pixmap icon;
Pixmap back;
Pixmap mtitle;
Pixmap mitem;
} _Panel;
#define ICON_FILE "appearance"
#define FTITLE (1<<0)
#define UTITLE (1<<1)
#define OTITLE (1<<2)
#define ICON (1<<3)
#define BACK (1<<4)
#define MTITLE (1<<5)
#define MITEM (1<<6)
#define EVERYTHING 0xff
static void
updatePreviewBox(_Panel *panel, int elements)
{
}
static void
changePage(WMWidget *self, void *data)
{
int i;
_Panel *panel = (_Panel*)data;
i = WMGetPopUpButtonSelectedItem(self);
if (i==0) {
WMMapWidget(panel->focF);
WMMapWidget(panel->unfF);
WMMapWidget(panel->ownF);
} else if (i==1) {
WMMapWidget(panel->backF);
WMMapWidget(panel->textF);
} else if (i==2) {
WMMapWidget(panel->unsF);
WMMapWidget(panel->selF);
} else if (i==3) {
WMMapWidget(panel->workF);
WMMapWidget(panel->clipF);
} else if (i==4) {
WMMapWidget(panel->iconF);
}
if (i!=0) {
WMUnmapWidget(panel->focF);
WMUnmapWidget(panel->unfF);
WMUnmapWidget(panel->ownF);
}
if (i!=1) {
WMUnmapWidget(panel->backF);
WMUnmapWidget(panel->textF);
}
if (i!=2) {
WMUnmapWidget(panel->unsF);
WMUnmapWidget(panel->selF);
}
if (i!=3) {
WMUnmapWidget(panel->workF);
WMUnmapWidget(panel->clipF);
}
if (i!=4) {
WMUnmapWidget(panel->iconF);
}
}
static char*
getStrArrayForKey(char *key)
{
proplist_t v;
v = GetObjectForKey(key);
if (!v)
return NULL;
return PLGetDescription(v);
}
static void
showData(_Panel *panel)
{
char *str;
WMScreen *scr = WMWidgetScreen(panel->win);
WMColor *color;
str = GetStringForKey("FTitleColor");
if (!str)
str = "white";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->focC, color);
WMReleaseColor(color);
str = GetStringForKey("PTitleColor");
if (!str)
str = "white";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->ownC, color);
WMReleaseColor(color);
str = GetStringForKey("UTitleColor");
if (!str)
str = "black";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->unfC, color);
WMReleaseColor(color);
str = getStrArrayForKey("FTitleBack");
if (!str)
str = wstrdup("(solid, black)");
WMSetTextFieldText(panel->focT, str);
free(str);
str = getStrArrayForKey("PTitleBack");
if (!str)
str = wstrdup("(solid, gray40)");
WMSetTextFieldText(panel->ownT, str);
free(str);
str = getStrArrayForKey("UTitleBack");
if (!str)
str = wstrdup("(solid, grey66)");
WMSetTextFieldText(panel->unfT, str);
free(str);
/**/
str = GetStringForKey("MenuTitleColor");
if (!str)
str = "white";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->textC, color);
WMReleaseColor(color);
str = getStrArrayForKey("MenuTitleBack");
if (!str)
str = wstrdup("(solid, black)");
WMSetTextFieldText(panel->backT, str);
free(str);
/**/
str = getStrArrayForKey("MenuTextBack");
if (!str)
str = wstrdup("gray66");
WMSetTextFieldText(panel->unsT, str);
free(str);
str = GetStringForKey("MenuTextColor");
if (!str)
str = "black";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->unsnC, color);
WMReleaseColor(color);
str = GetStringForKey("MenuDisabledColor");
if (!str)
str = "gray40";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->unsdC, color);
WMReleaseColor(color);
str = GetStringForKey("HighlightTextColor");
if (!str)
str = "white";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->seltC, color);
WMReleaseColor(color);
str = GetStringForKey("HighlightColor");
if (!str)
str = "black";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->selbC, color);
WMReleaseColor(color);
/**/
str = getStrArrayForKey("WorkspaceBack");
WMSetTextFieldText(panel->workT, str);
if (str)
free(str);
str = GetStringForKey("ClipTitleColor");
if (!str)
str = "black";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->clipnC, color);
WMReleaseColor(color);
str = GetStringForKey("CClipTitleColor");
if (!str)
str = "grey40";
color = WMCreateNamedColor(scr, str, True);
WMSetColorWellColor(panel->clipcC, color);
WMReleaseColor(color);
/**/
str = getStrArrayForKey("IconBack");
if (!str)
str = wstrdup("(solid, gray66)");
WMSetTextFieldText(panel->iconT, str);
free(str);
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
panel->secP = WMCreatePopUpButton(panel->frame);
WMResizeWidget(panel->secP, 220, 20);
WMMoveWidget(panel->secP, 15, 10);
WMSetPopUpButtonAction(panel->secP, changePage, panel);
WMAddPopUpButtonItem(panel->secP, _("Window Title Bar"));
WMAddPopUpButtonItem(panel->secP, _("Menu Title Bar"));
WMAddPopUpButtonItem(panel->secP, _("Menu Items"));
WMAddPopUpButtonItem(panel->secP, _("Workspace/Clip"));
WMAddPopUpButtonItem(panel->secP, _("Icons"));
panel->prevL = WMCreateLabel(panel->frame);
WMResizeWidget(panel->prevL, 220, 185);
WMMoveWidget(panel->prevL, 15, 40);
WMSetLabelRelief(panel->prevL, WRSunken);
/* window titlebar */
panel->focF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->focF, 265, 70);
WMMoveWidget(panel->focF, 245, 5);
WMSetFrameTitle(panel->focF, _("Focused Window"));
panel->focC = WMCreateColorWell(panel->focF);
WMResizeWidget(panel->focC, 60, 35);
WMMoveWidget(panel->focC, 15, 15);
panel->focT = WMCreateTextField(panel->focF);
WMResizeWidget(panel->focT, 116, 20);
WMMoveWidget(panel->focT, 85, 25);
panel->foc2L = WMCreateLabel(panel->focF);
WMResizeWidget(panel->foc2L, 165, 16);
WMMoveWidget(panel->foc2L, 90, 50);
WMSetLabelText(panel->foc2L, _("Texture"));
WMSetLabelTextAlignment(panel->foc2L, WACenter);
panel->focL = WMCreateLabel(panel->focF);
WMResizeWidget(panel->focL, 100, 16);
WMMoveWidget(panel->focL, 15, 50);
WMSetLabelText(panel->focL, _("Text Color"));
panel->focB = WMCreateCommandButton(panel->focF);
WMResizeWidget(panel->focB, 48, 22);
WMMoveWidget(panel->focB, 205, 24);
WMSetButtonText(panel->focB, _("Set..."));
WMMapSubwidgets(panel->focF);
/**/
panel->unfF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->unfF, 265, 70);
WMMoveWidget(panel->unfF, 245, 80);
WMSetFrameTitle(panel->unfF, _("Unfocused Window"));
panel->unfC = WMCreateColorWell(panel->unfF);
WMResizeWidget(panel->unfC, 60, 35);
WMMoveWidget(panel->unfC, 15, 15);
panel->unfT = WMCreateTextField(panel->unfF);
WMResizeWidget(panel->unfT, 116, 20);
WMMoveWidget(panel->unfT, 85, 25);
panel->unf2L = WMCreateLabel(panel->unfF);
WMResizeWidget(panel->unf2L, 165, 16);
WMMoveWidget(panel->unf2L, 90, 50);
WMSetLabelText(panel->unf2L, _("Texture"));
WMSetLabelTextAlignment(panel->unf2L, WACenter);
panel->unfL = WMCreateLabel(panel->unfF);
WMResizeWidget(panel->unfL, 100, 16);
WMMoveWidget(panel->unfL, 15, 50);
WMSetLabelText(panel->unfL, _("Text Color"));
panel->unfB = WMCreateCommandButton(panel->unfF);
WMResizeWidget(panel->unfB, 48, 22);
WMMoveWidget(panel->unfB, 205, 24);
WMSetButtonText(panel->unfB, _("Set..."));
WMMapSubwidgets(panel->unfF);
/**/
panel->ownF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->ownF, 265, 70);
WMMoveWidget(panel->ownF, 245, 155);
WMSetFrameTitle(panel->ownF, _("Owner of Focused Window"));
panel->ownC = WMCreateColorWell(panel->ownF);
WMResizeWidget(panel->ownC, 60, 35);
WMMoveWidget(panel->ownC, 15, 15);
panel->ownT = WMCreateTextField(panel->ownF);
WMResizeWidget(panel->ownT, 116, 20);
WMMoveWidget(panel->ownT, 85, 25);
panel->own2L = WMCreateLabel(panel->ownF);
WMResizeWidget(panel->own2L, 165, 16);
WMMoveWidget(panel->own2L, 90, 50);
WMSetLabelText(panel->own2L, _("Texture"));
WMSetLabelTextAlignment(panel->own2L, WACenter);
panel->ownL = WMCreateLabel(panel->ownF);
WMResizeWidget(panel->ownL, 100, 16);
WMMoveWidget(panel->ownL, 15, 50);
WMSetLabelText(panel->ownL, _("Text Color"));
panel->ownB = WMCreateCommandButton(panel->ownF);
WMResizeWidget(panel->ownB, 48, 22);
WMMoveWidget(panel->ownB, 205, 24);
WMSetButtonText(panel->ownB, _("Set..."));
WMMapSubwidgets(panel->ownF);
/***************** Menu Item *****************/
panel->unsF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->unsF, 260, 140);
WMMoveWidget(panel->unsF, 250, 5);
WMSetFrameTitle(panel->unsF, _("Unselected Items"));
panel->unsT = WMCreateTextField(panel->unsF);
WMResizeWidget(panel->unsT, 175, 20);
WMMoveWidget(panel->unsT, 15, 25);
panel->unsL = WMCreateLabel(panel->unsF);
WMResizeWidget(panel->unsL, 175, 16);
WMMoveWidget(panel->unsL, 15, 50);
WMSetLabelTextAlignment(panel->unsL, WACenter);
WMSetLabelText(panel->unsL, _("Background"));
panel->unsB = WMCreateCommandButton(panel->unsF);
WMResizeWidget(panel->unsB, 48, 22);
WMMoveWidget(panel->unsB, 200, 24);
WMSetButtonText(panel->unsB, _("Set..."));
panel->unsnC = WMCreateColorWell(panel->unsF);
WMResizeWidget(panel->unsnC, 60, 40);
WMMoveWidget(panel->unsnC, 40, 75);
panel->unsnL = WMCreateLabel(panel->unsF);
WMResizeWidget(panel->unsnL, 120, 16);
WMMoveWidget(panel->unsnL, 10, 117);
WMSetLabelTextAlignment(panel->unsnL, WACenter);
WMSetLabelText(panel->unsnL, _("Normal Text"));
panel->unsdC = WMCreateColorWell(panel->unsF);
WMResizeWidget(panel->unsdC, 60, 40);
WMMoveWidget(panel->unsdC, 160, 75);
panel->unsdL = WMCreateLabel(panel->unsF);
WMResizeWidget(panel->unsdL, 120, 16);
WMMoveWidget(panel->unsdL, 130, 117);
WMSetLabelTextAlignment(panel->unsdL, WACenter);
WMSetLabelText(panel->unsdL, _("Disabled Text"));
WMMapSubwidgets(panel->unsF);
/**/
panel->selF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->selF, 260, 75);
WMMoveWidget(panel->selF, 250, 150);
WMSetFrameTitle(panel->selF, _("Selected Items"));
panel->seltC = WMCreateColorWell(panel->selF);
WMResizeWidget(panel->seltC, 60, 36);
WMMoveWidget(panel->seltC, 40, 20);
panel->seltL = WMCreateLabel(panel->selF);
WMResizeWidget(panel->seltL, 120, 16);
WMMoveWidget(panel->seltL, 10, 56);
WMSetLabelTextAlignment(panel->seltL, WACenter);
WMSetLabelText(panel->seltL, _("Text"));
panel->selbC = WMCreateColorWell(panel->selF);
WMResizeWidget(panel->selbC, 60, 36);
WMMoveWidget(panel->selbC, 160, 20);
panel->selbL = WMCreateLabel(panel->selF);
WMResizeWidget(panel->selbL, 120, 16);
WMMoveWidget(panel->selbL, 130, 56);
WMSetLabelTextAlignment(panel->selbL, WACenter);
WMSetLabelText(panel->selbL, _("Background"));
WMMapSubwidgets(panel->selF);
/***************** Menu Title *****************/
panel->backF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->backF, 260, 110);
WMMoveWidget(panel->backF, 250, 35);
WMSetFrameTitle(panel->backF, _("Menu Title Background"));
panel->backT = WMCreateTextField(panel->backF);
WMResizeWidget(panel->backT, 210, 20);
WMMoveWidget(panel->backT, 25, 35);
panel->backB = WMCreateCommandButton(panel->backF);
WMResizeWidget(panel->backB, 50, 24);
WMMoveWidget(panel->backB, 185, 60);
WMSetButtonText(panel->backB, _("Set..."));
WMMapSubwidgets(panel->backF);
/**/
panel->textF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->textF, 260, 75);
WMMoveWidget(panel->textF, 250, 150);
WMSetFrameTitle(panel->textF, _("Menu Title Text"));
panel->textC = WMCreateColorWell(panel->textF);
WMResizeWidget(panel->textC, 60, 40);
WMMoveWidget(panel->textC, 100, 20);
WMMapSubwidgets(panel->textF);
/***************** Workspace ****************/
panel->workF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->workF, 260, 90);
WMMoveWidget(panel->workF, 250, 35);
WMSetFrameTitle(panel->workF, _("Workspace Background"));
panel->workT = WMCreateTextField(panel->workF);
WMResizeWidget(panel->workT, 220, 20);
WMMoveWidget(panel->workT, 20, 25);
panel->workB = WMCreateCommandButton(panel->workF);
WMResizeWidget(panel->workB, 70, 24);
WMMoveWidget(panel->workB, 170, 55);
WMSetButtonText(panel->workB, _("Change"));
/**/
panel->clipF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->clipF, 260, 90);
WMMoveWidget(panel->clipF, 250, 135);
WMSetFrameTitle(panel->clipF, _("Clip Title Text"));
panel->clipnC = WMCreateColorWell(panel->clipF);
WMResizeWidget(panel->clipnC, 60, 40);
WMMoveWidget(panel->clipnC, 40, 25);
panel->clipnL = WMCreateLabel(panel->clipF);
WMResizeWidget(panel->clipnL, 120, 16);
WMMoveWidget(panel->clipnL, 10, 70);
WMSetLabelTextAlignment(panel->clipnL, WACenter);
WMSetLabelText(panel->clipnL, _("Normal"));
panel->clipcC = WMCreateColorWell(panel->clipF);
WMResizeWidget(panel->clipcC, 60, 40);
WMMoveWidget(panel->clipcC, 160, 25);
panel->clipcL = WMCreateLabel(panel->clipF);
WMResizeWidget(panel->clipcL, 120, 16);
WMMoveWidget(panel->clipcL, 130, 70);
WMSetLabelTextAlignment(panel->clipcL, WACenter);
WMSetLabelText(panel->clipcL, _("Collapsed"));
WMMapSubwidgets(panel->clipF);
WMMapSubwidgets(panel->workF);
/***************** Icon *****************/
panel->iconF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->iconF, 260, 190);
WMMoveWidget(panel->iconF, 250, 35);
WMSetFrameTitle(panel->iconF, _("Icon Background"));
panel->iconT = WMCreateTextField(panel->iconF);
WMResizeWidget(panel->iconT, 220, 20);
WMMoveWidget(panel->iconT, 20, 80);
panel->iconB = WMCreateCommandButton(panel->iconF);
WMResizeWidget(panel->iconB, 50, 24);
WMMoveWidget(panel->iconB, 190, 105);
WMSetButtonText(panel->iconB, _("Set..."));
WMMapSubwidgets(panel->iconF);
/**/
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
WMSetPopUpButtonSelectedItem(panel->secP, 0);
changePage(panel->secP, panel);
showData(panel);
}
Panel*
InitTextureAndColor(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Texture and Color Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
AddSection(panel, ICON_FILE);
return panel;
}

855
WPrefs.app/WPrefs.c Normal file
View File

@@ -0,0 +1,855 @@
/* WPrefs.c- main window and other basic stuff
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
#include <assert.h>
extern Panel *InitWindowHandling(WMScreen *scr, WMWindow *win);
extern Panel *InitKeyboardSettings(WMScreen *scr, WMWindow *win);
extern Panel *InitMouseSettings(WMScreen *scr, WMWindow *win);
extern Panel *InitKeyboardShortcuts(WMScreen *scr, WMWindow *win);
extern Panel *InitWorkspace(WMScreen *scr, WMWindow *win);
extern Panel *InitFocus(WMScreen *scr, WMWindow *win);
extern Panel *InitPreferences(WMScreen *scr, WMWindow *win);
extern Panel *InitTextureAndColor(WMScreen *scr, WMWindow *win);
extern Panel *InitText(WMScreen *scr, WMWindow *win);
extern Panel *InitConfigurations(WMScreen *scr, WMWindow *win);
extern Panel *InitPaths(WMScreen *scr, WMWindow *win);
extern Panel *InitMenu(WMScreen *scr, WMWindow *win);
extern Panel *InitExpert(WMScreen *scr, WMWindow *win);
extern Panel *InitMenuPreferences(WMScreen *scr, WMWindow *win);
extern Panel *InitIcons(WMScreen *scr, WMWindow *win);
#define MAX_SECTIONS 16
typedef struct _WPrefs {
WMWindow *win;
WMScrollView *scrollV;
WMFrame *buttonF;
WMButton *sectionB[MAX_SECTIONS];
int sectionCount;
WMButton *saveBtn;
WMButton *closeBtn;
WMButton *undoBtn;
WMButton *undosBtn;
WMFrame *banner;
WMLabel *nameL;
WMLabel *versionL;
WMLabel *creditsL;
WMLabel *statusL;
Panel *currentPanel;
} _WPrefs;
static _WPrefs WPrefs;
/* system wide defaults dictionary. Read-only */
static proplist_t GlobalDB = NULL;
/* user defaults dictionary */
static proplist_t WindowMakerDB = NULL;
static Bool TIFFOK = False;
#define INITIALIZED_PANEL (1<<0)
static void loadConfigurations(WMScreen *scr, WMWindow *mainw);
static void savePanelData(Panel *panel);
void
quit(WMWidget *w, void *data)
{
exit(0);
}
static void
save(WMWidget *w, void *data)
{
int i;
proplist_t p1, p2;
proplist_t keyList;
proplist_t key;
/* puts("gathering data");*/
for (i=0; i<WPrefs.sectionCount; i++) {
PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
if ((rec->callbacks.flags & INITIALIZED_PANEL))
savePanelData((Panel*)rec);
}
/* puts("compressing data");*/
/* compare the user dictionary with the global and remove redundant data */
keyList = PLGetAllDictionaryKeys(GlobalDB);
/* puts(PLGetDescription(WindowMakerDB));*/
for (i=0; i<PLGetNumberOfElements(keyList); i++) {
key = PLGetArrayElement(keyList, i);
/* We don't have this value anyway, so no problem.
* Probably a new option */
p1 = PLGetDictionaryEntry(WindowMakerDB, key);
if (!p1)
continue;
/* The global doesn't have it, so no problem either. */
p2 = PLGetDictionaryEntry(GlobalDB, key);
if (!p2)
continue;
/* If both values are the same, don't save. */
if (PLIsEqual(p1, p2))
PLRemoveDictionaryEntry(WindowMakerDB, key);
}
/* puts(PLGetDescription(WindowMakerDB));*/
PLRelease(keyList);
/* puts("storing data");*/
PLSave(WindowMakerDB, YES);
}
static void
undo(WMWidget *w, void *data)
{
PanelRec *rec = (PanelRec*)WPrefs.currentPanel;
if (!rec)
return;
if (rec->callbacks.undoChanges
&& (rec->callbacks.flags & INITIALIZED_PANEL)) {
(*rec->callbacks.undoChanges)(WPrefs.currentPanel);
}
}
static void
undoAll(WMWidget *w, void *data)
{
int i;
for (i=0; i<WPrefs.sectionCount; i++) {
PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
if (rec->callbacks.undoChanges
&& (rec->callbacks.flags & INITIALIZED_PANEL))
(*rec->callbacks.undoChanges)((Panel*)rec);
}
}
static void
createMainWindow(WMScreen *scr)
{
WMScroller *scroller;
WMFont *font;
char buffer[128];
WPrefs.win = WMCreateWindow(scr, "wprefs");
WMResizeWidget(WPrefs.win, 520, 390);
WMSetWindowTitle(WPrefs.win, _("WindowMaker Preferences"));
WMSetWindowCloseAction(WPrefs.win, quit, NULL);
WMSetWindowMaxSize(WPrefs.win, 520, 390);
WMSetWindowMinSize(WPrefs.win, 520, 390);
WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
WMResizeWidget(WPrefs.scrollV, 500, 87);
WMMoveWidget(WPrefs.scrollV, 10, 10);
WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
WMSetScrollerArrowsPosition(scroller, WSANone);
WPrefs.buttonF = WMCreateFrame(WPrefs.win);
WMSetFrameRelief(WPrefs.buttonF, WRFlat);
WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
WMResizeWidget(WPrefs.undosBtn, 90, 28);
WMMoveWidget(WPrefs.undosBtn, 135, 350);
WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
WMResizeWidget(WPrefs.undoBtn, 90, 28);
WMMoveWidget(WPrefs.undoBtn, 235, 350);
WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
WMResizeWidget(WPrefs.saveBtn, 80, 28);
WMMoveWidget(WPrefs.saveBtn, 335, 350);
WMSetButtonText(WPrefs.saveBtn, _("Save"));
WMSetButtonAction(WPrefs.saveBtn, save, NULL);
WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
WMResizeWidget(WPrefs.closeBtn, 80, 28);
WMMoveWidget(WPrefs.closeBtn, 425, 350);
WMSetButtonText(WPrefs.closeBtn, _("Close"));
WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
/* banner */
WPrefs.banner = WMCreateFrame(WPrefs.win);
WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
WMSetFrameRelief(WPrefs.banner, WRFlat);
font = WMCreateFont(scr, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*");
if (!font)
font = WMBoldSystemFontOfSize(scr, 24);
WPrefs.nameL = WMCreateLabel(WPrefs.banner);
WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 30);
WMMoveWidget(WPrefs.nameL, 10, 25);
WMSetLabelFont(WPrefs.nameL, font);
WMSetLabelText(WPrefs.nameL, "WindowMaker Preferences Utility");
WMReleaseFont(font);
WPrefs.versionL = WMCreateLabel(WPrefs.banner);
WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
WMMoveWidget(WPrefs.versionL, 10, 65);
WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
sprintf(buffer, _("Version %s for WindowMaker %s"), WVERSION, WMVERSION);
WMSetLabelText(WPrefs.versionL, buffer);
WPrefs.statusL = WMCreateLabel(WPrefs.banner);
WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
WMMoveWidget(WPrefs.statusL, 10, 100);
WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
WMSetLabelText(WPrefs.statusL, _("Starting..."));
WPrefs.creditsL = WMCreateLabel(WPrefs.banner);
WMResizeWidget(WPrefs.creditsL, FRAME_WIDTH-20, 40);
WMMoveWidget(WPrefs.creditsL, 10, FRAME_HEIGHT-40);
WMSetLabelTextAlignment(WPrefs.creditsL, WACenter);
WMSetLabelText(WPrefs.creditsL, _("Programming/Design: Alfredo K. Kojima\n"
"Artwork: Marco van Hylckama Vlieg"));
WMMapSubwidgets(WPrefs.win);
WMUnmapWidget(WPrefs.undosBtn);
WMUnmapWidget(WPrefs.undoBtn);
WMUnmapWidget(WPrefs.saveBtn);
}
static void
showPanel(Panel *panel)
{
PanelRec *rec = (PanelRec*)panel;
if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
(*rec->callbacks.createWidgets)(panel);
rec->callbacks.flags |= INITIALIZED_PANEL;
}
WMSetWindowTitle(WPrefs.win, rec->sectionName);
WMMapWidget(rec->frame);
}
static void
hidePanel(Panel *panel)
{
PanelRec *rec = (PanelRec*)panel;
WMUnmapWidget(rec->frame);
}
static void
savePanelData(Panel *panel)
{
PanelRec *rec = (PanelRec*)panel;
if (rec->callbacks.updateDomain) {
(*rec->callbacks.updateDomain)(panel);
}
}
static void
changeSection(WMWidget *self, void *data)
{
if (WPrefs.banner) {
WMDestroyWidget(WPrefs.banner);
WPrefs.banner = NULL;
/* WMMapWidget(WPrefs.undosBtn);
WMMapWidget(WPrefs.undoBtn);
*/
WMMapWidget(WPrefs.saveBtn);
}
showPanel(data);
if (WPrefs.currentPanel)
hidePanel(WPrefs.currentPanel);
WPrefs.currentPanel = data;
}
char*
LocateImage(char *name)
{
char *path;
char *tmp = wmalloc(strlen(name)+8);
if (TIFFOK) {
sprintf(tmp, "%s.tiff", name);
path = WMPathForResourceOfType(tmp, "tiff");
} else {
sprintf(tmp, "%s.xpm", name);
path = WMPathForResourceOfType(tmp, "xpm");
}
free(tmp);
if (!path) {
wwarning(_("could not locate image file %s\n"), name);
}
return path;
}
void
AddSection(Panel *panel, char *iconFile)
{
WMButton *bPtr;
WMPixmap *icon;
RColor color;
char *iconPath;
assert(WPrefs.sectionCount < MAX_SECTIONS);
iconPath = LocateImage(iconFile);
bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask
|WBBStateChangeMask);
WMResizeWidget(bPtr, 64, 64);
WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
WMSetButtonImagePosition(bPtr, WIPImageOnly);
WMSetButtonAction(bPtr, changeSection, panel);
WMHangData(bPtr, panel);
color.red = 0xae;
color.green = 0xaa;
color.blue = 0xae;
color.alpha = 0;
if (iconPath) {
icon = WMCreateBlendedPixmapFromFile(WMWidgetScreen(WPrefs.win),
iconPath, &color);
if (!icon)
wwarning(_("could not load icon file %s"), iconPath);
} else {
icon = NULL;
}
WMSetButtonImage(bPtr, icon);
if (icon)
WMReleasePixmap(icon);
color.red = 0xff;
color.green = 0xff;
color.blue = 0xff;
color.alpha = 0;
if (iconPath) {
icon = WMCreateBlendedPixmapFromFile(WMWidgetScreen(WPrefs.win),
iconPath, &color);
if (!icon)
wwarning(_("could not load icon file %s"), iconPath);
} else {
icon = NULL;
}
WMSetButtonAltImage(bPtr, icon);
if (icon)
WMReleasePixmap(icon);
WMMapWidget(bPtr);
WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
if (WPrefs.sectionCount > 0) {
WMGroupButtons(WPrefs.sectionB[0], bPtr);
}
WPrefs.sectionCount++;
WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
free(iconPath);
}
void
Initialize(WMScreen *scr)
{
char **list;
int i;
char *path;
WMPixmap *icon;
list = RSupportedFileFormats();
for (i=0; list[i]!=NULL; i++) {
if (strcmp(list[i], "TIFF")==0) {
TIFFOK = True;
break;
}
}
RFreeStringList(list);
if (TIFFOK)
path = WMPathForResourceOfType("WPrefs.tiff", NULL);
else
path = WMPathForResourceOfType("WPrefs.xpm", NULL);
if (path) {
RImage *tmp;
tmp = RLoadImage(WMScreenRContext(scr), path, 0);
if (!tmp) {
wwarning("could not load image file %s:%s", path, RErrorString);
} else {
icon = WMCreatePixmapFromRImage(scr, tmp, 0);
RDestroyImage(tmp);
if (icon) {
WMSetApplicationIconImage(scr, icon);
WMReleasePixmap(icon);
}
}
free(path);
}
memset(&WPrefs, 0, sizeof(_WPrefs));
createMainWindow(scr);
WMRealizeWidget(WPrefs.win);
WMMapWidget(WPrefs.win);
XFlush(WMScreenDisplay(scr));
WMSetLabelText(WPrefs.statusL, _("Loading WindowMaker configuration files..."));
XFlush(WMScreenDisplay(scr));
loadConfigurations(scr, WPrefs.win);
WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
InitWindowHandling(scr, WPrefs.win);
InitFocus(scr, WPrefs.win);
InitMenuPreferences(scr, WPrefs.win);
InitIcons(scr, WPrefs.win);
InitPreferences(scr, WPrefs.win);
InitPaths(scr, WPrefs.win);
InitWorkspace(scr, WPrefs.win);
InitConfigurations(scr, WPrefs.win);
InitMenu(scr, WPrefs.win);
#ifdef not_yet_fully_implemented
InitKeyboardSettings(scr, WPrefs.win);
#endif
InitKeyboardShortcuts(scr, WPrefs.win);
InitMouseSettings(scr, WPrefs.win);
#ifdef not_yet_fully_implemented
InitTextureAndColor(scr, WPrefs.win);
InitText(scr, WPrefs.win);
#endif
InitExpert(scr, WPrefs.win);
WMRealizeWidget(WPrefs.scrollV);
WMSetLabelText(WPrefs.statusL, "This program is still under development. Backup your ~/GNUstep/Defaults directory, before using it.");
}
WMWindow*
GetWindow(Panel *panel)
{
return WPrefs.win;
}
static void
loadConfigurations(WMScreen *scr, WMWindow *mainw)
{
proplist_t db, gdb;
char *path;
FILE *file;
char buffer[1024];
char mbuf[1024];
int v1, v2, v3;
path = wdefaultspathfordomain("WindowMaker");
db = PLGetProplistWithPath(path);
if (db) {
if (!PLIsDictionary(db)) {
PLRelease(db);
db = NULL;
sprintf(mbuf, _("WindowMaker domain (%s) is corrupted!"), path);
WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
}
} else {
sprintf(mbuf, _("Could not load WindowMaker domain (%s) from defaults database."),
path);
WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
}
free(path);
file = popen("wmaker -version", "r");
if (!file || !fgets(buffer, 1023, file)) {
wsyserror(_("could not extract version information from WindowMaker"));
wfatal(_("Make sure WindowMaker is in your search path."));
WMRunAlertPanel(scr, mainw, _("Error"),
_("Could not extract version from WindowMaker. Make sure it is correctly installed."),
_("OK"), NULL, NULL);
exit(1);
}
if (file)
pclose(file);
if (sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
WMRunAlertPanel(scr, mainw, _("Error"),
_("Could not extract version from WindowMaker. Make sure it is correctly installed."),
_("OK"), NULL, NULL);
exit(1);
}
if (v1 == 0 && (v2 < 18 || v3 < 0)) {
sprintf(mbuf, _("WPrefs only supports WindowMaker 0.18.0 or newer.\n"
"The version installed is %i.%i.%i\n"), v1, v2, v3);
WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
exit(1);
}
if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
sprintf(mbuf, _("WindowMaker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
v1, v2, v3);
WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
}
file = popen("wmaker -global_defaults_path", "r");
if (!file || !fgets(buffer, 1023, file)) {
wsyserror(_("could not run \"wmaker -global_defaults_path\"."));
exit(1);
}
if (file)
pclose(file);
gdb = PLGetProplistWithPath(buffer);
if (gdb) {
if (!PLIsDictionary(gdb)) {
PLRelease(gdb);
gdb = NULL;
sprintf(mbuf, _("WindowMaker domain (%s) is corrupted!"), buffer);
WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
}
} else {
sprintf(mbuf, _("Could not load global WindowMaker domain (%s)."),
buffer);
WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
}
if (!db) {
db = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
}
if (!gdb) {
gdb = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
}
GlobalDB = gdb;
WindowMakerDB = db;
}
proplist_t
GetObjectForKey(char *defaultName)
{
proplist_t object = NULL;
proplist_t key = PLMakeString(defaultName);
object = PLGetDictionaryEntry(WindowMakerDB, key);
if (!object)
object = PLGetDictionaryEntry(GlobalDB, key);
PLRelease(key);
return object;
}
void
SetObjectForKey(proplist_t object, char *defaultName)
{
proplist_t key = PLMakeString(defaultName);
PLInsertDictionaryEntry(WindowMakerDB, key, object);
PLRelease(key);
}
void
RemoveObjectForKey(char *defaultName)
{
proplist_t key = PLMakeString(defaultName);
PLRemoveDictionaryEntry(WindowMakerDB, key);
PLRelease(key);
}
char*
GetStringForKey(char *defaultName)
{
proplist_t val;
val = GetObjectForKey(defaultName);
if (!val)
return NULL;
if (!PLIsString(val))
return NULL;
return PLGetString(val);
}
proplist_t
GetArrayForKey(char *defaultName)
{
proplist_t val;
val = GetObjectForKey(defaultName);
if (!val)
return NULL;
if (!PLIsArray(val))
return NULL;
return val;
}
proplist_t
GetDictionaryForKey(char *defaultName)
{
proplist_t val;
val = GetObjectForKey(defaultName);
if (!val)
return NULL;
if (!PLIsDictionary(val))
return NULL;
return val;
}
int
GetIntegerForKey(char *defaultName)
{
proplist_t val;
char *str;
int value;
val = GetObjectForKey(defaultName);
if (!val)
return 0;
if (!PLIsString(val))
return 0;
str = PLGetString(val);
if (!str)
return 0;
if (sscanf(str, "%i", &value)!=1)
return 0;
return value;
}
Bool
GetBoolForKey(char *defaultName)
{
int value;
char *str;
str = GetStringForKey(defaultName);
if (!str)
return False;
if (sscanf(str, "%i", &value)==1 && value!=0)
return True;
if (strcasecmp(str, "YES")==0)
return True;
if (strcasecmp(str, "Y")==0)
return True;
return False;
}
void
SetIntegerForKey(int value, char *defaultName)
{
proplist_t object;
char buffer[128];
sprintf(buffer, "%i", value);
object = PLMakeString(buffer);
SetObjectForKey(object, defaultName);
PLRelease(object);
}
void
SetStringForKey(char *value, char *defaultName)
{
proplist_t object;
object = PLMakeString(value);
SetObjectForKey(object, defaultName);
PLRelease(object);
}
void
SetBoolForKey(Bool value, char *defaultName)
{
static proplist_t yes = NULL, no = NULL;
if (!yes) {
yes = PLMakeString("YES");
no = PLMakeString("NO");
}
SetObjectForKey(value ? yes : no, defaultName);
}
void
SetSpeedForKey(int speed, char *defaultName)
{
char *str;
switch (speed) {
case 0:
str = "ultraslow";
break;
case 1:
str = "slow";
break;
case 2:
str = "medium";
break;
case 3:
str = "fast";
break;
case 4:
str = "ultrafast";
break;
default:
str = NULL;
}
if (str)
SetStringForKey(str, defaultName);
}
int
GetSpeedForKey(char *defaultName)
{
char *str;
int i;
str = GetStringForKey(defaultName);
if (strcasecmp(str, "ultraslow")==0)
i = 0;
else if (strcasecmp(str, "slow")==0)
i = 1;
else if (strcasecmp(str, "medium")==0)
i = 2;
else if (strcasecmp(str, "fast")==0)
i = 3;
else if (strcasecmp(str, "ultrafast")==0)
i = 4;
else {
wwarning(_("bad speed value for option %s\n. Using default Medium"),
defaultName);
i = 2;
}
return i;
}

119
WPrefs.app/WPrefs.h Normal file
View File

@@ -0,0 +1,119 @@
/* WPrefs.h- general definitions
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#ifndef WPREFS_H_
#define WPREFS_H_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <proplist.h>
#include <wraster.h>
#include <WINGs.h>
#include <WUtil.h>
#define WVERSION "0.6"
#define WMVERSION "0.20.x"
typedef struct _Panel Panel;
typedef struct {
unsigned flags; /* reserved for WPrefs.c Don't access it */
void (*createWidgets)(Panel*); /* called when showing for first time */
void (*updateDomain)(Panel*); /* save the changes to the dictionary */
Bool (*requiresRestart)(Panel*); /* return True if some static option was changed */
void (*undoChanges)(Panel*); /* reset values to those in the dictionary */
} CallbackRec;
/* all Panels must start with the following layout */
typedef struct PanelRec {
WMFrame *frame;
char *sectionName; /* section name to display in titlebar */
CallbackRec callbacks;
} PanelRec;
void AddSection(Panel *panel, char *iconFile);
char *LocateImage(char *name);
WMWindow *GetWindow(Panel *panel);
/* manipulate the dictionary for the WindowMaker domain */
proplist_t GetObjectForKey(char *defaultName);
void SetObjectForKey(proplist_t object, char *defaultName);
void RemoveObjectForKey(char *defaultName);
char *GetStringForKey(char *defaultName);
int GetIntegerForKey(char *defaultName);
Bool GetBoolForKey(char *defaultName);
int GetSpeedForKey(char *defaultName);
void SetIntegerForKey(int value, char *defaultName);
void SetStringForKey(char *value, char *defaultName);
void SetBoolForKey(Bool value, char *defaultName);
void SetSpeedForKey(int speed, char *defaultName);
#define FRAME_TOP 105
#define FRAME_LEFT -2
#define FRAME_WIDTH 524
#define FRAME_HEIGHT 235
/*
* Needed for HAVE_LIBINTL_H
*/
#include "../src/config.h"
#if HAVE_LIBINTL_H && I18N
# include <libintl.h>
# define _(text) gettext(text)
#else
# define _(text) (text)
#endif
#endif

BIN
WPrefs.app/WPrefs.tiff Normal file

Binary file not shown.

237
WPrefs.app/WPrefs.xpm Normal file
View File

@@ -0,0 +1,237 @@
/* XPM */
static char * image_name[] = {
"45 45 189 2",
" c None",
". c #186175D60000",
"X c #000000000000",
"o c #082004100820",
"O c #082008200820",
"+ c #4924A28930C2",
"@ c #514451445144",
"# c #492449244924",
"$ c #49244D344924",
"% c #208179E70820",
"& c #104010401040",
"* c #28A22CB228A2",
"= c #38E338E338E3",
"- c #28A228A228A2",
"; c #30C22CB230C2",
": c #186114511861",
"> c #514455555965",
", c #10400C301040",
"< c #186118611861",
"1 c #208120812081",
"2 c #2081249228A2",
"3 c #186171C60000",
"4 c #28A282071040",
"5 c #28A27DF70820",
"6 c #28A2249228A2",
"7 c #30C230C230C2",
"8 c #410341034103",
"9 c #30C292482081",
"0 c #30C234D338E3",
"q c #79E77DF78617",
"w c #C71BC71BC71B",
"e c #71C675D671C6",
"r c #965892489658",
"t c #FFFFFFFFFFFF",
"y c #EFBEEFBEEFBE",
"u c #5144AAAA38E3",
"i c #A699FFFF8E38",
"p c #596559656185",
"a c #AEBA10401040",
"s c #E79D14511861",
"d c #208104100000",
"f c #FFFF61856185",
"g c #F7DE2CB22081",
"h c #C71BAAAAA699",
"j c #DF7D14511861",
"k c #71C608200820",
"l c #FFFF30C230C2",
"z c #E79D20811861",
"x c #79E714511861",
"c c #28A204100000",
"v c #EFBE18611861",
"b c #79E70C300820",
"n c #FFFFE38DE79D",
"m c #FFFF28A228A2",
"M c #E79D18611861",
"N c #8E381C711861",
"B c #596559655965",
"V c #861749240820",
"C c #D75C24921040",
"Z c #B6DA10401040",
"A c #B6DA14511040",
"S c #10403CF30000",
"D c #69A6C30B5144",
"F c #CF3C96585144",
"G c #EFBE38E328A2",
"H c #BEFB18611861",
"J c #410375D638E3",
"K c #30C28E381861",
"L c #38E33CF34103",
"P c #A69910401040",
"I c #8E380C300820",
"U c #CF3C14511040",
"Y c #FFFF59655965",
"T c #D75C41034103",
"R c #965820811861",
"E c #DF7D20812081",
"W c #596508200820",
"Q c #38E304100820",
"! c #FFFF34D338E3",
"~ c #8E3838E338E3",
"^ c #6185492428A2",
"/ c #F7DE20812081",
"( c #8E388A288E38",
") c #30C204100000",
"_ c #104000000000",
"` c #FFFFD34CD75C",
"' c #FFFF20812081",
"] c #28A220812081",
"[ c #69A6A2895965",
"{ c #F7DE24922081",
"} c #492414511040",
"| c #AEBAAEBAAEBA",
" . c #86170C300820",
".. c #69A608200820",
"X. c #104059650000",
"o. c #FFFF8A288E38",
"O. c #F7DE38E338E3",
"+. c #9E79EFBE8617",
"@. c #71C614511040",
"#. c #861786178617",
"$. c #965810401040",
"%. c #208151441040",
"&. c #FFFF45144103",
"*. c #D75C34D338E3",
"=. c #FFFF49244924",
"-. c #9E791C712081",
";. c #618565956185",
":. c #492404100820",
">. c #38E35D7528A2",
",. c #C71BC30BC71B",
"<. c #8617E38D69A6",
"1. c #FFFF249228A2",
"2. c #69A628A228A2",
"3. c #FFFF65956185",
"4. c #C71B20812081",
"5. c #28A26DB60000",
"6. c #FFFF18611861",
"7. c #E79D1C711861",
"8. c #30C2492428A2",
"9. c #FFFFF3CEEFBE",
"0. c #B6DAB6DAB6DA",
"q. c #FFFFA2899E79",
"w. c #E79D20812081",
"e. c #51445D750820",
"r. c #F7DE1C711861",
"t. c #618549240820",
"y. c #18616DB60000",
"u. c #9E7941031040",
"i. c #A69934D31040",
"p. c #186120811040",
"a. c #BEFBC71B69A6",
"s. c #AEBA92485144",
"d. c #D75C7DF74924",
"f. c #CF3C618538E3",
"g. c #AEBAF3CE8617",
"h. c #104018610820",
"j. c #F7DE1C712081",
"k. c #18610C300820",
"l. c #AEBAA289A699",
"z. c #BEFB45144103",
"x. c #618561856185",
"c. c #104004100820",
"v. c #EFBE28A228A2",
"b. c #69A610401040",
"n. c #79E718611861",
"m. c #51442CB228A2",
"M. c #79E779E779E7",
"N. c #F7DE30C230C2",
"B. c #F7DE18611861",
"V. c #410304100820",
"C. c #E79D34D330C2",
"Z. c #C71B18611861",
"A. c #F7DE28A22081",
"S. c #DF7DA289A699",
"D. c #F7DE28A228A2",
"F. c #E79D30C230C2",
"G. c #D75CD34CD75C",
"H. c #EFBE41034103",
"J. c #C71B14511040",
"K. c #000014510000",
"L. c #514408200820",
"P. c #C71B59655965",
"I. c #B6DA249228A2",
"U. c #492410401040",
"Y. c #208110401040",
"T. c #082010400820",
"R. c #FFFF7DF779E7",
"E. c #618514511040",
"W. c #AEBA45144103",
"Q. c #000008200000",
"!. c #DF7D2CB22081",
"~. c #59655D755965",
"^. c #71C671C671C6",
"/. c #AEBAAAAAAEBA",
"(. c #69A66DB671C6",
"). c #28A282070820",
"_. c #71C6CB2B5965",
"`. c #A699FBEE8E38",
"'. c #69A6C71B5144",
"]. c #E79DE79DE79D",
"[. c #FFFFFBEEFFFF",
"{. c #BEFBBEFBBEFB",
"}. c #8E388E389658",
"|. c #A699A699A699",
" X c #9E79A2899E79",
".X c #DF7DDF7DDF7D",
"XX c #F7DEF7DEF7DE",
"oX c #861782078617",
"OX c #71C6D34C5965",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . ",
". . . . . . ",
". . . . . . ",
". . X o X O + @ # # # # # # $ % X X . . ",
". . & * $ = - . X X X X X X X X . ; ; o . . ",
". . : > - , X X . X X X X X X X X . X o O , X . . ",
". . < 1 , X X X X . X X X X X X X X . X X X o X 2 . . ",
". . . . . . . . 3 % 4 . . . . . . . . . . . . . . . . . . . . . % 5 . . . . . . . . . . . ",
". % 2 X X X X X X X . X X X X X X X X . X 6 7 ; 7 ; = 8 9 0 0 0 0 . ",
". < % X X X X X X X X . X X X X X X X X . X q w w w w w e % X X X X . ",
". < 6 . X X X X X X X X . X X X X X X X X . X r t t t t t y u X X X X . ",
". X o X . X X X X X X X X . X X X X X X X X . X r t t t t t t i p X X X . ",
". O : X . X X X X a s d X . X X X X X X X X . X r t t t t t f g h : X X . ",
". X < X X . X X X X s j k X . X X X X X X X X . X r t t t t t l z x > X X . ",
". X O X X . X X X c v j b X . X X X X X X X X . X r t t t t n m M N B & X . ",
". . . . . . . . . . . . V C Z A S . . . . . . . . . . . D i i i i F G A H J K . . . . . . ",
". L X X X . X X X Z P I U X . X X X X X X X X . X r t t t t Y T R E 8 @ X . ",
". : X X X . X X X j W Q v X . X X X X X X X X . X r t t t t ! ~ ^ / ; ( , . ",
". X X X X . X X ) v _ X v Q . X X X X X X X X . X r t t t ` ' ] [ { } | : . ",
". X X X X . X X .U X X j ..X.X X X X X X X X . X r t t t o.O., +.! @.#.: . ",
". X X X X . X X U Z X X U $.%.; * ; * * ; ; - K ; | t t t &.*.; i =.-.;.< . ",
". X X X X . X X v :.X X a H >.w ,.w w w w w w <.w y t t t 1.2.$ i 3.4.# : . ",
". X X X ) 5.X ) 6.X X X ..7.8.t t t t t t t t i t ` 9.t ` 6., 0.i q.w.7 : . ",
". . . . % . e.r.t.y.u.i.X . . 5.r.p.i i i i i i i i i a.{ s.+.d.f.X i i g.r.h.5 . . . . . ",
". = X v v s _ U .X X X X j.k.t t t t t t t t i m ' s l.&.z.x.t i t ' c.X . ",
". 6 W 6.Q 6...s c X X X X v.b.y t t t t t t t i 6.} 6.n.m m.M.t i t N...X . ",
"r.B.6.6.6.6.V.X 7.v U X X X X X C.Z.6.1.m m m ' { { A.S.X D.v F.: G.t i t H.J.6.v v v v . ",
"K.X X X X X X X u.v L.X X X X X P.v I.L.U.} } Y., & T.: ,.R.v E.7 t t i y W.v P L.Q Q Q Q.",
". & , X . X X X X X X X r !., ~.t t t t t t i t t t ^.& /.t t i ,.: U X X X X X X.",
". o < X . X X X X X X X r i 7 t t t t t t t i t t t t t t t t i (.X X X . ",
". X X . X X X X X X X r i t t t t t t t t i t t t t t t t t D , X X X . ",
". . . . 3 3 3 . . % ).).).).).)._.i i i i i i i i i i i i i i i i `.'.% . . . . . . . . . ",
". X X X X . - r | | | | | ].i t t t t t t t t i t t t t t [.{.7 . X X X X . ",
". X X X X . , $ w t t t t t i t t t t t t t t i t t t t t }.7 X . X X X X . ",
". X X X X . X X 1 |.t t t t i t t t t t t t t i t t t ].}., X X . X X X X . ",
". X X X X . X X X X 6 X.XXXi t t t t t t t t i XX.X X6 X X X X . X X X X . ",
". X X X X . X X X X X X = oXOXw w t t t t w w OXoX= X X X X X X . X X X X . ",
". X X X X . X X X X X X X X % 7 ; ;.;.;.;.; ; % X X X X X X X X . X X X X . ",
". X X X X 3 X X X X X X X X . X X X X X X X X . X X X X X X X X . X X X X . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
". . . . . . ",
". . . . . . ",
". . . . . . ",
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};

357
WPrefs.app/WindowHandling.c Normal file
View File

@@ -0,0 +1,357 @@
/* WindowHandling.c- options for handling windows
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *placF;
WMPopUpButton *placP;
WMLabel *porigL;
WMLabel *porigvL;
WMFrame *porigF;
WMLabel *porigW;
WMSlider *vsli;
WMSlider *hsli;
WMFrame *maxiF;
WMButton *miconB;
WMButton *mdockB;
WMFrame *opaqF;
WMButton *opaqB;
WMFrame *tranF;
WMButton *tranB;
} _Panel;
#define ICON_FILE "whandling"
#define OPAQUE_MOVE_PIXMAP "opaque"
#define NON_OPAQUE_MOVE_PIXMAP "nonopaque"
#define THUMB_SIZE 16
static char *placements[] = {
"auto",
"random",
"manual",
"cascade"
};
static void
sliderCallback(WMWidget *w, void *data)
{
_Panel *panel = (_Panel*)data;
int x, y, rx, ry;
char buffer[64];
int swidth = WMGetSliderMaxValue(panel->hsli);
int sheight = WMGetSliderMaxValue(panel->vsli);
x = WMGetSliderValue(panel->hsli);
y = WMGetSliderValue(panel->vsli);
rx = x*(WMWidgetWidth(panel->porigF)-3)/swidth+2;
ry = y*(WMWidgetHeight(panel->porigF)-3)/sheight+2;
WMMoveWidget(panel->porigW, rx, ry);
sprintf(buffer, "(%i,%i)", x, y);
WMSetLabelText(panel->porigvL, buffer);
}
static int
getPlacement(char *str)
{
if (strcasecmp(str, "auto")==0 || strcasecmp(str, "smart")==0)
return 0;
else if (strcasecmp(str, "random")==0)
return 3;
else if (strcasecmp(str, "manual")==0)
return 2;
else if (strcasecmp(str, "cascade")==0)
return 1;
else
wwarning(_("bad option value %s in WindowPlacement. Using default value"),
str);
return 0;
}
static void
showData(_Panel *panel)
{
char *str;
proplist_t arr;
int x, y;
str = GetStringForKey("WindowPlacement");
WMSetPopUpButtonSelectedItem(panel->placP, getPlacement(str));
arr = GetObjectForKey("WindowPlaceOrigin");
x = 0;
y = 0;
if (arr && (!PLIsArray(arr) || PLGetNumberOfElements(arr)!=2)) {
wwarning(_("invalid data in option WindowPlaceOrigin. Using default (0,0)"));
} else {
if (arr) {
x = atoi(PLGetString(PLGetArrayElement(arr, 0)));
y = atoi(PLGetString(PLGetArrayElement(arr, 1)));
}
}
WMSetSliderValue(panel->hsli, x);
WMSetSliderValue(panel->vsli, y);
sliderCallback(NULL, panel);
WMSetButtonSelected(panel->tranB, GetBoolForKey("OnTopTransients"));
WMSetButtonSelected(panel->opaqB, GetBoolForKey("OpaqueMove"));
WMSetButtonSelected(panel->miconB, GetBoolForKey("NoWindowOverIcons"));
WMSetButtonSelected(panel->mdockB, GetBoolForKey("NoWindowUnderDock"));
}
static void
storeData(_Panel *panel)
{
proplist_t arr;
char x[16], y[16];
SetBoolForKey(WMGetButtonSelected(panel->miconB), "NoWindowOverIcons");
SetBoolForKey(WMGetButtonSelected(panel->mdockB), "NoWindowUnderDock");
SetBoolForKey(WMGetButtonSelected(panel->opaqB), "OpaqueMove");
SetBoolForKey(WMGetButtonSelected(panel->tranB), "OnTopTransients");
SetStringForKey(placements[WMGetPopUpButtonSelectedItem(panel->placP)],
"WindowPlacement");
sprintf(x, "%i", WMGetSliderValue(panel->hsli));
sprintf(y, "%i", WMGetSliderValue(panel->vsli));
arr = PLMakeArrayFromElements(PLMakeString(x), PLMakeString(y), NULL);
SetObjectForKey(arr, "WindowPlaceOrigin");
PLRelease(arr);
}
static void
createPanel(Panel *p)
{
_Panel *panel = (Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
WMColor *color;
WMPixmap *pixmap;
int width, height;
int swidth, sheight;
char *path;
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/************** Window Placement ***************/
panel->placF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->placF, 270, 150);
WMMoveWidget(panel->placF, 20, 15);
WMSetFrameTitle(panel->placF, _("Window Placement"));
panel->placP = WMCreatePopUpButton(panel->placF);
WMResizeWidget(panel->placP, 195, 20);
WMMoveWidget(panel->placP, 35, 20);
WMAddPopUpButtonItem(panel->placP, _("Automatic"));
WMAddPopUpButtonItem(panel->placP, _("Random"));
WMAddPopUpButtonItem(panel->placP, _("Manual"));
WMAddPopUpButtonItem(panel->placP, _("Cascade"));
panel->porigL = WMCreateLabel(panel->placF);
WMResizeWidget(panel->porigL, 118, 32);
WMMoveWidget(panel->porigL, 5, 60);
WMSetLabelTextAlignment(panel->porigL, WACenter);
WMSetLabelText(panel->porigL, _("Placement Origin"));
panel->porigvL = WMCreateLabel(panel->placF);
WMResizeWidget(panel->porigvL, 70, 20);
WMMoveWidget(panel->porigvL, 25, 95);
WMSetLabelTextAlignment(panel->porigvL, WACenter);
color = WMCreateRGBColor(scr, 0x5100, 0x5100, 0x7100, True);
panel->porigF = WMCreateFrame(panel->placF);
WMSetWidgetBackgroundColor(panel->porigF, color);
WMReleaseColor(color);
WMSetFrameRelief(panel->porigF, WRSunken);
swidth = WidthOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr)));
sheight = HeightOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr)));
if (120*sheight/swidth < 80*swidth/sheight) {
width = 80*swidth/sheight;
height = 80;
} else {
height = 120*sheight/swidth;
width = 120;
}
WMResizeWidget(panel->porigF, width, height);
WMMoveWidget(panel->porigF, 125+(120-width)/2, 45+(80-height)/2);
panel->porigW = WMCreateLabel(panel->porigF);
WMResizeWidget(panel->porigW, THUMB_SIZE, THUMB_SIZE);
WMMoveWidget(panel->porigW, 2, 2);
WMSetLabelRelief(panel->porigW, WRRaised);
panel->hsli = WMCreateSlider(panel->placF);
WMResizeWidget(panel->hsli, width, 12);
WMMoveWidget(panel->hsli, 125+(120-width)/2, 45+(80-height)/2+height+2);
WMSetSliderAction(panel->hsli, sliderCallback, panel);
WMSetSliderMinValue(panel->hsli, 0);
WMSetSliderMaxValue(panel->hsli, swidth);
panel->vsli = WMCreateSlider(panel->placF);
WMResizeWidget(panel->vsli, 12, height);
WMMoveWidget(panel->vsli, 125+(120-width)/2+width+2, 45+(80-height)/2);
WMSetSliderAction(panel->vsli, sliderCallback, panel);
WMSetSliderMinValue(panel->vsli, 0);
WMSetSliderMaxValue(panel->vsli, sheight);
WMMapSubwidgets(panel->porigF);
WMMapSubwidgets(panel->placF);
/************** Opaque Move ***************/
panel->opaqF = WMCreateFrame(panel->frame);
WMMoveWidget(panel->opaqF, 300, 15);
WMResizeWidget(panel->opaqF, 205, 125);
WMSetFrameTitle(panel->opaqF, _("Opaque Move"));
panel->opaqB = WMCreateButton(panel->opaqF, WBTToggle);
WMResizeWidget(panel->opaqB, 64, 64);
WMMoveWidget(panel->opaqB, 70, 35);
WMSetButtonImagePosition(panel->opaqB, WIPImageOnly);
path = LocateImage(NON_OPAQUE_MOVE_PIXMAP);
if (path) {
pixmap = WMCreatePixmapFromFile(scr, path);
if (pixmap) {
WMSetButtonImage(panel->opaqB, pixmap);
WMReleasePixmap(pixmap);
} else {
wwarning(_("could not load icon %s"), path);
}
free(path);
}
path = LocateImage(OPAQUE_MOVE_PIXMAP);
if (path) {
pixmap = WMCreatePixmapFromFile(scr, path);
if (pixmap) {
WMSetButtonAltImage(panel->opaqB, pixmap);
WMReleasePixmap(pixmap);
} else {
wwarning(_("could not load icon %s"), path);
}
free(path);
}
WMMapSubwidgets(panel->opaqF);
/**************** Account for Icon/Dock ***************/
panel->maxiF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->maxiF, 205, 70);
WMMoveWidget(panel->maxiF, 300, 145);
WMSetFrameTitle(panel->maxiF, _("When maximizing..."));
panel->miconB = WMCreateSwitchButton(panel->maxiF);
WMResizeWidget(panel->miconB, 185, 20);
WMMoveWidget(panel->miconB, 10, 20);
WMSetButtonText(panel->miconB, _("...do not resize over icons"));
panel->mdockB = WMCreateSwitchButton(panel->maxiF);
WMResizeWidget(panel->mdockB, 185, 20);
WMMoveWidget(panel->mdockB, 10, 40);
WMSetButtonText(panel->mdockB, _("...do not resize over dock"));
WMMapSubwidgets(panel->maxiF);
/**************** Transients On Top ****************/
panel->tranF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->tranF, 270, 40);
WMMoveWidget(panel->tranF, 20, 175);
panel->tranB = WMCreateSwitchButton(panel->tranF);
WMMoveWidget(panel->tranB, 10, 10);
WMResizeWidget(panel->tranB, 235, 20);
WMSetButtonText(panel->tranB, _("Keep transients above their owners"));
WMMapSubwidgets(panel->tranF);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
/* show the config data */
showData(panel);
}
static void
undo(_Panel *panel)
{
showData(panel);
}
Panel*
InitWindowHandling(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Window Handling Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
panel->callbacks.undoChanges = undo;
AddSection(panel, ICON_FILE);
return panel;
}

295
WPrefs.app/Workspace.c Normal file
View File

@@ -0,0 +1,295 @@
/* Workspace.c- workspace options
*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMFrame *frame;
char *sectionName;
CallbackRec callbacks;
WMWindow *win;
WMFrame *navF;
WMButton *linkB;
WMButton *cyclB;
WMButton *newB;
WMLabel *linkL;
WMLabel *cyclL;
WMLabel *newL;
WMFrame *dockF;
WMButton *dockB;
WMButton *clipB;
} _Panel;
#define ICON_FILE "workspace"
#define ARQUIVO_XIS "xis"
#define DONT_LINK_FILE "dontlinkworkspaces"
#define CYCLE_FILE "cycleworkspaces"
#define ADVANCE_FILE "advancetonewworkspace"
#define DOCK_FILE "dock"
#define CLIP_FILE "clip"
static void
createImages(WMScreen *scr, RContext *rc, RImage *xis, char *file,
WMPixmap **icon1, WMPixmap **icon2)
{
RImage *icon;
*icon1 = WMCreatePixmapFromFile(scr, file);
if (!*icon1) {
wwarning(_("could not load icon %s"), file);
*icon2 = NULL;
return;
}
icon = RLoadImage(rc, file, 0);
if (!icon) {
wwarning(_("could not load icon %s"), file);
*icon2 = NULL;
return;
}
if (xis) {
RCombineImages(icon, xis);
if (!(*icon2 = WMCreatePixmapFromRImage(scr, icon, 127))) {
wwarning(_("could not process icon %s:"), file, RErrorString);
*icon2 = NULL;
}
}
RDestroyImage(icon);
}
static void
showData(_Panel *panel)
{
WMSetButtonSelected(panel->linkB, !GetBoolForKey("DontLinkWorkspaces"));
WMSetButtonSelected(panel->cyclB, GetBoolForKey("CycleWorkspaces"));
WMSetButtonSelected(panel->newB, GetBoolForKey("AdvanceToNewWorkspace"));
WMSetButtonSelected(panel->dockB, !GetBoolForKey("DisableDock"));
WMSetButtonSelected(panel->clipB, !GetBoolForKey("DisableClip"));
}
static void
createPanel(Panel *p)
{
_Panel *panel = (_Panel*)p;
WMScreen *scr = WMWidgetScreen(panel->win);
WMPixmap *icon1, *icon2;
RImage *xis = NULL;
RContext *rc = WMScreenRContext(scr);
char *path;
path = LocateImage(ARQUIVO_XIS);
if (path) {
xis = RLoadImage(rc, path, 0);
if (!xis) {
wwarning(_("could not load image file %s"), path);
}
free(path);
}
panel->frame = WMCreateFrame(panel->win);
WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
/***************** Workspace Navigation *****************/
panel->navF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->navF, 365, 200);
WMMoveWidget(panel->navF, 20, 15);
WMSetFrameTitle(panel->navF, _("Workspace Navigation"));
panel->linkB = WMCreateButton(panel->navF, WBTToggle);
WMResizeWidget(panel->linkB, 60, 60);
WMMoveWidget(panel->linkB, 20, 25);
WMSetButtonImagePosition(panel->linkB, WIPImageOnly);
path = LocateImage(DONT_LINK_FILE);
if (path) {
createImages(scr, rc, xis, path, &icon1, &icon2);
if (icon2) {
WMSetButtonImage(panel->linkB, icon2);
WMReleasePixmap(icon2);
}
if (icon1) {
WMSetButtonAltImage(panel->linkB, icon1);
WMReleasePixmap(icon1);
}
free(path);
}
panel->linkL = WMCreateLabel(panel->navF);
WMResizeWidget(panel->linkL, 260, 38);
WMMoveWidget(panel->linkL, 85, 25);
WMSetLabelTextAlignment(panel->linkL, WALeft);
WMSetLabelText(panel->linkL,
_("drag windows between workspaces."));
panel->cyclB = WMCreateButton(panel->navF, WBTToggle);
WMResizeWidget(panel->cyclB, 60, 60);
WMMoveWidget(panel->cyclB, 285, 75);
WMSetButtonImagePosition(panel->cyclB, WIPImageOnly);
path = LocateImage(CYCLE_FILE);
if (path) {
createImages(scr, rc, xis, path, &icon1, &icon2);
if (icon2) {
WMSetButtonImage(panel->cyclB, icon2);
WMReleasePixmap(icon2);
}
if (icon1) {
WMSetButtonAltImage(panel->cyclB, icon1);
WMReleasePixmap(icon1);
}
free(path);
}
panel->cyclL = WMCreateLabel(panel->navF);
WMResizeWidget(panel->cyclL, 260, 38);
WMMoveWidget(panel->cyclL, 20, 85);
WMSetLabelTextAlignment(panel->cyclL, WARight);
WMSetLabelText(panel->cyclL,
_("switch to first workspace when switching past the last workspace and vice-versa"));
panel->newB = WMCreateButton(panel->navF, WBTToggle);
WMResizeWidget(panel->newB, 60, 60);
WMMoveWidget(panel->newB, 20, 125);
WMSetButtonImagePosition(panel->newB, WIPImageOnly);
path = LocateImage(ADVANCE_FILE);
if (path) {
createImages(scr, rc, xis, path, &icon1, &icon2);
if (icon2) {
WMSetButtonImage(panel->newB, icon2);
WMReleasePixmap(icon2);
}
if (icon1) {
WMSetButtonAltImage(panel->newB, icon1);
WMReleasePixmap(icon1);
}
free(path);
}
panel->newL = WMCreateLabel(panel->navF);
WMResizeWidget(panel->newL, 260, 38);
WMMoveWidget(panel->newL, 85, 140);
WMSetLabelTextAlignment(panel->newL, WALeft);
WMSetLabelText(panel->newL,
_("create a new workspace when switching past the last workspace."));
WMMapSubwidgets(panel->navF);
/***************** Dock/Clip *****************/
panel->dockF = WMCreateFrame(panel->frame);
WMResizeWidget(panel->dockF, 105, 200);
WMMoveWidget(panel->dockF, 400, 15);
WMSetFrameTitle(panel->dockF, _("Dock/Clip"));
panel->dockB = WMCreateButton(panel->dockF, WBTToggle);
WMResizeWidget(panel->dockB, 64, 64);
WMMoveWidget(panel->dockB, 20, 30);
WMSetButtonImagePosition(panel->dockB, WIPImageOnly);
path = LocateImage(DOCK_FILE);
if (path) {
createImages(scr, rc, xis, path, &icon1, &icon2);
if (icon2) {
WMSetButtonImage(panel->dockB, icon2);
WMReleasePixmap(icon2);
}
if (icon1) {
WMSetButtonAltImage(panel->dockB, icon1);
WMReleasePixmap(icon1);
}
free(path);
}
panel->clipB = WMCreateButton(panel->dockF, WBTToggle);
WMResizeWidget(panel->clipB, 64, 64);
WMMoveWidget(panel->clipB, 20, 110);
WMSetButtonImagePosition(panel->clipB, WIPImageOnly);
path = LocateImage(CLIP_FILE);
if (path) {
createImages(scr, rc, xis, path, &icon1, &icon2);
if (icon2) {
WMSetButtonImage(panel->clipB, icon2);
WMReleasePixmap(icon2);
}
if (icon1) {
WMSetButtonAltImage(panel->clipB, icon1);
WMReleasePixmap(icon1);
}
}
WMMapSubwidgets(panel->dockF);
if (xis)
RDestroyImage(xis);
WMRealizeWidget(panel->frame);
WMMapSubwidgets(panel->frame);
showData(panel);
}
static void
storeData(_Panel *panel)
{
SetBoolForKey(!WMGetButtonSelected(panel->linkB), "DontLinkWorkspaces");
SetBoolForKey(WMGetButtonSelected(panel->cyclB), "CycleWorkspaces");
SetBoolForKey(WMGetButtonSelected(panel->newB), "AdvanceToNewWorkspace");
SetBoolForKey(!WMGetButtonSelected(panel->dockB), "DisableDock");
SetBoolForKey(!WMGetButtonSelected(panel->clipB), "DisableClip");
}
Panel*
InitWorkspace(WMScreen *scr, WMWindow *win)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
memset(panel, 0, sizeof(_Panel));
panel->sectionName = _("Workspace Preferences");
panel->win = win;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
AddSection(panel, ICON_FILE);
return panel;
}

200
WPrefs.app/double.c Normal file
View File

@@ -0,0 +1,200 @@
/*
* Widget for testing double-clicks
*
*/
#include "WINGsP.h"
#include "double.h"
typedef struct W_DoubleTest {
W_Class widgetClass;
WMView *view;
WMHandlerID timer;
char on;
char active;
char *text;
} _DoubleTest;
/* some forward declarations */
static void destroyDoubleTest(_DoubleTest *dPtr);
static void paintDoubleTest(_DoubleTest *dPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
static W_ViewProcedureTable _DoubleTestViewProcedures = {
NULL,
NULL,
NULL
};
/* our widget class ID */
static W_Class DoubleTestClass = 0;
/*
* Initializer for our widget. Must be called before creating any
* instances of the widget.
*/
W_Class
InitDoubleTest(WMScreen *scr)
{
/* register our widget with WINGs and get our widget class ID */
if (!DoubleTestClass) {
DoubleTestClass = W_RegisterUserWidget(&_DoubleTestViewProcedures);
}
return DoubleTestClass;
}
/*
* Our widget fabrication plant.
*/
DoubleTest*
CreateDoubleTest(WMWidget *parent, char *text)
{
DoubleTest *dPtr;
if (!DoubleTestClass)
InitDoubleTest(WMWidgetScreen(parent));
/* allocate some storage for our new widget instance */
dPtr = wmalloc(sizeof(DoubleTest));
/* initialize it */
memset(dPtr, 0, sizeof(DoubleTest));
/* set the class ID */
dPtr->widgetClass = DoubleTestClass;
dPtr->view = W_CreateView(W_VIEW(parent));
if (!dPtr->view) {
free(dPtr);
return NULL;
}
/* always do this */
dPtr->view->self = dPtr;
dPtr->text = wstrdup(text);
WMCreateEventHandler(dPtr->view, ExposureMask /* this allows us to know when we should paint */
|StructureNotifyMask, /* this allows us to know things like when we are destroyed */
handleEvents, dPtr);
WMCreateEventHandler(dPtr->view, ButtonPressMask,handleActionEvents, dPtr);
return dPtr;
}
static void
paintDoubleTest(_DoubleTest *dPtr)
{
W_Screen *scr = dPtr->view->screen;
if (dPtr->active) {
XFillRectangle(scr->display, dPtr->view->window, W_GC(scr->white),
0, 0, dPtr->view->size.width, dPtr->view->size.height);
} else {
XClearWindow(scr->display, dPtr->view->window);
}
W_DrawRelief(scr, dPtr->view->window, 0, 0, dPtr->view->size.width,
dPtr->view->size.height, dPtr->on ? WRSunken : WRRaised);
if (dPtr->text) {
int y;
y = (dPtr->view->size.height-scr->normalFont->height)/2;
W_PaintText(dPtr->view, dPtr->view->window, scr->normalFont,
dPtr->on, dPtr->on+y, dPtr->view->size.width, WACenter,
W_GC(scr->black), False, dPtr->text, strlen(dPtr->text));
}
}
static void
handleEvents(XEvent *event, void *data)
{
_DoubleTest *dPtr = (_DoubleTest*)data;
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintDoubleTest(dPtr);
break;
case DestroyNotify:
destroyDoubleTest(dPtr);
break;
}
}
static void
deactivate(void *data)
{
_DoubleTest *dPtr = (_DoubleTest*)data;
if (dPtr->active)
dPtr->active = 0;
paintDoubleTest(dPtr);
dPtr->timer = NULL;
}
static void
handleActionEvents(XEvent *event, void *data)
{
_DoubleTest *dPtr = (_DoubleTest*)data;
extern _WINGsConfiguration WINGsConfiguration;
switch (event->type) {
case ButtonPress:
if (WMIsDoubleClick(event)) {
if (dPtr->timer)
WMDeleteTimerHandler(dPtr->timer);
dPtr->timer = NULL;
dPtr->on = !dPtr->on;
dPtr->active = 0;
paintDoubleTest(dPtr);
} else {
dPtr->timer=WMAddTimerHandler(WINGsConfiguration.doubleClickDelay,
deactivate, dPtr);
dPtr->active = 1;
paintDoubleTest(dPtr);
}
break;
}
}
static void
destroyDoubleTest(_DoubleTest *dPtr)
{
if (dPtr->timer)
WMDeleteTimerHandler(dPtr->timer);
if (dPtr->text)
free(dPtr->text);
free(dPtr);
}

5
WPrefs.app/double.h Normal file
View File

@@ -0,0 +1,5 @@
typedef struct W_DoubleTest DoubleTest;
DoubleTest *CreateDoubleTest(WMWidget *parent, char *text);

135
WPrefs.app/main.c Normal file
View File

@@ -0,0 +1,135 @@
/*
* WPrefs - WindowMaker Preferences Program
*
* Copyright (c) 1998 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "WPrefs.h"
#include <X11/Xlocale.h>
extern void Initialize(WMScreen *scr);
void
wAbort(Bool foo)
{
exit(1);
}
static BOOL
stringCompareHook(proplist_t pl1, proplist_t pl2)
{
char *str1, *str2;
str1 = PLGetString(pl1);
str2 = PLGetString(pl2);
if (strcasecmp(str1, str2)==0)
return YES;
else
return NO;
}
static void
print_help(char *progname)
{
printf(_("usage: %s [options]\n"), progname);
puts(_("options:"));
puts(_(" -display <display> display to be used"));
puts(_(" -version print version number and exit"));
}
int
main(int argc, char **argv)
{
Display *dpy;
WMScreen *scr;
char *locale;
int i;
char *display_name="";
WMInitializeApplication("WPrefs", &argc, argv);
if (argc>1) {
for (i=1; i<argc; i++) {
if (strcmp(argv[i], "-version")==0) {
printf("WPrefs %s\n", WVERSION);
exit(0);
} else if (strcmp(argv[i], "-display")==0) {
i++;
if (i>=argc) {
wwarning(_("too few arguments for %s"), argv[i-1]);
exit(0);
}
display_name = argv[i];
} else {
print_help(argv[0]);
exit(0);
}
}
}
locale = getenv("LANG");
setlocale(LC_ALL, "");
#ifdef I18N
if (getenv("NLSPATH"))
bindtextdomain("WPrefs", getenv("NLSPATH"));
else
bindtextdomain("WPrefs", NLSDIR);
textdomain("WPrefs");
if (!XSupportsLocale()) {
wwarning(_("X server does not support locale"));
}
if (XSetLocaleModifiers("") == NULL) {
wwarning(_("cannot set locale modifiers"));
}
#endif
dpy = XOpenDisplay(display_name);
if (!dpy) {
wfatal(_("could not open display %s"), XDisplayName(display_name));
exit(0);
}
#if 0
XSynchronize(dpy, 1);
#endif
scr = WMCreateScreen(dpy, DefaultScreen(dpy));
if (!scr) {
wfatal(_("could not initialize application"));
exit(0);
}
PLSetStringCmpHook(stringCompareHook);
Initialize(scr);
while (1) {
XEvent event;
WMNextEvent(dpy, &event);
WMHandleEvent(&event);
}
}

55
WPrefs.app/po/Makefile.am Normal file
View File

@@ -0,0 +1,55 @@
nlsdir = @NLSDIR@
CATALOGS = @WPMOFILES@
CLEANFILES = $(CATALOGS)
EXTRA_DIST = pt.po hr.po fr.po ko.po cs.po
POTFILES = \
$(top_builddir)/WPrefs/Configurations.c \
$(top_builddir)/WPrefs/Expert.c \
$(top_builddir)/WPrefs/Focus.c \
$(top_builddir)/WPrefs/KeyboardSettings.c \
$(top_builddir)/WPrefs/KeyboardShortcuts.c \
$(top_builddir)/WPrefs/Menu.c \
$(top_builddir)/WPrefs/MenuGuru.c \
$(top_builddir)/WPrefs/MenuPreferences.c \
$(top_builddir)/WPrefs/MouseSettings.c \
$(top_builddir)/WPrefs/Paths.c \
$(top_builddir)/WPrefs/Preferences.c \
$(top_builddir)/WPrefs/Text.c \
$(top_builddir)/WPrefs/TextureAndColor.c \
$(top_builddir)/WPrefs/WPrefs.c \
$(top_builddir)/WPrefs/WindowHandling.c \
$(top_builddir)/WPrefs/Workspace.c \
$(top_builddir)/WPrefs/main.c \
$(top_builddir)/WPrefs/xmodifier.c
SUFFIXES = .po .mo
.po.mo:
msgfmt -o $@ $<
WPrefs.pot: $(POTFILES)
xgettext --default-domain=WPrefs \
--add-comments --keyword=_ $(POTFILES)
if cmp -s WPrefs.po WPrefs.pot; then \
rm -f WPrefs.po; \
else \
mv -f WPrefs.po WPrefs.pot; \
fi
install-data-local: $(CATALOGS)
$(mkinstalldirs) $(nlsdir)
chmod 755 $(nlsdir)
for n in $(CATALOGS) __DuMmY ; do \
if test "$$n" -a "$$n" != "__DuMmY" ; then \
l=`basename $$n .mo`; \
$(mkinstalldirs) $(nlsdir)/$$l/LC_MESSAGES; \
chmod 755 $(nlsdir)/$$l; \
chmod 755 $(nlsdir)/$$l/LC_MESSAGES; \
$(INSTALL) -m 644 $$n $(nlsdir)/$$l/LC_MESSAGES/WPrefs.mo; \
fi; \
done

238
WPrefs.app/po/Makefile.in Normal file
View File

@@ -0,0 +1,238 @@
# Makefile.in generated automatically by automake 1.3 from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLIBS = @GFXLIBS@
I18N = @I18N@
I18N_MB = @I18N_MB@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LIBPL_INC_PATH = @LIBPL_INC_PATH@
LIBPL_LIBS = @LIBPL_LIBS@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@
NLSDIR = @NLSDIR@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
REDUCE_APPICONS = @REDUCE_APPICONS@
SHAPE = @SHAPE@
SOUND = @SOUND@
VERSION = @VERSION@
WPMOFILES = @WPMOFILES@
XCFLAGS = @XCFLAGS@
XGETTEXT = @XGETTEXT@
XLFLAGS = @XLFLAGS@
XLIBS = @XLIBS@
XSHM = @XSHM@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LOCALE = @X_LOCALE@
pixmapdir = @pixmapdir@
wprefsdir = @wprefsdir@
nlsdir = @NLSDIR@
CATALOGS = @WPMOFILES@
CLEANFILES = $(CATALOGS)
EXTRA_DIST = pt.po hr.po fr.po ko.po cs.po
POTFILES = \
$(top_builddir)/WPrefs/Configurations.c \
$(top_builddir)/WPrefs/Expert.c \
$(top_builddir)/WPrefs/Focus.c \
$(top_builddir)/WPrefs/KeyboardSettings.c \
$(top_builddir)/WPrefs/KeyboardShortcuts.c \
$(top_builddir)/WPrefs/Menu.c \
$(top_builddir)/WPrefs/MenuGuru.c \
$(top_builddir)/WPrefs/MenuPreferences.c \
$(top_builddir)/WPrefs/MouseSettings.c \
$(top_builddir)/WPrefs/Paths.c \
$(top_builddir)/WPrefs/Preferences.c \
$(top_builddir)/WPrefs/Text.c \
$(top_builddir)/WPrefs/TextureAndColor.c \
$(top_builddir)/WPrefs/WPrefs.c \
$(top_builddir)/WPrefs/WindowHandling.c \
$(top_builddir)/WPrefs/Workspace.c \
$(top_builddir)/WPrefs/main.c \
$(top_builddir)/WPrefs/xmodifier.c
SUFFIXES = .po .mo
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../src/config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = README Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
all: Makefile
.SUFFIXES:
.SUFFIXES: .mo .po
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps WPrefs.app/po/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
tags: TAGS
TAGS:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = WPrefs.app/po
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file; \
done
info:
dvi:
check: all
$(MAKE)
installcheck:
install-exec:
@$(NORMAL_INSTALL)
install-data: install-data-local
@$(NORMAL_INSTALL)
install: install-exec install-data all
@:
uninstall:
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs:
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(DISTCLEANFILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean: mostlyclean-generic
clean: clean-generic mostlyclean
distclean: distclean-generic clean
-rm -f config.status
maintainer-clean: maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
.PHONY: tags distdir info dvi installcheck install-exec install-data \
install uninstall all installdirs mostlyclean-generic distclean-generic \
clean-generic maintainer-clean-generic clean mostlyclean distclean \
maintainer-clean
.po.mo:
msgfmt -o $@ $<
WPrefs.pot: $(POTFILES)
xgettext --default-domain=WPrefs \
--add-comments --keyword=_ $(POTFILES)
if cmp -s WPrefs.po WPrefs.pot; then \
rm -f WPrefs.po; \
else \
mv -f WPrefs.po WPrefs.pot; \
fi
install-data-local: $(CATALOGS)
$(mkinstalldirs) $(nlsdir)
chmod 755 $(nlsdir)
for n in $(CATALOGS) __DuMmY ; do \
if test "$$n" -a "$$n" != "__DuMmY" ; then \
l=`basename $$n .mo`; \
$(mkinstalldirs) $(nlsdir)/$$l/LC_MESSAGES; \
chmod 755 $(nlsdir)/$$l; \
chmod 755 $(nlsdir)/$$l/LC_MESSAGES; \
$(INSTALL) -m 644 $$n $(nlsdir)/$$l/LC_MESSAGES/WPrefs.mo; \
fi; \
done
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

Some files were not shown because too many files have changed in this diff Show More