Compare commits
142 Commits
Author | SHA1 | Date |
---|---|---|
wdlkmpx | f3ff2c62eb | |
wdlkmpx | f3043727dc | |
wdlkmpx | e8dd889f24 | |
wdlkmpx | 802a4bda50 | |
wdlkmpx | e390c1e063 | |
wdlkmpx | 0573d99082 | |
wdlkmpx | ee2560d57f | |
PRESFIL | 8e1c8718ae | |
wdlkmpx | c9e22f006a | |
wdlkmpx | 78cac66790 | |
wdlkmpx | 1e678b1038 | |
wdlkmpx | ceb6ae60b5 | |
wdlkmpx | a9c45a9f9d | |
wdlkmpx | bfed4acda5 | |
wdlkmpx | 077ac01700 | |
wdlkmpx | 073e95a57a | |
wdlkmpx | f59d31c5a4 | |
wdlkmpx | 26d4fb47c6 | |
wdlkmpx | 7caa9ae8b4 | |
wdlkmpx | 21dc2c4470 | |
wdlkmpx | 8ca61a3951 | |
wdlkmpx | 6223b53709 | |
wdlkmpx | 91173a2b49 | |
wdlkmpx | 49dab051bf | |
wdlkmpx | 8e028445ca | |
wdlkmpx | b3dbc9ca9a | |
wdlkmpx | 4fd7c52c48 | |
wdlkmpx | d41ba7df77 | |
wdlkmpx | e84930778a | |
wdlkmpx | 68282dd4c0 | |
wdlkmpx | 0bd21c2b90 | |
wdlkmpx | a46c04beca | |
wdlkmpx | 4bc440cbb8 | |
wdlkmpx | 8f95488c2c | |
wdlkmpx | 177832c04a | |
wdlkmpx | f529279ce5 | |
wdlkmpx | c5fb31c030 | |
wdlkmpx | b00981c4b3 | |
wdlkmpx | 771e5f5cfa | |
wdlkmpx | 03a98addb3 | |
wdlkmpx | ed2760ac97 | |
wdlkmpx | 833e0708e2 | |
wdlkmpx | 571d6f428c | |
wdlkmpx | a48ae4b973 | |
wdlkmpx | 4930aa9240 | |
wdlkmpx | 90a73af854 | |
wdlkmpx | ea07442da2 | |
wdlkmpx | 9f12390b20 | |
wdlkmpx | 3c4519a534 | |
wdlkmpx | 0f94a8cad3 | |
wdlkmpx | 30929fe68d | |
wdlkmpx | 2c254aad92 | |
wdlkmpx | 496a0782b4 | |
wdlkmpx | 53de437b97 | |
wdlkmpx | 70a9bde3f6 | |
wdlkmpx | 669f9094cc | |
wdlkmpx | aecb75916c | |
wdlkmpx | b026cd6e04 | |
wdlkmpx | d794934169 | |
wdlkmpx | 3727eb6d26 | |
wdlkmpx | 60b7bca318 | |
wdlkmpx | c8bd0dec3e | |
wdlkmpx | d46e89b2cf | |
wdlkmpx | acb6881379 | |
wdlkmpx | 9b51f89c54 | |
wdlkmpx | fe821ecd98 | |
wdlkmpx | e866c24c39 | |
wdlkmpx | da57c5dcb9 | |
wdlkmpx | 4361172862 | |
wdlkmpx | 30b75bd447 | |
wdlkmpx | 7218498da6 | |
wdlkmpx | d1b718c086 | |
wdlkmpx | 7622a99196 | |
wdlkmpx | 84df0cdecc | |
wdlkmpx | 41c75d7610 | |
wdlkmpx | 3762bfc1d4 | |
wdlkmpx | ef6ffe8d80 | |
wdlkmpx | 2869dc0e23 | |
wdlkmpx | b95c55899b | |
wdlkmpx | 7c73eb62ea | |
wdlkmpx | 5bec03672d | |
wdlkmpx | 1a72b7c36c | |
wdlkmpx | 05511520d9 | |
wdlkmpx | 1836e4a58f | |
wdlkmpx | 83cb7b7d85 | |
wdlkmpx | 92f184ac7e | |
wdlkmpx | b227610e0c | |
wdlkmpx | 42860f123a | |
wdlkmpx | 4615a8701c | |
wdlkmpx | ceff6dd2bd | |
wdlkmpx | f191713307 | |
wdlkmpx | da1ec0d8fd | |
wdlkmpx | 997eb7480e | |
wdlkmpx | 67096ce9ae | |
wdlkmpx | 3d3c2785ed | |
wdlkmpx | 37667213b0 | |
wdlkmpx | abb39e6d61 | |
wdlkmpx | a93e3b8b08 | |
wdlkmpx | 9097eba9f3 | |
wdlkmpx | 216c71d7fd | |
wdlkmpx | 81d1a925f2 | |
wdlkmpx | d73f7460c4 | |
wdlkmpx | 0dab60df9b | |
wdlkmpx | cd78cd0f0d | |
wdlkmpx | 703cf54b76 | |
wdlkmpx | fe7fdf4f54 | |
wdlkmpx | 2dd933b6a2 | |
wdlkmpx | 2b250ecbd7 | |
wdlkmpx | a2009d7d76 | |
wdlkmpx | c4813e68e4 | |
wdlkmpx | 54c03a2099 | |
wdlkmpx | e6328e50a8 | |
wdlkmpx | 1345447fb1 | |
wdlkmpx | 8340de3671 | |
Samuel Bauer | d6a5099595 | |
wdlkmpx | 1ce4041550 | |
Samuel Bauer | df93a29b66 | |
wdlkmpx | c64e88d053 | |
wdlkmpx | 35f715d5c9 | |
wdlkmpx | 97e81a047e | |
wdlkmpx | 108bd70d17 | |
Samuel Bauer | 617d1847df | |
Samuel Bauer | 7037e1079a | |
Samuel Bauer | 49443fe20b | |
wdlkmpx | de54e6311c | |
Samuel Bauer | f3a560cc31 | |
mazes_80 | bbc29eca32 | |
wdlkmpx | 869a63a7a0 | |
wdlkmpx | 6063a4d2ba | |
wdlkmpx | 5572744a9a | |
wdlkmpx | 876b146465 | |
wdlkmpx | 827d926d23 | |
wdlkmpx | aa4a37ddcc | |
wdlkmpx | f9094b6a61 | |
wdlkmpx | f5106c4526 | |
wdlkmpx | 39f5b171cb | |
wdlkmpx | d338978275 | |
wdlkmpx | 6bce26ac00 | |
wdlkmpx | 2ad08091e7 | |
wdlkmpx | 1571627ad9 | |
wdlkmpx | a7d13fdfa6 | |
wdlkmpx | edd815e3fd |
|
@ -4,6 +4,7 @@ compile
|
|||
config.guess
|
||||
config.h*
|
||||
config.log
|
||||
config.rpath
|
||||
config.status
|
||||
config.sub
|
||||
autom4te.cache
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
language: c++
|
||||
install: sudo apt-get install libgtk2.0-dev
|
||||
before_script: ./autogen.sh
|
||||
script:
|
||||
- ./configure
|
||||
- make
|
18
AUTHORS
18
AUTHORS
|
@ -1 +1,17 @@
|
|||
Mihai Bazon <mishoo@infoiasi.ro>
|
||||
Initial author: Mihai Bazon <mishoo@infoiasi.ro>
|
||||
|
||||
Icon: Andrea Soragna - https://icon-icons.com/icon/gtk-execute/36132
|
||||
|
||||
CVS:
|
||||
----
|
||||
|
||||
andreas99
|
||||
Henning Schild
|
||||
Makoto Nokata
|
||||
mishoo
|
||||
Paweł Błaszczyk
|
||||
PRESFIL
|
||||
R. Tyler Croy
|
||||
Samuel Bauer
|
||||
sonofkojak
|
||||
wdlkmpx
|
||||
|
|
340
COPYING
340
COPYING
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year 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.
|
330
ChangeLog
330
ChangeLog
|
@ -1,23 +1,323 @@
|
|||
2003-11-16 AV <andreas99@users.sourceforge.net>
|
||||
* configure.in: added support for libpopt
|
||||
==========
|
||||
gmrun 1.1w
|
||||
==========
|
||||
|
||||
* src/gtkcompletionline.cc: added UTF-8 support for input and output
|
||||
PRESFIL (1):
|
||||
Fix xterm -e handling with multiword queryes
|
||||
|
||||
* src/main.cc: added UTF-8 support for input and output and
|
||||
added an option to place gmrun (-geometry)
|
||||
wdlkmpx (7):
|
||||
restore system(3) call as the default option to run commands
|
||||
main.c: ext_check(): escape spaces only if USE_XDG = 1
|
||||
rename USE_XDG to USE_GLIB_XDG
|
||||
gmrunrc: EXT syntax-> EXT:ext,etc = handler '%s'
|
||||
main.c: main() gtk3.4+: hide cmd line args from GApplication
|
||||
main.c (gtk3.4+): G_APPLICATION_NON_UNIQUE
|
||||
merge data/zrelease into autogen.sh ..
|
||||
|
||||
2002-06-05 EJ <sonofkojak@users.sourceforge.net>
|
||||
|
||||
* src/history.cc (append): Previously, an item was not placed in
|
||||
the history when it was the last item. Now, if we find an entry,
|
||||
we move it to the end of the list.
|
||||
==========
|
||||
gmrun 1.0w
|
||||
==========
|
||||
|
||||
2002-06-05 EJ <sonofkojak@users.sourceforge.net>
|
||||
Highlights:
|
||||
- GTK 3 support (default / use --enable-gtk2 to compile the gtk2 port)
|
||||
- should work with GTK 2.12+ (or even older GTK versions)
|
||||
- fixed broken CTRL-R / CTRL-S
|
||||
- gmrun is now a C application
|
||||
- added desktop file and icon
|
||||
- added manual
|
||||
- changed license to ISC (approved by @mishoo)
|
||||
- support Glib XDG handling (set USE_XDG = 1 in gmrunrc)
|
||||
- keep support for custom extension and url handlers
|
||||
(the app is a bit more complex than it should because of this)
|
||||
- restored --geometry param (it's a bit different)
|
||||
- gmrunrc: Geometry = (read comments)
|
||||
(this probably doesn't work with wayland and other protocols)
|
||||
|
||||
* acinclude.m4: Added stlport detection code. When using an old
|
||||
version of g++/stdc++ you can get this code to compile only with
|
||||
the stlport. gcc-2.9[56] don't have a definition for
|
||||
char_traits.
|
||||
changes since 0.9.5w
|
||||
|
||||
|
||||
Samuel Bauer (6):
|
||||
parse_tilda(): use only glib
|
||||
removed quote_string: use glib regex
|
||||
removed compilation warnings
|
||||
Cosmetic changes
|
||||
renamed main window
|
||||
gtkcompletionline.cc: don't use `goto` in generate_dir_list()
|
||||
|
||||
mazes_80 (1):
|
||||
GtkCList to GtkTreeview
|
||||
|
||||
wdlkmpx (124):
|
||||
update README.markdown (a bit)
|
||||
gtk_signal_* -> g_signal_* / GTK_OBJECT -> GTK_WIDGET
|
||||
Replace GDK_<keyname> with GDK_KEY_<keyname>
|
||||
minimum gtk version = 2.24.0
|
||||
gtkcompletionline.cc: use gtk-widget-get-allocation
|
||||
replace gtk_timeout_add() with g_timeout_add() [not sure what I'm doing]
|
||||
Replace GTK_CHECK_CAST with G_TYPE_CHECK_INSTANCE_CAST
|
||||
Replace gtk_widget_set_usize() with gtk_widget_set_size_request()
|
||||
gtkcompletionline.cc: comment out gtk_window_set_policy()
|
||||
WIP gtk3 support [--enable-gtk3]
|
||||
gtk2/3: remove titlebar from dialog (is this a good idea?)
|
||||
gtk2/3: set_info_text_color() [unify GtkStyle functions]
|
||||
update readme
|
||||
gmrunrc: better defaults
|
||||
gtk2/3: support "navigating" history with mouse wheel
|
||||
indentation style: use tabs
|
||||
Silence "GtkDialog mapped without a transient parent. This is discouraged."
|
||||
update ChangeLog & AUTHORS
|
||||
remove gmrun.glade
|
||||
update README a bit
|
||||
fix setting dialog border, name and title..
|
||||
gmrunrc: remove unused options
|
||||
reimplement `--geometry WxH+X+Y` (cli param) [without libpopt]
|
||||
main.cc: properly free GError and GOptionContext...
|
||||
support gtk >= 2.14
|
||||
update autogen.sh
|
||||
gtkcompletionline.cc: hack for glibc < 2.10 (dirent)
|
||||
src: use gtk_box_new()
|
||||
src: (gtkcompat) use gtk_widget_set_halign/valign
|
||||
src: (gtkcompat) use gtk_widget_set_margin_start/end
|
||||
main.cc: (search) fix "Source ID was not found when attempting to remove it"
|
||||
gtkcompletionline.cc: avoid on_key_press callback when key is released
|
||||
completion: don't create extra column
|
||||
completion: use gtk_tree_selection_select_iter()
|
||||
completion: attemp to silence Gtk-WARNING **: Allocating size to Window ...
|
||||
completion: use gtk_tree_model_iter_n_children() to get row count
|
||||
gtk_completion_line_class_init(): cosmetic changes
|
||||
main.cc: main_vbox
|
||||
main.cc: gtk_widget_show_all (dialog)
|
||||
use G_OBJECT with g_signal_*
|
||||
run_the_command: use g_shell_parse_argv() and g_spawn_async()
|
||||
set_info_text_color: optimize a bit
|
||||
window icon: use 'system-run' or 'gtk-execute'
|
||||
remove src/main.h
|
||||
update gtkcompat.h
|
||||
gtkcompletionline.cc: use G_DEFINE_TYPE_EXTENDED()
|
||||
gtk_completion_line_init: 'self' instead of 'object'
|
||||
add gmrun.desktop / gmrun.png
|
||||
main.cc: gmrun_exit()
|
||||
main.cc: gmrun_activate() / parse_command_line()
|
||||
new configuration option: Geometry
|
||||
completion: TabTimeout: fix "Source ID was not found when attempting to remove it"
|
||||
*** handle configuration and history with C code ***
|
||||
completion: (search) cl->hist_word is now a char array
|
||||
src/main.cc: get rid of 'struct gigi'
|
||||
completionline.cc: fix Pango-CRITICAL **: pango_layout_get_cursor_pos ...
|
||||
main.cc: (history) show search text next to "Search:" label
|
||||
history.c: improvements
|
||||
completionline: remove handling of ctrl-e/g (what's this?)
|
||||
completionline.cc: make CTRL-R work as intended..
|
||||
main.cc: fix calls to config_get_int()
|
||||
ext_check/url_check: don't include handler in history entry
|
||||
option to use glib XDG handling (disabled by default)
|
||||
fix build with ancient glib
|
||||
add data/zmtrace.sh
|
||||
*** gtkcompletionline.c: use C code ***
|
||||
*** gmrun is now a C application ***
|
||||
configure.ac: enable many gcc warnings
|
||||
gtkcompletionline.c: don't use gtk_tree_model_sort_new_with_model()
|
||||
gtkcompletionline.c: use spaces
|
||||
main.c: use spaces
|
||||
complete_line(): optimize a bit / fix some memory leaks
|
||||
gtkcompletionline.c: add debug code
|
||||
gtkcompletionline.c: remove complete_common()
|
||||
gtkcompletionline.c: fix complete_from_list / set_words / complete_line
|
||||
gtkcompletionline.c: avoid triggering on_cursor_changed() twice
|
||||
merge generate_completion_from_execs/dirlist() into complete_line()
|
||||
gtkcompletionline.c: improve logic to free glists
|
||||
tab_pressed(): don't call complete_line() if completion window exists
|
||||
gtkcompletionline.c: fix memory leak in complete_from_list()
|
||||
get_words(): add empty string if glist is empty
|
||||
gtkcompletionline: remove unused cl->first_key
|
||||
gtkcompletionline.c: fix segfault with gtk3
|
||||
gtkcompletionline.c: properly sort completion list
|
||||
gtkcompletionline: set/unset prefix in generate_execs_list/dirlist()
|
||||
gtkcompletionline.c: use only cl->cmpl to get filelist
|
||||
gtkcompletionline.c: remove unused GEN_COMP...
|
||||
src/history.c: fix memory leaks
|
||||
generate_dir_list(): don't use GString
|
||||
gtkcompletionline.c: simplify my_alphasort()
|
||||
gtkcompletionline.c: (scandir) use standard alphasort
|
||||
complete_line: items > 1: always use 1st item from GtkTreeView
|
||||
complete_from_list: fix memory leak
|
||||
update README a bit
|
||||
Relicense project to ISC
|
||||
gtkcompletionline.c: set completion window transient for main window
|
||||
main.c: gmrun [text]
|
||||
add gmrun.1 (manual)
|
||||
gtkcompletionline: get rid of cl->cmpl
|
||||
completionline.c: CTRL-S/CTRL-R: search matches anywhere in strings
|
||||
gtkcompletionline.c: restore bash-like search for CTRL-S/R
|
||||
config_prefs.c: use free, strdup, calloc..
|
||||
gtkcompletionline.c: (scandir) don't use alphasort
|
||||
gtkcompletionline.c: (scandir) don't reverse GList
|
||||
gtkcompat.h 2020-10-11
|
||||
"!": history search mode that matches only the start of strings
|
||||
update gtkcompat
|
||||
search_off(): properly clear cl->hist_word ..
|
||||
CTRL-p: fetch the previous command from the history list
|
||||
CTRL-n: Fetch the next command from the history list
|
||||
CTRl-g (search mode): cancel search and clear text entry
|
||||
renamed: COPYING -> LICENSE
|
||||
remove .travis.yml
|
||||
move gmrunrc & zrelease to data/ dir
|
||||
update autogen.sh
|
||||
update README
|
||||
configure.ac: disable deprecated gtk2 stuff
|
||||
fix gcc9 warnings
|
||||
configure.ac: default to GTK3, fall back to GTK2
|
||||
update README
|
||||
history.c: use g_list_delete_link()
|
||||
gtkcompletionline: tweaks / don't declare var inside for loop..
|
||||
use GtkApplication for GTK3
|
||||
add Makefile.true
|
||||
|
||||
|
||||
|
||||
============
|
||||
gmrun 0.9.5w
|
||||
============ changes since 0.9.4w:
|
||||
|
||||
Henning Schild (2):
|
||||
gtk: replace deprecated gtk_type_new and _unique
|
||||
gtk: do not select any text to keep clipboard clean
|
||||
|
||||
unknown (1):
|
||||
Handle more than 256 characters in the history
|
||||
|
||||
wdlkmpx (3):
|
||||
add .travis.yml
|
||||
configure.ac: no need to check for glib
|
||||
gmrun 0.9.5w
|
||||
|
||||
|
||||
============
|
||||
gmrun 0.9.4w
|
||||
============ changes since 0.9.2:
|
||||
|
||||
Makoto Nokata (2):
|
||||
Rewritten feature which places gmrun window on monitor
|
||||
Updated default gmrun config
|
||||
|
||||
Paweł Błaszczyk (2):
|
||||
Fix for "undefined reference to symbol 'XQueryPointer'"
|
||||
Use GtkDialog instead of GtkWindow.
|
||||
|
||||
R. Tyler Ballance (1):
|
||||
Correct a few compiler errors due to missing imports under gcc4
|
||||
|
||||
R. Tyler Croy (7):
|
||||
Remove generated config.h.in
|
||||
Add simplistic git ignore file
|
||||
Fix bug with running quoted commands in the terminal
|
||||
Correct improper function prototype for my_alphasort.
|
||||
Rename the readme for extra special GitHub consideration
|
||||
Center the window on the screen with the mouse pointer
|
||||
Add a README symlink for kicks
|
||||
|
||||
wdlkmpx (15):
|
||||
clean up/update build system
|
||||
always use libc's system() function to run commands
|
||||
configure.ac: remove unneded AM_PROG_AR
|
||||
bump version to 0.9.3
|
||||
use gtk_window_set_position()
|
||||
remove commented out code
|
||||
remove libpopt dep / --geometry param
|
||||
remove gmrun.spec.in...
|
||||
configure.ac: update AM_INIT_AUTOMAKE
|
||||
update .gitignore
|
||||
remove unused screen_contains_pointer()
|
||||
add 'make-release' script
|
||||
configure.ac: remove unused XQueryPointer stuff
|
||||
simplify / use @sysconfdir@ for gmrunrc
|
||||
bump version to 0.9.4w
|
||||
|
||||
|
||||
===========
|
||||
gmrun 0.9.2
|
||||
===========
|
||||
|
||||
andreas99 (3):
|
||||
- merged gtk-2 branch to main branch
|
||||
- UTF-8 support - libpopt support
|
||||
changes for 0.9.2
|
||||
|
||||
mishoo (73):
|
||||
Initial revision
|
||||
These files are generated.
|
||||
little bug fixed in gtkcompletionline.cc (the prev. version works with an older compiler)
|
||||
Removed useless files
|
||||
jump to new version
|
||||
removed unconditional debug output.
|
||||
added drop-down list (nice)
|
||||
switch to new version (added drop-down list functionality)
|
||||
*** empty log message ***
|
||||
some nice changes - fixed bug, completion window is displayed even if we're not completing the last word. Also, cursor now marks two words for completion, even if there's no space between.
|
||||
some bugs fixes, support for CTRL-ENTER starts command in terminal.
|
||||
new version
|
||||
Added support for configuration file
|
||||
fix compilation prob.
|
||||
configure -- switch to new version gtkcompletionline -- much smoother completion.. select completed-text.. etc, really better.. prefs -- added support for $(Variable) expansion main -- added 3 config options: Top, Left (opper-left corner)
|
||||
End, Escape -- clear the selection
|
||||
-- swithced to new version -- more intuitive tab completion (hit tab only once, and the list is shown) -- fixed bug in prefs (made it recursive, so can replace more than one variable on a line) -- ... and other nice things :) hopefully
|
||||
fixed bug in gtkcompletionline.cc -- crashed when no completion found..
|
||||
case-insensitive std::string-like class
|
||||
*** empty log message ***
|
||||
default configuration file
|
||||
added support for default configuration file
|
||||
switched to new version
|
||||
revert to normal version (0.5.3-2 not good for building rpms..)
|
||||
[main.cc] set widget names [history.cc] history size moved to config file (not hard coded) [gmrunrc] set history size in default config file
|
||||
changed gdk_window_set_position to gtk_widget_set_uposition -- got rid of flicker.. :)
|
||||
updated
|
||||
*** empty log message ***
|
||||
trying to add CTRL-R feature from bash...
|
||||
updated code to support backward / forward searching through history using CTRL-R / CTRL-S as in bash / Emacs.
|
||||
fixed bug in CTRL-R/S searching. added code for backspace in history search mode.
|
||||
switched to new version (0.5.4)
|
||||
search phrase gets nice selected :)
|
||||
various bug fixes
|
||||
bug fixing / improvement..
|
||||
*** empty log message ***
|
||||
rpm spec file
|
||||
hmm...
|
||||
added "!" to complete from history with the last command beginning with the entered text
|
||||
cosmetic...
|
||||
updated
|
||||
new version
|
||||
- bug fixes - nice window, no titlebar
|
||||
fixed bug
|
||||
added URL-handling ability (check the config file)
|
||||
modified for URL-s also, added some small comments to make content clearer for user.
|
||||
changed version
|
||||
README -- improved documentation. configure -- hmm... this should be removed from CVS, but... later.
|
||||
removed. moved to gmrun.spec.in -- to be generated by configure.
|
||||
generates gmrun.spec when configure is run
|
||||
support for creating gmrun.spec
|
||||
fixed bug
|
||||
programs are now executed with exec*p
|
||||
fixed bug
|
||||
another bug fix... :)
|
||||
changes related to generation of gmrun.spec
|
||||
fixed some bugs; new features:
|
||||
updated for new configuration parameters
|
||||
updated for the new release
|
||||
fixed bug
|
||||
fixed bugs, new configuration parameter: ShowLast (1 / 0) to determine if gmrun should display the last history item as selected by default. (maybe some users don't like that...)
|
||||
added nice frame around the completion window
|
||||
*** empty log message ***
|
||||
included some patches from Michal Politowski (thanks!);
|
||||
bug fixes: - file names containing white-space now (hopefully) behave correctly - others, I don't remember
|
||||
they're kind of old, but..
|
||||
these are automatically generated, duh..
|
||||
preparing for a new version
|
||||
finally, I write news :)
|
||||
new bugfix version
|
||||
bugfixes: END/HOME (C-E/C-A) behavior is now much better, some code cleanup (mainly reindentation :)), removed some warnings, etc. Major bug fixed is that previously (with 0.8) you could not edit a .doc file with soffice if you had .doc extension handler set as AbiWord :)
|
||||
0.8.1 news
|
||||
bug fixed (the "e"/"E" character doesn't clear selection)
|
||||
|
||||
sonofkojak (1):
|
||||
Added support for STLPort.
|
||||
|
||||
|
|
5
Contrib
5
Contrib
|
@ -1,5 +0,0 @@
|
|||
-*- text -*-
|
||||
|
||||
Michal Politowski - provided patches for some.. well.. not bugs, but say
|
||||
incorrect behavior. Thanks! Also thanks to David B
|
||||
Harris who sent me these patches.
|
182
INSTALL
182
INSTALL
|
@ -1,182 +0,0 @@
|
|||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
|
@ -0,0 +1,13 @@
|
|||
Copyright 2020 Mihai Bazon
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided that
|
||||
the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALLWARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
26
Makefile.am
26
Makefile.am
|
@ -1,30 +1,6 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
SUBDIRS = src
|
||||
SUBDIRS = data src
|
||||
|
||||
myrcdir = @sysconfdir@
|
||||
myrc_DATA = gmrunrc
|
||||
EXTRA_DIST = gmrunrc
|
||||
|
||||
install-data-local:
|
||||
@$(NORMAL_INSTALL)
|
||||
if test -d $(srcdir)/pixmaps; then \
|
||||
$(SHELL) $(top_srcdir)/install-sh -d $(DESTDIR)$(pkgdatadir)/pixmaps; \
|
||||
for pixmap in $(srcdir)/pixmaps/*; do \
|
||||
if test -f $$pixmap; then \
|
||||
$(INSTALL_DATA) $$pixmap $(DESTDIR)$(pkgdatadir)/pixmaps; \
|
||||
fi \
|
||||
done \
|
||||
fi
|
||||
|
||||
dist-hook:
|
||||
if test -d pixmaps; then \
|
||||
mkdir $(distdir)/pixmaps; \
|
||||
for pixmap in pixmaps/*; do \
|
||||
if test -f $$pixmap; then \
|
||||
cp -p $$pixmap $(distdir)/pixmaps; \
|
||||
fi \
|
||||
done \
|
||||
fi
|
||||
|
||||
|
|
55
NEWS
55
NEWS
|
@ -1,55 +0,0 @@
|
|||
-*- text -*-
|
||||
|
||||
0.9.2 (Son, Nov 16 2003)
|
||||
|
||||
- UTF-8 support (only tested with german). Please report problems with
|
||||
other languages to <andreas99@users.sf.net>
|
||||
|
||||
- New little feature: you could place gmrun with the -geometry parameter
|
||||
|
||||
0.8.1 (Sat, Aug 17 2002)
|
||||
|
||||
- bug fix release:
|
||||
|
||||
- major bug fixed: you could not edit a .doc file with soffice if
|
||||
you had an extension handler for .doc set as "AbiWord %s" :)
|
||||
Analogue for other extensions.
|
||||
|
||||
- smoother key handling (mainly the END/C-E, HOME/C-A keys now work
|
||||
correctly and also clear the selection).
|
||||
|
||||
- others: elimined most compiler warnings (I just noticed them..:),
|
||||
some code cleanup (mainly reindentation).
|
||||
|
||||
0.8.0 (Fri, Aug 16 2002, it's been a long time)
|
||||
|
||||
- New feature: extension handlers. This allows us to type directly the
|
||||
file, and gmrun will select your preferred application handler based of
|
||||
the configuration in ~/.gmrunrc or $prefis/share/gmrun/gmrunrc
|
||||
|
||||
- New feature: TAB simulation. You can set a timeout for this in the
|
||||
config file, and gmrun will automatically issue a TAB press after that
|
||||
milliseconds after the last keypress.. I've tried to handle this the
|
||||
smart way, but it could still be buggy so by default is disabled
|
||||
(TabTimeout variable in config file, set it to some non-zero value to
|
||||
enable).
|
||||
|
||||
- New "feature": you can select the old way of running commands using the
|
||||
"system" libc function. This has the great advantage that allows you to
|
||||
combine commands using shell operators. To enable it specify
|
||||
"--enable-system" at configure time.
|
||||
|
||||
- Bug fix: white-space characters inside file names now (hopefully) behave
|
||||
correcly. They are backslash-ed :) like in bash.
|
||||
|
||||
- Bug fix: '!' character now enters search mode even if all the field is
|
||||
selected. Thanks to Michal Politowski for noticing this and also for
|
||||
fixing it :) actually I never regarded it as a bug, but it was.. :)
|
||||
|
||||
- Another patch from Michal Politowski lets two configuration files to
|
||||
work together. More specifically, if $prefix/share/gmrun/gmrunrc exists
|
||||
it will be loaded, and then it will try $HOME/.gmrunrc, but the latter
|
||||
does not override completely the settings from the global file. So you
|
||||
can provide clean defaults in the global file, and each user will
|
||||
customize it's own file by editing only those properties that he doesn't
|
||||
like.. which is kind of normal, after all :)
|
|
@ -1,47 +0,0 @@
|
|||
|
||||
since gmrun version 0.2.5 there is possible to use a configuration file for
|
||||
some features gmrun has... for now only Terminal and Width are available but
|
||||
maybe more will be added in the future ;-]~
|
||||
|
||||
The configuration file should be located in your home directory, named as
|
||||
GMRUNRC compilation directive (".gmrunrc" by default).
|
||||
|
||||
The syntax is plain simple. Look at the example below:
|
||||
--
|
||||
TermExec = xterm -bg black -fg white -geometry 100x60 -e
|
||||
Width = 300
|
||||
Top = 100
|
||||
Left = 50
|
||||
--
|
||||
|
||||
* 'TermExec' is the command used for terminal spawning when the magic
|
||||
Ctrl-Enter is pressed upon a gmrun command. NOTE that -e should be THE
|
||||
VERY LAST argument as the program just gets this configuration line and
|
||||
appends to it the gmrun input text. ie, try: 'man bash<Ctrl-Enter>'
|
||||
|
||||
* 'Width' is simply the desired width of the gmrun window in pixels (by
|
||||
default it is 500 which may be a little big for low-resolution X desktops).
|
||||
|
||||
* 'Top' and 'Left' represent ofc the distance from the top-left corner of your
|
||||
screen where the gmrun window will appear
|
||||
|
||||
|
||||
-----------------------------------
|
||||
NEWS:
|
||||
as gmrun v 0.5.3 appeared... mishoo thought it would be useful to be
|
||||
able to to things like these below in your configuration file:
|
||||
|
||||
##################### set terminal
|
||||
TermOptions = -bg black -cr green -fg white -C -fn 9x15 -sl 8912
|
||||
TermGeometry = -geometry 100x40
|
||||
MyTerm = rxvt
|
||||
|
||||
Terminal = ${MyTerm} ${TermOptions} ${TermGeometry}
|
||||
TermExec = ${Terminal} -e
|
||||
#####################################################
|
||||
|
||||
if you understand it and need it, use it =]~ it's pretty simple duh.. and
|
||||
quite useless though ;-]~
|
||||
|
||||
|
||||
//altblue
|
15
README.hints
15
README.hints
|
@ -1,15 +0,0 @@
|
|||
* Terminal spawning:
|
||||
- just activate your command by pressing not only ENTER but CTRL-ENTER
|
||||
(i.e.: man perl<CTRL-ENTER>)
|
||||
|
||||
* Completion:
|
||||
- hit TAB key to get a list of possible completions
|
||||
(isn't that obvious, duh!?! =]~ )
|
||||
|
||||
* Window too large?
|
||||
- read README.gmrunrc
|
||||
|
||||
* Want to run eterm/kterm/rxvt/gnome-terminal/footerm instead xterm?
|
||||
- read README.gmrunrc
|
||||
|
||||
//altblue
|
32
README.icewm
32
README.icewm
|
@ -1,32 +0,0 @@
|
|||
for those who use icewm as their window manager gmrun comes as a very light and good
|
||||
replacement for the nifty but desktop space consuming 'address bar' that
|
||||
comes with this window manager.
|
||||
what should you do:
|
||||
edit your icewm preferences (~/.icewm/preferences) and modify some
|
||||
params there as below:
|
||||
TaskBarDoubleHeight=0
|
||||
ShowAddressBar=0 # in fact this is the only option you need to
|
||||
# modify.. but this was my only reason to use a
|
||||
# double-height taskbar :))
|
||||
RunCommand="gmrun" # heh, this too :) .. it's pretty obvious why :P~
|
||||
|
||||
this can suffice but still there is more you can do to make your life easier:
|
||||
|
||||
1. put up a keyboard shortcut for gmrun:
|
||||
edit ~/.icewm/keys and put there a line like this one below:
|
||||
key "Alt+Ctrl+r" gmrun
|
||||
|
||||
2. customize the gmrun window management:
|
||||
edit ~/.icewm/winoptions and put there stuff like this:
|
||||
gmrun.ignoreTaskBar: 1
|
||||
gmrun.layer: OnTop
|
||||
gmrun.fResize: 0
|
||||
gmrun.fClose: 0
|
||||
gmrun.fMinimize: 0
|
||||
gmrun.fMaximize: 0
|
||||
gmrun.fHide: 0
|
||||
gmrun.fRollup: 0
|
||||
gmrun.dTitleBar: 0
|
||||
gmrun.dBorder: 0
|
||||
|
||||
//altblue
|
208
README.markdown
208
README.markdown
|
@ -1,208 +0,0 @@
|
|||
gmrun 0.9.4w http://students.infoiasi.ro/~mishoo/site/gmrun.epl
|
||||
------------ ---------------------------------------------------
|
||||
|
||||
Short GtkEntry for file autocompletion + main.cc that does the
|
||||
needed stuff for running programs. This is intended as a
|
||||
replacement to grun or gnome-run, which (sorry) sucks. The idea
|
||||
comes from the KDE Window Manager (ALT-F2 in KDE). Though, GNOME
|
||||
is better :)
|
||||
|
||||
|
||||
Copyright (c) 2000-2003 Mihai Bazon
|
||||
Author: Mihai Bazon <mishoo@infoiasi.ro>.
|
||||
|
||||
send postcards to:
|
||||
|
||||
Mihai Bazon,
|
||||
str. Republicii, nr. 350, sc. E, ap. 9, cod 6500 VASLUI - VASLUI
|
||||
Romania
|
||||
|
||||
This program falls under the GNU General Public License version 2 or above.
|
||||
|
||||
|
||||
Features
|
||||
---------
|
||||
|
||||
* Tilda completion (~/ <==> $HOME/)
|
||||
|
||||
* Completion works for separate words (e.g. you can type em<TAB> which
|
||||
turns to emacs, type a SPACE, and write the file you want to open using
|
||||
completion).
|
||||
|
||||
* I added history capability (limited to 20 entries, change history.cc for
|
||||
more, #define HIST_MAX_SIZE). History is maintained in the file "
|
||||
~/.gmrun_history ".
|
||||
|
||||
CHANGED (since 0.5.3, I think..) -- new config file parameter: History.
|
||||
|
||||
* CTRL-Enter runs the command in a terminal. CTRL-Enter without any
|
||||
command starts a new terminal.
|
||||
|
||||
* New configuration file: ~/.gmrunrc or /usr/local/share/gmrun/gmrunrc.
|
||||
Check one of them, configuration is very simple. From that file you
|
||||
can change window position and width, history size, terminal, URL
|
||||
handlers, etc.
|
||||
|
||||
* You can use CTRL-R / CTRL-S to search through history, much like in bash
|
||||
or Emacs. Also, pressing "!" as the first character enters some special
|
||||
search mode, finding those history entries that begin with the entered
|
||||
text.
|
||||
|
||||
* URL handlers (added in 0.6.0). Nice feature, allowing you to enter
|
||||
lines like "http://www.google.com" to start your favorite browser on
|
||||
www.google.com. The URL-s are configurable from the configuration
|
||||
file, in a simple manner (I hope..).
|
||||
|
||||
* Extension handlers (added in 0.8.0). Basically you can run, for
|
||||
instance, a ".txt" file, assuming that you have configured a handler for
|
||||
it in the configuration file. The default handler for ".txt" files is,
|
||||
of course, Emacs. But you can easily change that, you... you VIM user!
|
||||
|
||||
* UTF-8 support (added in 0.9.2)
|
||||
|
||||
Requirements
|
||||
-------------
|
||||
|
||||
* A good C++ compiler (that is, g++ 3.0 or later). It did originally
|
||||
compile with g++ 2.95, but not anymore ;-] -- though that's easy to fix.
|
||||
|
||||
* GTK-2. gmrun upto and including 0.8.1 were for GTK-1.x series, version
|
||||
0.9.0 requires GTK-2.
|
||||
|
||||
|
||||
For code critics
|
||||
-----------------
|
||||
|
||||
This program is written in 2 hours. The code might seem a little weird,
|
||||
but it works, and that's what I'm interested in. Code completion is
|
||||
written in C++, although GTK+ is written in standard C. Should you think
|
||||
this is a problem, feel free to rewrite the code in C (it could be at
|
||||
least 4 times bigger).
|
||||
|
||||
It uses some static data (I know, I'm a too lasy programmer to think about
|
||||
something better); this means that if you're having *two or more*
|
||||
GtkCompletionLine-s in a program, you're looking for trouble. The static
|
||||
data will be *shared* between them, and completion might not work
|
||||
correctly. However, I don't know for sure, and I'm not going to test
|
||||
this.
|
||||
|
||||
Having all that said, you should know that I'm not actually a bad
|
||||
programmer ;-] The problem being too simple for huge code complications, I
|
||||
preferred the easy way of doing different kind of things. It works quite
|
||||
fine, so "don't expect tons of C code for completion" (quoted from some
|
||||
sources in mini-commander applet of GNOME).
|
||||
|
||||
|
||||
Compilation, installation
|
||||
--------------------------
|
||||
|
||||
Use the configure script:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
After this the executable goes usually in /usr/local/bin, make sure this is
|
||||
in your path. Put this in your .sawmillrc:
|
||||
|
||||
(require 'sawmill-defaults)
|
||||
(bind-keys global-keymap "S-C-M-RET" '(system "gmrun &"))
|
||||
|
||||
Note that if you're using sawfish you have other ways to customize your
|
||||
keyboard, through the control panel.
|
||||
|
||||
For another window managers you gonna have to find a way to bind this
|
||||
program to a key combination; otherwise it wouldn't be much help... (I
|
||||
coded it exactly to get rid of the mouse-time-wasting-walking).
|
||||
E.g. for IceWM (my favorite, at this time) you edit ~/.icewm/preferences
|
||||
and add a line like:
|
||||
|
||||
KeySysRun="Alt+Ctrl+Shift+Enter"
|
||||
|
||||
|
||||
Tips and tricks (hope that doesn't sound MS-ish...)
|
||||
----------------------------------------------------
|
||||
|
||||
1. Everything that doesn't start with "/" or "~" gets completed from $PATH
|
||||
environment var. More exactly, all files from $PATH directories are
|
||||
subjects to completion (even if they are NOT executables; this is a
|
||||
bug, but I'm afraid I'm not willing to fix it).
|
||||
|
||||
Pressing TAB once when no text is entered opens the completion window,
|
||||
which will contain ALL files under $PATH.
|
||||
|
||||
2. For instance you use TAB to complete from "nets" to "netscape-navigator".
|
||||
A small window appears, allowing you to select from:
|
||||
|
||||
- netscape
|
||||
- netscape-communicator
|
||||
- netscape-navigator
|
||||
- netstat
|
||||
|
||||
That is because all these executables have the same prefix, "nets". You
|
||||
type TAB twice to get to the third element ("netscape-navigator"). Now,
|
||||
if you want to add a parameter such as "-url http://blah.blah.org" you
|
||||
can press SPACE (the list disappears, and a SPACE is inserted after the
|
||||
netscape-navigator).
|
||||
|
||||
3. If you accidentally pressed TAB more than you wanted (in that small
|
||||
window, described above) you can use UP / DOWN arrows to select the right
|
||||
completion.
|
||||
|
||||
4. - ESC closes the completion window, leaving the selected text in the entry.
|
||||
- HOME / END - the same, but clears the selection.
|
||||
- SPACE - the same, but clears the selection and appends one space.
|
||||
- Pressing ENTER (anytime) runs the command that is written in the entry.
|
||||
- Pressing CTRL+Enter (anytime) runs the command in a terminal (check your
|
||||
configuration file). But if the entry is empty (no text is present, or
|
||||
only whitespaces) then a fresh terminal will be started.
|
||||
|
||||
5. Suppose you use CTRL-R to search backwards through history. If,
|
||||
accidentally, you skipped the line that you're interested in, you can use
|
||||
CTRL-S to search forward. This is more awesome than in bash :) It
|
||||
basically acts like a filter on history, for which you use CTRL-R instead
|
||||
of UP arrow, and CTRL-S instead of DOWN arrow.
|
||||
|
||||
The same if you search something with "!": only lines that BEGIN with the
|
||||
entered text are matching, but you can reverse the search order using
|
||||
CTRL-R / CTRL-S. Very flexible approach.
|
||||
|
||||
|
||||
Bugs
|
||||
-----
|
||||
|
||||
* It gets pretty slow... Maybe I should consider writting it in ANSI-C,
|
||||
but.... maybe not.
|
||||
|
||||
* Writting this README took me more time than writting the program.
|
||||
|
||||
* As I mentioned before, the code is written in C++, although GTK+ is a
|
||||
C library. This is not actually a bug; I like C++ because programs
|
||||
become clearer and easier to maintain, not to mention the source file
|
||||
size is smaller. So, if anyone cares to port this to standard C, feel
|
||||
free to do it, but I fear the code should be rewritten (almost) from
|
||||
scratch.
|
||||
|
||||
* Documentation is inexistent (except this file) (however, it would be
|
||||
quite useless).
|
||||
|
||||
Should you have any problems mail me a detailed description; please put
|
||||
the text "ignore_me" in the subject line, for easy message filtering. :)
|
||||
(just kidding... I would gladely help if I can).
|
||||
|
||||
* Actually I worked more than 2 hours. Anyway, the completion code took
|
||||
about 2-3 h to design and implement.
|
||||
|
||||
|
||||
Disclaimer
|
||||
-----------
|
||||
|
||||
* The Short Way:
|
||||
NO WARRANTIES OF ANY KIND. USE IT AT YOUR OWN RISK.
|
||||
|
||||
* The Right Way:
|
||||
Please read the GNU General Public License. This program falls under
|
||||
its terms.
|
||||
|
||||
|
||||
(: END OF TERMS AND CONDITIONS :)
|
|
@ -0,0 +1,90 @@
|
|||
GMRUN
|
||||
-----
|
||||
A run utiliy featuring a slim design and bash style auto-completion.
|
||||
|
||||
Features
|
||||
---------
|
||||
|
||||
* Tilda completion (~/ <==> $HOME/)
|
||||
|
||||
* Completion works for separate words (e.g. you can type em<TAB> which
|
||||
turns to emacs, type a SPACE, and write the file you want to open using
|
||||
completion).
|
||||
|
||||
* Configuration file: ~/.gmrunrc or /etc/gmrunrc.
|
||||
Check one of them, configuration is very simple. From that file you
|
||||
can change window position and width, history size, terminal, URL
|
||||
handlers, etc.
|
||||
|
||||
* CTRL-Enter runs the command in a terminal.
|
||||
* CTRL-Enter without any command starts a new terminal.
|
||||
|
||||
* History is maintained in the file "~/.gmrun_history".
|
||||
|
||||
* CTRL-R to search backwards through history.
|
||||
* CTRL-S to search forward through history.
|
||||
* "!" enters a special search mode, matching only the start of strings.
|
||||
-- Esc to cancel search (only once).
|
||||
-- CTRL-G to cancel search and clear the text entry
|
||||
|
||||
* URL handlers allowing you to enter lines like "http://www.google.com"
|
||||
to start your favorite browser on www.google.com.
|
||||
The URL-s are configurable from the configuration file.
|
||||
|
||||
* Extension handlers. Basically you can run, for instance,
|
||||
a ".txt" file, assuming that you have configured a handler for it
|
||||
in the configuration file.
|
||||
|
||||
|
||||
Requirements
|
||||
-------------
|
||||
|
||||
* GTK 2/3
|
||||
|
||||
|
||||
Compilation, installation
|
||||
--------------------------
|
||||
|
||||
Use the configure script (run ./autogen.sh if ./configure is missing):
|
||||
|
||||
./configure --prefix=/usr --sysconfdir=/etc
|
||||
make
|
||||
make install
|
||||
|
||||
By default it will use the GTK3 ui if it's available.
|
||||
|
||||
Pass `--enable-gtk2` to `./configure` to build the gtk2 ui
|
||||
|
||||
Optionally you can configure your window manager to call gmrun
|
||||
with WinKey + R or something.
|
||||
|
||||
|
||||
Tips and tricks
|
||||
---------------
|
||||
|
||||
1. Everything that doesn't start with "/" or "~" gets completed from $PATH
|
||||
environment var. More exactly, all files from $PATH directories are
|
||||
subjects to completion.
|
||||
|
||||
Pressing TAB once when no text is entered opens the completion window,
|
||||
which will contain ALL files under $PATH.
|
||||
|
||||
2. For instance you use TAB to complete from "nets" to "netscape-navigator".
|
||||
A small window appears, allowing you to select from:
|
||||
|
||||
- netscape
|
||||
- netscape-navigator
|
||||
- netstat
|
||||
|
||||
That is because all these executables have the same prefix, "nets".
|
||||
|
||||
You can use UP / DOWN arrows to select the right completion.
|
||||
You can use CTRL-P / CTRL-N or TAB to select the right completion.
|
||||
|
||||
3. - ESC closes the completion window, leaving the selected text in the entry.
|
||||
- HOME / END - the same, but clears the selection.
|
||||
- SPACE - the same, but clears the selection and appends one space.
|
||||
- Pressing ENTER (anytime) runs the command that is written in the entry.
|
||||
- Pressing CTRL+Enter (anytime) runs the command in a terminal (check your
|
||||
configuration file). But if the entry is empty (no text is present, or
|
||||
only whitespaces) then a fresh terminal will be started.
|
65
autogen.sh
65
autogen.sh
|
@ -1,14 +1,61 @@
|
|||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
#Get all required m4 macros required for configure
|
||||
libtoolize -ci
|
||||
aclocal
|
||||
if test "$1" == "release" || test "$1" == "--release" ; then
|
||||
pkg="$(grep -m1 AC_INIT configure.ac | cut -f 2 -d '[' | cut -f 1 -d ']')"
|
||||
ver="$(grep -m1 AC_INIT configure.ac | cut -f 3 -d '[' | cut -f 1 -d ']')"
|
||||
ver=$(echo $ver)
|
||||
dir=${pkg}-${ver}
|
||||
rm -rf ../$dir
|
||||
mkdir -p ../$dir
|
||||
cp -rf $PWD/* ../$dir
|
||||
( cd ../$dir ; ./autogen.sh )
|
||||
cd ..
|
||||
tar -Jcf ${dir}.tar.xz $dir
|
||||
exit
|
||||
fi
|
||||
|
||||
#generate configure
|
||||
autoconf
|
||||
#===========================================================================
|
||||
|
||||
#Generate config.h.in
|
||||
autoheader
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
cd $srcdir
|
||||
|
||||
#Generate Makefile.in's
|
||||
automake -ac
|
||||
test -z "$AUTOMAKE" && AUTOMAKE=automake
|
||||
test -z "$ACLOCAL" && ACLOCAL=aclocal
|
||||
test -z "$AUTOCONF" && AUTOCONF=autoconf
|
||||
test -z "$AUTOHEADER" && AUTOHEADER=autoheader
|
||||
test -z "$LIBTOOLIZE" && LIBTOOLIZE=$(which libtoolize glibtoolize 2>/dev/null | head -1)
|
||||
test -z "$LIBTOOLIZE" && LIBTOOLIZE=libtoolize #paranoid precaution
|
||||
|
||||
if test "$1" == "verbose" || test "$1" == "--verbose" ; then
|
||||
set -x
|
||||
verbose='--verbose'
|
||||
verbose2='--debug'
|
||||
fi
|
||||
|
||||
# Get all required m4 macros required for configure
|
||||
$LIBTOOLIZE ${verbose} --copy --force || exit 1
|
||||
$ACLOCAL ${verbose} -I m4 || exit 1
|
||||
|
||||
# Generate config.h.in
|
||||
$AUTOHEADER ${verbose} --force || exit 1
|
||||
|
||||
# Generate Makefile.in's
|
||||
touch config.rpath
|
||||
$AUTOMAKE ${verbose} --add-missing --copy --force || exit 1
|
||||
|
||||
if grep "IT_PROG_INTLTOOL" configure.ac >/dev/null ; then
|
||||
intltoolize ${verbose2} -c --automake --force || exit 1
|
||||
# po/Makefile.in.in has these lines:
|
||||
# mostlyclean:
|
||||
# rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
|
||||
# prevent $(GETTEXT_PACKAGE).pot from being deleted by `make clean`
|
||||
sed 's/pox \$(GETTEXT_PACKAGE).pot/pox/' po/Makefile.in.in > po/Makefile.in.inx
|
||||
mv -f po/Makefile.in.inx po/Makefile.in.in
|
||||
fi
|
||||
|
||||
# generate configure
|
||||
$AUTOCONF ${verbose} --force || exit 1
|
||||
|
||||
rm -rf autom4te.cache
|
||||
|
|
69
configure.ac
69
configure.ac
|
@ -1,26 +1,21 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([gmrun], [0.9.5w])
|
||||
AC_INIT([gmrun], [1.1w])
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
AM_INIT_AUTOMAKE([-Wall foreign])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_MAINTAINER_MODE
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
m4_ifdef([AM_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
|
||||
LT_INIT
|
||||
|
||||
AC_ISC_POSIX
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_STDC
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_PROG_CXX
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug=[no/yes] Debugging information == no <--> optimization == yes],[],
|
||||
enable_debug=no)
|
||||
|
||||
if [ ! test "x$enable_debug" != "xyes"]; then
|
||||
CFLAGS="-g3 -O0 -DDEBUG"
|
||||
CXXFLAGS="-g3 -O0 -DDEBUG"
|
||||
if [ ! test "x$enable_debug" != xyes]; then
|
||||
CFLAGS="-g -DDEBUG"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(mtrace,
|
||||
|
@ -29,18 +24,60 @@ AC_ARG_ENABLE(mtrace,
|
|||
|
||||
if [ ! test "x$enable_mtrace" != "xyes"]; then
|
||||
CFLAGS="$CFLAGS -DMTRACE"
|
||||
CXXFLAGS="$CXXFLAGS -DMTRACE"
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.10)
|
||||
AC_SUBST(GTK_CFLAGS)
|
||||
AC_SUBST(GTK_LIBS)
|
||||
#========================================================================
|
||||
|
||||
PREFIX=${prefix}
|
||||
AC_SUBST(PREFIX)
|
||||
GTK3_CHECK="gtk+-3.0 >= 3.4.0"
|
||||
GTK2_CHECK="gtk+-2.0 >= 2.12.0"
|
||||
|
||||
AC_ARG_ENABLE(gtk3,
|
||||
AS_HELP_STRING([--disable-gtk3],[build with GTK3 (Autodetect)]),[],
|
||||
[enable_gtk3=check])
|
||||
|
||||
AC_ARG_ENABLE(gtk2,
|
||||
AS_HELP_STRING([--enable-gtk2],[build with GTK2 (Autodetect)]),[],
|
||||
[enable_gtk2=check])
|
||||
|
||||
AS_IF([test "x$enable_gtk3" = xyes],
|
||||
[enable_gtk2=no])
|
||||
AS_IF([test "x$enable_gtk2" = xyes],
|
||||
[enable_gtk3=no])
|
||||
|
||||
AS_IF([test "x$enable_gtk3" = xcheck],
|
||||
[PKG_CHECK_MODULES([GTK],[$GTK3_CHECK],
|
||||
[enable_gtk3=yes],[enable_gtk3=no])])
|
||||
|
||||
AS_IF([test "x$enable_gtk3" = xyes],
|
||||
[
|
||||
gtk_modules="$GTK3_CHECK"
|
||||
gtk_version="gtk+-3.0"
|
||||
errmsg="GTK3 is not installed, use --enable-gtk2 to build with GTK2"
|
||||
],
|
||||
[
|
||||
gtk_modules="$GTK2_CHECK"
|
||||
gtk_version="gtk+-2.0"
|
||||
errmsg="GTK2 is not installed, use --enable-gtk3 to build with GTK3"
|
||||
CPPFLAGS="$CPPFLAGS -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_DEPRECATED -DGTK_DISABLE_SINGLE_INCLUDES"
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([GTK], [$gtk_modules], [], [AC_ERROR([$errmsg])])
|
||||
AC_SUBST([GTK_CFLAGS])
|
||||
AC_SUBST([GTK_LIBS])
|
||||
|
||||
#========================================================================
|
||||
|
||||
case "$CC" in
|
||||
gcc*) CPPFLAGS="$CPPFLAGS -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers" ;;
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
data/Makefile
|
||||
src/Makefile
|
||||
])
|
||||
|
||||
echo
|
||||
echo "GTK Version: $(pkg-config --modversion $gtk_version)"
|
||||
echo
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
appdir = $(datadir)/applications
|
||||
app_DATA = gmrun.desktop
|
||||
|
||||
icondir = $(datadir)/pixmaps
|
||||
icon_DATA = gmrun.png
|
||||
|
||||
manualdir = $(mandir)/man1
|
||||
manual_DATA = gmrun.1
|
||||
|
||||
myrcdir = @sysconfdir@
|
||||
myrc_DATA = gmrunrc
|
||||
EXTRA_DIST = gmrunrc
|
|
@ -0,0 +1,72 @@
|
|||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH gmrun 1.1w "2021"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
gmrun \- Featureful CLI-like GTK+ application launcher
|
||||
.SH SYNOPSIS
|
||||
.B gmrun \fR\fI[TEXT]\fR
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||
.\" respectively.
|
||||
\fBgmrun\fP is a GTK program that allows a user to use a CLI-like interface to launch applications.
|
||||
.SH OPTIONS
|
||||
If gmrun is invoked with a command-line parameter, that will be the initial content of the dialog box.
|
||||
.PP
|
||||
gmrun can be customized using a configuration file, ~/.gmrunrc . The system-wide configuration file is /etc/gmrunrc .
|
||||
.PP
|
||||
The format of the configuration file is simple; "variable = value".
|
||||
.TP
|
||||
.B Example:
|
||||
variable1 = foobar
|
||||
.br
|
||||
.TP
|
||||
.B Terminal
|
||||
The command to run when Ctrl+Enter is pressed with no command entered; used to start a new terminal.
|
||||
.TP
|
||||
.B TermExec
|
||||
The command to run when Ctrl+Enter is pressed with a command entered. The entered command is supplied as an argument to TermExec.
|
||||
.TP
|
||||
.B Geometry
|
||||
see /etc/gmrunrc for more info
|
||||
.TP
|
||||
.B History
|
||||
Number of entered commands which should be kept in gmrun's history(~/.gmrun_history). Using the Up and Down arrow keys within the gmrun window will cycle through the history. You can search backwards through the history with Ctrl+R, and forward with Ctrl+S. Hit "!" to enter a special search that matches only the start of strings. To cancel a search, hit the \fIESC\fP key. Otherwise, after you have found the history item you wish to run, hit Enter. Also: CTRL-P = Up / CTRL-N = Down.
|
||||
.TP
|
||||
.B ShowLast
|
||||
Whether to show the last command as initial text, or an empty textarea (1 or 0).
|
||||
.TP
|
||||
.B Selected
|
||||
Whether the initial text should be selected or not (1 or 0).
|
||||
.SH URL/File HANDLING
|
||||
.TP
|
||||
.B USE_GLIB_XDG = 1
|
||||
For automatic URL and File handling using the freedesktop specification.
|
||||
.TP
|
||||
See /etc/gmrunrc for custom URL and extension handlers (USE_GLIB_XDG = 0)
|
||||
.TP
|
||||
The included configuration files have a few examples which you can work with. You should also note that the protocol part of URL_protocol can be *anything*. You can set up "URL_foobarbazcustom", and so long as you enter in "foobarbazcustom:<whatever>", it will use the given program.
|
||||
.SH SEE ALSO
|
||||
.BR /etc/gmrunrc.
|
||||
.br
|
||||
.SH AUTHOR
|
||||
Originally written by
|
||||
.B Mihai Bazon
|
||||
, the latest version is available from
|
||||
\fIhttps://github.com/wdlkmpx/gmrun/\fP
|
||||
.PP
|
||||
This manual page was originally written by David B Harris <david@eelf.ddts.net>
|
|
@ -0,0 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Name=gmrun
|
||||
Icon=gmrun.png
|
||||
Comment=execute a command
|
||||
Exec=gmrun
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=TerminalEmulator
|
||||
GenericName=gmrun
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,62 @@
|
|||
# gmrun configuration file
|
||||
|
||||
# Set terminal
|
||||
Terminal = xterm
|
||||
TermExec = ${Terminal} -e
|
||||
AlwaysInTerm = ssh telnet ftp lynx mc vi vim pine centericq perldoc man
|
||||
|
||||
# Set window geometry
|
||||
# - Wx width 400x
|
||||
# - WxH width x height 400x70 (height = 0 = ignore)
|
||||
# - WxH+x+y width x height +x +y 400x0+200+100
|
||||
#
|
||||
# If +x+y is not specified (or not allowed), the gmrun window is displayed centered
|
||||
Geometry = 450x
|
||||
|
||||
# History size
|
||||
History = 256
|
||||
|
||||
# Shows last history line selected when invoked
|
||||
ShowLast = 0
|
||||
|
||||
# Show files starting with '.'
|
||||
# Default is 0 (off), set it to 1 if you want "hidden" files to show up
|
||||
# in the completion window
|
||||
ShowDotFiles = 0
|
||||
|
||||
# Timeout (in milliseconds) after which gmrun will simulate a TAB press
|
||||
# Set this to NULL if don't like this feature.
|
||||
TabTimeout = 0
|
||||
|
||||
# Use libc's system(3) to run commands, this includes any shell command
|
||||
# and special stuff that only a shell interpreter can understand
|
||||
# Set to 0 if you want a more conservative approach where the file to run
|
||||
# is validated and errors running files are reported (without closing the gmrun window)
|
||||
SHELL_RUN = 1
|
||||
|
||||
|
||||
# use GLib XDG handling? (freedesktop specification)
|
||||
USE_GLIB_XDG = 0
|
||||
|
||||
#=======================================================================
|
||||
# USE_GLIB_XDG = 0, you can specify URL and extension Handlers...
|
||||
#=======================================================================
|
||||
|
||||
# URL handlers
|
||||
# If the entered text is "http://www.google.com" then:
|
||||
# - %u gets replaced with the whole URL ("http://www.google.com")
|
||||
# - %s gets replaced with "//www.google.com".
|
||||
# useful for URL's like "man:printf" --> %s becomes printf
|
||||
URL_http = xdg-open '%u'
|
||||
URL_mailto = xdg-email '%u'
|
||||
URL_file = xdg-open '%s'
|
||||
URL_man = ${TermExec} man %s
|
||||
URL_info = ${TermExec} info %s
|
||||
URL_search = xdg-open 'http://www.google.com/search?q=%s'
|
||||
|
||||
# extension handlers
|
||||
# Customize your own extension handler.
|
||||
# syntax-> EXT:ext,etc = handler '%s'
|
||||
EXT:doc,rtf,txt,cc,cpp,h,java,html,htm,epl,tex,latex,js,css,xml,xsl,am,ps,pdf = xdg-open '%s'
|
||||
EXT:mkv,mp4,avi,asf,wmv = xdg-open '%s'
|
||||
EXT:mp3,flac,ogg,aac,wav = xdg-open '%s'
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/sh
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
# For more information, please refer to <https://unlicense.org>
|
||||
|
||||
# ./data/zmtrace.sh
|
||||
|
||||
if ! test -f autogen.sh ; then
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! test -f configure ; then
|
||||
./autogen.sh;
|
||||
fi
|
||||
|
||||
export MALLOC_TRACE=$(pwd)/mtrace.txt
|
||||
|
||||
if ! test -f src/gmrun ; then
|
||||
./configure --prefix=/usr --enable-mtrace;
|
||||
make;
|
||||
fi
|
||||
|
||||
./src/gmrun;
|
||||
|
||||
mtrace=
|
||||
for i in $(echo $PATH | tr ':' ' ')
|
||||
do
|
||||
if test -x $i/mtrace ; then
|
||||
mtrace=$i/mtrace;
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if test "x${mtrace}" != "x" ; then
|
||||
mtrace src/gmrun mtrace.txt > mtrace-out.txt;
|
||||
printf "see mtrace-out.txt\n";
|
||||
else
|
||||
printf "mtrace is missing\n";
|
||||
printf "see mtrace.txt\n"
|
||||
fi
|
27
gmrun.glade
27
gmrun.glade
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<GTK-Interface>
|
||||
|
||||
<project>
|
||||
<name>Gmrun</name>
|
||||
<program_name>gmrun</program_name>
|
||||
<directory></directory>
|
||||
<source_directory>src</source_directory>
|
||||
<pixmaps_directory>pixmaps</pixmaps_directory>
|
||||
<language>C</language>
|
||||
<gnome_support>False</gnome_support>
|
||||
<gettext_support>False</gettext_support>
|
||||
<use_widget_names>False</use_widget_names>
|
||||
<output_main_file>False</output_main_file>
|
||||
<output_support_files>False</output_support_files>
|
||||
<output_build_files>True</output_build_files>
|
||||
<backup_source_files>False</backup_source_files>
|
||||
<main_source_file>interface.c</main_source_file>
|
||||
<main_header_file>interface.h</main_header_file>
|
||||
<handler_source_file>callbacks.c</handler_source_file>
|
||||
<handler_header_file>callbacks.h</handler_header_file>
|
||||
<support_source_file>support.c</support_source_file>
|
||||
<support_header_file>support.h</support_header_file>
|
||||
<translatable_strings_file></translatable_strings_file>
|
||||
</project>
|
||||
|
||||
</GTK-Interface>
|
54
gmrunrc
54
gmrunrc
|
@ -1,54 +0,0 @@
|
|||
# gmrun configuration file
|
||||
# gmrun is (C) Mihai Bazon, <mishoo@infoiasi.ro>
|
||||
# GPL v2.0 applies
|
||||
|
||||
# Set terminal
|
||||
Terminal = gnome-terminal --start-factory-server --use-factory
|
||||
TermExec = ${Terminal} -e
|
||||
AlwaysInTerm = ssh telnet ftp lynx mc vi vim pine centericq perldoc man
|
||||
|
||||
# Set window geometry (except height)
|
||||
Width = 400
|
||||
Top = 100
|
||||
Left = 200
|
||||
# Place window centered by the size of screen
|
||||
CenteredByWidth = 0
|
||||
CenteredByHeight = 0
|
||||
# Place window on active monitor
|
||||
UseActiveMonitor = 0
|
||||
|
||||
# History size
|
||||
History = 256
|
||||
|
||||
# Shows last history line selected when invoked
|
||||
ShowLast = 0
|
||||
|
||||
# Show files starting with '.'
|
||||
# Default is 0 (off), set it to 1 if you want "hidden" files to show up
|
||||
# in the completion window
|
||||
ShowDotFiles = 0
|
||||
|
||||
# Timeout (in milliseconds) after which gmrun will simulate a TAB press
|
||||
# Set this to NULL if don't like this feature.
|
||||
TabTimeout = 0
|
||||
|
||||
# URL handlers
|
||||
# If the entered text is "http://www.google.com" then:
|
||||
# - %u gets replaced with the whole URL ("http://www.google.com")
|
||||
# - %s gets replaced with "//www.google.com". This is useful for URL-s
|
||||
# like "man:printf" --> %s will get replaced with "printf"
|
||||
URL_http = mozilla -remote "openURL(%u, new-window)"
|
||||
URL_mailto = mozilla -remote "mailto(%s)"
|
||||
URL_man = ${TermExec} 'man %s'
|
||||
URL_info = ${TermExec} 'info %s'
|
||||
URL_pd = ${TermExec} 'perldoc %s'
|
||||
URL_file = nautilus %s
|
||||
URL_readme = ${TermExec} 'less /usr/doc/%s/README'
|
||||
URL_info = ${TermExec} 'info %s'
|
||||
URL_sh = sh -c '%s'
|
||||
|
||||
# extension handlers
|
||||
EXT:doc,rtf = AbiWord %s
|
||||
EXT:txt,cc,cpp,h,java,html,htm,epl,tex,latex,js,css,xml,xsl,am = emacs %s
|
||||
EXT:ps = gv %s
|
||||
EXT:pdf = xpdf %s
|
|
@ -4,11 +4,10 @@ AM_CPPFLAGS = @GTK_CFLAGS@
|
|||
|
||||
bin_PROGRAMS = gmrun
|
||||
|
||||
gmrun_SOURCES = \
|
||||
gtkcompletionline.cc gtkcompletionline.h \
|
||||
history.cc history.h \
|
||||
main.cc main.h \
|
||||
prefs.cc prefs.h ci_string.h
|
||||
gmrun_SOURCES = config_prefs.c \
|
||||
history.c \
|
||||
gtkcompletionline.c \
|
||||
main.c
|
||||
|
||||
# gmrun_LDFLAGS = -s
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
PROGRAM = gmrun
|
||||
OBJS = config_prefs.o gtkcompletionline.o history.o main.o
|
||||
BIN_PATH = /usr/local/bin
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = `pkg-config gtk+-2.0 --cflags` -Wall -O2
|
||||
LIBS = `pkg-config gtk+-2.0 --libs`
|
||||
|
||||
all: $(OBJS)
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $(PROGRAM) $(LIBS)
|
||||
|
||||
strip:
|
||||
strip $(PROGRAM)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ $(PROGRAM)
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)$(BIN_PATH)
|
||||
install $(PROGRAM) $(DESTDIR)$(BIN_PATH)
|
||||
|
||||
uninstall:
|
||||
rm -i $(DESTDIR)$(BIN_PATH)/$(PROGRAM)
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// $Id: ci_string.h,v 1.2 2001/05/16 14:39:31 mishoo Exp $
|
||||
|
||||
// This is a very nice class, probably because it's not coded by me ;=]~
|
||||
// Provide a case-insensitive std::string-like class.
|
||||
|
||||
#ifndef __CI_STRING_H__
|
||||
#define __CI_STRING_H__
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
struct ci_char_traits : public std::char_traits<char>
|
||||
{
|
||||
static bool eq( char c1, char c2 ) {
|
||||
return ::tolower(c1) == ::tolower(c2);
|
||||
}
|
||||
|
||||
static bool ne( char c1, char c2 ) {
|
||||
return ::tolower(c1) != ::tolower(c2);
|
||||
}
|
||||
|
||||
static bool lt( char c1, char c2 ) {
|
||||
return ::tolower(c1) < ::tolower(c2);
|
||||
}
|
||||
|
||||
static int compare( const char* s1,
|
||||
const char* s2,
|
||||
size_t n ) {
|
||||
return strncasecmp( s1, s2, n );
|
||||
}
|
||||
|
||||
static const char*
|
||||
find( const char* s, int n, char a ) {
|
||||
while ( n-- > 0 && ::tolower(*s) != ::tolower(a) ) ++s;
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::basic_string<char, ci_char_traits> ci_string;
|
||||
|
||||
#endif // __CI_STRING_H__
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* For more information, please refer to <https://unlicense.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Read config file formatted like this:
|
||||
*
|
||||
* key1 = value1
|
||||
* key2=value2
|
||||
*
|
||||
* It's possible to open several files with the same config
|
||||
* The keys will be updated with thew new values.
|
||||
* 'key' is not case sensitive
|
||||
*/
|
||||
|
||||
#include "config_prefs.h"
|
||||
|
||||
#define APP_CONFIG_FILE "gmrunrc"
|
||||
|
||||
// ============================================================
|
||||
// PRIVATE
|
||||
// ============================================================
|
||||
|
||||
static GList * PrefsGList = NULL;
|
||||
static GList * ExtensionGList = NULL;
|
||||
|
||||
struct _pref_item
|
||||
{
|
||||
char * key;
|
||||
char * value;
|
||||
};
|
||||
typedef struct _pref_item pref_item;
|
||||
|
||||
|
||||
static void pref_item_free (pref_item * item)
|
||||
{
|
||||
if (item) {
|
||||
if (item->key) free (item->key);
|
||||
if (item->value) free (item->value);
|
||||
free (item);
|
||||
}
|
||||
}
|
||||
|
||||
static void pref_item_free_cb (gpointer data)
|
||||
{
|
||||
pref_item_free ((pref_item *) data);
|
||||
}
|
||||
|
||||
|
||||
static GList * config_find_key (GList * list, const char * key)
|
||||
{
|
||||
GList *i;
|
||||
pref_item * item;
|
||||
|
||||
if (!key || !*key) { /* ignore empty keys (strings) */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (i = list; i; i = i->next)
|
||||
{
|
||||
item = (pref_item *) (i->data);
|
||||
if (strcasecmp (key, item->key) == 0) {
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
return (NULL); /* key not found */
|
||||
}
|
||||
|
||||
|
||||
static void config_replace_key (GList ** list, pref_item * item)
|
||||
{
|
||||
GList * found = config_find_key (*list, item->key);
|
||||
if (found) {
|
||||
/* only update found item */
|
||||
pref_item * found_item = (pref_item *) (found->data);
|
||||
if (strcmp (found_item->value, item->value) == 0) {
|
||||
pref_item_free (item);
|
||||
return; /* values are equal, nothing to update */
|
||||
}
|
||||
free (found_item->value);
|
||||
found_item->value = strdup (item->value);
|
||||
pref_item_free (item);
|
||||
} else {
|
||||
/* append item */
|
||||
*list = g_list_append (*list, (gpointer) item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** get value, it's always a string **/
|
||||
static char * config_get_item_value (GList * list, const char * key)
|
||||
{
|
||||
GList * ret;
|
||||
pref_item * item;
|
||||
|
||||
ret = config_find_key (list, key);
|
||||
if (ret) {
|
||||
item = (pref_item *) (ret->data);
|
||||
return (item->value);
|
||||
}
|
||||
return (NULL); /* key not found */
|
||||
}
|
||||
|
||||
|
||||
static void config_load_from_file (const char * filename, GList ** out_list)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024];
|
||||
|
||||
char * stripped;
|
||||
char ** keyvalue;
|
||||
pref_item * item;
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (!fp) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read file line by line */
|
||||
while (fgets (buf, sizeof (buf), fp))
|
||||
{
|
||||
stripped = buf;
|
||||
while (*stripped && *stripped <= 0x20) { // 32 = space
|
||||
stripped++;
|
||||
}
|
||||
if (strlen (stripped) < 3 || *stripped == '#') {
|
||||
continue;
|
||||
}
|
||||
if (!strchr (stripped, '=')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item = (pref_item *) calloc (1, sizeof (pref_item));
|
||||
keyvalue = g_strsplit (stripped, "=", 2);
|
||||
item->key = g_strstrip (keyvalue[0]);
|
||||
item->value = g_strstrip (keyvalue[1]);
|
||||
|
||||
if (!*item->key || !*item->value) {
|
||||
g_strfreev (keyvalue);
|
||||
free (item);
|
||||
continue;
|
||||
}
|
||||
|
||||
/// fprintf (stderr, "### %s = %s\n", key, value);
|
||||
/* Insert or replace item */
|
||||
config_replace_key (out_list, item);
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void create_extension_handler_list (void)
|
||||
{
|
||||
GList * i;
|
||||
pref_item * item, * item_out;
|
||||
char ** str_vector;
|
||||
|
||||
for (i = PrefsGList; i; i = i->next)
|
||||
{
|
||||
item = (pref_item *) (i->data);
|
||||
if (strncasecmp (item->key, "EXT:", 4) == 0)
|
||||
{
|
||||
int w;
|
||||
str_vector = g_strsplit (item->key + 4, ",", 0);
|
||||
for (w = 0; str_vector[w]; w++)
|
||||
{
|
||||
item_out = (pref_item *) calloc (1, sizeof (pref_item));
|
||||
item_out->key = strdup (str_vector[w]);
|
||||
item_out->value = strdup (item->value);
|
||||
config_replace_key (&ExtensionGList, item_out);
|
||||
}
|
||||
g_strfreev (str_vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char * replace_variable (char * txt) /* config_get_string_expanded() */
|
||||
{
|
||||
// pre${variable}post : ${Terminal} -e ...
|
||||
char * pre = NULL, * post = NULL;
|
||||
char * variable = NULL;
|
||||
char * variable_value = NULL;
|
||||
char * new_text = NULL;
|
||||
char * p, * p2;
|
||||
|
||||
if (strlen (txt) < 5) { // at least ${xx}
|
||||
return (NULL);
|
||||
}
|
||||
p = strstr (txt, "${");
|
||||
if (!p) {
|
||||
return (NULL); // syntax error
|
||||
}
|
||||
if (!strchr (p + 3, '}')) {
|
||||
return (NULL); // syntax error
|
||||
}
|
||||
|
||||
if (txt[0] != '$' && txt[1] != '$') {
|
||||
pre = strdup (txt);
|
||||
p2 = strchr (pre, '$');
|
||||
if (p2) p2 = 0;
|
||||
}
|
||||
|
||||
variable = strdup (p + 2); // variable start
|
||||
p2 = strchr (variable, '}'); // variable end
|
||||
*p2 = 0; // `Terminal`
|
||||
post = p2 + 1; // ` -e ...`
|
||||
|
||||
variable_value = config_get_item_value (PrefsGList, variable); // xterm
|
||||
|
||||
if (variable_value) {
|
||||
if (pre) {
|
||||
// pre xterm -e ...
|
||||
new_text = g_strconcat (pre, variable_value, post, NULL);
|
||||
} else {
|
||||
// xterm -e ...
|
||||
new_text = g_strconcat (variable_value, post, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (pre) free (pre);
|
||||
if (variable) free (variable);
|
||||
|
||||
return (new_text);
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// PUBLIC
|
||||
// ============================================================
|
||||
|
||||
void config_init ()
|
||||
{
|
||||
if (PrefsGList) {
|
||||
return;
|
||||
}
|
||||
char config_file[512];
|
||||
char * HOME;
|
||||
|
||||
snprintf (config_file, sizeof (config_file), "/etc/%s", APP_CONFIG_FILE);
|
||||
config_load_from_file (config_file, &PrefsGList);
|
||||
|
||||
HOME = getenv ("HOME");
|
||||
if (HOME) {
|
||||
snprintf (config_file, sizeof (config_file), "%s/.%s", HOME, APP_CONFIG_FILE);
|
||||
config_load_from_file (config_file, &PrefsGList);
|
||||
}
|
||||
|
||||
create_extension_handler_list ();
|
||||
}
|
||||
|
||||
|
||||
void config_destroy ()
|
||||
{
|
||||
if (PrefsGList) {
|
||||
g_list_free_full (PrefsGList, pref_item_free_cb);
|
||||
g_list_free_full (ExtensionGList, pref_item_free_cb);
|
||||
PrefsGList = NULL;
|
||||
ExtensionGList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void config_reload ()
|
||||
{
|
||||
config_destroy ();
|
||||
config_init ();
|
||||
}
|
||||
|
||||
|
||||
void config_print ()
|
||||
{
|
||||
GList * i;
|
||||
pref_item * item;
|
||||
for (i = PrefsGList; i; i = i->next)
|
||||
{
|
||||
item = (pref_item *) (i->data);
|
||||
printf ("%s = %s\n", item->key, item->value);
|
||||
}
|
||||
for (i = ExtensionGList; i; i = i->next)
|
||||
{
|
||||
item = (pref_item *) (i->data);
|
||||
printf ("%s = %s\n", item->key, item->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean config_get_int (const char * key, int * out_int)
|
||||
{
|
||||
char * value;
|
||||
value = config_get_item_value (PrefsGList, key);
|
||||
if (value) {
|
||||
*out_int = (int) strtoll (value, NULL, 0);
|
||||
return TRUE;
|
||||
} else {
|
||||
*out_int = -1;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// returns a string that must be freed with g_free
|
||||
gboolean config_get_string_expanded (const char * key, char ** out_str)
|
||||
{
|
||||
char * value1, * value2, * value = NULL;
|
||||
|
||||
value1 = config_get_item_value (PrefsGList, key);
|
||||
if (value1 && strstr (value1, "${")) {
|
||||
value2 = replace_variable (value1);
|
||||
value = value2;
|
||||
// expand variable up to 2 times
|
||||
if (value2 && strstr (value2, "${")) {
|
||||
value = replace_variable (value2);
|
||||
free (value2);
|
||||
}
|
||||
} else {
|
||||
value = strdup (value1);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
*out_str = value;
|
||||
return TRUE;
|
||||
} else {
|
||||
*out_str = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean config_get_string (const char * key, char ** out_str)
|
||||
{
|
||||
char * value;
|
||||
value = config_get_item_value (PrefsGList, key);
|
||||
if (value) {
|
||||
*out_str = value;
|
||||
return TRUE;
|
||||
} else {
|
||||
*out_str = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char * config_get_handler_for_extension (const char * extension)
|
||||
{
|
||||
char * handler;
|
||||
if (extension && *extension == '.') {
|
||||
extension++; // .html -> html
|
||||
}
|
||||
handler = config_get_item_value (ExtensionGList, extension);
|
||||
return (handler);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* For more information, please refer to <https://unlicense.org>
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_PREFS_H
|
||||
#define __CONFIG_PREFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "gtkcompat.h" // glib-compat.h
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void config_init ();
|
||||
void config_destroy ();
|
||||
void config_reload ();
|
||||
void config_print ();
|
||||
|
||||
gboolean config_get_int (const char * key, int * out_int);
|
||||
|
||||
/// changes string pointer (must not be freed)
|
||||
gboolean config_get_string (const char * key, char ** out_str);
|
||||
|
||||
/// allocates a string that must be freed with g_free
|
||||
gboolean config_get_string_expanded (const char * key, char ** out_str);
|
||||
|
||||
/// returns a constant string (must not be freed)
|
||||
char * config_get_handler_for_extension (const char * extension);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* For more information, please refer to <https://unlicense.org>
|
||||
*/
|
||||
|
||||
/** 2020-12-29 **/
|
||||
|
||||
/*
|
||||
* gtkcompat.h, GTK2+ compatibility layer
|
||||
*
|
||||
* This lib makes it easier to support older GTK versions
|
||||
* while still avoiding deprecated functions as much as possible.
|
||||
*
|
||||
* The older the GTK version, the more compatible functions are "defined"
|
||||
* so it's not wise to use the compiled binary in newer distros or something.
|
||||
*
|
||||
* Apps should support gtk2 >= 2.14 / gtk3 >= 3.14
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
special defines:
|
||||
gtkcompat_widget_set_halign_left (w)
|
||||
gtkcompat_widget_set_halign_center (w)
|
||||
gtkcompat_widget_set_halign_right (w)
|
||||
*/
|
||||
|
||||
/*
|
||||
GTKCOMPAT_DRAW_SIGNAL (gtk3="draw", gtk2="expose_event")
|
||||
---------------------
|
||||
g_signal_connect (w, GTKCOMPAT_DRAW_SIGNAL, G_CALLBACK (w_draw_cb), NULL);
|
||||
gboolean w_draw_cb (GtkWidget *w, gpointer compat, gpointer user_data)
|
||||
{
|
||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||
cairo_t * cr = (cairo_t *) compat;
|
||||
#else // gtk2
|
||||
//GdkEventExpose * event = (GdkEventExpose *) compat;
|
||||
cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (w));
|
||||
#endif
|
||||
#if GTK_MAJOR_VERSION == 2
|
||||
cairo_destroy (cr);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
#ifndef __GTKCOMPAT_H
|
||||
#define __GTKCOMPAT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#if GTK_MAJOR_VERSION == 3
|
||||
#include <gdk/gdkkeysyms-compat.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* ================================================== */
|
||||
/* GLIB */
|
||||
/* ================================================== */
|
||||
|
||||
#ifndef __GLIB_COMPAT_H
|
||||
#define __GLIB_COMPAT_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
// GLIB < 2.58
|
||||
#if ! GLIB_CHECK_VERSION (2, 58, 0)
|
||||
#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f))
|
||||
#endif
|
||||
|
||||
|
||||
// GLIB < 2.32
|
||||
#if ! GLIB_CHECK_VERSION (2, 32, 0)
|
||||
#define G_SOURCE_REMOVE FALSE
|
||||
#define G_SOURCE_CONTINUE TRUE
|
||||
#define GRecMutex GStaticRecMutex
|
||||
#define g_rec_mutex_init(x) g_static_rec_mutex_init(x)
|
||||
#define g_rec_mutex_lock(x) g_static_rec_mutex_lock(x)
|
||||
#define g_rec_mutex_trylock(x) g_static_rec_mutex_trylock(x)
|
||||
#define g_rec_mutex_unlock(x) g_static_rec_mutex_unlock(x)
|
||||
#define g_rec_mutex_clear(x) g_static_rec_mutex_free(x)
|
||||
#define g_thread_new(name,func,data) g_thread_create(func,data,TRUE,NULL)
|
||||
#define g_thread_try_new(name,func,data,error) g_thread_create(func,data,TRUE,error)
|
||||
#define g_hash_table_add(ht,key) g_hash_table_replace(ht,key,key)
|
||||
#define g_hash_table_contains(ht,key) g_hash_table_lookup_extended(ht,key,NULL,NULL)
|
||||
#endif
|
||||
|
||||
|
||||
// GMutex vs GStaticMutex
|
||||
#if GLIB_CHECK_VERSION (2, 32, 0)
|
||||
// since version 2.32.0 GMutex can be statically allocated
|
||||
// don't use WGMutex to replace GMutex * ... issues, errors.
|
||||
# define WGMutex GMutex
|
||||
# define Wg_mutex_init g_mutex_init
|
||||
# define Wg_mutex_lock g_mutex_lock
|
||||
# define Wg_mutex_trylock g_mutex_trylock
|
||||
# define Wg_mutex_unlock g_mutex_unlock
|
||||
# define Wg_mutex_clear g_mutex_clear
|
||||
#else
|
||||
# define WGMutex GStaticMutex
|
||||
# define Wg_mutex_init g_static_mutex_init
|
||||
# define Wg_mutex_lock g_static_mutex_lock
|
||||
# define Wg_mutex_trylock g_static_mutex_trylock
|
||||
# define Wg_mutex_unlock g_static_mutex_unlock
|
||||
# define Wg_mutex_clear g_static_mutex_free
|
||||
// sed -i 's%g_mutex_%Wg_mutex_%g' $(grep "g_mutex_" *.c *.h | cut -f 1 -d ":" | grep -v -E 'gtkcompat|glib-compat' | sort -u)
|
||||
#endif
|
||||
|
||||
|
||||
// GLIB < 2.30
|
||||
#if ! GLIB_CHECK_VERSION (2, 30, 0)
|
||||
#define g_format_size g_format_size_for_display
|
||||
#endif
|
||||
|
||||
|
||||
// GLIB < 2.28
|
||||
#if ! GLIB_CHECK_VERSION (2, 28, 0)
|
||||
#define g_list_free_full(list,free_func) {\
|
||||
g_list_foreach (list, (GFunc) free_func, NULL);\
|
||||
g_list_free (list);\
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// GLIB < 2.22
|
||||
#if ! GLIB_CHECK_VERSION (2, 22, 0)
|
||||
#define g_mapped_file_unref(x) g_mapped_file_free(x)
|
||||
#endif
|
||||
|
||||
// GLIB < 2.20
|
||||
#if ! GLIB_CHECK_VERSION (2, 20, 0)
|
||||
#define g_app_info_get_commandline(app) g_app_info_get_executable(app)
|
||||
#endif
|
||||
|
||||
/* glib 2.18+ tested */
|
||||
|
||||
#endif /* __GLIB_COMPAT_H */
|
||||
|
||||
|
||||
|
||||
|
||||
/* ================================================== */
|
||||
/* GTK 3 */
|
||||
/* ================================================== */
|
||||
|
||||
|
||||
// GTK >= 3.0 -- applies to GTK3, GTK4...
|
||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||
#define GTKCOMPAT_DRAW_SIGNAL "draw"
|
||||
#define gtkcompat_widget_set_halign_left(w) gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_START)
|
||||
#define gtkcompat_widget_set_halign_center(w) gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_CENTER)
|
||||
#define gtkcompat_widget_set_halign_right(w) gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_END)
|
||||
/* some compatible deprecated GTK2 functions... */
|
||||
#define gtk_hbox_new(homogenous,spacing) gtk_box_new(GTK_ORIENTATION_HORIZONTAL,spacing)
|
||||
#define gtk_vbox_new(homogenous,spacing) gtk_box_new(GTK_ORIENTATION_VERTICAL,spacing)
|
||||
#define gtk_hscale_new(adjustment) gtk_scale_new(GTK_ORIENTATION_HORIZONTAL,adjustment)
|
||||
#define gtk_vscale_new(adjustment) gtk_scale_new(GTK_ORIENTATION_VERTICAL,adjustment)
|
||||
#define gtk_hscale_new_with_range(min,max,step) gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,min,max,step)
|
||||
#define gtk_vscale_new_with_range(min,max,step) gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL,min,max,step)
|
||||
#define gtk_hseparator_new() gtk_separator_new(GTK_ORIENTATION_HORIZONTAL)
|
||||
#define gtk_vseparator_new() gtk_separator_new(GTK_ORIENTATION_VERTICAL)
|
||||
#define gtk_hscrollbar_new(adj) gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL,adj)
|
||||
#define gtk_vscrollbar_new(adj) gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL,adj)
|
||||
#define gtk_hpaned_new() gtk_paned_new(GTK_ORIENTATION_HORIZONTAL)
|
||||
#define gtk_vpaned_new() gtk_paned_new(GTK_ORIENTATION_VERTICAL)
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 3.12
|
||||
#if ! GTK_CHECK_VERSION (3, 12, 0)
|
||||
#define gtk_widget_set_margin_start(widget,margin) gtk_widget_set_margin_left(widget,margin)
|
||||
#define gtk_widget_set_margin_end(widget,margin) gtk_widget_set_margin_right(widget,margin)
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 3.4
|
||||
#if ! GTK_CHECK_VERSION (3, 4, 0)
|
||||
#define gtk_application_window_new(app) gtk_window_new(GTK_WINDOW_TOPLEVEL)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* ================================================== */
|
||||
/* GTK 2 */
|
||||
/* ================================================== */
|
||||
|
||||
// define some GTK3+ functions
|
||||
#if GTK_MAJOR_VERSION <= 2
|
||||
#define GTKCOMPAT_DRAW_SIGNAL "expose_event"
|
||||
#define gtk_box_new(ori,spacing) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hbox_new(FALSE,spacing) \
|
||||
: gtk_vbox_new(FALSE,spacing))
|
||||
#define gtk_button_box_new(ori) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hbutton_box_new() \
|
||||
: gtk_vbutton_box_new())
|
||||
#define gtk_scale_new(ori,adjustment) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hscale_new(adjustment) \
|
||||
: gtk_vscale_new(adjustment))
|
||||
#define gtk_scale_new_with_range(ori,min,max,step) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hscale_new_with_range(min,max,step) \
|
||||
: gtk_vscale_new_with_range(min,max,step))
|
||||
#define gtk_separator_new(ori) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hseparator_new() \
|
||||
: gtk_vseparator_new())
|
||||
#define gtk_scrollbar_new(ori,adjustment) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hscrollbar_new(adjustment) \
|
||||
: gtk_vscrollbar_new(adjustment))
|
||||
#define gtk_paned_new(ori) \
|
||||
((ori == GTK_ORIENTATION_HORIZONTAL) ? gtk_hpaned_new() \
|
||||
: gtk_vpaned_new())
|
||||
#define gtk_widget_get_allocated_height(widget) (GTK_WIDGET(widget)->allocation.height )
|
||||
#define gtk_widget_get_allocated_width(widget) (GTK_WIDGET(widget)->allocation.width )
|
||||
#define gtk_combo_box_text_remove_all(cmb) { \
|
||||
GtkTreeModel * model = gtk_combo_box_get_model (GTK_COMBO_BOX (cmb)); \
|
||||
gtk_list_store_clear (GTK_LIST_STORE (model)); \
|
||||
}
|
||||
#define gtk_tree_model_iter_previous(model,iter) ({ \
|
||||
GtkTreePath * path = gtk_tree_model_get_path (model, iter); \
|
||||
gboolean valid = gtk_tree_path_prev (path); \
|
||||
if (valid) gtk_tree_model_get_iter (model, iter, path); \
|
||||
gtk_tree_path_free (path); \
|
||||
valid; \
|
||||
})
|
||||
#define gtk_widget_override_font(w,f) gtk_widget_modify_font(w,f)
|
||||
#define gtkcompat_widget_set_halign_left(w) gtk_misc_set_alignment(GTK_MISC(w), 0.0, 0.5)
|
||||
#define gtkcompat_widget_set_halign_center(w) gtk_misc_set_alignment(GTK_MISC(w), 0.5, 0.5)
|
||||
#define gtkcompat_widget_set_halign_right(w) gtk_misc_set_alignment(GTK_MISC(w), 1.0, 0.5)
|
||||
/* GtkApplication */
|
||||
#define GtkApplication void
|
||||
#define g_application_quit(app) gtk_main_quit()
|
||||
#undef G_APPLICATION
|
||||
#define G_APPLICATION(app) ((void *) (app))
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 2.24
|
||||
#if ! GTK_CHECK_VERSION (2, 24, 0)
|
||||
typedef struct _GtkComboBox GtkComboBoxText;
|
||||
typedef struct _GtkComboBoxClass GtkComboBoxTextClass;
|
||||
typedef struct _GtkComboBoxPrivate GtkComboBoxTextPrivate;
|
||||
#define GTK_TYPE_COMBO_BOX_TEXT (gtk_combo_box_get_type ())
|
||||
#define GTK_COMBO_BOX_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_COMBO_BOX, GtkComboBoxText))
|
||||
#define GTK_COMBO_BOX_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_COMBO_BOX, GtkComboBoxTextClass))
|
||||
#define GTK_IS_COMBO_BOX_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_COMBO_BOX))
|
||||
#define GTK_IS_COMBO_BOX_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_COMBO_BOX))
|
||||
#define GTK_COMBO_BOX_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_COMBO_BOX, GtkComboBoxTextClass))
|
||||
#define gtk_combo_box_text_new() gtk_combo_box_new_text()
|
||||
#define gtk_combo_box_text_new_with_entry() gtk_combo_box_entry_new_text()
|
||||
#define gtk_combo_box_text_append_text(combo,text) gtk_combo_box_append_text(combo,text)
|
||||
#define gtk_combo_box_text_insert_text(combo,pos,text) gtk_combo_box_insert_text(combo,pos,text)
|
||||
#define gtk_combo_box_text_prepend_text(combo,text) gtk_combo_box_prepend_text(combo,text)
|
||||
#define gtk_combo_box_text_remove(combo,pos) gtk_combo_box_remove_text(combo,pos)
|
||||
#define gtk_combo_box_text_get_active_text(combo) (gtk_combo_box_get_active_text(combo))
|
||||
#define gtk_combo_box_get_has_entry(combo) (0)
|
||||
#define gtk_combo_box_set_entry_text_column(combo,cl)
|
||||
#define gtk_combo_box_get_entry_text_column(combo) (0)
|
||||
#define gtk_range_get_round_digits(range) (GTK_RANGE(range)->round_digits)
|
||||
//#define gdk_window_get_visual(w) (gdk_drawable_get_visual(GDK_DRAWABLE(w)))
|
||||
#define gdk_window_get_screen(w) (gdk_drawable_get_screen(GDK_DRAWABLE(w)))
|
||||
#define gdk_window_get_display(w) (gdk_drawable_get_display(GDK_DRAWABLE(w)))
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 2.22
|
||||
#if ! GTK_CHECK_VERSION (2, 22, 0)
|
||||
#define gtk_window_has_group(w) (GTK_WINDOW(w)->group != NULL)
|
||||
#define gtk_window_group_get_current_grab(wg) \
|
||||
((GTK_WINDOW_GROUP(wg)->grabs) ? GTK_WIDGET(GTK_WINDOW_GROUP(wg)->grabs->data) : NULL)
|
||||
#define gtk_font_selection_dialog_get_font_selection(fsd)(GTK_FONT_SELECTION_DIALOG(fsd)->fontsel)
|
||||
#define gtk_notebook_get_tab_hborder(n) (GTK_NOTEBOOK(n)->tab_hborder)
|
||||
#define gtk_notebook_get_tab_vborder(n) (GTK_NOTEBOOK(n)->tab_vborder)
|
||||
#define gtk_button_get_event_window(button) (GTK_BUTTON(button)->event_window)
|
||||
#define gdk_visual_get_visual_type(visual) (GDK_VISUAL(visual)->type)
|
||||
#define gdk_visual_get_depth(visual) (GDK_VISUAL(visual)->depth)
|
||||
#define gdk_visual_get_byte_order(visual) (GDK_VISUAL(visual)->byte_order)
|
||||
#define gdk_visual_get_colormap_size(visual) (GDK_VISUAL(visual)->colormap_size)
|
||||
#define gdk_visual_get_bits_per_rgb(visual) (GDK_VISUAL(visual)->bits_per_rgb)
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 2.20
|
||||
#if ! GTK_CHECK_VERSION (2, 20, 0)
|
||||
#define gtk_widget_get_mapped(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_MAPPED) != 0)
|
||||
#define gtk_widget_get_realized(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_REALIZED) != 0)
|
||||
#define gtk_window_get_window_type(window) (GTK_WINDOW(window)->type)
|
||||
#define gtk_widget_get_requisition(w,r) (*(r) = GTK_WIDGET(w)->requisition)
|
||||
#define gtk_widget_set_mapped(w,yes) { \
|
||||
if (yes) GTK_WIDGET_SET_FLAGS(w,GTK_MAPPED); \
|
||||
else GTK_WIDGET_UNSET_FLAGS(w,GTK_MAPPED); \
|
||||
}
|
||||
#define gtk_widget_set_realized(w,yes) { \
|
||||
if (yes) GTK_WIDGET_SET_FLAGS(w,GTK_REALIZED); \
|
||||
else GTK_WIDGET_UNSET_FLAGS(w,GTK_REALIZED); \
|
||||
}
|
||||
#define gtk_range_get_slider_size_fixed(range) (GTK_RANGE(range)->slider_size_fixed)
|
||||
#define gtk_range_get_min_slider_size(range) (GTK_RANGE(range)->min_slider_size)
|
||||
#define gtk_entry_get_text_window(entry) (GTK_ENTRY(entry)->text_area)
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 2.18
|
||||
#if ! GTK_CHECK_VERSION (2, 18, 0)
|
||||
#define gtk_widget_get_state(wid) (GTK_WIDGET (wid)->state)
|
||||
#define gtk_widget_is_toplevel(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_TOPLEVEL) != 0)
|
||||
#define gtk_widget_get_has_window(wid) !((GTK_WIDGET_FLAGS (wid) & GTK_NO_WINDOW) != 0)
|
||||
#define gtk_widget_get_visible(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_VISIBLE) != 0)
|
||||
#define gtk_widget_is_drawable(wid) (GTK_WIDGET_VISIBLE (wid) && GTK_WIDGET_MAPPED (wid))
|
||||
#define gtk_widget_get_sensitive(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_SENSITIVE) != 0)
|
||||
#define gtk_widget_get_can_focus(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_CAN_FOCUS) != 0)
|
||||
#define gtk_widget_has_focus(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_HAS_FOCUS) != 0)
|
||||
#define gtk_widget_get_can_default(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_CAN_DEFAULT) != 0)
|
||||
#define gtk_widget_get_receives_default(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_RECEIVES_DEFAULT) != 0)
|
||||
#define gtk_widget_has_default(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_HAS_DEFAULT) != 0)
|
||||
#define gtk_widget_has_grab(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_HAS_GRAB) != 0)
|
||||
#define gtk_widget_get_app_paintable(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_APP_PAINTABLE) != 0)
|
||||
#define gtk_widget_get_double_buffered(wid) ((GTK_WIDGET_FLAGS (wid) & GTK_DOUBLE_BUFFERED) != 0)
|
||||
#define gtk_widget_set_allocation(w,alloc) (GTK_WIDGET(w)->allocation = *(alloc))
|
||||
#define gtk_widget_get_allocation(w,alloc) (*(alloc) = GTK_WIDGET(w)->allocation)
|
||||
#define gtk_widget_set_can_default(w,yes) { \
|
||||
if (yes) GTK_WIDGET_SET_FLAGS(w,GTK_CAN_DEFAULT); \
|
||||
else GTK_WIDGET_UNSET_FLAGS(w,GTK_CAN_DEFAULT); \
|
||||
}
|
||||
#define gtk_widget_set_can_focus(w,yes) { \
|
||||
if (yes) GTK_WIDGET_SET_FLAGS(w,GTK_CAN_FOCUS); \
|
||||
else GTK_WIDGET_UNSET_FLAGS(w,GTK_CAN_FOCUS); \
|
||||
}
|
||||
#define gtk_widget_set_has_window(w,yes) { \
|
||||
if (yes) GTK_WIDGET_UNSET_FLAGS(w,GTK_NO_WINDOW); \
|
||||
else GTK_WIDGET_SET_FLAGS(w,GTK_NO_WINDOW); \
|
||||
}
|
||||
#define gtk_widget_set_visible(w,yes) { \
|
||||
if (yes) gtk_widget_show(w); \
|
||||
else gtk_widget_hide(w); \
|
||||
}
|
||||
#define gtk_range_get_flippable(range) (GTK_RANGE(range)->flippable)
|
||||
#define gdk_window_is_destroyed(w) (GDK_WINDOW_DESTROYED (GDK_WINDOW(w)))
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 2.16
|
||||
#if ! GTK_CHECK_VERSION (2, 16, 0)
|
||||
#define gtk_status_icon_set_tooltip_text(icon,text) gtk_status_icon_set_tooltip(icon,text)
|
||||
#define gtk_menu_item_get_label(i) (gtk_label_get_label (GTK_LABEL (GTK_BIN (i)->child)))
|
||||
#define gtk_menu_item_set_label(i,label) gtk_label_set_label(GTK_LABEL(GTK_BIN(i)->child), (label) ? label : "")
|
||||
#define gtk_menu_item_get_use_underline(i) (gtk_label_get_use_underline (GTK_LABEL (GTK_BIN (i)->child)))
|
||||
#endif
|
||||
|
||||
|
||||
// GTK < 2.14
|
||||
#if ! GTK_CHECK_VERSION (2, 14, 0)
|
||||
#define gtk_dialog_get_action_area(dialog) (GTK_DIALOG(dialog)->action_area)
|
||||
#define gtk_dialog_get_content_area(dialog) (GTK_DIALOG(dialog)->vbox)
|
||||
#define gtk_widget_get_window(widget) (GTK_WIDGET(widget)->window)
|
||||
#define gtk_window_get_default_widget(window) (GTK_WINDOW(window)->default_widget)
|
||||
#define gtk_menu_item_get_accel_path(i) (GTK_MENU_ITEM(i)->accel_path)
|
||||
#define gtk_menu_get_accel_path(menu) (GTK_MENU(menu)->accel_path)
|
||||
#define gtk_message_dialog_get_image(m) (GTK_MESSAGE_DIALOG(m)->image)
|
||||
#define gtk_entry_get_overwrite_mode(e) (GTK_ENTRY(e)->overwrite_mode)
|
||||
#endif
|
||||
|
||||
|
||||
/* ================================================== */
|
||||
/* GDK KEYS */
|
||||
/* ================================================== */
|
||||
|
||||
#ifndef GDK_KEY_a
|
||||
# define GDK_KEY_Control_R GDK_Control_R
|
||||
# define GDK_KEY_Control_L GDK_Control_L
|
||||
# define GDK_KEY_Shift_R GDK_Shift_R
|
||||
# define GDK_KEY_Shift_L GDK_Shift_L
|
||||
# define GDK_KEY_Alt_R GDK_Alt_R
|
||||
# define GDK_KEY_Alt_L GDK_Alt_L
|
||||
# define GDK_KEY_Tab GDK_Tab
|
||||
# define GDK_KEY_Up GDK_Up
|
||||
# define GDK_KEY_space GDK_space
|
||||
# define GDK_KEY_Down GDK_Down
|
||||
# define GDK_KEY_Return GDK_Return
|
||||
# define GDK_KEY_exclam GDK_exclam
|
||||
# define GDK_KEY_BackSpace GDK_BackSpace
|
||||
# define GDK_KEY_Home GDK_Home
|
||||
# define GDK_KEY_End GDK_End
|
||||
# define GDK_KEY_Escape GDK_Escape
|
||||
# define GDK_KEY_a GDK_a
|
||||
# define GDK_KEY_A GDK_A
|
||||
# define GDK_KEY_b GDK_b
|
||||
# define GDK_KEY_B GDK_B
|
||||
# define GDK_KEY_c GDK_c
|
||||
# define GDK_KEY_C GDK_C
|
||||
# define GDK_KEY_d GDK_d
|
||||
# define GDK_KEY_D GDK_D
|
||||
# define GDK_KEY_e GDK_e
|
||||
# define GDK_KEY_E GDK_E
|
||||
# define GDK_KEY_f GDK_F
|
||||
# define GDK_KEY_g GDK_g
|
||||
# define GDK_KEY_G GDK_G
|
||||
# define GDK_KEY_h GDK_h
|
||||
# define GDK_KEY_H GDK_H
|
||||
# define GDK_KEY_i GDK_i
|
||||
# define GDK_KEY_I GDK_I
|
||||
# define GDK_KEY_j GDK_j
|
||||
# define GDK_KEY_J GDK_J
|
||||
# define GDK_KEY_k GDK_k
|
||||
# define GDK_KEY_K GDK_K
|
||||
# define GDK_KEY_l GDK_l
|
||||
# define GDK_KEY_L GDK_L
|
||||
# define GDK_KEY_m GDK_m
|
||||
# define GDK_KEY_M GDK_M
|
||||
# define GDK_KEY_n GDK_n
|
||||
# define GDK_KEY_N GDK_N
|
||||
# define GDK_KEY_o GDK_o
|
||||
# define GDK_KEY_O GDK_O
|
||||
# define GDK_KEY_p GDK_p
|
||||
# define GDK_KEY_P GDK_P
|
||||
# define GDK_KEY_q GDK_q
|
||||
# define GDK_KEY_Q GDK_Q
|
||||
# define GDK_KEY_r GDK_r
|
||||
# define GDK_KEY_R GDK_R
|
||||
# define GDK_KEY_s GDK_s
|
||||
# define GDK_KEY_S GDK_S
|
||||
# define GDK_KEY_t GDK_t
|
||||
# define GDK_KEY_T GDK_T
|
||||
# define GDK_KEY_u GDK_u
|
||||
# define GDK_KEY_U GDK_U
|
||||
# define GDK_KEY_v GDK_v
|
||||
# define GDK_KEY_V GDK_V
|
||||
# define GDK_KEY_w GDK_w
|
||||
# define GDK_KEY_W GDK_W
|
||||
# define GDK_KEY_x GDK_x
|
||||
# define GDK_KEY_X GDK_X
|
||||
# define GDK_KEY_y GDK_y
|
||||
# define GDK_KEY_Y GDK_Y
|
||||
# define GDK_KEY_z GDK_z
|
||||
# define GDK_KEY_Z GDK_Z
|
||||
# define GDK_KEY_exclam GDK_exclam
|
||||
# define GDK_KEY_F1 GDK_F1
|
||||
# define GDK_KEY_F2 GDK_F2
|
||||
# define GDK_KEY_F3 GDK_F3
|
||||
# define GDK_KEY_F4 GDK_F4
|
||||
# define GDK_KEY_F5 GDK_F5
|
||||
# define GDK_KEY_F6 GDK_F6
|
||||
# define GDK_KEY_F7 GDK_F7
|
||||
# define GDK_KEY_F8 GDK_F8
|
||||
# define GDK_KEY_F9 GDK_F9
|
||||
# define GDK_KEY_F10 GDK_F10
|
||||
# define GDK_KEY_F11 GDK_F11
|
||||
# define GDK_KEY_F12 GDK_F12
|
||||
#endif
|
||||
|
||||
|
||||
// PANGO
|
||||
#ifndef PANGO_WEIGHT_MEDIUM
|
||||
#define PANGO_WEIGHT_MEDIUM 500
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GTKCOMPAT_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,90 +1,84 @@
|
|||
/*****************************************************************************
|
||||
* $Id: gtkcompletionline.h,v 1.12 2003/11/16 10:43:32 andreas99 Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 2020 Mihai Bazon
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software
|
||||
* for any purpose with or without fee is hereby granted, provided that
|
||||
* the above copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GTKCOMPLETIONLINE_H__
|
||||
#define __GTKCOMPLETIONLINE_H__
|
||||
|
||||
#include <gtk/gtkentry.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtkcompat.h"
|
||||
#include "history.h"
|
||||
|
||||
extern "C++" {
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define GTK_COMPLETION_LINE(obj) \
|
||||
GTK_CHECK_CAST(obj, gtk_completion_line_get_type(), GtkCompletionLine)
|
||||
#define GTK_COMPLETION_LINE_CLASS(klass) \
|
||||
GTK_CHECK_CLASS_CAST(klass, gtk_completion_line_get_type(), GtkCompletionLineClass)
|
||||
#define IS_GTK_COMPLETION_LINE(obj) \
|
||||
GTK_CHECK_TYPE(obj, gtk_completion_line_get_type())
|
||||
#define GTK_COMPLETION_LINE(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_completion_line_get_type(), GtkCompletionLine)
|
||||
#define GTK_COMPLETION_LINE_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_completion_line_get_type(), GtkCompletionLineClass)
|
||||
#define IS_GTK_COMPLETION_LINE(obj) GTK_CHECK_TYPE(obj, gtk_completion_line_get_type())
|
||||
|
||||
typedef struct _GtkCompletionLine GtkCompletionLine;
|
||||
typedef struct _GtkCompletionLineClass GtkCompletionLineClass;
|
||||
typedef struct _GtkCompletionLine GtkCompletionLine;
|
||||
typedef struct _GtkCompletionLineClass GtkCompletionLineClass;
|
||||
|
||||
enum GCL_SEARCH_MODE
|
||||
{
|
||||
GCL_SEARCH_OFF = 0,
|
||||
GCL_SEARCH_REW = 1,
|
||||
GCL_SEARCH_FWD = 2,
|
||||
GCL_SEARCH_BEG = 3
|
||||
};
|
||||
#define MAX_HISTWORD_CHARS 1024
|
||||
|
||||
struct _GtkCompletionLine
|
||||
{
|
||||
GtkEntry parent;
|
||||
GtkWidget *win_compl;
|
||||
GtkWidget *list_compl;
|
||||
int list_compl_items_where;
|
||||
int list_compl_nr_rows;
|
||||
int pos_in_text;
|
||||
struct _GtkCompletionLine
|
||||
{
|
||||
GtkEntry parent;
|
||||
GtkWidget * win_compl;
|
||||
GtkListStore * list_compl;
|
||||
GtkTreeModel * sort_list_compl;
|
||||
GtkWidget * tree_compl;
|
||||
GtkTreeIter list_compl_it;
|
||||
int pos_in_text; /* Cursor position in main "line" */
|
||||
|
||||
HistoryFile * hist;
|
||||
gboolean hist_search_mode;
|
||||
gboolean hist_search_match_start;
|
||||
char hist_word[MAX_HISTWORD_CHARS]; /* history search: word that is being typed */
|
||||
int hist_word_count; /* history search: word that is being typed */
|
||||
|
||||
GList *cmpl;
|
||||
GList *where;
|
||||
int tabtimeout;
|
||||
int show_dot_files;
|
||||
};
|
||||
|
||||
HistoryFile *hist;
|
||||
GCL_SEARCH_MODE hist_search_mode;
|
||||
std::string *hist_word;
|
||||
|
||||
int first_key;
|
||||
int tabtimeout;
|
||||
int show_dot_files;
|
||||
};
|
||||
struct _GtkCompletionLineClass
|
||||
{
|
||||
GtkEntryClass parent_class;
|
||||
/* add your CLASS members here */
|
||||
void (* unique) (GtkCompletionLine *cl);
|
||||
void (* notunique) (GtkCompletionLine *cl);
|
||||
void (* incomplete) (GtkCompletionLine *cl);
|
||||
void (* runwithterm) (GtkCompletionLine *cl);
|
||||
void (* search_mode) (GtkCompletionLine *cl);
|
||||
void (* search_letter) (GtkCompletionLine *cl);
|
||||
void (* search_not_found) (GtkCompletionLine *cl);
|
||||
void (* ext_handler) (GtkCompletionLine *cl);
|
||||
void (* cancel) (GtkCompletionLine *cl);
|
||||
};
|
||||
|
||||
struct _GtkCompletionLineClass
|
||||
{
|
||||
GtkEntryClass parent_class;
|
||||
/* add your CLASS members here */
|
||||
|
||||
void (* unique)(GtkCompletionLine *cl);
|
||||
void (* notunique)(GtkCompletionLine *cl);
|
||||
void (* incomplete)(GtkCompletionLine *cl);
|
||||
void (* runwithterm)(GtkCompletionLine *cl);
|
||||
void (* search_mode)(GtkCompletionLine *cl);
|
||||
void (* search_letter)(GtkCompletionLine *cl);
|
||||
void (* search_not_found)(GtkCompletionLine *cl);
|
||||
void (* ext_handler)(GtkCompletionLine *cl);
|
||||
void (* cancel)(GtkCompletionLine *cl);
|
||||
};
|
||||
GType gtk_completion_line_get_type (void);
|
||||
GtkWidget * gtk_completion_line_new ();
|
||||
void gtk_completion_line_last_history_item (GtkCompletionLine*);
|
||||
|
||||
GType gtk_completion_line_get_type(void);
|
||||
GtkWidget *gtk_completion_line_new();
|
||||
|
||||
void gtk_completion_line_last_history_item(GtkCompletionLine*);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GTKCOMPLETIONLINE_H__ */
|
||||
|
||||
// Local Variables: ***
|
||||
// mode: c++ ***
|
||||
// c-basic-offset: 2 ***
|
||||
// End: ***
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* For more information, please refer to <https://unlicense.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* - Generic implementation of HistoryFile
|
||||
* - Loads history from file. Saves history to file.
|
||||
* - Keeps track of the last entry, making it a bit more efficient
|
||||
* - Only adding entries is supported ...
|
||||
* - Supports maximum number of entries,
|
||||
* The first entry is removed if the new entry exceeds the max count.
|
||||
* - Does not allow duplicate strings
|
||||
* This is not a good idea if the list is too long
|
||||
* - If entry exists it's moved to the end of the list..
|
||||
*
|
||||
*/
|
||||
|
||||
#include "history.h"
|
||||
|
||||
// ============================================================
|
||||
// PRIVATE
|
||||
// ============================================================
|
||||
|
||||
struct _Whistory
|
||||
{
|
||||
long int index;
|
||||
unsigned int count;
|
||||
unsigned int max;
|
||||
char * filename;
|
||||
int has_changed;
|
||||
int save_if_changed;
|
||||
GList * list;
|
||||
GList * list_end;
|
||||
GList * current;
|
||||
};
|
||||
|
||||
static void _history_clear (HistoryFile * history)
|
||||
{
|
||||
// keep history->filename (destroyed in _history_free())
|
||||
if (history->list)
|
||||
{
|
||||
//g_list_free_full (history->list, free);
|
||||
GList * i;
|
||||
for (i = history->list; i; i = i->next) {
|
||||
free (i->data);
|
||||
}
|
||||
g_list_free (history->list);
|
||||
history->list = NULL;
|
||||
history->has_changed = 1;
|
||||
}
|
||||
history->index = 0;
|
||||
history->count = 0;
|
||||
}
|
||||
|
||||
|
||||
static void _history_free (HistoryFile * history)
|
||||
{
|
||||
_history_clear (history);
|
||||
if (history->filename) {
|
||||
free (history->filename);
|
||||
history->filename = NULL;
|
||||
}
|
||||
free (history);
|
||||
}
|
||||
|
||||
|
||||
/// load entries from file and initialize private variables
|
||||
static void _history_load_from_file (HistoryFile * history, const char * filename)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024];
|
||||
char * p, * item;
|
||||
size_t len;
|
||||
unsigned int count = 0;
|
||||
unsigned int max = history->max;
|
||||
GList * out_list = NULL;
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (!fp) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read file line by line */
|
||||
while (fgets (buf, sizeof (buf), fp))
|
||||
{
|
||||
p = buf;
|
||||
while (*p && *p <= 0x20) { // 32 = space [ignore spaces]
|
||||
p++;
|
||||
}
|
||||
if (!*p) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item = strdup (p);
|
||||
len = strlen (buf);
|
||||
item[len-1] = 0;
|
||||
if (max > 0 && count >= max) {
|
||||
free (item);
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
out_list = g_list_prepend (out_list, (gpointer) item);
|
||||
}
|
||||
|
||||
if (out_list) {
|
||||
history->list_end = out_list;
|
||||
history->list = out_list;
|
||||
if (out_list->next) {
|
||||
history->list = g_list_reverse (out_list);
|
||||
}
|
||||
history->index = 1;
|
||||
}
|
||||
|
||||
history->count = count;
|
||||
history->current = history->list; // current = 1st item
|
||||
fclose (fp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void _history_write_to_file (HistoryFile * history, const char * filename)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen (filename, "w");
|
||||
if (!fp) {
|
||||
return;
|
||||
}
|
||||
GList * i;
|
||||
for (i = history->list; i; i = i->next)
|
||||
{
|
||||
fprintf (fp, "%s\n", (char *) (i->data));
|
||||
}
|
||||
fclose (fp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// PUBLIC
|
||||
// ============================================================
|
||||
|
||||
HistoryFile * history_new (char * filename, unsigned int maxcount)
|
||||
{
|
||||
HistoryFile * history = calloc (1, sizeof (HistoryFile));
|
||||
history->max = maxcount;
|
||||
if (filename && *filename) {
|
||||
history->filename = strdup (filename);
|
||||
_history_load_from_file (history, filename);
|
||||
}
|
||||
return (history);
|
||||
}
|
||||
|
||||
void history_save (HistoryFile * history, int save_if_changed)
|
||||
{
|
||||
if (history && history->filename) {
|
||||
if (save_if_changed) {
|
||||
if (history->has_changed) {
|
||||
_history_write_to_file (history, history->filename);
|
||||
} // else printf ("not saving!!\n");
|
||||
} else {
|
||||
_history_write_to_file (history, history->filename);
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "history_save(): history or filename is NULL\n");
|
||||
}
|
||||
}
|
||||
|
||||
void history_destroy (HistoryFile * history)
|
||||
{
|
||||
if (history) {
|
||||
_history_free (history);
|
||||
}
|
||||
}
|
||||
|
||||
void history_reload (HistoryFile * history)
|
||||
{
|
||||
if (history) {
|
||||
_history_clear (history);
|
||||
if (history->filename) {
|
||||
_history_load_from_file (history, history->filename);
|
||||
}
|
||||
history->has_changed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void history_print (HistoryFile * history)
|
||||
{
|
||||
if (history) {
|
||||
unsigned int count = 0;
|
||||
GList * i;
|
||||
for (i = history->list; i; i = i->next) {
|
||||
count++;
|
||||
printf ("[%d] %s\n", count, (char *) (i->data));
|
||||
}
|
||||
printf ("-- list internal count: [%d]\n", history->count);
|
||||
if (history->list_end) {
|
||||
printf ("** list : %s\n", (char *) (history->list->data));
|
||||
printf ("** list_end : %s\n", (char *) (history->list_end->data));
|
||||
}
|
||||
if (history->current) {
|
||||
printf ("** list current : %s\n", (char *) (history->current->data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// some apps might want to handle prev/next in a special way
|
||||
void history_unset_current (HistoryFile * history)
|
||||
{
|
||||
if (history) {
|
||||
history->current = NULL;
|
||||
history->index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char * history_get_current (HistoryFile * history)
|
||||
{
|
||||
if (history) return ((char*) (history->current->data));
|
||||
else return (NULL);
|
||||
}
|
||||
|
||||
|
||||
int history_get_current_index (HistoryFile * history)
|
||||
{
|
||||
if (history) return (history->index);
|
||||
else return (-1);
|
||||
}
|
||||
|
||||
|
||||
const char * history_next (HistoryFile * history)
|
||||
{
|
||||
if (history->current && history->current->next) {
|
||||
history->current = history->current->next;
|
||||
history->index++;
|
||||
return ((char *) (history->current->data));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
const char * history_prev (HistoryFile * history)
|
||||
{
|
||||
if (history->current && history->current->prev) {
|
||||
history->current = history->current->prev;
|
||||
history->index--;
|
||||
return ((char *) (history->current->data));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
const char * history_first (HistoryFile * history)
|
||||
{
|
||||
if (history->list) {
|
||||
history->current = history->list;
|
||||
history->index = 1;
|
||||
return ((char *) (history->current->data));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
const char * history_last (HistoryFile * history)
|
||||
{
|
||||
if (history->list) {
|
||||
history->current = history->list_end; // g_list_last (history->list);
|
||||
return ((char *) (history->current->data));
|
||||
history->index = history->count;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
void history_append (HistoryFile * history, const char * text)
|
||||
{
|
||||
if (!text || !*text) {
|
||||
return;
|
||||
}
|
||||
|
||||
GList * i, * templist;
|
||||
char * ientry;
|
||||
// if new entry = last entry, then abort
|
||||
if (history->list_end) {
|
||||
ientry = (char *) (history->list_end->data);
|
||||
if (strcmp (text, ientry) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// do not allow duplicate entries, remove existing entry
|
||||
for (i = history->list; i; i = i->next)
|
||||
{
|
||||
char * ientry = (char *) (i->data);
|
||||
if (strcmp (text, ientry) == 0)
|
||||
{
|
||||
// entry already exists.. remove
|
||||
free (i->data);
|
||||
templist = g_list_delete_link (history->list, i);
|
||||
if (!templist->prev) { // no previous entry.. new start
|
||||
history->list = templist;
|
||||
}
|
||||
if (!templist->next) { // no next... only 1 entry
|
||||
history->list_end = templist;
|
||||
}
|
||||
history->count--;
|
||||
break;
|
||||
}
|
||||
// TODO: handle 'current'
|
||||
}
|
||||
|
||||
// if new entry exceeds the max count, first entry will be removed
|
||||
unsigned int remove_first = 0;
|
||||
if (history->max > 0
|
||||
&& history->count > 1
|
||||
&& history->count >= history->max) {
|
||||
remove_first = 1;
|
||||
}
|
||||
|
||||
if (history->count < history->max) {
|
||||
history->count++;
|
||||
}
|
||||
|
||||
// add new item
|
||||
char * new_item = strdup (text);
|
||||
GList * position = history->list_end ? history->list_end : history->list;
|
||||
position = g_list_append (position, (gpointer) new_item);
|
||||
history->has_changed = 1;
|
||||
if (!history->list) {
|
||||
history->list = position; // first
|
||||
history->current = history->list; // set current to first
|
||||
history->index = 1;
|
||||
}
|
||||
|
||||
if (history->list_end) {
|
||||
history->list_end = history->list_end->next;
|
||||
} else {
|
||||
history->list_end = history->list; // first element has just been added
|
||||
}
|
||||
|
||||
if (remove_first && history->list->next) {
|
||||
// problem when removing the first entry - current may become invalid
|
||||
if (history->current == history->list) {
|
||||
history->current = history->list->next;
|
||||
}
|
||||
free (history->list->data);
|
||||
history->list = g_list_delete_link (history->list, history->list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void history_reverse (HistoryFile * history)
|
||||
{
|
||||
if (history && history->list) {
|
||||
GList * prev_first = history->list;
|
||||
history->list = g_list_reverse (history->list);
|
||||
history->list_end = prev_first;
|
||||
if (history->current == prev_first) {
|
||||
history->current = history->list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
166
src/history.cc
166
src/history.cc
|
@ -1,166 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* $Id: history.cc,v 1.10 2002/08/17 13:19:31 mishoo Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#include "history.h"
|
||||
#include "prefs.h"
|
||||
|
||||
HistoryFile::HistoryFile()
|
||||
{
|
||||
m_file_entries = 0;
|
||||
m_filename = g_get_home_dir();
|
||||
m_filename += "/.gmrun_history";
|
||||
m_current = 0;
|
||||
m_default_set = false;
|
||||
read_the_file();
|
||||
}
|
||||
|
||||
HistoryFile::~HistoryFile()
|
||||
{}
|
||||
|
||||
void
|
||||
HistoryFile::read_the_file()
|
||||
{
|
||||
const char *filename = m_filename.c_str();
|
||||
ifstream f(filename);
|
||||
if (!f) return;
|
||||
|
||||
string line_text;
|
||||
|
||||
while (!f.eof()) {
|
||||
string line_str;
|
||||
|
||||
getline(f,line_text);
|
||||
line_str = line_text;
|
||||
history.push_back(line_str);
|
||||
}
|
||||
|
||||
m_file_entries = history.size();
|
||||
m_current = m_file_entries;
|
||||
}
|
||||
|
||||
void
|
||||
HistoryFile::sync_the_file()
|
||||
{
|
||||
const char *filename = m_filename.c_str();
|
||||
|
||||
int HIST_MAX_SIZE;
|
||||
|
||||
if (!configuration.get_int("History", HIST_MAX_SIZE))
|
||||
HIST_MAX_SIZE = 20;
|
||||
|
||||
ofstream f(filename, ios::out);
|
||||
|
||||
int start = 0;
|
||||
if (history.size() > (size_t)HIST_MAX_SIZE)
|
||||
start = history.size() - HIST_MAX_SIZE;
|
||||
|
||||
for (size_t i = start; i < history.size(); i++)
|
||||
if (history[i].length() != 0)
|
||||
f << history[i] << endl;
|
||||
|
||||
f.flush();
|
||||
}
|
||||
|
||||
void
|
||||
HistoryFile::append(const char *entry)
|
||||
{
|
||||
std::string ent = std::string(entry);
|
||||
if (!history.empty()) {
|
||||
StrArray::reverse_iterator i;
|
||||
#ifdef DEBUG
|
||||
for_each(history.begin(), history.end(), DumpString(cerr));
|
||||
#endif
|
||||
i = find(history.rbegin(), history.rend(), ent);
|
||||
if (i != history.rend()) {
|
||||
#ifdef DEBUG
|
||||
cerr << "erasing "<< ent << endl;
|
||||
#endif
|
||||
history.erase(remove(history.begin(), history.end(), ent));
|
||||
}
|
||||
}
|
||||
history.push_back(ent);
|
||||
}
|
||||
|
||||
void
|
||||
HistoryFile::set_default(const char *defstr)
|
||||
{
|
||||
if (!m_default_set) {
|
||||
m_default = defstr;
|
||||
m_default_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
HistoryFile::operator [] (size_t index)
|
||||
{
|
||||
if (index < 0 || index >= history.size()) {
|
||||
return m_default.c_str();
|
||||
}
|
||||
|
||||
return history[index].c_str();
|
||||
}
|
||||
|
||||
const char *
|
||||
HistoryFile::prev()
|
||||
{
|
||||
const char *ret = (*this)[--m_current];
|
||||
if (m_current < 0) m_current = history.size();
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *
|
||||
HistoryFile::next()
|
||||
{
|
||||
const char *ret = (*this)[++m_current];
|
||||
if (m_current >= history.size()) m_current = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *
|
||||
HistoryFile::prev_to_first()
|
||||
{
|
||||
if (m_current > 0) {
|
||||
return (*this)[--m_current];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
HistoryFile::next_to_last()
|
||||
{
|
||||
if (m_current < history.size()) {
|
||||
return (*this)[++m_current];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HistoryFile::clear_default()
|
||||
{
|
||||
m_default_set = false;
|
||||
}
|
||||
|
||||
void
|
||||
HistoryFile::reset_position()
|
||||
{
|
||||
m_current = m_file_entries;
|
||||
}
|
137
src/history.h
137
src/history.h
|
@ -1,71 +1,86 @@
|
|||
/*****************************************************************************
|
||||
* $Id: history.h,v 1.11 2002/08/17 13:19:31 mishoo Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
|
||||
/*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
* For more information, please refer to <https://unlicense.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic implementation of HistoryFile
|
||||
*/
|
||||
|
||||
#ifndef __HISTORY_H__
|
||||
#define __HISTORY_H__
|
||||
#ifndef __HISTORY_H
|
||||
#define __HISTORY_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
class HistoryFile
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
protected:
|
||||
int m_file_entries;
|
||||
string m_filename;
|
||||
string m_default;
|
||||
bool m_default_set;
|
||||
int m_current;
|
||||
#endif
|
||||
|
||||
typedef vector<string> StrArray;
|
||||
StrArray history;
|
||||
#include "gtkcompat.h"
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
public:
|
||||
HistoryFile();
|
||||
~HistoryFile();
|
||||
typedef struct _Whistory HistoryFile;
|
||||
|
||||
void append(const char *entry);
|
||||
void set_default(const char *defstr);
|
||||
void clear_default();
|
||||
|
||||
void reset_position();
|
||||
|
||||
const char * operator [] (size_t index);
|
||||
|
||||
const char * prev();
|
||||
const char * next();
|
||||
|
||||
const char * prev_to_first();
|
||||
const char * next_to_last();
|
||||
|
||||
void sync_the_file();
|
||||
|
||||
inline const char* last_item() {
|
||||
return history.empty() ? 0 : history.back().c_str();
|
||||
}
|
||||
|
||||
inline const char* first_item() {
|
||||
return history.empty() ? 0 : history.front().c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void read_the_file();
|
||||
private:
|
||||
struct DumpString {
|
||||
DumpString(std::ostream& o) : _out(o) {}
|
||||
void operator()(std::string& str) { _out << str << endl; }
|
||||
private:
|
||||
std::ostream& _out;
|
||||
};
|
||||
enum
|
||||
{
|
||||
HISTORY_SAVE_ALWAYS,
|
||||
HISTORY_SAVE_IF_CHANGED,
|
||||
};
|
||||
|
||||
#endif // __HISTORY_H__
|
||||
/// create a new HistoryFile
|
||||
/// the history is initialized using filename and the filename is stored
|
||||
/// maxcount > 0 sets a maximun item count
|
||||
HistoryFile * history_new (char * filename, unsigned int maxcount);
|
||||
|
||||
/// save history to file, 0 = force save / 1 = save only if history has changed
|
||||
void history_save (HistoryFile * history, int save_if_changed);
|
||||
|
||||
/// history is destroyed, you must variable to NULL
|
||||
void history_destroy (HistoryFile * history);
|
||||
|
||||
/// clear history and reload from file
|
||||
void history_reload (HistoryFile * history);
|
||||
|
||||
/// print history, good for debugging
|
||||
void history_print (HistoryFile * history);
|
||||
|
||||
/// some apps might want to handle prev/next in a special way
|
||||
void history_unset_current (HistoryFile * history);
|
||||
|
||||
/// returns string with the current history item
|
||||
const char * history_get_current (HistoryFile * history);
|
||||
|
||||
/// returns current index: valid index > 0
|
||||
/// assume unser current item if index <= 0
|
||||
int history_get_current_index (HistoryFile * history);
|
||||
|
||||
/// moves position to the next entry and returns text
|
||||
/// if there is no next entry, the position is not moved and returns NULL
|
||||
const char * history_next (HistoryFile * history);
|
||||
|
||||
/// moves position to the previous entry and returns text
|
||||
/// if there is no next entry, the position is not moved and returns NULL
|
||||
const char * history_prev (HistoryFile * history);
|
||||
|
||||
/// moves position to the first entry en returns text
|
||||
/// if there are no entries, it returns NULL
|
||||
const char * history_first (HistoryFile * history);
|
||||
|
||||
/// moves position to the last entry en returns text
|
||||
/// if there are no entries, it returns NULL
|
||||
const char * history_last (HistoryFile * history);
|
||||
|
||||
/// add entry to history, if entry already exists, it's moved to the end of the list
|
||||
void history_append (HistoryFile * history, const char * text);
|
||||
|
||||
void history_reverse (HistoryFile * history);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
* Copyright 2020 Mihai Bazon
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software
|
||||
* for any purpose with or without fee is hereby granted, provided that
|
||||
* the above copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#ifdef MTRACE
|
||||
#include <mcheck.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gtkcompletionline.h"
|
||||
#include "config_prefs.h"
|
||||
|
||||
#define CMD_LENGTH 1024
|
||||
|
||||
enum
|
||||
{
|
||||
W_TEXT_STYLE_NORMAL,
|
||||
W_TEXT_STYLE_NOTFOUND,
|
||||
W_TEXT_STYLE_NOTUNIQUE,
|
||||
W_TEXT_STYLE_UNIQUE,
|
||||
};
|
||||
|
||||
GtkApplication * gmrun_app;
|
||||
|
||||
char * gmrun_text = NULL;
|
||||
static void gmrun_exit (void);
|
||||
GtkAllocation window_geom = { -1, -1, -1, -1 };
|
||||
/* widgets that are used in several functions */
|
||||
GtkWidget * compline;
|
||||
GtkWidget * wlabel;
|
||||
GtkWidget * wlabel_search;
|
||||
|
||||
/* preferences */
|
||||
int USE_GLIB_XDG = 0;
|
||||
int SHELL_RUN = 1;
|
||||
|
||||
/// BEGIN: TIMEOUT MANAGEMENT
|
||||
|
||||
static gboolean search_off_timeout ();
|
||||
static guint g_search_off_timeout_id = 0;
|
||||
|
||||
static void remove_search_off_timeout (void)
|
||||
{
|
||||
if (g_search_off_timeout_id) {
|
||||
g_source_remove(g_search_off_timeout_id);
|
||||
g_search_off_timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_search_off_timeout (guint32 timeout, GSourceFunc func)
|
||||
{
|
||||
remove_search_off_timeout();
|
||||
if (!func)
|
||||
func = (GSourceFunc) search_off_timeout;
|
||||
g_search_off_timeout_id = g_timeout_add (timeout, func, NULL);
|
||||
}
|
||||
|
||||
/// END: TIMEOUT MANAGEMENT
|
||||
|
||||
// https://unix.stackexchange.com/questions/457584/gtk3-change-text-color-in-a-label-raspberry-pi
|
||||
static void set_info_text_color (GtkWidget *w, const char *text, int spec)
|
||||
{
|
||||
char *markup = NULL;
|
||||
static const char * colors[] = {
|
||||
"black", /* W_TEXT_STYLE_NORMAL */
|
||||
"red", /* W_TEXT_STYLE_NOTFOUND */
|
||||
"blue", /* W_TEXT_STYLE_NOTUNIQUE */
|
||||
"green", /* W_TEXT_STYLE_UNIQUE */
|
||||
};
|
||||
markup = g_markup_printf_escaped ("<span foreground=\"%s\">%s</span>",
|
||||
colors[spec], text);
|
||||
if (markup) {
|
||||
gtk_label_set_markup (GTK_LABEL (w), markup);
|
||||
g_free(markup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void run_the_command (char * cmd)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf (stderr, "command: %s\n", cmd);
|
||||
#endif
|
||||
if (SHELL_RUN)
|
||||
{
|
||||
// need to add extra &
|
||||
if (strlen (cmd) < (CMD_LENGTH-10)) {
|
||||
strcat (cmd, " &"); /* safe to use in this case */
|
||||
}
|
||||
int ret = system (cmd);
|
||||
if (ret != -1) {
|
||||
gmrun_exit ();
|
||||
} else {
|
||||
char errmsg[256];
|
||||
snprintf (errmsg, sizeof(errmsg)-1, "ERROR: %s", strerror (errno));
|
||||
set_info_text_color (wlabel, errmsg, W_TEXT_STYLE_NOTFOUND);
|
||||
add_search_off_timeout (3000, NULL);
|
||||
}
|
||||
}
|
||||
else // glib - more conservative approach and robust error reporting
|
||||
{
|
||||
GError * error = NULL;
|
||||
gboolean success;
|
||||
int argc;
|
||||
char ** argv;
|
||||
success = g_shell_parse_argv (cmd, &argc, &argv, &error);
|
||||
if (!success) {
|
||||
set_info_text_color (wlabel, error->message, W_TEXT_STYLE_NOTFOUND);
|
||||
g_error_free (error);
|
||||
add_search_off_timeout (3000, NULL);
|
||||
return;
|
||||
}
|
||||
success = g_spawn_async (NULL, argv, NULL,
|
||||
G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
|
||||
if (argv) {
|
||||
g_strfreev (argv);
|
||||
}
|
||||
if (success) {
|
||||
gmrun_exit ();
|
||||
} else {
|
||||
set_info_text_color (wlabel, error->message, W_TEXT_STYLE_NOTFOUND);
|
||||
g_error_free (error);
|
||||
add_search_off_timeout (3000, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_ext_handler (GtkCompletionLine *cl, const char * filename)
|
||||
{
|
||||
if (USE_GLIB_XDG) // GLib XDG handling (freedesktop specification)
|
||||
{
|
||||
gchar * content_type, * mime_type, * msg;
|
||||
const gchar * handler;
|
||||
GAppInfo * app_info;
|
||||
|
||||
if (filename) {
|
||||
content_type = g_content_type_guess (filename, NULL, 0, NULL);
|
||||
if (content_type) {
|
||||
mime_type = g_content_type_get_mime_type (content_type);
|
||||
g_free (content_type);
|
||||
app_info = g_app_info_get_default_for_type (mime_type, FALSE);
|
||||
g_free (mime_type);
|
||||
if (app_info) {
|
||||
handler = g_app_info_get_commandline (app_info);
|
||||
msg = g_strconcat("Handler: ", handler, NULL);
|
||||
gtk_label_set_text (GTK_LABEL (wlabel_search), msg);
|
||||
gtk_widget_show (wlabel_search);
|
||||
|
||||
g_object_unref(app_info);
|
||||
g_free(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
search_off_timeout();
|
||||
}
|
||||
else // custom EXT handlers
|
||||
{
|
||||
const char * ext = strrchr (filename, '.');
|
||||
if (!ext) {
|
||||
search_off_timeout ();
|
||||
return;
|
||||
}
|
||||
const char * handler = config_get_handler_for_extension (ext);
|
||||
if (handler) {
|
||||
char * tmp = g_strconcat ("Handler: ", handler, NULL);
|
||||
gtk_label_set_text (GTK_LABEL (wlabel_search), tmp);
|
||||
gtk_widget_show (wlabel_search);
|
||||
g_free (tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void on_compline_runwithterm (GtkCompletionLine *cl)
|
||||
{
|
||||
char cmd[CMD_LENGTH];
|
||||
char * term;
|
||||
char * entry_text = g_strdup (gtk_entry_get_text (GTK_ENTRY(cl)));
|
||||
g_strstrip (entry_text);
|
||||
|
||||
if (*entry_text) {
|
||||
if (config_get_string_expanded ("TermExec", &term)) {
|
||||
snprintf (cmd, sizeof (cmd), "%s %s", term, entry_text);
|
||||
g_free (term);
|
||||
} else {
|
||||
snprintf (cmd, sizeof (cmd), "xterm -e %s", entry_text);
|
||||
}
|
||||
} else {
|
||||
if (config_get_string ("Terminal", &term)) {
|
||||
strncpy (cmd, term, sizeof (cmd) - 1);
|
||||
} else {
|
||||
strncpy (cmd, "xterm", sizeof (cmd) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
history_append (cl->hist, cmd);
|
||||
run_the_command (cmd);
|
||||
g_free (entry_text);
|
||||
}
|
||||
|
||||
static gboolean search_off_timeout ()
|
||||
{
|
||||
set_info_text_color (wlabel, "Run program:", W_TEXT_STYLE_NORMAL);
|
||||
gtk_widget_hide (wlabel_search);
|
||||
g_search_off_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_unique (GtkCompletionLine *cl)
|
||||
{
|
||||
set_info_text_color (wlabel, "unique", W_TEXT_STYLE_UNIQUE);
|
||||
add_search_off_timeout (1000, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_notunique (GtkCompletionLine *cl)
|
||||
{
|
||||
set_info_text_color (wlabel, "not unique", W_TEXT_STYLE_NOTUNIQUE);
|
||||
add_search_off_timeout (1000, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_incomplete (GtkCompletionLine *cl)
|
||||
{
|
||||
set_info_text_color (wlabel, "not found", W_TEXT_STYLE_NOTFOUND);
|
||||
add_search_off_timeout (1000, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_search_mode (GtkCompletionLine *cl)
|
||||
{
|
||||
if (cl->hist_search_mode == TRUE) {
|
||||
gtk_widget_show (wlabel_search);
|
||||
gtk_label_set_text (GTK_LABEL (wlabel), "Search:");
|
||||
gtk_label_set_text (GTK_LABEL (wlabel_search), cl->hist_word);
|
||||
} else {
|
||||
gtk_widget_hide (wlabel_search);
|
||||
gtk_label_set_text (GTK_LABEL (wlabel), "Search OFF");
|
||||
add_search_off_timeout (1000, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_search_letter(GtkCompletionLine *cl, GtkWidget *label)
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL(label), cl->hist_word);
|
||||
}
|
||||
|
||||
static gboolean search_fail_timeout (gpointer user_data)
|
||||
{
|
||||
set_info_text_color (wlabel, "Search:", W_TEXT_STYLE_NOTUNIQUE);
|
||||
g_search_off_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_search_not_found(GtkCompletionLine *cl)
|
||||
{
|
||||
set_info_text_color (wlabel, "Not Found!", W_TEXT_STYLE_NOTFOUND);
|
||||
add_search_off_timeout (1000, (GSourceFunc) search_fail_timeout);
|
||||
}
|
||||
|
||||
|
||||
// =============================================================
|
||||
|
||||
static void xdg_app_run_command (GAppInfo *app, const gchar *args)
|
||||
{
|
||||
// get
|
||||
char * cmd, * exe;
|
||||
GRegex * regex;
|
||||
|
||||
regex = g_regex_new (".%[fFuUdDnNickvm]", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, NULL);
|
||||
exe = g_regex_replace_literal (regex, // Remove xdg desktop files fields from app
|
||||
g_app_info_get_commandline (app),
|
||||
-1, 0, "", G_REGEX_MATCH_NOTEMPTY, NULL);
|
||||
cmd = g_strconcat (exe, " ", args, NULL);
|
||||
run_the_command (cmd); /* Launch the command */
|
||||
g_regex_unref (regex);
|
||||
g_free (exe);
|
||||
g_free (cmd);
|
||||
}
|
||||
|
||||
/* Handler for URLs */
|
||||
static gboolean url_check (GtkCompletionLine *cl, char * entry_text)
|
||||
{
|
||||
if (USE_GLIB_XDG) // GLib XDG handling (freedesktop specification)
|
||||
{
|
||||
char * delim;
|
||||
const char * url, * protocol;
|
||||
GAppInfo * app;
|
||||
delim = strchr (entry_text, ':');
|
||||
if (!delim || !*(delim+1)) {
|
||||
return FALSE;
|
||||
}
|
||||
protocol = entry_text;
|
||||
url = delim + 1;
|
||||
*delim = 0;
|
||||
|
||||
if (url[0] == '/' && url[1] == '/')
|
||||
{
|
||||
app = g_app_info_get_default_for_uri_scheme (protocol);
|
||||
if (app) { // found known uri handler for protocol
|
||||
*delim = ':';
|
||||
xdg_app_run_command (app, entry_text);
|
||||
history_append (cl->hist, entry_text);
|
||||
g_object_unref (app);
|
||||
} else {
|
||||
char *tmp = g_strconcat ("No URL handler for [", protocol, "]", NULL);
|
||||
set_info_text_color (wlabel, tmp, W_TEXT_STYLE_NOTFOUND);
|
||||
add_search_off_timeout (1000, NULL);
|
||||
g_free (tmp);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
*delim = ':';
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
else //-------- custom URL handlers
|
||||
{
|
||||
// <url_type> <delim> <url>
|
||||
// http : //www.fsf.org
|
||||
// <f u l l u r l>
|
||||
// config: URL_<url_type>
|
||||
// handler %s (format 1) = run handler with <url>
|
||||
// handler %u (format 2) = run handler with <full url>
|
||||
char * cmd;
|
||||
char * tmp, * delim, * p;
|
||||
char * url, * url_type, * full_url, * chosen_url;
|
||||
char * url_handler;
|
||||
char * config_key;
|
||||
cmd = tmp = delim = p = url_handler = config_key = NULL;
|
||||
delim = strchr (entry_text, ':');
|
||||
if (!delim || !*(delim+1)) {
|
||||
return FALSE;
|
||||
}
|
||||
tmp = g_strdup (entry_text);
|
||||
delim = strchr (tmp, ':');
|
||||
*delim = 0;
|
||||
url_type = tmp; // http
|
||||
url = delim + 1; // //www.fsf.org
|
||||
full_url = entry_text;
|
||||
|
||||
config_key = g_strconcat ("URL_", url_type, NULL);
|
||||
if (config_get_string_expanded (config_key, &url_handler))
|
||||
{
|
||||
chosen_url = url;
|
||||
p = strchr (url_handler, '%');
|
||||
if (p) { // handler %s
|
||||
p++;
|
||||
if (*p == 'u') { // handler %u
|
||||
*p = 's'; // convert %u to %s (for printf)
|
||||
chosen_url = full_url;
|
||||
}
|
||||
cmd = g_strdup_printf (url_handler, chosen_url);
|
||||
} else {
|
||||
cmd = g_strconcat (url_handler, " ", url, NULL);
|
||||
}
|
||||
g_free (url_handler);
|
||||
}
|
||||
|
||||
if (cmd) {
|
||||
history_append (cl->hist, entry_text);
|
||||
run_the_command (cmd);
|
||||
g_free (cmd);
|
||||
} else {
|
||||
g_free (tmp);
|
||||
tmp = g_strconcat ("No URL handler for [", config_key, "]", NULL);
|
||||
set_info_text_color (wlabel, tmp, W_TEXT_STYLE_NOTFOUND);
|
||||
add_search_off_timeout (1000, NULL);
|
||||
}
|
||||
g_free (config_key);
|
||||
g_free (tmp);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char * escape_spaces (char * entry_text)
|
||||
{ // run file with glib: replace " " with "\ "
|
||||
GRegex * regex;
|
||||
char * quoted;
|
||||
if (!strstr (entry_text, "\\ ")) {
|
||||
regex = g_regex_new (" ", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, NULL);
|
||||
quoted = g_regex_replace_literal (regex, entry_text, -1, 0, "\\ ", G_REGEX_MATCH_NOTEMPTY, NULL);
|
||||
g_regex_unref (regex);
|
||||
} else {
|
||||
quoted = strdup (entry_text); // already scaped, just duplicate text
|
||||
}
|
||||
return (quoted);
|
||||
}
|
||||
|
||||
/* Handler for extensions */
|
||||
static gboolean ext_check (GtkCompletionLine *cl, char * entry_text)
|
||||
{
|
||||
if (USE_GLIB_XDG) // GLib XDG handling (freedesktop specification)
|
||||
{
|
||||
char *quoted, *content_type, *mime_type;
|
||||
GAppInfo *app_info;
|
||||
gboolean sure;
|
||||
quoted = escape_spaces (entry_text);
|
||||
/* File is executable: launch it (fail silently if file isn't really executable) */
|
||||
if (g_file_test (quoted, G_FILE_TEST_IS_EXECUTABLE)) {
|
||||
run_the_command (quoted);
|
||||
history_append (cl->hist, entry_text);
|
||||
g_free (quoted);
|
||||
return TRUE;
|
||||
}
|
||||
/* Check mime type through extension */
|
||||
if (quoted[0] == '/' && strchr (quoted, '.')) {
|
||||
content_type = g_content_type_guess (quoted, NULL, 0, &sure);
|
||||
if (content_type) {
|
||||
mime_type = g_content_type_get_mime_type (content_type);
|
||||
g_free (content_type);
|
||||
app_info = g_app_info_get_default_for_type (mime_type, FALSE);
|
||||
g_free (mime_type);
|
||||
if (app_info) { // found mime
|
||||
xdg_app_run_command (app_info, quoted);
|
||||
history_append (cl->hist, entry_text);
|
||||
g_free (quoted);
|
||||
g_object_unref(app_info);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free (quoted);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
else //-------- custom EXTension handlers
|
||||
{
|
||||
// example: file.html | xdg-open '%s' -> xdg-open 'file.html'
|
||||
char * cmd, * quoted;
|
||||
char * ext = strrchr (entry_text, '.');
|
||||
char * handler_format = NULL;
|
||||
if (ext) {
|
||||
handler_format = config_get_handler_for_extension (ext);
|
||||
}
|
||||
if (handler_format) {
|
||||
quoted = g_strcompress (entry_text); /* unescape chars */
|
||||
if (strstr (handler_format, "%s")) {
|
||||
cmd = g_strdup_printf (handler_format, quoted);
|
||||
}
|
||||
else { // xdg-open
|
||||
cmd = g_strconcat (handler_format, " '", quoted, "'", NULL);
|
||||
}
|
||||
history_append (cl->hist, entry_text);
|
||||
run_the_command (cmd);
|
||||
g_free (cmd);
|
||||
g_free (quoted);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
|
||||
static void on_compline_activated (GtkCompletionLine *cl)
|
||||
{
|
||||
char * entry_text = g_strdup (gtk_entry_get_text (GTK_ENTRY(cl)));
|
||||
g_strstrip (entry_text);
|
||||
|
||||
if (url_check (cl, entry_text) == TRUE
|
||||
|| ext_check (cl, entry_text) == TRUE) {
|
||||
g_free (entry_text);
|
||||
return;
|
||||
}
|
||||
|
||||
char cmd[CMD_LENGTH];
|
||||
char * AlwaysInTerm = NULL;
|
||||
char ** term_progs = NULL;
|
||||
char * selected_term_prog = NULL;
|
||||
|
||||
if (config_get_string ("AlwaysInTerm", &AlwaysInTerm))
|
||||
{
|
||||
term_progs = g_strsplit (AlwaysInTerm, " ", 0);
|
||||
int i;
|
||||
for (i = 0; term_progs[i]; i++) {
|
||||
if (strcmp (term_progs[i], entry_text) == 0) {
|
||||
selected_term_prog = g_strdup (term_progs[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_strfreev (term_progs);
|
||||
}
|
||||
|
||||
if (selected_term_prog) {
|
||||
char * TermExec;
|
||||
config_get_string_expanded ("TermExec", &TermExec);
|
||||
snprintf (cmd, sizeof (cmd), "%s %s", TermExec, selected_term_prog);
|
||||
g_free (selected_term_prog);
|
||||
g_free (TermExec);
|
||||
} else {
|
||||
strncpy (cmd, entry_text, sizeof (cmd) - 1);
|
||||
}
|
||||
g_free (entry_text);
|
||||
|
||||
history_append (cl->hist, cmd);
|
||||
run_the_command (cmd);
|
||||
}
|
||||
|
||||
|
||||
// =============================================================
|
||||
|
||||
|
||||
static void gmrun_activate(void)
|
||||
{
|
||||
GtkWidget *dialog, * main_vbox;
|
||||
GtkWidget *label_search;
|
||||
|
||||
GtkWidget * window = gtk_application_window_new (gmrun_app);
|
||||
dialog = gtk_dialog_new();
|
||||
gtk_window_set_transient_for( (GtkWindow*)dialog, (GtkWindow*)window );
|
||||
gtk_widget_realize(dialog);
|
||||
main_vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
// this removes the title bar..
|
||||
GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET(dialog));
|
||||
gdk_window_set_decorations (gwin, GDK_DECOR_BORDER);
|
||||
|
||||
gtk_widget_set_name (GTK_WIDGET (dialog), "gmrun");
|
||||
gtk_window_set_title (GTK_WINDOW(window), "A simple launcher with completion");
|
||||
|
||||
gtk_container_set_border_width(GTK_CONTAINER(dialog), 4);
|
||||
g_signal_connect(G_OBJECT(dialog), "destroy",
|
||||
G_CALLBACK(gmrun_exit), NULL);
|
||||
|
||||
GtkWidget *hhbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), hhbox, FALSE, FALSE, 0);
|
||||
|
||||
GtkWidget *label = gtk_label_new("Run program:");
|
||||
gtk_box_pack_start (GTK_BOX(hhbox), label, FALSE, FALSE, 10);
|
||||
gtkcompat_widget_set_halign_left (GTK_WIDGET (label));
|
||||
wlabel = label;
|
||||
|
||||
label_search = gtk_label_new("");
|
||||
gtk_box_pack_start (GTK_BOX (hhbox), label_search, FALSE, TRUE, 0);
|
||||
wlabel_search = label_search;
|
||||
|
||||
compline = gtk_completion_line_new();
|
||||
gtk_widget_set_name (compline, "gmrun_compline");
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), compline, TRUE, TRUE, 0);
|
||||
|
||||
if (!config_get_int ("SHELL_RUN", &SHELL_RUN)) {
|
||||
SHELL_RUN = 1;
|
||||
}
|
||||
|
||||
// don't show files starting with "." by default
|
||||
if (!config_get_int ("ShowDotFiles", &(GTK_COMPLETION_LINE(compline)->show_dot_files))) {
|
||||
GTK_COMPLETION_LINE(compline)->show_dot_files = 0;
|
||||
}
|
||||
int tmp;
|
||||
if (!config_get_int ("TabTimeout", &tmp)) {
|
||||
((GtkCompletionLine*)compline)->tabtimeout = tmp;
|
||||
}
|
||||
if (!config_get_int ("USE_GLIB_XDG", &USE_GLIB_XDG)) {
|
||||
USE_GLIB_XDG = 0;
|
||||
}
|
||||
|
||||
g_signal_connect(G_OBJECT(compline), "cancel",
|
||||
G_CALLBACK(gmrun_exit), NULL);
|
||||
g_signal_connect(G_OBJECT(compline), "activate",
|
||||
G_CALLBACK (on_compline_activated), NULL);
|
||||
g_signal_connect(G_OBJECT(compline), "runwithterm",
|
||||
G_CALLBACK (on_compline_runwithterm), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(compline), "unique",
|
||||
G_CALLBACK (on_compline_unique), NULL);
|
||||
g_signal_connect(G_OBJECT(compline), "notunique",
|
||||
G_CALLBACK (on_compline_notunique), NULL);
|
||||
g_signal_connect(G_OBJECT(compline), "incomplete",
|
||||
G_CALLBACK (on_compline_incomplete), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(compline), "search_mode",
|
||||
G_CALLBACK (on_search_mode), NULL);
|
||||
g_signal_connect(G_OBJECT(compline), "search_not_found",
|
||||
G_CALLBACK (on_search_not_found), NULL);
|
||||
g_signal_connect(G_OBJECT(compline), "search_letter",
|
||||
G_CALLBACK(on_search_letter), label_search);
|
||||
|
||||
g_signal_connect(G_OBJECT(compline), "ext_handler",
|
||||
G_CALLBACK (on_ext_handler), NULL);
|
||||
|
||||
int shows_last_history_item;
|
||||
if (!config_get_int ("ShowLast", &shows_last_history_item)) {
|
||||
shows_last_history_item = 0;
|
||||
}
|
||||
if (gmrun_text) {
|
||||
gtk_entry_set_text (GTK_ENTRY(compline), gmrun_text);
|
||||
} else if (shows_last_history_item) {
|
||||
gtk_completion_line_last_history_item (GTK_COMPLETION_LINE(compline));
|
||||
}
|
||||
|
||||
// geometry: window position
|
||||
if (window_geom.x > -1 || window_geom.y > -1) {
|
||||
gtk_window_move (GTK_WINDOW (dialog), window_geom.x, window_geom.y);
|
||||
} else {
|
||||
/* default: centered */
|
||||
gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ALWAYS);
|
||||
}
|
||||
|
||||
// geometry: window size
|
||||
if (window_geom.height > -1 || window_geom.width > -1) {
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog), window_geom.width,
|
||||
window_geom.height);
|
||||
} else {
|
||||
/* default width = 450 */
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog), 450, -1);
|
||||
}
|
||||
|
||||
// window icon
|
||||
GError * error = NULL;
|
||||
GtkIconTheme * theme = gtk_icon_theme_get_default ();
|
||||
GdkPixbuf * icon = gtk_icon_theme_load_icon (theme, "gmrun", 48, GTK_ICON_LOOKUP_USE_BUILTIN, &error);
|
||||
if (error) {
|
||||
g_object_set (dialog, "icon-name", "gtk-execute", NULL);
|
||||
g_error_free (error);
|
||||
} else {
|
||||
gtk_window_set_icon (GTK_WINDOW (dialog), icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
gtk_widget_show_all (dialog);
|
||||
|
||||
gtk_window_set_focus(GTK_WINDOW(dialog), compline);
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
|
||||
static void parse_command_line (int argc, char ** argv)
|
||||
{
|
||||
// --geometry / parse commandline options
|
||||
static char *geometry_str = NULL;
|
||||
GError *error = NULL;
|
||||
GOptionContext *context = NULL;
|
||||
static GOptionEntry entries[] =
|
||||
{
|
||||
{ "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry_str, "This option specifies the initial size and location of the window.", NULL, },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_add_group (context, gtk_get_option_group (TRUE));
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_print ("option parsing failed: %s\n", error->message);
|
||||
if (context) g_option_context_free (context);
|
||||
if (error) g_error_free (error);
|
||||
if (geometry_str) g_free (geometry_str);
|
||||
exit (1);
|
||||
}
|
||||
if (context) g_option_context_free (context);
|
||||
if (error) g_error_free (error);
|
||||
if (argc >= 2) {
|
||||
gmrun_text = argv[1];
|
||||
}
|
||||
// --
|
||||
|
||||
if (!geometry_str)
|
||||
{
|
||||
// --geometry was not specified, see config file
|
||||
char * geomstr;
|
||||
if (config_get_string ("Geometry", &geomstr)) {
|
||||
geometry_str = g_strdup (geomstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (geometry_str)
|
||||
{
|
||||
// --geometry WxH+X+Y
|
||||
// width x height + posX + posY
|
||||
int width, height, posX, posY;
|
||||
char *Wstr, *Hstr, *Xstr, *Ystr;
|
||||
Wstr = Hstr = Xstr = Ystr = NULL;
|
||||
|
||||
Xstr = strchr (geometry_str, '+');
|
||||
if (Xstr) { // +posX+posY
|
||||
*Xstr = 0;
|
||||
Xstr++; // posX+posY
|
||||
Ystr = strchr (Xstr, '+');
|
||||
if (Ystr) { // +posY
|
||||
*Ystr = 0;
|
||||
Ystr++; // posY
|
||||
}
|
||||
}
|
||||
if (Xstr && Ystr && *Xstr && *Ystr) {
|
||||
posX = strtoll (Xstr, NULL, 0);
|
||||
posY = strtoll (Ystr, NULL, 0);
|
||||
///fprintf (stderr, "x: %" G_GINT64_FORMAT "\ny: %" G_GINT64_FORMAT "\n", posX, posY);
|
||||
window_geom.x = posX;
|
||||
window_geom.y = posY;
|
||||
}
|
||||
|
||||
Hstr = strchr (geometry_str, 'x');
|
||||
if (Hstr) { // WxH
|
||||
*Hstr = 0;
|
||||
Hstr++; // H
|
||||
Wstr = geometry_str;
|
||||
width = strtoll (Wstr, NULL, 0);
|
||||
height = strtoll (Hstr, NULL, 0);
|
||||
///fprintf (stderr, "w: %" G_GINT64_FORMAT "\nh: %" G_GINT64_FORMAT "\n", width, height);
|
||||
window_geom.width = width;
|
||||
window_geom.height = height;
|
||||
}
|
||||
|
||||
g_free (geometry_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =============================================================
|
||||
// MAIN
|
||||
|
||||
void gmrun_exit(void)
|
||||
{
|
||||
gtk_widget_destroy (compline);
|
||||
config_destroy ();
|
||||
g_application_quit (G_APPLICATION (gmrun_app));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
#ifdef MTRACE
|
||||
mtrace();
|
||||
#endif
|
||||
int status = 0;
|
||||
|
||||
config_init ();
|
||||
parse_command_line (argc, argv);
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 4, 0)
|
||||
// Handling cmd line args with GApplication is a nightmare
|
||||
// follow this: https://developer.gnome.org/gtkmm-tutorial/stable/sec-multi-item-containers.html.en#boxes-command-line-options
|
||||
argc = 1; /* hide args from GApplication */
|
||||
gmrun_app = gtk_application_new ("org.gtk.gmrun", G_APPLICATION_NON_UNIQUE);
|
||||
g_signal_connect (gmrun_app, "activate", gmrun_activate, NULL);
|
||||
status = g_application_run (G_APPLICATION (gmrun_app), argc, argv);
|
||||
g_object_unref (gmrun_app);
|
||||
#else
|
||||
gtk_init (&argc, &argv);
|
||||
gmrun_activate ();
|
||||
gtk_main ();
|
||||
#endif
|
||||
|
||||
#ifdef MTRACE
|
||||
muntrace();
|
||||
#endif
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
526
src/main.cc
526
src/main.cc
|
@ -1,526 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* $Id: main.cc,v 1.26 2003/11/16 10:55:07 andreas99 Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef MTRACE
|
||||
#include <mcheck.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gtkcompletionline.h"
|
||||
#include "prefs.h"
|
||||
|
||||
// defined in gtkcompletionline.cc
|
||||
int get_words(GtkCompletionLine *object, vector<string>& words);
|
||||
string quote_string(const string& str);
|
||||
|
||||
struct gigi
|
||||
{
|
||||
GtkWidget *w1;
|
||||
GtkWidget *w2;
|
||||
};
|
||||
|
||||
/// BEGIN: TIMEOUT MANAGEMENT
|
||||
|
||||
static gint search_off_timeout(struct gigi *g);
|
||||
|
||||
static guint g_search_off_timeout_id = 0;
|
||||
|
||||
static void remove_search_off_timeout()
|
||||
{
|
||||
if (g_search_off_timeout_id) {
|
||||
gtk_timeout_remove(g_search_off_timeout_id);
|
||||
g_search_off_timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_search_off_timeout(guint32 timeout, struct gigi *g, GtkFunction func = 0)
|
||||
{
|
||||
remove_search_off_timeout();
|
||||
if (!func)
|
||||
func = GtkFunction(search_off_timeout);
|
||||
g_search_off_timeout_id = gtk_timeout_add(timeout, func, g);
|
||||
}
|
||||
|
||||
/// END: TIMEOUT MANAGEMENT
|
||||
|
||||
GtkStyle* style_normal(GtkWidget *w)
|
||||
{
|
||||
static GtkStyle *style;
|
||||
|
||||
if (!style) {
|
||||
style = gtk_style_copy(gtk_widget_get_style(w));
|
||||
style->fg[GTK_STATE_NORMAL] = (GdkColor){0, 0x0000, 0x0000, 0x0000};
|
||||
gtk_style_ref(style);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
GtkStyle* style_notfound(GtkWidget *w)
|
||||
{
|
||||
static GtkStyle *style;
|
||||
|
||||
if (!style) {
|
||||
style = gtk_style_copy(gtk_widget_get_style(w));
|
||||
style->fg[GTK_STATE_NORMAL] = (GdkColor){0, 0xFFFF, 0x0000, 0x0000};
|
||||
gtk_style_ref(style);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
GtkStyle* style_notunique(GtkWidget *w)
|
||||
{
|
||||
static GtkStyle *style;
|
||||
|
||||
if (!style) {
|
||||
style = gtk_style_copy(gtk_widget_get_style(w));
|
||||
style->fg[GTK_STATE_NORMAL] = (GdkColor){0, 0x0000, 0x0000, 0xFFFF};
|
||||
gtk_style_ref(style);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
GtkStyle* style_unique(GtkWidget *w)
|
||||
{
|
||||
static GtkStyle *style;
|
||||
|
||||
if (!style) {
|
||||
style = gtk_style_copy(gtk_widget_get_style(w));
|
||||
style->fg[GTK_STATE_NORMAL] = (GdkColor){0, 0x0000, 0xFFFF, 0x0000};
|
||||
gtk_style_ref(style);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
static void
|
||||
run_the_command(const std::string& command, struct gigi* g)
|
||||
{
|
||||
string cmd(command);
|
||||
cmd += '&';
|
||||
int ret = system(cmd.c_str());
|
||||
#ifdef DEBUG
|
||||
cerr << "System exit code: " << ret << endl;
|
||||
#endif
|
||||
if (ret != -1)
|
||||
gtk_main_quit();
|
||||
else {
|
||||
string error("ERROR: ");
|
||||
error += strerror(errno);
|
||||
#ifdef DEBUG
|
||||
cerr << error << endl;
|
||||
#endif
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), error.c_str());
|
||||
gtk_widget_set_style(g->w1, style_notfound(g->w1));
|
||||
add_search_off_timeout(2000, g);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_ext_handler(GtkCompletionLine *cl, const char* ext, struct gigi* g)
|
||||
{
|
||||
string cmd;
|
||||
if (ext && configuration.get_ext_handler(ext, cmd)) {
|
||||
string str("Handler: ");
|
||||
size_t pos = cmd.find_first_of(" \t");
|
||||
if (pos == string::npos)
|
||||
str += cmd;
|
||||
else
|
||||
str += cmd.substr(0, pos);
|
||||
gtk_label_set_text(GTK_LABEL(g->w2), str.c_str());
|
||||
gtk_widget_show(g->w2);
|
||||
// gtk_timeout_add(1000, GtkFunction(search_off_timeout), g);
|
||||
} else {
|
||||
search_off_timeout(g);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_runwithterm(GtkCompletionLine *cl, struct gigi* g)
|
||||
{
|
||||
string command(g_locale_from_utf8 (gtk_entry_get_text(GTK_ENTRY(cl)),
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL));
|
||||
string tmp;
|
||||
string term;
|
||||
|
||||
string::size_type i;
|
||||
i = command.find_first_not_of(" \t");
|
||||
|
||||
if (i != string::npos) {
|
||||
if (!configuration.get_string("TermExec", term)) {
|
||||
term = "xterm -e";
|
||||
}
|
||||
tmp = term;
|
||||
tmp += " ";
|
||||
tmp += command;
|
||||
} else {
|
||||
if (!configuration.get_string("Terminal", term)) {
|
||||
tmp = "xterm";
|
||||
} else {
|
||||
tmp = term;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
cerr << tmp << endl;
|
||||
#endif
|
||||
|
||||
cl->hist->append(command.c_str());
|
||||
cl->hist->sync_the_file();
|
||||
run_the_command(tmp.c_str(), g);
|
||||
}
|
||||
|
||||
static gint
|
||||
search_off_timeout(struct gigi *g)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "Run program:");
|
||||
gtk_widget_set_style(g->w1, style_normal(g->w1));
|
||||
gtk_widget_hide(g->w2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_unique(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "unique");
|
||||
gtk_widget_set_style(g->w1, style_unique(g->w1));
|
||||
add_search_off_timeout(1000, g);
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_notunique(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "not unique");
|
||||
gtk_widget_set_style(g->w1, style_notunique(g->w1));
|
||||
add_search_off_timeout(1000, g);
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_incomplete(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "not found");
|
||||
gtk_widget_set_style(g->w1, style_notfound(g->w1));
|
||||
add_search_off_timeout(1000, g);
|
||||
}
|
||||
|
||||
static void
|
||||
on_search_mode(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
if (cl->hist_search_mode != GCL_SEARCH_OFF) {
|
||||
gtk_widget_show(g->w2);
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "Search:");
|
||||
gtk_label_set_text(GTK_LABEL(g->w2), cl->hist_word->c_str());
|
||||
} else {
|
||||
gtk_widget_hide(g->w2);
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "Search OFF");
|
||||
add_search_off_timeout(1000, g);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_search_letter(GtkCompletionLine *cl, GtkWidget *label)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(label), cl->hist_word->c_str());
|
||||
}
|
||||
|
||||
static gint
|
||||
search_fail_timeout(struct gigi *g)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "Search:");
|
||||
gtk_widget_set_style(g->w2, style_notunique(g->w2));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_search_not_found(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(g->w1), "Not Found!");
|
||||
gtk_widget_set_style(g->w2, style_notfound(g->w2));
|
||||
add_search_off_timeout(1000, g, GtkFunction(search_fail_timeout));
|
||||
}
|
||||
|
||||
static bool
|
||||
url_check(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
string text(g_locale_from_utf8 (gtk_entry_get_text(GTK_ENTRY(cl)),
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL));
|
||||
|
||||
string::size_type i;
|
||||
string::size_type sp;
|
||||
|
||||
sp = text.find_first_not_of(" \t");
|
||||
if (sp == string::npos) return true;
|
||||
text = text.substr(sp);
|
||||
|
||||
sp = text.find_first_of(" \t");
|
||||
i = text.find(":");
|
||||
|
||||
if (i != string::npos && i < sp) {
|
||||
// URL entered...
|
||||
string url(text.substr(i + 1));
|
||||
string url_type(text.substr(0, i));
|
||||
string url_handler;
|
||||
|
||||
if (configuration.get_string(string("URL_") + url_type, url_handler)) {
|
||||
string::size_type j = 0;
|
||||
|
||||
do {
|
||||
j = url_handler.find("%s", j);
|
||||
if (j != string::npos) {
|
||||
url_handler.replace(j, 2, url);
|
||||
}
|
||||
} while (j != string::npos);
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
j = url_handler.find("%u", j);
|
||||
if (j != string::npos) {
|
||||
url_handler.replace(j, 2, text);
|
||||
}
|
||||
} while (j != string::npos);
|
||||
|
||||
cl->hist->append(text.c_str());
|
||||
cl->hist->sync_the_file();
|
||||
run_the_command(url_handler.c_str(), g);
|
||||
return true;
|
||||
} else {
|
||||
gtk_label_set_text(GTK_LABEL(g->w1),
|
||||
(string("No URL handler for [") +
|
||||
url_type + "]").c_str());
|
||||
gtk_widget_set_style(g->w1, style_notfound(g->w1));
|
||||
add_search_off_timeout(1000, g);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
ext_check(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
vector<string> words;
|
||||
get_words(cl, words);
|
||||
vector<string>::const_iterator
|
||||
i = words.begin(),
|
||||
i_end = words.end();
|
||||
|
||||
while (i != i_end) {
|
||||
const string& w = quote_string(*i++);
|
||||
if (w[0] == '/') {
|
||||
// absolute path, check for extension
|
||||
size_t pos = w.rfind('.');
|
||||
if (pos != string::npos) {
|
||||
// we have extension
|
||||
string ext = w.substr(pos + 1);
|
||||
string ext_handler;
|
||||
if (configuration.get_ext_handler(ext, ext_handler)) {
|
||||
// we have the handler
|
||||
pos = ext_handler.find("%s");
|
||||
if (pos != string::npos)
|
||||
ext_handler.replace(pos, 2, w);
|
||||
cl->hist->append(w.c_str());
|
||||
cl->hist->sync_the_file();
|
||||
run_the_command(ext_handler.c_str(), g);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME: for now we check only one entry
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
on_compline_activated(GtkCompletionLine *cl, struct gigi *g)
|
||||
{
|
||||
if (url_check(cl, g))
|
||||
return;
|
||||
if (ext_check(cl, g))
|
||||
return;
|
||||
|
||||
string command = g_locale_from_utf8 (gtk_entry_get_text(GTK_ENTRY(cl)),
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
string::size_type i;
|
||||
i = command.find_first_not_of(" \t");
|
||||
|
||||
if (i != string::npos) {
|
||||
string::size_type j = command.find_first_of(" \t", i);
|
||||
string progname = command.substr(i, j - i);
|
||||
list<string> term_progs;
|
||||
if (configuration.get_string_list("AlwaysInTerm", term_progs)) {
|
||||
#ifdef DEBUG
|
||||
cerr << "---" << std::endl;
|
||||
std::copy(term_progs.begin(), term_progs.end(),
|
||||
std::ostream_iterator<string>(cerr, "\n"));
|
||||
cerr << "---" << std::endl;
|
||||
#endif
|
||||
list<string>::const_iterator w =
|
||||
std::find(term_progs.begin(), term_progs.end(), progname);
|
||||
if (w != term_progs.end()) {
|
||||
on_compline_runwithterm(cl, g);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cl->hist->append(command.c_str());
|
||||
cl->hist->sync_the_file();
|
||||
run_the_command(command, g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *compline;
|
||||
GtkWidget *label_search;
|
||||
struct gigi g;
|
||||
|
||||
#ifdef MTRACE
|
||||
mtrace();
|
||||
#endif
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
gtk_widget_realize(dialog);
|
||||
gdk_window_set_decorations(dialog->window, GDK_DECOR_BORDER);
|
||||
gtk_widget_set_name(dialog, "Msh_Run_Window");
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Execute program feat. completion");
|
||||
gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE);
|
||||
// gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(dialog), 4);
|
||||
gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
|
||||
GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
|
||||
|
||||
GtkWidget *hhbox = gtk_hbox_new(FALSE, 2);
|
||||
gtk_widget_show(hhbox);
|
||||
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hhbox, FALSE, FALSE, 0);
|
||||
|
||||
GtkWidget *label = gtk_label_new("Run program:");
|
||||
gtk_widget_show(label);
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 1.0);
|
||||
gtk_misc_set_padding(GTK_MISC(label), 10, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hhbox), label, FALSE, FALSE, 0);
|
||||
|
||||
label_search = gtk_label_new("");
|
||||
gtk_widget_show(label_search);
|
||||
gtk_misc_set_alignment(GTK_MISC(label_search), 1.0, 0.5);
|
||||
gtk_misc_set_padding(GTK_MISC(label_search), 10, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hhbox), label_search, TRUE, TRUE, 0);
|
||||
|
||||
compline = gtk_completion_line_new();
|
||||
gtk_widget_set_name(compline, "Msh_Run_Compline");
|
||||
int prefs_width;
|
||||
if (!configuration.get_int("Width", prefs_width))
|
||||
prefs_width = 500;
|
||||
|
||||
// don't show files starting with "." by default
|
||||
if (!configuration.get_int("ShowDotFiles", GTK_COMPLETION_LINE(compline)->show_dot_files))
|
||||
GTK_COMPLETION_LINE(compline)->show_dot_files = 0;
|
||||
|
||||
{
|
||||
int tmp;
|
||||
if (configuration.get_int("TabTimeout", tmp))
|
||||
((GtkCompletionLine*)compline)->tabtimeout = tmp;
|
||||
}
|
||||
|
||||
g.w1 = label;
|
||||
g.w2 = label_search;
|
||||
|
||||
gtk_widget_set_usize(compline, prefs_width, -2);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "cancel",
|
||||
GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "activate",
|
||||
GTK_SIGNAL_FUNC(on_compline_activated), &g);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "runwithterm",
|
||||
GTK_SIGNAL_FUNC(on_compline_runwithterm), &g);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "unique",
|
||||
GTK_SIGNAL_FUNC(on_compline_unique), &g);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "notunique",
|
||||
GTK_SIGNAL_FUNC(on_compline_notunique), &g);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "incomplete",
|
||||
GTK_SIGNAL_FUNC(on_compline_incomplete), &g);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "search_mode",
|
||||
GTK_SIGNAL_FUNC(on_search_mode), &g);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "search_not_found",
|
||||
GTK_SIGNAL_FUNC(on_search_not_found), &g);
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "search_letter",
|
||||
GTK_SIGNAL_FUNC(on_search_letter), label_search);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(compline), "ext_handler",
|
||||
GTK_SIGNAL_FUNC(on_ext_handler), &g);
|
||||
gtk_widget_show(compline);
|
||||
|
||||
int shows_last_history_item;
|
||||
if (!configuration.get_int("ShowLast", shows_last_history_item)) {
|
||||
shows_last_history_item = 0;
|
||||
}
|
||||
if (shows_last_history_item) {
|
||||
gtk_completion_line_last_history_item(GTK_COMPLETION_LINE(compline));
|
||||
}
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), compline, TRUE, TRUE, 0);
|
||||
|
||||
int prefs_top = 80;
|
||||
int prefs_left = 100;
|
||||
int prefs_centred_by_width = 0;
|
||||
int prefs_centred_by_height = 0;
|
||||
int prefs_use_active_monitor = 0;
|
||||
configuration.get_int("Top", prefs_top);
|
||||
configuration.get_int("Left", prefs_left);
|
||||
configuration.get_int("CenteredByWidth", prefs_centred_by_width);
|
||||
configuration.get_int("CenteredByHeight", prefs_centred_by_height);
|
||||
configuration.get_int("UseActiveMonitor", prefs_use_active_monitor);
|
||||
|
||||
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ALWAYS);
|
||||
|
||||
gtk_widget_show(dialog);
|
||||
|
||||
gtk_window_set_focus(GTK_WINDOW(dialog), compline);
|
||||
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
// Local Variables: ***
|
||||
// mode: c++ ***
|
||||
// c-basic-offset: 2 ***
|
||||
// End: ***
|
13
src/main.h
13
src/main.h
|
@ -1,13 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* $Id: main.h,v 1.2 2001/05/16 14:39:31 mishoo Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
178
src/prefs.cc
178
src/prefs.cc
|
@ -1,178 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* $Id: prefs.cc,v 1.9 2002/08/16 10:48:22 mishoo Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
#define GMRUNRC "gmrunrc"
|
||||
|
||||
using std::ifstream;
|
||||
using std::getline;
|
||||
using std::string;
|
||||
using std::list;
|
||||
|
||||
#include "prefs.h"
|
||||
#include "config.h"
|
||||
|
||||
Prefs configuration;
|
||||
|
||||
Prefs::Prefs()
|
||||
{
|
||||
string file_name = "/etc/";
|
||||
file_name += GMRUNRC;
|
||||
init(file_name);
|
||||
|
||||
file_name = getenv("HOME");
|
||||
if (!file_name.empty()) {
|
||||
string::iterator i = file_name.end() - 1;
|
||||
if (*i == '/') file_name.erase(i);
|
||||
file_name += "/.";
|
||||
file_name += GMRUNRC;
|
||||
init(file_name);
|
||||
}
|
||||
}
|
||||
|
||||
Prefs::~Prefs()
|
||||
{}
|
||||
|
||||
bool Prefs::get_string(const string& key, string& val) const
|
||||
{
|
||||
CONFIG::const_iterator i;
|
||||
i = vals_.find(ci_string(key.c_str()));
|
||||
if (i != vals_.end()) {
|
||||
val = process(i->second);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Prefs::get_ext_handler(const std::string& ext, std::string& val) const
|
||||
{
|
||||
CONFIG::const_iterator i;
|
||||
i = exts_.find(ci_string(ext.c_str()));
|
||||
if (i != exts_.end()) {
|
||||
val = process(i->second);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Prefs::get_int(const std::string& key, int& val) const
|
||||
{
|
||||
string sval;
|
||||
if (get_string(key, sval)) {
|
||||
int ret;
|
||||
if (sscanf(sval.c_str(), "%d", &ret) == 1) {
|
||||
val = ret;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Prefs::init(const string& file_name)
|
||||
{
|
||||
ifstream f(file_name.c_str());
|
||||
|
||||
if (!f.good() || f.eof()) return false;
|
||||
|
||||
while (f.good() && !f.eof()) {
|
||||
string line;
|
||||
char key[0x100];
|
||||
char val[0x100];
|
||||
|
||||
getline(f, line);
|
||||
if (f.eof()) break;
|
||||
string::size_type i = line.find_first_not_of(" \t");
|
||||
if (i == string::npos) continue;
|
||||
if (line[i] == '#') continue;
|
||||
|
||||
sscanf(line.c_str(), "%255[a-zA-Z_0-9:,;] = %255[^\n]", key, val);
|
||||
if (strncmp(key, "EXT:", 4) == 0) {
|
||||
string k(key + 4);
|
||||
size_t i = 0;
|
||||
while (i != string::npos) {
|
||||
string ext;
|
||||
size_t j = k.find(',', i);
|
||||
if (j != string::npos) {
|
||||
ext = k.substr(i, j - i);
|
||||
i = j + 1;
|
||||
} else {
|
||||
ext = k.substr(i);
|
||||
i = string::npos;
|
||||
}
|
||||
if (ext.length() > 0) {
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Extension: " << ext << " - " << val << std::endl;
|
||||
#endif
|
||||
exts_[ext.c_str()] = val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vals_[key] = val;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Key: " << key << ", val: " << vals_[key] << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string Prefs::process(const std::string& cmd) const
|
||||
{
|
||||
string::size_type i = cmd.find("${");
|
||||
string::size_type j = cmd.find("}", i);
|
||||
|
||||
if (i == string::npos || j == string::npos) {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
string val;
|
||||
if (!get_string(cmd.substr(i + 2, j - i - 2), val)) return cmd;
|
||||
string ret(cmd);
|
||||
ret.replace(i, j - i + 1, val);
|
||||
return process(ret);
|
||||
}
|
||||
|
||||
bool Prefs::get_string_list(const string& key, list<string>& val) const
|
||||
{
|
||||
string sval;
|
||||
if (get_string(key, sval)) {
|
||||
const char *q, *p = sval.c_str();
|
||||
for (q = sval.c_str(); *q; ++q) {
|
||||
if (::isspace(*q)) {
|
||||
string s(p, q - p);
|
||||
val.push_back(s);
|
||||
while (*q && ::isspace(*q)) ++q;
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
if (p != q) {
|
||||
string s(p, q - p);
|
||||
val.push_back(s);
|
||||
}
|
||||
return (val.size() > 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
45
src/prefs.h
45
src/prefs.h
|
@ -1,45 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* $Id: prefs.h,v 1.6 2002/08/16 10:30:18 mishoo Exp $
|
||||
* Copyright (C) 2000, Mishoo
|
||||
* Author: Mihai Bazon Email: mishoo@fenrir.infoiasi.ro
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License. You are
|
||||
* free to use/modify/distribute this program as long as you comply to the
|
||||
* terms of the GNU General Public License, version 2 or above, at your
|
||||
* option, and provided that this copyright notice remains intact.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __PREFS_H__
|
||||
#define __PREFS_H__
|
||||
|
||||
#include "ci_string.h"
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
class Prefs
|
||||
{
|
||||
public:
|
||||
typedef std::map<ci_string, std::string> CONFIG;
|
||||
typedef std::pair<ci_string, std::string> PAIR;
|
||||
|
||||
private:
|
||||
CONFIG vals_;
|
||||
CONFIG exts_;
|
||||
|
||||
bool init(const std::string& file_name);
|
||||
string process(const std::string& cmd) const;
|
||||
|
||||
public:
|
||||
Prefs();
|
||||
~Prefs();
|
||||
|
||||
bool get_string(const std::string& key, std::string& val) const;
|
||||
bool get_int(const std::string& key, int& val) const;
|
||||
bool get_string_list(const std::string& ket, std::list<string>& val) const;
|
||||
bool get_ext_handler(const std::string& ext, std::string& val) const;
|
||||
};
|
||||
|
||||
extern Prefs configuration;
|
||||
|
||||
#endif /* __PREFS_H__ */
|
24
zrelease
24
zrelease
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
pkg=gmrun
|
||||
ver=$(grep AC_INIT configure.ac | cut -f 3 -d '[' | cut -f 1 -d ']')
|
||||
|
||||
dir=${pkg}-${ver}
|
||||
|
||||
mkdir -p ../$dir
|
||||
|
||||
cp -rf $PWD/* ../$dir
|
||||
|
||||
(
|
||||
cd ../$dir
|
||||
./autogen.sh
|
||||
rm -rf autom4te.cache
|
||||
#rm -rf m4
|
||||
rm -f make-release
|
||||
)
|
||||
|
||||
cd ..
|
||||
|
||||
tar -Jcf ${dir}.tar.xz $dir
|
||||
|
||||
### END ###
|
Loading…
Reference in New Issue