mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-18 20:10:29 +01: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