mirror of
https://github.com/gryf/wmaker.git
synced 2026-04-02 04:53:34 +02:00
Initial revision
This commit is contained in:
177
AUTHORS
Normal file
177
AUTHORS
Normal 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
71
BUGFORM
Normal 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
10
BUGS
Normal 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
340
COPYING
Normal 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.
|
||||||
907
FAQ
Normal file
907
FAQ
Normal 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
51
FAQ.I18N
Normal 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
455
INSTALL
Normal 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
210
Install
Executable 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
54
MIRRORS
Normal 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
14
Makefile.am
Normal 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
322
Makefile.in
Normal 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:
|
||||||
194
README
Normal file
194
README
Normal 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
50
TODO
Normal 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
96
WINGs/ChangeLog
Normal 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
90
WINGs/Makefile.am
Normal 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
513
WINGs/Makefile.in
Normal 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
102
WINGs/README
Normal 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
BIN
WINGs/Resources/Images.tiff
Normal file
Binary file not shown.
BIN
WINGs/Resources/Images.xcf
Normal file
BIN
WINGs/Resources/Images.xcf
Normal file
Binary file not shown.
236
WINGs/Resources/Images.xpm
Normal file
236
WINGs/Resources/Images.xpm
Normal 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 . ",
|
||||||
|
" . . . . . . . . . . . . . . . . . ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" "};
|
||||||
6
WINGs/Resources/Makefile.am
Normal file
6
WINGs/Resources/Makefile.am
Normal 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
210
WINGs/Resources/Makefile.in
Normal 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:
|
||||||
BIN
WINGs/Resources/defaultIcon.tiff
Normal file
BIN
WINGs/Resources/defaultIcon.tiff
Normal file
Binary file not shown.
54
WINGs/Resources/defaultIcon.xpm
Normal file
54
WINGs/Resources/defaultIcon.xpm
Normal 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
5
WINGs/TODO
Normal 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
1004
WINGs/WINGs.h
Normal file
File diff suppressed because it is too large
Load Diff
394
WINGs/WINGsP.h
Normal file
394
WINGs/WINGsP.h
Normal 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
227
WINGs/WUtil.h
Normal 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
49
WINGs/configuration.c
Normal 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
118
WINGs/error.c
Normal 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
285
WINGs/findfile.c
Normal 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
104
WINGs/fontl.c
Normal 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
406
WINGs/hashtable.c
Normal 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
12
WINGs/international.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#include "WINGsP.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InitI18n(Display *dpy)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
56
WINGs/logo.xpm
Normal file
56
WINGs/logo.xpm
Normal 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
169
WINGs/memory.c
Normal 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
221
WINGs/mywidget.c
Normal 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
15
WINGs/mywidget.h
Normal 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
414
WINGs/notification.c
Normal 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
293
WINGs/selection.c
Normal 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
51
WINGs/testmywidget.c
Normal 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
420
WINGs/userdefaults.c
Normal 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
50
WINGs/usleep.c
Normal 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
301
WINGs/wapplication.c
Normal 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
911
WINGs/wbrowser.c
Normal 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
714
WINGs/wbutton.c
Normal 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
325
WINGs/wcolor.c
Normal 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
257
WINGs/wcolorwell.c
Normal 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
918
WINGs/wevent.c
Normal 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
559
WINGs/wfilepanel.c
Normal 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
272
WINGs/wfont.c
Normal 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
654
WINGs/wfontpanel.c
Normal 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
223
WINGs/wframe.c
Normal 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
894
WINGs/widgets.c
Normal 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
243
WINGs/wlabel.c
Normal 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
797
WINGs/wlist.c
Normal 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
97
WINGs/wmfile.c
Normal 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
297
WINGs/wmisc.c
Normal 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
99
WINGs/wmquery.c
Normal 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
399
WINGs/wpanel.c
Normal 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
205
WINGs/wpixmap.c
Normal 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
709
WINGs/wpopupbutton.c
Normal 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
863
WINGs/wscroller.c
Normal 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
501
WINGs/wscrollview.c
Normal 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
482
WINGs/wslider.c
Normal 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
402
WINGs/wsplitview.c
Normal 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
445
WINGs/wtest.c
Normal 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
880
WINGs/wtextfield.c
Normal 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
663
WINGs/wview.c
Normal 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
646
WINGs/wwindow.c
Normal 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
458
WPrefs.app/Configurations.c
Normal 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
113
WPrefs.app/Expert.c
Normal 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
395
WPrefs.app/Focus.c
Normal 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
318
WPrefs.app/Icons.c
Normal 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;
|
||||||
|
}
|
||||||
181
WPrefs.app/KeyboardSettings.c
Normal file
181
WPrefs.app/KeyboardSettings.c
Normal 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;
|
||||||
|
}
|
||||||
439
WPrefs.app/KeyboardShortcuts.c
Normal file
439
WPrefs.app/KeyboardShortcuts.c
Normal 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
64
WPrefs.app/Makefile.am
Normal 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
439
WPrefs.app/Makefile.in
Normal 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
1366
WPrefs.app/Menu.c
Normal file
File diff suppressed because it is too large
Load Diff
502
WPrefs.app/MenuGuru.c
Normal file
502
WPrefs.app/MenuGuru.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
239
WPrefs.app/MenuPreferences.c
Normal file
239
WPrefs.app/MenuPreferences.c
Normal 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
906
WPrefs.app/MouseSettings.c
Normal 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
395
WPrefs.app/Paths.c
Normal 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
225
WPrefs.app/Preferences.c
Normal 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
111
WPrefs.app/README
Normal 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
335
WPrefs.app/Text.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
641
WPrefs.app/TextureAndColor.c
Normal file
641
WPrefs.app/TextureAndColor.c
Normal 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
855
WPrefs.app/WPrefs.c
Normal 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
119
WPrefs.app/WPrefs.h
Normal 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
BIN
WPrefs.app/WPrefs.tiff
Normal file
Binary file not shown.
237
WPrefs.app/WPrefs.xpm
Normal file
237
WPrefs.app/WPrefs.xpm
Normal 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
357
WPrefs.app/WindowHandling.c
Normal 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
295
WPrefs.app/Workspace.c
Normal 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
200
WPrefs.app/double.c
Normal 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
5
WPrefs.app/double.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
typedef struct W_DoubleTest DoubleTest;
|
||||||
|
|
||||||
|
|
||||||
|
DoubleTest *CreateDoubleTest(WMWidget *parent, char *text);
|
||||||
135
WPrefs.app/main.c
Normal file
135
WPrefs.app/main.c
Normal 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
55
WPrefs.app/po/Makefile.am
Normal 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
238
WPrefs.app/po/Makefile.in
Normal 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
Reference in New Issue
Block a user