From b77a83a1c61790596e12b2d626254ec49d54432a Mon Sep 17 00:00:00 2001 From: Mohamad Damaj Date: Sat, 4 Feb 2023 18:31:46 +0200 Subject: [PATCH] First Upload, Welcome to gitea --- README.md | 2 + candybar/LICENSE | 674 ++++ candybar/README.md | 35 + candybar/candybar.sh | 6 + candybar/config.sh | 34 + candybar/modules.sh | 90 + dfmpeg/LICENSE | 21 + dfmpeg/Makefile | 14 + dfmpeg/README.md | 42 + dfmpeg/dfmpeg | 46 + dfmpeg/dfmpegrc | 12 + dfmpeg/patches/dfmpeg-playlast.diff | 36 + dfmpeg/patches/dfmpeg-stop-on-run.diff | 34 + dfmpeg/patches/nodmenu-dfmpeg.diff | 51 + dfmpeg/patches/patch | 2 + dfmpeg/patches/player-dfmpeg.diff | 34 + dmenu/LICENSE | 30 + dmenu/Makefile | 62 + dmenu/README | 24 + dmenu/arg.h | 49 + dmenu/config.def.h | 30 + dmenu/config.mk | 32 + dmenu/dmenu | Bin 0 -> 43008 bytes dmenu/dmenu.1 | 199 ++ dmenu/dmenu.c | 812 +++++ dmenu/dmenu.o | Bin 0 -> 32912 bytes dmenu/dmenu_path | 13 + dmenu/dmenu_run | 2 + dmenu/drw.c | 450 +++ dmenu/drw.h | 58 + dmenu/drw.o | Bin 0 -> 11104 bytes dmenu/patches/patch.diff | 183 ++ dmenu/stest | Bin 0 -> 16488 bytes dmenu/stest.1 | 90 + dmenu/stest.c | 109 + dmenu/stest.o | Bin 0 -> 5312 bytes dmenu/util.c | 36 + dmenu/util.h | 8 + dmenu/util.o | Bin 0 -> 2256 bytes dwm/LICENSE | 38 + dwm/Makefile | 48 + dwm/README | 48 + dwm/config.def.h | 132 + dwm/config.mk | 39 + dwm/drw.c | 450 +++ dwm/drw.h | 58 + dwm/drw.o | Bin 0 -> 11104 bytes dwm/dwm | Bin 0 -> 67624 bytes dwm/dwm.1 | 176 ++ dwm/dwm.c | 2163 +++++++++++++ dwm/dwm.o | Bin 0 -> 58728 bytes dwm/dwm.png | Bin 0 -> 373 bytes dwm/patches/1-rainbowtags.patch | 59 + dwm/patches/2-custom.patch | 74 + dwm/transient.c | 42 + dwm/util.c | 36 + dwm/util.h | 8 + dwm/util.o | Bin 0 -> 2256 bytes pics/22.png | Bin 0 -> 133652 bytes pics/artix.jpg | Bin 0 -> 74965 bytes pics/emerge.jpg | Bin 0 -> 193319 bytes st/FAQ | 250 ++ st/LEGACY | 17 + st/LICENSE | 34 + st/Makefile | 54 + st/README | 34 + st/TODO | 28 + st/arg.h | 50 + st/config.def.h | 483 +++ st/config.mk | 35 + st/patches/st-alpha-0.8.2.diff | 163 + st/patches/st-anysize-0.8.4.diff | 152 + st/patches/st-font2-20190416-ba72400.diff | 17 + .../st-scrollback-20210507-4536f46.diff | 351 +++ .../st-scrollback-mouse-20220127-2c5edf2.diff | 25 + st/st | Bin 0 -> 106000 bytes st/st.1 | 177 ++ st/st.c | 2753 +++++++++++++++++ st/st.h | 130 + st/st.info | 239 ++ st/st.o | Bin 0 -> 81512 bytes st/win.h | 40 + st/x.c | 2120 +++++++++++++ st/x.o | Bin 0 -> 77488 bytes 84 files changed, 13843 insertions(+) create mode 100644 README.md create mode 100644 candybar/LICENSE create mode 100644 candybar/README.md create mode 100755 candybar/candybar.sh create mode 100755 candybar/config.sh create mode 100755 candybar/modules.sh create mode 100644 dfmpeg/LICENSE create mode 100644 dfmpeg/Makefile create mode 100644 dfmpeg/README.md create mode 100755 dfmpeg/dfmpeg create mode 100644 dfmpeg/dfmpegrc create mode 100644 dfmpeg/patches/dfmpeg-playlast.diff create mode 100644 dfmpeg/patches/dfmpeg-stop-on-run.diff create mode 100644 dfmpeg/patches/nodmenu-dfmpeg.diff create mode 100644 dfmpeg/patches/patch create mode 100644 dfmpeg/patches/player-dfmpeg.diff create mode 100644 dmenu/LICENSE create mode 100644 dmenu/Makefile create mode 100644 dmenu/README create mode 100644 dmenu/arg.h create mode 100644 dmenu/config.def.h create mode 100644 dmenu/config.mk create mode 100755 dmenu/dmenu create mode 100644 dmenu/dmenu.1 create mode 100644 dmenu/dmenu.c create mode 100644 dmenu/dmenu.o create mode 100755 dmenu/dmenu_path create mode 100755 dmenu/dmenu_run create mode 100644 dmenu/drw.c create mode 100644 dmenu/drw.h create mode 100644 dmenu/drw.o create mode 100644 dmenu/patches/patch.diff create mode 100755 dmenu/stest create mode 100644 dmenu/stest.1 create mode 100644 dmenu/stest.c create mode 100644 dmenu/stest.o create mode 100644 dmenu/util.c create mode 100644 dmenu/util.h create mode 100644 dmenu/util.o create mode 100644 dwm/LICENSE create mode 100644 dwm/Makefile create mode 100644 dwm/README create mode 100644 dwm/config.def.h create mode 100644 dwm/config.mk create mode 100644 dwm/drw.c create mode 100644 dwm/drw.h create mode 100644 dwm/drw.o create mode 100755 dwm/dwm create mode 100644 dwm/dwm.1 create mode 100644 dwm/dwm.c create mode 100644 dwm/dwm.o create mode 100644 dwm/dwm.png create mode 100644 dwm/patches/1-rainbowtags.patch create mode 100644 dwm/patches/2-custom.patch create mode 100644 dwm/transient.c create mode 100644 dwm/util.c create mode 100644 dwm/util.h create mode 100644 dwm/util.o create mode 100644 pics/22.png create mode 100644 pics/artix.jpg create mode 100644 pics/emerge.jpg create mode 100644 st/FAQ create mode 100644 st/LEGACY create mode 100644 st/LICENSE create mode 100644 st/Makefile create mode 100644 st/README create mode 100644 st/TODO create mode 100644 st/arg.h create mode 100644 st/config.def.h create mode 100644 st/config.mk create mode 100644 st/patches/st-alpha-0.8.2.diff create mode 100644 st/patches/st-anysize-0.8.4.diff create mode 100644 st/patches/st-font2-20190416-ba72400.diff create mode 100644 st/patches/st-scrollback-20210507-4536f46.diff create mode 100644 st/patches/st-scrollback-mouse-20220127-2c5edf2.diff create mode 100755 st/st create mode 100644 st/st.1 create mode 100644 st/st.c create mode 100644 st/st.h create mode 100644 st/st.info create mode 100644 st/st.o create mode 100644 st/win.h create mode 100644 st/x.c create mode 100644 st/x.o diff --git a/README.md b/README.md new file mode 100644 index 0000000..afe5a5e --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Sources +A repo with my configs diff --git a/candybar/LICENSE b/candybar/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/candybar/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +. diff --git a/candybar/README.md b/candybar/README.md new file mode 100644 index 0000000..a7e70e6 --- /dev/null +++ b/candybar/README.md @@ -0,0 +1,35 @@ +# candybar +a stupidly simple modular statusbar + +example output: +``` +MPD: Studio Pixel - Gravity | Up: 18h 45m | RAM: 1.1G/15G | User: jornmann@cowfield | Vol: 69% | Kernel: Linux 5.17.1-gentoo-r1 | Load Avg.: 0.01, 0.05, 0.01 | Weather: +2°C | Date: Fri 2022-04-08 12:46 +``` + +## usage +**candybar** only outputs the text that should be shown on the bar, which makes it useable on different applications. +### usage with dwm +add the following to your ~/.xinitrc: +```sh +while true; do + xsetroot -name "$(candybar)" + sleep 2 +done & +``` +### usage with tmux +add the following to your ~/.tmux.conf: +```tmux +set -g status-interval 2 +set -g status-right-length 100 +set -g status-right "#(candybar)" +``` +### usage with zsh +add the following to your ~/.zshrc: +```zsh +precmd() { + psvar[1]="$(candybar)" +} +export CSI=$'\e'"[" +export PROMPT="${CSI}s${CSI}1;$((LINES-1))r${CSI}$LINES;1f%S%1v%s${CSI}K${CSI}u${PROMPT}" +``` + diff --git a/candybar/candybar.sh b/candybar/candybar.sh new file mode 100755 index 0000000..1ba1b8c --- /dev/null +++ b/candybar/candybar.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# candybar - a stupidly simple statusbar written in shell + +export bar=" " +. "$HOME/.config/candybar/config.sh" +echo "$bar" diff --git a/candybar/config.sh b/candybar/config.sh new file mode 100755 index 0000000..d46e4cd --- /dev/null +++ b/candybar/config.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# candybar configuration + +# modules location +. "$HOME/.config/candybar/modules.sh" + +# network device, needed for upload and download modules +export netdevice="wlan0" + +# mail directory, needed for mail module +export maildir="" + +# module list. uncomment to enable. +# module list. uncomment to enable. +# re-arrange to change order. +# module name icon/prefix suffix +#module_mpc "MPD: " " | " +#module_uptime "Up: " " | " +module_ram "RAM: " " | " +#module_user "User: " " | " +#module_vol "Vol: " "% | " +module_kernel "Kernel: " " | " +module_loadavg "Load Avg.: " " | " +#module_weather "Weather: " " | " +module_du "Disk Usage: " " | " +#module_ip "IP: " " | " +module_cpu "CPU: " " | " +#module_battery "Battery: " " | " +#module_todo "TODO: " " | " +module_upload "Up: " " | " +module_download "Down: " " | " +#module_mail "Mail: " " | " +#module_dfmpeg "Recording!" " | " +module_date "Date: " "" diff --git a/candybar/modules.sh b/candybar/modules.sh new file mode 100755 index 0000000..73de0db --- /dev/null +++ b/candybar/modules.sh @@ -0,0 +1,90 @@ +#!/bin/sh +# candybar modules + +module_date() { + export bar="${bar}${1}$(date +'%a %Y-%m-%d %R')${2}" +} + +module_mpc() { + mpcoutput="$(mpc | grep -v '\[.*\]' | grep -v 'volume:')" + [ "$mpcoutput" = "" ] || export bar="${bar}${1}${mpcoutput}${2}" +} + +module_uptime() { + export bar="${bar}${1}$(uptime -p | sed 's/up // ; s/ year.*/y/ ; s/ week.*,/w/ ; s/ day.*,/d/ ; s/ hour.*,/h/ ; s/ minute.*/m/')${2}" +} + +module_ram() { + export bar="${bar}${1}$(free -h | awk '/^Mem/ { print $3"/"$2 }' | sed s/i//g)${2}" +} + +module_user() { + export bar="${bar}${1}$(whoami)@$(cat /proc/sys/kernel/hostname)${2}" +} + +module_vol_pa() { + export bar="${bar}${1}$(pamixer --get-volume)${2}" +} + +module_vol_alsa() { + export bar="${bar}${1}$(amixer sget Master | awk -F'[][]' '/Mono:/ { print $2 }')${2}" +} + +module_mic_pa() { + export bar="${bar}${1}$(if pamixer --source 1 --get-mute | grep -q 'true'; then echo "OFF"; else echo "ON"; fi)${2}" +} + +module_kernel() { + export bar="${bar}${1}$(sed "s/version // ; s/ (.*//" /proc/version)${2}" +} + +module_loadavg() { + export bar="${bar}${1}$(uptime | sed 's/.*load average: //')${2}" +} + +module_weather() { + export bar="${bar}${1}$(curl -s 'wttr.in/?format=1' | sed 's/.* //')${2}" +} + +module_du() { + export bar="${bar}${1}$(df -T / | awk '{if (NR!=1) {print $6}}')${2}" +} + +module_ip() { + export bar="${bar}${1}$(ip -f inet a | awk '/inet / { print $2 }' | tail -n 1 | sed 's/\/.*//')${2}" +} + +module_cpu() { + # https://github.com/speediegamer/xshbar-plugins/blob/main/cpustatus.plugin + export bar="${bar}${1}$(top -bn1 | grep 'Cpu(s)' | sed 's/.*, *\([0-9.]*\)%* id.*/\1/' | awk '{print 100 - $1"%"}')${2}" +} + +module_battery() { + export bar="${bar}${1}$(cat /sys/class/power_supply/BAT0/capacity)%${2}" +} + +module_todo() { + todooutput="$(head -n 1 ~/.todo.txt)" + [ "$todooutput" = "" ] || export bar="${bar}${1}${todooutput}${2}" +} + +module_upload() { + # https://github.com/speediegamer/xshbar-plugins/blob/main/netstat.plugin + up="$(cat /sys/class/net/${netdevice}/statistics/rx_bytes | awk '{$1=$1/1024000; print $1"B";}' | tail -n 1)" + export bar="${bar}${1}${up}${2}" +} + +module_download() { + # https://github.com/speediegamer/xshbar-plugins/blob/main/netstat.plugin + down="$(cat /sys/class/net/${netdevice}/statistics/tx_bytes | awk '{$1=$1/1024000; print $1"B";}' | tail -n 1)" + export bar="${bar}${1}${down}${2}" +} + +module_mail() { + mailoutput="$(ls ${maildir} | wc -l)" + [ "$mailoutput" = "0" ] || export bar="${bar}${1}${mailoutput}${2}" +} + +module_dfmpeg() { + [ -f "/tmp/dfmpeg-recording" ] && export bar="${bar}${1}${2}" +} diff --git a/dfmpeg/LICENSE b/dfmpeg/LICENSE new file mode 100644 index 0000000..e091500 --- /dev/null +++ b/dfmpeg/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 speedie + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dfmpeg/Makefile b/dfmpeg/Makefile new file mode 100644 index 0000000..09b7281 --- /dev/null +++ b/dfmpeg/Makefile @@ -0,0 +1,14 @@ +SHELL = /bin/sh + +INSTALL_DIR = /usr/bin/ +NAME = dfmpeg + +help: + @echo "make install Install dfmpeg." + @echo "make uninstall Remove dfmpeg." + +install: + cp ${NAME} ${INSTALL_DIR}${NAME} + +uninstall: + rm ${INSTALL_DIR}${NAME} diff --git a/dfmpeg/README.md b/dfmpeg/README.md new file mode 100644 index 0000000..a19a323 --- /dev/null +++ b/dfmpeg/README.md @@ -0,0 +1,42 @@ +# dfmpeg +Dmenu script to record your screen using ffmpeg. + +## Preview +![image](https://user-images.githubusercontent.com/71722170/161388108-fecb715d-8c6b-4fe3-8815-08367e66a3e7.png) + +## Usage +Install the script (see installation) and run it using dmenu. Make sure to edit the config file to match your system. + +## Installation +Download the [script](https://raw.githubusercontent.com/speediegamer/dfmpeg/main/dfmpeg) and save it to /usr/bin, /usr/local/bin, or any other path specified in your shell's $PATH variable. Then chmod +x it to make sure it's executable. + +If /bin/sh isn't an alias then edit the script and change #!/bin/sh to a shell on your Linux system. + +## Notes +- This script IS fully POSIX compliant. +- This script has ffmpeg and dmenu as a dependency +- If you are on Gentoo, enable X, xcb and libdrm USE flags for the ffmpeg package +- Rofi support might become a patch later on. + +## Configuration +NOTE: You do not need to configure it to use it however you should definitely do it if you want to change options. +Create ~/.config/dfmpeg and save [this](https://raw.githubusercontent.com/speediegamer/dfmpeg/main/dfmpegrc) file to ~/.config/dfmpeg/dfmpegrc Now change these variables to what's present on your system: +- DFMPEG_RESOLUTION (set to your screen resolution) +- DFMPEG_AUDIO_DEVICE (set to either alsa or pulse) +- DFMPEG_FRAME_RATE (set to the frame rate you wanna record in) +- DFMPEG_OUTPUT_PATH (set to the path where videos will be saved) +- DFMPEG_OUTPUT_FORMAT (set to the format you wanna record in) +- DFMPEG_DMENU (set to the path to your dmenu binary) +- DFMPEG_TERM (set to the path to your terminal emulator binary) +- DFMPEG_EDITOR (set to an editor on your system such as vim) + +## Credits +- Me +- The awesome people who have contributed + +## Have issues? +Report any issues to the GitHub page Issues. + +## License +This dmenu script is licensed under MIT. +See the "about" or LICENSE file for more information. diff --git a/dfmpeg/dfmpeg b/dfmpeg/dfmpeg new file mode 100755 index 0000000..96a73b7 --- /dev/null +++ b/dfmpeg/dfmpeg @@ -0,0 +1,46 @@ +#!/bin/sh +# dfmpeg +# dmenu gui for recording your screen with ffmpeg +# Licensed under MIT, written by speedie +# https://github.com/speediegamer/dfmpeg + +defaultConfig() { + DFMPEG_DOTDIR="$HOME/.config/dfmpeg" # The directory where dotfiles are + DFMPEG_RESOLUTION="1920x1080" # The resolution to record in + DFMPEG_AUDIO_DEVICE="alsa" # How to capture audio (alsa/pulseaudio) + DFMPEG_FRAME_RATE="60" # Frame rate to capture in. + DFMPEG_RECORD_DEVICE="x11grab" # Probably do not change. + DFMPEG_OUTPUT_PATH="$HOME/Videos" # Path where videos will be saved. + DFMPEG_OUTPUT_FORMAT="mp4" # What format to use + DFMPEG_OUTPUT_FILENAME="$DFMPEG_OUTPUT_PATH/Dfmpeg-Output-$(date +"%d-%d-%y-%T").$DFMPEG_OUTPUT_FORMAT" # File name of the output. Probably don't need to change. + DFMPEG_WH=":0.0" # Width and height, no need to change, defaults should work. + DFMPEG_DMENU="dmenu" # Path to dmenu + DFMPEG_TERM="$TERMINAL" # Terminal to use when editing the configuration file. + DFMPEG_EDITOR="vim" # Editor to edit the config file with +} + +defaultConfig +. "$DFMPEG_DOTDIR"/dfmpegrc +startrec="ffmpeg -f $DFMPEG_RECORD_DEVICE -s $DFMPEG_RESOLUTION -i $DFMPEG_WH -f $DFMPEG_AUDIO_DEVICE -r $DFMPEG_FRAME_RATE -i default $DFMPEG_OUTPUT_FILENAME" +startrec_no_audio="ffmpeg -f $DFMPEG_RECORD_DEVICE -s $DFMPEG_RESOLUTION -r $DFMPEG_FRAME_RATE -i $DFMPEG_WH $DFMPEG_OUTPUT_FILENAME" +stoprec="pkill ffmpeg" +dfmpeg_ver="2022-04-03-r1" +about_screen="dfmpeg $dfmpeg_ver." +about_screen_2="Licensed under MIT, written by speedie + contributors." +about_screen_3="https://github.com/speediegamer/dfmpeg" + +case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout' | dmenu -p 'Record your screen:')" in + "Exit") DFMPEG_STATUS=idle && exit 0 ;; + "Start") DFMPEG_STATUS=recording && touch /tmp/dfmpeg-recording && $startrec && exit 0 ;; + "Stop") $stoprec && rm /tmp/dfmpeg-recording && DFMPEG_STATUS=idle ;; + "Configure") $DFMPEG_TERM $DFMPEG_EDITOR $DFMPEG_DOTDIR/dfmpegrc ;; + "Start-No-Audio") DFMPEG_STATUS=recording && touch /tmp/dfmpeg-recording && $startrec_no_audio && exit 0 ;; + "About") + echo $about_screen > $DFMPEG_DOTDIR/dfmpeg_about + echo $about_screen_2 >> $DFMPEG_DOTDIR/dfmpeg_about + echo $about_screen_3 >> $DFMPEG_DOTDIR/dfmpeg_about + $DFMPEG_TERM $DFMPEG_EDITOR $DFMPEG_DOTDIR/dfmpeg_about + ;; +esac + +exit 0 # This fixes a small bug. diff --git a/dfmpeg/dfmpegrc b/dfmpeg/dfmpegrc new file mode 100644 index 0000000..16a74aa --- /dev/null +++ b/dfmpeg/dfmpegrc @@ -0,0 +1,12 @@ +DFMPEG_DOTDIR=~/.config/dfmpeg # The directory where dotfiles are +DFMPEG_RESOLUTION=1920x1080 # The resolution to record in +DFMPEG_AUDIO_DEVICE=alsa # How to capture audio (alsa/pulseaudio) +DFMPEG_FRAME_RATE=60 # Frame rate to capture in. +DFMPEG_RECORD_DEVICE=x11grab # Probably do not change. +DFMPEG_OUTPUT_PATH=~/Videos # Path where videos will be saved. +DFMPEG_OUTPUT_FORMAT=mp4 # What format to use +DFMPEG_OUTPUT_FILENAME=$DFMPEG_OUTPUT_PATH/Dfmpeg-Output-$(date +"%d-%d-%y-%T").$DFMPEG_OUTPUT_FORMAT # File name of the output. Probably don't need to change. +DFMPEG_WH=:0.0 # Width and height, no need to change, defaults should work. +DFMPEG_DMENU=dmenu # Path to dmenu +DFMPEG_TERM=$TERMINAL # Terminal to use when editing the configuration file. +DFMPEG_EDITOR=vim # Editor to edit the config file with diff --git a/dfmpeg/patches/dfmpeg-playlast.diff b/dfmpeg/patches/dfmpeg-playlast.diff new file mode 100644 index 0000000..c175ddd --- /dev/null +++ b/dfmpeg/patches/dfmpeg-playlast.diff @@ -0,0 +1,36 @@ +diff -up dfmpeg-vanilla/dfmpeg dfmpeg-patch/dfmpeg +--- dfmpeg-vanilla/dfmpeg 2022-04-10 11:56:41.414021739 +0200 ++++ dfmpeg-patch/dfmpeg 2022-04-11 02:40:28.898682361 +0200 +@@ -17,6 +17,7 @@ defaultConfig() { + DFMPEG_DMENU="dmenu" # Path to dmenu + DFMPEG_TERM="$TERMINAL" # Terminal to use when editing the configuration file. + DFMPEG_EDITOR="vim" # Editor to edit the config file with ++ DFMPEG_MEDIA_PLAYER=mpv # Media player to play videos in + } + + defaultConfig +@@ -29,12 +30,13 @@ about_screen="dfmpeg $dfmpeg_ver." + about_screen_2="Licensed under MIT, written by speedie + contributors." + about_screen_3="https://github.com/speediegamer/dfmpeg" + +-case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout' | dmenu -p 'Record your screen:')" in ++case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout\nPlayLast' | dmenu -p 'Record your screen:')" in + "Exit") DFMPEG_STATUS=idle && exit 0 ;; +- "Start") DFMPEG_STATUS=recording && touch /tmp/dfmpeg-recording && $startrec && exit 0 ;; ++ "Start") DFMPEG_STATUS=recording && touch /tmp/dfmpeg-recording && echo $DFMPEG_OUTPUT_FILENAME > /tmp/dfmpeg-filename && $startrec && exit 0 ;; + "Stop") $stoprec && rm /tmp/dfmpeg-recording && DFMPEG_STATUS=idle ;; + "Configure") $DFMPEG_TERM $DFMPEG_EDITOR $DFMPEG_DOTDIR/dfmpegrc ;; +- "Start-No-Audio") DFMPEG_STATUS=recording && $startrec_no_audio && exit 0 ;; ++ "Start-No-Audio") DFMPEG_STATUS=recording && touch /tmp/dfmpeg-recording && echo $DFMPEG_OUTPUT_FILENAME > /tmp/dfmpeg-filename && $startrec_no_audio && exit 0 ;; ++ "PlayLast") DFMPEG_STATUS=idle && $DFMPEG_MEDIA_PLAYER $(cat /tmp/dfmpeg-filename) && exit 0 ;; + "About") + echo $about_screen > $DFMPEG_DOTDIR/dfmpeg_about + echo $about_screen_2 >> $DFMPEG_DOTDIR/dfmpeg_about +diff -up dfmpeg-vanilla/dfmpegrc dfmpeg-patch/dfmpegrc +--- dfmpeg-vanilla/dfmpegrc 2022-04-10 11:56:50.093022166 +0200 ++++ dfmpeg-patch/dfmpegrc 2022-04-11 02:41:13.184684370 +0200 +@@ -10,3 +10,4 @@ DFMPEG_WH=:0.0 # Width and height, no ne + DFMPEG_DMENU=dmenu # Path to dmenu + DFMPEG_TERM=$TERMINAL # Terminal to use when editing the configuration file. + DFMPEG_EDITOR=vim # Editor to edit the config file with ++DFMPEG_MEDIA_PLAYER=mpv # Media player to play videos in diff --git a/dfmpeg/patches/dfmpeg-stop-on-run.diff b/dfmpeg/patches/dfmpeg-stop-on-run.diff new file mode 100644 index 0000000..5594b84 --- /dev/null +++ b/dfmpeg/patches/dfmpeg-stop-on-run.diff @@ -0,0 +1,34 @@ +diff -up dfmpeg-vanilla/dfmpeg dfmpeg-patch/dfmpeg +--- dfmpeg-vanilla/dfmpeg 2022-04-10 11:56:41.414021739 +0200 ++++ dfmpeg-patch/dfmpeg 2022-04-10 11:57:10.317023160 +0200 +@@ -17,6 +17,7 @@ defaultConfig() { + DFMPEG_DMENU="dmenu" # Path to dmenu + DFMPEG_TERM="$TERMINAL" # Terminal to use when editing the configuration file. + DFMPEG_EDITOR="vim" # Editor to edit the config file with ++ DFMPEG_STOP_ON_RUN=false # Stop recording once dfmpeg is loaded if it's already recording + } + + defaultConfig +@@ -29,6 +30,10 @@ about_screen="dfmpeg $dfmpeg_ver." + about_screen_2="Licensed under MIT, written by speedie + contributors." + about_screen_3="https://github.com/speediegamer/dfmpeg" + ++case "$DFMPEG_STOP_ON_RUN" in ++ "true") ls /tmp/dfmpeg-recording && $stoprec && DFMPEG_STATUS=idle && rm /tmp/dfmpeg-recording && exit 0 ;; ++esac ++ + case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout' | dmenu -p 'Record your screen:')" in + "Exit") DFMPEG_STATUS=idle && exit 0 ;; + "Start") DFMPEG_STATUS=recording && touch /tmp/dfmpeg-recording && $startrec && exit 0 ;; +@@ -43,4 +48,4 @@ case "$(printf 'Start\nStop\nStart-No-Au + ;; + esac + +diff -up dfmpeg-vanilla/dfmpegrc dfmpeg-patch/dfmpegrc +--- dfmpeg-vanilla/dfmpegrc 2022-04-10 11:56:50.093022166 +0200 ++++ dfmpeg-patch/dfmpegrc 2022-04-10 11:58:12.963026238 +0200 +@@ -10,3 +10,4 @@ DFMPEG_WH=:0.0 # Width and height, no ne + DFMPEG_DMENU=dmenu # Path to dmenu + DFMPEG_TERM=$TERMINAL # Terminal to use when editing the configuration file. + DFMPEG_EDITOR=vim # Editor to edit the config file with ++DFMPEG_STOP_ON_RUN=false # Stop recording when dfmpeg is loaded if its recording diff --git a/dfmpeg/patches/nodmenu-dfmpeg.diff b/dfmpeg/patches/nodmenu-dfmpeg.diff new file mode 100644 index 0000000..92babeb --- /dev/null +++ b/dfmpeg/patches/nodmenu-dfmpeg.diff @@ -0,0 +1,51 @@ +diff -up dfmpeg-vanilla/dfmpeg dfmpeg-patch/dfmpeg +--- dfmpeg-vanilla/dfmpeg 2022-04-03 14:45:55.259169925 +0200 ++++ dfmpeg-patch/dfmpeg 2022-04-03 14:45:07.438172998 +0200 +@@ -17,6 +17,7 @@ defaultConfig() { + DFMPEG_DMENU="dmenu" # Path to dmenu + DFMPEG_TERM="$TERMINAL" # Terminal to use when editing the configuration file. + DFMPEG_EDITOR="vim" # Editor to edit the config file with ++ DFMPEG_USE_DMENU=false # Use dmenu + } + + defaultConfig +@@ -29,6 +30,31 @@ about_screen="dfmpeg $dfmpeg_ver." + about_screen_2="Licensed under MIT, written by speedie + contributors." + about_screen_3="https://github.com/speediegamer/dfmpeg" + ++case "$DFMPEG_USE_DMENU" in ++ "true") DFMPEG_USE_DMENU=false ;; ++ "false") ++ clear && echo "dfmpeg $dfmpeg_ver" ++ echo "What do you wanna do? Run :help if you need help." ++ echo ":q to quit." ++ echo -n ">" && read DFMPEG_ACTION ++ ;; ++esac ++ ++case "$DFMPEG_ACTION" in ++ ":q") exit 0 ;; ++ ":help") echo -e ":q // Quit\n:help // Display this help screen\n:r // Record with sound\n:rn // Record without sound\n:s // Stop recording\n:c // Open the config file in the defined text editor\n:a // Display the about screen" ;; ++ ":r") $startrec && ${0} && exit 0 ;; ++ ":rn") $startrec_no_audio && ${0} && exit 0 ;; ++ ":s") $stoprec && ${0} && exit 0 ;; ++ ":c") $DFMPEG_TERM $DFMPEG_EDITOR $DFMPEG_DOTDIR/dfmpegrc && ${0} && exit 0 ;; ++ ":a") $DFMPEG_TERM $DFMPEG_EDITOR $DFMPEG_DOTDIR/dfmpeg_about && ${0} && exit 0 ;; ++esac ++ ++case "$DFMPEG_USE_DMENU" in ++ "false") DFMPEG_ACTION=:help && exit 0 ++esac ++ ++# Only do this if DMENU is enabled. + case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout' | dmenu -p 'Record your screen:')" in + "Exit") DFMPEG_STATUS=idle && exit 0 ;; + "Start") DFMPEG_STATUS=recording && $startrec && exit 0 ;; +diff -up dfmpeg-vanilla/dfmpegrc dfmpeg-patch/dfmpegrc +--- dfmpeg-vanilla/dfmpegrc 2022-04-03 14:45:53.344170048 +0200 ++++ dfmpeg-patch/dfmpegrc 2022-04-03 14:23:24.205256743 +0200 +@@ -10,3 +10,4 @@ DFMPEG_WH=:0.0 # Width and height, no ne + DFMPEG_DMENU=dmenu # Path to dmenu + DFMPEG_TERM=$TERMINAL # Terminal to use when editing the configuration file. + DFMPEG_EDITOR=vim # Editor to edit the config file with ++DFMPEG_USE_DMENU=false # Use dmenu diff --git a/dfmpeg/patches/patch b/dfmpeg/patches/patch new file mode 100644 index 0000000..79b4c77 --- /dev/null +++ b/dfmpeg/patches/patch @@ -0,0 +1,2 @@ +This is the directory where patches are stored. +Feel free to submit patches. diff --git a/dfmpeg/patches/player-dfmpeg.diff b/dfmpeg/patches/player-dfmpeg.diff new file mode 100644 index 0000000..501a1f4 --- /dev/null +++ b/dfmpeg/patches/player-dfmpeg.diff @@ -0,0 +1,34 @@ +diff -up dfmpeg-vanilla/dfmpeg dfmpeg-patch/dfmpeg +--- dfmpeg-vanilla/dfmpeg 2022-04-03 00:24:23.548491608 +0200 ++++ dfmpeg-patch/dfmpeg 2022-04-03 00:24:30.992491129 +0200 +@@ -17,6 +17,7 @@ defaultConfig() { + DFMPEG_DMENU="dmenu" # Path to dmenu + DFMPEG_TERM="$TERMINAL" # Terminal to use when editing the configuration file. + DFMPEG_EDITOR="vim" # Editor to edit the config file with ++ DFMPEG_PLAYER="mpv" # Player to use + } + + defaultConfig +@@ -29,12 +30,13 @@ about_screen="dfmpeg $dfmpeg_ver." + about_screen_2="Licensed under MIT, written by speedie + contributors." + about_screen_3="https://github.com/speediegamer/dfmpeg" + +-case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout' | dmenu -p 'Record your screen:')" in ++case "$(printf 'Start\nStop\nStart-No-Audio\nConfigure\nExit\nAbout\nPlay' | dmenu -p 'Record your screen:')" in + "Exit") DFMPEG_STATUS=idle && exit 0 ;; + "Start") DFMPEG_STATUS=recording && $startrec && exit 0 ;; + "Stop") $stoprec && DFMPEG_STATUS=idle ;; + "Configure") $DFMPEG_TERM $DFMPEG_EDITOR $DFMPEG_DOTDIR/dfmpegrc ;; + "Start-No-Audio") DFMPEG_STATUS=recording && $startrec_no_audio && exit 0 ;; ++ "Play") DFMPEG_PLAY=$(ls -A --color=auto $DFMPEG_OUTPUT_PATH | dmenu) && $DFMPEG_PLAYER $DFMPEG_OUTPUT_PATH/$DFMPEG_PLAY && exit 0 ;; + "About") + echo $about_screen > $DFMPEG_DOTDIR/dfmpeg_about + echo $about_screen_2 >> $DFMPEG_DOTDIR/dfmpeg_about +diff -up dfmpeg-vanilla/dfmpegrc dfmpeg-patch/dfmpegrc +--- dfmpeg-vanilla/dfmpegrc 2022-04-03 00:25:16.410488211 +0200 ++++ dfmpeg-patch/dfmpegrc 2022-04-03 00:24:57.511489425 +0200 +@@ -10,3 +10,4 @@ DFMPEG_WH=:0.0 # Width and height, no ne + DFMPEG_DMENU=dmenu # Path to dmenu + DFMPEG_TERM=st # Terminal to use when editing the configuration file. + DFMPEG_EDITOR=vim # Editor to edit the config file with ++DFMPEG_PLAYER=mpv # Player to play videos in diff --git a/dmenu/LICENSE b/dmenu/LICENSE new file mode 100644 index 0000000..2a64b28 --- /dev/null +++ b/dmenu/LICENSE @@ -0,0 +1,30 @@ +MIT/X Consortium License + +© 2006-2019 Anselm R Garbe +© 2006-2008 Sander van Dijk +© 2006-2007 Michał Janeczek +© 2007 Kris Maglione +© 2009 Gottox +© 2009 Markus Schnalke +© 2009 Evan Gates +© 2010-2012 Connor Lane Smith +© 2014-2022 Hiltjo Posthuma +© 2015-2019 Quentin Rameau + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/dmenu/Makefile b/dmenu/Makefile new file mode 100644 index 0000000..3d041d2 --- /dev/null +++ b/dmenu/Makefile @@ -0,0 +1,62 @@ +# dmenu - dynamic menu +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = drw.c dmenu.c stest.c util.c +OBJ = $(SRC:.c=.o) + +all: options dmenu stest + +options: + @echo dmenu build options: + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "CC = $(CC)" + +.c.o: + $(CC) -c $(CFLAGS) $< + + +$(OBJ): arg.h config.mk drw.h + +dmenu: dmenu.o drw.o util.o + $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) + +stest: stest.o + $(CC) -o $@ stest.o $(LDFLAGS) + +clean: + rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz + +dist: clean + mkdir -p dmenu-$(VERSION) + cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ + drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ + dmenu-$(VERSION) + tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) + gzip dmenu-$(VERSION).tar + rm -rf dmenu-$(VERSION) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run + chmod 755 $(DESTDIR)$(PREFIX)/bin/stest + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ + $(DESTDIR)$(PREFIX)/bin/dmenu_path\ + $(DESTDIR)$(PREFIX)/bin/dmenu_run\ + $(DESTDIR)$(PREFIX)/bin/stest\ + $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ + $(DESTDIR)$(MANPREFIX)/man1/stest.1 + +.PHONY: all options clean dist install uninstall diff --git a/dmenu/README b/dmenu/README new file mode 100644 index 0000000..a8fcdfe --- /dev/null +++ b/dmenu/README @@ -0,0 +1,24 @@ +dmenu - dynamic menu +==================== +dmenu is an efficient dynamic menu for X. + + +Requirements +------------ +In order to build dmenu you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (dmenu is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install dmenu +(if necessary as root): + + make clean install + + +Running dmenu +------------- +See the man page for details. diff --git a/dmenu/arg.h b/dmenu/arg.h new file mode 100644 index 0000000..e94e02b --- /dev/null +++ b/dmenu/arg.h @@ -0,0 +1,49 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/dmenu/config.def.h b/dmenu/config.def.h new file mode 100644 index 0000000..ed9b684 --- /dev/null +++ b/dmenu/config.def.h @@ -0,0 +1,30 @@ +/* See LICENSE file for copyright and license details. */ +/* Default settings; can be overriden by command line. */ + +static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +static int colorprompt = 1; /* -p option; if 1, prompt uses SchemeSel, otherwise SchemeNorm */ +/* -fn option overrides fonts[0]; default X11 font or font set */ +static const char *fonts[] = { + "Terminus:size=9" +}; +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#666666", "#1f2024" }, + [SchemeSel] = { "#f8f9f8", "#1f2024" }, + [SchemeOut] = { "#1f2024", "#f8f9f8" }, +}; +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 25; +/* -h option; minimum height of a menu line */ +static unsigned int lineheight = 0; +static unsigned int min_lineheight = 25; + +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; + +/* Size of the window border */ +static const unsigned int border_width = 1; diff --git a/dmenu/config.mk b/dmenu/config.mk new file mode 100644 index 0000000..566348b --- /dev/null +++ b/dmenu/config.mk @@ -0,0 +1,32 @@ +# dmenu version +VERSION = 5.2 + +# paths +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +# Xinerama, comment if you don't want it +XINERAMALIBS = -lXinerama +XINERAMAFLAGS = -DXINERAMA + +# freetype +FREETYPELIBS = -lfontconfig -lXft +FREETYPEINC = /usr/include/freetype2 +# OpenBSD (uncomment) +#FREETYPEINC = $(X11INC)/freetype2 +#MANPREFIX = ${PREFIX}/man + +# includes and libs +INCS = -I$(X11INC) -I$(FREETYPEINC) +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) + +# flags +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) +CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) +LDFLAGS = $(LIBS) + +# compiler and linker +CC = cc diff --git a/dmenu/dmenu b/dmenu/dmenu new file mode 100755 index 0000000000000000000000000000000000000000..dd667c1306d7a3f8310420bd6f29af5432ec5434 GIT binary patch literal 43008 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 literal 0 HcmV?d00001 diff --git a/dmenu/dmenu.1 b/dmenu/dmenu.1 new file mode 100644 index 0000000..f2a82b4 --- /dev/null +++ b/dmenu/dmenu.1 @@ -0,0 +1,199 @@ +.TH DMENU 1 dmenu\-VERSION +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-bfiv ] +.RB [ \-l +.IR lines ] +.RB [ \-h +.IR height ] +.RB [ \-m +.IR monitor ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] +.RB [ \-w +.IR windowid ] +.P +.BR dmenu_run " ..." +.SH DESCRIPTION +.B dmenu +is a dynamic menu for X, which reads a list of newline\-separated items from +stdin. When the user selects an item and presses Return, their choice is printed +to stdout and dmenu terminates. Entering text will narrow the items to those +matching the tokens in the input. +.P +.B dmenu_run +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and runs the result in their $SHELL. +.SH OPTIONS +.TP +.B \-b +dmenu appears at the bottom of the screen. +.TP +.B \-f +dmenu grabs the keyboard before reading stdin if not reading from a tty. This +is faster, but will lock up X until stdin reaches end\-of\-file. +.TP +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-l " lines" +dmenu lists items vertically, with the given number of lines. +.TP +.BI \-h " height" +dmenu uses a menu line of at least 'height' pixels tall, but no less than 8. +.TP +.BI \-m " monitor" +dmenu is displayed on the monitor number supplied. Monitor numbers are starting +from 0. +.TP +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input field. +.TP +.BI \-fn " font" +defines the font or font set used. +.TP +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and X color names are supported. +.TP +.BI \-nf " color" +defines the normal foreground color. +.TP +.BI \-sb " color" +defines the selected background color. +.TP +.BI \-sf " color" +defines the selected foreground color. +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-w " windowid" +embed into windowid. +.SH USAGE +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. +.TP +.B Tab +Copy the selected item to the input field. +.TP +.B Return +Confirm selection. Prints the selected item to stdout and exits, returning +success. +.TP +.B Ctrl-Return +Confirm selection. Prints the selected item to stdout and continues. +.TP +.B Shift\-Return +Confirm input. Prints the input text to stdout and exits, returning success. +.TP +.B Escape +Exit without selecting an item, returning failure. +.TP +.B Ctrl-Left +Move cursor to the start of the current word +.TP +.B Ctrl-Right +Move cursor to the end of the current word +.TP +.B C\-a +Home +.TP +.B C\-b +Left +.TP +.B C\-c +Escape +.TP +.B C\-d +Delete +.TP +.B C\-e +End +.TP +.B C\-f +Right +.TP +.B C\-g +Escape +.TP +.B C\-h +Backspace +.TP +.B C\-i +Tab +.TP +.B C\-j +Return +.TP +.B C\-J +Shift-Return +.TP +.B C\-k +Delete line right +.TP +.B C\-m +Return +.TP +.B C\-M +Shift-Return +.TP +.B C\-n +Down +.TP +.B C\-p +Up +.TP +.B C\-u +Delete line left +.TP +.B C\-w +Delete word left +.TP +.B C\-y +Paste from primary X selection +.TP +.B C\-Y +Paste from X clipboard +.TP +.B M\-b +Move cursor to the start of the current word +.TP +.B M\-f +Move cursor to the end of the current word +.TP +.B M\-g +Home +.TP +.B M\-G +End +.TP +.B M\-h +Up +.TP +.B M\-j +Page down +.TP +.B M\-k +Page up +.TP +.B M\-l +Down +.SH SEE ALSO +.IR dwm (1), +.IR stest (1) diff --git a/dmenu/dmenu.c b/dmenu/dmenu.c new file mode 100644 index 0000000..9196cc0 --- /dev/null +++ b/dmenu/dmenu.c @@ -0,0 +1,812 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef XINERAMA +#include +#endif +#include + +#include "drw.h" +#include "util.h" + +/* macros */ +#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + +/* enums */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + +struct item { + char *text; + struct item *left, *right; + int out; +}; + +static char text[BUFSIZ] = ""; +static char *embed; +static int bh, mw, mh; +static int inputw = 0, promptw; +static int lrpad; /* sum of left and right padding */ +static size_t cursor; +static struct item *items = NULL; +static struct item *matches, *matchend; +static struct item *prev, *curr, *next, *sel; +static int mon = -1, screen; + +static Atom clip, utf8; +static Display *dpy; +static Window root, parentwin, win; +static XIC xic; + +static Drw *drw; +static Clr *scheme[SchemeLast]; + +#include "config.def.h" + +static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; + +static unsigned int +textw_clamp(const char *str, unsigned int n) +{ + unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad; + return MIN(w, n); +} + +static void +appenditem(struct item *item, struct item **list, struct item **last) +{ + if (*last) + (*last)->right = item; + else + *list = item; + + item->left = *last; + item->right = NULL; + *last = item; +} + +static void +calcoffsets(void) +{ + int i, n; + + if (lines > 0) + n = lines * bh; + else + n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); + /* calculate which items will begin the next page and previous page */ + for (i = 0, next = curr; next; next = next->right) + if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n) + break; + for (i = 0, prev = curr; prev && prev->left; prev = prev->left) + if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n) + break; +} + +static int +max_textw(void) +{ + int len = 0; + for (struct item *item = items; item && item->text; item++) + len = MAX(TEXTW(item->text), len); + return len; +} + +static void +cleanup(void) +{ + size_t i; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); + for (i = 0; items && items[i].text; ++i) + free(items[i].text); + free(items); + drw_free(drw); + XSync(dpy, False); + XCloseDisplay(dpy); +} + +static char * +cistrstr(const char *h, const char *n) +{ + size_t i; + + if (!n[0]) + return (char *)h; + + for (; *h; ++h) { + for (i = 0; n[i] && tolower((unsigned char)n[i]) == + tolower((unsigned char)h[i]); ++i) + ; + if (n[i] == '\0') + return (char *)h; + } + return NULL; +} + +static int +drawitem(struct item *item, int x, int y, int w) +{ + if (item == sel) + drw_setscheme(drw, scheme[SchemeSel]); + else if (item->out) + drw_setscheme(drw, scheme[SchemeOut]); + else + drw_setscheme(drw, scheme[SchemeNorm]); + + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); +} + +static void +drawmenu(void) +{ + unsigned int curpos; + struct item *item; + int x = 0, y = 0, fh = drw->fonts->h, w; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); + + if (prompt && *prompt) { + if (colorprompt) + drw_setscheme(drw, scheme[SchemeSel]); + x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); + } + /* draw input field */ + w = (lines > 0 || !matches) ? mw - x : inputw; + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); + + curpos = TEXTW(text) - TEXTW(&text[cursor]); + if ((curpos += lrpad / 2 - 1) < w) { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0); + } + + if (lines > 0) { + /* draw vertical list */ + for (item = curr; item != next; item = item->right) + drawitem(item, 0, y += bh, mw - x); + } else if (matches) { + /* draw horizontal list */ + x += inputw; + w = TEXTW("<"); + if (curr->left) { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); + } + x += w; + for (item = curr; item != next; item = item->right) + x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); + if (next) { + w = TEXTW(">"); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); + } + } + drw_map(drw, win, 0, 0, mw, mh); +} + +static void +grabfocus(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; + Window focuswin; + int i, revertwin; + + for (i = 0; i < 100; ++i) { + XGetInputFocus(dpy, &focuswin, &revertwin); + if (focuswin == win) + return; + XSetInputFocus(dpy, win, RevertToParent, CurrentTime); + nanosleep(&ts, NULL); + } + die("cannot grab focus"); +} + +static void +grabkeyboard(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; + int i; + + if (embed) + return; + /* try to grab keyboard, we may have to wait for another process to ungrab */ + for (i = 0; i < 1000; i++) { + if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, + GrabModeAsync, CurrentTime) == GrabSuccess) + return; + nanosleep(&ts, NULL); + } + die("cannot grab keyboard"); +} + +static void +match(void) +{ + static char **tokv = NULL; + static int tokn = 0; + + char buf[sizeof text], *s; + int i, tokc = 0; + size_t len, textsize; + struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; + + strcpy(buf, text); + /* separate input text into tokens to be matched individually */ + for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) + if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) + die("cannot realloc %zu bytes:", tokn * sizeof *tokv); + len = tokc ? strlen(tokv[0]) : 0; + + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + textsize = strlen(text) + 1; + for (item = items; item && item->text; item++) { + for (i = 0; i < tokc; i++) + if (!fstrstr(item->text, tokv[i])) + break; + if (i != tokc) /* not all tokens match */ + continue; + /* exact matches go first, then prefixes, then substrings */ + if (!tokc || !fstrncmp(text, item->text, textsize)) + appenditem(item, &matches, &matchend); + else if (!fstrncmp(tokv[0], item->text, len)) + appenditem(item, &lprefix, &prefixend); + else + appenditem(item, &lsubstr, &substrend); + } + if (lprefix) { + if (matches) { + matchend->right = lprefix; + lprefix->left = matchend; + } else + matches = lprefix; + matchend = prefixend; + } + if (lsubstr) { + if (matches) { + matchend->right = lsubstr; + lsubstr->left = matchend; + } else + matches = lsubstr; + matchend = substrend; + } + curr = sel = matches; + calcoffsets(); +} + +static void +insert(const char *str, ssize_t n) +{ + if (strlen(text) + n > sizeof text - 1) + return; + /* move existing text out of the way, insert new text, and update cursor */ + memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); + if (n > 0) + memcpy(&text[cursor], str, n); + cursor += n; + match(); +} + +static size_t +nextrune(int inc) +{ + ssize_t n; + + /* return location of next utf8 rune in the given direction (+1 or -1) */ + for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) + ; + return n; +} + +static void +movewordedge(int dir) +{ + if (dir < 0) { /* move cursor to the start of the word*/ + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + } else { /* move cursor to the end of the word */ + while (text[cursor] && strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + while (text[cursor] && !strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + } +} + +static void +keypress(XKeyEvent *ev) +{ + char buf[64]; + int len; + KeySym ksym = NoSymbol; + Status status; + + len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); + switch (status) { + default: /* XLookupNone, XBufferOverflow */ + return; + case XLookupChars: /* composed string from input method */ + goto insert; + case XLookupKeySym: + case XLookupBoth: /* a KeySym and a string are returned: use keysym */ + break; + } + + if (ev->state & ControlMask) { + switch(ksym) { + case XK_a: ksym = XK_Home; break; + case XK_b: ksym = XK_Left; break; + case XK_c: ksym = XK_Escape; break; + case XK_d: ksym = XK_Delete; break; + case XK_e: ksym = XK_End; break; + case XK_f: ksym = XK_Right; break; + case XK_g: ksym = XK_Escape; break; + case XK_h: ksym = XK_BackSpace; break; + case XK_i: ksym = XK_Tab; break; + case XK_j: /* fallthrough */ + case XK_J: /* fallthrough */ + case XK_m: /* fallthrough */ + case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; + case XK_n: ksym = XK_Down; break; + case XK_p: ksym = XK_Up; break; + + case XK_k: /* delete right */ + text[cursor] = '\0'; + match(); + break; + case XK_u: /* delete left */ + insert(NULL, 0 - cursor); + break; + case XK_w: /* delete word */ + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) + insert(NULL, nextrune(-1) - cursor); + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) + insert(NULL, nextrune(-1) - cursor); + break; + case XK_y: /* paste selection */ + case XK_Y: + XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, + utf8, utf8, win, CurrentTime); + return; + case XK_Left: + case XK_KP_Left: + movewordedge(-1); + goto draw; + case XK_Right: + case XK_KP_Right: + movewordedge(+1); + goto draw; + case XK_Return: + case XK_KP_Enter: + break; + case XK_bracketleft: + cleanup(); + exit(1); + default: + return; + } + } else if (ev->state & Mod1Mask) { + switch(ksym) { + case XK_b: + movewordedge(-1); + goto draw; + case XK_f: + movewordedge(+1); + goto draw; + case XK_g: ksym = XK_Home; break; + case XK_G: ksym = XK_End; break; + case XK_h: ksym = XK_Up; break; + case XK_j: ksym = XK_Next; break; + case XK_k: ksym = XK_Prior; break; + case XK_l: ksym = XK_Down; break; + default: + return; + } + } + + switch(ksym) { + default: +insert: + if (!iscntrl((unsigned char)*buf)) + insert(buf, len); + break; + case XK_Delete: + case XK_KP_Delete: + if (text[cursor] == '\0') + return; + cursor = nextrune(+1); + /* fallthrough */ + case XK_BackSpace: + if (cursor == 0) + return; + insert(NULL, nextrune(-1) - cursor); + break; + case XK_End: + case XK_KP_End: + if (text[cursor] != '\0') { + cursor = strlen(text); + break; + } + if (next) { + /* jump to end of list and position items in reverse */ + curr = matchend; + calcoffsets(); + curr = prev; + calcoffsets(); + while (next && (curr = curr->right)) + calcoffsets(); + } + sel = matchend; + break; + case XK_Escape: + cleanup(); + exit(1); + case XK_Home: + case XK_KP_Home: + if (sel == matches) { + cursor = 0; + break; + } + sel = curr = matches; + calcoffsets(); + break; + case XK_Left: + case XK_KP_Left: + if (cursor > 0 && (!sel || !sel->left || lines > 0)) { + cursor = nextrune(-1); + break; + } + if (lines > 0) + return; + /* fallthrough */ + case XK_Up: + case XK_KP_Up: + if (sel && sel->left && (sel = sel->left)->right == curr) { + curr = prev; + calcoffsets(); + } + break; + case XK_Next: + case XK_KP_Next: + if (!next) + return; + sel = curr = next; + calcoffsets(); + break; + case XK_Prior: + case XK_KP_Prior: + if (!prev) + return; + sel = curr = prev; + calcoffsets(); + break; + case XK_Return: + case XK_KP_Enter: + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); + if (!(ev->state & ControlMask)) { + cleanup(); + exit(0); + } + if (sel) + sel->out = 1; + break; + case XK_Right: + case XK_KP_Right: + if (text[cursor] != '\0') { + cursor = nextrune(+1); + break; + } + if (lines > 0) + return; + /* fallthrough */ + case XK_Down: + case XK_KP_Down: + if (sel && sel->right && (sel = sel->right) == next) { + curr = next; + calcoffsets(); + } + break; + case XK_Tab: + if (!sel) + return; + cursor = strnlen(sel->text, sizeof text - 1); + memcpy(text, sel->text, cursor); + text[cursor] = '\0'; + match(); + break; + } + +draw: + drawmenu(); +} + +static void +paste(void) +{ + char *p, *q; + int di; + unsigned long dl; + Atom da; + + /* we have been given the current selection, now insert it into input */ + if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p) + == Success && p) { + insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); + XFree(p); + } + drawmenu(); +} + +static void +readstdin(void) +{ + char *line = NULL; + size_t i, junk, itemsiz = 0; + ssize_t len; + + /* read each line from stdin and add it to the item list */ + for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) { + if (i + 1 >= itemsiz) { + itemsiz += 256; + if (!(items = realloc(items, itemsiz * sizeof(*items)))) + die("cannot realloc %zu bytes:", itemsiz * sizeof(*items)); + } + if (line[len - 1] == '\n') + line[len - 1] = '\0'; + items[i].text = line; + items[i].out = 0; + line = NULL; /* next call of getline() allocates a new line */ + } + free(line); + if (items) + items[i].text = NULL; + lines = MIN(lines, i); +} + +static void +run(void) +{ + XEvent ev; + + while (!XNextEvent(dpy, &ev)) { + if (XFilterEvent(&ev, win)) + continue; + switch(ev.type) { + case DestroyNotify: + if (ev.xdestroywindow.window != win) + break; + cleanup(); + exit(1); + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); + break; + case FocusIn: + /* regrab focus from parent window */ + if (ev.xfocus.window != win) + grabfocus(); + break; + case KeyPress: + keypress(&ev.xkey); + break; + case SelectionNotify: + if (ev.xselection.property == utf8) + paste(); + break; + case VisibilityNotify: + if (ev.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(dpy, win); + break; + } + } +} + +static void +setup(void) +{ + int x, y, i, j; + unsigned int du; + XSetWindowAttributes swa; + XIM xim; + Window w, dw, *dws; + XWindowAttributes wa; + XClassHint ch = {"dmenu", "dmenu"}; +#ifdef XINERAMA + XineramaScreenInfo *info; + Window pw; + int a, di, n, area = 0; +#endif + /* init appearance */ + for (j = 0; j < SchemeLast; j++) + scheme[j] = drw_scm_create(drw, colors[j], 2); + + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); + + /* calculate menu geometry */ + bh = drw->fonts->h + 2; + bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; +#ifdef XINERAMA + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { + XGetInputFocus(dpy, &w, &di); + if (mon >= 0 && mon < n) + i = mon; + else if (w != root && w != PointerRoot && w != None) { + /* find top-level window containing current input focus */ + do { + if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) + XFree(dws); + } while (w != root && w != pw); + /* find xinerama screen with which the window intersects most */ + if (XGetWindowAttributes(dpy, pw, &wa)) + for (j = 0; j < n; j++) + if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { + area = a; + i = j; + } + } + /* no focused window is on screen, so use pointer location instead */ + if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + for (i = 0; i < n; i++) + if (INTERSECT(x, y, 1, 1, info[i]) != 0) + break; + + mw = MIN(MAX(max_textw() + promptw, 100), info[i].width); + x = info[i].x_org + ((info[i].width - mw) / 2); + y = info[i].y_org + ((info[i].height - mh) / 2); + XFree(info); + } else +#endif + { + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); + x = 0; + y = topbar ? 0 : wa.height - mh; + mw = wa.width; + } + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + inputw = mw / 3; /* input width: ~33% of monitor width */ + match(); + + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + XSetWindowBorder(dpy, win, scheme[SchemeOut][ColBg].pixel); + XSetClassHint(dpy, win, &ch); + + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); + + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, win, XNFocusWindow, win, NULL); + + XMapRaised(dpy, win); + if (embed) { + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); + if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { + for (i = 0; i < du && dws[i] != win; ++i) + XSelectInput(dpy, dws[i], FocusChangeMask); + XFree(dws); + } + grabfocus(); + } + drw_resize(drw, mw, mh); + drawmenu(); +} + +static void +usage(void) +{ + die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); +} + +int +main(int argc, char *argv[]) +{ + XWindowAttributes wa; + int i, fast = 0; + + for (i = 1; i < argc; i++) + /* these options take no arguments */ + if (!strcmp(argv[i], "-v")) { /* prints version information */ + puts("dmenu-"VERSION); + exit(0); + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ + topbar = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); + else if (!strcmp(argv[i], "-h")) { /* minimum height of one menu line */ + lineheight = atoi(argv[++i]); + lineheight = MAX(lineheight, min_lineheight); + } + else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ + prompt = argv[++i]; + else if (!strcmp(argv[i], "-fn")) /* font or font set */ + fonts[0] = argv[++i]; + else if (!strcmp(argv[i], "-nb")) /* normal background color */ + colors[SchemeNorm][ColBg] = argv[++i]; + else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ + colors[SchemeNorm][ColFg] = argv[++i]; + else if (!strcmp(argv[i], "-sb")) /* selected background color */ + colors[SchemeSel][ColBg] = argv[++i]; + else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ + colors[SchemeSel][ColFg] = argv[++i]; + else if (!strcmp(argv[i], "-w")) /* embedding window id */ + embed = argv[++i]; + else + usage(); + + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("cannot open display"); + screen = DefaultScreen(dpy); + root = RootWindow(dpy, screen); + if (!embed || !(parentwin = strtol(embed, NULL, 0))) + parentwin = root; + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); + drw = drw_create(dpy, screen, root, wa.width, wa.height); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + +#ifdef __OpenBSD__ + if (pledge("stdio rpath", NULL) == -1) + die("pledge"); +#endif + + if (fast && !isatty(0)) { + grabkeyboard(); + readstdin(); + } else { + readstdin(); + grabkeyboard(); + } + setup(); + run(); + + return 1; /* unreachable */ +} diff --git a/dmenu/dmenu.o b/dmenu/dmenu.o new file mode 100644 index 0000000000000000000000000000000000000000..629d4b86c5e5348f8217ef189df2bb5cccd1068d GIT binary patch literal 32912 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 cFTSP5=M^ literal 0 HcmV?d00001 diff --git a/dmenu/dmenu_path b/dmenu/dmenu_path new file mode 100755 index 0000000..3a7cda7 --- /dev/null +++ b/dmenu/dmenu_path @@ -0,0 +1,13 @@ +#!/bin/sh + +cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}" +cache="$cachedir/dmenu_run" + +[ ! -e "$cachedir" ] && mkdir -p "$cachedir" + +IFS=: +if stest -dqr -n "$cache" $PATH; then + stest -flx $PATH | sort -u | tee "$cache" +else + cat "$cache" +fi diff --git a/dmenu/dmenu_run b/dmenu/dmenu_run new file mode 100755 index 0000000..834ede5 --- /dev/null +++ b/dmenu/dmenu_run @@ -0,0 +1,2 @@ +#!/bin/sh +dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & diff --git a/dmenu/drw.c b/dmenu/drw.c new file mode 100644 index 0000000..a58a2b4 --- /dev/null +++ b/dmenu/drw.c @@ -0,0 +1,450 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); + drw->gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + drw->w = w; + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); +} + +void +drw_free(Drw *drw) +{ + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_fontset_create instead. + */ +static Fnt * +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ + Fnt *font; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font from pattern.\n"); + return NULL; + } + } else { + die("no font specified."); + } + + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->h = xfont->ascent + xfont->descent; + font->dpy = drw->dpy; + + return font; +} + +static void +xfont_free(Fnt *font) +{ + if (!font) + return; + if (font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); + free(font); +} + +Fnt* +drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) +{ + Fnt *cur, *ret = NULL; + size_t i; + + if (!drw || !fonts) + return NULL; + + for (i = 1; i <= fontcount; i++) { + if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { + cur->next = ret; + ret = cur; + } + } + return (drw->fonts = ret); +} + +void +drw_fontset_free(Fnt *font) +{ + if (font) { + drw_fontset_free(font->next); + xfont_free(font); + } +} + +void +drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +{ + if (!drw || !dest || !clrname) + return; + + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); +} + +/* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ +Clr * +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +{ + size_t i; + Clr *ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, &ret[i], clrnames[i]); + return ret; +} + +void +drw_setfontset(Drw *drw, Fnt *set) +{ + if (drw) + drw->fonts = set; +} + +void +drw_setscheme(Drw *drw, Clr *scm) +{ + if (drw) + drw->scheme = scm; +} + +void +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) +{ + if (!drw || !drw->scheme) + return; + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); + if (filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); +} + +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) +{ + int i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + int utf8strlen, utf8charlen, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; + + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) + return 0; + + if (!render) { + w = invert ? invert : ~invert; + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); + x += lpad; + w -= lpad; + } + + usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); + while (1) { + ew = ellipsis_len = utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { + utf8strlen += utf8charlen; + text += utf8charlen; + ew += tmpw; + } else { + nextfont = curfont; + } + break; + } + } + + if (overflow || !charexists || nextfont) + break; + else + charexists = 0; + } + + if (utf8strlen) { + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); + } + x += ew; + w -= ew; + } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); + + if (!*text || overflow) { + break; + } else if (nextfont) { + charexists = 0; + usedfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. */ + charexists = 1; + + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + goto no_match; + } + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts->pattern) { + /* Refer to the comment in xfont_create for more information. */ + die("the first font in the cache must be loaded from a font string."); + } + + fcpattern = FcPatternDuplicate(drw->fonts->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + usedfont = xfont_create(drw, NULL, match); + if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { + for (curfont = drw->fonts; curfont->next; curfont = curfont->next) + ; /* NOP */ + curfont->next = usedfont; + } else { + xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; +no_match: + usedfont = drw->fonts; + } + } + } + } + if (d) + XftDrawDestroy(d); + + return x + (render ? w : 0); +} + +void +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); + XSync(drw->dpy, False); +} + +unsigned int +drw_fontset_getwidth(Drw *drw, const char *text) +{ + if (!drw || !drw->fonts || !text) + return 0; + return drw_text(drw, 0, 0, 0, 0, 0, text, 0); +} + +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + +void +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) +{ + XGlyphInfo ext; + + if (!font || !text) + return; + + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + if (w) + *w = ext.xOff; + if (h) + *h = font->h; +} + +Cur * +drw_cur_create(Drw *drw, int shape) +{ + Cur *cur; + + if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) + return NULL; + + cur->cursor = XCreateFontCursor(drw->dpy, shape); + + return cur; +} + +void +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!cursor) + return; + + XFreeCursor(drw->dpy, cursor->cursor); + free(cursor); +} diff --git a/dmenu/drw.h b/dmenu/drw.h new file mode 100644 index 0000000..fd7631b --- /dev/null +++ b/dmenu/drw.h @@ -0,0 +1,58 @@ +/* See LICENSE file for copyright and license details. */ + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct Fnt { + Display *dpy; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; + struct Fnt *next; +} Fnt; + +enum { ColFg, ColBg }; /* Clr scheme index */ +typedef XftColor Clr; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + GC gc; + Clr *scheme; + Fnt *fonts; +} Drw; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + +/* Colorscheme abstraction */ +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/dmenu/drw.o b/dmenu/drw.o new file mode 100644 index 0000000000000000000000000000000000000000..f91ac0aec50631eb8d53dcd05e025e75a12f2461 GIT binary patch literal 11104 zcmb_idvsgHnZL43;yhLo5Q2deE>r;rvZ|HvutOla_LY4_l~lwII0;}BS&jv=DfoRkF)JLyLEX3(3M?Dr0)d4zysG_u zb7$YQ_ugjnSV@F@nI4twv;NkS)#+oSBDaht*Z-PjOgFBsj#`4s8f zWu;!*7eOPzSxok^$v%j)cP%#1V6pdN>;UTtSWmw(*Yf^3QN-CmqgifmFopOA0}h&phS#hx{OOj!6ZAKw&bCpO<{++o~l+-3A~b2b#ecV_B@!`z!|ObeGOKsJz%m)lf7=03ys#(C!pO!G-{S3Ee;iH z*Ef^&3D^$9H^AgBtMqGfm47q@MIhBbx|AC1Q;WS2AHVjO#=nt*(eRtG)_435dC`fL z*PXG(4%<7+g#e$J9kEzEC^bRL8mq+E!Qy3B`6lpc*7yZf?IS_q3Rh+F9|>pAeUY(v zS8XnuEzW++B~0bQ6>FT!=ly+6kjSIQyVk)-0Dy+Nk?L~&QmXt5X6P(LMk?JMgy4~Y z#S)E1`SyCldm&3SSmiFDck76^#R9SFGqKXU4U-@Kwpxv|RLhhXPO(Y{8owB{#UclF zM-|Gr@*>hvZ z?K!Y8Fy*z%$i4#Hcc0_F=vWm2<9*<|eJRTZBT@Fgu{p|4ZZ_GkrWY1p{?(sH$JbRc zgb|`NHqER&PS7*c=PIx2ieVEd_hQw4N{f(!c_wl zr#FkO##v~3pM^YZBJ+@Yjqnfr9Eq{_X*IV%C}IWKYhvtZoIS&ykB^(dg>iO-dv@*E zoAx~aQ)Y0H!Rmw7*gN)|a(e@d!c~yfXI+{veG#>X5adIf`a8+KdF?jdNkDl`SlngtJ^sPoHCd6T2h0#Mo$TvdYnx65nNb%=F^L(BHnm8o!Pd#rohXFxaJP z3qvA=`2VDW=4xt&Ux{Mvkm|6`qL?*f$fP0cBhfI{ni+(0`10>-iHu@L{wvyu$L-+2 z$v4hm&w(Wa7MqBT8&#`x#=EUx@a>K$hS#=!Y==2Bj-@$qY{!W<|Gw2NCw~A=Yu*IK zVpuD#ja3hloJ6cttuG$2oU`_p)+L8_UZ-^KZ?eWqS`#>Ls?J4_KCeO%f5(ec7d%N# z<6mhfpK4gkKIZ*+`GFSp@>)7Xj*>ZJuh{FXvK1#h=fAp?zZvz6(srVU!sIt;OP!F@uPO?a{fXPlw`SC@hbE88S;%{G)#X z{&0mdB?euvvh5&+*Q5yPmbcg(FZTqlNi;nFw&6YhR-+s6YO*GR52){lE5_^V;_PMa zuDg0M4!>ZLn#*jsW$dKArtGX4TqTf%2@yP=@)iXc)2_y>aW0@|6UDz#^N&3T%O+o^ zyaG{RS1Z=!kI?(R$3OP>sF9*D&R)bbDbC;;z8Ore#pxxcu*Uajb>MGp^p6gcpi-s5 zYCTqb*I5X!Vc}roJ{V)-Jiz*~N+XS0(I*ZeaRZ=*WtB%7Ia{24AXXGVYY%eJxh**h zEzbUjW4Ir(x58DyP~zoFGQv|jLwaMrp9?W z`>h2b=F+A%&s-olKoa2WX6S{x0#4+E^2%W#YPd<%2V-oF!8)B&3g_8H+;q0zDo1ph z@WVLUp-*mwHdrJlTRuYm^7SFEP1TCCyOd6>vDlLRwAdzBk?K68_Iyeg$BR7U{81!5 za%~}IZ}Os^IuA+g!&vwoI$g(7pOD$z!4Vu8i}+zAkBkQod=q)A9DB|IwahB*Y|-q? z=#aWNfrP`d4j;Zp3m?BNeA@8=j`<1PzbCrF74{1{)CA8J#B&MG>Vx9$g#-Gu zeG$&LkLXmk%GWz;O<(mPg-SY~&*hivspQa5&epTJWS`!j8?yEOd~Q%5N)D!1=~pc+ zTs7ZCIGoHE(hemN>2^*ZPTF=lKP2gga?WsJIGxJ$XVQHkmxyFGn@c6_w4Takb9p|C z77B$ldjNtn`2utxMKVJ=A*o~v--AWKThd(5G&Ch8lVTn_pBdU3(ozGYnynR5$!u~< zHtm|#WuZ_yG~e;Y7r(1jerMKpiXqzksZ_D)JGC?J^nUmEE=fXRSj{vwP~@$6Wyc}4=BOBT*;*aKp+W(gnBw1}wb0@5tnA*wrkf!%dmp7p^7 zI<4bk?0ZzV`2vsDMSYErc%wdjyguq{diWf}*Svd9%-2$y8}mi#a=sSR*KGKj+I)JO zuMrGwzJ}#seN4#NOm(L(FivtF_L@GuR8LKZ(wI2D*7280$e_Gij`D?R;ND zbb;Y(xE9cW7`JI0IzCbd9mlngpZfqatIm%uSPvXgas`E~m<4XaR1q9_R3h{Rf0gRGe2p*y zez$zhUA{p31osieH7jWEBU9rJ+fkf+U8@p${{cMi zX<;yiD982)+RKQR=U*4kKkCj_DD3sx`(hV5o5DN2>fJc)2xk}C&ahWZgAvhMjM}5k z(FR1HAHQf{D)2!UekJ-OCn9jZPoPac^gz=F5mTu_8^`BN)04lb#PFecWs!J-;LBzp-s%_lMi+jsz_TuVSm2Mi@S?!K<-&Ie{CO9?Q{XST z@KJ%k?!p=Rv=_L`cLB_X??ztDhW{Pt&x5CjgrM(<`k!ma`AH4@P!0Te4g9}>)4YC> za(u4`cB%&bXM+A7LC^PkV8lP0U6<9sudIPzTLX{Oz)j$!{{fND{JelZ8w7qr;LX6O z+*LzPzn~9@buxlzbbHfHvFx?-*VwU6!5Bx}eeo4sTX9wh*2Yfa?m)5|q7jnAAR>02` z$XQc^eyyP2vw*Y~X8`IgHRy+H;NPf$f2#)m*ER4bYT!p|;IGuc->reyArEHrr@scS z*T7fSz}tXR9G@2cU)Rys_4IWEeYI#Esf6<|GSdY+pWCkW^xGYnwLP0F zq)E%(R6dPoke0@S1ur74r=9l`nUTTdu*;_If`^2XVR!~f;bPLS4X20J;k~96>^{8wwBFwSVLY4c{@&EUy-=0L67+u3`ZA7k zQV#bK7fjCLvq2}Wem1Yn(oT;#gAC#G5J4d|C<%BsZ405C9ZDA9SLj58`E<(WmUiUw z>8<%(ai|ZIWwP1z7)TCn#e1&D%qO?abcxGxRBm{?0oQ?j`%sEYqj`F_rtS2IT_C@A zqY)jk@vS4+mPHPQIG!Oy(vG)gbR<)7q!U9I ze}!`49Vr?{(1eibzR}l5BT8lzhqD=a3eP}-2Ha<1ZMj?)KznYeKeM%~xTRocY-9o; zGu@voW^Dx%Azw>rOFWJ;t}LX45cw%>mK5Yz8GUJVZz`J{9OnK=6=%ZkSlB^XUCbA9 z`Dp^4H9T3wfF_>LxGQQJE#*FZsQ8>}8qbJ+m#FC&pgZYj_?d^w-3or8g8#9CU##GC zPoY9`F2P62d6hsE!s#rR_-6#75dI~6Bz_&vD=LK39whP23a-lMzu5@-%N6=x2zv6v z6$(!0Diy-%&%ILqTZ;TIEBF}&4=VUP5`f~CA5d`exs<;|;AEF7ze&MWKd)5e_!T)V z3jI!Bdyk`)Yis>~i5!&YJ=! zyXfyp5`SBvSLI*RK++sP--ue$pFfYo-2XJE#BUNf>7&}!tq%)RK3WJ3;G)cPI2i}^x2`{>bm}sf~$G>b`AVO zaUUl6s$Ewr_$|u3Usdq9f@jdCLUQQ$DCy6IWIT!+-=g4Z-VP9jQ?zN`1T zaQRNAcb-Zw-@_3XF5h+14k=&0>mGB_%lDfWDr_ILlUq>Rd8Zzbt$aG04DoAts4rYI=<+p6 z<5vn?xS1ec9(TaM;e_-U_E%L?(JpgWdYtext; item++) ++ len = MAX(TEXTW(item->text), len); ++ return len; ++} ++ + static void + cleanup(void) + { +@@ -131,13 +140,14 @@ + { + unsigned int curpos; + struct item *item; +- int x = 0, y = 0, w; ++ int x = 0, y = 0, fh = drw->fonts->h, w; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); + + if (prompt && *prompt) { +- drw_setscheme(drw, scheme[SchemeSel]); ++ if (colorprompt) ++ drw_setscheme(drw, scheme[SchemeSel]); + x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); + } + /* draw input field */ +@@ -148,13 +158,13 @@ + curpos = TEXTW(text) - TEXTW(&text[cursor]); + if ((curpos += lrpad / 2 - 1) < w) { + drw_setscheme(drw, scheme[SchemeNorm]); +- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); ++ drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0); + } + + if (lines > 0) { + /* draw vertical list */ + for (item = curr; item != next; item = item->right) +- drawitem(item, x, y += bh, mw - x); ++ drawitem(item, 0, y += bh, mw - x); + } else if (matches) { + /* draw horizontal list */ + x += inputw; +@@ -609,8 +619,10 @@ + + /* calculate menu geometry */ + bh = drw->fonts->h + 2; ++ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; ++ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + #ifdef XINERAMA + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { +@@ -637,9 +649,9 @@ + if (INTERSECT(x, y, 1, 1, info[i])) + break; + +- x = info[i].x_org; +- y = info[i].y_org + (topbar ? 0 : info[i].height - mh); +- mw = info[i].width; ++ mw = MIN(MAX(max_textw() + promptw, 100), info[i].width); ++ x = info[i].x_org + ((info[i].width - mw) / 2); ++ y = info[i].y_org + ((info[i].height - mh) / 2); + XFree(info); + } else + #endif +@@ -647,11 +659,10 @@ + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); +- x = 0; +- y = topbar ? 0 : wa.height - mh; +- mw = wa.width; ++ mw = MIN(MAX(max_textw() + promptw, 100), wa.width); ++ x = (wa.width - mw) / 2; ++ y = (wa.height - mh) / 2; + } +- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + inputw = MIN(inputw, mw/3); + match(); + +@@ -659,9 +670,10 @@ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; +- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, ++ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); ++ XSetWindowBorder(dpy, win, scheme[SchemeOut][ColBg].pixel); + XSetClassHint(dpy, win, &ch); + + +@@ -689,7 +701,7 @@ + static void + usage(void) + { +- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-bfiv] [-l lines] [-h height] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); + exit(1); + } +@@ -717,6 +729,10 @@ + /* these options take one argument */ + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); ++ else if (!strcmp(argv[i], "-h")) { /* minimum height of one menu line */ ++ lineheight = atoi(argv[++i]); ++ lineheight = MAX(lineheight, min_lineheight); ++ } + else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ diff --git a/dmenu/stest b/dmenu/stest new file mode 100755 index 0000000000000000000000000000000000000000..295ddf0f65606ceff5f4254056dc095fbd0e223a GIT binary patch literal 16488 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 +© 2007-2011 Peter Hartlich +© 2007-2009 Szabolcs Nagy +© 2007-2009 Christof Musik +© 2007-2009 Premysl Hruby +© 2007-2008 Enno Gottox Boland +© 2008 Martin Hurton +© 2008 Neale Pickett +© 2009 Mate Nagy +© 2010-2016 Hiltjo Posthuma +© 2010-2012 Connor Lane Smith +© 2011 Christoph Lohmann <20h@r-36.net> +© 2015-2016 Quentin Rameau +© 2015-2016 Eric Pruitt +© 2016-2017 Markus Teich +© 2020-2022 Chris Down + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/dwm/Makefile b/dwm/Makefile new file mode 100644 index 0000000..aca7109 --- /dev/null +++ b/dwm/Makefile @@ -0,0 +1,48 @@ +# dwm - dynamic window manager +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = drw.c dwm.c util.c +OBJ = ${SRC:.c=.o} + +all: options dwm + +options: + @echo dwm build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + ${CC} -c ${CFLAGS} $< + +${OBJ}: config.mk + +dwm: ${OBJ} + ${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz + +dist: clean + mkdir -p dwm-${VERSION} + cp -R LICENSE Makefile README config.def.h config.mk\ + dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} + tar -cf dwm-${VERSION}.tar dwm-${VERSION} + gzip dwm-${VERSION}.tar + rm -rf dwm-${VERSION} + +install: all + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f dwm ${DESTDIR}${PREFIX}/bin + chmod 755 ${DESTDIR}${PREFIX}/bin/dwm + mkdir -p ${DESTDIR}${MANPREFIX}/man1 + sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 + chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/dwm\ + ${DESTDIR}${MANPREFIX}/man1/dwm.1 + +.PHONY: all options clean dist install uninstall diff --git a/dwm/README b/dwm/README new file mode 100644 index 0000000..95d4fd0 --- /dev/null +++ b/dwm/README @@ -0,0 +1,48 @@ +dwm - dynamic window manager +============================ +dwm is an extremely fast, small, and dynamic window manager for X. + + +Requirements +------------ +In order to build dwm you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (dwm is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install dwm (if +necessary as root): + + make clean install + + +Running dwm +----------- +Add the following line to your .xinitrc to start dwm using startx: + + exec dwm + +In order to connect dwm to a specific display, make sure that +the DISPLAY environment variable is set correctly, e.g.: + + DISPLAY=foo.bar:1 exec dwm + +(This will start dwm on display :1 of the host foo.bar.) + +In order to display status info in the bar, you can do something +like this in your .xinitrc: + + while xsetroot -name "`date` `uptime | sed 's/.*,//'`" + do + sleep 1 + done & + exec dwm + + +Configuration +------------- +The configuration of dwm is done by creating a custom config.h +and (re)compiling the source code. diff --git a/dwm/config.def.h b/dwm/config.def.h new file mode 100644 index 0000000..557b9a2 --- /dev/null +++ b/dwm/config.def.h @@ -0,0 +1,132 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const unsigned int borderpx = 1; /* border pixel of windows */ +static const unsigned int snap = 32; /* snap pixel */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "terminus:size=10" }; +static const char dmenufont[] = "terminus:size=8"; +static const char col_gray1[] = "#222222"; +static const char col_gray2[] = "#1c1c1c"; +static const char col_gray3[] = "#403f3f"; +static const char col_gray4[] = "#666560"; +static const char col_dmenu1[] = "#FD7717"; +static const char col_dmenu2[] = "#ffffff"; +static const char col_dmenu3[] = "#ffffff"; +static const char col_cyan[] = "#222222"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_dmenu2, col_cyan, col_cyan }, + [SchemeSel] = { col_dmenu2, col_cyan, col_dmenu2 }, +}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const char *tagsel[][2] = { + { "#ffffff", "#fd7717" }, + { "#ffffff", "#fd7718" }, + { "#ffffff", "#fd7719" }, + { "#ffffff", "#fd7720" }, + { "#ffffff", "#fd7721" }, + { "#ffffff", "#fd7722" }, + { "#ffffff", "#fd7723" }, + { "#ffffff", "#fd7724" }, + { "#ffffff", "#fd7725" }, +}; + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#define MODKEY Mod1Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_dmenu2, "-sb", col_dmenu1, "-sf", col_dmenu2, NULL }; +static const char *termcmd[] = { "st", NULL }; +static const char *takess[] = { "speedwm-screenshotutil -s -f 5", NULL }; +static const Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY|ShiftMask, XK_s, spawn, { .v = takess } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static const Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +}; + diff --git a/dwm/config.mk b/dwm/config.mk new file mode 100644 index 0000000..ef8acf7 --- /dev/null +++ b/dwm/config.mk @@ -0,0 +1,39 @@ +# dwm version +VERSION = 6.4 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +# Xinerama, comment if you don't want it +XINERAMALIBS = -lXinerama +XINERAMAFLAGS = -DXINERAMA + +# freetype +FREETYPELIBS = -lfontconfig -lXft +FREETYPEINC = /usr/include/freetype2 +# OpenBSD (uncomment) +#FREETYPEINC = ${X11INC}/freetype2 +#MANPREFIX = ${PREFIX}/man + +# includes and libs +INCS = -I${X11INC} -I${FREETYPEINC} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} + +# flags +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} +LDFLAGS = ${LIBS} + +# Solaris +#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = ${LIBS} + +# compiler and linker +CC = cc diff --git a/dwm/drw.c b/dwm/drw.c new file mode 100644 index 0000000..a58a2b4 --- /dev/null +++ b/dwm/drw.c @@ -0,0 +1,450 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); + drw->gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + drw->w = w; + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); +} + +void +drw_free(Drw *drw) +{ + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_fontset_create instead. + */ +static Fnt * +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ + Fnt *font; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font from pattern.\n"); + return NULL; + } + } else { + die("no font specified."); + } + + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->h = xfont->ascent + xfont->descent; + font->dpy = drw->dpy; + + return font; +} + +static void +xfont_free(Fnt *font) +{ + if (!font) + return; + if (font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); + free(font); +} + +Fnt* +drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) +{ + Fnt *cur, *ret = NULL; + size_t i; + + if (!drw || !fonts) + return NULL; + + for (i = 1; i <= fontcount; i++) { + if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { + cur->next = ret; + ret = cur; + } + } + return (drw->fonts = ret); +} + +void +drw_fontset_free(Fnt *font) +{ + if (font) { + drw_fontset_free(font->next); + xfont_free(font); + } +} + +void +drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +{ + if (!drw || !dest || !clrname) + return; + + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); +} + +/* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ +Clr * +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +{ + size_t i; + Clr *ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, &ret[i], clrnames[i]); + return ret; +} + +void +drw_setfontset(Drw *drw, Fnt *set) +{ + if (drw) + drw->fonts = set; +} + +void +drw_setscheme(Drw *drw, Clr *scm) +{ + if (drw) + drw->scheme = scm; +} + +void +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) +{ + if (!drw || !drw->scheme) + return; + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); + if (filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); +} + +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) +{ + int i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + int utf8strlen, utf8charlen, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; + + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) + return 0; + + if (!render) { + w = invert ? invert : ~invert; + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); + x += lpad; + w -= lpad; + } + + usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); + while (1) { + ew = ellipsis_len = utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { + utf8strlen += utf8charlen; + text += utf8charlen; + ew += tmpw; + } else { + nextfont = curfont; + } + break; + } + } + + if (overflow || !charexists || nextfont) + break; + else + charexists = 0; + } + + if (utf8strlen) { + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); + } + x += ew; + w -= ew; + } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); + + if (!*text || overflow) { + break; + } else if (nextfont) { + charexists = 0; + usedfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. */ + charexists = 1; + + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + goto no_match; + } + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts->pattern) { + /* Refer to the comment in xfont_create for more information. */ + die("the first font in the cache must be loaded from a font string."); + } + + fcpattern = FcPatternDuplicate(drw->fonts->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + usedfont = xfont_create(drw, NULL, match); + if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { + for (curfont = drw->fonts; curfont->next; curfont = curfont->next) + ; /* NOP */ + curfont->next = usedfont; + } else { + xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; +no_match: + usedfont = drw->fonts; + } + } + } + } + if (d) + XftDrawDestroy(d); + + return x + (render ? w : 0); +} + +void +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); + XSync(drw->dpy, False); +} + +unsigned int +drw_fontset_getwidth(Drw *drw, const char *text) +{ + if (!drw || !drw->fonts || !text) + return 0; + return drw_text(drw, 0, 0, 0, 0, 0, text, 0); +} + +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + +void +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) +{ + XGlyphInfo ext; + + if (!font || !text) + return; + + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + if (w) + *w = ext.xOff; + if (h) + *h = font->h; +} + +Cur * +drw_cur_create(Drw *drw, int shape) +{ + Cur *cur; + + if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) + return NULL; + + cur->cursor = XCreateFontCursor(drw->dpy, shape); + + return cur; +} + +void +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!cursor) + return; + + XFreeCursor(drw->dpy, cursor->cursor); + free(cursor); +} diff --git a/dwm/drw.h b/dwm/drw.h new file mode 100644 index 0000000..6471431 --- /dev/null +++ b/dwm/drw.h @@ -0,0 +1,58 @@ +/* See LICENSE file for copyright and license details. */ + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct Fnt { + Display *dpy; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; + struct Fnt *next; +} Fnt; + +enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ +typedef XftColor Clr; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + GC gc; + Clr *scheme; + Fnt *fonts; +} Drw; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + +/* Colorscheme abstraction */ +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/dwm/drw.o b/dwm/drw.o new file mode 100644 index 0000000000000000000000000000000000000000..f91ac0aec50631eb8d53dcd05e025e75a12f2461 GIT binary patch literal 11104 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

kMT;{&K_s$En9bXYp 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 AWB>pF literal 0 HcmV?d00001 diff --git a/dwm/dwm.1 b/dwm/dwm.1 new file mode 100644 index 0000000..ddc8321 --- /dev/null +++ b/dwm/dwm.1 @@ -0,0 +1,176 @@ +.TH DWM 1 dwm\-VERSION +.SH NAME +dwm \- dynamic window manager +.SH SYNOPSIS +.B dwm +.RB [ \-v ] +.SH DESCRIPTION +dwm is a dynamic window manager for X. It manages windows in tiled, monocle +and floating layouts. Either layout can be applied dynamically, optimising the +environment for the application in use and the task performed. +.P +In tiled layouts windows are managed in a master and stacking area. The master +area on the left contains one window by default, and the stacking area on the +right contains all other windows. The number of master area windows can be +adjusted from zero to an arbitrary number. In monocle layout all windows are +maximised to the screen size. In floating layout windows can be resized and +moved freely. Dialog windows are always managed floating, regardless of the +layout applied. +.P +Windows are grouped by tags. Each window can be tagged with one or multiple +tags. Selecting certain tags displays all windows with these tags. +.P +Each screen contains a small status bar which displays all available tags, the +layout, the title of the focused window, and the text read from the root window +name property, if the screen is focused. A floating window is indicated with an +empty square and a maximised floating window is indicated with a filled square +before the windows title. The selected tags are indicated with a different +color. The tags of the focused window are indicated with a filled square in the +top left corner. The tags which are applied to one or more windows are +indicated with an empty square in the top left corner. +.P +dwm draws a small border around windows to indicate the focus state. +.SH OPTIONS +.TP +.B \-v +prints version information to stderr, then exits. +.SH USAGE +.SS Status bar +.TP +.B X root window name +is read and displayed in the status text area. It can be set with the +.BR xsetroot (1) +command. +.TP +.B Button1 +click on a tag label to display all windows with that tag, click on the layout +label toggles between tiled and floating layout. +.TP +.B Button3 +click on a tag label adds/removes all windows with that tag to/from the view. +.TP +.B Mod1\-Button1 +click on a tag label applies that tag to the focused window. +.TP +.B Mod1\-Button3 +click on a tag label adds/removes that tag to/from the focused window. +.SS Keyboard commands +.TP +.B Mod1\-Shift\-Return +Start +.BR st(1). +.TP +.B Mod1\-p +Spawn +.BR dmenu(1) +for launching other programs. +.TP +.B Mod1\-, +Focus previous screen, if any. +.TP +.B Mod1\-. +Focus next screen, if any. +.TP +.B Mod1\-Shift\-, +Send focused window to previous screen, if any. +.TP +.B Mod1\-Shift\-. +Send focused window to next screen, if any. +.TP +.B Mod1\-b +Toggles bar on and off. +.TP +.B Mod1\-t +Sets tiled layout. +.TP +.B Mod1\-f +Sets floating layout. +.TP +.B Mod1\-m +Sets monocle layout. +.TP +.B Mod1\-space +Toggles between current and previous layout. +.TP +.B Mod1\-j +Focus next window. +.TP +.B Mod1\-k +Focus previous window. +.TP +.B Mod1\-i +Increase number of windows in master area. +.TP +.B Mod1\-d +Decrease number of windows in master area. +.TP +.B Mod1\-l +Increase master area size. +.TP +.B Mod1\-h +Decrease master area size. +.TP +.B Mod1\-Return +Zooms/cycles focused window to/from master area (tiled layouts only). +.TP +.B Mod1\-Shift\-c +Close focused window. +.TP +.B Mod1\-Shift\-space +Toggle focused window between tiled and floating state. +.TP +.B Mod1\-Tab +Toggles to the previously selected tags. +.TP +.B Mod1\-Shift\-[1..n] +Apply nth tag to focused window. +.TP +.B Mod1\-Shift\-0 +Apply all tags to focused window. +.TP +.B Mod1\-Control\-Shift\-[1..n] +Add/remove nth tag to/from focused window. +.TP +.B Mod1\-[1..n] +View all windows with nth tag. +.TP +.B Mod1\-0 +View all windows with any tag. +.TP +.B Mod1\-Control\-[1..n] +Add/remove all windows with nth tag to/from the view. +.TP +.B Mod1\-Shift\-q +Quit dwm. +.SS Mouse commands +.TP +.B Mod1\-Button1 +Move focused window while dragging. Tiled windows will be toggled to the floating state. +.TP +.B Mod1\-Button2 +Toggles focused window between floating and tiled state. +.TP +.B Mod1\-Button3 +Resize focused window while dragging. Tiled windows will be toggled to the floating state. +.SH CUSTOMIZATION +dwm is customized by creating a custom config.h and (re)compiling the source +code. This keeps it fast, secure and simple. +.SH SEE ALSO +.BR dmenu (1), +.BR st (1) +.SH ISSUES +Java applications which use the XToolkit/XAWT backend may draw grey windows +only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early +JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds +are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the +environment variable +.BR AWT_TOOLKIT=MToolkit +(to use the older Motif backend instead) or running +.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D +or +.B wmname LG3D +(to pretend that a non-reparenting window manager is running that the +XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable +.BR _JAVA_AWT_WM_NONREPARENTING=1 . +.SH BUGS +Send all bug reports with a patch to hackers@suckless.org. diff --git a/dwm/dwm.c b/dwm/dwm.c new file mode 100644 index 0000000..cd7baa2 --- /dev/null +++ b/dwm/dwm.c @@ -0,0 +1,2163 @@ +/* See LICENSE file for copyright and license details. + * + * dynamic window manager is designed like any other X client as well. It is + * driven through handling X events. In contrast to other X clients, a window + * manager selects for SubstructureRedirectMask on the root window, to receive + * events about window (dis-)appearance. Only one X connection at a time is + * allowed to select for this event mask. + * + * The event handlers of dwm are organized in an array which is accessed + * whenever a new event has been fetched. This allows event dispatching + * in O(1) time. + * + * Each child of the root window is called a client, except windows which have + * set the override_redirect flag. Clients are organized in a linked client + * list on each monitor, the focus history is remembered through a stack list + * on each monitor. Each client contains a bit array to indicate the tags of a + * client. + * + * Keys and tagging rules are organized as arrays and defined in config.def.h. + * + * To understand everything else, start reading main(). + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef XINERAMA +#include +#endif /* XINERAMA */ +#include + +#include "drw.h" +#include "util.h" + +/* macros */ +#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) +#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) +#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define MOUSEMASK (BUTTONMASK|PointerMotionMask) +#define WIDTH(X) ((X)->w + 2 * (X)->bw) +#define HEIGHT(X) ((X)->h + 2 * (X)->bw) +#define TAGMASK ((1 << LENGTH(tags)) - 1) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + +/* enums */ +enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +enum { SchemeNorm, SchemeSel }; /* color schemes */ +enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ +enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ + +typedef union { + int i; + unsigned int ui; + float f; + const void *v; +} Arg; + +typedef struct { + unsigned int click; + unsigned int mask; + unsigned int button; + void (*func)(const Arg *arg); + const Arg arg; +} Button; + +typedef struct Monitor Monitor; +typedef struct Client Client; +struct Client { + char name[256]; + float mina, maxa; + int x, y, w, h; + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + Client *next; + Client *snext; + Monitor *mon; + Window win; +}; + +typedef struct { + unsigned int mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Key; + +typedef struct { + const char *symbol; + void (*arrange)(Monitor *); +} Layout; + +struct Monitor { + char ltsymbol[16]; + float mfact; + int nmaster; + int num; + int by; /* bar geometry */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + unsigned int seltags; + unsigned int sellt; + unsigned int tagset[2]; + int showbar; + int topbar; + Client *clients; + Client *sel; + Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; +}; + +typedef struct { + const char *class; + const char *instance; + const char *title; + unsigned int tags; + int isfloating; + int monitor; +} Rule; + +/* function declarations */ +static void applyrules(Client *c); +static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +static void arrange(Monitor *m); +static void arrangemon(Monitor *m); +static void attach(Client *c); +static void attachstack(Client *c); +static void buttonpress(XEvent *e); +static void checkotherwm(void); +static void cleanup(void); +static void cleanupmon(Monitor *mon); +static void clientmessage(XEvent *e); +static void configure(Client *c); +static void configurenotify(XEvent *e); +static void configurerequest(XEvent *e); +static Monitor *createmon(void); +static void destroynotify(XEvent *e); +static void detach(Client *c); +static void detachstack(Client *c); +static Monitor *dirtomon(int dir); +static void drawbar(Monitor *m); +static void drawbars(void); +static void enternotify(XEvent *e); +static void expose(XEvent *e); +static void focus(Client *c); +static void focusin(XEvent *e); +static void focusmon(const Arg *arg); +static void focusstack(const Arg *arg); +static Atom getatomprop(Client *c, Atom prop); +static int getrootptr(int *x, int *y); +static long getstate(Window w); +static int gettextprop(Window w, Atom atom, char *text, unsigned int size); +static void grabbuttons(Client *c, int focused); +static void grabkeys(void); +static void incnmaster(const Arg *arg); +static void keypress(XEvent *e); +static void killclient(const Arg *arg); +static void manage(Window w, XWindowAttributes *wa); +static void mappingnotify(XEvent *e); +static void maprequest(XEvent *e); +static void monocle(Monitor *m); +static void motionnotify(XEvent *e); +static void movemouse(const Arg *arg); +static Client *nexttiled(Client *c); +static void pop(Client *c); +static void propertynotify(XEvent *e); +static void quit(const Arg *arg); +static Monitor *recttomon(int x, int y, int w, int h); +static void resize(Client *c, int x, int y, int w, int h, int interact); +static void resizeclient(Client *c, int x, int y, int w, int h); +static void resizemouse(const Arg *arg); +static void restack(Monitor *m); +static void run(void); +static void scan(void); +static int sendevent(Client *c, Atom proto); +static void sendmon(Client *c, Monitor *m); +static void setclientstate(Client *c, long state); +static void setfocus(Client *c); +static void setfullscreen(Client *c, int fullscreen); +static void setlayout(const Arg *arg); +static void setmfact(const Arg *arg); +static void setup(void); +static void seturgent(Client *c, int urg); +static void showhide(Client *c); +static void spawn(const Arg *arg); +static void tag(const Arg *arg); +static void tagmon(const Arg *arg); +static void tile(Monitor *m); +static void togglebar(const Arg *arg); +static void togglefloating(const Arg *arg); +static void toggletag(const Arg *arg); +static void toggleview(const Arg *arg); +static void unfocus(Client *c, int setfocus); +static void unmanage(Client *c, int destroyed); +static void unmapnotify(XEvent *e); +static void updatebarpos(Monitor *m); +static void updatebars(void); +static void updateclientlist(void); +static int updategeom(void); +static void updatenumlockmask(void); +static void updatesizehints(Client *c); +static void updatestatus(void); +static void updatetitle(Client *c); +static void updatewindowtype(Client *c); +static void updatewmhints(Client *c); +static void view(const Arg *arg); +static Client *wintoclient(Window w); +static Monitor *wintomon(Window w); +static int xerror(Display *dpy, XErrorEvent *ee); +static int xerrordummy(Display *dpy, XErrorEvent *ee); +static int xerrorstart(Display *dpy, XErrorEvent *ee); +static void zoom(const Arg *arg); + +/* variables */ +static const char broken[] = "broken"; +static char stext[256]; +static int screen; +static int sw, sh; /* X display screen geometry width, height */ +static int bh; /* bar height */ +static int lrpad; /* sum of left and right padding for text */ +static int (*xerrorxlib)(Display *, XErrorEvent *); +static unsigned int numlockmask = 0; +static void (*handler[LASTEvent]) (XEvent *) = { + [ButtonPress] = buttonpress, + [ClientMessage] = clientmessage, + [ConfigureRequest] = configurerequest, + [ConfigureNotify] = configurenotify, + [DestroyNotify] = destroynotify, + [EnterNotify] = enternotify, + [Expose] = expose, + [FocusIn] = focusin, + [KeyPress] = keypress, + [MappingNotify] = mappingnotify, + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, + [UnmapNotify] = unmapnotify +}; +static Atom wmatom[WMLast], netatom[NetLast]; +static int running = 1; +static Cur *cursor[CurLast]; +static Clr **scheme; +static Clr **tagscheme; +static Display *dpy; +static Drw *drw; +static Monitor *mons, *selmon; +static Window root, wmcheckwin; + +/* configuration, allows nested code to access above variables */ +#include "config.def.h" + +/* compile-time check if all tags fit into an unsigned int bit array. */ +struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +/* function implementations */ +void +applyrules(Client *c) +{ + const char *class, *instance; + unsigned int i; + const Rule *r; + Monitor *m; + XClassHint ch = { NULL, NULL }; + + /* rule matching */ + c->isfloating = 0; + c->tags = 0; + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; + + for (i = 0; i < LENGTH(rules); i++) { + r = &rules[i]; + if ((!r->title || strstr(c->name, r->title)) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next); + if (m) + c->mon = m; + } + } + if (ch.res_class) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; +} + +int +applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) +{ + int baseismin; + Monitor *m = c->mon; + + /* set minimum possible */ + *w = MAX(1, *w); + *h = MAX(1, *h); + if (interact) { + if (*x > sw) + *x = sw - WIDTH(c); + if (*y > sh) + *y = sh - HEIGHT(c); + if (*x + *w + 2 * c->bw < 0) + *x = 0; + if (*y + *h + 2 * c->bw < 0) + *y = 0; + } else { + if (*x >= m->wx + m->ww) + *x = m->wx + m->ww - WIDTH(c); + if (*y >= m->wy + m->wh) + *y = m->wy + m->wh - HEIGHT(c); + if (*x + *w + 2 * c->bw <= m->wx) + *x = m->wx; + if (*y + *h + 2 * c->bw <= m->wy) + *y = m->wy; + } + if (*h < bh) + *h = bh; + if (*w < bh) + *w = bh; + if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { + if (!c->hintsvalid) + updatesizehints(c); + /* see last two sentences in ICCCM 4.1.2.3 */ + baseismin = c->basew == c->minw && c->baseh == c->minh; + if (!baseismin) { /* temporarily remove base dimensions */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for aspect limits */ + if (c->mina > 0 && c->maxa > 0) { + if (c->maxa < (float)*w / *h) + *w = *h * c->maxa + 0.5; + else if (c->mina < (float)*h / *w) + *h = *w * c->mina + 0.5; + } + if (baseismin) { /* increment calculation requires this */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for increment value */ + if (c->incw) + *w -= *w % c->incw; + if (c->inch) + *h -= *h % c->inch; + /* restore base dimensions */ + *w = MAX(*w + c->basew, c->minw); + *h = MAX(*h + c->baseh, c->minh); + if (c->maxw) + *w = MIN(*w, c->maxw); + if (c->maxh) + *h = MIN(*h, c->maxh); + } + return *x != c->x || *y != c->y || *w != c->w || *h != c->h; +} + +void +arrange(Monitor *m) +{ + if (m) + showhide(m->stack); + else for (m = mons; m; m = m->next) + showhide(m->stack); + if (m) { + arrangemon(m); + restack(m); + } else for (m = mons; m; m = m->next) + arrangemon(m); +} + +void +arrangemon(Monitor *m) +{ + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); + if (m->lt[m->sellt]->arrange) + m->lt[m->sellt]->arrange(m); +} + +void +attach(Client *c) +{ + c->next = c->mon->clients; + c->mon->clients = c; +} + +void +attachstack(Client *c) +{ + c->snext = c->mon->stack; + c->mon->stack = c; +} + +void +buttonpress(XEvent *e) +{ + unsigned int i, x, click; + Arg arg = {0}; + Client *c; + Monitor *m; + XButtonPressedEvent *ev = &e->xbutton; + + click = ClkRootWin; + /* focus monitor if necessary */ + if ((m = wintomon(ev->window)) && m != selmon) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + if (ev->window == selmon->barwin) { + i = x = 0; + do + x += TEXTW(tags[i]); + while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + click = ClkTagBar; + arg.ui = 1 << i; + } else if (ev->x < x + TEXTW(selmon->ltsymbol)) + click = ClkLtSymbol; + else if (ev->x > selmon->ww - (int)TEXTW(stext)) + click = ClkStatusText; + else + click = ClkWinTitle; + } else if ((c = wintoclient(ev->window))) { + focus(c); + restack(selmon); + XAllowEvents(dpy, ReplayPointer, CurrentTime); + click = ClkClientWin; + } + for (i = 0; i < LENGTH(buttons); i++) + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); +} + +void +checkotherwm(void) +{ + xerrorxlib = XSetErrorHandler(xerrorstart); + /* this causes an error if some other window manager is running */ + XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); + XSync(dpy, False); + XSetErrorHandler(xerror); + XSync(dpy, False); +} + +void +cleanup(void) +{ + Arg a = {.ui = ~0}; + Layout foo = { "", NULL }; + Monitor *m; + size_t i; + + view(&a); + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) + while (m->stack) + unmanage(m->stack, 0); + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < LENGTH(colors); i++) + free(scheme[i]); + free(scheme); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); +} + +void +cleanupmon(Monitor *mon) +{ + Monitor *m; + + if (mon == mons) + mons = mons->next; + else { + for (m = mons; m && m->next != mon; m = m->next); + m->next = mon->next; + } + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); + free(mon); +} + +void +clientmessage(XEvent *e) +{ + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) { + if (cme->data.l[1] == netatom[NetWMFullscreen] + || cme->data.l[2] == netatom[NetWMFullscreen]) + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); + } else if (cme->message_type == netatom[NetActiveWindow]) { + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); + } +} + +void +configure(Client *c) +{ + XConfigureEvent ce; + + ce.type = ConfigureNotify; + ce.display = dpy; + ce.event = c->win; + ce.window = c->win; + ce.x = c->x; + ce.y = c->y; + ce.width = c->w; + ce.height = c->h; + ce.border_width = c->bw; + ce.above = None; + ce.override_redirect = False; + XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); +} + +void +configurenotify(XEvent *e) +{ + Monitor *m; + Client *c; + XConfigureEvent *ev = &e->xconfigure; + int dirty; + + /* TODO: updategeom handling sucks, needs to be simplified */ + if (ev->window == root) { + dirty = (sw != ev->width || sh != ev->height); + sw = ev->width; + sh = ev->height; + if (updategeom() || dirty) { + drw_resize(drw, sw, bh); + updatebars(); + for (m = mons; m; m = m->next) { + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + } + focus(NULL); + arrange(NULL); + } + } +} + +void +configurerequest(XEvent *e) +{ + Client *c; + Monitor *m; + XConfigureRequestEvent *ev = &e->xconfigurerequest; + XWindowChanges wc; + + if ((c = wintoclient(ev->window))) { + if (ev->value_mask & CWBorderWidth) + c->bw = ev->border_width; + else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { + m = c->mon; + if (ev->value_mask & CWX) { + c->oldx = c->x; + c->x = m->mx + ev->x; + } + if (ev->value_mask & CWY) { + c->oldy = c->y; + c->y = m->my + ev->y; + } + if (ev->value_mask & CWWidth) { + c->oldw = c->w; + c->w = ev->width; + } + if (ev->value_mask & CWHeight) { + c->oldh = c->h; + c->h = ev->height; + } + if ((c->x + c->w) > m->mx + m->mw && c->isfloating) + c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ + if ((c->y + c->h) > m->my + m->mh && c->isfloating) + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + configure(c); + if (ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } else + configure(c); + } else { + wc.x = ev->x; + wc.y = ev->y; + wc.width = ev->width; + wc.height = ev->height; + wc.border_width = ev->border_width; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; + XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); + } + XSync(dpy, False); +} + +Monitor * +createmon(void) +{ + Monitor *m; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; + m->topbar = topbar; + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); + return m; +} + +void +destroynotify(XEvent *e) +{ + Client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); +} + +void +detach(Client *c) +{ + Client **tc; + + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; +} + +void +detachstack(Client *c) +{ + Client **tc, *t; + + for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); + *tc = c->snext; + + if (c == c->mon->sel) { + for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); + c->mon->sel = t; + } +} + +Monitor * +dirtomon(int dir) +{ + Monitor *m = NULL; + + if (dir > 0) { + if (!(m = selmon->next)) + m = mons; + } else if (selmon == mons) + for (m = mons; m->next; m = m->next); + else + for (m = mons; m->next != selmon; m = m->next); + return m; +} + +void +drawbar(Monitor *m) +{ + int x, w, tw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; + Client *c; + + if (!m->showbar) + return; + + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + } + + for (c = m->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + x = 0; + for (i = 0; i < LENGTH(tags); i++) { + w = TEXTW(tags[i]); + drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm])); + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, + urg & 1 << i); + x += w; + } + w = TEXTW(m->ltsymbol); + drw_setscheme(drw, scheme[SchemeNorm]); + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + + if ((w = m->ww - tw - x) > bh) { + if (m->sel) { + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); + if (m->sel->isfloating) + drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + } else { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x, 0, w, bh, 1, 1); + } + } + drw_map(drw, m->barwin, 0, 0, m->ww, bh); +} + +void +drawbars(void) +{ + Monitor *m; + + for (m = mons; m; m = m->next) + drawbar(m); +} + +void +enternotify(XEvent *e) +{ + Client *c; + Monitor *m; + XCrossingEvent *ev = &e->xcrossing; + + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) + return; + c = wintoclient(ev->window); + m = c ? c->mon : wintomon(ev->window); + if (m != selmon) { + unfocus(selmon->sel, 1); + selmon = m; + } else if (!c || c == selmon->sel) + return; + focus(c); +} + +void +expose(XEvent *e) +{ + Monitor *m; + XExposeEvent *ev = &e->xexpose; + + if (ev->count == 0 && (m = wintomon(ev->window))) + drawbar(m); +} + +void +focus(Client *c) +{ + if (!c || !ISVISIBLE(c)) + for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); + if (c) { + if (c->mon != selmon) + selmon = c->mon; + if (c->isurgent) + seturgent(c, 0); + detachstack(c); + attachstack(c); + grabbuttons(c, 1); + XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); + setfocus(c); + } else { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } + selmon->sel = c; + drawbars(); +} + +/* there are some broken focus acquiring clients needing extra handling */ +void +focusin(XEvent *e) +{ + XFocusChangeEvent *ev = &e->xfocus; + + if (selmon->sel && ev->window != selmon->sel->win) + setfocus(selmon->sel); +} + +void +focusmon(const Arg *arg) +{ + Monitor *m; + + if (!mons->next) + return; + if ((m = dirtomon(arg->i)) == selmon) + return; + unfocus(selmon->sel, 0); + selmon = m; + focus(NULL); +} + +void +focusstack(const Arg *arg) +{ + Client *c = NULL, *i; + + if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + if (!c) + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); + } else { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i)) + c = i; + if (!c) + for (; i; i = i->next) + if (ISVISIBLE(i)) + c = i; + } + if (c) { + focus(c); + restack(selmon); + } +} + +Atom +getatomprop(Client *c, Atom prop) +{ + int di; + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; + + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; + XFree(p); + } + return atom; +} + +int +getrootptr(int *x, int *y) +{ + int di; + unsigned int dui; + Window dummy; + + return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); +} + +long +getstate(Window w) +{ + int format; + long result = -1; + unsigned char *p = NULL; + unsigned long n, extra; + Atom real; + + if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], + &real, &format, &n, &extra, (unsigned char **)&p) != Success) + return -1; + if (n != 0) + result = *p; + XFree(p); + return result; +} + +int +gettextprop(Window w, Atom atom, char *text, unsigned int size) +{ + char **list = NULL; + int n; + XTextProperty name; + + if (!text || size == 0) + return 0; + text[0] = '\0'; + if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) + return 0; + if (name.encoding == XA_STRING) { + strncpy(text, (char *)name.value, size - 1); + } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { + strncpy(text, *list, size - 1); + XFreeStringList(list); + } + text[size - 1] = '\0'; + XFree(name.value); + return 1; +} + +void +grabbuttons(Client *c, int focused) +{ + updatenumlockmask(); + { + unsigned int i, j; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + if (!focused) + XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, + BUTTONMASK, GrabModeSync, GrabModeSync, None, None); + for (i = 0; i < LENGTH(buttons); i++) + if (buttons[i].click == ClkClientWin) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabButton(dpy, buttons[i].button, + buttons[i].mask | modifiers[j], + c->win, False, BUTTONMASK, + GrabModeAsync, GrabModeSync, None, None); + } +} + +void +grabkeys(void) +{ + updatenumlockmask(); + { + unsigned int i, j, k; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; + int start, end, skip; + KeySym *syms; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + XDisplayKeycodes(dpy, &start, &end); + syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); + if (!syms) + return; + for (k = start; k <= end; k++) + for (i = 0; i < LENGTH(keys); i++) + /* skip modifier codes, we do that ourselves */ + if (keys[i].keysym == syms[(k - start) * skip]) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, k, + keys[i].mod | modifiers[j], + root, True, + GrabModeAsync, GrabModeAsync); + XFree(syms); + } +} + +void +incnmaster(const Arg *arg) +{ + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); +} + +#ifdef XINERAMA +static int +isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) +{ + while (n--) + if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org + && unique[n].width == info->width && unique[n].height == info->height) + return 0; + return 1; +} +#endif /* XINERAMA */ + +void +keypress(XEvent *e) +{ + unsigned int i; + KeySym keysym; + XKeyEvent *ev; + + ev = &e->xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) + if (keysym == keys[i].keysym + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) + keys[i].func(&(keys[i].arg)); +} + +void +killclient(const Arg *arg) +{ + if (!selmon->sel) + return; + if (!sendevent(selmon->sel, wmatom[WMDelete])) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); + XKillClient(dpy, selmon->sel->win); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } +} + +void +manage(Window w, XWindowAttributes *wa) +{ + Client *c, *t = NULL; + Window trans = None; + XWindowChanges wc; + + c = ecalloc(1, sizeof(Client)); + c->win = w; + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; + c->w = c->oldw = wa->width; + c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; + + updatetitle(c); + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { + c->mon = t->mon; + c->tags = t->tags; + } else { + c->mon = selmon; + applyrules(c); + } + + if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) + c->x = c->mon->wx + c->mon->ww - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) + c->y = c->mon->wy + c->mon->wh - HEIGHT(c); + c->x = MAX(c->x, c->mon->wx); + c->y = MAX(c->y, c->mon->wy); + c->bw = borderpx; + + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); + XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); + configure(c); /* propagates border_width, if size doesn't change */ + updatewindowtype(c); + updatesizehints(c); + updatewmhints(c); + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); + grabbuttons(c, 0); + if (!c->isfloating) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); + attach(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); + XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ + setclientstate(c, NormalState); + if (c->mon == selmon) + unfocus(selmon->sel, 0); + c->mon->sel = c; + arrange(c->mon); + XMapWindow(dpy, c->win); + focus(NULL); +} + +void +mappingnotify(XEvent *e) +{ + XMappingEvent *ev = &e->xmapping; + + XRefreshKeyboardMapping(ev); + if (ev->request == MappingKeyboard) + grabkeys(); +} + +void +maprequest(XEvent *e) +{ + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; + + if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) + return; + if (!wintoclient(ev->window)) + manage(ev->window, &wa); +} + +void +monocle(Monitor *m) +{ + unsigned int n = 0; + Client *c; + + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) + n++; + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); + for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); +} + +void +motionnotify(XEvent *e) +{ + static Monitor *mon = NULL; + Monitor *m; + XMotionEvent *ev = &e->xmotion; + + if (ev->window != root) + return; + if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + mon = m; +} + +void +movemouse(const Arg *arg) +{ + int x, y, ocx, ocy, nx, ny; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + if (!getrootptr(&x, &y)) + return; + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nx = ocx + (ev.xmotion.x - x); + ny = ocy + (ev.xmotion.y - y); + if (abs(selmon->wx - nx) < snap) + nx = selmon->wx; + else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) + nx = selmon->wx + selmon->ww - WIDTH(c); + if (abs(selmon->wy - ny) < snap) + ny = selmon->wy; + else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) + ny = selmon->wy + selmon->wh - HEIGHT(c); + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange + && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) + togglefloating(NULL); + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, nx, ny, c->w, c->h, 1); + break; + } + } while (ev.type != ButtonRelease); + XUngrabPointer(dpy, CurrentTime); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + sendmon(c, m); + selmon = m; + focus(NULL); + } +} + +Client * +nexttiled(Client *c) +{ + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); + return c; +} + +void +pop(Client *c) +{ + detach(c); + attach(c); + focus(c); + arrange(c->mon); +} + +void +propertynotify(XEvent *e) +{ + Client *c; + Window trans; + XPropertyEvent *ev = &e->xproperty; + + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) + return; /* ignore */ + else if ((c = wintoclient(ev->window))) { + switch(ev->atom) { + default: break; + case XA_WM_TRANSIENT_FOR: + if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && + (c->isfloating = (wintoclient(trans)) != NULL)) + arrange(c->mon); + break; + case XA_WM_NORMAL_HINTS: + c->hintsvalid = 0; + break; + case XA_WM_HINTS: + updatewmhints(c); + drawbars(); + break; + } + if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { + updatetitle(c); + if (c == c->mon->sel) + drawbar(c->mon); + } + if (ev->atom == netatom[NetWMWindowType]) + updatewindowtype(c); + } +} + +void +quit(const Arg *arg) +{ + running = 0; +} + +Monitor * +recttomon(int x, int y, int w, int h) +{ + Monitor *m, *r = selmon; + int a, area = 0; + + for (m = mons; m; m = m->next) + if ((a = INTERSECT(x, y, w, h, m)) > area) { + area = a; + r = m; + } + return r; +} + +void +resize(Client *c, int x, int y, int w, int h, int interact) +{ + if (applysizehints(c, &x, &y, &w, &h, interact)) + resizeclient(c, x, y, w, h); +} + +void +resizeclient(Client *c, int x, int y, int w, int h) +{ + XWindowChanges wc; + + c->oldx = c->x; c->x = wc.x = x; + c->oldy = c->y; c->y = wc.y = y; + c->oldw = c->w; c->w = wc.width = w; + c->oldh = c->h; c->h = wc.height = h; + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); + configure(c); + XSync(dpy, False); +} + +void +resizemouse(const Arg *arg) +{ + int ocx, ocy, nw, nh; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); + nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); + if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww + && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) + { + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange + && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) + togglefloating(NULL); + } + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, c->x, c->y, nw, nh, 1); + break; + } + } while (ev.type != ButtonRelease); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + sendmon(c, m); + selmon = m; + focus(NULL); + } +} + +void +restack(Monitor *m) +{ + Client *c; + XEvent ev; + XWindowChanges wc; + + drawbar(m); + if (!m->sel) + return; + if (m->sel->isfloating || !m->lt[m->sellt]->arrange) + XRaiseWindow(dpy, m->sel->win); + if (m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; + for (c = m->stack; c; c = c->snext) + if (!c->isfloating && ISVISIBLE(c)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } + } + XSync(dpy, False); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + +void +run(void) +{ + XEvent ev; + /* main event loop */ + XSync(dpy, False); + while (running && !XNextEvent(dpy, &ev)) + if (handler[ev.type]) + handler[ev.type](&ev); /* call handler */ +} + +void +scan(void) +{ + unsigned int i, num; + Window d1, d2, *wins = NULL; + XWindowAttributes wa; + + if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { + for (i = 0; i < num; i++) { + if (!XGetWindowAttributes(dpy, wins[i], &wa) + || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + continue; + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + manage(wins[i], &wa); + } + for (i = 0; i < num; i++) { /* now the transients */ + if (!XGetWindowAttributes(dpy, wins[i], &wa)) + continue; + if (XGetTransientForHint(dpy, wins[i], &d1) + && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) + manage(wins[i], &wa); + } + if (wins) + XFree(wins); + } +} + +void +sendmon(Client *c, Monitor *m) +{ + if (c->mon == m) + return; + unfocus(c, 1); + detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ + attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +} + +void +setclientstate(Client *c, long state) +{ + long data[] = { state, None }; + + XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, + PropModeReplace, (unsigned char *)data, 2); +} + +int +sendevent(Client *c, Atom proto) +{ + int n; + Atom *protocols; + int exists = 0; + XEvent ev; + + if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { + while (!exists && n--) + exists = protocols[n] == proto; + XFree(protocols); + } + if (exists) { + ev.type = ClientMessage; + ev.xclient.window = c->win; + ev.xclient.message_type = wmatom[WMProtocols]; + ev.xclient.format = 32; + ev.xclient.data.l[0] = proto; + ev.xclient.data.l[1] = CurrentTime; + XSendEvent(dpy, c->win, False, NoEventMask, &ev); + } + return exists; +} + +void +setfocus(Client *c) +{ + if (!c->neverfocus) { + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + XChangeProperty(dpy, root, netatom[NetActiveWindow], + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); + } + sendevent(c, wmatom[WMTakeFocus]); +} + +void +setfullscreen(Client *c, int fullscreen) +{ + if (fullscreen && !c->isfullscreen) { + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); + c->isfullscreen = 1; + c->oldstate = c->isfloating; + c->oldbw = c->bw; + c->bw = 0; + c->isfloating = 1; + resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); + XRaiseWindow(dpy, c->win); + } else if (!fullscreen && c->isfullscreen){ + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)0, 0); + c->isfullscreen = 0; + c->isfloating = c->oldstate; + c->bw = c->oldbw; + c->x = c->oldx; + c->y = c->oldy; + c->w = c->oldw; + c->h = c->oldh; + resizeclient(c, c->x, c->y, c->w, c->h); + arrange(c->mon); + } +} + +void +setlayout(const Arg *arg) +{ + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if (arg && arg->v) + selmon->lt[selmon->sellt] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); + else + drawbar(selmon); +} + +/* arg > 1.0 will set mfact absolutely */ +void +setmfact(const Arg *arg) +{ + float f; + + if (!arg || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.05 || f > 0.95) + return; + selmon->mfact = f; + arrange(selmon); +} + +void +setup(void) +{ + int i; + XSetWindowAttributes wa; + Atom utf8string; + struct sigaction sa; + + /* do not transform children into zombies when they terminate */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + + /* clean up any zombies (inherited from .xinitrc etc) immediately */ + while (waitpid(-1, NULL, WNOHANG) > 0); + + /* init screen */ + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + bh = drw->fonts->h + 2; + updategeom(); + /* init atoms */ + utf8string = XInternAtom(dpy, "UTF8_STRING", False); + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); + wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + /* init cursors */ + cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ + if (LENGTH(tags) > LENGTH(tagsel)) + die("too few color schemes for the tags"); + scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *)); + for (i = 0; i < LENGTH(tagsel); i++) + tagscheme[i] = drw_scm_create(drw, tagsel[i], 2); + /* init bars */ + updatebars(); + updatestatus(); + /* supporting window for NetWMCheck */ + wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, + PropModeReplace, (unsigned char *) &wmcheckwin, 1); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, + PropModeReplace, (unsigned char *) "dwm", 3); + XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, + PropModeReplace, (unsigned char *) &wmcheckwin, 1); + /* EWMH support per view */ + XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, + PropModeReplace, (unsigned char *) netatom, NetLast); + XDeleteProperty(dpy, root, netatom[NetClientList]); + /* select events */ + wa.cursor = cursor[CurNormal]->cursor; + wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask + |ButtonPressMask|PointerMotionMask|EnterWindowMask + |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; + XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); +} + +void +seturgent(Client *c, int urg) +{ + XWMHints *wmh; + + c->isurgent = urg; + if (!(wmh = XGetWMHints(dpy, c->win))) + return; + wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); + XSetWMHints(dpy, c->win, wmh); + XFree(wmh); +} + +void +showhide(Client *c) +{ + if (!c) + return; + if (ISVISIBLE(c)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); + } else { + /* hide clients bottom up */ + showhide(c->snext); + XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); + } +} + +void +spawn(const Arg *arg) +{ + if (arg->v == dmenucmd) + dmenumon[0] = '0' + selmon->num; + if (fork() == 0) { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); + execvp(((char **)arg->v)[0], (char **)arg->v); + die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); + } +} + +void +tag(const Arg *arg) +{ + if (selmon->sel && arg->ui & TAGMASK) { + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); + } +} + +void +tagmon(const Arg *arg) +{ + if (!selmon->sel || !mons->next) + return; + sendmon(selmon->sel, dirtomon(arg->i)); +} + +void +tile(Monitor *m) +{ + unsigned int i, n, h, mw, my, ty; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + + if (n > m->nmaster) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); + if (my + HEIGHT(c) < m->wh) + my += HEIGHT(c); + } else { + h = (m->wh - ty) / (n - i); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); + if (ty + HEIGHT(c) < m->wh) + ty += HEIGHT(c); + } +} + +void +togglebar(const Arg *arg) +{ + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +} + +void +togglefloating(const Arg *arg) +{ + if (!selmon->sel) + return; + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, + selmon->sel->w, selmon->sel->h, 0); + arrange(selmon); +} + +void +toggletag(const Arg *arg) +{ + unsigned int newtags; + + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { + selmon->sel->tags = newtags; + focus(NULL); + arrange(selmon); + } +} + +void +toggleview(const Arg *arg) +{ + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if (newtagset) { + selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); + arrange(selmon); + } +} + +void +unfocus(Client *c, int setfocus) +{ + if (!c) + return; + grabbuttons(c, 0); + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); + if (setfocus) { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } +} + +void +unmanage(Client *c, int destroyed) +{ + Monitor *m = c->mon; + XWindowChanges wc; + + detach(c); + detachstack(c); + if (!destroyed) { + wc.border_width = c->oldbw; + XGrabServer(dpy); /* avoid race conditions */ + XSetErrorHandler(xerrordummy); + XSelectInput(dpy, c->win, NoEventMask); + XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + setclientstate(c, WithdrawnState); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } + free(c); + focus(NULL); + updateclientlist(); + arrange(m); +} + +void +unmapnotify(XEvent *e) +{ + Client *c; + XUnmapEvent *ev = &e->xunmap; + + if ((c = wintoclient(ev->window))) { + if (ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); + } +} + +void +updatebars(void) +{ + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, + .background_pixmap = ParentRelative, + .event_mask = ButtonPressMask|ExposureMask + }; + XClassHint ch = {"dwm", "dwm"}; + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->barwin); + XSetClassHint(dpy, m->barwin, &ch); + } +} + +void +updatebarpos(Monitor *m) +{ + m->wy = m->my; + m->wh = m->mh; + if (m->showbar) { + m->wh -= bh; + m->by = m->topbar ? m->wy : m->wy + m->wh; + m->wy = m->topbar ? m->wy + bh : m->wy; + } else + m->by = -bh; +} + +void +updateclientlist() +{ + Client *c; + Monitor *m; + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], + XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +} + +int +updategeom(void) +{ + int dirty = 0; + +#ifdef XINERAMA + if (XineramaIsActive(dpy)) { + int i, j, n, nn; + Client *c; + Monitor *m; + XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); + XineramaScreenInfo *unique = NULL; + + for (n = 0, m = mons; m; m = m->next, n++); + /* only consider unique geometries as separate screens */ + unique = ecalloc(nn, sizeof(XineramaScreenInfo)); + for (i = 0, j = 0; i < nn; i++) + if (isuniquegeom(unique, j, &info[i])) + memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); + XFree(info); + nn = j; + + /* new monitors if nn > n */ + for (i = n; i < nn; i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); + } + /* removed monitors if n > nn */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while ((c = m->clients)) { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachstack(c); + } + if (m == selmon) + selmon = mons; + cleanupmon(m); + } + free(unique); + } else +#endif /* XINERAMA */ + { /* default monitor setup */ + if (!mons) + mons = createmon(); + if (mons->mw != sw || mons->mh != sh) { + dirty = 1; + mons->mw = mons->ww = sw; + mons->mh = mons->wh = sh; + updatebarpos(mons); + } + } + if (dirty) { + selmon = mons; + selmon = wintomon(root); + } + return dirty; +} + +void +updatenumlockmask(void) +{ + unsigned int i, j; + XModifierKeymap *modmap; + + numlockmask = 0; + modmap = XGetModifierMapping(dpy); + for (i = 0; i < 8; i++) + for (j = 0; j < modmap->max_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] + == XKeysymToKeycode(dpy, XK_Num_Lock)) + numlockmask = (1 << i); + XFreeModifiermap(modmap); +} + +void +updatesizehints(Client *c) +{ + long msize; + XSizeHints size; + + if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) + /* size is uninitialized, ensure that size.flags aren't used */ + size.flags = PSize; + if (size.flags & PBaseSize) { + c->basew = size.base_width; + c->baseh = size.base_height; + } else if (size.flags & PMinSize) { + c->basew = size.min_width; + c->baseh = size.min_height; + } else + c->basew = c->baseh = 0; + if (size.flags & PResizeInc) { + c->incw = size.width_inc; + c->inch = size.height_inc; + } else + c->incw = c->inch = 0; + if (size.flags & PMaxSize) { + c->maxw = size.max_width; + c->maxh = size.max_height; + } else + c->maxw = c->maxh = 0; + if (size.flags & PMinSize) { + c->minw = size.min_width; + c->minh = size.min_height; + } else if (size.flags & PBaseSize) { + c->minw = size.base_width; + c->minh = size.base_height; + } else + c->minw = c->minh = 0; + if (size.flags & PAspect) { + c->mina = (float)size.min_aspect.y / size.min_aspect.x; + c->maxa = (float)size.max_aspect.x / size.max_aspect.y; + } else + c->maxa = c->mina = 0.0; + c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); + c->hintsvalid = 1; +} + +void +updatestatus(void) +{ + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); + drawbar(selmon); +} + +void +updatetitle(Client *c) +{ + if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) + gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); + if (c->name[0] == '\0') /* hack to mark broken clients */ + strcpy(c->name, broken); +} + +void +updatewindowtype(Client *c) +{ + Atom state = getatomprop(c, netatom[NetWMState]); + Atom wtype = getatomprop(c, netatom[NetWMWindowType]); + + if (state == netatom[NetWMFullscreen]) + setfullscreen(c, 1); + if (wtype == netatom[NetWMWindowTypeDialog]) + c->isfloating = 1; +} + +void +updatewmhints(Client *c) +{ + XWMHints *wmh; + + if ((wmh = XGetWMHints(dpy, c->win))) { + if (c == selmon->sel && wmh->flags & XUrgencyHint) { + wmh->flags &= ~XUrgencyHint; + XSetWMHints(dpy, c->win, wmh); + } else + c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; + if (wmh->flags & InputHint) + c->neverfocus = !wmh->input; + else + c->neverfocus = 0; + XFree(wmh); + } +} + +void +view(const Arg *arg) +{ + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); +} + +Client * +wintoclient(Window w) +{ + Client *c; + Monitor *m; + + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + if (c->win == w) + return c; + return NULL; +} + +Monitor * +wintomon(Window w) +{ + int x, y; + Client *c; + Monitor *m; + + if (w == root && getrootptr(&x, &y)) + return recttomon(x, y, 1, 1); + for (m = mons; m; m = m->next) + if (w == m->barwin) + return m; + if ((c = wintoclient(w))) + return c->mon; + return selmon; +} + +/* There's no way to check accesses to destroyed windows, thus those cases are + * ignored (especially on UnmapNotify's). Other types of errors call Xlibs + * default error handler, which may call exit. */ +int +xerror(Display *dpy, XErrorEvent *ee) +{ + if (ee->error_code == BadWindow + || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) + || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) + || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) + || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) + || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) + || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) + || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) + || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) + return 0; + fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", + ee->request_code, ee->error_code); + return xerrorxlib(dpy, ee); /* may call exit */ +} + +int +xerrordummy(Display *dpy, XErrorEvent *ee) +{ + return 0; +} + +/* Startup Error handler to check if another window manager + * is already running. */ +int +xerrorstart(Display *dpy, XErrorEvent *ee) +{ + die("dwm: another window manager is already running"); + return -1; +} + +void +zoom(const Arg *arg) +{ + Client *c = selmon->sel; + + if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) + return; + if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next))) + return; + pop(c); +} + +int +main(int argc, char *argv[]) +{ + if (argc == 2 && !strcmp("-v", argv[1])) + die("dwm-"VERSION); + else if (argc != 1) + die("usage: dwm [-v]"); + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display"); + checkotherwm(); + setup(); +#ifdef __OpenBSD__ + if (pledge("stdio rpath proc exec", NULL) == -1) + die("pledge"); +#endif /* __OpenBSD__ */ + scan(); + run(); + cleanup(); + XCloseDisplay(dpy); + return EXIT_SUCCESS; +} diff --git a/dwm/dwm.o b/dwm/dwm.o new file mode 100644 index 0000000000000000000000000000000000000000..7bdf5a2f015d759347035b9ea747e5997d4c8fbd GIT binary patch literal 58728 zcmeIbeRx&HwFkUU5-=d16D?M1Q4b|*P{ahOCWAMotaUOWR@4Qr#rjY{&l5(;y>Kc>#A{)8iKl1xdW~@skYPgjuLG_ zdgE2db&`~=MCo$<^{VuxrGE7{-O=l*bn=bPor9!_oiXp3gntTMR>j+go#gt*(RtCU zvCv_+ZFh2}e|e!FD~|iI38B65l3lUL^erWyMiPG*v-fc#jJR9<%O}P|TjM4Bkhd>Z zawr~2?1+!q8rw+uv531j^3c|j&YK5$ofY1*u3ypI{quyke@>@ACEuSuHodCS@lPaD zZ^{I3`o!cYe?|3}7h+xqF4~Tya^medxp8mG$hITNtk7N%b$8b=1V;4Gqj_?tZ1HqZ5CXZu`YlQ&C5T4(VMzvpeIF$0kQ(tB+NT``gvAt9ni+sb&{-;GD#Debr46=%21X zs~N_VI??r1$!>I%3#2PK)b)0u>8ba-&vCuVX4g-xa=yP=xXPnxYQZd&6z7&d*g`QQr`EXFNYQmk4~ExZYOR z+me1W@76aQ>VRWhKbh}#52fx2(|OeOep7&)?ql7ZX*!|wK&j3wL}sC6(uvB9>dXRU z7E30bP$IslqdGrIb?hd}>U`Jr?kW{ZI-&Hy>f~7;M$Ss)7vq0Cf8vLcYqqHC_=l0> z(5d;+bYZL1FdDm0APUaT?E~QR#sWmuO(ou_m9veum#!h8x>30hI2~(gY z@qSD4coXtjB(FL@2lZoc#`A}HYeyi{UptIQzDxffKMmD+Yey=Wg!S&E|F9!(ZB&87 z@jvdZrGvLNUqRFeHb8LA)6#nHXP*1Kr$>g+k=`~G44~V>t2^6vZv-1Bc16s48SW}J zv%IY%hCy8&^R}rRY9*XiM-{tguT!fp)KLyonxY*`$>E!i^OeY&a_-jUSKzvx%sX=KGs`PJj782mfbsBRq~OmO5N}4#ePj7aA4aZx=EKPB-G?JJ zYH~OnkBohz`xNBA7&&+E^5Mt_*V!G&R}SlNWbA%anBofkM+?Co?t4hwJNUhiKaY)h z$$xZ$hK}*}0~zz87C9bzqhw1YvCD6ZBRdvCOFPig4!^CK$UBmQkUbsQJP40b`O`b% zCBGumOr0Drd6Y~qb$m%XsXH|!UeZRoO@4V!+&dii-h-;(Tw_HY&*%c+TW)#y!m=!?fu7cBh!r|5#s^yZq( zRY%b|UMI~^55I zjw~;F7qy>E{R?k_!<86bA0{GWGu?yA{U!Oua1g^Fv{PQxQ(kn$ZF@Dc=8w4aeG)eY z=Q^BtO^o?Bwh_|(vALa9{*?IR z)N8JP-_F(QcpiJ7ovvS&OMRC;r|00D&dR6OBl~H{&OO}zb(}h`>U%=nP0#Ha_6>E` zeoLO~x%gCKYO1Vsy@yv5fwyrT9d$ra6mrYRiI9*ZaH z+g5`GNtQc+WO*=hW#Ti*y3s-U$M zyDC2?j)9fq>gc+>OJ~gMjXdlL2dCBi1-%3MT zP$zGRMV>Cgry>jgF3-Wg*x>S#H*X$Z(i%-gN-oP!4K1lENDV3}8=E{U?o}Zgcs-_K zOs}=jYmIuBP4F(u_o|A$ssgWUqE|LHv*sgmFms@rtrh7l!@BQGlqe6DIws*M|DN!6 z#^6bAMo*WQ{N?6(9H&h6c1=Zphby30>i9twUPt%475+*%%%0@qyz0@FS9qm0nV!Qv zJr#beCgI(wdf!vaA|Q#3>8_!Q!B&y5kcu2S2~flb~@F=#GR*_828JH{mVwW zTMi!MX0Ih>`c;K98$&}W22kDF(_G5FW0B*R7FRBk8A^|&^tM9R+u?d;SU<4RIR5fm zttADnX(_-0sE#9p>bipbs;`^+h0yHQZKN5@XSCvrtSQgNw8Ar+n%2}Jq(B-~atesi z#3@*M*5;(sz+odw(c{pi=td*gD)P8c{}~G(zy5O=<2kaJdRs@ zsXrluC606nB7fCn-CpK$WK$N2MSh=K{XHi8_>=NcpJG0p5l6J1-;>PG^Aq{en72ih zzw(-R+fDhylL_d|)fy)zBU4yimetZ24~!s4sALy+6gCBtZ=gFbg!juZ2d_7D3maRB@Z) z-Vte5?Bjn@kf2);_irqY&5n6HVsm0+-j9vh8Q0TUr2P?8h5=IxJ7SAg0w=G7QRwDI z?#4VdVXs|fPiyUeQzhvAW#MDfR@W?xI zd2bD$EJ9e>*Q+(NU5q#y&qcdIsRu6;AZjTPpA(y_7V@1~#hikMs_7yO_n-Lz`7Mmc z?sw-P6XS}4xm`rzr^ylfm8E`sy*oNh-I~0?zl(xr->1mg^?$QY9s0!SEfmMl-n*LE zq*vx*lPUd#-fcQ3{lpTKaZ>rdpGTbTB2Hvd-s}Evh6%+xEMqBx;|l0eDx8!-a! zmA(ZAwqi2mbBTNapGyj&H3ZhaA1S4Iza_ucf3HVZh2eg&>myj*?s|Jyzx8=}+gr)O zbh;&uKE) zNIs`%cSU*+g8p~lK-CT!H^MNUczyxR&ot%29CA^}QL%N@_&-vemsZZuD#M%!{eRg_ z-;|#R1>KaNo6Nz6;+Z-ZzF@!|iiCHN6y?ITL7?Jc7B z`K@Z;_R=Fe@{(acR_e9U8mj96{`u=^9JcLCox*O;Ur9E4bTt~FhH9j(iAwuVs=+@u z3MQfCNq!p*O|NYPv4|Ch_InD5V_OykS&04HXdHWOBNf4fc&Niu2y%0hC;DwPQoS}B zHrOEc)FrZVDT`KiUYpv|iB0s>rKb0%7qr2pwNurYP&(U(e$5-WM(mUGM3yqY}A zzlWL?dz`uqOT+KQKE|HN7H=1wcw6FQcDLtzMazk;V_lE`B#DXbl2B-8$scYRM|{RG zA2ly(KA(6y6`N1IEn_~JgdLCG#$+eMrK|rsOz)%Aze7rIQ<`Eo*{0lN%5SH7{Ch}r z*MF3TB^p94#U2ak!W24c~Av zN9THn6W$JBQMMuFh>QN~J+ERl!f96vZt+97#e>xKLEE`&^7kW~Og(|+FfA!nRWRg1 zSV?u?M0T9#&cj-{y|M@44E#dG?b+p)jNF-eH?|oqbs*?4Rfv4VGpvmShRz6@vii@q z7)v8Ykv!O#RIM!q;zkv6RemLnwHjQAzthqU;K>ex1`!s`ew{PZPt%A8&wo;AXzp7V z?bhp5iXzu0ZHTKCLP{E6K7r4dZ-+=j~ z2R9k~JBh7Z;zpB$x|%V0b<+Nf)_=R2i)Tb0TTxxKFVX&!`;P&oF}q`tnkZSEn>vG6 zFxlsoSEirI`gq@{t*hVsXDWi(2+@8AJa7ArBYO6_>CR}P_P5 zs#vUeXX==^r^0MnJ@4r0O#dS{^$6B$?^}^aZ}_gjZJzI67 z$yeTv-o&mEwtBWF^yW;-Rrz@>ixTapBgaW#2{yvpe>My}@(_Z5+`riFRFuHwr!GWP zAM=OjmmNF&p-S&hWH@T+gqT)GZd_+fwM*4F`$`15IVnsp+oDrTK1%((r?Y!K4SuSM zZjB5y1z^DHT}aw_LL{Sz(>E4`QiJDo{R~z&M>a%gOk+r=---6qFE)cRhp|z}`fVqB zL z>58_ka;$BusOU=W__g)iazetN)QruD)VT@WyzVo^>6GkEg|RU~n?D#vsgJsc$rW-w zN_ZVue->k_7$M54Xy$El_gH+;fScWQ?FT(QHJzB5G0IPY=0Vb!d7QRO(4Vi+bWC^8 zR%2hp_4PWm?Opgr|K`Tb-D*>1X><2GMi!#+_cK3M(>QY8y;}9Pzjg^U*LEbb=Eu-B z?6s`~*S+gS<;xa@;G*EIlhHlG$Iwk=Ps+)zOIhE()`oRSRq-5}A(@a3I;J zdW!$=QqjY2Mvydq6#uofS{jlTYXcQ0DA7E%bnw)o!Bb*;YDp3I^aA4QzmV#mSdDTu zv*&bGsgZI80x8{@Zy*;vxq^Dsj}^EVDc6!hRI8VNC9zWY)r(?osv7yl`c`cEXefCi z#!mWZR_eH-Bk89}n@(xu?j2WlC1?U*F7RB;Wo2!0c>3vDB1;{sn9T0_0s6m2?%2Bi zN;Oj~U}mXn(oa)co#e>$(>1Exmv*jI2td|)_k>Dc-8e(n>r5ilcc6TA>n-l9du5rC zN(;*Q&F-2GFF+3fz@8Q2&x(@{#<)KAtam3zc`v&c-SP2iu)@t_KhK|n?0tA}!Mj^+ zb9Wz`J{1rsQ?!d>FZE%i&0#vK`zv+BH9N?h7l12CF=4DYG}2}X&|?@;?nSPV?5%>3weEGTCc z`qM|c{t7ImX%|T`XJU5FtioYxy{tQzd+rvf^Xq7dlldujv*AY;_bb_c@vl*X$)z_! zV>XI4oKP*VAqS#uzj&3!Wwsh|a6wh#53tHDIVSZbwmrXeM7pDJovK4|gk%%NF460` z{z@Ipadp|QkC1Ce@0EW10XildOCpZ@9o5<>J`teQpO-tO>TScDx-bWWveGDXP) zPu2z4X>h&6vhvPFB}KatAn1j+YFNKYdBv?a!$GW9+_;-XwPA69|D~0Sa&!;q)i%O! zsGiI=H{t(}R@x9rYf}5t!pGEcdX9h*#prHp ziR!`B(7uV5f)n12()VTi$7ytP?IP9e)EU@`EI2cD8mTU~H_nN)9j2<%bThJRAAEWG z#^O+9&2s=VC%;Ngc01g8WX)!x^2-V^O%){P<9{6XnLau?RZlU-TDarPM+h{!XQrQ2 z^GYhgt1{_J?@gsdIEnEt?&xKnd>5oA7v)9W6(v(2R`sITTT zaZ`6Z9>)g?6Y5kqToq^eSBJNdsB2MpOa<O+p01ugW0%A9^yS$nJ*p6DkBq4n^<)1Noi`C11}B*-x!iwQA$> zE3uz=*Gko>n#Rm%6)CcRRi@Fq@l}djD(qm1L+Bsb(z$55YAJ+I3QW;}u zO@1x_TGii_kJ~d#@|%^ISdDw{J$*d-aOawQ+6=^Pmpt;b&7jt6Uc@}l_w+5A+d5X^ zewP+(-r9qp!VJRq-uiAXLC`$k#qEaDk^D%SzIPbcl&WsUv)8-rl)G=>2>;rV!rp_b zMbSz-<^E1-v0s|2d8IqDnCTxVz~fHZ$BenO;)KR(UrHlcRbvtN6XE~zdiC|c)XP(G zWfjVXO+7!gG60`o;ZNlPc$zl(2B`UQm?+jmJntd4{X#wcDG=nGf)d)8HRmCUb6GCm z?`IYXUbL}sd+(`jMmN1($4nKW*RUAPt?;ndo&JZL+M7A^P1u`W^=8f||F7o>+T)V2 zQ*R6C{Q$MT)ndS*M`f3(cl!zBNH3M(?ezFEo2KspFG6dSCqxBG1K^Ut)}SsB+enJj zD%UkIHPxZWH;n>8|5`LTvxlFw*{j7|Zw1lb3i=0ev;m-n(EQlRdv84MxacljyR-|D zB3z7{bY`Q28U zZn`7Suf9FEH6(ZO=nlGpn9JdFOI}R`Eqjwf>Ze zsbh;?)elu*k6S;n%UwPEwVs|K`y*@q1x2)i`)N)q@jw#TSbTTUMB9AB>Z2{bZksC>NZK{{k@1dPJIDSh#-b&yPsOKR&OpSMbmbZ z?)3JH)BAdtN@~}fjihKFTZIODZCtHDIZN$M3H=eZGsQV7@WmW{y4s9Ub;=T~{o;bY z8dZ)i!|^p*?c*6a9tZsmmzk?5j}$)L^{W}l%tKUAg_`u-)V{l|#D1El20R(-*3)Hn3CmU!~k^F`cmDD`WKbqSR} z23k1~i~Mj~dE~LTVt87n>nybxGZ#kU_|?j&ce7lK$*+Xx-aj1S#cR5X5HZ7kk3)ML%o5j?>M7!)>i=+)XSm*>S?NO|FIEaxIbQXxE__2% zU-6o*!(E2Q*L6nLybNCH$CV?FwC$#gZ#cJ{>-vw=P{&#(vgQte{Ajt)-@N&*TExtA z{il_S-jA)J8dw+}%f`Oq7r)`-M#_)MLr1TGCmzil;CW<&3Ko<)K#SswDl;3@V-`vS zv%B{F3C7OP=$*!kD|rA!udIG2LLKNG>FJftPV&4e{~MWgw4gIwKqoyfv9cDvwv+sr z9)XxZx-LMa)<}Gs%!uwtKDC}SlYR%^IWTT>ySUAbbxM>%g%O}++x8xyC3yuNhRRNO zxc{iWSbzg9Z~U?xoQ=d84#O0Xi?gT(@)R%(0PQH_FkAt7IIF~2<{{d&^ClGGANapHCnjIl=OtxD%QHEjEHdD?4F?o*(lkkAzxi)sNE=u^~z%wMeJ@ zFUS08(GqtAcFS=erTZOjRz-S;2%0E46lqIh)IwZr#9&@iHA0IJxQ7RC%vWqH^q1h& zNKGB%Pr|bPHkUyNLCOGSLLJoCB=k2Y%6--6p^nhb&jFxb=)yuG<`(L1U^Buu3XEM*>W6O1fOBE>$E8q_LuX?K&WfLVD|u^{GSGn13fJh{Y}U z@1y~TZli(N_t=)wTZP_r)1gB%cB-(2s5E(HMTr_Rsbkr%EQZeoHH9DvZ&ht(8B`;q zOOHCm5UzR~M^e~F{=!{DgdV+<#!Of5D$oWuc8w7#t-yF!{!y`l!GBGjHO9!lu^@B* zPUQzu6wJJbVCD?$6j3n4GFSPPao4Y@#e-!0KpZ_tR!f269DedEg}d@AYckjF0Hcyl z+L2b@=*V17fc`2-A&tmiY^T=gJt}kuHi}etcr`VdztDz~zS%XWtMSj|Ufq)4l3tSY z5TE~D>5|%1nYloD>DMz?f?H-C{`uvluJ<6(7WMe?HrG?TWUgP18q&JM%dsnk;MPm4 z4)?BZ%p_5vUJQJSg|9R=fmPO2gcV;C52PlC;gy&i7K1F|Jr5=A=&FM+=!?VXL1@w~ ztJ(1Ty-%O`O;8xVrt&<(8eZ2#+P2~%a~k3^{dCf%1bEOhkm_qa%*dWc!UH=}kTjtIoU1)31Gc&T)b3F-fU(c@I zr=|PW!HM?z{1HzjR_DP^_2w!)G&3T7bXfA_RYTK92PaSKx&(~VM~CBK$)hJl+6r+6 zR~hRWzO##_DDv-k@MnKwOa^I`;SQjhv(ex&d*lAJ z!ic-2e9WO3F4`MI8;KHMJL_O&l!vvqfXqF+ut|J%+rEmWRz27tP(IKaET@7aJ$N&mc9Qcl3lI{~ z4Txg^QNdV0-q{hY7c>ES1Y9H8v+fu!h{#=sow5%(FB%2$WWQ^jwZ$& z(qo_upjbwAehr>izbfuG7lvLr8xQ{A8-i!!(Vw{Y@t8k&pMU(Pi2HH+^V4qmy8mPX z#r#Lf5aYgEj4zGfQjVyheFCDtm*d{^V?OR9Up2UV%$9QRcQAbK4`ZJ1%ebWwBfx)@ zSm8@-+N|0qw!oU(Cq%{^_Fkq64|~s`%2k7aj``Gg<7}+x^IfZABsjCr0rJ}z2 z5+a@sB=>?RzWavGY`Ey|*>UfKv(=N3-YyzCTWIJE_g*+#J!sg6-BLumQ5ZNsd>!44 z6VZ-~Nr)>|Ph{UI<}GiIo_Tuf znbG-m3zsz1Uq~6}oIh@Yv#cpPziC;r6=hRP>Z8{-M3*$x)i>0Sb7odgE}mOeJ)>gU z6ld1dxs@}fS5GgSo~WXWczL3{x_s`eifQrbvk0iFj#Zb_NpVXTRP}7p8d38$~qOGas=BAe9P_5c|b<5C=(Wd5xWzqVDt<6j7u6J6S8yZNx zt@BzM8kV&-HYHQZg-fF6v_{XFAN{)1nsn-yHY`icMfW=AEOpMAkHfNS@tN|8SO5@*iTtDPwemo__-7q&FaZ(8Y$p05&)^%q=FbO9fW`BB42H)(cw~-q3JyQDNU#lgKesgw!vD zX#{|$&wH}ynQN@C%o|zy9OHj*_i;VXV>zY){>=$~2C)cnlm4C{c?vw3qx`bTr+bLR zrf(wDr2)iuF{nWQTW7igdM-~tk$@lOKum(AH9{lhrllm`&NJ`gHS;#DCX|`cY)`)& zEeIZ=$eZdN!s=H9*F*_q(uWB#RrphU=mr@@2NR3mR;N)(~!g@DDPso5eLC-Es)U3LX)xxHaW+&goLz!!O zMLQ zuO6C0tfU@`DCi|*zfTXpLXnCA#ZKNGY7x?Xf!n?z{{c{QEwaLdz5L9bw}!KF)Ys5` z%tbwWyVuayglO4YC-qAMX&N23s2s> z)+<0yr^?3NwCogq6-RHY`!~x<`sQ4n%^UOmZAoY8n#}Y5GVs&hdRa+|lD7A|d1aR8 z^ELT2h6f1HXsj1?7$F*QRS6mWj(pjBkbJs*IZzTDfz*IWa5>sUv?H90kJJ;C|KF7t zIqdRs9mHSq|Eu!sY~fN^#GPWH~&k1s|gzC!v9(WGfyRd zkqP2l^db3+t$Z4_1WEovE8i|(Z{^$N8?F53_9UJpNcb=LV!rb7k{_fW$sh9H=x?6I zUoNG5QUL2H`SUGYE+v1d0M=3RqZTfg(!W9ZQl4T?Gl_nsd{DlWA8QuIxs;duaaO+c zuka5lFZn^`g?~{1|6z;=Tue5wCDtA6r( zl%)Qke5pSuU+NFam-^{p6*CDg^#|ok{XzLse^9>Eqe4MLfIL2z`h)VN{-AuRKPX@7 zKi{aEPNRG+^#|ok{XzLse^9>Ee*xDghf=HlpnR!6C|~Li%9r|!rD8s=w(1Ycm->V9 zrT(CNslUXkUnU^Ye^9>EACxck2jxro>+JgfKe#3zDtr+^|gaaqt`8{~o1ZenS_3?;DP@`Ww!ava$=K z1ydT9C7YU}MMdMz8&@>9d3@pc@kQecOQOx^jbSh>qMeghpZ3+JV?vX+J6c!_=;=b_;$5q2M+7xIy?hxuIAF(m&s##CEk;k+4ON`C$T z<3FI|<>9mC!9O^SiogC59h{q>;WmYdju{&Wll#9Fm1@2vhnl{fmd2v%Ve9CEiKK zw-b)Cx1(%n))T5|0?^%@e;x&Y72&*ZWx3%I?b&WPdPh!0xZw6dZn!W#IJ-MEG+c0L zI65gjVv>@+91SUm832msA~@EY4(FzstuOj$fifKk)2KYP<2cWLvK^U z4~Me6@WxPixFd9Fcvq+*yf+jN?+;B19}HDe<~-4=#o#|3%766KKKHXu}dcuH8XI~m#pOrl-)TaybBh5^!*7@j{JF?<5CZYXwPF590 zWxUsv$ucn}wa&gkolW*$mL<%QMf@i+?YlVF{89bwpha6Q z4X@71dMO-5X=#QUi_Kg{?PDnZP2mw3+1Dz%%aqQ^&)v&(XAo~B(%lBeM0f3E(|3^W zZqJE_3)18lvSuh3071}TXfKX(Z*e)F7y;&SjaqqJEBlMlxGsYunjbF4z_W&RHHwZM zObi@na*%)M<3rx=h49LFcy(xAcqNpa{4adP8s>WvF^5jlS<{uPC0}tBpr3O7m$=?9 zjAe+M9*kbist(so3)jN%CsDUnHiv7f!nGJr`m%9=flj*4Ifg36e5nuG|1&m9WnfO} zl}P)aV$K);b$iy;ieforo`^CvoIjJtL^^9B*>*JRI_mB`R}o(x9s&QIb+fjs-WsAP ze=nC;eFmLmU8%CkiISD)()_ZSX;$LgSryJ}Mcp)BUt&B(IL1@fd?}^p+K)KDp7N1M z2kOV9ar_zqNW_06#vY|9^p9jfy~KY4<98B{c{OW!AAicP=6q$Rsy~%-E+x5XUQTlU zaw%KR2IB%r#YR*XKmJ>wHm{@vEHk^Z_M#_h6-OO`PG3=WrAR7C{Omi2}DBn^OE}gG@ zOH6!=vbxfyUf;5W%hdIj!MrZMZ-$b-*WcaCwBKO+;dV|57v5yJyR1WIoA+>;bEpjZ zJ)M=EAA-C|TxK{ghkOC#HGKz$dV0{5a7R}5joIN{Su?|X;aK+Lb1zc> zKBKpPC&M-#N5jj4Y=ioF50|}-+OPUV%`M6wlLJ3Kq};>YaE%+TTo{h($wH~ziK56b z3ht05&_CE#y)ue2F%31g3Yq3KrkT~73!4B|$@w=@{_NiQgJP|zkUt(IKiTXZTvm!E*{#+{wda}*8sIlb9WAC`sSX#m{Q4I zL2@U;>qFU_v%~j>V&VHkS<`Xi0?L{-(9}U=a5MA1lB0g)`UevnXDQ`hO8r-%{Yw-!-)nx_KThOL9kr)9H=IYa_Zk$dX1s{v zy}&lB`F2Y9{;aGe;RjI5!|2hC_;ld>{;X?&T>~s(VARn zuX7AMu+8+zQ338V!F?L)q=8RzWS3_R#NJ7O|HLrPPqmBjA1Ksu zZo`q}e}HjmS3A>RM>dMIKp&iYaU}Y^d@c0%;hOl%`cAFCfo))XDmPTExq&^#_*;x` z$2Fxvm=B51FF7_=Yi;0gTdLm8ET`y=;t$m?7QP!e@i{<-ghcXDdI2B8SF+%0O%06t zoAB3AKc%zu!FdBm!jIuOOvRPJ$mfRW?jzGne|^aGbxdD}Yf7KvLvlW>uKMmNK@0!7;5e$p$BPu6>)g-!aXGt`=^th~k(1Ug#D722ardb4 zLwdOP1f8MQ!8pAV^n^dkxLN}Pzn1YkzNG2Z+83vb7~jkTVv){Pdp^YHj1x8BF;1}x z;SVu>KjS`dl5;hVl%ndt<9wUxr+--kYMqMHpD_MI3M7!;)d%NSjQd~Fz+%Q915W&- zI8qY5(Zd`h&k?3SLuWfX7#~Rv5J}qg7sV&nsbxO&i+hxQukak_e#S-r&*Pf--_Cq| zP42wG`0-!WfLdeX^lipxjnueWBjWTZ1Q*ZWc+K4H!%Jk#-&|NjK9XXTC1VV4U8{g2GWnKfrp%-PL%mJ^U+gy-)w+O zmA;J=(&x)x)7Q%x|32f1(HeM%@&9DJI9~%38K>VNAU;XPFJ=5$;33>~7JtWPW7x(uiPV0;tfbxc1DO`>{FW&>C2EactI^jDs#3DsH(r(b3I+Y2lQS8=U&GFNK8|C&l^Oze8ym;|p03iFa;b{9hSovv$@ozM1hGH5=z{#xLN2NbL4U zz{$@@l6L)q>3_iVYFz`O$&9a2LA8UYM0KKhgY>Y8afx$&!}w9gyP5te#{bL>n#A}5 z#!qL)YF&c7oxsU&l=3`M$@I@L{U*L~EB3ix(Zhc--8w$L#`M`2YG5_vZ!(@{d@18^ zGk%D1Zie##2cIR80D*zC`0H=I1)Hoxyz8|B&4~>-OOh z@F9E7V@QrCF)oyX({(oJ?R2W5AJ(fMp)X*Zr>R~E#xpMVA;*gum-2$Uj7zNvGbUuWesFh1YH7b%>BC?l_l`I~Z6c9L;v zuN1kS`7aWHkGC+Mw(vEK%RD66-(>t}0`PG?jo`1ot4|HQ%{VVu5KW2VO$KheTF7$0rnI~bp6;d>aD`CIDP$M`~vem~=DEc{Q5 z-(%r=y)nqS*TUasdRYfay@we8rA2>)@$DA=8F1T16fdl22EvaCz)uXozZQW15&m%? z{zU=wWdV3~06sSWr~4)Y)w?_ZZwtWbmv{!^b58*NlK}jY0DN}<{(J!bS^(Z1fFB9K zbKv3!YS#$?_?ZECVE|qdfX4#xsR8)x0DMsZzB~ZGEdakK0RKe*{@Vb2M*#kE0RFcC z{2u}MFa)#%_17r@ctHSO5`a$)z^@3vmj&QA1>oxf@Vf)>p9SE*4Zu4C@D~E`mjiIx zml;UUe-6Ok4#58rfFFwqd?5aG?`$Ca`~ZA%06sMUzcv707J$<})IjpA4#52Y{D%Sf zzX#x(0`Oe{_<;bN?%53_e<)x+8Ww+D&03R2CmjvL`0`NHjcw+$G8i3yh`~)MO zS9|Z6_}2!|e=7i|`-=nV^M?WWuLJNW0`MIH_zMB}p91i|1>p2u$Z_+W`i5lPyhc8> z;(W2QtYKvmUw&+;cdkngre#iR!xB2+)9R#}>+6yY*VeT(H?=y~ zHahrbY_e(Il7)EW&RMCx`C6Y^y7YQJM+Gf{GqiHa!fTy*OB(8yrJ9Lree?Cql)lW^ z2zIT`yryOI7cNM(G&n5{gfjou6;5j-iGd0m91_{7YiX%lwxEF+;hUV0jLz@{&!!aE zENDo!G&LoglPwM%wX8&-8?m6FX=z`3P;08CwW-CaZ>d{>_Th-?lF*HltXt6PENN-3 zt5>J<8XJ~22w5vcYFg2_uwKck^x4{wOtmZ^h3I-#EY+=oIM7G3!CA4i4vOt-C4W;G zdR|uFu$&5l#r&pusaEt2N`O{fEnMa-Zn(Y~I+1=@mRgFhye?i^*SgqQ&{B6TvRj>{ zbFKp30+OQJc*Q-5MU24e^{bg8m4)x|z)Pir?I?1L5 z3zjs@$2X3X^gU-trqxSlOXt_kOF9de&07Wu@W3V$llB%bT(U&Et+{Rm`kB5@J8x;d zK2g1}Ot%qwAvHI*G&PSy&$sHcLa_=c0E*D6OfF2K)A>*z+0N6GN`tpg>#moi<;=m$<$F$3B=c3rTbW^M~_i; zN=j=P+F|`%X1F@A|rB&bUNbA^j_&f9KJ^3H0yl^zVH7cLDt? zrhg^$4_{NJ|BAe5ygFBBWyhVqLHn+J#2 zfUl`z;5s#zry5$WuWSN)^iIvfWeqKLOY16HWAl;=mpAkRimFO~Ro$tXjIXRaHD$`( zNoDbd`6yhbJy^}uy5<>m3tQpQAz`v?NnL9zwSZjOTo`++c(4_7mC-jO=VH{XSXiIL z!~hcI^yq}90EIwFPR&#pkJP8w%S9QDk*V-OtO}(#tum^A)>J+xT&cQ}$DigoLm8?t zQ-wi*S*2-7t7<^SvgTBBvhs&DWiaIh4SftQYq*|%V4=DRC#}~nb!t$4YE%8f`3oCb zpayb;PL0k}G(@abC{(I#GnbM31RbnE|3m;Yh6Lbw)rET;~KcFO73B3vGyy1U?-<4r4;K|qLl860Vuo?l_DBqbM~-_)`g zzMA|v_36TTNB@R|;;OYdsi_4v z)l?|A7^AsPQKni<>ehKn<&q7*3ct9pq}Lp^Rp>^?k`Nbe6mAmgTmlnT_M_P9aKfpH zVf3v~)~frrZ-}6Q_=92gxdpWKi=3%Pd&li8ghRa-#z4^hB{@s$FpZD`@mmql5yn4$ ztHPNN+a^i%Pgb-hG+HwqzgEGP$X=pa4f|>689mHIO|U|5NZaIFWjvW1M*W z*uYDP0TLa4f{)NoGw?P8uVS3|{M5kb8T2ZT>q}a=$hj^6-(cZ;PzR;|V4QgW3?Gqm za{&DogZ}3R{o4Wb$51CB5&sA95&mTaAkpEM_y}IjII*KskyG#EYV6+)`d0(^EXF<= zC7Vx@aVqv8K2mQwfc~2XJw0P0^#5kyru?*TM@j14D0YK=AQPA8a#mZo*x?}THwgXh zIFWi!55P~x`dH}K8uUesQ+t19;D@oUqD1(w@e%%C;#)a{KV;x1GfwTgfpF%#%)qIP z^w&2noODO&euMwRxR!c18Mvv>*8=!Nj#cb>^(^*3-onKXR54C6n*5ho^dkSQ20h&q z5jocf(EqDJ|DOi^FD!bIbB951>iMi;x?LpaZwx*cGA?!{d=6N+wD&Io_-7U_d}{et z7uEXwp7d^ZX zfWKwo!haawsEL__ABICrH z+A8(FV$n;z?^yUdEYC*6BaIfwi$dL zH~19tCLHOF{OWz|moG4Il2!P)j1y+cGtHvk!0m0Z@Rv}I(kcrVy?GWc^?r+Ss@K%p z-4?yn`+$Xuejc`P;r}~>zp0-$EPCnp;m50H^!k6{Gm3GNlYEuf=fnW|OAUHcpOqH9 zv}=}yOTBd#F8W+(@Hh3=WYG)%n=D-Pw${R>-n$L{rrtJK^up&U3l}-JTe$GwYvH2* z1B{cN&33(M(M!8NuyB#*GYgk`hw$^3#NTXJsezmIRxvLANBGaRaN%EX@G0t{# zqKESX==ED-bllrv&`+`GA3+|aMHVjlTpm#GGZy_F?1x{laN!f?=Xgo}t@w!iV-4Jl z17ikm>houei+)7@(Ico8U({Ox<5X`aK2qp`ajRYMgO%1pMM80(ZfmuH|6|s0H0qQ^xF+SPg(SF zmS=~Bla46;-oi!Bg9iT{pc6T}EPDCvfKM!3?4jUfRgD@)H{ewEK`u6M(y7!tiE+Yq z;v@B5ZqeVz?Yhsxh0l*IT%L=1(BQwz;Qx|EFMQrK=yx0R?^*OB&&02S2ubW=gT8bs zEL`|sY2m_WA>*WnXYmm|++fiQpH&7uVM2db0R8<2{c{HWZw>kz2n?Bc&&v`?moq&z?p9XG9g;Yv+Q`3BcC};6Dz)k1$T{`ZYc>UcNdC7f7NX zskg+yJ>(1hb-ocDhz5DPH{hVOnFByN^cxKN8Ur`wpBuoZ*}!iGA9icbDg!tB-8XRBVi&!wXPjv1yJ~{}z@Vo*Y3~CD z{eFY~R|ft^1AoH6Uor6Q2LC$@{5=DwdJo`3=`#x#d2&bVe4>4o=-6+6iSaC8lt;Rz zbh3pDpEC?TW;}L|MKAtjf`tqJi!5CDuM5EMVw_}r4IhzzlYyIlV`~7Pmkjzp8GJr9 zaFb6~K8TR0-q-PwdcS1g<~)9mft&N%M8<7Bms$9M5Y>j4f*N=`uBG022LFQwzQ~}@ z0WRZlrG@7+|Nk`bH0a0TLutE#6CYV;y=&ppUxQCq#gu-``R)`0H}z1)xadLn++@&i z1xsn~cMROr^MeL%@_)+WFZ1AQ7M@@|ykp@qKMp!Ww@c)#X8H>)e1j%)Hd(l|YYXF~ z%QuX6<(}D}zx2!57A|s5W1RSy?X9)wrQe?pz;^}UuUWXX>n#hHb{%4ztl;v z{J`fHF8l`-^w)#%AIdoKC*LOaFwLSDzcU*94E#NdzsU2sg>PoN`sx@IMiP4y{fx43xxZ6j;c|cH9L7m+f5AueR$|c8Jh+7G zEi-T`vkf0guEFQ8xE4Ou2K~1T{7QrV#|B<&(3|`h7&ysuA3l_l22S)FSk9X*T;eXz z!bQ*DHt;*aN96x5T;NLO$ z&oFS}Ka%w`D}ets7QOIaVBp_1_%AbX;xF?^YXJWnEPCOeHt>55{@*lk;y;$ss~L*kguaMzlE>T^z1YCbeZ|WH_{=cqO*@$vK)=+W zf6$Qg#sK=Y2EBQ|=Dq;>pBVIHBVxA?8MxW5#{&2~VbH&9@aZ)0Ul{lc79a5s`z@Sg zqV&3jOTWBj@HhQKw?!{@GNe%Rlm3-@PqJ{ScZ`Kgz4$JbN@Ne_JaUzRo8$d?i;wXC z%)-SFe7UHkt8q)MV^q5rah(|tgB zzHXF(lTNqk;?5b26SfH-k*Cn2m-T+5g-g9RSh)1#?FRq%4F2r~J;^Ec{>H#bru*1W zerDlPZ}xd0LJ~blyTXjy?HX>;OS{gnaN&QBg&$yfCRn)CTgtdy?_`T!>b=gOH|=?? zMKALFIso4sfWI4n|04i@ctU@DO1*!za2fAC7B2K({`$atu4SC`^AJAL@4GB|v7g@? z^lupSx#the|0@Pgb~SN`ri&Ul)h+z187J(0d_||J(%-L zm~m;Z#8DG0T=d;pn5KR-8c(?2|E@foR`lXc8%xCb0`b6{~@_!hBXJ6ExUdF`*7A}0&Sh&df0}KC%<@t$)Z(#h_j8i{; zh>z&)O^aUmcNsX1ug`dVg(hl-#E0q>KEoInJqVvu4f?+u^bc6{(%$NeHGknF_>V1I z_&?6LEzgz!`aK5y5ksCA1LzML^iLb~xt9zq=coYu62?hR(>@ym=>NmQKhxDYJ1kuK z_azG#{k+P!-S4^I=#$^<--v-z8R0XEal*`gTxQWrf89~q$DhgwzS+Wse<$NaYxc|E zEPCPN#6XB-+sP@66CYF0&k!LJ;b#1Q*9i(%_-34nJ>UMNKKw}oKjp+e+?-#25r7}} z)js-X3_c&8+J`@7;0<5v!(TS=y$1ec11}rhM}NS;H|F=@2MwIVe5JR4HSn)%a;1l( z2F}A&(YG7;RHi4j{?Ndy87DoPa?W9#=>H8L(Q^aiME{9_U&lDn|HQyo8u(g5udQ6k!R@DV;VXHl~GkZvgv{RVu59zW`-lE}G_ zuLtqbmUEavZ^|jZvuyJpVbD_@xAFbsvkY9ykRbH?-;`|m<-Qit{u3XOe?b6!E8|3O z&g1_QK>t01{tbh_^qc5s6b}^n-9^D4|CKx#JdIuj$r53(T!;Z^1(e~gY_0sP*QxZ83=u77sgWjCi z==Y2%5g!w83c#0J{C}!SJI>7(F8aC6;PZ3PikzNBFYWr4K~FwM=?wAZ4S-`_uE;qtrWdBhZnvguUtLJODQ_pc1Vn=M@46R3^w%K^e{B>=4SQjG7Wu_)#eWh`_UW*F76#B48#vMDi9H)Qi6H!I44ml2{+kWl zq+f60qoXK<^st3Xd-qzn*x?}ym*0`kBS(uQdJw$O!sYkeD+BOm3m19TTeysuhb>&> z+-u=7UJhBf@Xs66Uw+|VXyL-Y(!zy*vxN))^%gGtAGUDezt_Tr{~-$({&|A~>IH{MTD}ulyD+{P$Y8 z@IPeX!apxJKz<7s{*@Lk{F^OY_^-F{UimFt`0urF;eW`&DYjFI{SA%ZFM`hDG8tPjNfnJ-(>s&3%`T$hb{bD zjBm7XnI}3d{M$^w%fjh>D3tbE_;(oJZ{hbce$c|{y)cyWhUz1=mmqncP}IWZya zF7Fp9ws3hLiEH8V9-~?dm-qdwvv7IeiM)qWsq->&>RAbSLJ=9vb&^KDR&^H@6>E}La7Z;>Uh7>Zv!sXhv z@bB~WRTeJuU9*MLUNfaT^g-20^;WWc_glEUCsOurL{526G|hkze*1q82Xu7{wMY`v5f-F8eAnZiK(Q7w{2_Ufv5x z?|Gmk^zvT7qZTgj1suWgq|nRz|KxcV!Ou8d^KG{1<^6y1{Fl&6+$Hg?;PU>zcPu{g z{=a&T--KS)9XDCHtY7Z7aETB1TDZKQPvSk{FY)IDjspdkc(vNXB_1|^uae40{Jg=U zmw5ZAh08iCZSh&R1A6dBUUkyL5zdY#+^>wL* z%RWqvh0A;O4qCYEf0l;(_+PJ2_5X4BS?*-rwaz&F^szoR%2`XplDcu~*T%=;trB(4 zxNGrK^y6BZ=z_?L@YD9=dWnGGZ4&sUehn!iWP*O2`YmM}7f`Y5Wjn7GPYg*NxWF&S z&udzWmlGtNarhhsg~Vn zFUL|oJ1^D?sS}=-dqKL5PE$*1FQQM}+x4-4_nU{~lFG8X=v_CQ!8lKsx)A;+xn7}{ z44%g1QhmRiXzcQ?T1s*(=W|+G{wCY4$;R5o$b`%NIdQKm%5rD%Km}Lov57fu?ok5>d)P+ z2`bs&QTR*hEf$Fb$QJ3i8hEe?_ie3L|U{t@=P0qn; zfJpopp}xTXyxuc?vJM9-e}aXNn5hBLvt&#Ca=Zr_1C=l2^3*mn$+aARj7%zDXcFOk z0+;98v%R@QOG%Co8s{p5|1IG1CPwE{PVgsiLMCSGuaV2!a!I?TJarTCw9DVi<=3%a z7J9qx`7I;J! zGca%iWx0hJ8D`Cq01C2~c>21sUt<^MF=V?Ztt9{yk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(c+=CxF{I+w+q;fj4F)_6j>`Z3pZ>_($QEQ&92OXP z%lpEKGwG8$G-U1H{@Y%;mx-mNK|p|siBVAj$Z~Mt-~h6K0!}~{PyozQ07(f5fTdVi zm=-zT`NweeJ#%S&{fequZGmkDDC*%x$$Sa*fAP=$`nJkhx1Y~k<8b2;Hq)FOdV=P$ q&oWzoxz_&nv&n0)xBzV8k*jsxheTIy&cCY600f?{elF{r5}E*x)opSB literal 0 HcmV?d00001 diff --git a/dwm/patches/1-rainbowtags.patch b/dwm/patches/1-rainbowtags.patch new file mode 100644 index 0000000..6c31062 --- /dev/null +++ b/dwm/patches/1-rainbowtags.patch @@ -0,0 +1,59 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..3fb5cf8 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -21,6 +21,18 @@ static const char *colors[][3] = { + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + ++static const char *tagsel[][2] = { ++ { "#ffffff", "#ff0000" }, ++ { "#ffffff", "#ff7f00" }, ++ { "#000000", "#ffff00" }, ++ { "#000000", "#00ff00" }, ++ { "#ffffff", "#0000ff" }, ++ { "#ffffff", "#4b0082" }, ++ { "#ffffff", "#9400d3" }, ++ { "#000000", "#ffffff" }, ++ { "#ffffff", "#000000" }, ++}; ++ + static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class +diff --git a/dwm.c b/dwm.c +index b0b3466..c16d5f5 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -264,6 +264,7 @@ static Atom wmatom[WMLast], netatom[NetLast]; + static int running = 1; + static Cur *cursor[CurLast]; + static Clr **scheme; ++static Clr **tagscheme; + static Display *dpy; + static Drw *drw; + static Monitor *mons, *selmon; +@@ -717,7 +718,7 @@ drawbar(Monitor *m) + x = 0; + for (i = 0; i < LENGTH(tags); i++) { + w = TEXTW(tags[i]); +- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); ++ drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm])); + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, +@@ -1568,9 +1569,14 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ ++ if (LENGTH(tags) > LENGTH(tagsel)) ++ die("too few color schemes for the tags"); + scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); ++ tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *)); ++ for (i = 0; i < LENGTH(tagsel); i++) ++ tagscheme[i] = drw_scm_create(drw, tagsel[i], 2); + /* init bars */ + updatebars(); + updatestatus(); diff --git a/dwm/patches/2-custom.patch b/dwm/patches/2-custom.patch new file mode 100644 index 0000000..c97b30d --- /dev/null +++ b/dwm/patches/2-custom.patch @@ -0,0 +1,74 @@ +diff --git a/config.def.h b/config.def.h +--- a/config.def.h 2022-12-03 23:02:59.820577756 +0200 ++++ b/config.def.h 2022-12-03 23:15:09.844816736 +0200 +@@ -5,32 +5,37 @@ + static const unsigned int snap = 32; /* snap pixel */ + static const int showbar = 1; /* 0 means no bar */ + static const int topbar = 1; /* 0 means bottom bar */ +-static const char *fonts[] = { "monospace:size=10" }; +-static const char dmenufont[] = "monospace:size=10"; +-static const char col_gray1[] = "#222222"; +-static const char col_gray2[] = "#444444"; +-static const char col_gray3[] = "#bbbbbb"; +-static const char col_gray4[] = "#eeeeee"; +-static const char col_cyan[] = "#005577"; ++static const char *fonts[] = { "terminus:size=10" }; ++static const char dmenufont[] = "terminus:size=8"; ++static const char col_gray1[] = "#222222"; ++static const char col_gray2[] = "#1c1c1c"; ++static const char col_gray3[] = "#403f3f"; ++static const char col_gray4[] = "#666560"; ++static const char col_dmenu1[] = "#FD7717"; ++static const char col_dmenu2[] = "#ffffff"; ++static const char col_dmenu3[] = "#ffffff"; ++static const char col_cyan[] = "#222222"; + static const char *colors[][3] = { + /* fg bg border */ +- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, +- [SchemeSel] = { col_gray4, col_cyan, col_cyan }, ++ [SchemeNorm] = { col_dmenu2, col_cyan, col_cyan }, ++ [SchemeSel] = { col_dmenu2, col_cyan, col_dmenu2 }, + }; + + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + + static const char *tagsel[][2] = { +- { "#ffffff", "#ff0000" }, +- { "#ffffff", "#ff7f00" }, +- { "#000000", "#ffff00" }, +- { "#000000", "#00ff00" }, +- { "#ffffff", "#0000ff" }, +- { "#ffffff", "#4b0082" }, +- { "#ffffff", "#9400d3" }, +- { "#000000", "#ffffff" }, +- { "#ffffff", "#000000" }, ++ { "#ffffff", "#fd7717" }, ++ { "#ffffff", "#fd7718" }, ++ { "#ffffff", "#fd7719" }, ++ { "#ffffff", "#fd7720" }, ++ { "#ffffff", "#fd7721" }, ++ { "#ffffff", "#fd7722" }, ++ { "#ffffff", "#fd7723" }, ++ { "#ffffff", "#fd7724" }, ++ { "#ffffff", "#fd7725" }, + }; + + static const Rule rules[] = { +@@ -69,13 +74,60 @@ + + /* commands */ + static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; ++static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_dmenu2, "-sb", col_dmenu1, "-sf", col_dmenu2, NULL }; + static const char *termcmd[] = { "st", NULL }; ++static const char *takess[] = { "speedwm-screenshotutil -s -f 5", NULL }; + + static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, ++ { MODKEY|ShiftMask, XK_s, spawn, { .v = takess } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, diff --git a/dwm/transient.c b/dwm/transient.c new file mode 100644 index 0000000..040adb5 --- /dev/null +++ b/dwm/transient.c @@ -0,0 +1,42 @@ +/* cc transient.c -o transient -lX11 */ + +#include +#include +#include +#include + +int main(void) { + Display *d; + Window r, f, t = None; + XSizeHints h; + XEvent e; + + d = XOpenDisplay(NULL); + if (!d) + exit(1); + r = DefaultRootWindow(d); + + f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); + h.min_width = h.max_width = h.min_height = h.max_height = 400; + h.flags = PMinSize | PMaxSize; + XSetWMNormalHints(d, f, &h); + XStoreName(d, f, "floating"); + XMapWindow(d, f); + + XSelectInput(d, f, ExposureMask); + while (1) { + XNextEvent(d, &e); + + if (t == None) { + sleep(5); + t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); + XSetTransientForHint(d, t, f); + XStoreName(d, t, "transient"); + XMapWindow(d, t); + XSelectInput(d, t, ExposureMask); + } + } + + XCloseDisplay(d); + exit(0); +} diff --git a/dwm/util.c b/dwm/util.c new file mode 100644 index 0000000..96b82c9 --- /dev/null +++ b/dwm/util.c @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include + +#include "util.h" + +void +die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(1); +} + +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; +} diff --git a/dwm/util.h b/dwm/util.h new file mode 100644 index 0000000..f633b51 --- /dev/null +++ b/dwm/util.h @@ -0,0 +1,8 @@ +/* See LICENSE file for copyright and license details. */ + +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) + +void die(const char *fmt, ...); +void *ecalloc(size_t nmemb, size_t size); diff --git a/dwm/util.o b/dwm/util.o new file mode 100644 index 0000000000000000000000000000000000000000..bf3ed7f38f11dafe891aac59c164dda18d44be4a GIT binary patch literal 2256 zcmbu9O-vI(6vy8JYDH*^l8C{>9!8}JZn{Mi1T`g~tfn#e71T>D?N$h-t=p*qH4!5o zDj^}p0|yTrJR0M{g9jr`Jm8VDiP3`x6FuNnjriW~3`{odMPD+!H^29PGmn{_-aC~z z-Joe8O@ouLHIo!zWZPC8cf&XYp%pG#m0#BV@1GG_70!CC$|V-JDhXyKDno1}fzg$@ zD(?$LhS>E`B*BWI$P+e;@=)X{TXg+1w(R=n?4|2pv8wCeur>41-AniTzi*J<#L5|AHeY7 zV4vPKZ0C8Qpqr-AW0=WeEE)9pkp6CcNrQ$s}iHF$uu$F z=}nmt`Ha{EMXG#C)1wxj)<;KxR- zY~yBkTUl>4<>L{lR`k0Sz1thIHXLE0Q62pswfLbr+^EBk)ZzVgcpN$PDf@HJ3E4m$ zJ(T%G&Paoi7>q(@!iEyh*p36q&tNGnXpbkePHM`Qo&BHJv7C;A?pC$9nCunjBy+wgbYg;D4ks1-K= literal 0 HcmV?d00001 diff --git a/pics/22.png b/pics/22.png new file mode 100644 index 0000000000000000000000000000000000000000..a3075ce2afe03727ade7d2a9658efe85e1578b1e GIT binary patch literal 133652 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 b;A>KnpN}P^-xALg;4ifoTF=Xs%s&4wa+!(e literal 0 HcmV?d00001 diff --git a/pics/artix.jpg b/pics/artix.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f1f13d0f4395871e558b03e167f2ca178d88621a GIT binary patch literal 74965 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

`(Y92NOjeJFu?K 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 Lp@x6p=c)V;y7UP4 literal 0 HcmV?d00001 diff --git a/pics/emerge.jpg b/pics/emerge.jpg new file mode 100644 index 0000000000000000000000000000000000000000..921b59898d92ff998d3941043a44fed418745f87 GIT binary patch literal 193319 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

YpkjG`l)auB=+_PHjr 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

-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 CG>kp~ literal 0 HcmV?d00001 diff --git a/st/FAQ b/st/FAQ new file mode 100644 index 0000000..969b195 --- /dev/null +++ b/st/FAQ @@ -0,0 +1,250 @@ +## Why does st not handle utmp entries? + +Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task. + + +## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever! + +It means that st doesn’t have any terminfo entry on your system. Chances are +you did not `make install`. If you just want to test it without installing it, +you can manually run `tic -sx st.info`. + + +## Nothing works, and nothing is said about an unknown terminal! + +* Some programs just assume they’re running in xterm i.e. they don’t rely on + terminfo. What you see is the current state of the “xterm compliance”. +* Some programs don’t complain about the lacking st description and default to + another terminal. In that case see the question about terminfo. + + +## How do I scroll back up? + +* Using a terminal multiplexer. + * `st -e tmux` using C-b [ + * `st -e screen` using C-a ESC +* Using the excellent tool of [scroll](https://git.suckless.org/scroll/). +* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/). + + +## I would like to have utmp and/or scroll functionality by default + +You can add the absolute path of both programs in your config.h file. You only +have to modify the value of utmp and scroll variables. + + +## Why doesn't the Del key work in some programs? + +Taken from the terminfo manpage: + + If the terminal has a keypad that transmits codes when the keys + are pressed, this information can be given. Note that it is not + possible to handle terminals where the keypad only works in + local (this applies, for example, to the unshifted HP 2621 keys). + If the keypad can be set to transmit or not transmit, give these + codes as smkx and rmkx. Otherwise the keypad is assumed to + always transmit. + +In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that +applications which want to test against keypad keys send these +sequences. + +But buggy applications (like bash and irssi, for example) don't do this. A fast +solution for them is to use the following command: + + $ printf '\033[?1h\033=' >/dev/tty + +or + $ tput smkx + +In the case of bash, readline is used. Readline has a different note in its +manpage about this issue: + + enable-keypad (Off) + When set to On, readline will try to enable the + application keypad when it is called. Some systems + need this to enable arrow keys. + +Adding this option to your .inputrc will fix the keypad problem for all +applications using readline. + +If you are using zsh, then read the zsh FAQ +: + + It should be noted that the O / [ confusion can occur with other keys + such as Home and End. Some systems let you query the key sequences + sent by these keys from the system's terminal database, terminfo. + Unfortunately, the key sequences given there typically apply to the + mode that is not the one zsh uses by default (it's the "application" + mode rather than the "raw" mode). Explaining the use of terminfo is + outside of the scope of this FAQ, but if you wish to use the key + sequences given there you can tell the line editor to turn on + "application" mode when it starts and turn it off when it stops: + + function zle-line-init () { echoti smkx } + function zle-line-finish () { echoti rmkx } + zle -N zle-line-init + zle -N zle-line-finish + +Putting these lines into your .zshrc will fix the problems. + + +## How can I use meta in 8bit mode? + +St supports meta in 8bit mode, but the default terminfo entry doesn't +use this capability. If you want it, you have to use the 'st-meta' value +in TERM. + + +## I cannot compile st in OpenBSD + +OpenBSD lacks librt, despite it being mandatory in POSIX +. +If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and +st will compile without any loss of functionality, because all the functions are +included in libc on this platform. + + +## The Backspace Case + +St is emulating the Linux way of handling backspace being delete and delete being +backspace. + +This is an issue that was discussed in suckless mailing list +. Here is why some old grumpy +terminal users wants its backspace to be how he feels it: + + Well, I am going to comment why I want to change the behaviour + of this key. When ASCII was defined in 1968, communication + with computers was done using punched cards, or hardcopy + terminals (basically a typewriter machine connected with the + computer using a serial port). ASCII defines DELETE as 7F, + because, in punched-card terms, it means all the holes of the + card punched; it is thus a kind of 'physical delete'. In the + same way, the BACKSPACE key was a non-destructive backspace, + as on a typewriter. So, if you wanted to delete a character, + you had to BACKSPACE and then DELETE. Another use of BACKSPACE + was to type accented characters, for example 'a BACKSPACE `'. + The VT100 had no BACKSPACE key; it was generated using the + CONTROL key as another control character (CONTROL key sets to + 0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code + 0x08)), but it had a DELETE key in a similar position where + the BACKSPACE key is located today on common PC keyboards. + All the terminal emulators emulated the difference between + these keys correctly: the backspace key generated a BACKSPACE + (^H) and delete key generated a DELETE (^?). + + But a problem arose when Linus Torvalds wrote Linux. Unlike + earlier terminals, the Linux virtual terminal (the terminal + emulator integrated in the kernel) returned a DELETE when + backspace was pressed, due to the VT100 having a DELETE key in + the same position. This created a lot of problems (see [1] + and [2]). Since Linux has become the king, a lot of terminal + emulators today generate a DELETE when the backspace key is + pressed in order to avoid problems with Linux. The result is + that the only way of generating a BACKSPACE on these systems + is by using CONTROL + H. (I also think that emacs had an + important point here because the CONTROL + H prefix is used + in emacs in some commands (help commands).) + + From point of view of the kernel, you can change the key + for deleting a previous character with stty erase. When you + connect a real terminal into a machine you describe the type + of terminal, so getty configures the correct value of stty + erase for this terminal. In the case of terminal emulators, + however, you don't have any getty that can set the correct + value of stty erase, so you always get the default value. + For this reason, it is necessary to add 'stty erase ^H' to your + profile if you have changed the value of the backspace key. + Of course, another solution is for st itself to modify the + value of stty erase. I usually have the inverse problem: + when I connect to non-Unix machines, I have to press CONTROL + + h to get a BACKSPACE. The inverse problem occurs when a user + connects to my Unix machines from a different system with a + correct backspace key. + + [1] http://www.ibb.net/~anne/keyboard.html + [2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html + + +## But I really want the old grumpy behaviour of my terminal + +Apply [1]. + +[1] https://st.suckless.org/patches/delkey + + +## Why do images not work in st using the w3m image hack? + +w3mimg uses a hack that draws an image on top of the terminal emulator Drawable +window. The hack relies on the terminal to use a single buffer to draw its +contents directly. + +st uses double-buffered drawing so the image is quickly replaced and may show a +short flicker effect. + +Below is a patch example to change st double-buffering to a single Drawable +buffer. + +diff --git a/x.c b/x.c +--- a/x.c ++++ b/x.c +@@ -732,10 +732,6 @@ xresize(int col, int row) + win.tw = col * win.cw; + win.th = row * win.ch; + +- XFreePixmap(xw.dpy, xw.buf); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); +- XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + + /* resize to new width */ +@@ -1148,8 +1144,7 @@ xinit(int cols, int rows) + gcvalues.graphics_exposures = False; + dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, + &gcvalues); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.buf = xw.win; + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); + +@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2) + void + xfinishdraw(void) + { +- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, +- win.h, 0, 0); + XSetForeground(xw.dpy, dc.gc, + dc.col[IS_SET(MODE_REVERSE)? + defaultfg : defaultbg].pixel); + + +## BadLength X error in Xft when trying to render emoji + +Xft makes st crash when rendering color emojis with the following error: + +"X Error of failed request: BadLength (poly request too large or internal Xlib length error)" + Major opcode of failed request: 139 (RENDER) + Minor opcode of failed request: 20 (RenderAddGlyphs) + Serial number of failed request: 1595 + Current serial number in output stream: 1818" + +This is a known bug in Xft (not st) which happens on some platforms and +combination of particular fonts and fontconfig settings. + +See also: +https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6 +https://bugs.freedesktop.org/show_bug.cgi?id=107534 +https://bugzilla.redhat.com/show_bug.cgi?id=1498269 + +The solution is to remove color emoji fonts or disable this in the fontconfig +XML configuration. As an ugly workaround (which may work only on newer +fontconfig versions (FC_COLOR)), the following code can be used to mask color +fonts: + + FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); + +Please don't bother reporting this bug to st, but notify the upstream Xft +developers about fixing this bug. diff --git a/st/LEGACY b/st/LEGACY new file mode 100644 index 0000000..bf28b1e --- /dev/null +++ b/st/LEGACY @@ -0,0 +1,17 @@ +A STATEMENT ON LEGACY SUPPORT + +In the terminal world there is much cruft that comes from old and unsup‐ +ported terminals that inherit incompatible modes and escape sequences +which noone is able to know, except when he/she comes from that time and +developed a graphical vt100 emulator at that time. + +One goal of st is to only support what is really needed. When you en‐ +counter a sequence which you really need, implement it. But while you +are at it, do not add the other cruft you might encounter while sneek‐ +ing at other terminal emulators. History has bloated them and there is +no real evidence that most of the sequences are used today. + + +Christoph Lohmann <20h@r-36.net> +2012-09-13T07:00:36.081271045+02:00 + diff --git a/st/LICENSE b/st/LICENSE new file mode 100644 index 0000000..3cbf420 --- /dev/null +++ b/st/LICENSE @@ -0,0 +1,34 @@ +MIT/X Consortium License + +© 2014-2022 Hiltjo Posthuma +© 2018 Devin J. Pohly +© 2014-2017 Quentin Rameau +© 2009-2012 Aurélien APTEL +© 2008-2017 Anselm R Garbe +© 2012-2017 Roberto E. Vargas Caballero +© 2012-2016 Christoph Lohmann <20h at r-36 dot net> +© 2013 Eon S. Jeon +© 2013 Alexander Sedov +© 2013 Mark Edgar +© 2013-2014 Eric Pruitt +© 2013 Michael Forney +© 2013-2014 Markus Teich +© 2014-2015 Laslo Hunhold + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/st/Makefile b/st/Makefile new file mode 100644 index 0000000..ab1d9b8 --- /dev/null +++ b/st/Makefile @@ -0,0 +1,54 @@ +# st - simple terminal +# See LICENSE file for copyright and license details. +.POSIX: + +include config.mk + +SRC = st.c x.c +OBJ = $(SRC:.c=.o) + +all: options st + +options: + @echo st build options: + @echo "CFLAGS = $(STCFLAGS)" + @echo "LDFLAGS = $(STLDFLAGS)" + @echo "CC = $(CC)" + +.c.o: + $(CC) $(STCFLAGS) -c $< + +st.o: config.def.h st.h win.h +x.o: arg.h config.def.h st.h win.h + +$(OBJ): config.def.h config.mk + +st: $(OBJ) + $(CC) -o $@ $(OBJ) $(STLDFLAGS) + +clean: + rm -f st $(OBJ) st-$(VERSION).tar.gz + +dist: clean + mkdir -p st-$(VERSION) + cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\ + config.def.h st.info st.1 arg.h st.h win.h $(SRC)\ + st-$(VERSION) + tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz + rm -rf st-$(VERSION) + +install: st + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f st $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/st + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 + tic -sx st.info + @echo Please see the README file regarding the terminfo entry of st. + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/st + rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1 + +.PHONY: all options clean dist install uninstall diff --git a/st/README b/st/README new file mode 100644 index 0000000..6a846ed --- /dev/null +++ b/st/README @@ -0,0 +1,34 @@ +st - simple terminal +-------------------- +st is a simple terminal emulator for X which sucks less. + + +Requirements +------------ +In order to build st you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (st is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install st (if +necessary as root): + + make clean install + + +Running st +---------- +If you did not install st with make clean install, you must compile +the st terminfo entry with the following command: + + tic -sx st.info + +See the man page for additional details. + +Credits +------- +Based on Aurélien APTEL bt source code. + diff --git a/st/TODO b/st/TODO new file mode 100644 index 0000000..5f74cd5 --- /dev/null +++ b/st/TODO @@ -0,0 +1,28 @@ +vt emulation +------------ + +* double-height support + +code & interface +---------------- + +* add a simple way to do multiplexing + +drawing +------- +* add diacritics support to xdraws() + * switch to a suckless font drawing library +* make the font cache simpler +* add better support for brightening of the upper colors + +bugs +---- + +* fix shift up/down (shift selection in emacs) +* remove DEC test sequence when appropriate + +misc +---- + + $ grep -nE 'XXX|TODO' st.c + diff --git a/st/arg.h b/st/arg.h new file mode 100644 index 0000000..a22e019 --- /dev/null +++ b/st/arg.h @@ -0,0 +1,50 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + int i_;\ + for (i_ = 1, brk_ = 0, argv_ = argv;\ + argv[0][i_] && !brk_;\ + i_++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][i_];\ + switch (argc_) + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][i_+1] != '\0')?\ + (&argv[0][i_+1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][i_+1] != '\0')?\ + (&argv[0][i_+1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/st/config.def.h b/st/config.def.h new file mode 100644 index 0000000..dc13b6d --- /dev/null +++ b/st/config.def.h @@ -0,0 +1,483 @@ +/* See LICENSE file for copyright and license details. */ + +/* + * appearance + * + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ +static char *font = "Terminus:pixelsize=12:antialias=true:autohint=true"; + + +static int borderpx = 2; + +/* + * What program is execed by st depends of these precedence rules: + * 1: program passed with -e + * 2: scroll and/or utmp + * 3: SHELL environment variable + * 4: value of shell in /etc/passwd + * 5: value of shell in config.h + */ +static char *shell = "/bin/sh"; +char *utmp = NULL; +/* scroll program: to enable use a string like "scroll" */ +char *scroll = NULL; +char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; + +/* identification sequence returned in DA and DECID */ +char *vtiden = "\033[?6c"; + +/* Kerning / character bounding-box multipliers */ +static float cwscale = 1.0; +static float chscale = 1.0; + +/* + * word delimiter string + * + * More advanced example: L" `'\"()[]{}" + */ +wchar_t *worddelimiters = L" "; + +/* selection timeouts (in milliseconds) */ +static unsigned int doubleclicktimeout = 300; +static unsigned int tripleclicktimeout = 600; + +/* alt screens */ +int allowaltscreen = 1; + +/* allow certain non-interactive (insecure) window operations such as: + setting the clipboard text */ +int allowwindowops = 0; + +/* + * draw latency range in ms - from new content/keypress/etc until drawing. + * within this range, st draws when content stops arriving (idle). mostly it's + * near minlatency, but it waits longer for slow updates to avoid partial draw. + * low minlatency will tear/flicker more, as it can "detect" idle too early. + */ +static double minlatency = 8; +static double maxlatency = 33; + +/* + * blinking timeout (set to 0 to disable blinking) for the terminal blinking + * attribute. + */ +static unsigned int blinktimeout = 800; + +/* + * thickness of underline and bar cursors + */ +static unsigned int cursorthickness = 2; + +/* + * bell volume. It must be a value between -100 and 100. Use 0 for disabling + * it + */ +static int bellvolume = 0; + +/* default TERM value */ +char *termname = "st-256color"; + +/* + * spaces per tab + * + * When you are changing this value, don't forget to adapt the »it« value in + * the st.info and appropriately install the st.info in the environment where + * you use this st version. + * + * it#$tabspaces, + * + * Secondly make sure your kernel is not expanding tabs. When running `stty + * -a` »tab0« should appear. You can tell the terminal to not expand tabs by + * running following command: + * + * stty tabs + */ +unsigned int tabspaces = 8; + +/* bg opacity */ +float alpha = 0.40; + +/* Terminal colors (16 first used in escape sequence) */ +static const char *colorname[] = { + /* 8 normal colors */ + "black", + "red3", + "green3", + "yellow3", + "blue2", + "magenta3", + "cyan3", + "gray90", + + /* 8 bright colors */ + "gray50", + "red", + "green", + "yellow", + "#5c5cff", + "magenta", + "cyan", + "white", + + [255] = 0, + + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", + "gray90", /* default foreground colour */ + "black", /* default background colour */ +}; + + +/* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +unsigned int defaultfg = 258; +unsigned int defaultbg = 259; +unsigned int defaultcs = 256; +static unsigned int defaultrcs = 257; + +/* + * Default shape of cursor + * 2: Block ("█") + * 4: Underline ("_") + * 6: Bar ("|") + * 7: Snowman ("☃") + */ +static unsigned int cursorshape = 2; + +/* + * Default columns and rows numbers + */ + +static unsigned int cols = 80; +static unsigned int rows = 24; + +/* + * Default colour and shape of the mouse cursor + */ +static unsigned int mouseshape = XC_xterm; +static unsigned int mousefg = 7; +static unsigned int mousebg = 0; + +/* + * Color used to display font attributes when fontconfig selected a font which + * doesn't match the ones requested. + */ +static unsigned int defaultattr = 11; + +/* + * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). + * Note that if you want to use ShiftMask with selmasks, set this to an other + * modifier, set to 0 to not use it. + */ +static uint forcemousemod = ShiftMask; + +/* + * Internal mouse shortcuts. + * Beware that overloading Button1 will disable the selection. + */ +static MouseShortcut mshortcuts[] = { + /* mask button function argument release */ + { ShiftMask, Button4, kscrollup, {.i = 1} }, + { ShiftMask, Button5, kscrolldown, {.i = 1} }, + { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, + { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, + { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, + { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, +}; + +/* Internal keyboard shortcuts. */ +#define MODKEY Mod1Mask +#define TERMMOD (ControlMask|ShiftMask) + +static Shortcut shortcuts[] = { + /* mask keysym function argument */ + { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, + { ControlMask, XK_Print, toggleprinter, {.i = 0} }, + { ShiftMask, XK_Print, printscreen, {.i = 0} }, + { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, + { TERMMOD, XK_Prior, zoom, {.f = +1} }, + { TERMMOD, XK_Next, zoom, {.f = -1} }, + { TERMMOD, XK_Home, zoomreset, {.f = 0} }, + { TERMMOD, XK_C, clipcopy, {.i = 0} }, + { TERMMOD, XK_V, clippaste, {.i = 0} }, + { TERMMOD, XK_Y, selpaste, {.i = 0} }, + { ShiftMask, XK_Insert, selpaste, {.i = 0} }, + { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, + { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, + { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, +}; + +/* + * Special keys (change & recompile st.info accordingly) + * + * Mask value: + * * Use XK_ANY_MOD to match the key no matter modifiers state + * * Use XK_NO_MOD to match the key alone (no modifiers) + * appkey value: + * * 0: no value + * * > 0: keypad application mode enabled + * * = 2: term.numlock = 1 + * * < 0: keypad application mode disabled + * appcursor value: + * * 0: no value + * * > 0: cursor application mode enabled + * * < 0: cursor application mode disabled + * + * Be careful with the order of the definitions because st searches in + * this table sequentially, so any XK_ANY_MOD must be in the last + * position for a key. + */ + +/* + * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) + * to be mapped below, add them to this array. + */ +static KeySym mappedkeys[] = { -1 }; + +/* + * State bits to ignore when matching key or button events. By default, + * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. + */ +static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; + +/* + * This is the huge key array which defines all compatibility to the Linux + * world. Please decide about changes wisely. + */ +static Key key[] = { + /* keysym mask string appkey appcursor */ + { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, + { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, + { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, + { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, + { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, + { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, + { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, + { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, + { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, + { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, + { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, + { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, + { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, + { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, + { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, + { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, + { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, + { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, + { XK_KP_End, ControlMask, "\033[J", -1, 0}, + { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, + { XK_KP_End, ShiftMask, "\033[K", -1, 0}, + { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, + { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, + { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, + { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, + { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, + { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, + { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, + { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, + { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, + { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, + { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, + { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, + { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, + { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, + { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, + { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, + { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, + { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, + { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, + { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, + { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, + { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, + { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, + { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, + { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, + { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, + { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, + { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, + { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, + { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, + { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, + { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, + { XK_Up, ControlMask, "\033[1;5A", 0, 0}, + { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, + { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, + { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, + { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, + { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, + { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, + { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, + { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, + { XK_Down, ControlMask, "\033[1;5B", 0, 0}, + { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, + { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, + { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, + { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, + { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, + { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, + { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, + { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, + { XK_Left, ControlMask, "\033[1;5D", 0, 0}, + { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, + { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, + { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, + { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, + { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, + { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, + { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, + { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, + { XK_Right, ControlMask, "\033[1;5C", 0, 0}, + { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, + { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, + { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, + { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, + { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, + { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, + { XK_Return, Mod1Mask, "\033\r", 0, 0}, + { XK_Return, XK_ANY_MOD, "\r", 0, 0}, + { XK_Insert, ShiftMask, "\033[4l", -1, 0}, + { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, + { XK_Insert, ControlMask, "\033[L", -1, 0}, + { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, + { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, + { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, + { XK_Delete, ControlMask, "\033[M", -1, 0}, + { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, + { XK_Delete, ShiftMask, "\033[2K", -1, 0}, + { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, + { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, + { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, + { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, + { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, + { XK_Home, ShiftMask, "\033[2J", 0, -1}, + { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, + { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, + { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, + { XK_End, ControlMask, "\033[J", -1, 0}, + { XK_End, ControlMask, "\033[1;5F", +1, 0}, + { XK_End, ShiftMask, "\033[K", -1, 0}, + { XK_End, ShiftMask, "\033[1;2F", +1, 0}, + { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, + { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, + { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, + { XK_Next, ControlMask, "\033[6;5~", 0, 0}, + { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, + { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, + { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, + { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, + { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, + { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, + { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, + { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, + { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, + { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, + { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, + { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, + { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, + { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, + { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, + { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, + { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, + { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, + { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, + { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, + { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, + { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, + { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, + { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, + { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, + { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, + { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, + { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, + { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, + { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, + { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, + { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, + { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, + { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, + { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, + { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, + { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, + { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, + { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, + { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, + { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, + { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, + { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, + { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, + { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, + { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, + { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, + { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, + { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, + { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, + { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, + { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, + { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, + { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, + { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, + { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, + { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, + { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, + { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, + { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, + { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, + { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, + { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, + { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, + { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, + { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, + { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, + { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, + { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, + { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, + { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, + { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, + { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, + { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, + { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, + { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, + { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, + { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, + { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, + { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, + { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, + { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, + { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, + { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, + { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, + { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, + { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, + { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, +}; + +/* + * Selection types' masks. + * Use the same masks as usual. + * Button1Mask is always unset, to make masks match between ButtonPress. + * ButtonRelease and MotionNotify. + * If no match is found, regular selection is used. + */ +static uint selmasks[] = { + [SEL_RECTANGULAR] = Mod1Mask, +}; + +/* + * Printable characters in ASCII, used to estimate the advance width + * of single wide characters. + */ +static char ascii_printable[] = + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/st/config.mk b/st/config.mk new file mode 100644 index 0000000..0114bad --- /dev/null +++ b/st/config.mk @@ -0,0 +1,35 @@ +# st version +VERSION = 0.8.5 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +PKG_CONFIG = pkg-config + +# includes and libs +INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ + `$(PKG_CONFIG) --cflags freetype2` +LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ + `$(PKG_CONFIG) --libs fontconfig` \ + `$(PKG_CONFIG) --libs freetype2` + +# flags +STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) +STLDFLAGS = $(LIBS) $(LDFLAGS) + +# OpenBSD: +#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE +#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ +# `$(PKG_CONFIG) --libs fontconfig` \ +# `$(PKG_CONFIG) --libs freetype2` + +# compiler and linker +# CC = c99 diff --git a/st/patches/st-alpha-0.8.2.diff b/st/patches/st-alpha-0.8.2.diff new file mode 100644 index 0000000..dad6615 --- /dev/null +++ b/st/patches/st-alpha-0.8.2.diff @@ -0,0 +1,163 @@ +diff --git a/config.def.h b/config.def.h +index 0e01717..e116631 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -82,6 +82,9 @@ char *termname = "st-256color"; + */ + unsigned int tabspaces = 8; + ++/* bg opacity */ ++float alpha = 0.8; ++ + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { + /* 8 normal colors */ +@@ -109,6 +112,7 @@ static const char *colorname[] = { + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", ++ "black", + }; + + +@@ -117,7 +121,7 @@ static const char *colorname[] = { + * foreground, background, cursor, reverse cursor + */ + unsigned int defaultfg = 7; +-unsigned int defaultbg = 0; ++unsigned int defaultbg = 258; + static unsigned int defaultcs = 256; + static unsigned int defaultrcs = 257; + +diff --git a/config.mk b/config.mk +index 0cbb002..1d2f0e2 100644 +--- a/config.mk ++++ b/config.mk +@@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config + INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ + `$(PKG_CONFIG) --cflags freetype2` +-LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ ++LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ + `$(PKG_CONFIG) --libs fontconfig` \ + `$(PKG_CONFIG) --libs freetype2` + +diff --git a/st.h b/st.h +index 38c61c4..b7634ab 100644 +--- a/st.h ++++ b/st.h +@@ -120,3 +120,4 @@ extern char *termname; + extern unsigned int tabspaces; + extern unsigned int defaultfg; + extern unsigned int defaultbg; ++extern float alpha; +diff --git a/x.c b/x.c +index 0422421..588dec3 100644 +--- a/x.c ++++ b/x.c +@@ -98,6 +98,7 @@ typedef struct { + XSetWindowAttributes attrs; + int scr; + int isfixed; /* is fixed geometry? */ ++ int depth; /* bit depth */ + int l, t; /* left and top offset */ + int gm; /* geometry mask */ + } XWindow; +@@ -229,6 +230,7 @@ static char *usedfont = NULL; + static double usedfontsize = 0; + static double defaultfontsize = 0; + ++static char *opt_alpha = NULL; + static char *opt_class = NULL; + static char **opt_cmd = NULL; + static char *opt_embed = NULL; +@@ -688,7 +690,7 @@ xresize(int col, int row) + + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + +@@ -748,6 +750,13 @@ xloadcols(void) + else + die("could not allocate color %d\n", i); + } ++ ++ /* set alpha value of bg color */ ++ if (opt_alpha) ++ alpha = strtof(opt_alpha, NULL); ++ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); ++ dc.col[defaultbg].pixel &= 0x00FFFFFF; ++ dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; + loaded = 1; + } + +@@ -1004,11 +1013,23 @@ xinit(int cols, int rows) + Window parent; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; ++ XWindowAttributes attr; ++ XVisualInfo vis; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); +- xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ ++ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { ++ parent = XRootWindow(xw.dpy, xw.scr); ++ xw.depth = 32; ++ } else { ++ XGetWindowAttributes(xw.dpy, parent, &attr); ++ xw.depth = attr.depth; ++ } ++ ++ XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); ++ xw.vis = vis.visual; + + /* font */ + if (!FcInit()) +@@ -1018,7 +1039,7 @@ xinit(int cols, int rows) + xloadfonts(usedfont, 0); + + /* colors */ +- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ +@@ -1038,19 +1059,15 @@ xinit(int cols, int rows) + | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; + xw.attrs.colormap = xw.cmap; + +- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) +- parent = XRootWindow(xw.dpy, xw.scr); + xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, +- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, ++ win.w, win.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; +- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, +- &gcvalues); +- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); ++ dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); + +@@ -1894,6 +1911,9 @@ main(int argc, char *argv[]) + case 'a': + allowaltscreen = 0; + break; ++ case 'A': ++ opt_alpha = EARGF(usage()); ++ break; + case 'c': + opt_class = EARGF(usage()); + break; diff --git a/st/patches/st-anysize-0.8.4.diff b/st/patches/st-anysize-0.8.4.diff new file mode 100644 index 0000000..2f9a291 --- /dev/null +++ b/st/patches/st-anysize-0.8.4.diff @@ -0,0 +1,152 @@ +diff --git a/x.c b/x.c +index 8bf998e..e2cda07 100644 +--- a/x.c ++++ b/x.c +@@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; + typedef struct { + int tw, th; /* tty width and height */ + int w, h; /* window width and height */ ++ int hborderpx, vborderpx; + int ch; /* char height */ + int cw; /* char width */ + int mode; /* window state/mode flags */ +@@ -331,7 +332,7 @@ ttysend(const Arg *arg) + int + evcol(XEvent *e) + { +- int x = e->xbutton.x - borderpx; ++ int x = e->xbutton.x - win.hborderpx; + LIMIT(x, 0, win.tw - 1); + return x / win.cw; + } +@@ -339,7 +340,7 @@ evcol(XEvent *e) + int + evrow(XEvent *e) + { +- int y = e->xbutton.y - borderpx; ++ int y = e->xbutton.y - win.vborderpx; + LIMIT(y, 0, win.th - 1); + return y / win.ch; + } +@@ -723,6 +724,9 @@ cresize(int width, int height) + col = MAX(1, col); + row = MAX(1, row); + ++ win.hborderpx = (win.w - col * win.cw) / 2; ++ win.vborderpx = (win.h - row * win.ch) / 2; ++ + tresize(col, row); + xresize(col, row); + ttyresize(win.tw, win.th); +@@ -840,8 +844,8 @@ xhints(void) + sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; + sizeh->height = win.h; + sizeh->width = win.w; +- sizeh->height_inc = win.ch; +- sizeh->width_inc = win.cw; ++ sizeh->height_inc = 1; ++ sizeh->width_inc = 1; + sizeh->base_height = 2 * borderpx; + sizeh->base_width = 2 * borderpx; + sizeh->min_height = win.ch + 2 * borderpx; +@@ -1123,8 +1127,8 @@ xinit(int cols, int rows) + xloadcols(); + + /* adjust fixed window geometry */ +- win.w = 2 * borderpx + cols * win.cw; +- win.h = 2 * borderpx + rows * win.ch; ++ win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; ++ win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; + if (xw.gm & XNegative) + xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; + if (xw.gm & YNegative) +@@ -1213,7 +1217,7 @@ xinit(int cols, int rows) + int + xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) + { +- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; ++ float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; + ushort mode, prevmode = USHRT_MAX; + Font *font = &dc.font; + int frcflags = FRC_NORMAL; +@@ -1346,7 +1350,7 @@ void + xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) + { + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); +- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, ++ int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; + XRenderColor colfg, colbg; +@@ -1436,17 +1440,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + + /* Intelligent cleaning up of the borders. */ + if (x == 0) { +- xclear(0, (y == 0)? 0 : winy, borderpx, ++ xclear(0, (y == 0)? 0 : winy, win.vborderpx, + winy + win.ch + +- ((winy + win.ch >= borderpx + win.th)? win.h : 0)); ++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); + } +- if (winx + width >= borderpx + win.tw) { ++ if (winx + width >= win.hborderpx + win.tw) { + xclear(winx + width, (y == 0)? 0 : winy, win.w, +- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); ++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); + } + if (y == 0) +- xclear(winx, 0, winx + width, borderpx); +- if (winy + win.ch >= borderpx + win.th) ++ xclear(winx, 0, winx + width, win.vborderpx); ++ if (winy + win.ch >= win.vborderpx + win.th) + xclear(winx, winy + win.ch, winx + width, win.h); + + /* Clean up the region we want to draw to. */ +@@ -1540,35 +1544,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) + case 3: /* Blinking Underline */ + case 4: /* Steady Underline */ + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + (cy + 1) * win.ch - \ ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + (cy + 1) * win.ch - \ + cursorthickness, + win.cw, cursorthickness); + break; + case 5: /* Blinking bar */ + case 6: /* Steady bar */ + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + cursorthickness, win.ch); + break; + } + } else { + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + win.cw - 1, 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + (cx + 1) * win.cw - 1, +- borderpx + cy * win.ch, ++ win.hborderpx + (cx + 1) * win.cw - 1, ++ win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + (cy + 1) * win.ch - 1, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + (cy + 1) * win.ch - 1, + win.cw, 1); + } + } diff --git a/st/patches/st-font2-20190416-ba72400.diff b/st/patches/st-font2-20190416-ba72400.diff new file mode 100644 index 0000000..837f02a --- /dev/null +++ b/st/patches/st-font2-20190416-ba72400.diff @@ -0,0 +1,17 @@ +diff --git a/config.def.h b/config.def.h +index 482901e..676719e 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,6 +6,12 @@ + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ + static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; ++/* Spare fonts */ ++static char *font2[] = { ++/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */ ++/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */ ++}; ++ + static int borderpx = 2; + + /* diff --git a/st/patches/st-scrollback-20210507-4536f46.diff b/st/patches/st-scrollback-20210507-4536f46.diff new file mode 100644 index 0000000..f960f6b --- /dev/null +++ b/st/patches/st-scrollback-20210507-4536f46.diff @@ -0,0 +1,351 @@ +diff --git a/config.def.h b/config.def.h +index 6f05dce..93cbcc0 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -199,6 +199,8 @@ static Shortcut shortcuts[] = { + { TERMMOD, XK_Y, selpaste, {.i = 0} }, + { ShiftMask, XK_Insert, selpaste, {.i = 0} }, + { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, ++ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, ++ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, + }; + + /* +diff --git a/st.c b/st.c +index ebdf360..817cc47 100644 +--- a/st.c ++++ b/st.c +@@ -35,6 +35,7 @@ + #define ESC_ARG_SIZ 16 + #define STR_BUF_SIZ ESC_BUF_SIZ + #define STR_ARG_SIZ ESC_ARG_SIZ ++#define HISTSIZE 2000 + + /* macros */ + #define IS_SET(flag) ((term.mode & (flag)) != 0) +@@ -42,6 +43,9 @@ + #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) + #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) + #define ISDELIM(u) (u && wcschr(worddelimiters, u)) ++#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \ ++ term.scr + HISTSIZE + 1) % HISTSIZE] : \ ++ term.line[(y) - term.scr]) + + enum term_mode { + MODE_WRAP = 1 << 0, +@@ -115,6 +119,9 @@ typedef struct { + int col; /* nb col */ + Line *line; /* screen */ + Line *alt; /* alternate screen */ ++ Line hist[HISTSIZE]; /* history buffer */ ++ int histi; /* history index */ ++ int scr; /* scroll back */ + int *dirty; /* dirtyness of lines */ + TCursor c; /* cursor */ + int ocx; /* old cursor col */ +@@ -184,8 +191,8 @@ static void tnewline(int); + static void tputtab(int); + static void tputc(Rune); + static void treset(void); +-static void tscrollup(int, int); +-static void tscrolldown(int, int); ++static void tscrollup(int, int, int); ++static void tscrolldown(int, int, int); + static void tsetattr(const int *, int); + static void tsetchar(Rune, const Glyph *, int, int); + static void tsetdirt(int, int); +@@ -416,10 +423,10 @@ tlinelen(int y) + { + int i = term.col; + +- if (term.line[y][i - 1].mode & ATTR_WRAP) ++ if (TLINE(y)[i - 1].mode & ATTR_WRAP) + return i; + +- while (i > 0 && term.line[y][i - 1].u == ' ') ++ while (i > 0 && TLINE(y)[i - 1].u == ' ') + --i; + + return i; +@@ -528,7 +535,7 @@ selsnap(int *x, int *y, int direction) + * Snap around if the word wraps around at the end or + * beginning of a line. + */ +- prevgp = &term.line[*y][*x]; ++ prevgp = &TLINE(*y)[*x]; + prevdelim = ISDELIM(prevgp->u); + for (;;) { + newx = *x + direction; +@@ -543,14 +550,14 @@ selsnap(int *x, int *y, int direction) + yt = *y, xt = *x; + else + yt = newy, xt = newx; +- if (!(term.line[yt][xt].mode & ATTR_WRAP)) ++ if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) + break; + } + + if (newx >= tlinelen(newy)) + break; + +- gp = &term.line[newy][newx]; ++ gp = &TLINE(newy)[newx]; + delim = ISDELIM(gp->u); + if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim + || (delim && gp->u != prevgp->u))) +@@ -571,14 +578,14 @@ selsnap(int *x, int *y, int direction) + *x = (direction < 0) ? 0 : term.col - 1; + if (direction < 0) { + for (; *y > 0; *y += direction) { +- if (!(term.line[*y-1][term.col-1].mode ++ if (!(TLINE(*y-1)[term.col-1].mode + & ATTR_WRAP)) { + break; + } + } + } else if (direction > 0) { + for (; *y < term.row-1; *y += direction) { +- if (!(term.line[*y][term.col-1].mode ++ if (!(TLINE(*y)[term.col-1].mode + & ATTR_WRAP)) { + break; + } +@@ -609,13 +616,13 @@ getsel(void) + } + + if (sel.type == SEL_RECTANGULAR) { +- gp = &term.line[y][sel.nb.x]; ++ gp = &TLINE(y)[sel.nb.x]; + lastx = sel.ne.x; + } else { +- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0]; ++ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; + lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; + } +- last = &term.line[y][MIN(lastx, linelen-1)]; ++ last = &TLINE(y)[MIN(lastx, linelen-1)]; + while (last >= gp && last->u == ' ') + --last; + +@@ -850,6 +857,9 @@ void + ttywrite(const char *s, size_t n, int may_echo) + { + const char *next; ++ Arg arg = (Arg) { .i = term.scr }; ++ ++ kscrolldown(&arg); + + if (may_echo && IS_SET(MODE_ECHO)) + twrite(s, n, 1); +@@ -1061,13 +1071,53 @@ tswapscreen(void) + } + + void +-tscrolldown(int orig, int n) ++kscrolldown(const Arg* a) ++{ ++ int n = a->i; ++ ++ if (n < 0) ++ n = term.row + n; ++ ++ if (n > term.scr) ++ n = term.scr; ++ ++ if (term.scr > 0) { ++ term.scr -= n; ++ selscroll(0, -n); ++ tfulldirt(); ++ } ++} ++ ++void ++kscrollup(const Arg* a) ++{ ++ int n = a->i; ++ ++ if (n < 0) ++ n = term.row + n; ++ ++ if (term.scr <= HISTSIZE-n) { ++ term.scr += n; ++ selscroll(0, n); ++ tfulldirt(); ++ } ++} ++ ++void ++tscrolldown(int orig, int n, int copyhist) + { + int i; + Line temp; + + LIMIT(n, 0, term.bot-orig+1); + ++ if (copyhist) { ++ term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE; ++ temp = term.hist[term.histi]; ++ term.hist[term.histi] = term.line[term.bot]; ++ term.line[term.bot] = temp; ++ } ++ + tsetdirt(orig, term.bot-n); + tclearregion(0, term.bot-n+1, term.col-1, term.bot); + +@@ -1077,17 +1127,28 @@ tscrolldown(int orig, int n) + term.line[i-n] = temp; + } + +- selscroll(orig, n); ++ if (term.scr == 0) ++ selscroll(orig, n); + } + + void +-tscrollup(int orig, int n) ++tscrollup(int orig, int n, int copyhist) + { + int i; + Line temp; + + LIMIT(n, 0, term.bot-orig+1); + ++ if (copyhist) { ++ term.histi = (term.histi + 1) % HISTSIZE; ++ temp = term.hist[term.histi]; ++ term.hist[term.histi] = term.line[orig]; ++ term.line[orig] = temp; ++ } ++ ++ if (term.scr > 0 && term.scr < HISTSIZE) ++ term.scr = MIN(term.scr + n, HISTSIZE-1); ++ + tclearregion(0, orig, term.col-1, orig+n-1); + tsetdirt(orig+n, term.bot); + +@@ -1097,7 +1158,8 @@ tscrollup(int orig, int n) + term.line[i+n] = temp; + } + +- selscroll(orig, -n); ++ if (term.scr == 0) ++ selscroll(orig, -n); + } + + void +@@ -1126,7 +1188,7 @@ tnewline(int first_col) + int y = term.c.y; + + if (y == term.bot) { +- tscrollup(term.top, 1); ++ tscrollup(term.top, 1, 1); + } else { + y++; + } +@@ -1291,14 +1353,14 @@ void + tinsertblankline(int n) + { + if (BETWEEN(term.c.y, term.top, term.bot)) +- tscrolldown(term.c.y, n); ++ tscrolldown(term.c.y, n, 0); + } + + void + tdeleteline(int n) + { + if (BETWEEN(term.c.y, term.top, term.bot)) +- tscrollup(term.c.y, n); ++ tscrollup(term.c.y, n, 0); + } + + int32_t +@@ -1735,11 +1797,11 @@ csihandle(void) + break; + case 'S': /* SU -- Scroll line up */ + DEFAULT(csiescseq.arg[0], 1); +- tscrollup(term.top, csiescseq.arg[0]); ++ tscrollup(term.top, csiescseq.arg[0], 0); + break; + case 'T': /* SD -- Scroll line down */ + DEFAULT(csiescseq.arg[0], 1); +- tscrolldown(term.top, csiescseq.arg[0]); ++ tscrolldown(term.top, csiescseq.arg[0], 0); + break; + case 'L': /* IL -- Insert blank lines */ + DEFAULT(csiescseq.arg[0], 1); +@@ -2251,7 +2313,7 @@ eschandle(uchar ascii) + return 0; + case 'D': /* IND -- Linefeed */ + if (term.c.y == term.bot) { +- tscrollup(term.top, 1); ++ tscrollup(term.top, 1, 1); + } else { + tmoveto(term.c.x, term.c.y+1); + } +@@ -2264,7 +2326,7 @@ eschandle(uchar ascii) + break; + case 'M': /* RI -- Reverse index */ + if (term.c.y == term.top) { +- tscrolldown(term.top, 1); ++ tscrolldown(term.top, 1, 1); + } else { + tmoveto(term.c.x, term.c.y-1); + } +@@ -2474,7 +2536,7 @@ twrite(const char *buf, int buflen, int show_ctrl) + void + tresize(int col, int row) + { +- int i; ++ int i, j; + int minrow = MIN(row, term.row); + int mincol = MIN(col, term.col); + int *bp; +@@ -2511,6 +2573,14 @@ tresize(int col, int row) + term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); + term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); + ++ for (i = 0; i < HISTSIZE; i++) { ++ term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph)); ++ for (j = mincol; j < col; j++) { ++ term.hist[i][j] = term.c.attr; ++ term.hist[i][j].u = ' '; ++ } ++ } ++ + /* resize each row to new width, zero-pad if needed */ + for (i = 0; i < minrow; i++) { + term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); +@@ -2569,7 +2639,7 @@ drawregion(int x1, int y1, int x2, int y2) + continue; + + term.dirty[y] = 0; +- xdrawline(term.line[y], x1, y, x2); ++ xdrawline(TLINE(y), x1, y, x2); + } + } + +@@ -2590,8 +2660,9 @@ draw(void) + cx--; + + drawregion(0, 0, term.col, term.row); +- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], +- term.ocx, term.ocy, term.line[term.ocy][term.ocx]); ++ if (term.scr == 0) ++ xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], ++ term.ocx, term.ocy, term.line[term.ocy][term.ocx]); + term.ocx = cx; + term.ocy = term.c.y; + xfinishdraw(); +diff --git a/st.h b/st.h +index fa2eddf..adda2db 100644 +--- a/st.h ++++ b/st.h +@@ -81,6 +81,8 @@ void die(const char *, ...); + void redraw(void); + void draw(void); + ++void kscrolldown(const Arg *); ++void kscrollup(const Arg *); + void printscreen(const Arg *); + void printsel(const Arg *); + void sendbreak(const Arg *); diff --git a/st/patches/st-scrollback-mouse-20220127-2c5edf2.diff b/st/patches/st-scrollback-mouse-20220127-2c5edf2.diff new file mode 100644 index 0000000..5c47abc --- /dev/null +++ b/st/patches/st-scrollback-mouse-20220127-2c5edf2.diff @@ -0,0 +1,25 @@ +From b5d3351a21442a842e01e8c0317603b6890b379c Mon Sep 17 00:00:00 2001 +From: asparagii +Date: Thu, 27 Jan 2022 15:44:02 +0100 +Subject: [PATCH] st-scrollback-mouse + +--- + config.def.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/config.def.h b/config.def.h +index e3b469b..c217315 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -176,6 +176,8 @@ static uint forcemousemod = ShiftMask; + */ + static MouseShortcut mshortcuts[] = { + /* mask button function argument release */ ++ { ShiftMask, Button4, kscrollup, {.i = 1} }, ++ { ShiftMask, Button5, kscrolldown, {.i = 1} }, + { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, + { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, +-- +2.34.1 + diff --git a/st/st b/st/st new file mode 100755 index 0000000000000000000000000000000000000000..cd684d3be0a0e7af884e9598a09aa5e8b1596f9c GIT binary patch literal 106000 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 WDt>iO{xX}][{+-}{+-}]. See +.BR XParseGeometry (3) +for further details. +.TP +.B \-i +will fixate the position given with the -g option. +.TP +.BI \-n " name" +defines the window instance name (default $TERM). +.TP +.BI \-o " iofile" +writes all the I/O to +.I iofile. +This feature is useful when recording st sessions. A value of "-" means +standard output. +.TP +.BI \-T " title" +defines the window title (default 'st'). +.TP +.BI \-t " title" +defines the window title (default 'st'). +.TP +.BI \-w " windowid" +embeds st within the window identified by +.I windowid +.TP +.BI \-l " line" +use a tty +.I line +instead of a pseudo terminal. +.I line +should be a (pseudo-)serial device (e.g. /dev/ttyS0 on Linux for serial port +0). +When this flag is given +remaining arguments are used as flags for +.BR stty(1). +By default st initializes the serial line to 8 bits, no parity, 1 stop bit +and a 38400 baud rate. The speed is set by appending it as last argument +(e.g. 'st -l /dev/ttyS0 115200'). Arguments before the last one are +.BR stty(1) +flags. If you want to set odd parity on 115200 baud use for example 'st -l +/dev/ttyS0 parenb parodd 115200'. Set the number of bits by using for +example 'st -l /dev/ttyS0 cs7 115200'. See +.BR stty(1) +for more arguments and cases. +.TP +.B \-v +prints version information to stderr, then exits. +.TP +.BI \-e " command " [ " arguments " "... ]" +st executes +.I command +instead of the shell. If this is used it +.B must be the last option +on the command line, as in xterm / rxvt. +This option is only intended for compatibility, +and all the remaining arguments are used as a command +even without it. +.SH SHORTCUTS +.TP +.B Break +Send a break in the serial line. +Break key is obtained in PC keyboards +pressing at the same time control and pause. +.TP +.B Ctrl-Print Screen +Toggle if st should print to the +.I iofile. +.TP +.B Shift-Print Screen +Print the full screen to the +.I iofile. +.TP +.B Print Screen +Print the selection to the +.I iofile. +.TP +.B Ctrl-Shift-Page Up +Increase font size. +.TP +.B Ctrl-Shift-Page Down +Decrease font size. +.TP +.B Ctrl-Shift-Home +Reset to default font size. +.TP +.B Ctrl-Shift-y +Paste from primary selection (middle mouse button). +.TP +.B Ctrl-Shift-c +Copy the selected text to the clipboard selection. +.TP +.B Ctrl-Shift-v +Paste from the clipboard selection. +.SH CUSTOMIZATION +.B st +can be customized by creating a custom config.h and (re)compiling the source +code. This keeps it fast, secure and simple. +.SH AUTHORS +See the LICENSE file for the authors. +.SH LICENSE +See the LICENSE file for the terms of redistribution. +.SH SEE ALSO +.BR tabbed (1), +.BR utmp (1), +.BR stty (1), +.BR scroll (1) +.SH BUGS +See the TODO file in the distribution. + diff --git a/st/st.c b/st/st.c new file mode 100644 index 0000000..ad73a51 --- /dev/null +++ b/st/st.c @@ -0,0 +1,2753 @@ +/* See LICENSE for license details. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "st.h" +#include "win.h" + +#if defined(__linux) + #include +#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) + #include +#elif defined(__FreeBSD__) || defined(__DragonFly__) + #include +#endif + +/* Arbitrary sizes */ +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 +#define ESC_BUF_SIZ (128*UTF_SIZ) +#define ESC_ARG_SIZ 16 +#define STR_BUF_SIZ ESC_BUF_SIZ +#define STR_ARG_SIZ ESC_ARG_SIZ +#define HISTSIZE 2000 + +/* macros */ +#define IS_SET(flag) ((term.mode & (flag)) != 0) +#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == 0x7f) +#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) +#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) +#define ISDELIM(u) (u && wcschr(worddelimiters, u)) +#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \ + term.scr + HISTSIZE + 1) % HISTSIZE] : \ + term.line[(y) - term.scr]) + +enum term_mode { + MODE_WRAP = 1 << 0, + MODE_INSERT = 1 << 1, + MODE_ALTSCREEN = 1 << 2, + MODE_CRLF = 1 << 3, + MODE_ECHO = 1 << 4, + MODE_PRINT = 1 << 5, + MODE_UTF8 = 1 << 6, +}; + +enum cursor_movement { + CURSOR_SAVE, + CURSOR_LOAD +}; + +enum cursor_state { + CURSOR_DEFAULT = 0, + CURSOR_WRAPNEXT = 1, + CURSOR_ORIGIN = 2 +}; + +enum charset { + CS_GRAPHIC0, + CS_GRAPHIC1, + CS_UK, + CS_USA, + CS_MULTI, + CS_GER, + CS_FIN +}; + +enum escape_state { + ESC_START = 1, + ESC_CSI = 2, + ESC_STR = 4, /* DCS, OSC, PM, APC */ + ESC_ALTCHARSET = 8, + ESC_STR_END = 16, /* a final string was encountered */ + ESC_TEST = 32, /* Enter in test mode */ + ESC_UTF8 = 64, +}; + +typedef struct { + Glyph attr; /* current char attributes */ + int x; + int y; + char state; +} TCursor; + +typedef struct { + int mode; + int type; + int snap; + /* + * Selection variables: + * nb – normalized coordinates of the beginning of the selection + * ne – normalized coordinates of the end of the selection + * ob – original coordinates of the beginning of the selection + * oe – original coordinates of the end of the selection + */ + struct { + int x, y; + } nb, ne, ob, oe; + + int alt; +} Selection; + +/* Internal representation of the screen */ +typedef struct { + int row; /* nb row */ + int col; /* nb col */ + Line *line; /* screen */ + Line *alt; /* alternate screen */ + Line hist[HISTSIZE]; /* history buffer */ + int histi; /* history index */ + int scr; /* scroll back */ + int *dirty; /* dirtyness of lines */ + TCursor c; /* cursor */ + int ocx; /* old cursor col */ + int ocy; /* old cursor row */ + int top; /* top scroll limit */ + int bot; /* bottom scroll limit */ + int mode; /* terminal mode flags */ + int esc; /* escape state flags */ + char trantbl[4]; /* charset table translation */ + int charset; /* current charset */ + int icharset; /* selected charset for sequence */ + int *tabs; + Rune lastc; /* last printed char outside of sequence, 0 if control */ +} Term; + +/* CSI Escape sequence structs */ +/* ESC '[' [[ [] [;]] []] */ +typedef struct { + char buf[ESC_BUF_SIZ]; /* raw string */ + size_t len; /* raw string length */ + char priv; + int arg[ESC_ARG_SIZ]; + int narg; /* nb of args */ + char mode[2]; +} CSIEscape; + +/* STR Escape sequence structs */ +/* ESC type [[ [] [;]] ] ESC '\' */ +typedef struct { + char type; /* ESC type ... */ + char *buf; /* allocated raw string */ + size_t siz; /* allocation size */ + size_t len; /* raw string length */ + char *args[STR_ARG_SIZ]; + int narg; /* nb of args */ +} STREscape; + +static void execsh(char *, char **); +static void stty(char **); +static void sigchld(int); +static void ttywriteraw(const char *, size_t); + +static void csidump(void); +static void csihandle(void); +static void csiparse(void); +static void csireset(void); +static int eschandle(uchar); +static void strdump(void); +static void strhandle(void); +static void strparse(void); +static void strreset(void); + +static void tprinter(char *, size_t); +static void tdumpsel(void); +static void tdumpline(int); +static void tdump(void); +static void tclearregion(int, int, int, int); +static void tcursor(int); +static void tdeletechar(int); +static void tdeleteline(int); +static void tinsertblank(int); +static void tinsertblankline(int); +static int tlinelen(int); +static void tmoveto(int, int); +static void tmoveato(int, int); +static void tnewline(int); +static void tputtab(int); +static void tputc(Rune); +static void treset(void); +static void tscrollup(int, int, int); +static void tscrolldown(int, int, int); +static void tsetattr(const int *, int); +static void tsetchar(Rune, const Glyph *, int, int); +static void tsetdirt(int, int); +static void tsetscroll(int, int); +static void tswapscreen(void); +static void tsetmode(int, int, const int *, int); +static int twrite(const char *, int, int); +static void tfulldirt(void); +static void tcontrolcode(uchar ); +static void tdectest(char ); +static void tdefutf8(char); +static int32_t tdefcolor(const int *, int *, int); +static void tdeftran(char); +static void tstrsequence(uchar); + +static void drawregion(int, int, int, int); + +static void selnormalize(void); +static void selscroll(int, int); +static void selsnap(int *, int *, int); + +static size_t utf8decode(const char *, Rune *, size_t); +static Rune utf8decodebyte(char, size_t *); +static char utf8encodebyte(Rune, size_t); +static size_t utf8validate(Rune *, size_t); + +static char *base64dec(const char *); +static char base64dec_getc(const char **); + +static ssize_t xwrite(int, const char *, size_t); + +/* Globals */ +static Term term; +static Selection sel; +static CSIEscape csiescseq; +static STREscape strescseq; +static int iofd = 1; +static int cmdfd; +static pid_t pid; + +static const uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +ssize_t +xwrite(int fd, const char *s, size_t len) +{ + size_t aux = len; + ssize_t r; + + while (len > 0) { + r = write(fd, s, len); + if (r < 0) + return r; + len -= r; + s += r; + } + + return aux; +} + +void * +xmalloc(size_t len) +{ + void *p; + + if (!(p = malloc(len))) + die("malloc: %s\n", strerror(errno)); + + return p; +} + +void * +xrealloc(void *p, size_t len) +{ + if ((p = realloc(p, len)) == NULL) + die("realloc: %s\n", strerror(errno)); + + return p; +} + +char * +xstrdup(const char *s) +{ + char *p; + + if ((p = strdup(s)) == NULL) + die("strdup: %s\n", strerror(errno)); + + return p; +} + +size_t +utf8decode(const char *c, Rune *u, size_t clen) +{ + size_t i, j, len, type; + Rune udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type != 0) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Rune +utf8decodebyte(char c, size_t *i) +{ + for (*i = 0; *i < LEN(utfmask); ++(*i)) + if (((uchar)c & utfmask[*i]) == utfbyte[*i]) + return (uchar)c & ~utfmask[*i]; + + return 0; +} + +size_t +utf8encode(Rune u, char *c) +{ + size_t len, i; + + len = utf8validate(&u, 0); + if (len > UTF_SIZ) + return 0; + + for (i = len - 1; i != 0; --i) { + c[i] = utf8encodebyte(u, 0); + u >>= 6; + } + c[0] = utf8encodebyte(u, len); + + return len; +} + +char +utf8encodebyte(Rune u, size_t i) +{ + return utfbyte[i] | (u & ~utfmask[i]); +} + +size_t +utf8validate(Rune *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + + return i; +} + +char +base64dec_getc(const char **src) +{ + while (**src && !isprint((unsigned char)**src)) + (*src)++; + return **src ? *((*src)++) : '='; /* emulate padding if string ends */ +} + +char * +base64dec(const char *src) +{ + size_t in_len = strlen(src); + char *result, *dst; + static const char base64_digits[256] = { + [43] = 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, + 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + + if (in_len % 4) + in_len += 4 - (in_len % 4); + result = dst = xmalloc(in_len / 4 * 3 + 1); + while (*src) { + int a = base64_digits[(unsigned char) base64dec_getc(&src)]; + int b = base64_digits[(unsigned char) base64dec_getc(&src)]; + int c = base64_digits[(unsigned char) base64dec_getc(&src)]; + int d = base64_digits[(unsigned char) base64dec_getc(&src)]; + + /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */ + if (a == -1 || b == -1) + break; + + *dst++ = (a << 2) | ((b & 0x30) >> 4); + if (c == -1) + break; + *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); + if (d == -1) + break; + *dst++ = ((c & 0x03) << 6) | d; + } + *dst = '\0'; + return result; +} + +void +selinit(void) +{ + sel.mode = SEL_IDLE; + sel.snap = 0; + sel.ob.x = -1; +} + +int +tlinelen(int y) +{ + int i = term.col; + + if (TLINE(y)[i - 1].mode & ATTR_WRAP) + return i; + + while (i > 0 && TLINE(y)[i - 1].u == ' ') + --i; + + return i; +} + +void +selstart(int col, int row, int snap) +{ + selclear(); + sel.mode = SEL_EMPTY; + sel.type = SEL_REGULAR; + sel.alt = IS_SET(MODE_ALTSCREEN); + sel.snap = snap; + sel.oe.x = sel.ob.x = col; + sel.oe.y = sel.ob.y = row; + selnormalize(); + + if (sel.snap != 0) + sel.mode = SEL_READY; + tsetdirt(sel.nb.y, sel.ne.y); +} + +void +selextend(int col, int row, int type, int done) +{ + int oldey, oldex, oldsby, oldsey, oldtype; + + if (sel.mode == SEL_IDLE) + return; + if (done && sel.mode == SEL_EMPTY) { + selclear(); + return; + } + + oldey = sel.oe.y; + oldex = sel.oe.x; + oldsby = sel.nb.y; + oldsey = sel.ne.y; + oldtype = sel.type; + + sel.oe.x = col; + sel.oe.y = row; + selnormalize(); + sel.type = type; + + if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY) + tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); + + sel.mode = done ? SEL_IDLE : SEL_READY; +} + +void +selnormalize(void) +{ + int i; + + if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) { + sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x; + sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x; + } else { + sel.nb.x = MIN(sel.ob.x, sel.oe.x); + sel.ne.x = MAX(sel.ob.x, sel.oe.x); + } + sel.nb.y = MIN(sel.ob.y, sel.oe.y); + sel.ne.y = MAX(sel.ob.y, sel.oe.y); + + selsnap(&sel.nb.x, &sel.nb.y, -1); + selsnap(&sel.ne.x, &sel.ne.y, +1); + + /* expand selection over line breaks */ + if (sel.type == SEL_RECTANGULAR) + return; + i = tlinelen(sel.nb.y); + if (i < sel.nb.x) + sel.nb.x = i; + if (tlinelen(sel.ne.y) <= sel.ne.x) + sel.ne.x = term.col - 1; +} + +int +selected(int x, int y) +{ + if (sel.mode == SEL_EMPTY || sel.ob.x == -1 || + sel.alt != IS_SET(MODE_ALTSCREEN)) + return 0; + + if (sel.type == SEL_RECTANGULAR) + return BETWEEN(y, sel.nb.y, sel.ne.y) + && BETWEEN(x, sel.nb.x, sel.ne.x); + + return BETWEEN(y, sel.nb.y, sel.ne.y) + && (y != sel.nb.y || x >= sel.nb.x) + && (y != sel.ne.y || x <= sel.ne.x); +} + +void +selsnap(int *x, int *y, int direction) +{ + int newx, newy, xt, yt; + int delim, prevdelim; + const Glyph *gp, *prevgp; + + switch (sel.snap) { + case SNAP_WORD: + /* + * Snap around if the word wraps around at the end or + * beginning of a line. + */ + prevgp = &TLINE(*y)[*x]; + prevdelim = ISDELIM(prevgp->u); + for (;;) { + newx = *x + direction; + newy = *y; + if (!BETWEEN(newx, 0, term.col - 1)) { + newy += direction; + newx = (newx + term.col) % term.col; + if (!BETWEEN(newy, 0, term.row - 1)) + break; + + if (direction > 0) + yt = *y, xt = *x; + else + yt = newy, xt = newx; + if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) + break; + } + + if (newx >= tlinelen(newy)) + break; + + gp = &TLINE(newy)[newx]; + delim = ISDELIM(gp->u); + if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim + || (delim && gp->u != prevgp->u))) + break; + + *x = newx; + *y = newy; + prevgp = gp; + prevdelim = delim; + } + break; + case SNAP_LINE: + /* + * Snap around if the the previous line or the current one + * has set ATTR_WRAP at its end. Then the whole next or + * previous line will be selected. + */ + *x = (direction < 0) ? 0 : term.col - 1; + if (direction < 0) { + for (; *y > 0; *y += direction) { + if (!(TLINE(*y-1)[term.col-1].mode + & ATTR_WRAP)) { + break; + } + } + } else if (direction > 0) { + for (; *y < term.row-1; *y += direction) { + if (!(TLINE(*y)[term.col-1].mode + & ATTR_WRAP)) { + break; + } + } + } + break; + } +} + +char * +getsel(void) +{ + char *str, *ptr; + int y, bufsize, lastx, linelen; + const Glyph *gp, *last; + + if (sel.ob.x == -1) + return NULL; + + bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ; + ptr = str = xmalloc(bufsize); + + /* append every set & selected glyph to the selection */ + for (y = sel.nb.y; y <= sel.ne.y; y++) { + if ((linelen = tlinelen(y)) == 0) { + *ptr++ = '\n'; + continue; + } + + if (sel.type == SEL_RECTANGULAR) { + gp = &TLINE(y)[sel.nb.x]; + lastx = sel.ne.x; + } else { + gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; + lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; + } + last = &TLINE(y)[MIN(lastx, linelen-1)]; + while (last >= gp && last->u == ' ') + --last; + + for ( ; gp <= last; ++gp) { + if (gp->mode & ATTR_WDUMMY) + continue; + + ptr += utf8encode(gp->u, ptr); + } + + /* + * Copy and pasting of line endings is inconsistent + * in the inconsistent terminal and GUI world. + * The best solution seems like to produce '\n' when + * something is copied from st and convert '\n' to + * '\r', when something to be pasted is received by + * st. + * FIXME: Fix the computer world. + */ + if ((y < sel.ne.y || lastx >= linelen) && + (!(last->mode & ATTR_WRAP) || sel.type == SEL_RECTANGULAR)) + *ptr++ = '\n'; + } + *ptr = 0; + return str; +} + +void +selclear(void) +{ + if (sel.ob.x == -1) + return; + sel.mode = SEL_IDLE; + sel.ob.x = -1; + tsetdirt(sel.nb.y, sel.ne.y); +} + +void +die(const char *errstr, ...) +{ + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(1); +} + +void +execsh(char *cmd, char **args) +{ + char *sh, *prog, *arg; + const struct passwd *pw; + + errno = 0; + if ((pw = getpwuid(getuid())) == NULL) { + if (errno) + die("getpwuid: %s\n", strerror(errno)); + else + die("who are you?\n"); + } + + if ((sh = getenv("SHELL")) == NULL) + sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd; + + if (args) { + prog = args[0]; + arg = NULL; + } else if (scroll) { + prog = scroll; + arg = utmp ? utmp : sh; + } else if (utmp) { + prog = utmp; + arg = NULL; + } else { + prog = sh; + arg = NULL; + } + DEFAULT(args, ((char *[]) {prog, arg, NULL})); + + unsetenv("COLUMNS"); + unsetenv("LINES"); + unsetenv("TERMCAP"); + setenv("LOGNAME", pw->pw_name, 1); + setenv("USER", pw->pw_name, 1); + setenv("SHELL", sh, 1); + setenv("HOME", pw->pw_dir, 1); + setenv("TERM", termname, 1); + + signal(SIGCHLD, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGALRM, SIG_DFL); + + execvp(prog, args); + _exit(1); +} + +void +sigchld(int a) +{ + int stat; + pid_t p; + + if ((p = waitpid(pid, &stat, WNOHANG)) < 0) + die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); + + if (pid != p) + return; + + if (WIFEXITED(stat) && WEXITSTATUS(stat)) + die("child exited with status %d\n", WEXITSTATUS(stat)); + else if (WIFSIGNALED(stat)) + die("child terminated due to signal %d\n", WTERMSIG(stat)); + _exit(0); +} + +void +stty(char **args) +{ + char cmd[_POSIX_ARG_MAX], **p, *q, *s; + size_t n, siz; + + if ((n = strlen(stty_args)) > sizeof(cmd)-1) + die("incorrect stty parameters\n"); + memcpy(cmd, stty_args, n); + q = cmd + n; + siz = sizeof(cmd) - n; + for (p = args; p && (s = *p); ++p) { + if ((n = strlen(s)) > siz-1) + die("stty parameter length too long\n"); + *q++ = ' '; + memcpy(q, s, n); + q += n; + siz -= n + 1; + } + *q = '\0'; + if (system(cmd) != 0) + perror("Couldn't call stty"); +} + +int +ttynew(const char *line, char *cmd, const char *out, char **args) +{ + int m, s; + + if (out) { + term.mode |= MODE_PRINT; + iofd = (!strcmp(out, "-")) ? + 1 : open(out, O_WRONLY | O_CREAT, 0666); + if (iofd < 0) { + fprintf(stderr, "Error opening %s:%s\n", + out, strerror(errno)); + } + } + + if (line) { + if ((cmdfd = open(line, O_RDWR)) < 0) + die("open line '%s' failed: %s\n", + line, strerror(errno)); + dup2(cmdfd, 0); + stty(args); + return cmdfd; + } + + /* seems to work fine on linux, openbsd and freebsd */ + if (openpty(&m, &s, NULL, NULL, NULL) < 0) + die("openpty failed: %s\n", strerror(errno)); + + switch (pid = fork()) { + case -1: + die("fork failed: %s\n", strerror(errno)); + break; + case 0: + close(iofd); + close(m); + setsid(); /* create a new process group */ + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + if (ioctl(s, TIOCSCTTY, NULL) < 0) + die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); + if (s > 2) + close(s); +#ifdef __OpenBSD__ + if (pledge("stdio getpw proc exec", NULL) == -1) + die("pledge\n"); +#endif + execsh(cmd, args); + break; + default: +#ifdef __OpenBSD__ + if (pledge("stdio rpath tty proc", NULL) == -1) + die("pledge\n"); +#endif + close(s); + cmdfd = m; + signal(SIGCHLD, sigchld); + break; + } + return cmdfd; +} + +size_t +ttyread(void) +{ + static char buf[BUFSIZ]; + static int buflen = 0; + int ret, written; + + /* append read bytes to unprocessed bytes */ + ret = read(cmdfd, buf+buflen, LEN(buf)-buflen); + + switch (ret) { + case 0: + exit(0); + case -1: + die("couldn't read from shell: %s\n", strerror(errno)); + default: + buflen += ret; + written = twrite(buf, buflen, 0); + buflen -= written; + /* keep any incomplete UTF-8 byte sequence for the next call */ + if (buflen > 0) + memmove(buf, buf + written, buflen); + return ret; + } +} + +void +ttywrite(const char *s, size_t n, int may_echo) +{ + const char *next; + Arg arg = (Arg) { .i = term.scr }; + + kscrolldown(&arg); + + if (may_echo && IS_SET(MODE_ECHO)) + twrite(s, n, 1); + + if (!IS_SET(MODE_CRLF)) { + ttywriteraw(s, n); + return; + } + + /* This is similar to how the kernel handles ONLCR for ttys */ + while (n > 0) { + if (*s == '\r') { + next = s + 1; + ttywriteraw("\r\n", 2); + } else { + next = memchr(s, '\r', n); + DEFAULT(next, s + n); + ttywriteraw(s, next - s); + } + n -= next - s; + s = next; + } +} + +void +ttywriteraw(const char *s, size_t n) +{ + fd_set wfd, rfd; + ssize_t r; + size_t lim = 256; + + /* + * Remember that we are using a pty, which might be a modem line. + * Writing too much will clog the line. That's why we are doing this + * dance. + * FIXME: Migrate the world to Plan 9. + */ + while (n > 0) { + FD_ZERO(&wfd); + FD_ZERO(&rfd); + FD_SET(cmdfd, &wfd); + FD_SET(cmdfd, &rfd); + + /* Check if we can write. */ + if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) { + if (errno == EINTR) + continue; + die("select failed: %s\n", strerror(errno)); + } + if (FD_ISSET(cmdfd, &wfd)) { + /* + * Only write the bytes written by ttywrite() or the + * default of 256. This seems to be a reasonable value + * for a serial line. Bigger values might clog the I/O. + */ + if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0) + goto write_error; + if (r < n) { + /* + * We weren't able to write out everything. + * This means the buffer is getting full + * again. Empty it. + */ + if (n < lim) + lim = ttyread(); + n -= r; + s += r; + } else { + /* All bytes have been written. */ + break; + } + } + if (FD_ISSET(cmdfd, &rfd)) + lim = ttyread(); + } + return; + +write_error: + die("write error on tty: %s\n", strerror(errno)); +} + +void +ttyresize(int tw, int th) +{ + struct winsize w; + + w.ws_row = term.row; + w.ws_col = term.col; + w.ws_xpixel = tw; + w.ws_ypixel = th; + if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0) + fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno)); +} + +void +ttyhangup() +{ + /* Send SIGHUP to shell */ + kill(pid, SIGHUP); +} + +int +tattrset(int attr) +{ + int i, j; + + for (i = 0; i < term.row-1; i++) { + for (j = 0; j < term.col-1; j++) { + if (term.line[i][j].mode & attr) + return 1; + } + } + + return 0; +} + +void +tsetdirt(int top, int bot) +{ + int i; + + LIMIT(top, 0, term.row-1); + LIMIT(bot, 0, term.row-1); + + for (i = top; i <= bot; i++) + term.dirty[i] = 1; +} + +void +tsetdirtattr(int attr) +{ + int i, j; + + for (i = 0; i < term.row-1; i++) { + for (j = 0; j < term.col-1; j++) { + if (term.line[i][j].mode & attr) { + tsetdirt(i, i); + break; + } + } + } +} + +void +tfulldirt(void) +{ + tsetdirt(0, term.row-1); +} + +void +tcursor(int mode) +{ + static TCursor c[2]; + int alt = IS_SET(MODE_ALTSCREEN); + + if (mode == CURSOR_SAVE) { + c[alt] = term.c; + } else if (mode == CURSOR_LOAD) { + term.c = c[alt]; + tmoveto(c[alt].x, c[alt].y); + } +} + +void +treset(void) +{ + uint i; + + term.c = (TCursor){{ + .mode = ATTR_NULL, + .fg = defaultfg, + .bg = defaultbg + }, .x = 0, .y = 0, .state = CURSOR_DEFAULT}; + + memset(term.tabs, 0, term.col * sizeof(*term.tabs)); + for (i = tabspaces; i < term.col; i += tabspaces) + term.tabs[i] = 1; + term.top = 0; + term.bot = term.row - 1; + term.mode = MODE_WRAP|MODE_UTF8; + memset(term.trantbl, CS_USA, sizeof(term.trantbl)); + term.charset = 0; + + for (i = 0; i < 2; i++) { + tmoveto(0, 0); + tcursor(CURSOR_SAVE); + tclearregion(0, 0, term.col-1, term.row-1); + tswapscreen(); + } +} + +void +tnew(int col, int row) +{ + term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } }; + tresize(col, row); + treset(); +} + +void +tswapscreen(void) +{ + Line *tmp = term.line; + + term.line = term.alt; + term.alt = tmp; + term.mode ^= MODE_ALTSCREEN; + tfulldirt(); +} + +void +kscrolldown(const Arg* a) +{ + int n = a->i; + + if (n < 0) + n = term.row + n; + + if (n > term.scr) + n = term.scr; + + if (term.scr > 0) { + term.scr -= n; + selscroll(0, -n); + tfulldirt(); + } +} + +void +kscrollup(const Arg* a) +{ + int n = a->i; + + if (n < 0) + n = term.row + n; + + if (term.scr <= HISTSIZE-n) { + term.scr += n; + selscroll(0, n); + tfulldirt(); + } +} + +void +tscrolldown(int orig, int n, int copyhist) +{ + int i; + Line temp; + + LIMIT(n, 0, term.bot-orig+1); + + if (copyhist) { + term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE; + temp = term.hist[term.histi]; + term.hist[term.histi] = term.line[term.bot]; + term.line[term.bot] = temp; + } + + tsetdirt(orig, term.bot-n); + tclearregion(0, term.bot-n+1, term.col-1, term.bot); + + for (i = term.bot; i >= orig+n; i--) { + temp = term.line[i]; + term.line[i] = term.line[i-n]; + term.line[i-n] = temp; + } + + if (term.scr == 0) + selscroll(orig, n); +} + +void +tscrollup(int orig, int n, int copyhist) +{ + int i; + Line temp; + + LIMIT(n, 0, term.bot-orig+1); + + if (copyhist) { + term.histi = (term.histi + 1) % HISTSIZE; + temp = term.hist[term.histi]; + term.hist[term.histi] = term.line[orig]; + term.line[orig] = temp; + } + + if (term.scr > 0 && term.scr < HISTSIZE) + term.scr = MIN(term.scr + n, HISTSIZE-1); + + tclearregion(0, orig, term.col-1, orig+n-1); + tsetdirt(orig+n, term.bot); + + for (i = orig; i <= term.bot-n; i++) { + temp = term.line[i]; + term.line[i] = term.line[i+n]; + term.line[i+n] = temp; + } + + if (term.scr == 0) + selscroll(orig, -n); +} + +void +selscroll(int orig, int n) +{ + if (sel.ob.x == -1) + return; + + if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) { + selclear(); + } else if (BETWEEN(sel.nb.y, orig, term.bot)) { + sel.ob.y += n; + sel.oe.y += n; + if (sel.ob.y < term.top || sel.ob.y > term.bot || + sel.oe.y < term.top || sel.oe.y > term.bot) { + selclear(); + } else { + selnormalize(); + } + } +} + +void +tnewline(int first_col) +{ + int y = term.c.y; + + if (y == term.bot) { + tscrollup(term.top, 1, 1); + } else { + y++; + } + tmoveto(first_col ? 0 : term.c.x, y); +} + +void +csiparse(void) +{ + char *p = csiescseq.buf, *np; + long int v; + + csiescseq.narg = 0; + if (*p == '?') { + csiescseq.priv = 1; + p++; + } + + csiescseq.buf[csiescseq.len] = '\0'; + while (p < csiescseq.buf+csiescseq.len) { + np = NULL; + v = strtol(p, &np, 10); + if (np == p) + v = 0; + if (v == LONG_MAX || v == LONG_MIN) + v = -1; + csiescseq.arg[csiescseq.narg++] = v; + p = np; + if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) + break; + p++; + } + csiescseq.mode[0] = *p++; + csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0'; +} + +/* for absolute user moves, when decom is set */ +void +tmoveato(int x, int y) +{ + tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0)); +} + +void +tmoveto(int x, int y) +{ + int miny, maxy; + + if (term.c.state & CURSOR_ORIGIN) { + miny = term.top; + maxy = term.bot; + } else { + miny = 0; + maxy = term.row - 1; + } + term.c.state &= ~CURSOR_WRAPNEXT; + term.c.x = LIMIT(x, 0, term.col-1); + term.c.y = LIMIT(y, miny, maxy); +} + +void +tsetchar(Rune u, const Glyph *attr, int x, int y) +{ + static const char *vt100_0[62] = { /* 0x41 - 0x7e */ + "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ + 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ + 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ + 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */ + "◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */ + "␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */ + "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ + "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ + }; + + /* + * The table is proudly stolen from rxvt. + */ + if (term.trantbl[term.charset] == CS_GRAPHIC0 && + BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41]) + utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ); + + if (term.line[y][x].mode & ATTR_WIDE) { + if (x+1 < term.col) { + term.line[y][x+1].u = ' '; + term.line[y][x+1].mode &= ~ATTR_WDUMMY; + } + } else if (term.line[y][x].mode & ATTR_WDUMMY) { + term.line[y][x-1].u = ' '; + term.line[y][x-1].mode &= ~ATTR_WIDE; + } + + term.dirty[y] = 1; + term.line[y][x] = *attr; + term.line[y][x].u = u; +} + +void +tclearregion(int x1, int y1, int x2, int y2) +{ + int x, y, temp; + Glyph *gp; + + if (x1 > x2) + temp = x1, x1 = x2, x2 = temp; + if (y1 > y2) + temp = y1, y1 = y2, y2 = temp; + + LIMIT(x1, 0, term.col-1); + LIMIT(x2, 0, term.col-1); + LIMIT(y1, 0, term.row-1); + LIMIT(y2, 0, term.row-1); + + for (y = y1; y <= y2; y++) { + term.dirty[y] = 1; + for (x = x1; x <= x2; x++) { + gp = &term.line[y][x]; + if (selected(x, y)) + selclear(); + gp->fg = term.c.attr.fg; + gp->bg = term.c.attr.bg; + gp->mode = 0; + gp->u = ' '; + } + } +} + +void +tdeletechar(int n) +{ + int dst, src, size; + Glyph *line; + + LIMIT(n, 0, term.col - term.c.x); + + dst = term.c.x; + src = term.c.x + n; + size = term.col - src; + line = term.line[term.c.y]; + + memmove(&line[dst], &line[src], size * sizeof(Glyph)); + tclearregion(term.col-n, term.c.y, term.col-1, term.c.y); +} + +void +tinsertblank(int n) +{ + int dst, src, size; + Glyph *line; + + LIMIT(n, 0, term.col - term.c.x); + + dst = term.c.x + n; + src = term.c.x; + size = term.col - dst; + line = term.line[term.c.y]; + + memmove(&line[dst], &line[src], size * sizeof(Glyph)); + tclearregion(src, term.c.y, dst - 1, term.c.y); +} + +void +tinsertblankline(int n) +{ + if (BETWEEN(term.c.y, term.top, term.bot)) + tscrolldown(term.c.y, n, 0); +} + +void +tdeleteline(int n) +{ + if (BETWEEN(term.c.y, term.top, term.bot)) + tscrollup(term.c.y, n, 0); +} + +int32_t +tdefcolor(const int *attr, int *npar, int l) +{ + int32_t idx = -1; + uint r, g, b; + + switch (attr[*npar + 1]) { + case 2: /* direct color in RGB space */ + if (*npar + 4 >= l) { + fprintf(stderr, + "erresc(38): Incorrect number of parameters (%d)\n", + *npar); + break; + } + r = attr[*npar + 2]; + g = attr[*npar + 3]; + b = attr[*npar + 4]; + *npar += 4; + if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255)) + fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n", + r, g, b); + else + idx = TRUECOLOR(r, g, b); + break; + case 5: /* indexed color */ + if (*npar + 2 >= l) { + fprintf(stderr, + "erresc(38): Incorrect number of parameters (%d)\n", + *npar); + break; + } + *npar += 2; + if (!BETWEEN(attr[*npar], 0, 255)) + fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]); + else + idx = attr[*npar]; + break; + case 0: /* implemented defined (only foreground) */ + case 1: /* transparent */ + case 3: /* direct color in CMY space */ + case 4: /* direct color in CMYK space */ + default: + fprintf(stderr, + "erresc(38): gfx attr %d unknown\n", attr[*npar]); + break; + } + + return idx; +} + +void +tsetattr(const int *attr, int l) +{ + int i; + int32_t idx; + + for (i = 0; i < l; i++) { + switch (attr[i]) { + case 0: + term.c.attr.mode &= ~( + ATTR_BOLD | + ATTR_FAINT | + ATTR_ITALIC | + ATTR_UNDERLINE | + ATTR_BLINK | + ATTR_REVERSE | + ATTR_INVISIBLE | + ATTR_STRUCK ); + term.c.attr.fg = defaultfg; + term.c.attr.bg = defaultbg; + break; + case 1: + term.c.attr.mode |= ATTR_BOLD; + break; + case 2: + term.c.attr.mode |= ATTR_FAINT; + break; + case 3: + term.c.attr.mode |= ATTR_ITALIC; + break; + case 4: + term.c.attr.mode |= ATTR_UNDERLINE; + break; + case 5: /* slow blink */ + /* FALLTHROUGH */ + case 6: /* rapid blink */ + term.c.attr.mode |= ATTR_BLINK; + break; + case 7: + term.c.attr.mode |= ATTR_REVERSE; + break; + case 8: + term.c.attr.mode |= ATTR_INVISIBLE; + break; + case 9: + term.c.attr.mode |= ATTR_STRUCK; + break; + case 22: + term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT); + break; + case 23: + term.c.attr.mode &= ~ATTR_ITALIC; + break; + case 24: + term.c.attr.mode &= ~ATTR_UNDERLINE; + break; + case 25: + term.c.attr.mode &= ~ATTR_BLINK; + break; + case 27: + term.c.attr.mode &= ~ATTR_REVERSE; + break; + case 28: + term.c.attr.mode &= ~ATTR_INVISIBLE; + break; + case 29: + term.c.attr.mode &= ~ATTR_STRUCK; + break; + case 38: + if ((idx = tdefcolor(attr, &i, l)) >= 0) + term.c.attr.fg = idx; + break; + case 39: + term.c.attr.fg = defaultfg; + break; + case 48: + if ((idx = tdefcolor(attr, &i, l)) >= 0) + term.c.attr.bg = idx; + break; + case 49: + term.c.attr.bg = defaultbg; + break; + default: + if (BETWEEN(attr[i], 30, 37)) { + term.c.attr.fg = attr[i] - 30; + } else if (BETWEEN(attr[i], 40, 47)) { + term.c.attr.bg = attr[i] - 40; + } else if (BETWEEN(attr[i], 90, 97)) { + term.c.attr.fg = attr[i] - 90 + 8; + } else if (BETWEEN(attr[i], 100, 107)) { + term.c.attr.bg = attr[i] - 100 + 8; + } else { + fprintf(stderr, + "erresc(default): gfx attr %d unknown\n", + attr[i]); + csidump(); + } + break; + } + } +} + +void +tsetscroll(int t, int b) +{ + int temp; + + LIMIT(t, 0, term.row-1); + LIMIT(b, 0, term.row-1); + if (t > b) { + temp = t; + t = b; + b = temp; + } + term.top = t; + term.bot = b; +} + +void +tsetmode(int priv, int set, const int *args, int narg) +{ + int alt; const int *lim; + + for (lim = args + narg; args < lim; ++args) { + if (priv) { + switch (*args) { + case 1: /* DECCKM -- Cursor key */ + xsetmode(set, MODE_APPCURSOR); + break; + case 5: /* DECSCNM -- Reverse video */ + xsetmode(set, MODE_REVERSE); + break; + case 6: /* DECOM -- Origin */ + MODBIT(term.c.state, set, CURSOR_ORIGIN); + tmoveato(0, 0); + break; + case 7: /* DECAWM -- Auto wrap */ + MODBIT(term.mode, set, MODE_WRAP); + break; + case 0: /* Error (IGNORED) */ + case 2: /* DECANM -- ANSI/VT52 (IGNORED) */ + case 3: /* DECCOLM -- Column (IGNORED) */ + case 4: /* DECSCLM -- Scroll (IGNORED) */ + case 8: /* DECARM -- Auto repeat (IGNORED) */ + case 18: /* DECPFF -- Printer feed (IGNORED) */ + case 19: /* DECPEX -- Printer extent (IGNORED) */ + case 42: /* DECNRCM -- National characters (IGNORED) */ + case 12: /* att610 -- Start blinking cursor (IGNORED) */ + break; + case 25: /* DECTCEM -- Text Cursor Enable Mode */ + xsetmode(!set, MODE_HIDE); + break; + case 9: /* X10 mouse compatibility mode */ + xsetpointermotion(0); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEX10); + break; + case 1000: /* 1000: report button press */ + xsetpointermotion(0); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEBTN); + break; + case 1002: /* 1002: report motion on button press */ + xsetpointermotion(0); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEMOTION); + break; + case 1003: /* 1003: enable all mouse motions */ + xsetpointermotion(set); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEMANY); + break; + case 1004: /* 1004: send focus events to tty */ + xsetmode(set, MODE_FOCUS); + break; + case 1006: /* 1006: extended reporting mode */ + xsetmode(set, MODE_MOUSESGR); + break; + case 1034: + xsetmode(set, MODE_8BIT); + break; + case 1049: /* swap screen & set/restore cursor as xterm */ + if (!allowaltscreen) + break; + tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); + /* FALLTHROUGH */ + case 47: /* swap screen */ + case 1047: + if (!allowaltscreen) + break; + alt = IS_SET(MODE_ALTSCREEN); + if (alt) { + tclearregion(0, 0, term.col-1, + term.row-1); + } + if (set ^ alt) /* set is always 1 or 0 */ + tswapscreen(); + if (*args != 1049) + break; + /* FALLTHROUGH */ + case 1048: + tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); + break; + case 2004: /* 2004: bracketed paste mode */ + xsetmode(set, MODE_BRCKTPASTE); + break; + /* Not implemented mouse modes. See comments there. */ + case 1001: /* mouse highlight mode; can hang the + terminal by design when implemented. */ + case 1005: /* UTF-8 mouse mode; will confuse + applications not supporting UTF-8 + and luit. */ + case 1015: /* urxvt mangled mouse mode; incompatible + and can be mistaken for other control + codes. */ + break; + default: + fprintf(stderr, + "erresc: unknown private set/reset mode %d\n", + *args); + break; + } + } else { + switch (*args) { + case 0: /* Error (IGNORED) */ + break; + case 2: + xsetmode(set, MODE_KBDLOCK); + break; + case 4: /* IRM -- Insertion-replacement */ + MODBIT(term.mode, set, MODE_INSERT); + break; + case 12: /* SRM -- Send/Receive */ + MODBIT(term.mode, !set, MODE_ECHO); + break; + case 20: /* LNM -- Linefeed/new line */ + MODBIT(term.mode, set, MODE_CRLF); + break; + default: + fprintf(stderr, + "erresc: unknown set/reset mode %d\n", + *args); + break; + } + } + } +} + +void +csihandle(void) +{ + char buf[40]; + int len; + + switch (csiescseq.mode[0]) { + default: + unknown: + fprintf(stderr, "erresc: unknown csi "); + csidump(); + /* die(""); */ + break; + case '@': /* ICH -- Insert blank char */ + DEFAULT(csiescseq.arg[0], 1); + tinsertblank(csiescseq.arg[0]); + break; + case 'A': /* CUU -- Cursor Up */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(term.c.x, term.c.y-csiescseq.arg[0]); + break; + case 'B': /* CUD -- Cursor Down */ + case 'e': /* VPR --Cursor Down */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(term.c.x, term.c.y+csiescseq.arg[0]); + break; + case 'i': /* MC -- Media Copy */ + switch (csiescseq.arg[0]) { + case 0: + tdump(); + break; + case 1: + tdumpline(term.c.y); + break; + case 2: + tdumpsel(); + break; + case 4: + term.mode &= ~MODE_PRINT; + break; + case 5: + term.mode |= MODE_PRINT; + break; + } + break; + case 'c': /* DA -- Device Attributes */ + if (csiescseq.arg[0] == 0) + ttywrite(vtiden, strlen(vtiden), 0); + break; + case 'b': /* REP -- if last char is printable print it more times */ + DEFAULT(csiescseq.arg[0], 1); + if (term.lastc) + while (csiescseq.arg[0]-- > 0) + tputc(term.lastc); + break; + case 'C': /* CUF -- Cursor Forward */ + case 'a': /* HPR -- Cursor Forward */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(term.c.x+csiescseq.arg[0], term.c.y); + break; + case 'D': /* CUB -- Cursor Backward */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(term.c.x-csiescseq.arg[0], term.c.y); + break; + case 'E': /* CNL -- Cursor Down and first col */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(0, term.c.y+csiescseq.arg[0]); + break; + case 'F': /* CPL -- Cursor Up and first col */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(0, term.c.y-csiescseq.arg[0]); + break; + case 'g': /* TBC -- Tabulation clear */ + switch (csiescseq.arg[0]) { + case 0: /* clear current tab stop */ + term.tabs[term.c.x] = 0; + break; + case 3: /* clear all the tabs */ + memset(term.tabs, 0, term.col * sizeof(*term.tabs)); + break; + default: + goto unknown; + } + break; + case 'G': /* CHA -- Move to */ + case '`': /* HPA */ + DEFAULT(csiescseq.arg[0], 1); + tmoveto(csiescseq.arg[0]-1, term.c.y); + break; + case 'H': /* CUP -- Move to */ + case 'f': /* HVP */ + DEFAULT(csiescseq.arg[0], 1); + DEFAULT(csiescseq.arg[1], 1); + tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1); + break; + case 'I': /* CHT -- Cursor Forward Tabulation tab stops */ + DEFAULT(csiescseq.arg[0], 1); + tputtab(csiescseq.arg[0]); + break; + case 'J': /* ED -- Clear screen */ + switch (csiescseq.arg[0]) { + case 0: /* below */ + tclearregion(term.c.x, term.c.y, term.col-1, term.c.y); + if (term.c.y < term.row-1) { + tclearregion(0, term.c.y+1, term.col-1, + term.row-1); + } + break; + case 1: /* above */ + if (term.c.y > 1) + tclearregion(0, 0, term.col-1, term.c.y-1); + tclearregion(0, term.c.y, term.c.x, term.c.y); + break; + case 2: /* all */ + tclearregion(0, 0, term.col-1, term.row-1); + break; + default: + goto unknown; + } + break; + case 'K': /* EL -- Clear line */ + switch (csiescseq.arg[0]) { + case 0: /* right */ + tclearregion(term.c.x, term.c.y, term.col-1, + term.c.y); + break; + case 1: /* left */ + tclearregion(0, term.c.y, term.c.x, term.c.y); + break; + case 2: /* all */ + tclearregion(0, term.c.y, term.col-1, term.c.y); + break; + } + break; + case 'S': /* SU -- Scroll line up */ + DEFAULT(csiescseq.arg[0], 1); + tscrollup(term.top, csiescseq.arg[0], 0); + break; + case 'T': /* SD -- Scroll line down */ + DEFAULT(csiescseq.arg[0], 1); + tscrolldown(term.top, csiescseq.arg[0], 0); + break; + case 'L': /* IL -- Insert blank lines */ + DEFAULT(csiescseq.arg[0], 1); + tinsertblankline(csiescseq.arg[0]); + break; + case 'l': /* RM -- Reset Mode */ + tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg); + break; + case 'M': /* DL -- Delete lines */ + DEFAULT(csiescseq.arg[0], 1); + tdeleteline(csiescseq.arg[0]); + break; + case 'X': /* ECH -- Erase char */ + DEFAULT(csiescseq.arg[0], 1); + tclearregion(term.c.x, term.c.y, + term.c.x + csiescseq.arg[0] - 1, term.c.y); + break; + case 'P': /* DCH -- Delete char */ + DEFAULT(csiescseq.arg[0], 1); + tdeletechar(csiescseq.arg[0]); + break; + case 'Z': /* CBT -- Cursor Backward Tabulation tab stops */ + DEFAULT(csiescseq.arg[0], 1); + tputtab(-csiescseq.arg[0]); + break; + case 'd': /* VPA -- Move to */ + DEFAULT(csiescseq.arg[0], 1); + tmoveato(term.c.x, csiescseq.arg[0]-1); + break; + case 'h': /* SM -- Set terminal mode */ + tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg); + break; + case 'm': /* SGR -- Terminal attribute (color) */ + tsetattr(csiescseq.arg, csiescseq.narg); + break; + case 'n': /* DSR – Device Status Report (cursor position) */ + if (csiescseq.arg[0] == 6) { + len = snprintf(buf, sizeof(buf), "\033[%i;%iR", + term.c.y+1, term.c.x+1); + ttywrite(buf, len, 0); + } + break; + case 'r': /* DECSTBM -- Set Scrolling Region */ + if (csiescseq.priv) { + goto unknown; + } else { + DEFAULT(csiescseq.arg[0], 1); + DEFAULT(csiescseq.arg[1], term.row); + tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1); + tmoveato(0, 0); + } + break; + case 's': /* DECSC -- Save cursor position (ANSI.SYS) */ + tcursor(CURSOR_SAVE); + break; + case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ + tcursor(CURSOR_LOAD); + break; + case ' ': + switch (csiescseq.mode[1]) { + case 'q': /* DECSCUSR -- Set Cursor Style */ + if (xsetcursor(csiescseq.arg[0])) + goto unknown; + break; + default: + goto unknown; + } + break; + } +} + +void +csidump(void) +{ + size_t i; + uint c; + + fprintf(stderr, "ESC["); + for (i = 0; i < csiescseq.len; i++) { + c = csiescseq.buf[i] & 0xff; + if (isprint(c)) { + putc(c, stderr); + } else if (c == '\n') { + fprintf(stderr, "(\\n)"); + } else if (c == '\r') { + fprintf(stderr, "(\\r)"); + } else if (c == 0x1b) { + fprintf(stderr, "(\\e)"); + } else { + fprintf(stderr, "(%02x)", c); + } + } + putc('\n', stderr); +} + +void +csireset(void) +{ + memset(&csiescseq, 0, sizeof(csiescseq)); +} + +void +osc4_color_response(int num) +{ + int n; + char buf[32]; + unsigned char r, g, b; + + if (xgetcolor(num, &r, &g, &b)) { + fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num); + return; + } + + n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", + num, r, r, g, g, b, b); + + ttywrite(buf, n, 1); +} + +void +osc_color_response(int index, int num) +{ + int n; + char buf[32]; + unsigned char r, g, b; + + if (xgetcolor(index, &r, &g, &b)) { + fprintf(stderr, "erresc: failed to fetch osc color %d\n", index); + return; + } + + n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", + num, r, r, g, g, b, b); + + ttywrite(buf, n, 1); +} + +void +strhandle(void) +{ + char *p = NULL, *dec; + int j, narg, par; + + term.esc &= ~(ESC_STR_END|ESC_STR); + strparse(); + par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0; + + switch (strescseq.type) { + case ']': /* OSC -- Operating System Command */ + switch (par) { + case 0: + if (narg > 1) { + xsettitle(strescseq.args[1]); + xseticontitle(strescseq.args[1]); + } + return; + case 1: + if (narg > 1) + xseticontitle(strescseq.args[1]); + return; + case 2: + if (narg > 1) + xsettitle(strescseq.args[1]); + return; + case 52: + if (narg > 2 && allowwindowops) { + dec = base64dec(strescseq.args[2]); + if (dec) { + xsetsel(dec); + xclipcopy(); + } else { + fprintf(stderr, "erresc: invalid base64\n"); + } + } + return; + case 10: + if (narg < 2) + break; + + p = strescseq.args[1]; + + if (!strcmp(p, "?")) + osc_color_response(defaultfg, 10); + else if (xsetcolorname(defaultfg, p)) + fprintf(stderr, "erresc: invalid foreground color: %s\n", p); + else + tfulldirt(); + return; + case 11: + if (narg < 2) + break; + + p = strescseq.args[1]; + + if (!strcmp(p, "?")) + osc_color_response(defaultbg, 11); + else if (xsetcolorname(defaultbg, p)) + fprintf(stderr, "erresc: invalid background color: %s\n", p); + else + tfulldirt(); + return; + case 12: + if (narg < 2) + break; + + p = strescseq.args[1]; + + if (!strcmp(p, "?")) + osc_color_response(defaultcs, 12); + else if (xsetcolorname(defaultcs, p)) + fprintf(stderr, "erresc: invalid cursor color: %s\n", p); + else + tfulldirt(); + return; + case 4: /* color set */ + if (narg < 3) + break; + p = strescseq.args[2]; + /* FALLTHROUGH */ + case 104: /* color reset */ + j = (narg > 1) ? atoi(strescseq.args[1]) : -1; + + if (p && !strcmp(p, "?")) + osc4_color_response(j); + else if (xsetcolorname(j, p)) { + if (par == 104 && narg <= 1) + return; /* color reset without parameter */ + fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", + j, p ? p : "(null)"); + } else { + /* + * TODO if defaultbg color is changed, borders + * are dirty + */ + tfulldirt(); + } + return; + } + break; + case 'k': /* old title set compatibility */ + xsettitle(strescseq.args[0]); + return; + case 'P': /* DCS -- Device Control String */ + case '_': /* APC -- Application Program Command */ + case '^': /* PM -- Privacy Message */ + return; + } + + fprintf(stderr, "erresc: unknown str "); + strdump(); +} + +void +strparse(void) +{ + int c; + char *p = strescseq.buf; + + strescseq.narg = 0; + strescseq.buf[strescseq.len] = '\0'; + + if (*p == '\0') + return; + + while (strescseq.narg < STR_ARG_SIZ) { + strescseq.args[strescseq.narg++] = p; + while ((c = *p) != ';' && c != '\0') + ++p; + if (c == '\0') + return; + *p++ = '\0'; + } +} + +void +strdump(void) +{ + size_t i; + uint c; + + fprintf(stderr, "ESC%c", strescseq.type); + for (i = 0; i < strescseq.len; i++) { + c = strescseq.buf[i] & 0xff; + if (c == '\0') { + putc('\n', stderr); + return; + } else if (isprint(c)) { + putc(c, stderr); + } else if (c == '\n') { + fprintf(stderr, "(\\n)"); + } else if (c == '\r') { + fprintf(stderr, "(\\r)"); + } else if (c == 0x1b) { + fprintf(stderr, "(\\e)"); + } else { + fprintf(stderr, "(%02x)", c); + } + } + fprintf(stderr, "ESC\\\n"); +} + +void +strreset(void) +{ + strescseq = (STREscape){ + .buf = xrealloc(strescseq.buf, STR_BUF_SIZ), + .siz = STR_BUF_SIZ, + }; +} + +void +sendbreak(const Arg *arg) +{ + if (tcsendbreak(cmdfd, 0)) + perror("Error sending break"); +} + +void +tprinter(char *s, size_t len) +{ + if (iofd != -1 && xwrite(iofd, s, len) < 0) { + perror("Error writing to output file"); + close(iofd); + iofd = -1; + } +} + +void +toggleprinter(const Arg *arg) +{ + term.mode ^= MODE_PRINT; +} + +void +printscreen(const Arg *arg) +{ + tdump(); +} + +void +printsel(const Arg *arg) +{ + tdumpsel(); +} + +void +tdumpsel(void) +{ + char *ptr; + + if ((ptr = getsel())) { + tprinter(ptr, strlen(ptr)); + free(ptr); + } +} + +void +tdumpline(int n) +{ + char buf[UTF_SIZ]; + const Glyph *bp, *end; + + bp = &term.line[n][0]; + end = &bp[MIN(tlinelen(n), term.col) - 1]; + if (bp != end || bp->u != ' ') { + for ( ; bp <= end; ++bp) + tprinter(buf, utf8encode(bp->u, buf)); + } + tprinter("\n", 1); +} + +void +tdump(void) +{ + int i; + + for (i = 0; i < term.row; ++i) + tdumpline(i); +} + +void +tputtab(int n) +{ + uint x = term.c.x; + + if (n > 0) { + while (x < term.col && n--) + for (++x; x < term.col && !term.tabs[x]; ++x) + /* nothing */ ; + } else if (n < 0) { + while (x > 0 && n++) + for (--x; x > 0 && !term.tabs[x]; --x) + /* nothing */ ; + } + term.c.x = LIMIT(x, 0, term.col-1); +} + +void +tdefutf8(char ascii) +{ + if (ascii == 'G') + term.mode |= MODE_UTF8; + else if (ascii == '@') + term.mode &= ~MODE_UTF8; +} + +void +tdeftran(char ascii) +{ + static char cs[] = "0B"; + static int vcs[] = {CS_GRAPHIC0, CS_USA}; + char *p; + + if ((p = strchr(cs, ascii)) == NULL) { + fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii); + } else { + term.trantbl[term.icharset] = vcs[p - cs]; + } +} + +void +tdectest(char c) +{ + int x, y; + + if (c == '8') { /* DEC screen alignment test. */ + for (x = 0; x < term.col; ++x) { + for (y = 0; y < term.row; ++y) + tsetchar('E', &term.c.attr, x, y); + } + } +} + +void +tstrsequence(uchar c) +{ + switch (c) { + case 0x90: /* DCS -- Device Control String */ + c = 'P'; + break; + case 0x9f: /* APC -- Application Program Command */ + c = '_'; + break; + case 0x9e: /* PM -- Privacy Message */ + c = '^'; + break; + case 0x9d: /* OSC -- Operating System Command */ + c = ']'; + break; + } + strreset(); + strescseq.type = c; + term.esc |= ESC_STR; +} + +void +tcontrolcode(uchar ascii) +{ + switch (ascii) { + case '\t': /* HT */ + tputtab(1); + return; + case '\b': /* BS */ + tmoveto(term.c.x-1, term.c.y); + return; + case '\r': /* CR */ + tmoveto(0, term.c.y); + return; + case '\f': /* LF */ + case '\v': /* VT */ + case '\n': /* LF */ + /* go to first col if the mode is set */ + tnewline(IS_SET(MODE_CRLF)); + return; + case '\a': /* BEL */ + if (term.esc & ESC_STR_END) { + /* backwards compatibility to xterm */ + strhandle(); + } else { + xbell(); + } + break; + case '\033': /* ESC */ + csireset(); + term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST); + term.esc |= ESC_START; + return; + case '\016': /* SO (LS1 -- Locking shift 1) */ + case '\017': /* SI (LS0 -- Locking shift 0) */ + term.charset = 1 - (ascii - '\016'); + return; + case '\032': /* SUB */ + tsetchar('?', &term.c.attr, term.c.x, term.c.y); + /* FALLTHROUGH */ + case '\030': /* CAN */ + csireset(); + break; + case '\005': /* ENQ (IGNORED) */ + case '\000': /* NUL (IGNORED) */ + case '\021': /* XON (IGNORED) */ + case '\023': /* XOFF (IGNORED) */ + case 0177: /* DEL (IGNORED) */ + return; + case 0x80: /* TODO: PAD */ + case 0x81: /* TODO: HOP */ + case 0x82: /* TODO: BPH */ + case 0x83: /* TODO: NBH */ + case 0x84: /* TODO: IND */ + break; + case 0x85: /* NEL -- Next line */ + tnewline(1); /* always go to first col */ + break; + case 0x86: /* TODO: SSA */ + case 0x87: /* TODO: ESA */ + break; + case 0x88: /* HTS -- Horizontal tab stop */ + term.tabs[term.c.x] = 1; + break; + case 0x89: /* TODO: HTJ */ + case 0x8a: /* TODO: VTS */ + case 0x8b: /* TODO: PLD */ + case 0x8c: /* TODO: PLU */ + case 0x8d: /* TODO: RI */ + case 0x8e: /* TODO: SS2 */ + case 0x8f: /* TODO: SS3 */ + case 0x91: /* TODO: PU1 */ + case 0x92: /* TODO: PU2 */ + case 0x93: /* TODO: STS */ + case 0x94: /* TODO: CCH */ + case 0x95: /* TODO: MW */ + case 0x96: /* TODO: SPA */ + case 0x97: /* TODO: EPA */ + case 0x98: /* TODO: SOS */ + case 0x99: /* TODO: SGCI */ + break; + case 0x9a: /* DECID -- Identify Terminal */ + ttywrite(vtiden, strlen(vtiden), 0); + break; + case 0x9b: /* TODO: CSI */ + case 0x9c: /* TODO: ST */ + break; + case 0x90: /* DCS -- Device Control String */ + case 0x9d: /* OSC -- Operating System Command */ + case 0x9e: /* PM -- Privacy Message */ + case 0x9f: /* APC -- Application Program Command */ + tstrsequence(ascii); + return; + } + /* only CAN, SUB, \a and C1 chars interrupt a sequence */ + term.esc &= ~(ESC_STR_END|ESC_STR); +} + +/* + * returns 1 when the sequence is finished and it hasn't to read + * more characters for this sequence, otherwise 0 + */ +int +eschandle(uchar ascii) +{ + switch (ascii) { + case '[': + term.esc |= ESC_CSI; + return 0; + case '#': + term.esc |= ESC_TEST; + return 0; + case '%': + term.esc |= ESC_UTF8; + return 0; + case 'P': /* DCS -- Device Control String */ + case '_': /* APC -- Application Program Command */ + case '^': /* PM -- Privacy Message */ + case ']': /* OSC -- Operating System Command */ + case 'k': /* old title set compatibility */ + tstrsequence(ascii); + return 0; + case 'n': /* LS2 -- Locking shift 2 */ + case 'o': /* LS3 -- Locking shift 3 */ + term.charset = 2 + (ascii - 'n'); + break; + case '(': /* GZD4 -- set primary charset G0 */ + case ')': /* G1D4 -- set secondary charset G1 */ + case '*': /* G2D4 -- set tertiary charset G2 */ + case '+': /* G3D4 -- set quaternary charset G3 */ + term.icharset = ascii - '('; + term.esc |= ESC_ALTCHARSET; + return 0; + case 'D': /* IND -- Linefeed */ + if (term.c.y == term.bot) { + tscrollup(term.top, 1, 1); + } else { + tmoveto(term.c.x, term.c.y+1); + } + break; + case 'E': /* NEL -- Next line */ + tnewline(1); /* always go to first col */ + break; + case 'H': /* HTS -- Horizontal tab stop */ + term.tabs[term.c.x] = 1; + break; + case 'M': /* RI -- Reverse index */ + if (term.c.y == term.top) { + tscrolldown(term.top, 1, 1); + } else { + tmoveto(term.c.x, term.c.y-1); + } + break; + case 'Z': /* DECID -- Identify Terminal */ + ttywrite(vtiden, strlen(vtiden), 0); + break; + case 'c': /* RIS -- Reset to initial state */ + treset(); + resettitle(); + xloadcols(); + break; + case '=': /* DECPAM -- Application keypad */ + xsetmode(1, MODE_APPKEYPAD); + break; + case '>': /* DECPNM -- Normal keypad */ + xsetmode(0, MODE_APPKEYPAD); + break; + case '7': /* DECSC -- Save Cursor */ + tcursor(CURSOR_SAVE); + break; + case '8': /* DECRC -- Restore Cursor */ + tcursor(CURSOR_LOAD); + break; + case '\\': /* ST -- String Terminator */ + if (term.esc & ESC_STR_END) + strhandle(); + break; + default: + fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", + (uchar) ascii, isprint(ascii)? ascii:'.'); + break; + } + return 1; +} + +void +tputc(Rune u) +{ + char c[UTF_SIZ]; + int control; + int width, len; + Glyph *gp; + + control = ISCONTROL(u); + if (u < 127 || !IS_SET(MODE_UTF8)) { + c[0] = u; + width = len = 1; + } else { + len = utf8encode(u, c); + if (!control && (width = wcwidth(u)) == -1) + width = 1; + } + + if (IS_SET(MODE_PRINT)) + tprinter(c, len); + + /* + * STR sequence must be checked before anything else + * because it uses all following characters until it + * receives a ESC, a SUB, a ST or any other C1 control + * character. + */ + if (term.esc & ESC_STR) { + if (u == '\a' || u == 030 || u == 032 || u == 033 || + ISCONTROLC1(u)) { + term.esc &= ~(ESC_START|ESC_STR); + term.esc |= ESC_STR_END; + goto check_control_code; + } + + if (strescseq.len+len >= strescseq.siz) { + /* + * Here is a bug in terminals. If the user never sends + * some code to stop the str or esc command, then st + * will stop responding. But this is better than + * silently failing with unknown characters. At least + * then users will report back. + * + * In the case users ever get fixed, here is the code: + */ + /* + * term.esc = 0; + * strhandle(); + */ + if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2) + return; + strescseq.siz *= 2; + strescseq.buf = xrealloc(strescseq.buf, strescseq.siz); + } + + memmove(&strescseq.buf[strescseq.len], c, len); + strescseq.len += len; + return; + } + +check_control_code: + /* + * Actions of control codes must be performed as soon they arrive + * because they can be embedded inside a control sequence, and + * they must not cause conflicts with sequences. + */ + if (control) { + tcontrolcode(u); + /* + * control codes are not shown ever + */ + if (!term.esc) + term.lastc = 0; + return; + } else if (term.esc & ESC_START) { + if (term.esc & ESC_CSI) { + csiescseq.buf[csiescseq.len++] = u; + if (BETWEEN(u, 0x40, 0x7E) + || csiescseq.len >= \ + sizeof(csiescseq.buf)-1) { + term.esc = 0; + csiparse(); + csihandle(); + } + return; + } else if (term.esc & ESC_UTF8) { + tdefutf8(u); + } else if (term.esc & ESC_ALTCHARSET) { + tdeftran(u); + } else if (term.esc & ESC_TEST) { + tdectest(u); + } else { + if (!eschandle(u)) + return; + /* sequence already finished */ + } + term.esc = 0; + /* + * All characters which form part of a sequence are not + * printed + */ + return; + } + if (selected(term.c.x, term.c.y)) + selclear(); + + gp = &term.line[term.c.y][term.c.x]; + if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) { + gp->mode |= ATTR_WRAP; + tnewline(1); + gp = &term.line[term.c.y][term.c.x]; + } + + if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) + memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph)); + + if (term.c.x+width > term.col) { + tnewline(1); + gp = &term.line[term.c.y][term.c.x]; + } + + tsetchar(u, &term.c.attr, term.c.x, term.c.y); + term.lastc = u; + + if (width == 2) { + gp->mode |= ATTR_WIDE; + if (term.c.x+1 < term.col) { + if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) { + gp[2].u = ' '; + gp[2].mode &= ~ATTR_WDUMMY; + } + gp[1].u = '\0'; + gp[1].mode = ATTR_WDUMMY; + } + } + if (term.c.x+width < term.col) { + tmoveto(term.c.x+width, term.c.y); + } else { + term.c.state |= CURSOR_WRAPNEXT; + } +} + +int +twrite(const char *buf, int buflen, int show_ctrl) +{ + int charsize; + Rune u; + int n; + + for (n = 0; n < buflen; n += charsize) { + if (IS_SET(MODE_UTF8)) { + /* process a complete utf8 char */ + charsize = utf8decode(buf + n, &u, buflen - n); + if (charsize == 0) + break; + } else { + u = buf[n] & 0xFF; + charsize = 1; + } + if (show_ctrl && ISCONTROL(u)) { + if (u & 0x80) { + u &= 0x7f; + tputc('^'); + tputc('['); + } else if (u != '\n' && u != '\r' && u != '\t') { + u ^= 0x40; + tputc('^'); + } + } + tputc(u); + } + return n; +} + +void +tresize(int col, int row) +{ + int i, j; + int minrow = MIN(row, term.row); + int mincol = MIN(col, term.col); + int *bp; + TCursor c; + + if (col < 1 || row < 1) { + fprintf(stderr, + "tresize: error resizing to %dx%d\n", col, row); + return; + } + + /* + * slide screen to keep cursor where we expect it - + * tscrollup would work here, but we can optimize to + * memmove because we're freeing the earlier lines + */ + for (i = 0; i <= term.c.y - row; i++) { + free(term.line[i]); + free(term.alt[i]); + } + /* ensure that both src and dst are not NULL */ + if (i > 0) { + memmove(term.line, term.line + i, row * sizeof(Line)); + memmove(term.alt, term.alt + i, row * sizeof(Line)); + } + for (i += row; i < term.row; i++) { + free(term.line[i]); + free(term.alt[i]); + } + + /* resize to new height */ + term.line = xrealloc(term.line, row * sizeof(Line)); + term.alt = xrealloc(term.alt, row * sizeof(Line)); + term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); + term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); + + for (i = 0; i < HISTSIZE; i++) { + term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph)); + for (j = mincol; j < col; j++) { + term.hist[i][j] = term.c.attr; + term.hist[i][j].u = ' '; + } + } + + /* resize each row to new width, zero-pad if needed */ + for (i = 0; i < minrow; i++) { + term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); + term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph)); + } + + /* allocate any new rows */ + for (/* i = minrow */; i < row; i++) { + term.line[i] = xmalloc(col * sizeof(Glyph)); + term.alt[i] = xmalloc(col * sizeof(Glyph)); + } + if (col > term.col) { + bp = term.tabs + term.col; + + memset(bp, 0, sizeof(*term.tabs) * (col - term.col)); + while (--bp > term.tabs && !*bp) + /* nothing */ ; + for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces) + *bp = 1; + } + /* update terminal size */ + term.col = col; + term.row = row; + /* reset scrolling region */ + tsetscroll(0, row-1); + /* make use of the LIMIT in tmoveto */ + tmoveto(term.c.x, term.c.y); + /* Clearing both screens (it makes dirty all lines) */ + c = term.c; + for (i = 0; i < 2; i++) { + if (mincol < col && 0 < minrow) { + tclearregion(mincol, 0, col - 1, minrow - 1); + } + if (0 < col && minrow < row) { + tclearregion(0, minrow, col - 1, row - 1); + } + tswapscreen(); + tcursor(CURSOR_LOAD); + } + term.c = c; +} + +void +resettitle(void) +{ + xsettitle(NULL); +} + +void +drawregion(int x1, int y1, int x2, int y2) +{ + int y; + + for (y = y1; y < y2; y++) { + if (!term.dirty[y]) + continue; + + term.dirty[y] = 0; + xdrawline(TLINE(y), x1, y, x2); + } +} + +void +draw(void) +{ + int cx = term.c.x, ocx = term.ocx, ocy = term.ocy; + + if (!xstartdraw()) + return; + + /* adjust cursor position */ + LIMIT(term.ocx, 0, term.col-1); + LIMIT(term.ocy, 0, term.row-1); + if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY) + term.ocx--; + if (term.line[term.c.y][cx].mode & ATTR_WDUMMY) + cx--; + + drawregion(0, 0, term.col, term.row); + if (term.scr == 0) + xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], + term.ocx, term.ocy, term.line[term.ocy][term.ocx]); + term.ocx = cx; + term.ocy = term.c.y; + xfinishdraw(); + if (ocx != term.ocx || ocy != term.ocy) + xximspot(term.ocx, term.ocy); +} + +void +redraw(void) +{ + tfulldirt(); + draw(); +} diff --git a/st/st.h b/st/st.h new file mode 100644 index 0000000..da36b34 --- /dev/null +++ b/st/st.h @@ -0,0 +1,130 @@ +/* See LICENSE for license details. */ + +#include +#include + +/* macros */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +#define LEN(a) (sizeof(a) / sizeof(a)[0]) +#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) +#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) +#define DEFAULT(a, b) (a) = (a) ? (a) : (b) +#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) +#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ + (a).bg != (b).bg) +#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ + (t1.tv_nsec-t2.tv_nsec)/1E6) +#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) + +#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) +#define IS_TRUECOL(x) (1 << 24 & (x)) + +enum glyph_attribute { + ATTR_NULL = 0, + ATTR_BOLD = 1 << 0, + ATTR_FAINT = 1 << 1, + ATTR_ITALIC = 1 << 2, + ATTR_UNDERLINE = 1 << 3, + ATTR_BLINK = 1 << 4, + ATTR_REVERSE = 1 << 5, + ATTR_INVISIBLE = 1 << 6, + ATTR_STRUCK = 1 << 7, + ATTR_WRAP = 1 << 8, + ATTR_WIDE = 1 << 9, + ATTR_WDUMMY = 1 << 10, + ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, +}; + +enum selection_mode { + SEL_IDLE = 0, + SEL_EMPTY = 1, + SEL_READY = 2 +}; + +enum selection_type { + SEL_REGULAR = 1, + SEL_RECTANGULAR = 2 +}; + +enum selection_snap { + SNAP_WORD = 1, + SNAP_LINE = 2 +}; + +typedef unsigned char uchar; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned short ushort; + +typedef uint_least32_t Rune; + +#define Glyph Glyph_ +typedef struct { + Rune u; /* character code */ + ushort mode; /* attribute flags */ + uint32_t fg; /* foreground */ + uint32_t bg; /* background */ +} Glyph; + +typedef Glyph *Line; + +typedef union { + int i; + uint ui; + float f; + const void *v; + const char *s; +} Arg; + +void die(const char *, ...); +void redraw(void); +void draw(void); + +void kscrolldown(const Arg *); +void kscrollup(const Arg *); +void printscreen(const Arg *); +void printsel(const Arg *); +void sendbreak(const Arg *); +void toggleprinter(const Arg *); + +int tattrset(int); +void tnew(int, int); +void tresize(int, int); +void tsetdirtattr(int); +void ttyhangup(void); +int ttynew(const char *, char *, const char *, char **); +size_t ttyread(void); +void ttyresize(int, int); +void ttywrite(const char *, size_t, int); + +void resettitle(void); + +void selclear(void); +void selinit(void); +void selstart(int, int, int); +void selextend(int, int, int, int); +int selected(int, int); +char *getsel(void); + +size_t utf8encode(Rune, char *); + +void *xmalloc(size_t); +void *xrealloc(void *, size_t); +char *xstrdup(const char *); + +int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b); + +/* config.h globals */ +extern char *utmp; +extern char *scroll; +extern char *stty_args; +extern char *vtiden; +extern wchar_t *worddelimiters; +extern int allowaltscreen; +extern int allowwindowops; +extern char *termname; +extern unsigned int tabspaces; +extern unsigned int defaultfg; +extern unsigned int defaultbg; +extern unsigned int defaultcs; diff --git a/st/st.info b/st/st.info new file mode 100644 index 0000000..8201ad6 --- /dev/null +++ b/st/st.info @@ -0,0 +1,239 @@ +st-mono| simpleterm monocolor, + acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, + am, + bce, + bel=^G, + blink=\E[5m, + bold=\E[1m, + cbt=\E[Z, + cvvis=\E[?25h, + civis=\E[?25l, + clear=\E[H\E[2J, + cnorm=\E[?12l\E[?25h, + colors#2, + cols#80, + cr=^M, + csr=\E[%i%p1%d;%p2%dr, + cub=\E[%p1%dD, + cub1=^H, + cud1=^J, + cud=\E[%p1%dB, + cuf1=\E[C, + cuf=\E[%p1%dC, + cup=\E[%i%p1%d;%p2%dH, + cuu1=\E[A, + cuu=\E[%p1%dA, + dch=\E[%p1%dP, + dch1=\E[P, + dim=\E[2m, + dl=\E[%p1%dM, + dl1=\E[M, + ech=\E[%p1%dX, + ed=\E[J, + el=\E[K, + el1=\E[1K, + enacs=\E)0, + flash=\E[?5h$<80/>\E[?5l, + fsl=^G, + home=\E[H, + hpa=\E[%i%p1%dG, + hs, + ht=^I, + hts=\EH, + ich=\E[%p1%d@, + il1=\E[L, + il=\E[%p1%dL, + ind=^J, + indn=\E[%p1%dS, + invis=\E[8m, + is2=\E[4l\E>\E[?1034l, + it#8, + kel=\E[1;2F, + ked=\E[1;5F, + ka1=\E[1~, + ka3=\E[5~, + kc1=\E[4~, + kc3=\E[6~, + kbs=\177, + kcbt=\E[Z, + kb2=\EOu, + kcub1=\EOD, + kcud1=\EOB, + kcuf1=\EOC, + kcuu1=\EOA, + kDC=\E[3;2~, + kent=\EOM, + kEND=\E[1;2F, + kIC=\E[2;2~, + kNXT=\E[6;2~, + kPRV=\E[5;2~, + kHOM=\E[1;2H, + kLFT=\E[1;2D, + kRIT=\E[1;2C, + kind=\E[1;2B, + kri=\E[1;2A, + kclr=\E[3;5~, + kdl1=\E[3;2~, + kdch1=\E[3~, + kich1=\E[2~, + kend=\E[4~, + kf1=\EOP, + kf2=\EOQ, + kf3=\EOR, + kf4=\EOS, + kf5=\E[15~, + kf6=\E[17~, + kf7=\E[18~, + kf8=\E[19~, + kf9=\E[20~, + kf10=\E[21~, + kf11=\E[23~, + kf12=\E[24~, + kf13=\E[1;2P, + kf14=\E[1;2Q, + kf15=\E[1;2R, + kf16=\E[1;2S, + kf17=\E[15;2~, + kf18=\E[17;2~, + kf19=\E[18;2~, + kf20=\E[19;2~, + kf21=\E[20;2~, + kf22=\E[21;2~, + kf23=\E[23;2~, + kf24=\E[24;2~, + kf25=\E[1;5P, + kf26=\E[1;5Q, + kf27=\E[1;5R, + kf28=\E[1;5S, + kf29=\E[15;5~, + kf30=\E[17;5~, + kf31=\E[18;5~, + kf32=\E[19;5~, + kf33=\E[20;5~, + kf34=\E[21;5~, + kf35=\E[23;5~, + kf36=\E[24;5~, + kf37=\E[1;6P, + kf38=\E[1;6Q, + kf39=\E[1;6R, + kf40=\E[1;6S, + kf41=\E[15;6~, + kf42=\E[17;6~, + kf43=\E[18;6~, + kf44=\E[19;6~, + kf45=\E[20;6~, + kf46=\E[21;6~, + kf47=\E[23;6~, + kf48=\E[24;6~, + kf49=\E[1;3P, + kf50=\E[1;3Q, + kf51=\E[1;3R, + kf52=\E[1;3S, + kf53=\E[15;3~, + kf54=\E[17;3~, + kf55=\E[18;3~, + kf56=\E[19;3~, + kf57=\E[20;3~, + kf58=\E[21;3~, + kf59=\E[23;3~, + kf60=\E[24;3~, + kf61=\E[1;4P, + kf62=\E[1;4Q, + kf63=\E[1;4R, + khome=\E[1~, + kil1=\E[2;5~, + krmir=\E[2;2~, + knp=\E[6~, + kmous=\E[M, + kpp=\E[5~, + lines#24, + mir, + msgr, + npc, + op=\E[39;49m, + pairs#64, + mc0=\E[i, + mc4=\E[4i, + mc5=\E[5i, + rc=\E8, + rev=\E[7m, + ri=\EM, + rin=\E[%p1%dT, + ritm=\E[23m, + rmacs=\E(B, + rmcup=\E[?1049l, + rmir=\E[4l, + rmkx=\E[?1l\E>, + rmso=\E[27m, + rmul=\E[24m, + rs1=\Ec, + rs2=\E[4l\E>\E[?1034l, + sc=\E7, + sitm=\E[3m, + sgr0=\E[0m, + smacs=\E(0, + smcup=\E[?1049h, + smir=\E[4h, + smkx=\E[?1h\E=, + smso=\E[7m, + smul=\E[4m, + tbc=\E[3g, + tsl=\E]0;, + xenl, + vpa=\E[%i%p1%dd, +# XTerm extensions + rmxx=\E[29m, + smxx=\E[9m, +# disabled rep for now: causes some issues with older ncurses versions. +# rep=%p1%c\E[%p2%{1}%-%db, +# tmux extensions, see TERMINFO EXTENSIONS in tmux(1) + Tc, + Ms=\E]52;%p1%s;%p2%s\007, + Se=\E[2 q, + Ss=\E[%p1%d q, + +st| simpleterm, + use=st-mono, + colors#8, + setab=\E[4%p1%dm, + setaf=\E[3%p1%dm, + setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, + setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, + sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, + +st-256color| simpleterm with 256 colors, + use=st, + ccc, + colors#256, + oc=\E]104\007, + pairs#32767, +# Nicked from xterm-256color + initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, + setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, + setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, + +st-meta| simpleterm with meta key, + use=st, + km, + rmm=\E[?1034l, + smm=\E[?1034h, + rs2=\E[4l\E>\E[?1034h, + is2=\E[4l\E>\E[?1034h, + +st-meta-256color| simpleterm with meta key and 256 colors, + use=st-256color, + km, + rmm=\E[?1034l, + smm=\E[?1034h, + rs2=\E[4l\E>\E[?1034h, + is2=\E[4l\E>\E[?1034h, + +st-bs| simpleterm with backspace as backspace, + use=st, + kbs=\010, + kdch1=\177, + +st-bs-256color| simpleterm with backspace as backspace and 256colors, + use=st-256color, + kbs=\010, + kdch1=\177, diff --git a/st/st.o b/st/st.o new file mode 100644 index 0000000000000000000000000000000000000000..8d5401d86bc7117846432a17e1790dc5798ffb55 GIT binary patch literal 81512 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *argv0; +#include "arg.h" +#include "st.h" +#include "win.h" + +/* types used in config.def.h */ +typedef struct { + uint mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Shortcut; + +typedef struct { + uint mod; + uint button; + void (*func)(const Arg *); + const Arg arg; + uint release; +} MouseShortcut; + +typedef struct { + KeySym k; + uint mask; + char *s; + /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ + signed char appkey; /* application keypad */ + signed char appcursor; /* application cursor */ +} Key; + +/* X modifiers */ +#define XK_ANY_MOD UINT_MAX +#define XK_NO_MOD 0 +#define XK_SWITCH_MOD (1<<13|1<<14) + +/* function definitions used in config.def.h */ +static void clipcopy(const Arg *); +static void clippaste(const Arg *); +static void numlock(const Arg *); +static void selpaste(const Arg *); +static void zoom(const Arg *); +static void zoomabs(const Arg *); +static void zoomreset(const Arg *); +static void ttysend(const Arg *); + +/* config.def.h for applying patches and the configuration. */ +#include "config.def.h" + +/* XEMBED messages */ +#define XEMBED_FOCUS_IN 4 +#define XEMBED_FOCUS_OUT 5 + +/* macros */ +#define IS_SET(flag) ((win.mode & (flag)) != 0) +#define TRUERED(x) (((x) & 0xff0000) >> 8) +#define TRUEGREEN(x) (((x) & 0xff00)) +#define TRUEBLUE(x) (((x) & 0xff) << 8) + +typedef XftDraw *Draw; +typedef XftColor Color; +typedef XftGlyphFontSpec GlyphFontSpec; + +/* Purely graphic info */ +typedef struct { + int tw, th; /* tty width and height */ + int w, h; /* window width and height */ + int hborderpx, vborderpx; + int ch; /* char height */ + int cw; /* char width */ + int mode; /* window state/mode flags */ + int cursor; /* cursor style */ +} TermWindow; + +typedef struct { + Display *dpy; + Colormap cmap; + Window win; + Drawable buf; + GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ + Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; + struct { + XIM xim; + XIC xic; + XPoint spot; + XVaNestedList spotlist; + } ime; + Draw draw; + Visual *vis; + XSetWindowAttributes attrs; + int scr; + int isfixed; /* is fixed geometry? */ + int depth; /* bit depth */ + int l, t; /* left and top offset */ + int gm; /* geometry mask */ +} XWindow; + +typedef struct { + Atom xtarget; + char *primary, *clipboard; + struct timespec tclick1; + struct timespec tclick2; +} XSelection; + +/* Font structure */ +#define Font Font_ +typedef struct { + int height; + int width; + int ascent; + int descent; + int badslant; + int badweight; + short lbearing; + short rbearing; + XftFont *match; + FcFontSet *set; + FcPattern *pattern; +} Font; + +/* Drawing Context */ +typedef struct { + Color *col; + size_t collen; + Font font, bfont, ifont, ibfont; + GC gc; +} DC; + +static inline ushort sixd_to_16bit(int); +static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); +static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); +static void xdrawglyph(Glyph, int, int); +static void xclear(int, int, int, int); +static int xgeommasktogravity(int); +static int ximopen(Display *); +static void ximinstantiate(Display *, XPointer, XPointer); +static void ximdestroy(XIM, XPointer, XPointer); +static int xicdestroy(XIC, XPointer, XPointer); +static void xinit(int, int); +static void cresize(int, int); +static void xresize(int, int); +static void xhints(void); +static int xloadcolor(int, const char *, Color *); +static int xloadfont(Font *, FcPattern *); +static void xloadfonts(const char *, double); +static void xunloadfont(Font *); +static void xunloadfonts(void); +static void xsetenv(void); +static void xseturgency(int); +static int evcol(XEvent *); +static int evrow(XEvent *); + +static void expose(XEvent *); +static void visibility(XEvent *); +static void unmap(XEvent *); +static void kpress(XEvent *); +static void cmessage(XEvent *); +static void resize(XEvent *); +static void focus(XEvent *); +static uint buttonmask(uint); +static int mouseaction(XEvent *, uint); +static void brelease(XEvent *); +static void bpress(XEvent *); +static void bmotion(XEvent *); +static void propnotify(XEvent *); +static void selnotify(XEvent *); +static void selclear_(XEvent *); +static void selrequest(XEvent *); +static void setsel(char *, Time); +static void mousesel(XEvent *, int); +static void mousereport(XEvent *); +static char *kmap(KeySym, uint); +static int match(uint, uint); + +static void run(void); +static void usage(void); + +static void (*handler[LASTEvent])(XEvent *) = { + [KeyPress] = kpress, + [ClientMessage] = cmessage, + [ConfigureNotify] = resize, + [VisibilityNotify] = visibility, + [UnmapNotify] = unmap, + [Expose] = expose, + [FocusIn] = focus, + [FocusOut] = focus, + [MotionNotify] = bmotion, + [ButtonPress] = bpress, + [ButtonRelease] = brelease, +/* + * Uncomment if you want the selection to disappear when you select something + * different in another window. + */ +/* [SelectionClear] = selclear_, */ + [SelectionNotify] = selnotify, +/* + * PropertyNotify is only turned on when there is some INCR transfer happening + * for the selection retrieval. + */ + [PropertyNotify] = propnotify, + [SelectionRequest] = selrequest, +}; + +/* Globals */ +static DC dc; +static XWindow xw; +static XSelection xsel; +static TermWindow win; + +/* Font Ring Cache */ +enum { + FRC_NORMAL, + FRC_ITALIC, + FRC_BOLD, + FRC_ITALICBOLD +}; + +typedef struct { + XftFont *font; + int flags; + Rune unicodep; +} Fontcache; + +/* Fontcache is an array now. A new font will be appended to the array. */ +static Fontcache *frc = NULL; +static int frclen = 0; +static int frccap = 0; +static char *usedfont = NULL; +static double usedfontsize = 0; +static double defaultfontsize = 0; + +static char *opt_alpha = NULL; +static char *opt_class = NULL; +static char **opt_cmd = NULL; +static char *opt_embed = NULL; +static char *opt_font = NULL; +static char *opt_io = NULL; +static char *opt_line = NULL; +static char *opt_name = NULL; +static char *opt_title = NULL; + +static uint buttons; /* bit field of pressed buttons */ + +void +clipcopy(const Arg *dummy) +{ + Atom clipboard; + + free(xsel.clipboard); + xsel.clipboard = NULL; + + if (xsel.primary != NULL) { + xsel.clipboard = xstrdup(xsel.primary); + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); + } +} + +void +clippaste(const Arg *dummy) +{ + Atom clipboard; + + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, + xw.win, CurrentTime); +} + +void +selpaste(const Arg *dummy) +{ + XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, + xw.win, CurrentTime); +} + +void +numlock(const Arg *dummy) +{ + win.mode ^= MODE_NUMLOCK; +} + +void +zoom(const Arg *arg) +{ + Arg larg; + + larg.f = usedfontsize + arg->f; + zoomabs(&larg); +} + +void +zoomabs(const Arg *arg) +{ + xunloadfonts(); + xloadfonts(usedfont, arg->f); + cresize(0, 0); + redraw(); + xhints(); +} + +void +zoomreset(const Arg *arg) +{ + Arg larg; + + if (defaultfontsize > 0) { + larg.f = defaultfontsize; + zoomabs(&larg); + } +} + +void +ttysend(const Arg *arg) +{ + ttywrite(arg->s, strlen(arg->s), 1); +} + +int +evcol(XEvent *e) +{ + int x = e->xbutton.x - win.hborderpx; + LIMIT(x, 0, win.tw - 1); + return x / win.cw; +} + +int +evrow(XEvent *e) +{ + int y = e->xbutton.y - win.vborderpx; + LIMIT(y, 0, win.th - 1); + return y / win.ch; +} + +void +mousesel(XEvent *e, int done) +{ + int type, seltype = SEL_REGULAR; + uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); + + for (type = 1; type < LEN(selmasks); ++type) { + if (match(selmasks[type], state)) { + seltype = type; + break; + } + } + selextend(evcol(e), evrow(e), seltype, done); + if (done) + setsel(getsel(), e->xbutton.time); +} + +void +mousereport(XEvent *e) +{ + int len, btn, code; + int x = evcol(e), y = evrow(e); + int state = e->xbutton.state; + char buf[40]; + static int ox, oy; + + if (e->type == MotionNotify) { + if (x == ox && y == oy) + return; + if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) + return; + /* MODE_MOUSEMOTION: no reporting if no button is pressed */ + if (IS_SET(MODE_MOUSEMOTION) && buttons == 0) + return; + /* Set btn to lowest-numbered pressed button, or 12 if no + * buttons are pressed. */ + for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++) + ; + code = 32; + } else { + btn = e->xbutton.button; + /* Only buttons 1 through 11 can be encoded */ + if (btn < 1 || btn > 11) + return; + if (e->type == ButtonRelease) { + /* MODE_MOUSEX10: no button release reporting */ + if (IS_SET(MODE_MOUSEX10)) + return; + /* Don't send release events for the scroll wheel */ + if (btn == 4 || btn == 5) + return; + } + code = 0; + } + + ox = x; + oy = y; + + /* Encode btn into code. If no button is pressed for a motion event in + * MODE_MOUSEMANY, then encode it as a release. */ + if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12) + code += 3; + else if (btn >= 8) + code += 128 + btn - 8; + else if (btn >= 4) + code += 64 + btn - 4; + else + code += btn - 1; + + if (!IS_SET(MODE_MOUSEX10)) { + code += ((state & ShiftMask ) ? 4 : 0) + + ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */ + + ((state & ControlMask) ? 16 : 0); + } + + if (IS_SET(MODE_MOUSESGR)) { + len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", + code, x+1, y+1, + e->type == ButtonRelease ? 'm' : 'M'); + } else if (x < 223 && y < 223) { + len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", + 32+code, 32+x+1, 32+y+1); + } else { + return; + } + + ttywrite(buf, len, 0); +} + +uint +buttonmask(uint button) +{ + return button == Button1 ? Button1Mask + : button == Button2 ? Button2Mask + : button == Button3 ? Button3Mask + : button == Button4 ? Button4Mask + : button == Button5 ? Button5Mask + : 0; +} + +int +mouseaction(XEvent *e, uint release) +{ + MouseShortcut *ms; + + /* ignore Buttonmask for Button - it's set on release */ + uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); + + for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { + if (ms->release == release && + ms->button == e->xbutton.button && + (match(ms->mod, state) || /* exact or forced */ + match(ms->mod, state & ~forcemousemod))) { + ms->func(&(ms->arg)); + return 1; + } + } + + return 0; +} + +void +bpress(XEvent *e) +{ + int btn = e->xbutton.button; + struct timespec now; + int snap; + + if (1 <= btn && btn <= 11) + buttons |= 1 << (btn-1); + + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + if (mouseaction(e, 0)) + return; + + if (btn == Button1) { + /* + * If the user clicks below predefined timeouts specific + * snapping behaviour is exposed. + */ + clock_gettime(CLOCK_MONOTONIC, &now); + if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { + snap = SNAP_LINE; + } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { + snap = SNAP_WORD; + } else { + snap = 0; + } + xsel.tclick2 = xsel.tclick1; + xsel.tclick1 = now; + + selstart(evcol(e), evrow(e), snap); + } +} + +void +propnotify(XEvent *e) +{ + XPropertyEvent *xpev; + Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + + xpev = &e->xproperty; + if (xpev->state == PropertyNewValue && + (xpev->atom == XA_PRIMARY || + xpev->atom == clipboard)) { + selnotify(e); + } +} + +void +selnotify(XEvent *e) +{ + ulong nitems, ofs, rem; + int format; + uchar *data, *last, *repl; + Atom type, incratom, property = None; + + incratom = XInternAtom(xw.dpy, "INCR", 0); + + ofs = 0; + if (e->type == SelectionNotify) + property = e->xselection.property; + else if (e->type == PropertyNotify) + property = e->xproperty.atom; + + if (property == None) + return; + + do { + if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, + BUFSIZ/4, False, AnyPropertyType, + &type, &format, &nitems, &rem, + &data)) { + fprintf(stderr, "Clipboard allocation failed\n"); + return; + } + + if (e->type == PropertyNotify && nitems == 0 && rem == 0) { + /* + * If there is some PropertyNotify with no data, then + * this is the signal of the selection owner that all + * data has been transferred. We won't need to receive + * PropertyNotify events anymore. + */ + MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, + &xw.attrs); + } + + if (type == incratom) { + /* + * Activate the PropertyNotify events so we receive + * when the selection owner does send us the next + * chunk of data. + */ + MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, + &xw.attrs); + + /* + * Deleting the property is the transfer start signal. + */ + XDeleteProperty(xw.dpy, xw.win, (int)property); + continue; + } + + /* + * As seen in getsel: + * Line endings are inconsistent in the terminal and GUI world + * copy and pasting. When receiving some selection data, + * replace all '\n' with '\r'. + * FIXME: Fix the computer world. + */ + repl = data; + last = data + nitems * format / 8; + while ((repl = memchr(repl, '\n', last - repl))) { + *repl++ = '\r'; + } + + if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) + ttywrite("\033[200~", 6, 0); + ttywrite((char *)data, nitems * format / 8, 1); + if (IS_SET(MODE_BRCKTPASTE) && rem == 0) + ttywrite("\033[201~", 6, 0); + XFree(data); + /* number of 32-bit chunks returned */ + ofs += nitems * format / 32; + } while (rem > 0); + + /* + * Deleting the property again tells the selection owner to send the + * next data chunk in the property. + */ + XDeleteProperty(xw.dpy, xw.win, (int)property); +} + +void +xclipcopy(void) +{ + clipcopy(NULL); +} + +void +selclear_(XEvent *e) +{ + selclear(); +} + +void +selrequest(XEvent *e) +{ + XSelectionRequestEvent *xsre; + XSelectionEvent xev; + Atom xa_targets, string, clipboard; + char *seltext; + + xsre = (XSelectionRequestEvent *) e; + xev.type = SelectionNotify; + xev.requestor = xsre->requestor; + xev.selection = xsre->selection; + xev.target = xsre->target; + xev.time = xsre->time; + if (xsre->property == None) + xsre->property = xsre->target; + + /* reject */ + xev.property = None; + + xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); + if (xsre->target == xa_targets) { + /* respond with the supported type */ + string = xsel.xtarget; + XChangeProperty(xsre->display, xsre->requestor, xsre->property, + XA_ATOM, 32, PropModeReplace, + (uchar *) &string, 1); + xev.property = xsre->property; + } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { + /* + * xith XA_STRING non ascii characters may be incorrect in the + * requestor. It is not our problem, use utf8. + */ + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + if (xsre->selection == XA_PRIMARY) { + seltext = xsel.primary; + } else if (xsre->selection == clipboard) { + seltext = xsel.clipboard; + } else { + fprintf(stderr, + "Unhandled clipboard selection 0x%lx\n", + xsre->selection); + return; + } + if (seltext != NULL) { + XChangeProperty(xsre->display, xsre->requestor, + xsre->property, xsre->target, + 8, PropModeReplace, + (uchar *)seltext, strlen(seltext)); + xev.property = xsre->property; + } + } + + /* all done, send a notification to the listener */ + if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) + fprintf(stderr, "Error sending SelectionNotify event\n"); +} + +void +setsel(char *str, Time t) +{ + if (!str) + return; + + free(xsel.primary); + xsel.primary = str; + + XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); + if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) + selclear(); +} + +void +xsetsel(char *str) +{ + setsel(str, CurrentTime); +} + +void +brelease(XEvent *e) +{ + int btn = e->xbutton.button; + + if (1 <= btn && btn <= 11) + buttons &= ~(1 << (btn-1)); + + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + if (mouseaction(e, 1)) + return; + if (btn == Button1) + mousesel(e, 1); +} + +void +bmotion(XEvent *e) +{ + if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { + mousereport(e); + return; + } + + mousesel(e, 0); +} + +void +cresize(int width, int height) +{ + int col, row; + + if (width != 0) + win.w = width; + if (height != 0) + win.h = height; + + col = (win.w - 2 * borderpx) / win.cw; + row = (win.h - 2 * borderpx) / win.ch; + col = MAX(1, col); + row = MAX(1, row); + + win.hborderpx = (win.w - col * win.cw) / 2; + win.vborderpx = (win.h - row * win.ch) / 2; + + tresize(col, row); + xresize(col, row); + ttyresize(win.tw, win.th); +} + +void +xresize(int col, int row) +{ + win.tw = col * win.cw; + win.th = row * win.ch; + + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, + xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + + /* resize to new width */ + xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); +} + +ushort +sixd_to_16bit(int x) +{ + return x == 0 ? 0 : 0x3737 + 0x2828 * x; +} + +int +xloadcolor(int i, const char *name, Color *ncolor) +{ + XRenderColor color = { .alpha = 0xffff }; + + if (!name) { + if (BETWEEN(i, 16, 255)) { /* 256 color */ + if (i < 6*6*6+16) { /* same colors as xterm */ + color.red = sixd_to_16bit( ((i-16)/36)%6 ); + color.green = sixd_to_16bit( ((i-16)/6) %6 ); + color.blue = sixd_to_16bit( ((i-16)/1) %6 ); + } else { /* greyscale */ + color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16)); + color.green = color.blue = color.red; + } + return XftColorAllocValue(xw.dpy, xw.vis, + xw.cmap, &color, ncolor); + } else + name = colorname[i]; + } + + return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); +} + +void +xloadcols(void) +{ + int i; + static int loaded; + Color *cp; + + if (loaded) { + for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) + XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); + } else { + dc.collen = MAX(LEN(colorname), 256); + dc.col = xmalloc(dc.collen * sizeof(Color)); + } + + for (i = 0; i < dc.collen; i++) + if (!xloadcolor(i, NULL, &dc.col[i])) { + if (colorname[i]) + die("could not allocate color '%s'\n", colorname[i]); + else + die("could not allocate color %d\n", i); + } + + /* set alpha value of bg color */ + if (opt_alpha) + alpha = strtof(opt_alpha, NULL); + dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); + dc.col[defaultbg].pixel &= 0x00FFFFFF; + dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; + loaded = 1; +} + +int +xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) +{ + if (!BETWEEN(x, 0, dc.collen)) + return 1; + + *r = dc.col[x].color.red >> 8; + *g = dc.col[x].color.green >> 8; + *b = dc.col[x].color.blue >> 8; + + return 0; +} + +int +xsetcolorname(int x, const char *name) +{ + Color ncolor; + + if (!BETWEEN(x, 0, dc.collen)) + return 1; + + if (!xloadcolor(x, name, &ncolor)) + return 1; + + XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); + dc.col[x] = ncolor; + + return 0; +} + +/* + * Absolute coordinates. + */ +void +xclear(int x1, int y1, int x2, int y2) +{ + XftDrawRect(xw.draw, + &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], + x1, y1, x2-x1, y2-y1); +} + +void +xhints(void) +{ + XClassHint class = {opt_name ? opt_name : termname, + opt_class ? opt_class : termname}; + XWMHints wm = {.flags = InputHint, .input = 1}; + XSizeHints *sizeh; + + sizeh = XAllocSizeHints(); + + sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; + sizeh->height = win.h; + sizeh->width = win.w; + sizeh->height_inc = 1; + sizeh->width_inc = 1; + sizeh->base_height = 2 * borderpx; + sizeh->base_width = 2 * borderpx; + sizeh->min_height = win.ch + 2 * borderpx; + sizeh->min_width = win.cw + 2 * borderpx; + if (xw.isfixed) { + sizeh->flags |= PMaxSize; + sizeh->min_width = sizeh->max_width = win.w; + sizeh->min_height = sizeh->max_height = win.h; + } + if (xw.gm & (XValue|YValue)) { + sizeh->flags |= USPosition | PWinGravity; + sizeh->x = xw.l; + sizeh->y = xw.t; + sizeh->win_gravity = xgeommasktogravity(xw.gm); + } + + XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, + &class); + XFree(sizeh); +} + +int +xgeommasktogravity(int mask) +{ + switch (mask & (XNegative|YNegative)) { + case 0: + return NorthWestGravity; + case XNegative: + return NorthEastGravity; + case YNegative: + return SouthWestGravity; + } + + return SouthEastGravity; +} + +int +xloadfont(Font *f, FcPattern *pattern) +{ + FcPattern *configured; + FcPattern *match; + FcResult result; + XGlyphInfo extents; + int wantattr, haveattr; + + /* + * Manually configure instead of calling XftMatchFont + * so that we can use the configured pattern for + * "missing glyph" lookups. + */ + configured = FcPatternDuplicate(pattern); + if (!configured) + return 1; + + FcConfigSubstitute(NULL, configured, FcMatchPattern); + XftDefaultSubstitute(xw.dpy, xw.scr, configured); + + match = FcFontMatch(NULL, configured, &result); + if (!match) { + FcPatternDestroy(configured); + return 1; + } + + if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { + FcPatternDestroy(configured); + FcPatternDestroy(match); + return 1; + } + + if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == + XftResultMatch)) { + /* + * Check if xft was unable to find a font with the appropriate + * slant but gave us one anyway. Try to mitigate. + */ + if ((XftPatternGetInteger(f->match->pattern, "slant", 0, + &haveattr) != XftResultMatch) || haveattr < wantattr) { + f->badslant = 1; + fputs("font slant does not match\n", stderr); + } + } + + if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == + XftResultMatch)) { + if ((XftPatternGetInteger(f->match->pattern, "weight", 0, + &haveattr) != XftResultMatch) || haveattr != wantattr) { + f->badweight = 1; + fputs("font weight does not match\n", stderr); + } + } + + XftTextExtentsUtf8(xw.dpy, f->match, + (const FcChar8 *) ascii_printable, + strlen(ascii_printable), &extents); + + f->set = NULL; + f->pattern = configured; + + f->ascent = f->match->ascent; + f->descent = f->match->descent; + f->lbearing = 0; + f->rbearing = f->match->max_advance_width; + + f->height = f->ascent + f->descent; + f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); + + return 0; +} + +void +xloadfonts(const char *fontstr, double fontsize) +{ + FcPattern *pattern; + double fontval; + + if (fontstr[0] == '-') + pattern = XftXlfdParse(fontstr, False, False); + else + pattern = FcNameParse((const FcChar8 *)fontstr); + + if (!pattern) + die("can't open font %s\n", fontstr); + + if (fontsize > 1) { + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternDel(pattern, FC_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); + usedfontsize = fontsize; + } else { + if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == + FcResultMatch) { + usedfontsize = fontval; + } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == + FcResultMatch) { + usedfontsize = -1; + } else { + /* + * Default font size is 12, if none given. This is to + * have a known usedfontsize value. + */ + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); + usedfontsize = 12; + } + defaultfontsize = usedfontsize; + } + + if (xloadfont(&dc.font, pattern)) + die("can't open font %s\n", fontstr); + + if (usedfontsize < 0) { + FcPatternGetDouble(dc.font.match->pattern, + FC_PIXEL_SIZE, 0, &fontval); + usedfontsize = fontval; + if (fontsize == 0) + defaultfontsize = fontval; + } + + /* Setting character width and height. */ + win.cw = ceilf(dc.font.width * cwscale); + win.ch = ceilf(dc.font.height * chscale); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + if (xloadfont(&dc.ifont, pattern)) + die("can't open font %s\n", fontstr); + + FcPatternDel(pattern, FC_WEIGHT); + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if (xloadfont(&dc.ibfont, pattern)) + die("can't open font %s\n", fontstr); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); + if (xloadfont(&dc.bfont, pattern)) + die("can't open font %s\n", fontstr); + + FcPatternDestroy(pattern); +} + +void +xunloadfont(Font *f) +{ + XftFontClose(xw.dpy, f->match); + FcPatternDestroy(f->pattern); + if (f->set) + FcFontSetDestroy(f->set); +} + +void +xunloadfonts(void) +{ + /* Free the loaded fonts in the font cache. */ + while (frclen > 0) + XftFontClose(xw.dpy, frc[--frclen].font); + + xunloadfont(&dc.font); + xunloadfont(&dc.bfont); + xunloadfont(&dc.ifont); + xunloadfont(&dc.ibfont); +} + +int +ximopen(Display *dpy) +{ + XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy }; + XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy }; + + xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); + if (xw.ime.xim == NULL) + return 0; + + if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL)) + fprintf(stderr, "XSetIMValues: " + "Could not set XNDestroyCallback.\n"); + + xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, + NULL); + + if (xw.ime.xic == NULL) { + xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle, + XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, xw.win, + XNDestroyCallback, &icdestroy, + NULL); + } + if (xw.ime.xic == NULL) + fprintf(stderr, "XCreateIC: Could not create input context.\n"); + + return 1; +} + +void +ximinstantiate(Display *dpy, XPointer client, XPointer call) +{ + if (ximopen(dpy)) + XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); +} + +void +ximdestroy(XIM xim, XPointer client, XPointer call) +{ + xw.ime.xim = NULL; + XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); + XFree(xw.ime.spotlist); +} + +int +xicdestroy(XIC xim, XPointer client, XPointer call) +{ + xw.ime.xic = NULL; + return 1; +} + +void +xinit(int cols, int rows) +{ + XGCValues gcvalues; + Cursor cursor; + Window parent; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; + XWindowAttributes attr; + XVisualInfo vis; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); + + if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { + parent = XRootWindow(xw.dpy, xw.scr); + xw.depth = 32; + } else { + XGetWindowAttributes(xw.dpy, parent, &attr); + xw.depth = attr.depth; + } + + XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); + xw.vis = vis.visual; + + /* font */ + if (!FcInit()) + die("could not init fontconfig.\n"); + + usedfont = (opt_font == NULL)? font : opt_font; + xloadfonts(usedfont, 0); + + /* colors */ + xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ + win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; + win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; + if (xw.gm & XNegative) + xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; + if (xw.gm & YNegative) + xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2; + + /* Events */ + xw.attrs.background_pixel = dc.col[defaultbg].pixel; + xw.attrs.border_pixel = dc.col[defaultbg].pixel; + xw.attrs.bit_gravity = NorthWestGravity; + xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask + | ExposureMask | VisibilityChangeMask | StructureNotifyMask + | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; + xw.attrs.colormap = xw.cmap; + + xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, + win.w, win.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + + memset(&gcvalues, 0, sizeof(gcvalues)); + gcvalues.graphics_exposures = False; + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); + dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); + + /* font spec buffer */ + xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); + + /* Xft rendering context */ + xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); + + /* input methods */ + if (!ximopen(xw.dpy)) { + XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, + ximinstantiate, NULL); + } + + /* white cursor, black outline */ + cursor = XCreateFontCursor(xw.dpy, mouseshape); + XDefineCursor(xw.dpy, xw.win, cursor); + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { + xmousefg.red = 0xffff; + xmousefg.green = 0xffff; + xmousefg.blue = 0xffff; + } + + if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { + xmousebg.red = 0x0000; + xmousebg.green = 0x0000; + xmousebg.blue = 0x0000; + } + + XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); + + xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); + xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); + xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); + xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); + XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); + + xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); + XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, + PropModeReplace, (uchar *)&thispid, 1); + + win.mode = MODE_NUMLOCK; + resettitle(); + xhints(); + XMapWindow(xw.dpy, xw.win); + XSync(xw.dpy, False); + + clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); + clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); + xsel.primary = NULL; + xsel.clipboard = NULL; + xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); + if (xsel.xtarget == None) + xsel.xtarget = XA_STRING; +} + +int +xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) +{ + float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; + ushort mode, prevmode = USHRT_MAX; + Font *font = &dc.font; + int frcflags = FRC_NORMAL; + float runewidth = win.cw; + Rune rune; + FT_UInt glyphidx; + FcResult fcres; + FcPattern *fcpattern, *fontpattern; + FcFontSet *fcsets[] = { NULL }; + FcCharSet *fccharset; + int i, f, numspecs = 0; + + for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { + /* Fetch rune and mode for current glyph. */ + rune = glyphs[i].u; + mode = glyphs[i].mode; + + /* Skip dummy wide-character spacing. */ + if (mode == ATTR_WDUMMY) + continue; + + /* Determine font for glyph if different from previous glyph. */ + if (prevmode != mode) { + prevmode = mode; + font = &dc.font; + frcflags = FRC_NORMAL; + runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); + if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { + font = &dc.ibfont; + frcflags = FRC_ITALICBOLD; + } else if (mode & ATTR_ITALIC) { + font = &dc.ifont; + frcflags = FRC_ITALIC; + } else if (mode & ATTR_BOLD) { + font = &dc.bfont; + frcflags = FRC_BOLD; + } + yp = winy + font->ascent; + } + + /* Lookup character index with default font. */ + glyphidx = XftCharIndex(xw.dpy, font->match, rune); + if (glyphidx) { + specs[numspecs].font = font->match; + specs[numspecs].glyph = glyphidx; + specs[numspecs].x = (short)xp; + specs[numspecs].y = (short)yp; + xp += runewidth; + numspecs++; + continue; + } + + /* Fallback on font cache, search the font cache for match. */ + for (f = 0; f < frclen; f++) { + glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); + /* Everything correct. */ + if (glyphidx && frc[f].flags == frcflags) + break; + /* We got a default font for a not found glyph. */ + if (!glyphidx && frc[f].flags == frcflags + && frc[f].unicodep == rune) { + break; + } + } + + /* Nothing was found. Use fontconfig to find matching font. */ + if (f >= frclen) { + if (!font->set) + font->set = FcFontSort(0, font->pattern, + 1, 0, &fcres); + fcsets[0] = font->set; + + /* + * Nothing was found in the cache. Now use + * some dozen of Fontconfig calls to get the + * font for one single character. + * + * Xft and fontconfig are design failures. + */ + fcpattern = FcPatternDuplicate(font->pattern); + fccharset = FcCharSetCreate(); + + FcCharSetAddChar(fccharset, rune); + FcPatternAddCharSet(fcpattern, FC_CHARSET, + fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, 1); + + FcConfigSubstitute(0, fcpattern, + FcMatchPattern); + FcDefaultSubstitute(fcpattern); + + fontpattern = FcFontSetMatch(0, fcsets, 1, + fcpattern, &fcres); + + /* Allocate memory for the new cache entry. */ + if (frclen >= frccap) { + frccap += 16; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); + } + + frc[frclen].font = XftFontOpenPattern(xw.dpy, + fontpattern); + if (!frc[frclen].font) + die("XftFontOpenPattern failed seeking fallback font: %s\n", + strerror(errno)); + frc[frclen].flags = frcflags; + frc[frclen].unicodep = rune; + + glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); + + f = frclen; + frclen++; + + FcPatternDestroy(fcpattern); + FcCharSetDestroy(fccharset); + } + + specs[numspecs].font = frc[f].font; + specs[numspecs].glyph = glyphidx; + specs[numspecs].x = (short)xp; + specs[numspecs].y = (short)yp; + xp += runewidth; + numspecs++; + } + + return numspecs; +} + +void +xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) +{ + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; + XRenderColor colfg, colbg; + XRectangle r; + + /* Fallback on color display for attributes not supported by the font */ + if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) { + if (dc.ibfont.badslant || dc.ibfont.badweight) + base.fg = defaultattr; + } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) || + (base.mode & ATTR_BOLD && dc.bfont.badweight)) { + base.fg = defaultattr; + } + + if (IS_TRUECOL(base.fg)) { + colfg.alpha = 0xffff; + colfg.red = TRUERED(base.fg); + colfg.green = TRUEGREEN(base.fg); + colfg.blue = TRUEBLUE(base.fg); + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); + fg = &truefg; + } else { + fg = &dc.col[base.fg]; + } + + if (IS_TRUECOL(base.bg)) { + colbg.alpha = 0xffff; + colbg.green = TRUEGREEN(base.bg); + colbg.red = TRUERED(base.bg); + colbg.blue = TRUEBLUE(base.bg); + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); + bg = &truebg; + } else { + bg = &dc.col[base.bg]; + } + + /* Change basic system colors [0-7] to bright system colors [8-15] */ + if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) + fg = &dc.col[base.fg + 8]; + + if (IS_SET(MODE_REVERSE)) { + if (fg == &dc.col[defaultfg]) { + fg = &dc.col[defaultbg]; + } else { + colfg.red = ~fg->color.red; + colfg.green = ~fg->color.green; + colfg.blue = ~fg->color.blue; + colfg.alpha = fg->color.alpha; + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, + &revfg); + fg = &revfg; + } + + if (bg == &dc.col[defaultbg]) { + bg = &dc.col[defaultfg]; + } else { + colbg.red = ~bg->color.red; + colbg.green = ~bg->color.green; + colbg.blue = ~bg->color.blue; + colbg.alpha = bg->color.alpha; + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, + &revbg); + bg = &revbg; + } + } + + if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { + colfg.red = fg->color.red / 2; + colfg.green = fg->color.green / 2; + colfg.blue = fg->color.blue / 2; + colfg.alpha = fg->color.alpha; + XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); + fg = &revfg; + } + + if (base.mode & ATTR_REVERSE) { + temp = fg; + fg = bg; + bg = temp; + } + + if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) + fg = bg; + + if (base.mode & ATTR_INVISIBLE) + fg = bg; + + /* Intelligent cleaning up of the borders. */ + if (x == 0) { + xclear(0, (y == 0)? 0 : winy, win.vborderpx, + winy + win.ch + + ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); + } + if (winx + width >= win.hborderpx + win.tw) { + xclear(winx + width, (y == 0)? 0 : winy, win.w, + ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); + } + if (y == 0) + xclear(winx, 0, winx + width, win.vborderpx); + if (winy + win.ch >= win.vborderpx + win.th) + xclear(winx, winy + win.ch, winx + width, win.h); + + /* Clean up the region we want to draw to. */ + XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); + + /* Set the clip region because Xft is sometimes dirty. */ + r.x = 0; + r.y = 0; + r.height = win.ch; + r.width = width; + XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); + + /* Render the glyphs. */ + XftDrawGlyphFontSpec(xw.draw, fg, specs, len); + + /* Render underline and strikethrough. */ + if (base.mode & ATTR_UNDERLINE) { + XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1, + width, 1); + } + + if (base.mode & ATTR_STRUCK) { + XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, + width, 1); + } + + /* Reset clip to none. */ + XftDrawSetClip(xw.draw, 0); +} + +void +xdrawglyph(Glyph g, int x, int y) +{ + int numspecs; + XftGlyphFontSpec spec; + + numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); + xdrawglyphfontspecs(&spec, g, numspecs, x, y); +} + +void +xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) +{ + Color drawcol; + + /* remove the old cursor */ + if (selected(ox, oy)) + og.mode ^= ATTR_REVERSE; + xdrawglyph(og, ox, oy); + + if (IS_SET(MODE_HIDE)) + return; + + /* + * Select the right color for the right mode. + */ + g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; + + if (IS_SET(MODE_REVERSE)) { + g.mode |= ATTR_REVERSE; + g.bg = defaultfg; + if (selected(cx, cy)) { + drawcol = dc.col[defaultcs]; + g.fg = defaultrcs; + } else { + drawcol = dc.col[defaultrcs]; + g.fg = defaultcs; + } + } else { + if (selected(cx, cy)) { + g.fg = defaultfg; + g.bg = defaultrcs; + } else { + g.fg = defaultbg; + g.bg = defaultcs; + } + drawcol = dc.col[g.bg]; + } + + /* draw the new one */ + if (IS_SET(MODE_FOCUSED)) { + switch (win.cursor) { + case 7: /* st extension */ + g.u = 0x2603; /* snowman (U+2603) */ + /* FALLTHROUGH */ + case 0: /* Blinking Block */ + case 1: /* Blinking Block (Default) */ + case 2: /* Steady Block */ + xdrawglyph(g, cx, cy); + break; + case 3: /* Blinking Underline */ + case 4: /* Steady Underline */ + XftDrawRect(xw.draw, &drawcol, + win.hborderpx + cx * win.cw, + win.vborderpx + (cy + 1) * win.ch - \ + cursorthickness, + win.cw, cursorthickness); + break; + case 5: /* Blinking bar */ + case 6: /* Steady bar */ + XftDrawRect(xw.draw, &drawcol, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, + cursorthickness, win.ch); + break; + } + } else { + XftDrawRect(xw.draw, &drawcol, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, + win.cw - 1, 1); + XftDrawRect(xw.draw, &drawcol, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, + win.hborderpx + (cx + 1) * win.cw - 1, + win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, + win.hborderpx + cx * win.cw, + win.vborderpx + (cy + 1) * win.ch - 1, + win.cw, 1); + } +} + +void +xsetenv(void) +{ + char buf[sizeof(long) * 8 + 1]; + + snprintf(buf, sizeof(buf), "%lu", xw.win); + setenv("WINDOWID", buf, 1); +} + +void +xseticontitle(char *p) +{ + XTextProperty prop; + DEFAULT(p, opt_title); + + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) + return; + XSetWMIconName(xw.dpy, xw.win, &prop); + XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); + XFree(prop.value); +} + +void +xsettitle(char *p) +{ + XTextProperty prop; + DEFAULT(p, opt_title); + + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) + return; + XSetWMName(xw.dpy, xw.win, &prop); + XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); + XFree(prop.value); +} + +int +xstartdraw(void) +{ + return IS_SET(MODE_VISIBLE); +} + +void +xdrawline(Line line, int x1, int y1, int x2) +{ + int i, x, ox, numspecs; + Glyph base, new; + XftGlyphFontSpec *specs = xw.specbuf; + + numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); + i = ox = 0; + for (x = x1; x < x2 && i < numspecs; x++) { + new = line[x]; + if (new.mode == ATTR_WDUMMY) + continue; + if (selected(x, y1)) + new.mode ^= ATTR_REVERSE; + if (i > 0 && ATTRCMP(base, new)) { + xdrawglyphfontspecs(specs, base, i, ox, y1); + specs += i; + numspecs -= i; + i = 0; + } + if (i == 0) { + ox = x; + base = new; + } + i++; + } + if (i > 0) + xdrawglyphfontspecs(specs, base, i, ox, y1); +} + +void +xfinishdraw(void) +{ + XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, + win.h, 0, 0); + XSetForeground(xw.dpy, dc.gc, + dc.col[IS_SET(MODE_REVERSE)? + defaultfg : defaultbg].pixel); +} + +void +xximspot(int x, int y) +{ + if (xw.ime.xic == NULL) + return; + + xw.ime.spot.x = borderpx + x * win.cw; + xw.ime.spot.y = borderpx + (y + 1) * win.ch; + + XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); +} + +void +expose(XEvent *ev) +{ + redraw(); +} + +void +visibility(XEvent *ev) +{ + XVisibilityEvent *e = &ev->xvisibility; + + MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); +} + +void +unmap(XEvent *ev) +{ + win.mode &= ~MODE_VISIBLE; +} + +void +xsetpointermotion(int set) +{ + MODBIT(xw.attrs.event_mask, set, PointerMotionMask); + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); +} + +void +xsetmode(int set, unsigned int flags) +{ + int mode = win.mode; + MODBIT(win.mode, set, flags); + if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) + redraw(); +} + +int +xsetcursor(int cursor) +{ + if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ + return 1; + win.cursor = cursor; + return 0; +} + +void +xseturgency(int add) +{ + XWMHints *h = XGetWMHints(xw.dpy, xw.win); + + MODBIT(h->flags, add, XUrgencyHint); + XSetWMHints(xw.dpy, xw.win, h); + XFree(h); +} + +void +xbell(void) +{ + if (!(IS_SET(MODE_FOCUSED))) + xseturgency(1); + if (bellvolume) + XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); +} + +void +focus(XEvent *ev) +{ + XFocusChangeEvent *e = &ev->xfocus; + + if (e->mode == NotifyGrab) + return; + + if (ev->type == FocusIn) { + if (xw.ime.xic) + XSetICFocus(xw.ime.xic); + win.mode |= MODE_FOCUSED; + xseturgency(0); + if (IS_SET(MODE_FOCUS)) + ttywrite("\033[I", 3, 0); + } else { + if (xw.ime.xic) + XUnsetICFocus(xw.ime.xic); + win.mode &= ~MODE_FOCUSED; + if (IS_SET(MODE_FOCUS)) + ttywrite("\033[O", 3, 0); + } +} + +int +match(uint mask, uint state) +{ + return mask == XK_ANY_MOD || mask == (state & ~ignoremod); +} + +char* +kmap(KeySym k, uint state) +{ + Key *kp; + int i; + + /* Check for mapped keys out of X11 function keys. */ + for (i = 0; i < LEN(mappedkeys); i++) { + if (mappedkeys[i] == k) + break; + } + if (i == LEN(mappedkeys)) { + if ((k & 0xFFFF) < 0xFD00) + return NULL; + } + + for (kp = key; kp < key + LEN(key); kp++) { + if (kp->k != k) + continue; + + if (!match(kp->mask, state)) + continue; + + if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) + continue; + if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) + continue; + + if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) + continue; + + return kp->s; + } + + return NULL; +} + +void +kpress(XEvent *ev) +{ + XKeyEvent *e = &ev->xkey; + KeySym ksym; + char buf[64], *customkey; + int len; + Rune c; + Status status; + Shortcut *bp; + + if (IS_SET(MODE_KBDLOCK)) + return; + + if (xw.ime.xic) + len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); + else + len = XLookupString(e, buf, sizeof buf, &ksym, NULL); + /* 1. shortcuts */ + for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { + if (ksym == bp->keysym && match(bp->mod, e->state)) { + bp->func(&(bp->arg)); + return; + } + } + + /* 2. custom keys from config.def.h */ + if ((customkey = kmap(ksym, e->state))) { + ttywrite(customkey, strlen(customkey), 1); + return; + } + + /* 3. composed string from input method */ + if (len == 0) + return; + if (len == 1 && e->state & Mod1Mask) { + if (IS_SET(MODE_8BIT)) { + if (*buf < 0177) { + c = *buf | 0x80; + len = utf8encode(c, buf); + } + } else { + buf[1] = buf[0]; + buf[0] = '\033'; + len = 2; + } + } + ttywrite(buf, len, 1); +} + +void +cmessage(XEvent *e) +{ + /* + * See xembed specs + * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html + */ + if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { + if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { + win.mode |= MODE_FOCUSED; + xseturgency(0); + } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { + win.mode &= ~MODE_FOCUSED; + } + } else if (e->xclient.data.l[0] == xw.wmdeletewin) { + ttyhangup(); + exit(0); + } +} + +void +resize(XEvent *e) +{ + if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) + return; + + cresize(e->xconfigure.width, e->xconfigure.height); +} + +void +run(void) +{ + XEvent ev; + int w = win.w, h = win.h; + fd_set rfd; + int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; + struct timespec seltv, *tv, now, lastblink, trigger; + double timeout; + + /* Waiting for window mapping */ + do { + XNextEvent(xw.dpy, &ev); + /* + * This XFilterEvent call is required because of XOpenIM. It + * does filter out the key event and some client message for + * the input method too. + */ + if (XFilterEvent(&ev, None)) + continue; + if (ev.type == ConfigureNotify) { + w = ev.xconfigure.width; + h = ev.xconfigure.height; + } + } while (ev.type != MapNotify); + + ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); + cresize(w, h); + + for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { + FD_ZERO(&rfd); + FD_SET(ttyfd, &rfd); + FD_SET(xfd, &rfd); + + if (XPending(xw.dpy)) + timeout = 0; /* existing events might not set xfd */ + + seltv.tv_sec = timeout / 1E3; + seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); + tv = timeout >= 0 ? &seltv : NULL; + + if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { + if (errno == EINTR) + continue; + die("select failed: %s\n", strerror(errno)); + } + clock_gettime(CLOCK_MONOTONIC, &now); + + if (FD_ISSET(ttyfd, &rfd)) + ttyread(); + + xev = 0; + while (XPending(xw.dpy)) { + xev = 1; + XNextEvent(xw.dpy, &ev); + if (XFilterEvent(&ev, None)) + continue; + if (handler[ev.type]) + (handler[ev.type])(&ev); + } + + /* + * To reduce flicker and tearing, when new content or event + * triggers drawing, we first wait a bit to ensure we got + * everything, and if nothing new arrives - we draw. + * We start with trying to wait minlatency ms. If more content + * arrives sooner, we retry with shorter and shorter periods, + * and eventually draw even without idle after maxlatency ms. + * Typically this results in low latency while interacting, + * maximum latency intervals during `cat huge.txt`, and perfect + * sync with periodic updates from animations/key-repeats/etc. + */ + if (FD_ISSET(ttyfd, &rfd) || xev) { + if (!drawing) { + trigger = now; + drawing = 1; + } + timeout = (maxlatency - TIMEDIFF(now, trigger)) \ + / maxlatency * minlatency; + if (timeout > 0) + continue; /* we have time, try to find idle */ + } + + /* idle detected or maxlatency exhausted -> draw */ + timeout = -1; + if (blinktimeout && tattrset(ATTR_BLINK)) { + timeout = blinktimeout - TIMEDIFF(now, lastblink); + if (timeout <= 0) { + if (-timeout > blinktimeout) /* start visible */ + win.mode |= MODE_BLINK; + win.mode ^= MODE_BLINK; + tsetdirtattr(ATTR_BLINK); + lastblink = now; + timeout = blinktimeout; + } + } + + draw(); + XFlush(xw.dpy); + drawing = 0; + } +} + +void +usage(void) +{ + die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" + " [-n name] [-o file]\n" + " [-T title] [-t title] [-w windowid]" + " [[-e] command [args ...]]\n" + " %s [-aiv] [-c class] [-f font] [-g geometry]" + " [-n name] [-o file]\n" + " [-T title] [-t title] [-w windowid] -l line" + " [stty_args ...]\n", argv0, argv0); +} + +int +main(int argc, char *argv[]) +{ + xw.l = xw.t = 0; + xw.isfixed = False; + xsetcursor(cursorshape); + + ARGBEGIN { + case 'a': + allowaltscreen = 0; + break; + case 'A': + opt_alpha = EARGF(usage()); + break; + case 'c': + opt_class = EARGF(usage()); + break; + case 'e': + if (argc > 0) + --argc, ++argv; + goto run; + case 'f': + opt_font = EARGF(usage()); + break; + case 'g': + xw.gm = XParseGeometry(EARGF(usage()), + &xw.l, &xw.t, &cols, &rows); + break; + case 'i': + xw.isfixed = 1; + break; + case 'o': + opt_io = EARGF(usage()); + break; + case 'l': + opt_line = EARGF(usage()); + break; + case 'n': + opt_name = EARGF(usage()); + break; + case 't': + case 'T': + opt_title = EARGF(usage()); + break; + case 'w': + opt_embed = EARGF(usage()); + break; + case 'v': + die("%s " VERSION "\n", argv0); + break; + default: + usage(); + } ARGEND; + +run: + if (argc > 0) /* eat all remaining arguments */ + opt_cmd = argv; + + if (!opt_title) + opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0]; + + setlocale(LC_CTYPE, ""); + XSetLocaleModifiers(""); + cols = MAX(cols, 1); + rows = MAX(rows, 1); + tnew(cols, rows); + xinit(cols, rows); + xsetenv(); + selinit(); + run(); + + return 0; +} diff --git a/st/x.o b/st/x.o new file mode 100644 index 0000000000000000000000000000000000000000..8b5e023f56c7619ca2dfcc61ae5d778be3c5be38 GIT binary patch literal 77488 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 X2Q#WI_va7KOfh_AQ6qm0NbT{z;ZiiN literal 0 HcmV?d00001